diff options
Diffstat (limited to 'qt-ui/maintab.cpp')
-rw-r--r-- | qt-ui/maintab.cpp | 235 |
1 files changed, 158 insertions, 77 deletions
diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp index 2fafb65ff..fd760445b 100644 --- a/qt-ui/maintab.cpp +++ b/qt-ui/maintab.cpp @@ -6,9 +6,16 @@ */ #include "maintab.h" #include "mainwindow.h" +#include "globe.h" #include "helpers.h" #include "statistics.h" #include "modeldelegates.h" +#include "models.h" +#include "divelistview.h" +#include "display.h" +#include "profile/profilewidget2.h" +#include "diveplanner.h" +#include "divesitehelpers.h" #if defined(FBSUPPORT) #include "socialnetworks.h" @@ -20,6 +27,7 @@ #include <QShortcut> #include <QMessageBox> #include <QDesktopServices> +#include <QStringList> MainTab::MainTab(QWidget *parent) : QTabWidget(parent), weightModel(new WeightModel(this)), @@ -43,18 +51,19 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent), ui.extraData->setModel(extraDataModel); closeMessage(); + connect(ui.manageDiveSite, SIGNAL(clicked()), this, SLOT(prepareDiveSiteEdit())); + QAction *action = new QAction(tr("Apply changes"), this); connect(action, SIGNAL(triggered(bool)), this, SLOT(acceptChanges())); addMessageAction(action); action = new QAction(tr("Discard changes"), this); connect(action, SIGNAL(triggered(bool)), this, SLOT(rejectChanges())); + addMessageAction(action); QShortcut *closeKey = new QShortcut(QKeySequence(Qt::Key_Escape), this); connect(closeKey, SIGNAL(activated()), this, SLOT(escDetected())); - addMessageAction(action); - if (qApp->style()->objectName() == "oxygen") setDocumentMode(true); else @@ -64,21 +73,6 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent), // filled from a dive, they are made writeable setEnabled(false); - ui.location->installEventFilter(this); - ui.coordinates->installEventFilter(this); - ui.divemaster->installEventFilter(this); - ui.buddy->installEventFilter(this); - ui.suit->installEventFilter(this); - ui.notes->viewport()->installEventFilter(this); - ui.rating->installEventFilter(this); - ui.visibility->installEventFilter(this); - ui.airtemp->installEventFilter(this); - ui.watertemp->installEventFilter(this); - ui.dateEdit->installEventFilter(this); - ui.timeEdit->installEventFilter(this); - ui.tagWidget->installEventFilter(this); - ui.DiveType->installEventFilter(this); - Q_FOREACH (QObject *obj, ui.statisticsTab->children()) { QLabel *label = qobject_cast<QLabel *>(obj); if (label) @@ -192,6 +186,15 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent), ui.socialNetworks->setVisible(false); #endif + ui.waitingSpinner->setRoundness(70.0); + ui.waitingSpinner->setMinimumTrailOpacity(15.0); + ui.waitingSpinner->setTrailFadePercentage(70.0); + ui.waitingSpinner->setNumberOfLines(8); + ui.waitingSpinner->setLineLength(5); + ui.waitingSpinner->setLineWidth(3); + ui.waitingSpinner->setInnerRadius(5); + ui.waitingSpinner->setRevolutionsPerSecond(1); + acceptingEdit = false; } @@ -206,6 +209,22 @@ MainTab::~MainTab() } } +void MainTab::enableGeoLoockupEdition() +{ + ui.waitingSpinner->stop(); + ui.manageDiveSite->show(); +} + +void MainTab::disableGeoLoockupEdition() +{ + ui.waitingSpinner->start(); + ui.manageDiveSite->hide(); +} + +void MainTab::prepareDiveSiteEdit() { + emit requestDiveSiteEdit(displayed_dive.dive_site_uuid); +} + void MainTab::toggleTriggeredColumn() { QAction *action = qobject_cast<QAction *>(sender()); @@ -284,11 +303,15 @@ void MainTab::updateTextLabels(bool showUnits) void MainTab::enableEdition(EditMode newEditMode) { + const bool isTripEdit = MainWindow::instance() && + MainWindow::instance()->dive_list()->selectedTrips().count() == 1; + if (((newEditMode == DIVE || newEditMode == NONE) && current_dive == NULL) || editMode != NONE) return; modified = false; copyPaste = false; if ((newEditMode == DIVE || newEditMode == NONE) && + !isTripEdit && current_dive->dc.model && strcmp(current_dive->dc.model, "manually added dive") == 0) { // editCurrentDive will call enableEdition with newEditMode == MANUALLY_ADDED_DIVE @@ -310,7 +333,7 @@ void MainTab::enableEdition(EditMode newEditMode) if (amount_selected == 1 && newEditMode != ADD) MainWindow::instance()->globe()->prepareForGetDiveCoordinates(); - if (MainWindow::instance() && MainWindow::instance()->dive_list()->selectedTrips().count() == 1) { + if (isTripEdit) { // we are editing trip location and notes displayMessage(tr("This trip is being edited.")); memset(&displayedTrip, 0, sizeof(displayedTrip)); @@ -385,12 +408,17 @@ bool MainTab::isEditing() return editMode != NONE; } +void MainTab::showLocation() +{ + ui.location->setText(get_dive_location(&displayed_dive)); +} + void MainTab::updateDiveInfo(bool clear) { // don't execute this while adding / planning a dive if (editMode == ADD || editMode == MANUALLY_ADDED_DIVE || MainWindow::instance()->graphics()->isPlanner()) return; - if (!isEnabled() && !clear) + if (!isEnabled() && !clear ) setEnabled(true); if (isEnabled() && clear) setEnabled(false); @@ -418,9 +446,7 @@ void MainTab::updateDiveInfo(bool clear) else ui.notes->setPlainText(tmp); } - UPDATE_TEXT(displayed_dive, notes); - UPDATE_TEXT(displayed_dive, location); UPDATE_TEXT(displayed_dive, suit); UPDATE_TEXT(displayed_dive, divemaster); UPDATE_TEXT(displayed_dive, buddy); @@ -429,7 +455,11 @@ void MainTab::updateDiveInfo(bool clear) ui.DiveType->setCurrentIndex(displayed_dive.dc.divemode); if (!clear) { - updateGpsCoordinates(); + struct dive_site *ds = get_dive_site_by_uuid(displayed_dive.dive_site_uuid); + if (ds) + ui.location->setText(ds->name); + else + ui.location->clear(); // Subsurface always uses "local time" as in "whatever was the local time at the location" // so all time stamps have no time zone information and are in UTC QDateTime localTime = QDateTime::fromTime_t(displayed_dive.when - gettimezoneoffset(displayed_dive.when)); @@ -440,8 +470,6 @@ void MainTab::updateDiveInfo(bool clear) setTabText(0, tr("Trip notes")); currentTrip = *MainWindow::instance()->dive_list()->selectedTrips().begin(); // only use trip relevant fields - ui.coordinates->setVisible(false); - ui.CoordinatedLabel->setVisible(false); ui.divemaster->setVisible(false); ui.DivemasterLabel->setVisible(false); ui.buddy->setVisible(false); @@ -468,11 +496,9 @@ void MainTab::updateDiveInfo(bool clear) clearEquipment(); ui.equipmentTab->setEnabled(false); } else { - setTabText(0, tr("Dive notes")); + setTabText(0, tr("Notes")); currentTrip = NULL; // make all the fields visible writeable - ui.coordinates->setVisible(true); - ui.CoordinatedLabel->setVisible(true); ui.divemaster->setVisible(true); ui.buddy->setVisible(true); ui.suit->setVisible(true); @@ -641,8 +667,8 @@ void MainTab::updateDiveInfo(bool clear) clearStats(); clearEquipment(); ui.rating->setCurrentStars(0); - ui.coordinates->clear(); ui.visibility->setCurrentStars(0); + ui.location->clear(); } editMode = NONE; ui.cylinders->view()->hideColumn(CylindersModel::DEPTH); @@ -750,19 +776,13 @@ void MainTab::acceptChanges() copy_samples(&displayed_dive.dc, ¤t_dive->dc); } struct dive *cd = current_dive; - //Reset coordinates field, in case it contains garbage. - updateGpsCoordinates(); // now check if something has changed and if yes, edit the selected dives that // were identical with the master dive shown (and mark the divelist as changed) - if (!same_string(displayed_dive.buddy, cd->buddy)) - MODIFY_SELECTED_DIVES(EDIT_TEXT(buddy)); if (!same_string(displayed_dive.suit, cd->suit)) MODIFY_SELECTED_DIVES(EDIT_TEXT(suit)); if (!same_string(displayed_dive.notes, cd->notes)) MODIFY_SELECTED_DIVES(EDIT_TEXT(notes)); if (!same_string(displayed_dive.divemaster, cd->divemaster)) - MODIFY_SELECTED_DIVES(EDIT_TEXT(divemaster)); - if (displayed_dive.rating != cd->rating) MODIFY_SELECTED_DIVES(EDIT_VALUE(rating)); if (displayed_dive.visibility != cd->visibility) MODIFY_SELECTED_DIVES(EDIT_VALUE(visibility)); @@ -779,18 +799,12 @@ void MainTab::acceptChanges() time_t offset = cd->when - displayed_dive.when; MODIFY_SELECTED_DIVES(mydive->when -= offset;); } - if (displayed_dive.latitude.udeg != cd->latitude.udeg || - displayed_dive.longitude.udeg != cd->longitude.udeg) - MODIFY_SELECTED_DIVES( - if (copyPaste || - (same_string(mydive->location, cd->location) && - mydive->latitude.udeg == cd->latitude.udeg && - mydive->longitude.udeg == cd->longitude.udeg)) - gpsHasChanged(mydive, cd, ui.coordinates->text(), 0); - ); - if (!same_string(displayed_dive.location, cd->location)) - MODIFY_SELECTED_DIVES(EDIT_TEXT(location)); + if (displayed_dive.dive_site_uuid != cd->dive_site_uuid) + MODIFY_SELECTED_DIVES(EDIT_VALUE(dive_site_uuid)); + // three text fields are somewhat special and are represented as tags + // in the UI - they need somewhat smarter handling + saveTaggedStrings(); saveTags(); if (editMode != ADD && cylindersModel->changed) { @@ -821,6 +835,16 @@ void MainTab::acceptChanges() cd->cylinder[i] = displayed_dive.cylinder[i]; cd->cylinder[i].type.description = copy_string(displayed_dive.cylinder[i].type.description); } + /* if cylinders changed we may have changed gas change events + * - so far this is ONLY supported for a single selected dive */ + struct divecomputer *tdc = ¤t_dive->dc; + struct divecomputer *sdc = &displayed_dive.dc; + while(tdc && sdc) { + free_events(tdc->events); + copy_events(sdc, tdc); + tdc = tdc->next; + sdc = sdc->next; + } do_replot = true; } @@ -895,7 +919,6 @@ void MainTab::resetPallete() ui.buddy->setPalette(p); ui.notes->setPalette(p); ui.location->setPalette(p); - ui.coordinates->setPalette(p); ui.divemaster->setPalette(p); ui.suit->setPalette(p); ui.airtemp->setPalette(p); @@ -970,10 +993,7 @@ void MainTab::markChangedWidget(QWidget *w) qApp->palette().color(QPalette::Text).getHslF(&h, &s, &l, &a); p.setBrush(QPalette::Base, (l <= 0.3) ? QColor(Qt::yellow).lighter() : (l <= 0.6) ? QColor(Qt::yellow).light() : /* else */ QColor(Qt::yellow).darker(300)); w->setPalette(p); - if (!modified) { - modified = true; - enableEdition(); - } + modified = true; } void MainTab::on_buddy_textChanged() @@ -1137,6 +1157,73 @@ void MainTab::saveTags() ); } +// buddy and divemaster are represented in the UI just like the tags, but the internal +// representation is just a string (with commas as delimiters). So we need to do the same +// thing we did for tags, just differently +void MainTab::saveTaggedStrings() +{ + QStringList addedList, removedList; + struct dive *cd = current_dive; + + diffTaggedStrings(cd->buddy, displayed_dive.buddy, addedList, removedList); + MODIFY_SELECTED_DIVES( + QStringList oldList = QString(mydive->buddy).split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); + QString newString; + QString comma; + Q_FOREACH (const QString tag, oldList) { + if (!removedList.contains(tag, Qt::CaseInsensitive)) { + newString += comma + tag; + comma = ", "; + } + } + Q_FOREACH (const QString tag, addedList) { + if (!oldList.contains(tag, Qt::CaseInsensitive)) { + newString += comma + tag; + comma = ", "; + } + } + free(mydive->buddy); + mydive->buddy = copy_string(qPrintable(newString)); + ); + addedList.clear(); + removedList.clear(); + diffTaggedStrings(cd->divemaster, displayed_dive.divemaster, addedList, removedList); + MODIFY_SELECTED_DIVES( + QStringList oldList = QString(mydive->divemaster).split(QRegExp("\\s*,\\s*"), QString::SkipEmptyParts); + QString newString; + QString comma; + Q_FOREACH (const QString tag, oldList) { + if (!removedList.contains(tag, Qt::CaseInsensitive)) { + newString += comma + tag; + comma = ", "; + } + } + Q_FOREACH (const QString tag, addedList) { + if (!oldList.contains(tag, Qt::CaseInsensitive)) { + newString += comma + tag; + comma = ", "; + } + } + free(mydive->divemaster); + mydive->divemaster = copy_string(qPrintable(newString)); + ); +} + +void MainTab::diffTaggedStrings(QString currentString, QString displayedString, QStringList &addedList, QStringList &removedList) +{ + QStringList displayedList, currentList; + currentList = currentString.split(',', QString::SkipEmptyParts); + displayedList = displayedString.split(',', QString::SkipEmptyParts); + Q_FOREACH ( const QString tag, currentList) { + if (!displayedList.contains(tag, Qt::CaseInsensitive)) + removedList << tag.trimmed(); + } + Q_FOREACH (const QString tag, displayedList) { + if (!currentList.contains(tag, Qt::CaseInsensitive)) + addedList << tag.trimmed(); + } +} + void MainTab::on_tagWidget_textChanged() { char buf[1024]; @@ -1158,9 +1245,6 @@ void MainTab::on_location_textChanged(const QString &text) if (currentTrip) { free(displayedTrip.location); displayedTrip.location = strdup(ui.location->text().toUtf8().data()); - } else { - free(displayed_dive.location); - displayed_dive.location = strdup(ui.location->text().toUtf8().data()); } markChangedWidget(ui.location); } @@ -1168,25 +1252,13 @@ void MainTab::on_location_textChanged(const QString &text) // If we have GPS data for the location entered, add it. void MainTab::on_location_editingFinished() { - // if we have a location and no GPS data, look up the GPS data; - // but if the GPS data was intentionally cleared then don't - if (!currentTrip && - !same_string(displayed_dive.location, "") && - ui.coordinates->text().trimmed().isEmpty() && - !(editMode == DIVE && dive_has_gps_location(current_dive))) { - struct dive *dive; - int i = 0; - for_each_dive (i, dive) { - if (same_string(displayed_dive.location, dive->location) && - (dive->latitude.udeg || dive->longitude.udeg)) { - displayed_dive.latitude = dive->latitude; - displayed_dive.longitude = dive->longitude; - MainWindow::instance()->globe()->reload(); - updateGpsCoordinates(); - break; - } - } - } + // find the dive site or create it + const char *name = copy_string(qPrintable(ui.location->text())); + uint32_t uuid = get_dive_site_uuid_by_name(name, NULL); + if (!uuid) + uuid = create_dive_site(name); + displayed_dive.dive_site_uuid = uuid; + free((void*)name); } void MainTab::on_suit_textChanged(const QString &text) @@ -1219,6 +1291,7 @@ void MainTab::on_notes_textChanged() markChangedWidget(ui.notes); } +#if 0 // we'll need something like this for the dive site management void MainTab::on_coordinates_textChanged(const QString &text) { if (editMode == IGNORE || acceptingEdit == true) @@ -1235,6 +1308,7 @@ void MainTab::on_coordinates_textChanged(const QString &text) ui.coordinates->setPalette(p); // marks things red } } +#endif void MainTab::on_rating_valueChanged(int value) { @@ -1286,6 +1360,7 @@ void MainTab::editWeightWidget(const QModelIndex &index) ui.weights->edit(index); } +#if 0 // we'll need this for dive sites void MainTab::updateCoordinatesText(qreal lat, qreal lon) { int ulat = rint(lat * 1000000); @@ -1298,9 +1373,16 @@ void MainTab::updateGpsCoordinates() if (editMode == NONE) enableEdition(); - ui.coordinates->setText(printGPSCoords(displayed_dive.latitude.udeg, displayed_dive.longitude.udeg)); - ui.coordinates->setModified(displayed_dive.latitude.udeg || displayed_dive.longitude.udeg); + struct dive_site *ds = get_dive_site_by_uuid(displayed_dive.dive_site_uuid); + if (ds && dive_site_has_gps_location(ds)) { + ui.coordinates->setText(printGPSCoords(ds->latitude.udeg, ds->longitude.udeg)); + ui.coordinates->setModified(true); + } else if (!ui.coordinates->text().isEmpty()) { + ui.coordinates->setModified(true); + ui.coordinates->clear(); + } } +#endif void MainTab::escDetected() { @@ -1332,7 +1414,6 @@ void MainTab::showAndTriggerEditSelective(struct dive_components what) // take the data in our copyPasteDive and apply it to selected dives enableEdition(); copyPaste = true; - SHOW_SELECTIVE(location); SHOW_SELECTIVE(buddy); SHOW_SELECTIVE(divemaster); SHOW_SELECTIVE(suit); @@ -1347,8 +1428,8 @@ void MainTab::showAndTriggerEditSelective(struct dive_components what) ui.rating->setCurrentStars(displayed_dive.rating); if (what.visibility) ui.visibility->setCurrentStars(displayed_dive.visibility); - if (what.gps) - updateGpsCoordinates(); + if (what.divesite) + ui.location->setText(get_dive_location(&displayed_dive)); if (what.tags) { char buf[1024]; taglist_get_tagstring(displayed_dive.tag_list, buf, 1024); |