Remember Trip Selection.

This patch remembers the trip selection across the Dive Tree Model.
It's a tiny bit big because we used to have a variable 'selected
trips' that's now calculed dynamically - this is more future proof.

This is a start of Un-cluttering the view ( for 4.1 I hope to reduce the
code in this class to nearly a half. )

Fixes #303

Signed-off-by: Tomaz Canabrava <tcanabrava@kde.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Tomaz Canabrava 2013-11-26 15:44:18 -02:00 committed by Dirk Hohndel
parent e91a1fc26c
commit e175b1d1ab
6 changed files with 76 additions and 24 deletions

View file

@ -47,8 +47,6 @@ DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelec
searchBox->hide(); searchBox->hide();
connect(showSearchBox, SIGNAL(triggered(bool)), this, SLOT(showSearchEdit())); connect(showSearchBox, SIGNAL(triggered(bool)), this, SLOT(showSearchEdit()));
connect(searchBox, SIGNAL(textChanged(QString)), model, SLOT(setFilterFixedString(QString))); connect(searchBox, SIGNAL(textChanged(QString)), model, SLOT(setFilterFixedString(QString)));
selectedTrips.clear();
setupUi(); setupUi();
} }
@ -133,24 +131,66 @@ void DiveListView::rememberSelection()
continue; continue;
struct dive *d = (struct dive *) index.data(DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *d = (struct dive *) index.data(DiveTripModel::DIVE_ROLE).value<void*>();
if (d) if (d)
selectedDives.push_front(get_divenr(d)); selectedDives.insert(d->divetrip, get_divenr(d));
} }
} }
void DiveListView::restoreSelection() void DiveListView::restoreSelection()
{ {
unselectDives(); unselectDives();
selectedTrips.clear(); // I wish we didn't lose those... Q_FOREACH(dive_trip_t *trip, selectedDives.keys()){
Q_FOREACH(int i, selectedDives) { QList<int> divesOnTrip = getDivesInTrip(trip);
selectDive(i); QList<int> selectedDivesOnTrip = selectedDives.values(trip);
// Trip was not selected, let's select single-dives.
if (trip == NULL || divesOnTrip.count() != selectedDivesOnTrip.count()){
Q_FOREACH(int i, selectedDivesOnTrip){
selectDive(i);
}
}else{
selectTrip(trip);
Q_FOREACH(int i, selectedDivesOnTrip){
selectDive(i);
}
}
} }
} }
void DiveListView::selectTrip ( dive_trip_t* trip )
{
if (!trip)
return;
QSortFilterProxyModel *m = qobject_cast<QSortFilterProxyModel*>(model());
QModelIndexList match = m->match(m->index(0,0), DiveTripModel::TRIP_ROLE, QVariant::fromValue<void*>(trip), 2, Qt::MatchRecursive);
QItemSelectionModel::SelectionFlags flags;
if (!match.count())
return;
QModelIndex idx = match.first();
flags = QItemSelectionModel::Select;
flags |= QItemSelectionModel::Rows;
selectionModel()->select(idx, flags);
expand(idx);
}
void DiveListView::unselectDives() void DiveListView::unselectDives()
{ {
selectionModel()->clearSelection(); selectionModel()->clearSelection();
} }
QList< dive_trip_t* > DiveListView::selectedTrips()
{
QModelIndexList indexes = selectionModel()->selectedRows();
QList<dive_trip_t*> ret;
Q_FOREACH(const QModelIndex& index, indexes){
dive_trip_t *trip = static_cast<dive_trip_t*>(index.data(DiveTripModel::TRIP_ROLE).value<void*>());
if(!trip)
continue;
ret.push_back(trip);
}
return ret;
}
void DiveListView::selectDive(int i, bool scrollto, bool toggle) void DiveListView::selectDive(int i, bool scrollto, bool toggle)
{ {
if( i == -1) if( i == -1)
@ -347,8 +387,6 @@ void DiveListView::selectionChanged(const QItemSelection& selected, const QItemS
if (!dive) { // it's a trip! if (!dive) { // it's a trip!
if (model->rowCount(index)) { if (model->rowCount(index)) {
struct dive *child = (struct dive*) model->data(index.child(0,0), DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *child = (struct dive*) model->data(index.child(0,0), DiveTripModel::DIVE_ROLE).value<void*>();
if (child && child->divetrip)
selectedTrips.remove(child->divetrip);
while (child) { while (child) {
deselect_dive(get_divenr(child)); deselect_dive(get_divenr(child));
child = child->next; child = child->next;
@ -368,8 +406,6 @@ void DiveListView::selectionChanged(const QItemSelection& selected, const QItemS
if (model->rowCount(index)) { if (model->rowCount(index)) {
QItemSelection selection; QItemSelection selection;
struct dive *child = (struct dive*) model->data(index.child(0,0), DiveTripModel::DIVE_ROLE).value<void*>(); struct dive *child = (struct dive*) model->data(index.child(0,0), DiveTripModel::DIVE_ROLE).value<void*>();
if (child && child->divetrip)
selectedTrips.insert(child->divetrip);
while (child) { while (child) {
select_dive(get_divenr(child)); select_dive(get_divenr(child));
child = child->next; child = child->next;

View file

@ -29,8 +29,7 @@ public:
void rememberSelection(); void rememberSelection();
void restoreSelection(); void restoreSelection();
void contextMenuEvent(QContextMenuEvent *event); void contextMenuEvent(QContextMenuEvent *event);
QSet<dive_trip_t *> selectedTrips; QList<dive_trip_t*> selectedTrips();
public slots: public slots:
void toggleColumnVisibilityByIndex(); void toggleColumnVisibilityByIndex();
void reloadHeaderActions(); void reloadHeaderActions();
@ -55,17 +54,20 @@ signals:
private: private:
bool mouseClickSelection; bool mouseClickSelection;
QList<int> expandedRows; QList<int> expandedRows;
QList<int> selectedDives;
int sortColumn; int sortColumn;
Qt::SortOrder currentOrder; Qt::SortOrder currentOrder;
DiveTripModel::Layout currentLayout; DiveTripModel::Layout currentLayout;
QLineEdit *searchBox; QLineEdit *searchBox;
QModelIndex contextMenuIndex; QModelIndex contextMenuIndex;
/* if dive_trip_t is null, there's no problem. */
QMultiHash<dive_trip_t *, int> selectedDives;
void merge_trip(const QModelIndex &a, const int offset); void merge_trip(const QModelIndex &a, const int offset);
void setupUi(); void setupUi();
void backupExpandedRows(); void backupExpandedRows();
void restoreExpandedRows(); void restoreExpandedRows();
int lastVisibleColumn(); int lastVisibleColumn();
void selectTrip ( dive_trip_t* trip );
}; };
#endif // DIVELISTVIEW_H #endif // DIVELISTVIEW_H

View file

@ -129,7 +129,7 @@ void MainTab::enableEdition(EditMode newEditMode)
ui.notesButtonBox->show(); ui.notesButtonBox->show();
ui.equipmentButtonBox->show(); ui.equipmentButtonBox->show();
if (mainWindow() && mainWindow()->dive_list()->selectedTrips.count() == 1) { if (mainWindow() && mainWindow()->dive_list()->selectedTrips().count() == 1) {
// we are editing trip location and notes // we are editing trip location and notes
ui.diveNotesMessage->setText(tr("This trip is being edited. Select Save or Cancel when done.")); ui.diveNotesMessage->setText(tr("This trip is being edited. Select Save or Cancel when done."));
ui.diveNotesMessage->animatedShow(); ui.diveNotesMessage->animatedShow();
@ -292,7 +292,7 @@ void MainTab::updateDiveInfo(int dive)
if (d) { if (d) {
updateGpsCoordinates(d); updateGpsCoordinates(d);
ui.dateTimeEdit->setDateTime(QDateTime::fromTime_t(d->when - gettimezoneoffset())); ui.dateTimeEdit->setDateTime(QDateTime::fromTime_t(d->when - gettimezoneoffset()));
if (mainWindow() && mainWindow()->dive_list()->selectedTrips.count() == 1) { if (mainWindow() && mainWindow()->dive_list()->selectedTrips().count() == 1) {
setTabText(0, tr("Trip Notes")); setTabText(0, tr("Trip Notes"));
// only use trip relevant fields // only use trip relevant fields
ui.coordinates->setVisible(false); ui.coordinates->setVisible(false);
@ -313,7 +313,7 @@ void MainTab::updateDiveInfo(int dive)
ui.airtemp->setVisible(false); ui.airtemp->setVisible(false);
ui.watertemp->setVisible(false); ui.watertemp->setVisible(false);
// rename the remaining fields and fill data from selected trip // rename the remaining fields and fill data from selected trip
dive_trip_t *currentTrip = *mainWindow()->dive_list()->selectedTrips.begin(); dive_trip_t *currentTrip = *mainWindow()->dive_list()->selectedTrips().begin();
ui.LocationLabel->setText(tr("Trip Location")); ui.LocationLabel->setText(tr("Trip Location"));
ui.location->setText(currentTrip->location); ui.location->setText(currentTrip->location);
ui.NotesLabel->setText(tr("Trip Notes")); ui.NotesLabel->setText(tr("Trip Notes"));
@ -472,7 +472,7 @@ void MainTab::acceptChanges()
ui.notesButtonBox->hide(); ui.notesButtonBox->hide();
ui.equipmentButtonBox->hide(); ui.equipmentButtonBox->hide();
/* now figure out if things have changed */ /* now figure out if things have changed */
if (mainWindow() && mainWindow()->dive_list()->selectedTrips.count() == 1) { if (mainWindow() && mainWindow()->dive_list()->selectedTrips().count() == 1) {
if (notesBackup[NULL].notes != ui.notes->toPlainText() || if (notesBackup[NULL].notes != ui.notes->toPlainText() ||
notesBackup[NULL].location != ui.location->text()) notesBackup[NULL].location != ui.location->text())
mark_divelist_changed(TRUE); mark_divelist_changed(TRUE);
@ -585,7 +585,7 @@ void MainTab::rejectChanges()
tabBar()->setTabIcon(1, QIcon()); // Equipment tabBar()->setTabIcon(1, QIcon()); // Equipment
mainWindow()->dive_list()->setEnabled(true); mainWindow()->dive_list()->setEnabled(true);
if (mainWindow() && mainWindow()->dive_list()->selectedTrips.count() == 1){ if (mainWindow() && mainWindow()->dive_list()->selectedTrips().count() == 1){
ui.notes->setText(notesBackup[NULL].notes ); ui.notes->setText(notesBackup[NULL].notes );
ui.location->setText(notesBackup[NULL].location); ui.location->setText(notesBackup[NULL].location);
} else { } else {
@ -749,9 +749,9 @@ void MainTab::on_location_textChanged(const QString& text)
{ {
if (editMode == NONE) if (editMode == NONE)
return; return;
if (editMode == TRIP && mainWindow() && mainWindow()->dive_list()->selectedTrips.count() == 1) { if (editMode == TRIP && mainWindow() && mainWindow()->dive_list()->selectedTrips().count() == 1) {
// we are editing a trip // we are editing a trip
dive_trip_t *currentTrip = *mainWindow()->dive_list()->selectedTrips.begin(); dive_trip_t *currentTrip = *mainWindow()->dive_list()->selectedTrips().begin();
EDIT_TEXT(currentTrip->location, text); EDIT_TEXT(currentTrip->location, text);
} else if (editMode == DIVE || editMode == ADD){ } else if (editMode == DIVE || editMode == ADD){
if (!ui.coordinates->isModified() || if (!ui.coordinates->isModified() ||
@ -787,9 +787,9 @@ void MainTab::on_notes_textChanged()
{ {
if (editMode == NONE) if (editMode == NONE)
return; return;
if (editMode == TRIP && mainWindow() && mainWindow()->dive_list()->selectedTrips.count() == 1) { if (editMode == TRIP && mainWindow() && mainWindow()->dive_list()->selectedTrips().count() == 1) {
// we are editing a trip // we are editing a trip
dive_trip_t *currentTrip = *mainWindow()->dive_list()->selectedTrips.begin(); dive_trip_t *currentTrip = *mainWindow()->dive_list()->selectedTrips().begin();
EDIT_TEXT(currentTrip->notes, ui.notes->toPlainText()); EDIT_TEXT(currentTrip->notes, ui.notes->toPlainText());
} else if (editMode == DIVE || editMode == ADD) { } else if (editMode == DIVE || editMode == ADD) {
EDIT_SELECTED_DIVES( EDIT_TEXT(mydive->notes, ui.notes->toPlainText()) ); EDIT_SELECTED_DIVES( EDIT_TEXT(mydive->notes, ui.notes->toPlainText()) );

View file

@ -149,7 +149,7 @@ void MainWindow::on_actionClose_triggered()
while (dive_table.nr) while (dive_table.nr)
delete_single_dive(0); delete_single_dive(0);
dive_list()->selectedTrips.clear(); dive_list()->clearSelection();
/* clear the selection and the statistics */ /* clear the selection and the statistics */
selected_dive = -1; selected_dive = -1;

View file

@ -145,5 +145,17 @@ bool gpsHasChanged(struct dive *dive, struct dive *master, const QString& gps_te
dive->latitude.udeg = latudeg; dive->latitude.udeg = latudeg;
dive->longitude.udeg = longudeg; dive->longitude.udeg = longudeg;
return true; return true;
} }
QList< int > getDivesInTrip ( dive_trip_t* trip )
{
QList<int> ret;
for(int i = 0; i < dive_table.nr; i++){
struct dive *d = get_dive(i);
if (d->divetrip == trip){
ret.push_back(get_divenr(d));
}
}
return ret;
}

View file

@ -5,6 +5,7 @@
#include <QString> #include <QString>
#include <stdint.h> #include <stdint.h>
#include "dive.h" #include "dive.h"
#include "divelist.h"
#include <QTranslator> #include <QTranslator>
// global pointers for our translation // global pointers for our translation
@ -40,4 +41,5 @@ public:
QString weight_string(int weight_in_grams); QString weight_string(int weight_in_grams);
bool gpsHasChanged(struct dive* dive, struct dive *master, const QString &gps_text); bool gpsHasChanged(struct dive* dive, struct dive *master, const QString &gps_text);
QList<int> getDivesInTrip(dive_trip_t *trip);
#endif // QTHELPER_H #endif // QTHELPER_H