DiveList should not depend on StartPage, so remove references to
startPage.
Signed-off-by: Jan Iversen <jani@apache.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Instanciate DiveList like all the other pages.
Move DiveList properties set in main to DiveList.qml
Signed-off-by: Jan Iversen <jani@apache.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
setupActions() in StartPage contained a mixture of StartPage
actions and DiveList actions.
Split setupActions to be pure.
However currently StartPage is embedded inside DiveList so the
action onVisibleChanged must be simulated.
Signed-off-by: Jan Iversen <jani@apache.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
manager.finishSetup() have nothing to do with startpage/divelist,
but belong in main (seeing main as responsible for setup and window layout).
Move onCompleted functionality to main.
Signed-off-by: Jan Iversen <jani@apache.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Replace prefs.cloudPassword with PrefCloudStorage.cloud_storage_password in QML
Replace QMLPrefs.....cloudPassword with PrefCloudStorage::cloud_storage_password in C++
Signed-off-by: Jan Iversen <jani@apache.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Replace prefs.cloudUserName with PrefCloudStorage.cloud_storage_email in QML
Replace QMLPrefs.....cloudUserName with PrefCloudStorage::cloud_storage_email in C++
Signed-off-by: Jan Iversen <jani@apache.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If the user asked to change credentials it is equivalent to a signout,
so no need to store old credentials. This simplification allows removal
of the temporary credentials in qmlPrefs.
this commits secures the user is locked in the login page, until one
of 3 things happen:
- enter verified credentials (divelist is loaded from cloud)
- select no-cloud mode (divelist is loaded from local)
- enter new credentials, PIN page shows, enter PIN or
cancel (back to enter credentials).
This is consistent even if the program is restarted.
Old version had a non consistent way:
A user enters new credentials,
sees the PIN screen,
but does not receive the email immediately,
so works with other applications (causing the mobile app to close)
Having received the email with the PiN,
the user starts mobile again,
BUT does not see the PIN screen, instead the old credentials are used.
Signed-off-by: Jan Iversen <jani@apache.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Call saveCredentials with username/password to avoid first
setting the two and then calling.
Change saveCredentials() to use newUser, newPassword.
Signed-off-by: Jan Iversen <jani@apache.org>
Remove aliases for showPin/oldStatus and reference prefs.showPin/oldStatus directly.
showPin/oldStatus are "temporary" variables, that are not saved in settings,
so they easily be replaced
Signed-off-by: Jan Iversen <jani@apache.org>
change prefs.cloudUserName to PrefCloudStage.cloud_storage_email.
This is slightly more effective (direct instead of indirect), and
reduces the use of prefs.
This is part of limiting the use of prefs. (which is a precessor to
qPref) to the login process, and ultimately remove it.
Signed-off-by: Jan Iversen <jani@apache.org>
set_default_cylinder is accepted, because it is defined in Qt Meta system,
however the call is never carried out, because the Q_INVOKE macro is missing
Change PrefGeneral.set_default_cylinder(...) which is a function call
to PrefGeneral.default_cylinder = ... which is a builtin assignment
Signed-off-by: Jan Iversen <jani@apache.org>
When opening the saveAsDialog a second time, it contains
the last status from first time.
Clear statusText before calling saveAsDialog
Signed-off-by: Jan Iversen <jan@casacondor.com>
When using Connect, the context is switched, so close()
might or might not work.
Change unqualified close() to qualified uploadDialog.close()
Signed-off-by: Jan Iversen <jan@casacondor.com>
Handle reading/writing of userid/password settings in the
saveAsDialog and set field to visible when needed.
Activate divelogsde radio button
Signed-off-by: Jan Iversen <jan@casacondor.com>
The current png generation is intertangled with the desktop
UI, and a shared Webservice needs to be developed.
Block Radiobutton
Signed-off-by: Jan Iversen <jan@casacondor.com>
The current Webservice implementation is intertangled with the desktop
UI, and a shared Webservice needs to be developed.
Block Radiobutton
Signed-off-by: Jan Iversen <jan@casacondor.com>
DiveFilter have 2 implementation on or desktop and one for mobile,
the common export function uses DiveFilter (desktop version).
Block Radiobutton
Signed-off-by: Jan Iversen <jan@casacondor.com>
All exports are to file except 2 which are upload to web.
Integrate standard qml filedialog for all exports (minus 2).
Signed-off-by: Jan Iversen <jan@casacondor.com>
Prepare page for exporting the diveLog (feature currently
only in the desktop version).
Add Radiobuttons to select type of export
also add "anonymize button"
and a "explain" text field
Subsurface-mobile does not allow selection of dives, therefore
export will always be all dives
Signed-off-by: Jan Iversen <jan@casacondor.com>
qml demands all qml files to be in 1 directory, but allows
a "qmldir" file to reference qml files in other directories.
Add qmldir to reference map-widget.
Signed-off-by: Jan Iversen <jan@casacondor.com>
Making this persistant creates a very unpleasant user experience.
And if a dive computer needs this setting, we really want people
to report this to us so we can fix it.
Fixes: #2358
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
default parameter values is not supported as this syntax was introduced
in ECMA-262 6th edition while QML only implements the fifth edition
(as of Qt 5.11).
remove default parameter and check for undefined instead.
Signed-off-by: Jan Iversen <jan@casacondor.com>
This is even easier and more obvious than copying the logs on the About page
and then manually creating an email and pasting those logs.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When we change the filter string, we need to make sure that the collapsed model is
also aware of the change.
Similarly, instead of just calling resetFilter and directly changing the core
data structures, we need to set the filter to the empty string which ensures
that all three models get notified and the view updates correctly.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The previous code assumes that both the vertical dive list and the list of dive
details which allows the horizontal swiping from dive to dive are based on the
same model.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Running Subsurface-mobile on iOS, the notification texts are sometimes very
hard to read, and in some situations the busy indicator isn't showing up at
all.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
If the dive list is connected to the model while the model is updated
with the downloaded dives, sometimes the UI hangs completely.
Disconnecting the model and then reconnecting it does add a fairly
noticeable delay on longer dive lists, so there are tradeoffs here.
Of course the obvious solution is to make reconnecting the model
faster...
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This helps tremendously when tracking down some problems. We should
never use console.log.
In the process this also updates a couple of the messages to be clearer.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Due to some recent changes processing the downloaded dives and
re-displaying the dive list can take quite a while. So show a small
message and the busy spinner to warn the user.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The old code was ill named - this way the busy spinner itself
becomes reusable with a reasonable set of function names.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This way new fixes are actually shown when the user looks at the dive
list after applying the GPS fixes.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Add a couple more roles and remove the dive role that allows accesss to
the DiveObjectHelper in the first place.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
By getting a DiveObjectHelper and then dereferencing that we ended up
creating hundres and hundreds of these objects, only to immediately
destroy them after using a tiny part of the data.
Instead make those data available directly from the model, without
having to create a DiveObjectHelper forst.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When the user taps on a TextField to enter text, usually the virtual
keyboard will pop up. This code tries to ensure that the keyboard
doesn't cover the entry field that the user was trying to work on.
In order to centralize these changes, this introduces a new
SsrfTextField type which we use to also remove a few redundant default
settings that we previously had for every field. The one TextArea for
the Notes field didn't seem worth creating yet another type for, so
there the changes are done directly in DiveDetailsEdit.
The awkward timer mechanism is necessary as the keyboard pops up
asynchronously and then triggers a change of height for the app, so we
need to wait a little bit before doing the adjustment.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
QML has ways to style icons - and we use that for the main theme color,
but it doesn't seem to work (anymore?) for the edit and save icons.
Instead of tracking down what changed there, simply switch between icons
with different foreground color, depending on theme.
All the other icons seem to work well in all three themes.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
When switching to the global tool bar this was lost, and then it turned
out to be broken and required more patches to fix.
Commented out because it doesn't work at all.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This way we'll get a working back icon on Android and also correct font
size for the (translated) Back text.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Previously if the dive was in a different trip, we'd scroll to that trip
but not expand the trip, which was a confusing user experience.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
While pageStack.push() can handle pushing a page that's already there,
that creates an unfortunate sequence of currentItemChanged signal which
leads us to do the wrong thing with our map hack.
This commit changes things around to first look for the page in the page
stack and just switch to it, and only pushing the page as new if it
cannoot be found oon the page stack.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
QML enums are a bit painful to use, so this uses poor man's emums
instead.
Basically what this changes is that a forced switch to the map doesn't
count as picking the map. That seems obviously correct, as otherwise you
could end up in a situation where a legitimate switch away from the map
is ignored.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This makes no sense and seems crazy. But it also seems to work,
For some reason with the current Kirigami version and Qt 5.13.1
selecting the map page makes the pageStack jump back to the previous
page right away. I cannot find what triggers this behavior.
Since I cannot fix the root cause, I am working around the bug. When we
select the map page we remember that fact and when a different page is
picked with the mapPage being the last page on the stack, we force the
page selection back to the map page. I can imagine countless ways in
which this could go horribly wrong - but right now I can't figure out a
better solution.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
There doesn't appear to be a reason to pop all of the existing pages from the stack.
Just on principle, only close the drawer if it was open.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This had very strange results with the current Kirigami.
Instead set the width of those pages based on our overall column width.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The old calculation was clearly bogus, we'd also get zero columns here.
Instead do a correct calculation of the number of columns and make the
resulting column width a property of the rootItem so we can refer to it
elsewhere.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
There was a sad typo in commit eecca6aab0 ("Mobile: replace model-reset
by row-addition in DiveListModel::reload()").
Additionally, we need to also refresh the dive list so that the new
dives are shown.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We get incorrect changes to a new screen width that causes us to try
draw to a much larger screen than we actually have. Ignore those
changes.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Different Android devices seem to have different patterns of throwing
incorrect width information at us. This seems like a really bad hack,
but for the ones I've seen so far this should give us the right width
information.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Currently, desktop and mobile are accessing the DownloadThread
and the DiveImportedModel concurrently. This makes a big data
flow mess. To achieve a more hierarchical data flow, start
by making the DownloadThread a subobject of DiveImportedModel.
Start the download by calling a function in DiveImportedModel.
Route the finished signal through DiveImportedModel. Thus,
the model can reload itself with the new data.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Owing to apparent QML breakage, a model-reset leads to the DiveDetail
page being reloaded for every dive in the list(!). Therefore, add
rows instead.
This leads to extremely subtle code, as it is now imperative that
the model has been properly cleared beforehand. Nevertheless, for
now we have to do this to fix a severe performance regression.
Fixes#2295
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There is already a role to do that. Query the model directly to
avoid creating a full DiveHelperObject.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This looked fine when playing with it on the desktop, but required
more space on device for some reason.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Instead of converting the section-heading string to a trip-pointer
in QML and pass that to the tripTitle() and tripShortDate()
functions, pass the string and convert in C++ code.
Hopefully, this makes the code more robust.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since that object is very heavy, generate one object and read out all
the necessary values. The old code accessed the model again and again.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The clear()/addAllDives() pair was bogus as the former didn't
clear the model (this is not possible anymore - the model
represents the core dive list) and the latter readded all
dives again.
Replace this by a reload() function.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We don't want to generate a DiveObjectHelper numerous times for
every item in the dive list. Therefore, return this data directly
from the model. In this case, don't remove from DiveObjectHelper,
as these data might be used by grantlee templates.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We don't want to generate a DiveObjectHelper numerous times for
every item in the dive list. Therefore, return this datum directly
from the model. In this case, don't remove from DiveObjectHelper,
as this datum might be used by grantlee templates.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We don't want to generate a DiveObjectHelper numerous times for
every item in the dive list. Therefore, return this datum directly
from the model. In this case, don't remove from DiveObjectHelper,
as this datum might be used by grantlee templates.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We don't want to generate a DiveObjectHelper numerous times for
every item in the dive list. Therefore, return this datum directly
from the model. In this case, don't remove from DiveObjectHelper,
as this datum might be used by grantlee templates.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We don't want to generate a DiveObjectHelper numerous times for
every item in the dive list. Therefore, return this data directly
from the model. In this case, don't remove from DiveObjectHelper,
as these data might be used by grantlee templates.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
We don't want to generate a DiveObjectHelper numerous times for
every item in the dive list. Therefore, return this datum directly
from the model.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The canonical way of displaying lists in Qt is via models.
Thus, return the tripId directly from the DiveListModel instead
of going indirectly via a DiveObjectHelper. In the future, this
will allow us to make the DiveObjectHelper value-based, as it
is not generated numerous times for every list item.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
If the default font size is big enough to leave us fewer than 21 grid
units per row, shrink the grid unit.
In order for this to create consistent results, we need to reduce the
default column width to 21 grid units as well. And with that change, the
columnWidth property becomes obsolete.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
There are reported crashes on Android that suggest a null
"tables" attribute in DownloadDCThread. This should never
happen, as the table() function connected to this attribute
returns the address of a subobject. Thus, even if the original
DownloadThread is null, this would not return a null pointer
(the subobject is not at address 0).
Catch these null-object accesses and write a warning message
to the console. Hopefully, this will help is localizing the
problem.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This has been a feature people have asked for quite frequently. It is
taking up some valuable screen real estate - so the question could
become if there should be a switch to enable / disable it.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
As opposed to dive trips, dive sites were always directly added
to the global table, even on import. Instead, parse the divesites
into a distinct table and merge them on import.
Currently, this does not do any merging of dive sites, i.e. dive
sites are considered as either equal or different. Nevertheless,
merging of data should be rather easy to implement and simply
follow the code of the dive merging.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
And offer an option to show all devices in the settings. This is intentionally
not stored in the preferences as this should never be needed. We don't support
BT or BLE dive computers that we don't recognize. This is a last resort in case
a new firmware were to change the name or some other weird issue causes us not
to recognize a dive computer - and that should be fixed instead of worked
around.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Since process_imported_dives() can add dives to a newly generated
trip, this need not be done in the downloading code. This makes
data flow distinctly simpler, as no trip table and no add-new-trip
flag has to be passed down to the libdivecomputer glue code.
Moreover, since now the trip creation is done at the import step
rather than the download step, the latest status of the "add to
new trip" checkbox will be considered.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In the future we want to download trips into a distinct trip-table
instead of the global trip-table to allow for undo of import.
Therefore add a trip_table argument to DiveImportedModel::repopulate()
and a trip_table member to DiveImportedModel. To correctly set these,
add a DownloadThread::trips() function, which currently simply returns
the global trip table.
Finally, make "struct trip_table *" a Q_METATYPE, so that the corresponding
arguments can be passed from QML.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Instead of trying to update this whenever the connection text changes,
instead deal with it right before it actually gets used.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
To make data flow more clear, unglobalize the downloadTable object.
Make it a subobject of DownloadThread. The difficult part was making
this compatible with QML, because somehow the pointer to the
download-table has to be passed to the DiveImportedModel. Desktop would
simply pass it to the constructor. But with objects generated in QML
this is not possible. Instead, pass the table in the repopulate()
function. This seems to make sense, but for this to work, we have to
declare pointer-to-dive-table as a Q_METATYPE. And this only works
if we use a typedef, because MOC removes the "struct" from "struct
dive_table". This leads to compilation errors, because dive_table is
the symbol-name of the global dive table! Sigh.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
QML's ListView uses the "section" property to test if items belong to the
same section. Apparently, this must be a string and therefore we can't
pass e.g. a dive-trip object. Therefore a specially formatted string
was passed in, which was guaranteed to be unique (contained the dive-trip
pointer value) and the fully formatted trip-title and short-date.
The disadvantage of that approach is that the formatting is performed for
every dive and not every trip. Perhaps not a problem now, but it makes
it for example necessary to cache the number of filtered dives.
To be more flexible, pass in only the pointer value formatted as
hexadecimal string and provide a function to convert that string
back to a trip-pointer (in the form of a QVariant, so that it can
be passed to QML). Moreover provide two functions for formatting the
title and the short-date.
The three new functions are members of DiveListSortModel. This might not
be the perfect place, but it is easy to reach from the DiveListView.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Now these buttons are finally shown with long press and seem to be
working more-or-less as intended.
Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
Initial implementation/prototype of copy-paste support for
Subsurface-mobile. The UI part is really lacking; right now the copy
button is initially visible and paste is achieved by long press on a
dive and clicking the paste button when it appears. Delete is currently
not possible at all, as I just failed to layout the buttons properly
using QML. It just sounds so simple, to put all the copy-paste-delete
buttons next to each other...
The data to be copied is currently hard-coded. A dialog to choose
inteded fields would be nice, but it'll take quite a bit effort to get
used to QML enough to be able to hack something together.
Anyway, this seems to work, even though the UI is not always reflecting
the paste without switching dives (when testing on laptop).
Signed-off-by: Miika Turkia <miika.turkia@gmail.com>
While not something that many will use, editing a dive on
Subsurface-mobile should not result in data loss.
This makes the divemaster field behave in the same way as the buddy
field with regards to multiple entries.
Fixes#1853
Signed-off-by: Joakim Bygdell <j.bygdell@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Even though the height was zero, when pulling down the dive list for refresh,
the filter input line would still be visible. With this fix it no longer is.
Also remove unused property.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Replace UUIDs by pointers to dive-site in mobile code. In both
cases, the value is transported via a QVariant. The function
getCoordinatesForUUID(), which was only used from mobile, can
be replaced by a getCoordinatesFor() function taking a variant
supposed to contain a dive-site pointer. Likewise, the variant
of the centerOnDiveSite function is now supposed to wrap a
pointer-to-divesite.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
In commit 99c06dec3d ("Mobile/filtering: simple busy indicator") we switched to
Controls 2.4 which requires Qt 5.11. Revert that one line of the commit as it
isn't necessary.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Otherwise we start showing an illogical '0' there when first opening the filter
dialog, and the equally wrong previous count when closing and then re-opening
the filter dialog.
Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
It's important to disconnect the model from the ListView, otherwise the update in a
different thread will fail.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Simply make it always reset the filter. There's no point remembering the last
filter pattern and explicitly setting it, if the last thing we do is to reset
this pattern.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This one does nothing but whitespace - separating it into two commits makes the
previous one a lot easier to read.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We are still trying to ensure that the filter is indeed shown in front of the
dive list. This is working when running on the desktop without the rectangle,
but on Android this appears to be needed.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
We don't need to toggle visibility, toggling height is sufficient. This
dramatically simplifies the transitions. But as a result we need to use the
'enabled' property to reset the filter.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
QML's logic for who gets focus is a bit complicated. But forceActiveFocus()
cuts through the confusion and makes sure that your field does indeed get
focus.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This is a usability / performance tradeoff. I like it better when it filters as
I type, but on mobile this may make things feel sluggish.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>