aboutsummaryrefslogtreecommitdiffstats
path: root/desktop-widgets/mainwindow.cpp
AgeCommit message (Collapse)Author
2019-05-06Add "Import dive sites" menu to mainwindowGravatar Doug Junkins
Adds "Import->Import dive sites" menu to mainwindow.cpp and adds the on_actionImportDiveSites_triggered() method to prompt for the filename to import from. The files are parsed and then any dive and trip data is cleared before opening a dialog box to select which sites are to be imported. Signed-off-by: Doug Junkins <junkins@foghead.com>
2019-04-29Cleanup: implement proper Qt-model semantics in WeightInfoModelGravatar Berthold Stoeger
- Use a beginResetModel()/endResetModel() pair instead of distinct addRows / removeRows pairs. - Reuse the update function in the constructor(). - Let "rows" be the number of rows, not the number of rows minus one. - Remove updateInfo() function as it does the same as update(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-15Cleanup: Remove MainTab::getEditMode() functionGravatar Berthold Stoeger
The only caller of said function used to check whether MainTab is in edit mode. For this case there is already a function - use that instead. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-14Desktop: destroy maintab before destructing mainwindowGravatar Berthold Stoeger
Apparently, in some Qt-versions the destructor of the base class calls hide on child-objects (according to Qt's object hierarchy). This is obviously called after the derived class has been destructed. In a concrete case, the base class of the destructed MainWindow would hide the TabDiveSite object. That would reset the filtering if a dive site was selected, which would indirectly access the MainWindow, which is already partially destroyed. Therefore, destroy the MainTab before destroying the MainWindow. Do this by keeping it as a std::unique_ptr subobject. Thus, it will be destroyed before the MainWindow and remove itself from Qt's object hierarchy. Reported-by: Dirk Hohndel <dirk@hohndel.org> Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-13Desktop: update dive site list on file-closeGravatar Berthold Stoeger
The model was not reset on file close, leading to weird effects. New dive sites would be added at the end of a table full of empty entries. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Undo: on save remove focus from active fieldsGravatar Berthold Stoeger
The editing of a dive field is only performed when focus is removed from the field. On pressing CTRL-s, the changes in the currently active field were therefore not saved. Remove the focus from all fields to trigger an edit command yand thus ensure that all changes are saved. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Undo: use QUndoStack::isClean() to determine unsaved changesGravatar Berthold Stoeger
Properly implement the unsaved-changes flag(s). Since we currently have two kinds of changes, there are two flags: 1) dive_list_changed in divelist.c marks non-undoable changes. This flag is only cleared on save or load. 2) QUndoStack::isClean() is used to determine the state of undoable changes. Every time the user returns to the state where they saved, this flag is cleared. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Desktop: read tab-items from current_dive, not displayed_diveGravatar Berthold Stoeger
The whole edit logic moved from displayed_dive to current_dive and it became more and more tedious to keep these in sync. Therefore, simply always display current_dive. The only exceptions are the equipment tab and the planner, as these are not yet integrated in the undo system. Once this is done, displayed_dive can be removed. Moreover, remove the clear parameter from updateDiveInfo(). Instead simply clear of there is no current_dive set. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Undo: remove ADD mode from main tabGravatar Berthold Stoeger
Instead of letting the user edit the fields before adding a dive, simply add an empty dive. Thus, the ADD mode of the main tab can be removed. Constructing a new dive with default-depth and making sure that the dive is displayed correctly is very subtle. This all needs to be detangled in due course. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Coding style: remove Java-style function definitionGravatar Berthold Stoeger
Remove a few cases of void fun() { ... } While touching these functions, fix a few other whitespace coding style violations. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Cleanup: remove EDIT_TEXT and EDIT_VALUE macros in maintab.cppGravatar Berthold Stoeger
These functions are now performed by the edit commands and the macros have no users. Remove them. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Undo: implement undo of dive site editingGravatar Berthold Stoeger
This one is a bit more tricky. There are two modes: set dive site and set newly created dive site. This is realized using an OO model with derived classed. Quite convoluted - but it seems to work. Moreover, editing a dive site is not simply setting a value, but the list of dives in a dive site has to be kept up to date. Finally, we have to inform the dive site list of the changed number of dives. Therefore add a new signal diveSiteDivesChanged. To send only one signal per dive site, hook into the undo() and redo() functions and call the functions of the base class there. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Cleanup: remove unnecessary signalGravatar Berthold Stoeger
The edit dive site button was connected to a *signal* of MainWindow, which was connected to a slot of MainWindow. Remove the unnecessary intermediate signal. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Dive site: add edit field to dive site tableGravatar Berthold Stoeger
Add an edit column that calls the new editDiveSite() function of MainWindow. The calling code is in DiveSiteSortedModel. Quite illogical, but that's how TableView works, for now. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Cleanup: remove LocationInformationWidget::endEditDiveSite signalGravatar Berthold Stoeger
The signal was caught by the MainWindow to: 1) call setDefaultState() 2) call refreshDisplay() 3) call refreshDisplayedDiveSite() 1) Let's call that directly from the widget. The reason is that in the future there might be multiple way to get into the widget and therefore the widget needs finer control. 2) Remove this call as it produces an unsteady UI. 3) This should be done by undo commands, not only when finishing dive site editing. Thus, the signal becomes unnecessary and can be removed. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Cleanup: move parse-function declarations out of "dive.h"Gravatar Berthold Stoeger
Move the declaration of these functions to "file.h" and "parse.h" according to the translation unit they are defined in. Thus, not all users of "dive.h" have to suck in "sqlite3.h". Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-04-12Undo: make undo-system dive site-awareGravatar Berthold Stoeger
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>
2019-04-12Parser: parse into custom dive site tableGravatar Berthold Stoeger
To extend the undo system to dive sites, the importers and downloaders must not parse directly into the global dive site table. Instead, pass a dive_site_table argument to parse into. For now, always pass the global dive_site_table so that this commit should not cause any functional change. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-02-19Desktop: show the filter information in the window titleGravatar Dirk Hohndel
Instead of using the filter widget itself to show the information how many dives are displayed, put it in the window title where it's visible even if the filter widget isn't shown. If the filter is not active, simply show the total number of dives. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-02-11Desktop: show filter panel with maximized dive listGravatar Dirk Hohndel
This way we can filter both in the default layout and in the dive list layout. Fixes #1951 Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-02-11Small whitespace fixGravatar Dirk Hohndel
Simply because it bugged me. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2019-02-05Add button to toggle deco info in info boxGravatar Robert C. Helling
The info box can get longish. Offer the user to turn off display of deco information (surface GF and individual ceilings). Signed-off-by: Robert C. Helling <helling@atdotde.de>
2019-02-01facebook: remove the featute from the code baseGravatar Lubomir I. Ivanov
Remove from: - unit tests - desktop widgets - preferences - core intergration - cmakefiles - build scripts - icons - docs Also remove the plugins and social network integration. Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
2019-01-26Cleanup: remove unused function setCheckedActionFilterTags()Gravatar Berthold Stoeger
Last caller was removed in e0f473fcb49c8121a0a9c52bf0536049b0f342ed Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-19Desktop: Make filterWidget2 a subobject of MainWindowGravatar Berthold Stoeger
In commit b0556abdd35f96b816ba11e40bf5707abe0c3ebf, the filter-widget and the filter were connected by a direct function call. This led to a rather obscure crash on application-close with Qt 5.12. The crash is due to the Ui::MainWindow class being a sub-object of MainWindow, but the FilterWidget2 being *not* a subobject. What happens is that after calling the MainWindow destructor, the subobjects are destructed, notably the Ui class. Then the base-class destructor is called (which makes sense, as destructors are called in reverse order of constructors). But: the QObject destructor calls hide() on all still existing child-objects according to Qt's object hierarchy, notably the visible FilterWidget2. Now the FilterWidget2, on hiding, updates the MainWindow, which has already destructed all its subobjects. Crash. Prevent this crash by making FilterWidget2 a subobject of MainWindow and thus have it destructed before running the QObject destructor. Alternative ways would be: 1) Use signal/slot() instead of function calls, as these are automatically removed if an object is destroyed. 2) Make the FilterWidget2 subobject a smart-pointer. Thus, we probably wouldn't have to include the corresponding header. 3) Make the FilterWidget2 subobject a plain pointer and delete it explicitly in the constructor. Reported-by: Jan Mulder <jlmulder@xs4all.nl> Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-19Import: control process_imported_dives() by flagsGravatar Berthold Stoeger
process_imported_dives() takes four boolean parameters. Replace these by flags. This makes the function calls much more descriptive. Morover, it becomes easier to add or remove flags. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-19Import: add add_to_new_trip flag to process_imported_dives()Gravatar Berthold Stoeger
If this flag is set, dives that are not assigned to a trip will be assigned to a new trip. This flag is set if the user checked "add to new trip" in the download dialog of the desktop version. Currently this is a no-op as the dives will already have been added to a new trip by the downloading code. This will be removed in a subsequent commit. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-13Planner: Add checkbox to force OC bailoutGravatar Robert C. Helling
This adds a checkbox for rebreather modes of the planner that force the ascent to be in OC mode. Before, one had to add a one minute last segment with the mode change but this is not practical when manually searching for the maximal bottom time given gas reserves. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2019-01-09Undo: make dive-import undoableGravatar Berthold Stoeger
On desktop, replace all add_imported_dives() calls by a new undo-command. This was rather straight forward, as all the preparation work was done in previous commits. By using an undo-command, a full UI-reset can be avoided, making the UI react smoother. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09Import: split process_imported_dives() functionGravatar Berthold Stoeger
Split the process_imported_dives() function in two: 1) process_imported_dives() processes the dives and generates a list of dives and trips to be added and removed. 2) add_imported_dives() calls process_imported_dives() and does the actual removal / addition of dives and trips. The goal is to split preparation and actual work, to make dive import undo-able. The code adds extra checks to never merge into the same dive twice, as this would lead to a double-free() bug. This should in principle never happen, as dives that compare equal according to is_same_dive() are merged in the imported-dives list, but perhaps in some pathologival corner-cases is_same_dive() turns out to be non-transitive. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09Import: add merge_all_trips parameter to process_imported_dives()Gravatar Berthold Stoeger
When importing log-files we generally want to merge trips. But when downloading and the user chose "generate new trip", that new trip should not be merged into existing trips. Therefore, add a "merge_all_trips" parameter to process_imported_dives(). If false only autogenerated trips [via autogroup] will be merged. In the future we might want to let the user choose if trips should be merged when importing log-files. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09Import: merge dives trip-wiseGravatar Berthold Stoeger
The old way of merging log-files was not well defined: Trips were recognized as the same if and only if the first dives started at the same instant. Later dives did not matter. Change this to merge dives if they are overlapping. Moreover, on parsing and download generate trips in a separate trip-table. This will be fundamental for undo of dive-import: Firstly, we don't want to mix trips of imported and not-yet imported dives. Secondly, by merging trip-wise, we can autogroup the dives in the import-data to trips and merge these at once. This will simplify the code to decide to which trip dives should be autogrouped. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09Parser: add trip_table parameter to parsing functionsGravatar Berthold Stoeger
To allow parsing into arbitrary trip_tables, add the corresponding parameter to the parsing functions and the parser state. Currently, all callers pass the global trip_table so there should be no change in functionality. These arguments will be replaced in subsequent commits. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-09Core: move autogroup() into divelist.cGravatar Berthold Stoeger
After loading or importing, the caller usually called autogroup() to autogroup dives if so wished by the user. This has already led to bugs, when autogroup() was forgotten. Instead, call autogroup() directly in the process_loaded_dives() and process_imported_dives() functions. Not only does this prevent forgetting the call - it also means that autogrouping can be changed without changing every caller. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2019-01-08Helper function to determined planned divesGravatar Robert C. Helling
... to reduce code duplication. Signed-off-by: Robert C. Helling <helling@atdotde.de>
2019-01-07Dive list: split DiveTripModel into distinct models (tree and list)Gravatar Berthold Stoeger
The DiveTripModel was used to represent both, trip and list views. Thus many functions had conditionals checking for the current mode and both modes had to be represented by the same data structure. Instead, split the model in two and derive them from a base class, which implements common functions and defines an interface. The model can be switched by a call to resetModel(), which invalidates any pointer obtained by instance(). This is quite surprising behavior. To handle it, straighten out the control flow: DiveListView --> MultiFilterSortModel --> DiveTripModelBase Before, DiveListView accessed DiveTripModelBase directly. A goal of this commit is to enable usage of the same model by mobile and desktop. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-12-14Drop old filter codeGravatar Tomaz Canabrava
Drop tons of now-unused-code. Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
2018-12-14Replace the old filter widget for a new oneGravatar Tomaz Canabrava
Wires the code to display the filter widget on the mainwindow. Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
2018-12-14Start the FilterDive stateGravatar Tomaz Canabrava
Register the new FilterDive widget on the mainwindow so we can trigger a shortcut to display it. The shortcut currently doesn't exists. Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
2018-11-21Desktop: don't refresh display on autogroupGravatar Berthold Stoeger
The whole point of the undo-command system is that the divelist doesn't have to be refreshed. Therefore, don't do it for autogrouping / deautogrouping. Moreover, the divelist-changed flag is also set by the command and doesn't have to be set explicitly. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-05Dive list: let sort arrows reflect sort order for NR and DATEGravatar Berthold Stoeger
The old code always sorted by "ascending" by default. But because users typically want their new dives top, "ascending" was defined for NR and DATE, such that it is actually descending. Turn these around and intitialize these two fields as default-descending. This is possible using the Qt::InitialSortOrderRole role in DiveTripModel::headerData(). Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-11-05Dive list: split reload() in reload() and setSortOrder()Gravatar Berthold Stoeger
The DiveListView code had a very fundamental problem with its header: Each had its own idea of who is responsible for sorting. Since we can't easily change QHeaderView, accept QHeaderView as the authority on sort-column and order. To make this possible, split the reload() function in two distinct functions: - reload() reloads the model and sorts according to the current sort criterion. - setSortOrder() tells the header to display a certain sort criterion. If this is a new criterion, it will then emit a signal. In this signal, resort according to that criterion. Thus, the actual sorting code has to be moved from the headerClicked() to a new sortIndicatorChanged() slot. Morover, the sorting of the QHeaderView has to be used. Reported-by: Stefan Fuchs <sfuchs@gmx.de> Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-14Desktop: Enable next/prev DCs only for applicable divesGravatar Jan Mulder
Does not solve any problem, but might help users that are confused about the next/prev DC menu items, to select a different profile for the currently selected dive. So, enable these menu items only for dives where more than one DC is used. Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-10-14Autogroup only when selectedGravatar Jan Mulder
Comits f427226b3b and 43c3885249f of the undo series introduced 2 calls of autogroup_dives() without checking the autogroup global boolean. This is a bug. An import from DC (for example) then triggers an autogrouping, the divelist is autogrouped, and the UI button is off. This commit solves this. I've chosen for a guard in the autogroup_dives() that now is a no-op when called when the user did not select autogrouping. In additon, simplified the other calls to this function, as we do not need to check before calling any more. Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2018-10-13Cleanup: rename MainWindow member variablesGravatar Berthold Stoeger
Instead of the weirdly named "information" and the inconsistent "dive_list" use the logical "mainTab" and the camel-cased "diveList", respectively. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-13Cleanup: Turn widget accessor-functions into simple pointersGravatar Berthold Stoeger
The keeps track of different sub widgets needed by other parts of the code, notably: MainTab PlannerDetails PlannerSettingsWidget ProfileWidget2 DivePlannerWidget DiveListView Access to these widgets was provided with accessor functions. Now these functions were very weird: instead of simply returning pointers that were stored in the class, they accessed a data structure which describes the different application states. But this data structure was "duck-typed", so there was an implicit agreement at which position the pointers to the widgets were put inside. The widgets were then down-cast by the accessor functions. This might make sense if the individual widgets could for some reason be replaced by other widgets [dynamic plugins?], but even then it would be strange, as one would expect to get a pointer to some base class. Therefore, directly store the properly typed pointers to the widgets and simply remove the accessor functions. Why bother? Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-13Dive site: explicitly init displayed_dive_site on show widgetGravatar Berthold Stoeger
The global object "displayed_dive_site" is used to store the old dive site data for the edit-dive-site widget. The fields of the widget were initialized from this object in the show event. Therefore the object was updated in numerous parts of the code to make sure that it was up-to-date. Instead, move the initialization of the object to the function that also initiatlizes the fields. Call this function explicitly before showing the widget. This makes the data-fow distinctly easier to understand. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Cleanup: remove ReverseGeoLookupThreadGravatar Berthold Stoeger
Fetching the taxonomy from GPS coordinates was implemented in a QThread. But the only access to the main function was a direct call to run(). Thus, the thread was *never* started. The function call was always asynchronous [it was using an event loop though, so the UI doesn't hang]. Notably this means that the signals connected to the thread would never fire. And the spinner would never be activated. Thus: 1) Turn the thread into a simple function. 2) Remove the spinner. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Undo: make adding of planned dive undo-ableGravatar Berthold Stoeger
Planned dives were still added by directly calling core code. This could confuse the undo-machinery, leading to crashes. Instead, use the proper undo-command. The problem is that as opposed to the other AddDive-commands, planned dives may belong to a trip. Thus, the interface to the AddDive command was changed to respect the divetrip field. Make sure that the other callers reset that field (actually, it should never be set). Add a comment describing the perhaps surprising interface (the passed-in dive, usually displayed dive, is reset). Moreover, a dive cloned in the planner is not assigned a new number. Thus, add an argument to the AddDive-command, which expresses whether a new number should be generated for the to-be-added dive. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2018-10-11Dive list: propagate current-item to frontendGravatar Berthold Stoeger
The command-objects select a current item, but this selection was not propagated to the front-end. The current item is the base for keyboard-navigation through the dive-list and therefore should be set correctly. It took some experimentation to get the flags right: QItemSelectionModel::Current Hopefully, these are the correct flags across all supported Qt versions! Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>