Uffs, so: This patch series completely rewrites the LocationManagement *lineedit + combobox* that we used to have.
It is stetically identical to the old one, everything beneath the UI has changed. it currently *doesn't* works ( the line edit + selection *works* , but it doesn't *sets* the dive site ) - I need a bit of help on that as my time just runned out. but basically: after a dive site is choosed on the new location line edit, you have: currentDiveSiteUuid and text() if location.currentDiveSiteUuid() == 1, this means that we need to create a new dive site and set the text() as dive_site.name if location.currentDiveSiteUuid() > 1, it's an existing dive site. just set it on the dive. Please test: I'm doing this in berseker mode for two days trying to remove the old system that's completely broken ( because we where abusing QCompleter, it works very well in all other cases that we use it. )
From 5b20caf90e5e9cef91d84a3a6c552159c681b503 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 21 Sep 2015 14:01:58 -0300 Subject: [PATCH 01/14] Skeleton of the new LocationCombobox This is the bare minimum skeleton of the new Completer for the DiveSite management. nothing works yet, nothing is hoocked up yet. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 135 ++++++++++++++++++++++++++++++++++++++++++ qt-ui/locationinformation.h | 40 +++++++++++++ qt-ui/maintab.cpp | 1 + qt-ui/maintab.ui | 7 ++- 4 files changed, 182 insertions(+), 1 deletion(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index bf83004..096b616 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -317,3 +317,138 @@ void LocationInformationWidget::reverseGeocode() geoLookup->lookup(&displayed_dive_site); updateLabels(); } + +DiveLocationFilterProxyModel::DiveLocationFilterProxyModel(QObject *parent) +{ + +} + +DiveLocationLineEdit *location_line_edit = 0; + +bool DiveLocationFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const +{ + if(source_row == 0 || source_row == 1) + return true; + + QString sourceString = sourceModel()->index(source_row, DiveLocationModel::NAME).data(Qt::DisplayRole).toString(); + return sourceString.toLower().startsWith(location_line_edit->text().toLower()); +} + +DiveLocationModel::DiveLocationModel(QObject *o) +{ + resetModel(); +} + +void DiveLocationModel::resetModel() +{ + beginResetModel(); + qDebug() << "Dive site table size" <<dive_site_table.nr; + endResetModel(); +} + +QVariant DiveLocationModel::data(const QModelIndex& index, int role) const +{ + if(index.row() <= 1) { // two special cases. + switch(role) { + case Qt::DisplayRole : return new_ds_value[index.row()]; + case Qt::ToolTipRole : return "Create a new dive site"; + } + } + + // The dive sites are -2 because of the first two items. + struct dive_site *ds = get_dive_site(index.row() - 2); + switch(role) { + case Qt::EditRole: + case Qt::DisplayRole : + switch(index.column()) { + case UUID: return ds->uuid; + case NAME: return ds->name; + case LATITUDE: return ds->latitude.udeg; + case LONGITUDE: return ds->longitude.udeg; + case DESCRIPTION: return ds->description; + case NOTES: return ds->name; + } + break; + case Qt::DecorationRole : { + if (dive_site_has_gps_location(ds)) + return QIcon(":geocode"); + } + } + return QVariant(); +} + +int DiveLocationModel::columnCount(const QModelIndex& parent) const +{ + return COLUMNS; +} + +int DiveLocationModel::rowCount(const QModelIndex& parent) const +{ + return dive_site_table.nr + 2; +} + + +bool DiveLocationModel::setData(const QModelIndex& index, const QVariant& value, int role) +{ + if(!index.isValid()) + return false; + if (index.row() > 1) + return false; + + new_ds_value[index.row()] = value.toString(); + + dataChanged(index, index); + return true; +} + +DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) +{ + proxy = new DiveLocationFilterProxyModel(); + model = new DiveLocationModel(); + view = new DiveLocationListView(); + + proxy->setSourceModel(model); + view->setModel(model); + + connect(this, &QLineEdit::textEdited, this, &DiveLocationLineEdit::setTemporaryDiveSiteName); + + //HACK: + /* This is being show currently just to test. */ + qDebug() << "AAAAAAH"; + qDebug() << model->rowCount() << model->columnCount(); + view->show(); +} + +void DiveLocationLineEdit::refreshDiveSiteCache() +{ + model->resetModel(); +} + +static struct dive_site *get_dive_site_name_start_which_str(const QString& str) { + struct dive_site *ds; + int i; + for_each_dive_site(i,ds) { + QString dsName(ds->name); + if (dsName.startsWith(str)) { + return ds; + } + } + return NULL; +} + +void DiveLocationLineEdit::setTemporaryDiveSiteName(const QString& s) +{ + QModelIndex i0 = model->index(0, DiveLocationModel::NAME); + model->setData(i0, text()); + + struct dive_site *ds = get_dive_site_name_start_which_str(text()); + QModelIndex i1 = model->index(1, DiveLocationModel::NAME); + model->setData(i1, ds ? ds->name : INVALID_DIVE_SITE_NAME); +} + +DiveLocationListView::DiveLocationListView(QWidget *parent) +{ + +} + + diff --git a/qt-ui/locationinformation.h b/qt-ui/locationinformation.h index 080e013..18c3dc7 100644 --- a/qt-ui/locationinformation.h +++ b/qt-ui/locationinformation.h @@ -4,6 +4,7 @@ #include "ui_locationInformation.h" #include <stdint.h> #include <QAbstractListModel> +#include <QSortFilterProxyModel> class LocationInformationWidget : public QGroupBox { Q_OBJECT @@ -58,4 +59,43 @@ private: uint32_t last_uuid; }; +class DiveLocationFilterProxyModel : public QSortFilterProxyModel { + Q_OBJECT +public: + DiveLocationFilterProxyModel(QObject *parent = 0); + virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; +}; + +class DiveLocationModel : public QAbstractTableModel { + Q_OBJECT +public: + enum columns{UUID, NAME, LATITUDE, LONGITUDE, DESCRIPTION, NOTES, COLUMNS}; + DiveLocationModel(QObject *o = 0); + void resetModel(); + QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; + int rowCount(const QModelIndex& parent = QModelIndex()) const; + int columnCount(const QModelIndex& parent = QModelIndex()) const; + bool setData(const QModelIndex& index, const QVariant& value, int role = Qt::EditRole); +private: + QString new_ds_value[2]; +}; + +class DiveLocationListView : public QListView { + Q_OBJECT +public: + DiveLocationListView(QWidget *parent = 0); +}; + +class DiveLocationLineEdit : public QLineEdit { + Q_OBJECT +public: + DiveLocationLineEdit(QWidget *parent =0 ); + void refreshDiveSiteCache(); + void setTemporaryDiveSiteName(const QString& s); +private: + DiveLocationFilterProxyModel *proxy; + DiveLocationModel *model; + DiveLocationListView *view; +}; + #endif diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp index 2e4d3fc..2499906 100644 --- a/qt-ui/maintab.cpp +++ b/qt-ui/maintab.cpp @@ -480,6 +480,7 @@ void MainTab::updateDiveInfo(bool clear) #endif } + ui.location->refreshDiveSiteCache(); EditMode rememberEM = editMode; // don't execute this while adding / planning a dive if (editMode == ADD || editMode == MANUALLY_ADDED_DIVE || MainWindow::instance()->graphics()->isPlanner()) diff --git a/qt-ui/maintab.ui b/qt-ui/maintab.ui index 23bacbf..28c9645 100644 --- a/qt-ui/maintab.ui +++ b/qt-ui/maintab.ui @@ -188,7 +188,7 @@ <number>2</number> </property> <item> - <widget class="QLineEdit" name="location"/> + <widget class="DiveLocationLineEdit" name="location"/> </item> <item> <widget class="QToolButton" name="editDiveSiteButton"> @@ -1131,6 +1131,11 @@ <header>qtwaitingspinner.h</header> <container>1</container> </customwidget> + <customwidget> + <class>DiveLocationLineEdit</class> + <extends>QLineEdit</extends> + <header>locationinformation.h</header> + </customwidget> </customwidgets> <tabstops> <tabstop>dateEdit</tabstop> -- 2.5.3
From c385548138158333c2117cfe9f9169c0c328befe Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 21 Sep 2015 15:04:52 -0300 Subject: [PATCH 02/14] Stabilize the location model/proxy model. Since I removed the old location edit from the ui, I also need to remove a bit of code from the ui that was calling it. fix a few crashes regarding the old location edit. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 34 +++++++++++++++++++++++++--------- qt-ui/locationinformation.h | 1 + qt-ui/maintab.cpp | 31 +++++++------------------------ 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 096b616..3bc5081 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -7,6 +7,7 @@ #include "filtermodels.h" #include "divelocationmodel.h" #include "divesitehelpers.h" +#include "modeldelegates.h" #include <QDebug> #include <QShowEvent> @@ -327,13 +328,19 @@ DiveLocationLineEdit *location_line_edit = 0; bool DiveLocationFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const { - if(source_row == 0 || source_row == 1) + if(source_row == 0) return true; QString sourceString = sourceModel()->index(source_row, DiveLocationModel::NAME).data(Qt::DisplayRole).toString(); return sourceString.toLower().startsWith(location_line_edit->text().toLower()); } +bool DiveLocationFilterProxyModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const +{ + return source_left.data().toString() <= source_right.data().toString(); +} + + DiveLocationModel::DiveLocationModel(QObject *o) { resetModel(); @@ -342,7 +349,6 @@ DiveLocationModel::DiveLocationModel(QObject *o) void DiveLocationModel::resetModel() { beginResetModel(); - qDebug() << "Dive site table size" <<dive_site_table.nr; endResetModel(); } @@ -403,18 +409,20 @@ bool DiveLocationModel::setData(const QModelIndex& index, const QVariant& value, DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) { + location_line_edit = this; proxy = new DiveLocationFilterProxyModel(); model = new DiveLocationModel(); view = new DiveLocationListView(); proxy->setSourceModel(model); - view->setModel(model); - + proxy->setFilterKeyColumn(DiveLocationModel::NAME); + view->setModel(proxy); + view->setModelColumn(DiveLocationModel::NAME); + view->setItemDelegate(new LocationFilterDelegate()); connect(this, &QLineEdit::textEdited, this, &DiveLocationLineEdit::setTemporaryDiveSiteName); //HACK: /* This is being show currently just to test. */ - qDebug() << "AAAAAAH"; qDebug() << model->rowCount() << model->columnCount(); view->show(); } @@ -429,7 +437,7 @@ static struct dive_site *get_dive_site_name_start_which_str(const QString& str) int i; for_each_dive_site(i,ds) { QString dsName(ds->name); - if (dsName.startsWith(str)) { + if (dsName.toLower().startsWith(str.toLower())) { return ds; } } @@ -439,11 +447,19 @@ static struct dive_site *get_dive_site_name_start_which_str(const QString& str) void DiveLocationLineEdit::setTemporaryDiveSiteName(const QString& s) { QModelIndex i0 = model->index(0, DiveLocationModel::NAME); + QModelIndex i1 = model->index(1, DiveLocationModel::NAME); model->setData(i0, text()); - struct dive_site *ds = get_dive_site_name_start_which_str(text()); - QModelIndex i1 = model->index(1, DiveLocationModel::NAME); - model->setData(i1, ds ? ds->name : INVALID_DIVE_SITE_NAME); + QString i1_name = INVALID_DIVE_SITE_NAME; + if (struct dive_site *ds = get_dive_site_name_start_which_str(text())) { + const QString orig_name = QString(ds->name).toLower(); + const QString new_name = text().toLower(); + if (new_name != orig_name) + i1_name = QString(ds->name); + } + + model->setData(i1, i1_name ); + proxy->invalidate(); } DiveLocationListView::DiveLocationListView(QWidget *parent) diff --git a/qt-ui/locationinformation.h b/qt-ui/locationinformation.h index 18c3dc7..16d5a3e 100644 --- a/qt-ui/locationinformation.h +++ b/qt-ui/locationinformation.h @@ -64,6 +64,7 @@ class DiveLocationFilterProxyModel : public QSortFilterProxyModel { public: DiveLocationFilterProxyModel(QObject *parent = 0); virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const; + virtual bool lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const; }; class DiveLocationModel : public QAbstractTableModel { diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp index 2499906..51df81d 100644 --- a/qt-ui/maintab.cpp +++ b/qt-ui/maintab.cpp @@ -55,23 +55,6 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent), ui.extraData->setModel(extraDataModel); closeMessage(); - QCompleter *completer = new QCompleter(); - QListView *completerListview = new QListView(); - LocationInformationModel::instance()->setFirstRowTextField(ui.location); - completer->setPopup(completerListview); - completer->setModel(LocationInformationModel::instance()); - completer->setCompletionColumn(LocationInformationModel::NAME); - completer->setCaseSensitivity(Qt::CaseInsensitive); - completerListview->setItemDelegate(new LocationFilterDelegate()); - completerListview->setMouseTracking(true); - locationManagementEditHelper = new LocationManagementEditHelper(); - connect(locationManagementEditHelper, &LocationManagementEditHelper::setLineEditText, - ui.location, &QLineEdit::setText); - completerListview->installEventFilter(locationManagementEditHelper); - connect(completerListview, &QAbstractItemView::clicked, - locationManagementEditHelper, &LocationManagementEditHelper::handleActivation); - - ui.location->setCompleter(completer); ui.editDiveSiteButton->setEnabled(true); connect(ui.editDiveSiteButton, SIGNAL(clicked()), MainWindow::instance(), SIGNAL(startDiveSiteEdit())); @@ -238,7 +221,7 @@ bool MainTab::eventFilter(QObject *obj, QEvent *ev) if (line) { if (ev->type() == QEvent::Resize) { - if (line->completer()->popup()->isVisible()) { + /*if (line->completer()->popup()->isVisible()) { QListView *choices = qobject_cast<QListView*>(line->completer()->popup()); QPoint p = ui.location->mapToGlobal(ui.location->pos()); choices->setGeometry( @@ -246,7 +229,9 @@ bool MainTab::eventFilter(QObject *obj, QEvent *ev) p.y() + 3, choices->geometry().width(), choices->geometry().height()); + } + */ } } return false; @@ -392,7 +377,7 @@ void MainTab::enableEdition(EditMode newEditMode) displayMessage(tr("Multiple dives are being edited.")); } else { displayMessage(tr("This dive is being edited.")); - locationManagementEditHelper->resetDiveSiteUuid(); + //locationManagementEditHelper->resetDiveSiteUuid(); } editMode = newEditMode != NONE ? newEditMode : DIVE; } @@ -474,10 +459,6 @@ void MainTab::updateDiveInfo(bool clear) { // I don't like this code here - but globe() wasn't initialized on the constructor. { - QListView *completerListview = qobject_cast<QListView*>(ui.location->completer()->popup()); -#ifndef NO_MARBLE - connect(completerListview, SIGNAL(entered(QModelIndex)), GlobeGPS::instance(), SLOT(centerOnIndex(QModelIndex)), Qt::UniqueConnection); -#endif } ui.location->refreshDiveSiteCache(); @@ -861,7 +842,9 @@ void MainTab::updateDisplayedDiveSite() const QString new_name = ui.location->text(); const QString orig_name = displayed_dive_site.name; const uint32_t orig_uuid = displayed_dive_site.uuid; - const uint32_t new_uuid = locationManagementEditHelper->diveSiteUuid(); + //TODO: FIX THIS + const uint32_t new_uuid = orig_uuid; + // locationManagementEditHelper->diveSiteUuid(); qDebug() << "Updating Displayed Dive Site"; -- 2.5.3
From 456d948653eaf61dc48cd488f2cb02b8797f3843 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 21 Sep 2015 15:15:11 -0300 Subject: [PATCH 03/14] Readd the 'plus' button on the delegate This was missing in the delegate - now it's prettier. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 3bc5081..7cccbc5 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -358,6 +358,7 @@ QVariant DiveLocationModel::data(const QModelIndex& index, int role) const switch(role) { case Qt::DisplayRole : return new_ds_value[index.row()]; case Qt::ToolTipRole : return "Create a new dive site"; + case Qt::DecorationRole : return QIcon(":plus"); } } -- 2.5.3
From 1a61f80b3af0e8eb0bf73c000f88f8ee0ebd1220 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 21 Sep 2015 16:08:58 -0300 Subject: [PATCH 04/14] Display the popup in the correct place The popup should be shown beneath the QLineEdit. this code here is shamelessy stolen from the QCompleter source code because I really didn't want to rethink the correct way of doing this. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 56 +++++++++++++++++++++++++++++++++++++++---- qt-ui/locationinformation.h | 3 +++ 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 7cccbc5..e343eed 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -14,6 +14,8 @@ #include <QItemSelectionModel> #include <qmessagebox.h> #include <cstdlib> +#include <QDesktopWidget> +#include <QScrollBar> LocationInformationWidget::LocationInformationWidget(QWidget *parent) : QGroupBox(parent), modified(false) { @@ -421,11 +423,6 @@ DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) view->setModelColumn(DiveLocationModel::NAME); view->setItemDelegate(new LocationFilterDelegate()); connect(this, &QLineEdit::textEdited, this, &DiveLocationLineEdit::setTemporaryDiveSiteName); - - //HACK: - /* This is being show currently just to test. */ - qDebug() << model->rowCount() << model->columnCount(); - view->show(); } void DiveLocationLineEdit::refreshDiveSiteCache() @@ -463,6 +460,55 @@ void DiveLocationLineEdit::setTemporaryDiveSiteName(const QString& s) proxy->invalidate(); } +void DiveLocationLineEdit::keyPressEvent(QKeyEvent *ev) +{ + QLineEdit::keyPressEvent(ev); + if(ev->key() != Qt::Key_Left && ev->key() != Qt::Key_Right && !view->isVisible()) { + qDebug() << "Showing popup"; + showPopup(); + } else { + qDebug() << "Not showing popup"; + } +} + +void DiveLocationLineEdit::showPopup() +{ + const QRect screen = QApplication::desktop()->availableGeometry(this); + const int maxVisibleItems = 5; + Qt::LayoutDirection dir = layoutDirection(); + QPoint pos; + int rh, w; + int h = (view->sizeHintForRow(0) * qMin(maxVisibleItems, view->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = view->horizontalScrollBar(); + if (hsb && hsb->isVisible()) + h += view->horizontalScrollBar()->sizeHint().height(); + + rh = height(); + pos = mapToGlobal(QPoint(0, height() - 2)); + w = width(); + + if (w > screen.width()) + w = screen.width(); + if ((pos.x() + w) > (screen.x() + screen.width())) + pos.setX(screen.x() + screen.width() - w); + if (pos.x() < screen.x()) + pos.setX(screen.x()); + + int top = pos.y() - rh - screen.top() + 2; + int bottom = screen.bottom() - pos.y(); + h = qMax(h, view->minimumHeight()); + if (h > bottom) { + h = qMin(qMax(top, bottom), h); + if (top > bottom) + pos.setY(pos.y() - h - rh + 2); + } + + view->setGeometry(pos.x(), pos.y(), w, h); + + if (!view->isVisible()) + view->show(); +} + DiveLocationListView::DiveLocationListView(QWidget *parent) { diff --git a/qt-ui/locationinformation.h b/qt-ui/locationinformation.h index 16d5a3e..b60c506 100644 --- a/qt-ui/locationinformation.h +++ b/qt-ui/locationinformation.h @@ -93,6 +93,9 @@ public: DiveLocationLineEdit(QWidget *parent =0 ); void refreshDiveSiteCache(); void setTemporaryDiveSiteName(const QString& s); +protected: + void keyPressEvent(QKeyEvent *ev); + void showPopup(); private: DiveLocationFilterProxyModel *proxy; DiveLocationModel *model; -- 2.5.3
From 7fef12110379d14751b72ef62e7722c9761d20e1 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 21 Sep 2015 16:51:39 -0300 Subject: [PATCH 05/14] Start to handle keypresses Keypress management is one of the main functions of the completer, so we must create an event filter and hook things properly. key esq / enter should close the popup ( and not let us with a popup open and no way to close it - it breaks X ) Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 46 ++++++++++++++++++++++++++++++++++++++----- qt-ui/locationinformation.h | 1 + 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index e343eed..5fcedee 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -419,12 +419,41 @@ DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) proxy->setSourceModel(model); proxy->setFilterKeyColumn(DiveLocationModel::NAME); + view->setModel(proxy); view->setModelColumn(DiveLocationModel::NAME); view->setItemDelegate(new LocationFilterDelegate()); + view->setEditTriggers(QAbstractItemView::NoEditTriggers); + view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + view->setSelectionBehavior(QAbstractItemView::SelectRows); + view->setSelectionMode(QAbstractItemView::SingleSelection); + view->setParent(0, Qt::Popup); + view->installEventFilter(this); + view->setFocusProxy(this); + connect(this, &QLineEdit::textEdited, this, &DiveLocationLineEdit::setTemporaryDiveSiteName); } +bool DiveLocationLineEdit::eventFilter(QObject *o, QEvent *e) +{ + if(e->type() == QEvent::KeyPress) { + QKeyEvent *keyEv = (QKeyEvent*) e; + + qDebug() << view->focusProxy()->objectName(); + + if (keyEv->key() == Qt::Key_Escape) { + view->hide(); + return true; + } + + if(keyEv->key() == Qt::Key_Return) { + view->hide(); + return false; + } + } + return false; +} + void DiveLocationLineEdit::refreshDiveSiteCache() { model->resetModel(); @@ -462,12 +491,17 @@ void DiveLocationLineEdit::setTemporaryDiveSiteName(const QString& s) void DiveLocationLineEdit::keyPressEvent(QKeyEvent *ev) { - QLineEdit::keyPressEvent(ev); - if(ev->key() != Qt::Key_Left && ev->key() != Qt::Key_Right && !view->isVisible()) { - qDebug() << "Showing popup"; + qDebug() << "Pressing key" << ev->key(); + if(ev->key() != Qt::Key_Left && + ev->key() != Qt::Key_Right && + ev->key() != Qt::Key_Escape && + ev->key() != Qt::Key_Return && + !view->isVisible()) { showPopup(); + } else if (ev->key() == Qt::Key_Escape) { + view->hide(); } else { - qDebug() << "Not showing popup"; + QLineEdit::keyPressEvent(ev); } } @@ -505,8 +539,10 @@ void DiveLocationLineEdit::showPopup() view->setGeometry(pos.x(), pos.y(), w, h); - if (!view->isVisible()) + if (!view->isVisible()) { view->show(); + view->setFocus(); + } } DiveLocationListView::DiveLocationListView(QWidget *parent) diff --git a/qt-ui/locationinformation.h b/qt-ui/locationinformation.h index b60c506..a1649d6 100644 --- a/qt-ui/locationinformation.h +++ b/qt-ui/locationinformation.h @@ -93,6 +93,7 @@ public: DiveLocationLineEdit(QWidget *parent =0 ); void refreshDiveSiteCache(); void setTemporaryDiveSiteName(const QString& s); + bool eventFilter(QObject*, QEvent*); protected: void keyPressEvent(QKeyEvent *ev); void showPopup(); -- 2.5.3
From 268abfa4d9bd3ae3e61b0e87e098dc503a478a1f Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 21 Sep 2015 17:11:59 -0300 Subject: [PATCH 06/14] Made it possible to keypress again click outside of the popup = closes it, also handles theme enter / return keys. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 5fcedee..06ecf2c 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -429,7 +429,7 @@ DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) view->setSelectionMode(QAbstractItemView::SingleSelection); view->setParent(0, Qt::Popup); view->installEventFilter(this); - view->setFocusProxy(this); + view->setFocusProxy(location_line_edit); connect(this, &QLineEdit::textEdited, this, &DiveLocationLineEdit::setTemporaryDiveSiteName); } @@ -437,6 +437,8 @@ DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) bool DiveLocationLineEdit::eventFilter(QObject *o, QEvent *e) { if(e->type() == QEvent::KeyPress) { + if (view->focusProxy() == this) qDebug() << "Ueh..."; + else qDebug() << "Nao eh..."; QKeyEvent *keyEv = (QKeyEvent*) e; qDebug() << view->focusProxy()->objectName(); @@ -446,11 +448,21 @@ bool DiveLocationLineEdit::eventFilter(QObject *o, QEvent *e) return true; } - if(keyEv->key() == Qt::Key_Return) { + if(keyEv->key() == Qt::Key_Return || keyEv->key() == Qt::Key_Enter) { view->hide(); return false; } + + event(e); + } + + if(e->type() == QEvent::MouseButtonPress ) { + if (!view->underMouse()) { + view->hide(); + return true; + } } + return false; } -- 2.5.3
From 8ac0bd0b2d8f24e62d911eef3cb18835c7cfc90f Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 21 Sep 2015 17:18:52 -0300 Subject: [PATCH 07/14] Handle dive_site activation Connect the view activated signal to send us the index. removing debug output that I forgot inside it. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 8 ++++++-- qt-ui/locationinformation.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 06ecf2c..b5d7d3a 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -432,13 +432,12 @@ DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) view->setFocusProxy(location_line_edit); connect(this, &QLineEdit::textEdited, this, &DiveLocationLineEdit::setTemporaryDiveSiteName); + connect(view, &QAbstractItemView::activated, this, &DiveLocationLineEdit::itemActivated); } bool DiveLocationLineEdit::eventFilter(QObject *o, QEvent *e) { if(e->type() == QEvent::KeyPress) { - if (view->focusProxy() == this) qDebug() << "Ueh..."; - else qDebug() << "Nao eh..."; QKeyEvent *keyEv = (QKeyEvent*) e; qDebug() << view->focusProxy()->objectName(); @@ -466,6 +465,11 @@ bool DiveLocationLineEdit::eventFilter(QObject *o, QEvent *e) return false; } +void DiveLocationLineEdit::itemActivated(const QModelIndex& index) +{ + qDebug() << "Activated" << index.data(); +} + void DiveLocationLineEdit::refreshDiveSiteCache() { model->resetModel(); diff --git a/qt-ui/locationinformation.h b/qt-ui/locationinformation.h index a1649d6..b52c03a 100644 --- a/qt-ui/locationinformation.h +++ b/qt-ui/locationinformation.h @@ -94,6 +94,7 @@ public: void refreshDiveSiteCache(); void setTemporaryDiveSiteName(const QString& s); bool eventFilter(QObject*, QEvent*); + void itemActivated(const QModelIndex& index); protected: void keyPressEvent(QKeyEvent *ev); void showPopup(); -- 2.5.3
From d6f7764dc470924b6cc3c95d13524f45c981ff61 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Mon, 21 Sep 2015 17:22:31 -0300 Subject: [PATCH 08/14] Fix correct size of the Popup Correct the popup visibility. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index b5d7d3a..31a22cc 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -508,16 +508,14 @@ void DiveLocationLineEdit::setTemporaryDiveSiteName(const QString& s) void DiveLocationLineEdit::keyPressEvent(QKeyEvent *ev) { qDebug() << "Pressing key" << ev->key(); + QLineEdit::keyPressEvent(ev); if(ev->key() != Qt::Key_Left && ev->key() != Qt::Key_Right && ev->key() != Qt::Key_Escape && - ev->key() != Qt::Key_Return && - !view->isVisible()) { + ev->key() != Qt::Key_Return ) { showPopup(); } else if (ev->key() == Qt::Key_Escape) { view->hide(); - } else { - QLineEdit::keyPressEvent(ev); } } -- 2.5.3
From 1a6651ed9789f79a61310329ff1cc60981f266df Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Tue, 22 Sep 2015 14:13:51 -0300 Subject: [PATCH 09/14] Space fix. Sorry. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 68 +++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 31a22cc..8aec1f1 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -521,42 +521,42 @@ void DiveLocationLineEdit::keyPressEvent(QKeyEvent *ev) void DiveLocationLineEdit::showPopup() { - const QRect screen = QApplication::desktop()->availableGeometry(this); - const int maxVisibleItems = 5; - Qt::LayoutDirection dir = layoutDirection(); - QPoint pos; - int rh, w; - int h = (view->sizeHintForRow(0) * qMin(maxVisibleItems, view->model()->rowCount()) + 3) + 3; - QScrollBar *hsb = view->horizontalScrollBar(); - if (hsb && hsb->isVisible()) - h += view->horizontalScrollBar()->sizeHint().height(); - - rh = height(); - pos = mapToGlobal(QPoint(0, height() - 2)); - w = width(); - - if (w > screen.width()) - w = screen.width(); - if ((pos.x() + w) > (screen.x() + screen.width())) - pos.setX(screen.x() + screen.width() - w); - if (pos.x() < screen.x()) - pos.setX(screen.x()); - - int top = pos.y() - rh - screen.top() + 2; - int bottom = screen.bottom() - pos.y(); - h = qMax(h, view->minimumHeight()); - if (h > bottom) { - h = qMin(qMax(top, bottom), h); - if (top > bottom) - pos.setY(pos.y() - h - rh + 2); - } + const QRect screen = QApplication::desktop()->availableGeometry(this); + const int maxVisibleItems = 5; + Qt::LayoutDirection dir = layoutDirection(); + QPoint pos; + int rh, w; + int h = (view->sizeHintForRow(0) * qMin(maxVisibleItems, view->model()->rowCount()) + 3) + 3; + QScrollBar *hsb = view->horizontalScrollBar(); + if (hsb && hsb->isVisible()) + h += view->horizontalScrollBar()->sizeHint().height(); + + rh = height(); + pos = mapToGlobal(QPoint(0, height() - 2)); + w = width(); + + if (w > screen.width()) + w = screen.width(); + if ((pos.x() + w) > (screen.x() + screen.width())) + pos.setX(screen.x() + screen.width() - w); + if (pos.x() < screen.x()) + pos.setX(screen.x()); + + int top = pos.y() - rh - screen.top() + 2; + int bottom = screen.bottom() - pos.y(); + h = qMax(h, view->minimumHeight()); + if (h > bottom) { + h = qMin(qMax(top, bottom), h); + if (top > bottom) + pos.setY(pos.y() - h - rh + 2); + } - view->setGeometry(pos.x(), pos.y(), w, h); + view->setGeometry(pos.x(), pos.y(), w, h); - if (!view->isVisible()) { - view->show(); - view->setFocus(); - } + if (!view->isVisible()) { + view->show(); + view->setFocus(); + } } DiveLocationListView::DiveLocationListView(QWidget *parent) -- 2.5.3
From d97a171147d053d41edb2d31657991b2596b8f86 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Tue, 22 Sep 2015 14:31:56 -0300 Subject: [PATCH 10/14] Random Fixes and improvements. Space fixes, Constructor fixes, new Slot ( still unused. ) Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 35 +++++++++++++++++------------------ qt-ui/locationinformation.h | 8 ++++++++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 8aec1f1..0388f9d 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -410,12 +410,10 @@ bool DiveLocationModel::setData(const QModelIndex& index, const QVariant& value, return true; } -DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) +DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) : QLineEdit(parent), + proxy(new DiveLocationFilterProxyModel()), model(new DiveLocationModel()), view(new DiveLocationListView()) { location_line_edit = this; - proxy = new DiveLocationFilterProxyModel(); - model = new DiveLocationModel(); - view = new DiveLocationListView(); proxy->setSourceModel(model); proxy->setFilterKeyColumn(DiveLocationModel::NAME); @@ -429,19 +427,24 @@ DiveLocationLineEdit::DiveLocationLineEdit(QWidget *parent) view->setSelectionMode(QAbstractItemView::SingleSelection); view->setParent(0, Qt::Popup); view->installEventFilter(this); - view->setFocusProxy(location_line_edit); + view->setFocusPolicy(Qt::NoFocus); + view->setFocusProxy(this); connect(this, &QLineEdit::textEdited, this, &DiveLocationLineEdit::setTemporaryDiveSiteName); + connect(this, &QLineEdit::editingFinished, this, &DiveLocationLineEdit::setDiveSiteName); connect(view, &QAbstractItemView::activated, this, &DiveLocationLineEdit::itemActivated); } +void DiveLocationLineEdit::setDiveSiteName() +{ + +} + bool DiveLocationLineEdit::eventFilter(QObject *o, QEvent *e) { if(e->type() == QEvent::KeyPress) { QKeyEvent *keyEv = (QKeyEvent*) e; - qDebug() << view->focusProxy()->objectName(); - if (keyEv->key() == Qt::Key_Escape) { view->hide(); return true; @@ -451,15 +454,12 @@ bool DiveLocationLineEdit::eventFilter(QObject *o, QEvent *e) view->hide(); return false; } - event(e); - } - - if(e->type() == QEvent::MouseButtonPress ) { - if (!view->underMouse()) { - view->hide(); - return true; - } + } else if(e->type() == QEvent::MouseButtonPress ) { + if (!view->underMouse()) { + view->hide(); + return true; + } } return false; @@ -507,7 +507,6 @@ void DiveLocationLineEdit::setTemporaryDiveSiteName(const QString& s) void DiveLocationLineEdit::keyPressEvent(QKeyEvent *ev) { - qDebug() << "Pressing key" << ev->key(); QLineEdit::keyPressEvent(ev); if(ev->key() != Qt::Key_Left && ev->key() != Qt::Key_Right && @@ -554,8 +553,8 @@ void DiveLocationLineEdit::showPopup() view->setGeometry(pos.x(), pos.y(), w, h); if (!view->isVisible()) { - view->show(); - view->setFocus(); + proxy->invalidate(); + view->show(); } } diff --git a/qt-ui/locationinformation.h b/qt-ui/locationinformation.h index b52c03a..6df56f0 100644 --- a/qt-ui/locationinformation.h +++ b/qt-ui/locationinformation.h @@ -90,11 +90,17 @@ public: class DiveLocationLineEdit : public QLineEdit { Q_OBJECT public: + enum DiveSiteType { NO_DIVE_SITE, NEW_DIVE_SITE, EXISTING_DIVE_SITE }; DiveLocationLineEdit(QWidget *parent =0 ); void refreshDiveSiteCache(); void setTemporaryDiveSiteName(const QString& s); bool eventFilter(QObject*, QEvent*); void itemActivated(const QModelIndex& index); + void setDiveSiteName(); + + DiveSiteType currDiveSiteType() const; + uint32_t currDiveSiteUuid() const; + protected: void keyPressEvent(QKeyEvent *ev); void showPopup(); @@ -102,6 +108,8 @@ private: DiveLocationFilterProxyModel *proxy; DiveLocationModel *model; DiveLocationListView *view; + DiveSiteType currType; + uint32_t currUuid; }; #endif -- 2.5.3
From 7704412097b45dd710e7962d7cc05b131ef4ada3 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Tue, 22 Sep 2015 15:23:38 -0300 Subject: [PATCH 11/14] Block focus out event. The line edit wasn't being properly updated regarding it's paint event. turns out it was because it received a focus out event and then stopped refreshing the paint. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 9 ++++++++- qt-ui/locationinformation.h | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 0388f9d..62889c9 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -396,7 +396,6 @@ int DiveLocationModel::rowCount(const QModelIndex& parent) const return dive_site_table.nr + 2; } - bool DiveLocationModel::setData(const QModelIndex& index, const QVariant& value, int role) { if(!index.isValid()) @@ -465,6 +464,14 @@ bool DiveLocationLineEdit::eventFilter(QObject *o, QEvent *e) return false; } +void DiveLocationLineEdit::focusOutEvent(QFocusEvent* ev) +{ + if (!view->isVisible()) { + qDebug() << "Focusing Out"; + QLineEdit::focusOutEvent(ev); + } +} + void DiveLocationLineEdit::itemActivated(const QModelIndex& index) { qDebug() << "Activated" << index.data(); diff --git a/qt-ui/locationinformation.h b/qt-ui/locationinformation.h index 6df56f0..2b41f52 100644 --- a/qt-ui/locationinformation.h +++ b/qt-ui/locationinformation.h @@ -103,6 +103,7 @@ public: protected: void keyPressEvent(QKeyEvent *ev); + void focusOutEvent(QFocusEvent *ev); void showPopup(); private: DiveLocationFilterProxyModel *proxy; -- 2.5.3
From 83e9a5835998414de56181364fd6ec2cc6491558 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Tue, 22 Sep 2015 16:27:07 -0300 Subject: [PATCH 12/14] Correctly handle space and tab Space and tab should select the item in the itemview and hide it, while Enter and Return also does that automatically. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 62889c9..a53ad68 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -449,10 +449,18 @@ bool DiveLocationLineEdit::eventFilter(QObject *o, QEvent *e) return true; } - if(keyEv->key() == Qt::Key_Return || keyEv->key() == Qt::Key_Enter) { + if(keyEv->key() == Qt::Key_Return || + keyEv->key() == Qt::Key_Enter) { view->hide(); return false; } + + if (keyEv->key() == Qt::Key_Space || + keyEv->key() == Qt::Key_Tab){ + itemActivated(view->currentIndex()); + view->hide(); + return false; + } event(e); } else if(e->type() == QEvent::MouseButtonPress ) { if (!view->underMouse()) { @@ -560,6 +568,7 @@ void DiveLocationLineEdit::showPopup() view->setGeometry(pos.x(), pos.y(), w, h); if (!view->isVisible()) { + setTemporaryDiveSiteName(text()); proxy->invalidate(); view->show(); } -- 2.5.3
From bb214c7b1d8b830c9ee90173d984653cce517400 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Tue, 22 Sep 2015 16:36:17 -0300 Subject: [PATCH 13/14] Set the current dive site uid / text Start to make this thing userfull: Upon selecting the current index or writting something on the line edit, we need to set the dive site. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index a53ad68..11da00a 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -357,6 +357,9 @@ void DiveLocationModel::resetModel() QVariant DiveLocationModel::data(const QModelIndex& index, int role) const { if(index.row() <= 1) { // two special cases. + if(index.column() == UUID) { + return RECENTLY_ADDED_DIVESITE; + } switch(role) { case Qt::DisplayRole : return new_ds_value[index.row()]; case Qt::ToolTipRole : return "Create a new dive site"; @@ -475,14 +478,17 @@ bool DiveLocationLineEdit::eventFilter(QObject *o, QEvent *e) void DiveLocationLineEdit::focusOutEvent(QFocusEvent* ev) { if (!view->isVisible()) { - qDebug() << "Focusing Out"; QLineEdit::focusOutEvent(ev); } } void DiveLocationLineEdit::itemActivated(const QModelIndex& index) { - qDebug() << "Activated" << index.data(); + QModelIndex uuidIndex = index.model()->index(index.row(), DiveLocationModel::UUID); + uint32_t uuid = uuidIndex.data().toInt(); + currType = uuid == 1 ? NEW_DIVE_SITE : EXISTING_DIVE_SITE; + currUuid = uuid; + setText(index.data().toString()); } void DiveLocationLineEdit::refreshDiveSiteCache() -- 2.5.3
From 5ec7c49a214731da89aa9337532803792cc6a545 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava <[email protected]> Date: Tue, 22 Sep 2015 17:20:55 -0300 Subject: [PATCH 14/14] Fix New/Existing dive site choices. Only set the currType and currUuid if text changed. this is needed because if you hitted key_down it would set NEW_DIVE_SITE because a keypress on the lineedit was due. Signed-off-by: Tomaz Canabrava <[email protected]> --- qt-ui/locationinformation.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/qt-ui/locationinformation.cpp b/qt-ui/locationinformation.cpp index 11da00a..7e640f1 100644 --- a/qt-ui/locationinformation.cpp +++ b/qt-ui/locationinformation.cpp @@ -489,6 +489,10 @@ void DiveLocationLineEdit::itemActivated(const QModelIndex& index) currType = uuid == 1 ? NEW_DIVE_SITE : EXISTING_DIVE_SITE; currUuid = uuid; setText(index.data().toString()); + if(currUuid == NEW_DIVE_SITE) + qDebug() << "Setting a New dive site"; + else + qDebug() << "Setting a Existing dive site"; } void DiveLocationLineEdit::refreshDiveSiteCache() @@ -533,6 +537,11 @@ void DiveLocationLineEdit::keyPressEvent(QKeyEvent *ev) ev->key() != Qt::Key_Right && ev->key() != Qt::Key_Escape && ev->key() != Qt::Key_Return ) { + + if(ev->key() != Qt::Key_Up && ev->key() != Qt::Key_Down) { + currType = NEW_DIVE_SITE; + currUuid = RECENTLY_ADDED_DIVESITE; + } showPopup(); } else if (ev->key() == Qt::Key_Escape) { view->hide(); -- 2.5.3
_______________________________________________ subsurface mailing list [email protected] http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
