From a117428ff46b15f458cabf29c250b2e7d70cc31d Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Mon, 19 May 2014 14:39:34 +0900 Subject: Add ability to make a dive computer the first dive computer of a dive If a dive has multiple dive computers we enable a special context menu when the user right-clicks on the dive computer name AND is not already showing the first dive computer. In that case we offer to make the currently shown dive computer the first one. Signed-off-by: Dirk Hohndel --- dive.c | 20 +++++++++++++++++ dive.h | 3 +++ qt-ui/profile/profilewidget2.cpp | 46 ++++++++++++++++++++++++++++++++++++++-- qt-ui/profile/profilewidget2.h | 1 + 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/dive.c b/dive.c index 80aa555ee..82d44b41b 100644 --- a/dive.c +++ b/dive.c @@ -19,6 +19,26 @@ static const char *default_tags[] = { QT_TRANSLATE_NOOP("gettextFromC", "deco") }; +void make_first_dc() +{ + struct divecomputer *dc = ¤t_dive->dc; + struct divecomputer *newdc = malloc(sizeof(*newdc)); + struct divecomputer *cur_dc = current_dc; /* needs to be in a local variable so the macro isn't re-executed */ + + /* skip the current DC in the linked list */ + while (dc && dc->next != cur_dc) + dc = dc->next; + if (!dc) { + fprintf(stderr, "data inconsistent: can't find the current DC"); + return; + } + dc->next = cur_dc->next; + *newdc = current_dive->dc; + current_dive->dc = *cur_dc; + current_dive->dc.next = newdc; + free(cur_dc); +} + void add_event(struct divecomputer *dc, int time, int type, int flags, int value, const char *name) { struct event *ev, **p; diff --git a/dive.h b/dive.h index d371b1508..98238970f 100644 --- a/dive.h +++ b/dive.h @@ -361,6 +361,7 @@ struct dive_table { extern struct dive_table dive_table; extern int selected_dive; +extern unsigned int dc_number; #define current_dive (get_dive(selected_dive)) #define current_dc (get_dive_dc(current_dive, dc_number)) @@ -405,6 +406,8 @@ static inline struct divecomputer *get_dive_dc(struct dive *dive, int nr) return dc; } +extern void make_first_dc(void); + /* * Iterate over each dive, with the first parameter being the index * iterator variable, and the second one being the dive one. diff --git a/qt-ui/profile/profilewidget2.cpp b/qt-ui/profile/profilewidget2.cpp index c1e4fcab3..097f03d52 100644 --- a/qt-ui/profile/profilewidget2.cpp +++ b/qt-ui/profile/profilewidget2.cpp @@ -107,6 +107,9 @@ ProfileWidget2::ProfileWidget2(QWidget *parent) : QGraphicsView(parent), #endif } +#define SUBSURFACE_OBJ_DATA 1 +#define SUBSURFACE_OBJ_DC_TEXT 0x42 + void ProfileWidget2::addItemsToScene() { scene()->addItem(background); @@ -120,6 +123,11 @@ void ProfileWidget2::addItemsToScene() scene()->addItem(temperatureItem); scene()->addItem(gasPressureItem); scene()->addItem(meanDepth); + // I cannot seem to figure out if an object that I find with itemAt() on the scene + // is the object I am looking for - my guess is there's a simple way in Qt to do that + // but nothing I tried worked. + // so instead this adds a special magic key/value pair to the object to mark it + diveComputerText->setData(SUBSURFACE_OBJ_DATA, SUBSURFACE_OBJ_DC_TEXT); scene()->addItem(diveComputerText); scene()->addItem(diveCeiling); scene()->addItem(reportedCeiling); @@ -692,9 +700,32 @@ extern int evn_used; void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event) { + QMenu m; + bool isDCName = false; if (selected_dive == -1) return; - QMenu m; + // figure out if we are ontop of the dive computer name in the profile + QGraphicsItem *sceneItem = itemAt(mapFromGlobal(event->globalPos())); + if (sceneItem) { + QGraphicsItem *parentItem = sceneItem; + while (parentItem) { + if (parentItem->data(SUBSURFACE_OBJ_DATA) == SUBSURFACE_OBJ_DC_TEXT) { + isDCName = true; + break; + } + parentItem = parentItem->parentItem(); + } + if (isDCName) { + if (dc_number == 0) + return; + // create menu to show when right clicking on dive computer name + m.addAction(tr("Make first divecomputer"), this, SLOT(makeFirstDC())); + m.exec(event->globalPos()); + // don't show the regular profile context menu + return; + } + } + // create the profile context menu QMenu *gasChange = m.addMenu(tr("Add Gas Change")); GasSelectionModel *model = GasSelectionModel::instance(); model->repopulate(); @@ -708,7 +739,6 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event) } QAction *action = m.addAction(tr("Add Bookmark"), this, SLOT(addBookmark())); action->setData(event->globalPos()); - QGraphicsItem *sceneItem = itemAt(mapFromGlobal(event->globalPos())); if (DiveEventItem *item = dynamic_cast(sceneItem)) { action = new QAction(&m); action->setText(tr("Remove Event")); @@ -742,6 +772,18 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event) m.exec(event->globalPos()); } +void ProfileWidget2::makeFirstDC() +{ + make_first_dc(); + mark_divelist_changed(true); + // this is now the first DC, so we need to redraw the profile and refresh the dive list + // (and no, it's not just enough to rewrite the text - the first DC is special so values in the + // dive list may change). + // As a side benefit, this returns focus to the dive list. + dc_number = 0; + MainWindow::instance()->refreshDisplay(); +} + void ProfileWidget2::hideEvents() { QAction *action = qobject_cast(sender()); diff --git a/qt-ui/profile/profilewidget2.h b/qt-ui/profile/profilewidget2.h index d00cb26c1..4517cc144 100644 --- a/qt-ui/profile/profilewidget2.h +++ b/qt-ui/profile/profilewidget2.h @@ -80,6 +80,7 @@ slots: // Necessary to call from QAction's signals. void unhideEvents(); void removeEvent(); void editName(); + void makeFirstDC(); protected: virtual void resizeEvent(QResizeEvent *event); -- cgit v1.2.3-70-g09d2