diff options
author | Viktor Verebelyi <vviktor2@gmail.com> | 2020-09-17 01:16:33 +0100 |
---|---|---|
committer | Viktor Verebelyi <vviktor2@gmail.com> | 2020-09-22 02:16:57 +0100 |
commit | 61a0c2e04be92490661fc102c721d0c231e21c5c (patch) | |
tree | 77ab6bde3f14259a0898b3aef410c20e5716d2e8 | |
parent | 3c79869a89dfea9957ce28588539e9c30458cec6 (diff) | |
download | navit-61a0c2e04be92490661fc102c721d0c231e21c5c.tar.gz |
Add:qt5_gui:Add Current WIP
27 files changed, 2096 insertions, 406 deletions
diff --git a/navit/gui/qt5_qml/CMakeLists.txt b/navit/gui/qt5_qml/CMakeLists.txt index 19c0c1802..07e996ad5 100644 --- a/navit/gui/qt5_qml/CMakeLists.txt +++ b/navit/gui/qt5_qml/CMakeLists.txt @@ -6,5 +6,5 @@ set(CMAKE_AUTOMOC ON) qt5_add_resources(GUI_QT5_QML_QRC "gui_qt5_qml.qrc") module_add_library(gui_qt5_qml gui_qt5_qml.cpp ${GUI_QT5_QML_QRC} - navitpoimodel.cpp navitrecentsmodel.cpp navitfavouritesmodel.cpp proxy.c) + navitpoimodel.cpp navitrecentsmodel.cpp navitfavouritesmodel.cpp navitsearchmodel.cpp navithelper.cpp navitroute.cpp proxy.c) diff --git a/navit/gui/qt5_qml/gui_qt5_qml.cpp b/navit/gui/qt5_qml/gui_qt5_qml.cpp index 57d3efd6a..1a786361f 100644 --- a/navit/gui/qt5_qml/gui_qt5_qml.cpp +++ b/navit/gui/qt5_qml/gui_qt5_qml.cpp @@ -62,6 +62,8 @@ extern "C" { #include "navitpoimodel.h" #include "navitrecentsmodel.h" #include "navitfavouritesmodel.h" +#include "navitsearchmodel.h" +#include "navitroute.h" struct gui_priv { /* navit internal handle */ @@ -228,6 +230,8 @@ static int gui_qt5_qml_set_graphics(struct gui_priv* gui_priv, struct graphics* qmlRegisterType<NavitPOIModel>("Navit.POI", 1, 0, "NavitPOIModel"); qmlRegisterType<NavitRecentsModel>("Navit.Recents", 1, 0, "NavitRecentsModel"); qmlRegisterType<NavitFavouritesModel>("Navit.Favourites", 1, 0, "NavitFavouritesModel"); + qmlRegisterType<NavitSearchModel>("Navit.Search", 1, 0, "NavitSearchModel"); + qmlRegisterType<NavitRoute>("Navit.Route", 1, 0, "NavitRoute"); /* find the loader component */ gui_priv->loader = gui_priv->engine->rootObjects().value(0)->findChild<QObject*>("navit_loader"); diff --git a/navit/gui/qt5_qml/gui_qt5_qml.qrc b/navit/gui/qt5_qml/gui_qt5_qml.qrc index 09524c2d7..9bbd72b62 100644 --- a/navit/gui/qt5_qml/gui_qt5_qml.qrc +++ b/navit/gui/qt5_qml/gui_qt5_qml.qrc @@ -946,5 +946,8 @@ <file>themes/Levy/assets/corner-arrow.svg</file> <file>themes/Levy/assets/destination-view.png</file> <file>themes/Levy/icons.js</file> + <file>themes/Levy/SearchDrawerRecentsList.qml</file> + <file>themes/Levy/SearchDrawerFavouritesList.qml</file> + <file>themes/Levy/SearchDrawerContextMenu.qml</file> </qresource> </RCC> diff --git a/navit/gui/qt5_qml/navitfavouritesmodel.cpp b/navit/gui/qt5_qml/navitfavouritesmodel.cpp index 68a21b0b1..8fb8055c3 100644 --- a/navit/gui/qt5_qml/navitfavouritesmodel.cpp +++ b/navit/gui/qt5_qml/navitfavouritesmodel.cpp @@ -6,10 +6,8 @@ NavitFavouritesModel::NavitFavouritesModel(QObject *parent) } QHash<int, QByteArray> NavitFavouritesModel::roleNames() const{ QHash<int, QByteArray> roles; - roles[NameRole] = "name"; - roles[CoordXRole] = "coordX"; - roles[CoordYRole] = "coordY"; - roles[CoordProjectionRole] = "coordProjection"; + roles[LabelRole] = "label"; + roles[CoordinatesRole] = "coords"; return roles; } @@ -19,14 +17,10 @@ QVariant NavitFavouritesModel::data(const QModelIndex & index, int role) const { const QVariantMap *poi = &m_favourites.at(index.row()); - if (role == NameRole) - return poi->value("name"); - if (role == CoordXRole) - return poi->value("coordX"); - if (role == CoordYRole) - return poi->value("coordY"); - if (role == CoordProjectionRole) - return poi->value("coordProjection"); + if (role == LabelRole) + return poi->value("label"); + if (role == CoordinatesRole) + return poi->value("coords"); return QVariant(); } @@ -69,34 +63,34 @@ void NavitFavouritesModel::update() { struct navigation * nav = nullptr; struct item *item; struct coord c; - struct pcoord pc; + enum projection projection; m_favourites.clear(); - pc.pro = transform_get_projection(navit_get_trans(m_navitInstance->getNavit())); + projection = transform_get_projection(navit_get_trans(m_navitInstance->getNavit())); if(navit_get_attr(m_navitInstance->getNavit(), attr_bookmarks, &mattr, nullptr) ) { bookmarks_item_rewind(mattr.u.bookmarks); while ((item=bookmarks_get_item(mattr.u.bookmarks))) { if (!item_attr_get(item, attr_label, &attr)) continue; - qDebug() << c.x << " : " << c.y; + // qDebug() << c.x << " : " << c.y; if (item_coord_get(item, &c, 1)) { - pc.x = c.x; - pc.y = c.y; - qDebug() << attr.u.str << c.x << " : " << c.y; + QVariantMap coords; + coords.insert("x", c.x); + coords.insert("y", c.y); + coords.insert("pro", projection); + QVariantMap recentItem; - recentItem.insert("coordX",pc.x); - recentItem.insert("coordY",pc.y); - recentItem.insert("coordProjection",pc.pro); - recentItem.insert("name",attr.u.str); + recentItem.insert("coords",coords); + recentItem.insert("label",attr.u.str); beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_favourites.append(recentItem); endInsertRows(); } } - qDebug() << m_favourites; + // qDebug() << m_favourites; } } } @@ -130,18 +124,40 @@ void NavitFavouritesModel::showFavourites(){ } } } - bm_count=i; - - if (bm_count>0) { - navit_set_destinations(m_navitInstance->getNavit(), pc, bm_count, "test_", 1); -// if (this->flags & 512) { - struct attr follow; - follow.type=attr_follow; - follow.u.num=180; -// navit_set_attr(this->nav, &this->osd_configuration); - navit_set_attr(m_navitInstance->getNavit(), &follow); - navit_zoom_to_route(m_navitInstance->getNavit(), 0); -// } - } + } +} +void NavitFavouritesModel::setAsDestination(int index){ + if(m_favourites.size() > index){ + NavitHelper::setDestination(m_navitInstance, + m_favourites[index]["label"].toString(), + m_favourites[index]["coords"].toMap()["x"].toInt(), + m_favourites[index]["coords"].toMap()["y"].toInt()); + } +} + +void NavitFavouritesModel::setAsPosition(int index){ + if(m_favourites.size() > index){ + NavitHelper::setPosition(m_navitInstance, + m_favourites[index]["coords"].toMap()["x"].toInt(), + m_favourites[index]["coords"].toMap()["y"].toInt()); + } +} + +void NavitFavouritesModel::addAsBookmark(int index){ + if(m_favourites.size() > index){ + NavitHelper::addBookmark(m_navitInstance, + m_favourites[index]["label"].toString(), + m_favourites[index]["coords"].toMap()["x"].toInt(), + m_favourites[index]["coords"].toMap()["y"].toInt()); + } +} + +void NavitFavouritesModel::addStop(int index, int position){ + if(m_favourites.size() > index){ + NavitHelper::addStop(m_navitInstance, + position, + m_favourites[index]["label"].toString(), + m_favourites[index]["coords"].toMap()["x"].toInt(), + m_favourites[index]["coords"].toMap()["y"].toInt()); } } diff --git a/navit/gui/qt5_qml/navitfavouritesmodel.h b/navit/gui/qt5_qml/navitfavouritesmodel.h index 16ce28947..fd24a1faf 100644 --- a/navit/gui/qt5_qml/navitfavouritesmodel.h +++ b/navit/gui/qt5_qml/navitfavouritesmodel.h @@ -3,7 +3,6 @@ #include <QAbstractItemModel> #include <QDebug> -#include "navitinstance.h" #include <glib.h> extern "C" { @@ -25,16 +24,17 @@ extern "C" { #include "proxy.h" } +#include "navitinstance.h" +#include "navithelper.h" + class NavitFavouritesModel : public QAbstractItemModel { Q_OBJECT Q_PROPERTY(NavitInstance * navit MEMBER m_navitInstance WRITE setNavit) public: enum FavouriteModelRoles { - NameRole = Qt::UserRole + 1, - CoordXRole, - CoordYRole, - CoordProjectionRole + LabelRole = Qt::UserRole + 1, + CoordinatesRole }; NavitFavouritesModel(QObject *parent = 0); @@ -52,6 +52,10 @@ public: void setNavit(NavitInstance * navit); Q_INVOKABLE void showFavourites(); + Q_INVOKABLE void setAsDestination(int index); + Q_INVOKABLE void setAsPosition(int index); + Q_INVOKABLE void addAsBookmark(int index); + Q_INVOKABLE void addStop(int index, int position); private: QList<QVariantMap> m_favourites; NavitInstance *m_navitInstance = nullptr; diff --git a/navit/gui/qt5_qml/navithelper.cpp b/navit/gui/qt5_qml/navithelper.cpp new file mode 100644 index 000000000..16b4a185e --- /dev/null +++ b/navit/gui/qt5_qml/navithelper.cpp @@ -0,0 +1,308 @@ +#include "navithelper.h" + +NavitHelper::NavitHelper() +{ + +} + +QString NavitHelper::formatDist(int dist) { + double distance = dist/1000; + if (dist > 10000) + return QString::number(distance, 'f', 0); + else if (dist>0) + return QString("%1.%2").arg(distance).arg((dist%1000)/100); + return QString(); +} + + +QString NavitHelper::getClosest(QList<QVariantMap> items, int maxDistance) { + QString ret; + int retDistance = 1000000; + for(QVariantMap item : items){ + if(item.value("distance") < retDistance){ + ret = item.value("label").toString(); + retDistance = item.value("distance").toInt(); + } + } + if(maxDistance > 0 && retDistance > maxDistance){ + return QString(); + } + + return ret; +} + +QVariantMap NavitHelper::getPOI(NavitInstance *navitInstance, struct coord center, int distance){ + if(navitInstance){ + struct transformation * trans; + + struct map_selection * sel, * selm; + struct coord c; + struct pcoord pcenter; + struct mapset_handle * h; + struct map * m; + struct map_rect * mr; + struct item * item; + + enum projection pro; + int idist = 0; + + trans = navit_get_trans(navitInstance->getNavit()); + pro = transform_get_projection(trans); + + pcenter.x = center.x; + pcenter.y = center.y; + pcenter.pro = pro; + + int distanceSel = distance * transform_scale(abs(center.y) + distance * 1.5); + sel = map_selection_rect_new(&(pcenter), distanceSel, 18); + + dbg(lvl_debug, "center is at %x, %x", center.x, center.y); + + h = mapset_open(navit_get_mapset(navitInstance->getNavit())); + QList<QVariantMap> pois; + while ((m = mapset_next(h, 1))) { + selm = map_selection_dup_pro(sel, pro, map_projection(m)); + mr = map_rect_new(m, selm); + dbg(lvl_debug, "mr=%p", mr); + if (mr) { + while ((item = map_rect_get_item(mr))) { + if ( item_is_poi(*item) && + item_coord_get_pro(item, &c, 1, pro) && + coord_rect_contains(&sel->u.c_rect, &c) && + (idist = transform_distance(pro, ¢er, &c)) < distance) { + item_attr_rewind(item); + struct attr attr; + char * label; + char * icon = get_icon(navitInstance->getNavit(), item); + + if (item_attr_get(item, attr_label, &attr)) { + label = map_convert_string(item->map, attr.u.str); + + QVariantMap poi; + poi.insert("label", label); + poi.insert("distance", idist); + pois << poi; + } + } + } + map_rect_destroy(mr); + } + map_selection_destroy(selm); + } + map_selection_destroy(sel); + mapset_close(h); + + QVariantMap ret; + int retDistance = 1000000; + for(QVariantMap poi : pois){ + if(poi.value("distance") < retDistance){ + ret = poi; + retDistance = poi.value("distance").toInt(); + } + } + + return ret; + } + return QVariantMap(); +} + +QString NavitHelper::getAddress(NavitInstance *navitInstance, struct coord center, QString filter){ + if(navitInstance){ + struct transformation * trans; + + struct map_selection * sel, * selm; + struct coord c; + struct pcoord pcenter; + struct mapset_handle * h; + struct map * m; + struct map_rect * mr; + struct item * item; + + enum projection pro; + int idist = 0; + int distance = 1000; + + trans = navit_get_trans(navitInstance->getNavit()); + pro = transform_get_projection(trans); + + pcenter.x = center.x; + pcenter.y = center.y; + pcenter.pro = pro; + + int distanceSel = distance * transform_scale(abs(center.y) + distance * 1.5); + sel = map_selection_rect_new(&(pcenter), distanceSel, 18); + + dbg(lvl_debug, "center is at %x, %x", center.x, center.y); + + h = mapset_open(navit_get_mapset(navitInstance->getNavit())); + QList<QVariantMap> housenumbers; + QList<QVariantMap> streets; + QList<QVariantMap> districts; + QList<QVariantMap> towns; + while ((m = mapset_next(h, 1))) { + selm = map_selection_dup_pro(sel, pro, map_projection(m)); + mr = map_rect_new(m, selm); + dbg(lvl_debug, "mr=%p", mr); + if (mr) { + while ((item = map_rect_get_item(mr))) { + if(!filter.isEmpty() && filter != item_to_name(item->type)){ + continue; + } + + if ( (item_is_house_number(*item) || item_is_street(*item) || item_is_district(*item) || item_is_town(*item)) && + item_coord_get_pro(item, &c, 1, pro) && + coord_rect_contains(&sel->u.c_rect, &c) && + (idist = transform_distance(pro, ¢er, &c)) < distance) { + item_attr_rewind(item); + struct attr attr; + char * label; + char * icon = get_icon(navitInstance->getNavit(), item); + + if (item_attr_get(item, attr_label, &attr)) { + label = map_convert_string(item->map, attr.u.str); + //TODO: District city and country search doesn't always work + if(item_is_house_number(*item)){ + QVariantMap street; + street.insert("label", label); + street.insert("distance", idist); + streets << street; + } else if(item_is_street(*item)){ + QVariantMap street; + street.insert("label", label); + street.insert("distance", idist); + streets << street; + } else if (item_is_town(*item)) { + QVariantMap town; + town.insert("label", label); + town.insert("distance", idist); + towns << town; + } else if (item_is_district(*item)) { + QVariantMap district; + district.insert("label", label); + district.insert("distance", idist); + districts << district; + } + } + } + } + map_rect_destroy(mr); + } + map_selection_destroy(selm); + } + map_selection_destroy(sel); + mapset_close(h); + + QStringList address; + QString housenumber = getClosest(housenumbers, 15); + QString street = getClosest(streets, 100); + QString district = getClosest(districts); + QString town = getClosest(towns); + + if(!housenumber.isEmpty()){ + address.append(housenumber); + } else if(!street.isEmpty()) { + address.append(street); + } + + if(street.isEmpty()){ + QString streetFar = getClosest(streets, 500); + address.append(QString("%1 %2").arg("Near").arg(streetFar)); + } + + if(!district.isEmpty()) + address.append(district); + + if(!town.isEmpty()) + address.append(town); + + return address.join(", ");; + } + return QString(); +} + + +coord NavitHelper::positionToCoord (NavitInstance *navitInstance, int x, int y){ + struct coord co; + if(navitInstance){ + struct point p; + p.x = x; + p.y = y; + + + struct transformation * trans = navit_get_trans(navitInstance->getNavit()); + transform_reverse(trans, &p, &co); + + } + return co; +} +pcoord NavitHelper::positionToPcoord (NavitInstance *navitInstance, int x, int y){ + struct pcoord c; + if(navitInstance){ + struct coord co = positionToCoord(navitInstance, x, y); + struct transformation * trans = navit_get_trans(navitInstance->getNavit()); + + c.pro = transform_get_projection(trans); + c.x = co.x; + c.y = co.y; + + } + return c; +} +pcoord NavitHelper::coordToPcoord (NavitInstance *navitInstance, int x, int y){ + struct pcoord c; + if(navitInstance){ + struct transformation * trans = navit_get_trans(navitInstance->getNavit()); + + c.pro = transform_get_projection(trans); + c.x = x; + c.y = y; + } + return c; +} + +void NavitHelper::setDestination(NavitInstance *navitInstance, QString label, int x, int y){ + if(navitInstance){ + navit_set_destination(navitInstance->getNavit(), nullptr, nullptr, 0); + struct pcoord c = coordToPcoord(navitInstance, x, y); + navit_set_destination(navitInstance->getNavit(), &c, label.toUtf8().data(), 1); + } +} + +void NavitHelper::setPosition(NavitInstance *navitInstance, int x, int y){ + if(navitInstance){ + struct pcoord c = NavitHelper::coordToPcoord(navitInstance, x, y); + + navit_set_position(navitInstance->getNavit(), &c); + } +} + +void NavitHelper::addStop(NavitInstance *navitInstance, int position, QString label, int x, int y) { + struct pcoord c = coordToPcoord(navitInstance, x, y); + + int dstcount=navit_get_destination_count(navitInstance->getNavit())+1; + int pos,i; + struct pcoord *dst=(pcoord *)g_alloca(dstcount*sizeof(struct pcoord)); + dstcount=navit_get_destinations(navitInstance->getNavit(),dst,dstcount); + + pos=position; + if(pos<0) + pos=0; + + for(i=dstcount; i>pos; i--) + dst[i]=dst[i-1]; + + dst[pos]=c; + + navit_add_destination_description(navitInstance->getNavit(),&c,label.toUtf8().data()); + navit_set_destinations(navitInstance->getNavit(),dst,dstcount+1,label.toUtf8().data(),1); +} +void NavitHelper::addBookmark(NavitInstance *navitInstance, QString label, int x, int y){ + if(navitInstance){ + + struct attr attr; + struct pcoord c = NavitHelper::positionToPcoord(navitInstance, x ,y); + navit_get_attr(navitInstance->getNavit(), attr_bookmarks, &attr, nullptr); + + bookmarks_add_bookmark(attr.u.bookmarks, &c, label.toUtf8().data()); + } +} diff --git a/navit/gui/qt5_qml/navithelper.h b/navit/gui/qt5_qml/navithelper.h new file mode 100644 index 000000000..6c0513089 --- /dev/null +++ b/navit/gui/qt5_qml/navithelper.h @@ -0,0 +1,47 @@ +#ifndef NAVITHELPER_H +#define NAVITHELPER_H + +#include <QString> +#include <QDebug> + +#include "navitinstance.h" + +#include <glib.h> +extern "C" { +#include "config.h" +#include "item.h" /* needs to be first, as attr.h depends on it */ +#include "navit.h" + +#include "coord.h" +#include "attr.h" +#include "xmlconfig.h" // for NAVIT_OBJECT +#include "layout.h" +#include "map.h" +#include "transform.h" + +#include "mapset.h" +#include "search.h" +#include "bookmarks.h" + +#include "proxy.h" +} + +class NavitHelper +{ +public: + NavitHelper(); + + static QString getAddress(NavitInstance * navitInstance, struct coord center, QString filter = ""); + static QVariantMap getPOI(NavitInstance *navitInstance, struct coord center, int distance = 2); + static QString getClosest(QList<QVariantMap> items, int maxDistance = -1); + static QString formatDist(int dist); + static pcoord positionToPcoord (NavitInstance *navitInstance, int x, int y); + static coord positionToCoord (NavitInstance *navitInstance, int x, int y); + static pcoord coordToPcoord(NavitInstance *navitInstance, int x, int y); + static void setDestination(NavitInstance *navitInstance, QString label, int x, int y); + static void setPosition(NavitInstance *navitInstance, int x, int y); + static void addBookmark(NavitInstance *navitInstance, QString label, int x, int y); + static void addStop(NavitInstance *navitInstance, int position, QString label, int x, int y); +}; + +#endif // NAVITHELPER_H diff --git a/navit/gui/qt5_qml/navitpoimodel.cpp b/navit/gui/qt5_qml/navitpoimodel.cpp index 29803c420..14ca4f006 100644 --- a/navit/gui/qt5_qml/navitpoimodel.cpp +++ b/navit/gui/qt5_qml/navitpoimodel.cpp @@ -1,8 +1,135 @@ #include "navitpoimodel.h" +POISearchWorker::POISearchWorker (NavitInstance * navit) : + m_navitInstance(navit), + m_running(false), m_mutex(){ + +} +POISearchWorker::~POISearchWorker (){ + qDebug() << "Deleting POISearchWorker"; +} +void POISearchWorker::setParameters(QString filter, int screenX, int screenY, int distance){ + m_filter = filter; + m_screenX = screenX; + m_screenY = screenY; + m_distance = distance; +} +void POISearchWorker::run() +{ + struct point p; + struct transformation * trans; + + struct map_selection * sel, * selm; + struct coord c, center; + struct pcoord pcenter; + struct mapset_handle * h; + struct map * m; + struct map_rect * mr; + struct item * item; + + enum projection pro; + int idist = 0; + + if(m_screenX < 0) { + m_screenX = navit_get_width(m_navitInstance->getNavit()) / 2; + m_screenY = navit_get_height(m_navitInstance->getNavit()) / 2; + } + + p.x = m_screenX; + p.y = m_screenY; + + trans = navit_get_trans(m_navitInstance->getNavit()); + pro = transform_get_projection(trans); + transform_reverse(trans, &p, ¢er); + + pcenter.x = center.x; + pcenter.y = center.y; + pcenter.pro = pro; + + int distanceSel = m_distance * transform_scale(abs(center.y) + m_distance * 1.5); + qDebug() << "distanceSel : " << distanceSel; + sel = map_selection_rect_new(&(pcenter), distanceSel, 18); + + dbg(lvl_debug, "screenX : %d screenY : %d center is at %x, %x", m_screenX, m_screenY, center.x, center.y); + + h = mapset_open(navit_get_mapset(m_navitInstance->getNavit())); + m_mutex.lock(); + m_running = true; + while ((m = mapset_next(h, 1)) && m_running) { + selm = map_selection_dup_pro(sel, pro, map_projection(m)); + mr = map_rect_new(m, selm); + dbg(lvl_debug, "mr=%p", mr); + if (mr) { + // QMutexLocker locker(&m_mutex); + + while ((item = map_rect_get_item(mr)) && m_running) { + if(!m_filter.isEmpty() && m_filter != item_to_name(item->type)){ + continue; + } + + if ( item_is_poi(*item) && + item_coord_get_pro(item, &c, 1, pro) && + coord_rect_contains(&sel->u.c_rect, &c) && + (idist = transform_distance(pro, ¢er, &c))/* < m_distance*/) { + + item_attr_rewind(item); + struct attr attr; + char * name; + char * icon = get_icon(m_navitInstance->getNavit(), item); + + if (item_attr_get(item, attr_label, &attr)) { + name = map_convert_string(item->map, attr.u.str); + + QString address = NavitHelper::getAddress(m_navitInstance, c,""); + QString label = QString("%0, %1").arg(name).arg(address); + QVariantMap coords; + coords.insert("x", c.x); + coords.insert("y", c.y); + coords.insert("pro", pro); + QVariantMap poi; + poi.insert("name", name); + poi.insert("type", item_to_name(item->type)); + poi.insert("distance", idist); + poi.insert("icon", icon); + poi.insert("coords", coords); + poi.insert("address", address); + poi.insert("label", label); + emit gotSearchResult(poi); + } + } + } + map_rect_destroy(mr); + } + map_selection_destroy(selm); + } + + map_selection_destroy(sel); + mapset_close(h); + m_mutex.unlock(); +} +void POISearchWorker::stop() { + qDebug() << "Stopping worker"; + m_running = false; + m_mutex.lock(); + m_mutex.unlock(); + qDebug() << "Worker stopped"; +} + NavitPOIModel::NavitPOIModel(QObject *parent) { +} +NavitPOIModel::~NavitPOIModel(){ + if(m_poiWorker){ + delete m_poiWorker; + } +} + +void NavitPOIModel::setNavit(NavitInstance * navit){ + m_navitInstance = navit; + m_poiWorker = new POISearchWorker(m_navitInstance); + m_poiWorker->setAutoDelete(false); + connect(m_poiWorker, &POISearchWorker::gotSearchResult, this, &NavitPOIModel::receiveSearchResult); } QHash<int, QByteArray> NavitPOIModel::roleNames() const{ @@ -11,8 +138,9 @@ QHash<int, QByteArray> NavitPOIModel::roleNames() const{ roles[TypeRole] = "type"; roles[DistanceRole] = "distance"; roles[IconRole] = "icon"; - roles[CoordinatesRole] = "coordinates"; + roles[CoordinatesRole] = "coords"; roles[AddressRole] = "address"; + roles[LabelRole] = "label"; return roles; } @@ -34,6 +162,8 @@ QVariant NavitPOIModel::data(const QModelIndex & index, int role) const { return poi->value("coords"); if (role == AddressRole) return poi->value("address"); + if (role == LabelRole) + return poi->value("label"); return QVariant(); } @@ -89,104 +219,106 @@ QString NavitPOIModel::getAddressString(struct item *item, int prependPostal) { return address.join(" "); } -static void format_dist(int dist, char *distbuf) { - if (dist > 10000) - sprintf(distbuf,"%d ", dist/1000); - else if (dist>0) - sprintf(distbuf,"%d.%d ", dist/1000, (dist%1000)/100); -} -void NavitPOIModel::search(double lng, double lat, QString filter){ - if(m_navitInstance){ - struct coord d; - struct coord_geo g; - - struct pcoord new_center; - new_center.pro = transform_get_projection(navit_get_trans(m_navitInstance->getNavit())); - - g.lng = lng; - g.lat = lat; - transform_from_geo(new_center.pro, &g, &d); - new_center.x = d.x; - new_center.y = d.y; - - struct map_selection * sel, * selm; - struct coord c, center; - struct mapset_handle * h; - struct map * m; - struct map_rect * mr; - struct item * item; - int idist; - int dist; - dist = 10000; - sel = map_selection_rect_new(&(new_center), dist * transform_scale(abs(new_center.y) + dist * 1.5), 18); +void NavitPOIModel::search(QString filter, int screenX, int screenY, int distance){ + if(m_poiWorker){ + m_poiWorker->blockSignals(true); + m_poiWorker->stop(); + qDebug() << "clearing pois"; + + beginResetModel(); m_pois.clear(); m_poiTypes.clear(); + endResetModel(); - dbg(lvl_debug, "center is at %x, %x", center.x, center.y); - - h = mapset_open(navit_get_mapset(m_navitInstance->getNavit())); - while ((m = mapset_next(h, 1))) { - selm = map_selection_dup_pro(sel, new_center.pro, map_projection(m)); - mr = map_rect_new(m, selm); - dbg(lvl_debug, "mr=%p", mr); - if (mr) { - while ((item = map_rect_get_item(mr))) { - if(!filter.isEmpty() && filter != item_to_name(item->type)){ - continue; - } - if ( item_is_poi(*item) && - item_coord_get_pro(item, &c, 1, new_center.pro) && - coord_rect_contains(&sel->u.c_rect, &c) && - (idist=transform_distance(new_center.pro, ¢er, &c)) < dist) { - - struct attr attr; - char * label; - char * icon = get_icon(m_navitInstance->getNavit(), item); - struct pcoord item_coord; - item_coord.pro = transform_get_projection(navit_get_trans(m_navitInstance->getNavit())); - item_coord.x = c.x; - item_coord.y = c.y; - - idist = transform_distance(new_center.pro, ¢er, &c); - if (item_attr_get(item, attr_label, &attr)) { - label = map_convert_string(item->map, attr.u.str); - - if (icon) { - - if(!m_poiTypes.contains(item_to_name(item->type))){ - m_poiTypes << item_to_name(item->type); - } - char distStr[32]=""; - format_dist(idist, distStr); - - qDebug () << distStr; - QString address = getAddressString(item,0); - - QVariantMap coords; - coords.insert("x", item_coord.x); - coords.insert("y", item_coord.y); - coords.insert("pro", item_coord.pro); - QVariantMap poi; - poi.insert("name", label); - poi.insert("type", item_to_name(item->type)); - poi.insert("distance", idist); - poi.insert("icon", icon); - poi.insert("coords", coords); - poi.insert("address", address); - - beginInsertRows(QModelIndex(), rowCount(), rowCount()); - m_pois.append(poi); - endInsertRows(); - } - } - } - } - map_rect_destroy(mr); - } - map_selection_destroy(selm); + m_poiWorker->setParameters(filter, screenX, screenY, distance); + + m_poiWorker->blockSignals(false); + QThreadPool::globalInstance()->start(m_poiWorker); + } +} +//void NavitPOIModel::receiveSearchResult(QVariantMap poi){ +// qDebug() << "\t" << poi.value("name").toString(); + + +// // if(!m_poiTypes.contains(item_to_name(item->type))){ +// // m_poiTypes << item_to_name(item->type); +// // } + +//// QVariantMap tmpPoi(poi); +// int poiDist = poi.value("distM").toInt(); +//// tmpPoi.insert("distance", NavitHelper::formatDist(poiDist)); +// if(m_pois.size() == 0){ +// beginInsertRows(QModelIndex(), 0, 0); +// m_pois.append(poi); +// endInsertRows(); +// } +// for(int i = 0; i < m_pois.length(); i++){ +// int listDist = m_pois.at(i).value("distance").toInt(); +// if(poiDist >= listDist ){ +// continue; +// } +// beginInsertRows(QModelIndex(), i, i); +// m_pois.append(poi); +// endInsertRows(); +// } +//} +void NavitPOIModel::receiveSearchResult(QVariantMap poi){ + modelMutex.lock(); +// qDebug() << "\t" << poi.value("name").toString() << "\t" << poi.value("distance").toInt(); + + + // if(!m_poiTypes.contains(item_to_name(item->type))){ + // m_poiTypes << item_to_name(item->type); + // } + + int index = 0; + int poiDist = poi.value("distance").toInt(); + for(; index < m_pois.length(); index++){ + int itemDist = m_pois.at(index).value("distance").toInt(); + if(poiDist < itemDist){ + break; } - map_selection_destroy(sel); - mapset_close(h); + } + + beginInsertRows(QModelIndex(), index, index); + m_pois.insert(index, poi); + endInsertRows(); + modelMutex.unlock(); +} + +void NavitPOIModel::setAsDestination(int index){ + if(m_pois.size() > index){ + NavitHelper::setDestination(m_navitInstance, + m_pois[index]["label"].toString(), + m_pois[index]["coords"].toMap()["x"].toInt(), + m_pois[index]["coords"].toMap()["y"].toInt()); + } +} + +void NavitPOIModel::setAsPosition(int index){ + if(m_pois.size() > index){ + NavitHelper::setPosition(m_navitInstance, + m_pois[index]["coords"].toMap()["x"].toInt(), + m_pois[index]["coords"].toMap()["y"].toInt()); + } +} + +void NavitPOIModel::addAsBookmark(int index){ + if(m_pois.size() > index){ + NavitHelper::addBookmark(m_navitInstance, + m_pois[index]["label"].toString(), + m_pois[index]["coords"].toMap()["x"].toInt(), + m_pois[index]["coords"].toMap()["y"].toInt()); + } +} + +void NavitPOIModel::addStop(int index, int position){ + if(m_pois.size() > index){ + NavitHelper::addStop(m_navitInstance, + position, + m_pois[index]["label"].toString(), + m_pois[index]["coords"].toMap()["x"].toInt(), + m_pois[index]["coords"].toMap()["y"].toInt()); } } diff --git a/navit/gui/qt5_qml/navitpoimodel.h b/navit/gui/qt5_qml/navitpoimodel.h index 2c2ee9757..e3b527038 100644 --- a/navit/gui/qt5_qml/navitpoimodel.h +++ b/navit/gui/qt5_qml/navitpoimodel.h @@ -3,7 +3,16 @@ #include <QAbstractItemModel> #include <QDebug> +#include <QThreadPool> +#include <QRunnable> +#include <QMutex> +#include <QMap> +#include <QVariant> +#include <QJsonDocument> +#include <QJsonObject> + #include "navitinstance.h" +#include "navithelper.h" #include <glib.h> extern "C" { @@ -24,10 +33,32 @@ extern "C" { #include "proxy.h" } + +class POISearchWorker : public QObject, public QRunnable +{ + Q_OBJECT +public: + POISearchWorker (NavitInstance * navit); + ~POISearchWorker (); + void setParameters(QString filter, int screenX, int screenY, int distance); + void run() override; + void stop(); +signals: + void gotSearchResult(QVariantMap poi); +private: + NavitInstance * m_navitInstance; + bool m_running; + QMutex m_mutex; + QString m_filter; + int m_screenX; + int m_screenY; + int m_distance; +}; + class NavitPOIModel : public QAbstractItemModel { Q_OBJECT - Q_PROPERTY(NavitInstance * navit MEMBER m_navitInstance) + Q_PROPERTY(NavitInstance * navit MEMBER m_navitInstance WRITE setNavit) public: enum POIModelRoles { NameRole = Qt::UserRole + 1, @@ -35,10 +66,12 @@ public: DistanceRole, IconRole, CoordinatesRole, - AddressRole + AddressRole, + LabelRole }; NavitPOIModel(QObject *parent = 0); + ~NavitPOIModel() override; int rowCount(const QModelIndex & parent = QModelIndex()) const override; QHash<int, QByteArray> roleNames() const override; QVariant data(const QModelIndex & index, int role) const override; @@ -49,13 +82,22 @@ public: QModelIndex parent(const QModelIndex &child) const override; int columnCount(const QModelIndex &parent = QModelIndex()) const override; - Q_INVOKABLE void search(double lng, double lat, QString filter); + Q_INVOKABLE void search(QString filter, int screenX = -1, int screenY = -1, int distance = 15000); + Q_INVOKABLE void setAsDestination(int index); + Q_INVOKABLE void setAsPosition(int index); + Q_INVOKABLE void addAsBookmark(int index); + Q_INVOKABLE void addStop(int index, int position); + void setNavit(NavitInstance * navit); +private slots: + void receiveSearchResult(QVariantMap poi); private: QList<QVariantMap> m_pois; NavitInstance *m_navitInstance = nullptr; QStringList m_poiTypes; QString getAddressString(struct item *item, int prependPostal); + POISearchWorker *m_poiWorker; + QMutex modelMutex; }; #endif // NAVITPOIMODEL_H diff --git a/navit/gui/qt5_qml/navitrecentsmodel.cpp b/navit/gui/qt5_qml/navitrecentsmodel.cpp index 46ed14f3f..00a9046da 100644 --- a/navit/gui/qt5_qml/navitrecentsmodel.cpp +++ b/navit/gui/qt5_qml/navitrecentsmodel.cpp @@ -4,12 +4,10 @@ NavitRecentsModel::NavitRecentsModel(QObject *parent) { } + QHash<int, QByteArray> NavitRecentsModel::roleNames() const{ QHash<int, QByteArray> roles; - roles[NameRole] = "name"; - roles[CoordXRole] = "coordX"; - roles[CoordYRole] = "coordY"; - roles[CoordProjectionRole] = "coordProjection"; + roles[LabelRole] = "label"; return roles; } @@ -19,15 +17,8 @@ QVariant NavitRecentsModel::data(const QModelIndex & index, int role) const { const QVariantMap *poi = &m_recents.at(index.row()); - if (role == NameRole) - return poi->value("name"); - if (role == CoordXRole) - return poi->value("coordX"); - if (role == CoordYRole) - return poi->value("coordY"); - if (role == CoordProjectionRole) - return poi->value("coordProjection"); - + if (role == LabelRole) + return poi->value("label"); return QVariant(); } @@ -90,11 +81,15 @@ void NavitRecentsModel::update() { label_full=attr.u.str; if (item_coord_get(item, &c, 1)) { + QVariantMap coords; + coords.insert("x", c.x); + coords.insert("y", c.y); + coords.insert("pro", projection); + QVariantMap recentItem; - recentItem.insert("coordX",c.x); - recentItem.insert("coordY",c.y); - recentItem.insert("coordProjection",projection); - recentItem.insert("name",label_full); + recentItem.insert("coords",coords); + recentItem.insert("label",label_full); +// qDebug() << label_full; beginInsertRows(QModelIndex(), rowCount(), rowCount()); m_recents.append(recentItem); @@ -104,3 +99,47 @@ void NavitRecentsModel::update() { map_rect_destroy(mr_formerdests); } } + +void NavitRecentsModel::setAsDestination(int index){ + if(m_recents.size() > index){ + NavitHelper::setDestination(m_navitInstance, + m_recents[index]["label"].toString(), + m_recents[index]["coords"].toMap()["x"].toInt(), + m_recents[index]["coords"].toMap()["y"].toInt()); + } +} + +void NavitRecentsModel::addStop(int index, int position){ + if(m_recents.size() > index){ + NavitHelper::addStop(m_navitInstance, + position, + m_recents[index]["label"].toString(), + m_recents[index]["coords"].toMap()["x"].toInt(), + m_recents[index]["coords"].toMap()["y"].toInt()); + } +} + +void NavitRecentsModel::setAsPosition(int index){ + if(m_recents.size() > index){ + NavitHelper::setPosition(m_navitInstance, + m_recents[index]["coords"].toMap()["x"].toInt(), + m_recents[index]["coords"].toMap()["y"].toInt()); + } +} + +void NavitRecentsModel::addAsBookmark(int index){ + if(m_recents.size() > index){ + NavitHelper::addBookmark(m_navitInstance, + m_recents[index]["label"].toString(), + m_recents[index]["coords"].toMap()["x"].toInt(), + m_recents[index]["coords"].toMap()["y"].toInt()); + } +} + +void NavitRecentsModel::remove(int index) { + if(index < m_recents.size()){ + beginRemoveRows(QModelIndex(), index, index); + m_recents.removeAt(index); + endInsertRows(); + } +} diff --git a/navit/gui/qt5_qml/navitrecentsmodel.h b/navit/gui/qt5_qml/navitrecentsmodel.h index c33d01544..f040aa429 100644 --- a/navit/gui/qt5_qml/navitrecentsmodel.h +++ b/navit/gui/qt5_qml/navitrecentsmodel.h @@ -4,6 +4,7 @@ #include <QAbstractItemModel> #include <QDebug> #include "navitinstance.h" +#include "navithelper.h" #include <glib.h> extern "C" { @@ -32,10 +33,7 @@ class NavitRecentsModel : public QAbstractItemModel public: enum RecentsModelRoles { - NameRole = Qt::UserRole + 1, - CoordXRole, - CoordYRole, - CoordProjectionRole + LabelRole = Qt::UserRole + 1 }; explicit NavitRecentsModel(QObject *parent = 0); @@ -50,6 +48,12 @@ public: int columnCount(const QModelIndex &parent = QModelIndex()) const override; void setNavit(NavitInstance * navit); + + Q_INVOKABLE void setAsDestination(int index); + Q_INVOKABLE void setAsPosition(int index); + Q_INVOKABLE void addAsBookmark(int index); + Q_INVOKABLE void addStop(int index, int position); + Q_INVOKABLE void remove(int index); private: QList<QVariantMap> m_recents; NavitInstance *m_navitInstance = nullptr; diff --git a/navit/gui/qt5_qml/navitroute.cpp b/navit/gui/qt5_qml/navitroute.cpp new file mode 100644 index 000000000..18101eb0b --- /dev/null +++ b/navit/gui/qt5_qml/navitroute.cpp @@ -0,0 +1,167 @@ +#include "navitroute.h" + +NavitRoute::NavitRoute() +{ + +} +void listIcons(NavitInstance *navitInstance) { + struct attr attr; + navit_get_attr(navitInstance->getNavit(), attr_layout, &attr, nullptr); + + if(attr.u.layout && attr.u.layout->layers) { + qDebug() << "Got layout"; + GList* layers = attr.u.layout->layers; + while (layers) { + qDebug() << "Got layers"; + struct layer * l = (struct layer *)layers->data; + QString name = l->name; + if(name.contains("POI", Qt::CaseInsensitive)){ + GList * itemgras = l->itemgras; + while(itemgras){ + struct itemgra * itg = (struct itemgra *)itemgras->data; + GList * elements = itg->elements; + GList * types = itg->type; + while(elements){ + struct element * el = (struct element *)elements->data; + // struct attr itattr = (struct attr) g_list_nth(types, g_list_index(elements, elements->data)); + if(el->type == element::element_icon){ + qDebug () << "src : " << el->u.icon.src << "x : " << el->u.icon.x << "y : " << el->u.icon.y; + } + elements = g_list_next(elements); + } + itemgras = g_list_next(itemgras); + } + } + layers=g_list_next(layers); + } + } +} + +void NavitRoute::setNavit(NavitInstance * navit){ + m_navitInstance = navit; + + struct callback* cb = callback_new_attr_1(callback_cast(NavitRoute::routeCallbackHandler), + attr_position_coord_geo,this); + struct callback* cb2 = callback_new_attr_1(callback_cast(NavitRoute::destinationCallbackHandler), + attr_destination,this); + + struct route * route = navit_get_route(m_navitInstance->getNavit()); + m_destCount = route_get_destination_count(route); + + navit_add_callback(m_navitInstance->getNavit(),cb); + navit_add_callback(m_navitInstance->getNavit(),cb2); + + struct navit * tst = navit->getNavit(); + +} + +void NavitRoute::routeUpdate(){ +// listIcons(m_navitInstance); + struct map * map = nullptr; + struct map_rect * mr = nullptr; + struct navigation * nav = nullptr; + struct attr attr,route; + struct item * item = nullptr; + + nav = navit_get_navigation(m_navitInstance->getNavit()); + if(!nav) { + return; + } + map = navigation_get_map(nav); + if(map) + mr = map_rect_new(map,nullptr); + if(mr) { + if (navit_get_attr(m_navitInstance->getNavit(), attr_route, &route, nullptr)) { + struct attr destination_length, destination_time; + char *distance=nullptr,*timeLeft=nullptr; + if (route_get_attr(route.u.route, attr_destination_length, &destination_length, nullptr)) + distance=attr_to_text_ext(&destination_length, nullptr, attr_format_with_units, attr_format_default, nullptr); + if (route_get_attr(route.u.route, attr_destination_time, &destination_time, nullptr)) + timeLeft=attr_to_text_ext(&destination_time, nullptr, attr_format_with_units, attr_format_default, nullptr); + QStringList timeLeftArr = QString(timeLeft).split(":"); + QDateTime dt = QDateTime::currentDateTime(); + QTime time; + + switch (timeLeftArr.size()) { + case 4: + dt = dt.addDays(timeLeftArr[0].toInt()); + time.setHMS(timeLeftArr[1].toInt(),timeLeftArr[2].toInt(),timeLeftArr[3].toInt()); + break; + case 3: + time.setHMS(timeLeftArr[0].toInt(),timeLeftArr[1].toInt(),timeLeftArr[2].toInt()); + break; + case 2: + time.setHMS(0,timeLeftArr[0].toInt(),timeLeftArr[1].toInt()); + break; + case 1: + time.setHMS(0,0,timeLeftArr[0].toInt()); + break; + } + + dt = dt.addMSecs(time.msecsSinceStartOfDay()); + + m_distance = distance; + m_timeLeft = timeLeft; + m_arrivalTime = dt.toString("hh:mm"); + } + + m_directions.clear(); + while((item = map_rect_get_item(mr))) { + if(item_attr_get(item,attr_navigation_long,&attr)) { + m_directions << map_convert_string_tmp(item->map,attr.u.str); + } + } + emit propertiesChanged(); + } + map_rect_destroy(mr); +} + +void NavitRoute::destinationUpdate(){ + struct route * route = navit_get_route(m_navitInstance->getNavit()); + int destCount = route_get_destination_count(route); + + if(destCount > m_destCount){ + emit destinationAdded(); + } else if (destCount < m_destCount) { + emit destinationRemoved(); + } + if(destCount == 0){ + emit navigationFinished(); + } + m_destCount = destCount; +} +void NavitRoute::routeCallbackHandler(NavitRoute * navitRoute){ + navitRoute->routeUpdate(); +} +void NavitRoute::destinationCallbackHandler(NavitRoute * navitRoute){ + navitRoute->destinationUpdate(); +} + +void NavitRoute::cancelNavigation(){ + if(m_navitInstance){ + navit_set_destination(m_navitInstance->getNavit(), nullptr, nullptr, 0); + } +} + +void NavitRoute::setDestination(QString label, int x, int y){ + if(m_navitInstance){ + cancelNavigation(); + struct pcoord c = NavitHelper::positionToPcoord(m_navitInstance, x, y); + NavitHelper::setDestination(m_navitInstance, label, c.x, c.y); + } +} + +void NavitRoute::setPosition(int x, int y){ + if(m_navitInstance){ + struct pcoord c = NavitHelper::positionToPcoord(m_navitInstance, x, y); + navit_set_position(m_navitInstance->getNavit(), &c); + NavitHelper::setPosition(m_navitInstance, c.x, c.y); + } +} + +void NavitRoute::addStop(QString label, int x, int y, int position){ + if(m_navitInstance){ + struct pcoord c = NavitHelper::positionToPcoord(m_navitInstance, x, y); + NavitHelper::addStop(m_navitInstance, position, label, c.x, c.y); + } +} diff --git a/navit/gui/qt5_qml/navitroute.h b/navit/gui/qt5_qml/navitroute.h new file mode 100644 index 000000000..8ff4ab5ab --- /dev/null +++ b/navit/gui/qt5_qml/navitroute.h @@ -0,0 +1,82 @@ +#ifndef NAVITROUTE_H +#define NAVITROUTE_H + +#include <QObject> +#include <QDebug> +#include <QTime> +#include "navitinstance.h" + +#include <glib.h> +extern "C" { +#include "config.h" +#include "item.h" /* needs to be first, as attr.h depends on it */ +#include "navit.h" + +#include "coord.h" +#include "attr.h" +#include "xmlconfig.h" // for NAVIT_OBJECT +#include "layout.h" +#include "map.h" +#include "transform.h" + +#include "mapset.h" +#include "search.h" +#include "bookmarks.h" + +#include "callback.h" +#include "route.h" +#include "navigation.h" +#include "layout.h" + +#include "proxy.h" +} + +#include "navithelper.h" + +class NavitRoute : public QObject +{ + Q_OBJECT + Q_PROPERTY(NavitInstance * navit MEMBER m_navitInstance WRITE setNavit) + Q_PROPERTY(QStringList directions READ getDirections NOTIFY propertiesChanged) + Q_PROPERTY(QString distance READ getDistance NOTIFY propertiesChanged) + Q_PROPERTY(QString timeLeft READ getTimeLeft NOTIFY propertiesChanged) + Q_PROPERTY(QString arrivalTime READ getArrivalTime NOTIFY propertiesChanged) +public: + NavitRoute(); + void setNavit(NavitInstance * navit); + static void routeCallbackHandler(NavitRoute * navitRoute); + static void destinationCallbackHandler(NavitRoute * navitRoute); + void routeUpdate(); + void destinationUpdate(); + Q_INVOKABLE void setDestination(QString label, int x, int y); + Q_INVOKABLE void setPosition(int x, int y); + Q_INVOKABLE void addStop(QString label, int x, int y, int position); + Q_INVOKABLE void cancelNavigation(); +signals: + void propertiesChanged(); + void destinationAdded(); + void destinationRemoved(); + void navigationFinished(); +private: + NavitInstance *m_navitInstance = nullptr; + QStringList m_directions; + QString m_distance; + QString m_timeLeft; + QString m_arrivalTime; + int m_destCount; + + QStringList getDirections() { + return m_directions; + } + QString getDistance() { + return m_distance; + } + QString getTimeLeft() { + return m_timeLeft; + } + QString getArrivalTime() { + return m_arrivalTime; + } +}; + +#endif // NAVITROUTE_H diff --git a/navit/gui/qt5_qml/navitsearchmodel.cpp b/navit/gui/qt5_qml/navitsearchmodel.cpp new file mode 100644 index 000000000..d62715c51 --- /dev/null +++ b/navit/gui/qt5_qml/navitsearchmodel.cpp @@ -0,0 +1,336 @@ +#include "navitsearchmodel.h" + +#include "event.h" + +NavitSearchModel::NavitSearchModel(QObject *parent) +{ +} + + +QHash<int, QByteArray> NavitSearchModel::roleNames() const{ + QHash<int, QByteArray> roles; + roles[LabelRole] = "label"; + roles[NameRole] = "name"; + roles[IconRole] = "icon"; + roles[AddressRole] = "address"; + roles[DistanceRole] = "distance"; + + return roles; +} + +QVariant NavitSearchModel::data(const QModelIndex & index, int role) const { + if (index.row() < 0 || index.row() >= m_searchResults.count()) + return QVariant(); + + const QVariantMap *poi = &m_searchResults.at(index.row()); + + if (role == LabelRole) + return poi->value("label"); + else if (role == NameRole) + return poi->value("label"); + else if (role == IconRole) + return poi->value("icon"); + else if (role == AddressRole) + return poi->value("address"); + else if (role == DistanceRole) + return poi->value("distance"); + return QVariant(); +} + + +int NavitSearchModel::rowCount(const QModelIndex & parent) const { + return m_searchResults.count(); +} + +Qt::ItemFlags NavitSearchModel::flags(const QModelIndex &index) const { + return Qt::ItemIsEnabled | Qt::ItemIsSelectable; +} + +bool NavitSearchModel::setData(const QModelIndex &index, const QVariant &value, int role) { + return false; +} + +QModelIndex NavitSearchModel::index(int row, int column, const QModelIndex &parent) const { + return createIndex(row, column); +} + +QModelIndex NavitSearchModel::parent(const QModelIndex &child) const { + return QModelIndex(); +} + +int NavitSearchModel::columnCount(const QModelIndex &parent) const { + return 0; +} + +void NavitSearchModel::setNavit(NavitInstance * navit){ + m_navitInstance = navit; + + struct mapset * ms = navit_get_mapset(m_navitInstance->getNavit()); + m_searchResultList=search_list_new(ms); + search_list_set_default_country(); + + m_search_type = attr_town_or_district_name; +} + +void NavitSearchModel::handleSearchResult(){ + struct search_list_result *res; + + res=search_list_get_result(m_searchResultList); + if (!res) { + idle_end(); + return; + } + + + QVariantMap result; + QString label; + QString icon; + QStringList address; + + if (res->country) { + label = g_strdup(res->country->name); + icon = res->country->flag; + address.append(label); + } + + if (res->town) { + label = g_strdup(res->town->common.town_name); + icon = "icons/bigcity.png"; + address.append(label); + } + + if (res->street) { + label = g_strdup(res->street->name); + icon = "icons/smallcity.png"; + address.append(label); + } + + + qDebug() << label; + + result.insert("label", label); + result.insert("icon", icon); + + result.insert("address", address.join(", ")); + result.insert("distance", 1); + + beginInsertRows(QModelIndex(), rowCount(), rowCount()); + m_searchResults.append(result); + endInsertRows(); + + qDebug() << result["label"]; + +} +void NavitSearchModel::idle_cb(NavitSearchModel * searchModel){ + searchModel->handleSearchResult(); +} + +void NavitSearchModel::idle_start(){ + m_idle_cb = callback_new_1(callback_cast(idle_cb), this); + m_event_idle = event_add_idle(50,m_idle_cb); + callback_call_0(m_idle_cb); +} + +void NavitSearchModel::idle_end(){ + if (m_event_idle != nullptr) { + event_remove_idle(m_event_idle); + m_event_idle=nullptr; + } + if (m_idle_cb != nullptr) { + callback_destroy(m_idle_cb); + m_idle_cb=nullptr; + } +} + +void NavitSearchModel::search2(QString queryText){ + struct search_list_result *res; + + struct attr attr; + QString label; + QString icon; + + + if(!m_search_type){ + m_search_type = attr_country_all; + } + + attr.u.str = queryText.toUtf8().data(); + attr.type = m_search_type; + + search_list_search(m_searchResultList, &attr, 1); + int count = 0; + + beginResetModel(); + m_searchResults.clear(); + endResetModel(); + + while((res=search_list_get_result(m_searchResultList))) { + + QVariantMap result; + QStringList address; + + if (res->country) { + label = g_strdup(res->country->name); + icon = res->country->flag; + address.append(label); + } + + if (res->town) { + label = g_strdup(res->town->common.town_name); + icon = "icons/bigcity.png"; + address.append(label); + } + + if (res->street) { + label = g_strdup(res->street->name); + icon = "icons/smallcity.png"; + address.append(label); + } + + + + result.insert("label", label); + result.insert("icon", icon); + result.insert("address", address.join(", ")); + + beginInsertRows(QModelIndex(), rowCount(), rowCount()); + m_searchResults.append(result); + endInsertRows(); + + if (count ++ > 50) { + break; + } + qDebug() << icon << label; + } +} + +void NavitSearchModel::search(QString queryText){ + if(queryText == ""){ + return; + } + struct attr attr; + + idle_end(); + + beginResetModel(); + m_searchResults.clear(); + endResetModel(); + + attr.u.str = queryText.toLocal8Bit().data(); + attr.type = m_search_type; + + qDebug () << "searching : " << queryText.toLocal8Bit().data(); + search_list_search(m_searchResultList, &attr, 1); + idle_start(); +} + +void NavitSearchModel::search_list_set_default_country() { + struct attr search_attr, country_name, country_iso2, *country_attr; + struct item *item; + struct country_search *cs; + struct tracking *tracking; + struct search_list_result *res; + + country_attr=country_default(); + tracking=navit_get_tracking(m_navitInstance->getNavit()); + if (tracking && tracking_get_attr(tracking, attr_country_id, &search_attr, nullptr)) + country_attr=&search_attr; + if (country_attr) { + cs=country_search_new(country_attr, 0); + item=country_search_get_item(cs); + if (item && item_attr_get(item, attr_country_name, &country_name)) { + search_attr.type=attr_country_all; + qDebug() << "country " << country_name.u.str; + search_attr.u.str=country_name.u.str; + search_list_search(m_searchResultList, &search_attr, 0); + while((res=search_list_get_result(m_searchResultList))); + if(m_country_iso2) { + g_free(m_country_iso2); + this->m_country_iso2=nullptr; + } + if (item_attr_get(item, attr_country_iso2, &country_iso2)) + this->m_country_iso2=g_strdup(country_iso2.u.str); + } + country_search_destroy(cs); + } else { + qWarning() << "warning: no default country found"; + if (m_country_iso2) { + qDebug() << "attempting to use country" << m_country_iso2; + search_attr.type=attr_country_iso2; + search_attr.u.str=m_country_iso2; + search_list_search(m_searchResultList, &search_attr, 0); + while((res=search_list_get_result(m_searchResultList))); + } + } + search_list_select(m_searchResultList, attr_country_all, 0, 0); +} + + +void NavitSearchModel::select(int index){ + qDebug() << "Select : " << index; + + beginResetModel(); + m_searchResults.clear(); + endResetModel(); + + search_list_select(m_searchResultList, m_search_type, 0, 0); + search_list_select(m_searchResultList, m_search_type, index, 1); + + switch(m_search_type){ + case attr_country_all: + m_search_type = attr_town_or_district_name; + break; + case attr_town_or_district_name: + m_search_type = attr_street_name; + break; + case attr_street_name: + m_search_type = attr_house_number; + break; + case attr_house_number: + break; + } +} + +void NavitSearchModel::setAsDestination(int index){ + // if(m_recents.size() > index){ + // NavitHelper::setDestination(m_navitInstance, + // m_recents[index]["label"].toString(), + // m_recents[index]["coords"].toMap()["x"].toInt(), + // m_recents[index]["coords"].toMap()["y"].toInt()); + // } +} + +void NavitSearchModel::addStop(int index, int position){ + // if(m_recents.size() > index){ + // NavitHelper::addStop(m_navitInstance, + // position, + // m_recents[index]["label"].toString(), + // m_recents[index]["coords"].toMap()["x"].toInt(), + // m_recents[index]["coords"].toMap()["y"].toInt()); + // } +} + +void NavitSearchModel::setAsPosition(int index){ + // if(m_recents.size() > index){ + // NavitHelper::setPosition(m_navitInstance, + // m_recents[index]["coords"].toMap()["x"].toInt(), + // m_recents[index]["coords"].toMap()["y"].toInt()); + // } +} + +void NavitSearchModel::addAsBookmark(int index){ + // if(m_recents.size() > index){ + // NavitHelper::addBookmark(m_navitInstance, + // m_recents[index]["label"].toString(), + // m_recents[index]["coords"].toMap()["x"].toInt(), + // m_recents[index]["coords"].toMap()["y"].toInt()); + // } +} + +void NavitSearchModel::remove(int index) { + // if(index < m_recents.size()){ + // beginRemoveRows(QModelIndex(), index, index); + // m_recents.removeAt(index); + // endInsertRows(); + // } +} diff --git a/navit/gui/qt5_qml/navitsearchmodel.h b/navit/gui/qt5_qml/navitsearchmodel.h new file mode 100644 index 000000000..2245f169d --- /dev/null +++ b/navit/gui/qt5_qml/navitsearchmodel.h @@ -0,0 +1,96 @@ +#ifndef NAVITSEARCHMODEL_H +#define NAVITSEARCHMODEL_H + +#include <QAbstractItemModel> +#include <QDebug> +#include "navitinstance.h" +#include "navithelper.h" + +#include <glib.h> +extern "C" { +#include "config.h" +#include "item.h" /* needs to be first, as attr.h depends on it */ +#include "navit.h" + +#include "coord.h" +#include "attr.h" +#include "xmlconfig.h" // for NAVIT_OBJECT +#include "layout.h" +#include "map.h" +#include "transform.h" + +#include "mapset.h" +#include "callback.h" +#include "search.h" +#include "country.h" +#include "track.h" + +} + +class NavitSearchModel : public QAbstractItemModel +{ + Q_OBJECT + Q_PROPERTY(NavitInstance * navit MEMBER m_navitInstance WRITE setNavit) +public: + enum RecentsModelRoles { + LabelRole = Qt::UserRole + 1, + NameRole, + IconRole, + AddressRole, + DistanceRole + }; + + enum SearchField { + SearchCountry, + SearchTown, + SearchStreet, + SearchHouse + }; + + Q_ENUMS(SearchField) + + explicit NavitSearchModel(QObject *parent = 0); + int rowCount(const QModelIndex & parent = QModelIndex()) const override; + QHash<int, QByteArray> roleNames() const override; + QVariant data(const QModelIndex & index, int role) const override; + Qt::ItemFlags flags(const QModelIndex &index) const override; + bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override; + + QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override; + QModelIndex parent(const QModelIndex &child) const override; + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + void setNavit(NavitInstance * navit); + + Q_INVOKABLE void setAsDestination(int index); + Q_INVOKABLE void setAsPosition(int index); + Q_INVOKABLE void addAsBookmark(int index); + Q_INVOKABLE void addStop(int index, int position); + Q_INVOKABLE void remove(int index); + Q_INVOKABLE void select(int index); + Q_INVOKABLE void search(QString queryText); + Q_INVOKABLE void search2(QString queryText); + void search_list_set_default_country(); + static void idle_cb(NavitSearchModel * searchModel); + void handleSearchResult(); + +private: + NavitInstance *m_navitInstance = nullptr; + QList<QVariantMap> m_searchResults; + QString m_country = "United Kingdom"; + + struct callback * m_idle_cb; + struct event_idle * m_event_idle; + + struct search_list *m_searchResultList; + + char *m_country_iso2; + enum attr_type m_search_type; + void update(); + + void idle_start(); + void idle_end(); + void setDefaultCountry(); +}; + +#endif // NAVITSEARCHMODEL_H diff --git a/navit/gui/qt5_qml/themes/Levy/DestinationBar.qml b/navit/gui/qt5_qml/themes/Levy/DestinationBar.qml index 6488e4342..66dcdc084 100644 --- a/navit/gui/qt5_qml/themes/Levy/DestinationBar.qml +++ b/navit/gui/qt5_qml/themes/Levy/DestinationBar.qml @@ -8,6 +8,10 @@ Item { signal routeDetailsClicked() signal cancelButtonClicked() + property alias timeLeft: timeLeft.text + property alias distanceLeft: distanceLeft.text + property alias arrivalTime: arrivingTime.text + Rectangle{ id: buttonsBackground height: parent.height diff --git a/navit/gui/qt5_qml/themes/Levy/MainLayout.qml b/navit/gui/qt5_qml/themes/Levy/MainLayout.qml index 0df732bee..4eff9f812 100644 --- a/navit/gui/qt5_qml/themes/Levy/MainLayout.qml +++ b/navit/gui/qt5_qml/themes/Levy/MainLayout.qml @@ -3,6 +3,7 @@ import QtQuick.Controls 2.4 import QtQuick.Layouts 1.3 import Navit 1.0 import Navit.Graphics 2.0 +import Navit.Route 1.0 Item { id: __root @@ -10,9 +11,53 @@ Item { property string prevState: "" height: parent.height + QtObject { + id:navigation + + property int previous_pitch : 0 + property int previous_zoom : 0 + function routeOverview() { + previous_pitch = navit1.pitch; + __root.state = "routeOverview" + navit1.pitch = 0; + navit1.followVehicle = 0; + navit1.zoomToRoute(); + navit1.zoomOut(2); + } + + function startNavigation() { + __root.state = "" + __root.prevState = "" + mapNavigationBar.state = "navigationState" + + navit1.pitch = 45; + navit1.followVehicle = 1 + navit1.autoZoom = true + navit1.centerOnPosition() + } + + function cancelNavigation() { + __root.state = __root.prevState + __root.prevState = "" + navit1.followVehicle = 1; + } + } + + NavitRoute { + id:navitRoute + navit: Navit + onDestinationAdded: { + navigation.routeOverview(); + } + onNavigationFinished: { + mapNavigationBar.state = "" + } + } + NavitMap { id: navit1 - anchors.left: searchDrawer.right + // anchors.left: searchDrawer.right + anchors.leftMargin: 0 anchors.top: parent.top anchors.bottom: parent.bottom @@ -20,6 +65,12 @@ Item { navit:Navit } + Text { + x: 25 + y: 25 + text: "Zoom Level : " + navit1.zoomLevel + } + onStateChanged: { if(state != "mapControlsVisible") { mapControlsTimer.stop() @@ -39,11 +90,15 @@ Item { onClicked: { switch(mouse.button){ case Qt.LeftButton : - mapControls.showControls() + if(__root.state == ""){ + mapControls.showControls() + } break; case Qt.RightButton : + navit1.followVehicle = 0 pinpointPopup.mouseY = mouse.y pinpointPopup.mouseX = mouse.x + pinpointPopup.address = navit1.getAddress(mouse.x, mouse.y) pinpointPopup.open() break; } @@ -55,7 +110,7 @@ Item { } onPositionChanged: { - mapControls.showControls() + mapControls.restartTimer() hasMoved = true if(mouse.modifiers === Qt.ShiftModifier){ var pitch = Math.floor((originY - mouse.y) / 10); @@ -72,6 +127,7 @@ Item { navit1.orientation = orientation % 360 } else { + navit1.followVehicle = 0 navit1.mapMove(originX, originY, mouse.x, mouse.y); originX = mouse.x originY = mouse.y @@ -85,8 +141,10 @@ Item { } onPressAndHold: { if(!hasMoved){ + navit1.followVehicle = 0 pinpointPopup.mouseY = mouse.y pinpointPopup.mouseX = mouse.x + pinpointPopup.address = navit1.getAddress(mouse.x, mouse.y) pinpointPopup.open() } } @@ -112,7 +170,7 @@ Item { orientation: navit1.orientation autoZoom: navit1.autoZoom onDimensionClicked: { - showControls() + restartTimer() if(navit1.pitch != 0) { navit1.pitch = 0 } else { @@ -120,16 +178,16 @@ Item { } } onZoomInClicked: { - showControls() + restartTimer() navit1.zoomIn(2) } onZoomOutClicked: { - showControls() + restartTimer() navit1.zoomOut(2) } onZoomModeClicked: { - showControls() + restartTimer() navit1.autoZoom = !navit1.autoZoom } onCompassClicked: { @@ -143,6 +201,9 @@ Item { } mapControlsTimer.restart() } + function restartTimer() { + mapControlsTimer.restart() + } } @@ -154,6 +215,11 @@ Item { anchors.horizontalCenter: parent.horizontalCenter anchors.bottomMargin: parent.height * 0.05 anchors.bottom: parent.bottom + + timeLeft: navitRoute.timeLeft + distanceLeft: navitRoute.distance + arrivalTime: navitRoute.arrivalTime + onSearchButtonClicked: { __root.state = "searchDrawerOpen" searchDrawer.open() @@ -174,21 +240,61 @@ Item { anchors.bottom: parent.bottom anchors.horizontalCenter: parent.horizontalCenter + timeLeft: navitRoute.timeLeft + distanceLeft: navitRoute.distance + arrivalTime: navitRoute.arrivalTime onCancelButtonClicked: { - __root.state = __root.prevState + navigation.cancelNavigation(); } onRouteDetailsClicked: { } onStartButtonClicked: { - __root.state = "" - mapNavigationBar.state = "navigationState" - __root.prevState = "" - navit1.centerOnVehicle() - navit1.followVehicle = true - navit1.autoZoom = true + navigation.startNavigation(); } } + Item { + id: recenterButton + width: parent.width > parent.height ? parent.height * 0.1 : parent.width * 0.1 + height: width + x: navit1.followVehicle? parent.width : parent.width - ((parent.width * 0.025) + (mapNavigationBar.height / 2)) - (width / 2) + anchors.verticalCenter: parent.verticalCenter + Behavior on x { + NumberAnimation { duration: 200 } + } + + Rectangle { + id: rectangle1 + color: "#ffffff" + radius: width/2 + border.width: 1 + anchors.fill: parent + } + + Image { + id: image + width: parent.width * 0.8 + height: width + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + source: "qrc:/themes/Levy/assets/ionicons/md-locate.svg" + fillMode: Image.PreserveAspectFit + mipmap: true + } + + MouseArea { + id: mouseArea1 + width: 71 + anchors.fill: parent + onClicked: { + navit1.followVehicle = 1 + navit1.autoZoom = true + navit1.centerOnPosition() + } + } + + } + Rectangle { id: rectangle color: "#00000000" @@ -232,30 +338,22 @@ Item { onMenuItemClicked: { switch (action) { case "setDestination": - navit1.setDestination(mouseX, mouseY) - navit1.pitch = 0; - __root.state = "routeOverview" - navit1.zoomToRoute(); - navit1.zoomOut(2); + navitRoute.setDestination(pinpointPopup.address, mouseX, mouseY) break; - case "setWaypoint": + case "addStop": + navitRoute.addStop(pinpointPopup.address, mouseX, mouseY, 0) break; case "setPosition": - navit1.setPosition(mouseX, mouseY) - console.log("Setting position") + navitRoute.setPosition(mouseX, mouseY) break; case "bookmark": - navit1.addBookmark("asasdad", mouseX, mouseY); - console.log("Adding bookmark") + navit1.addBookmark(pinpointPopup.address, mouseX, mouseY); break; case "pois": break; } pinpointPopup.close() } - onOpened: { -// coordinates = navit1.positionToCoordinates(mouseX, mouseY) - } } SearchDrawer { @@ -275,10 +373,6 @@ Item { __root.state = "" __root.prevState = "" } - onRouteOverview: { - __root.prevState = __root.state - __root.state = "routeOverview" - } } MenuDrawer { @@ -289,21 +383,21 @@ Item { height: parent.height visible: false onCloseMenu : { - __root.state = __root.prevState - __root.prevState = "" + navigation.cancelNavigation() } onRouteOverview : { - __root.state = __root.prevState - __root.prevState = "" - navit1.zoomToRoute() + navigation.routeOverview() } onCancelRoute : { __root.state = "" mapNavigationBar.state = "" + navitRoute.cancelNavigation(); } } + + states: [ State { name: "mapControlsVisible" @@ -324,23 +418,22 @@ Item { PropertyChanges { target: rectangle - visible: false - } - - PropertyChanges { - target: rectangle - color: parent.width > parent.height ? "#00000000" : "#a6000000" - visible: parent.width < parent.height + // color: parent.width > parent.height ? "#00000000" : "#a6000000" + // visible: parent.width < parent.height + color: "#a6000000" + visible: true } PropertyChanges { target: mouseArea4 - enabled: parent.width < parent.height + // enabled: true + enabled: false } PropertyChanges { target: navit1 - width: parent.width > parent.height ? parent.width - searchDrawer.width : parent.width + //width: parent.width > parent.height ? parent.width - searchDrawer.width : parent.width + } }, State { @@ -552,9 +645,29 @@ Item { + + + + + + + + + + + + + + + + /*##^## Designer { D{i:0;height:720;width:1280}D{i:4;anchors_x:196}D{i:5;anchors_width:200;anchors_x:196} -D{i:6;anchors_height:100;anchors_width:100}D{i:8;anchors_y:109}D{i:7;anchors_height:100;anchors_width:100} -D{i:9;anchors_y:109}D{i:21;anchors_height:200;anchors_width:200}D{i:23;anchors_height:200;anchors_width:200} +D{i:6;anchors_height:100;anchors_width:100}D{i:7;anchors_height:100;anchors_width:100} +D{i:8;anchors_y:109}D{i:10;anchors_height:200;anchors_width:200}D{i:11;anchors_height:100;anchors_width:100} +D{i:12;anchors_height:100;anchors_width:100;anchors_y:109}D{i:9;anchors_y:109}D{i:13;anchors_y:109} +D{i:22;anchors_height:200;anchors_width:200}D{i:23;anchors_height:200;anchors_width:200} +D{i:24;anchors_height:200;anchors_width:200}D{i:26;anchors_height:200;anchors_width:200} +D{i:27;anchors_height:200;anchors_width:200}D{i:25;anchors_height:200;anchors_width:200} } ##^##*/ diff --git a/navit/gui/qt5_qml/themes/Levy/MapNavigationBar.qml b/navit/gui/qt5_qml/themes/Levy/MapNavigationBar.qml index a463f6fb8..9c37b0721 100644 --- a/navit/gui/qt5_qml/themes/Levy/MapNavigationBar.qml +++ b/navit/gui/qt5_qml/themes/Levy/MapNavigationBar.qml @@ -5,6 +5,9 @@ Item { id: __root signal searchButtonClicked() signal menuButtonClicked() + property alias timeLeft: timeLeft.text + property alias distanceLeft: distanceLeft.text + property alias arrivalTime: arrivingTime.text Rectangle { id: leftButton diff --git a/navit/gui/qt5_qml/themes/Levy/MapPinpointPopup.qml b/navit/gui/qt5_qml/themes/Levy/MapPinpointPopup.qml index 0fdb03083..e89b709e4 100644 --- a/navit/gui/qt5_qml/themes/Levy/MapPinpointPopup.qml +++ b/navit/gui/qt5_qml/themes/Levy/MapPinpointPopup.qml @@ -8,6 +8,7 @@ Popup { id:__root property string verticalPosition: "top" property string horizontalPosition: "left" + property alias address: address.text property int xOffset: __root.horizontalPosition == "left"? __root.width * 0.1 : 0 property int yOffset: __root.verticalPosition == "top"? __root.width * 0.1 : 0 signal menuItemClicked (var action) @@ -78,73 +79,111 @@ Popup { } } - ColumnLayout { - id: menuItems + Item{ + id:menuWrapper x: __root.xOffset y: __root.yOffset width: parent.width - __root.width * 0.1 height: parent.height - __root.width * 0.1 - Repeater { - id: menuElementsRepeater - model: ListModel { - ListElement { - name: "Set as destination" - action: "setDestination" - } - ListElement { - name: "Visit before.." - action: "setWaypoint" - } - ListElement { - name: "Set as position" - action: "setPosition" - } - ListElement { - name: "Add as bookmark" - action: "bookmark" - } - ListElement { - name: "POIs" - action: "pois" - } + Rectangle { + id: rectangle + height: parent.height * 0.2 + color: "#a2a2a2" + anchors.top: parent.top + anchors.topMargin: 0 + anchors.left: parent.left + anchors.leftMargin: 0 + anchors.right: parent.right + + Text { + id: address + text: qsTr("Address") + font.pixelSize: parent.height * 0.2 + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + anchors.fill: parent } - Item { - id: element - Layout.fillHeight: true - Layout.fillWidth: true - - Text { - id:nameText - text: name - fontSizeMode: Text.Fit - font.pixelSize: (menuItems.height / menuElementsRepeater.count) * 0.45 - anchors.verticalCenter: parent.verticalCenter - font.bold: true - } + } - Rectangle { - visible: menuElementsRepeater.count !== index + 1 - height: 1 - color: "#000000" - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.leftMargin: 0 - anchors.right: parent.right + ColumnLayout { + id: menuItems + anchors.top: rectangle.bottom + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.left: parent.left + + Repeater { + id: menuElementsRepeater + model: ListModel { + ListElement { + name: "Set as destination" + action: "setDestination" + } + ListElement { + name: "Visit before.." + action: "addStop" + } + ListElement { + name: "Set as position" + action: "setPosition" + } + ListElement { + name: "Add as bookmark" + action: "bookmark" + } + ListElement { + name: "POIs" + action: "pois" + } } - MouseArea { - anchors.fill: parent - onClicked: { - __root.menuItemClicked(action) + Item { + id: element + Layout.fillHeight: true + Layout.fillWidth: true + + Text { + id:nameText + text: name + fontSizeMode: Text.Fit + font.pixelSize: (menuItems.height / menuElementsRepeater.count) * 0.45 + anchors.verticalCenter: parent.verticalCenter + font.bold: true + } + + Rectangle { + visible: menuElementsRepeater.count !== index + 1 + height: 1 + color: "#000000" + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.leftMargin: 0 + anchors.right: parent.right + } + MouseArea { + anchors.fill: parent + onClicked: { + __root.menuItemClicked(action) + } } } } + + } + } } + + + + + + /*##^## Designer { - D{i:0;autoSize:true;height:720;width:1280}D{i:2;anchors_width:80}D{i:1;anchors_height:200;anchors_width:200} + D{i:0;autoSize:true;height:720;width:1280}D{i:7;anchors_width:200;anchors_x:0;anchors_y:0} +D{i:2;anchors_width:80}D{i:1;anchors_height:200;anchors_width:200} } ##^##*/ diff --git a/navit/gui/qt5_qml/themes/Levy/NavitMain.qml b/navit/gui/qt5_qml/themes/Levy/NavitMain.qml index 2d1940101..cf6bda53d 100644 --- a/navit/gui/qt5_qml/themes/Levy/NavitMain.qml +++ b/navit/gui/qt5_qml/themes/Levy/NavitMain.qml @@ -19,6 +19,6 @@ Window { property alias y: window.y property alias width: window.width property alias height: window.height - property alias modality : window.modality +// property alias modality : window.modality } } diff --git a/navit/gui/qt5_qml/themes/Levy/SearchDrawer.qml b/navit/gui/qt5_qml/themes/Levy/SearchDrawer.qml index b1a328664..dd60c9410 100644 --- a/navit/gui/qt5_qml/themes/Levy/SearchDrawer.qml +++ b/navit/gui/qt5_qml/themes/Levy/SearchDrawer.qml @@ -5,6 +5,7 @@ import QtQuick.Layouts 1.3 import Navit 1.0 import Navit.POI 1.0 import Navit.Recents 1.0 +import Navit.Search 1.0 Item { id: __root @@ -12,7 +13,6 @@ Item { signal openSearch() signal closeSearch() signal closeDrawer() - signal routeOverview() function open() { stackView.clear() @@ -32,6 +32,11 @@ Item { } } + NavitSearchModel { + id: searchModel + navit: Navit + } + Rectangle { id: contentRect color: "#a4a4a4" @@ -60,7 +65,6 @@ Item { anchors.right: parent.right anchors.bottom: parent.bottom anchors.left: parent.left - POIs { id: pois height: __root.width > __root.height ? parent.height * 0.25 : parent.width * 0.25 @@ -73,8 +77,11 @@ Item { return; } - navitPoiModel.search(__root.lng, __root.lat, action) - stackView.push(searchResultsComponents,{model:navitPoiModel}) + console.log(action + " pois clicked"); + + navitPoiModel.search(action) + + stackView.push(searchResultsComponents,{results:navitPoiModel}) __root.state = "poiView" } } @@ -132,8 +139,9 @@ Item { Item { id: searchWrapper height: parent.height + anchors.top: parent.top + anchors.topMargin: 0 anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter clip: true width: parent.width @@ -194,9 +202,11 @@ Item { onPressed: { __root.state = "searchOpen" __root.openSearch() + stackView.push(searchResultsComponents,{results:searchModel}) } onTextChanged: { - backend.updateSearch(text) +// backend.updateSearch(text) + searchModel.search2(text) } } @@ -284,7 +294,6 @@ Item { height: parent.height * 0.8 anchors.top: parent.top anchors.bottom: parent.bottom - anchors.verticalCenter: parent.verticalCenter source: "assets/ionicons/md-arrow-back.svg" sourceSize.width: width sourceSize.height: height @@ -296,6 +305,7 @@ Item { onClicked: { __root.state = "" __root.closeSearch() + console.log("Back button clicked"); } } } @@ -307,7 +317,6 @@ Item { radius: height / 2 anchors.top: parent.top anchors.bottom: parent.bottom - anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right Image { id: image4 @@ -330,6 +339,110 @@ Item { } } } + + Item { + id: element2 + width: parent.width + visible: false + anchors.topMargin: parent.height * 0.2 + anchors.top: searchWrapper.bottom + anchors.bottom: parent.bottom + + Rectangle { + id: leftBlob + width: height + height: parent.height + color: "#ffffff" + radius: height/2 + } + + Rectangle { + id: rightBlob + width: height + height: parent.height + color: "#ffffff" + radius: height/2 + anchors.rightMargin: -width/2 + anchors.right: breadcrumbs.right + } + + RowLayout { + id: breadcrumbs + width: parent.width - parent.height + anchors.leftMargin: leftBlob.width / 2 + anchors.left: leftBlob.left + anchors.bottom: parent.bottom + anchors.top: parent.top + spacing: 0 + + Rectangle { + id: rectangle1 + color: "#ffffff" + visible: true + Layout.fillHeight: true + Layout.fillWidth: true + + Text { + id: element3 + text: qsTr("Country") + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 12 + } + } + + Rectangle { + id: rectangle2 + color: "#ffffff" + visible: true + Layout.fillHeight: true + Layout.fillWidth: true + + Text { + id: element4 + text: qsTr("Town") + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 12 + } + } + + Rectangle { + id: rectangle4 + color: "#ffffff" + visible: false + Layout.fillHeight: true + Layout.fillWidth: true + + Text { + id: element5 + text: qsTr("Street") + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 12 + } + } + + Rectangle { + id: rectangle3 + color: "#ffffff" + visible: false + Layout.fillHeight: true + Layout.fillWidth: true + + Text { + id: element6 + text: qsTr("House") + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + font.pixelSize: 12 + } + } + + } + + + } } } @@ -338,10 +451,6 @@ Item { id:navitPoiModel navit: Navit } - NavitRecentsModel { - id:navitRecentsModel - navit: Navit - } Component{ id:mainComponent @@ -355,7 +464,14 @@ Item { Component{ id:searchResultsComponents SearchDrawerSearchResults { - onResultClicked: __root.routeOverview() + onItemClicked: { + if(__root.state == "poiView"){ + navitPoiModel.setAsDestination(index) + } else if(__root.state == "searchOpen"){ + search.clear() + searchModel.select(index) + } + } } } states: [ @@ -383,6 +499,24 @@ Item { height: 0 visible: false } + + PropertyChanges { + target: searchWrapper + height: parent.height /2 + } + + PropertyChanges { + } + + PropertyChanges { + target: headerContainer + height: __root.width > __root.height ? parent.height * 0.2 : parent.width * 0.2 + } + + PropertyChanges { + target: element2 + visible: true + } }, State { name: "poiView" @@ -433,8 +567,16 @@ Item { + + + + + + /*##^## Designer { - D{i:0;autoSize:true;height:720;width:1000}D{i:2;anchors_height:200;anchors_width:200} -D{i:37;anchors_height:100;anchors_width:100;anchors_x:"-591";anchors_y:"-25"}D{i:38;anchors_height:200;anchors_width:200} + D{i:0;autoSize:true;height:720;width:1000}D{i:15;anchors_height:132.24}D{i:40;anchors_height:200;anchors_width:200;anchors_x:"-205";anchors_y:0} +D{i:42;anchors_height:200;anchors_width:200;anchors_x:"-205";anchors_y:0}D{i:44;anchors_height:200;anchors_width:200;anchors_x:"-205";anchors_y:0} +D{i:38;anchors_height:100;anchors_width:100;anchors_x:"-591";anchors_y:"-25"}D{i:2;anchors_height:200;anchors_width:200} +D{i:49;anchors_height:100;anchors_width:100;anchors_x:"-591";anchors_y:"-25"}D{i:50;anchors_height:200;anchors_width:200} } ##^##*/ diff --git a/navit/gui/qt5_qml/themes/Levy/SearchDrawerContextMenu.qml b/navit/gui/qt5_qml/themes/Levy/SearchDrawerContextMenu.qml new file mode 100644 index 000000000..e8497ebb1 --- /dev/null +++ b/navit/gui/qt5_qml/themes/Levy/SearchDrawerContextMenu.qml @@ -0,0 +1,32 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 + + +Menu { + id: __root + signal itemClicked(var action) + property alias addBookmarkVisible : addBookmark.visible + MenuItem { + text: "Set as destination" + onClicked: __root.itemClicked("setDestination") + } + MenuItem { + text: "Add a stop" + onClicked: __root.itemClicked("addStop") + } + MenuItem { + text: "Set as position" + onClicked: __root.itemClicked("setPosition") + } + MenuItem { + id: addBookmark + visible: true + text: "Add as bookmark" + onClicked: __root.itemClicked("addBookmark") + } + MenuItem { + text: "POIs" + onClicked: __root.itemClicked("pois") + } +} diff --git a/navit/gui/qt5_qml/themes/Levy/SearchDrawerFavouritesList.qml b/navit/gui/qt5_qml/themes/Levy/SearchDrawerFavouritesList.qml new file mode 100644 index 000000000..2d8c0baf6 --- /dev/null +++ b/navit/gui/qt5_qml/themes/Levy/SearchDrawerFavouritesList.qml @@ -0,0 +1,79 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 + +import Navit 1.0 +import Navit.Favourites 1.0 + +ListView { + id:__root + + clip: true + + Component.onCompleted: { + console.log("Favourites loaded"); + // navitFavouritesModel.showFavourites(); + } + + model: NavitFavouritesModel { + id:navitFavouritesModel + navit: Navit + } + + anchors.fill: parent + delegate: Item { + id: element + height: 40 + width: parent.width + + Text { + y: 0 + text: model.label + anchors.left: parent.left + font.bold: true + anchors.verticalCenter: parent.verticalCenter + } + + MouseArea { + id: mouseArea + anchors.fill : parent + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + if (mouse.button === Qt.LeftButton) + navitFavouritesModel.setAsDestination(index) + else if (mouse.button === Qt.RightButton) + contextMenu.popup() + } + onPressAndHold: { + if (mouse.source === Qt.MouseEventNotSynthesized) + contextMenu.popup() + } + SearchDrawerContextMenu { + id: contextMenu + addBookmarkVisible: false + onItemClicked: { + switch(action){ + case "addBookmark": + navitFavouritesModel.addAsBookmark(index) + break; + case "pois": + break; + case "setPosition": + navitFavouritesModel.setAsPosition(index) + break; + case "addStop": + navitFavouritesModel.addStop(index, 0) + break; + case "setDestination": + navitFavouritesModel.setAsDestination(index) + break; + } + } + + MenuItem { + text: "Delete" + } + } + } + } +} diff --git a/navit/gui/qt5_qml/themes/Levy/SearchDrawerMain.qml b/navit/gui/qt5_qml/themes/Levy/SearchDrawerMain.qml index ded10939b..7185eaf97 100644 --- a/navit/gui/qt5_qml/themes/Levy/SearchDrawerMain.qml +++ b/navit/gui/qt5_qml/themes/Levy/SearchDrawerMain.qml @@ -11,68 +11,6 @@ Item { property int boxRadius : 10 signal menuItemClicked(var index) - - QtObject { - id:navitPlaces - property ListModel favourites: ListModel{ - ListElement {name:"5462 Cursus Rd. Walsall E72 0SL United Kingdom"} - ListElement {name:"8202 Senectus Av. Brecon R5 1VC United Kingdom"} - ListElement {name:"776-4520 Donec Street Milton Keynes P2T 9HV United Kingdom"} - ListElement {name:"189-893 Amet St. Newtonmore G4X 9WS United Kingdom"} - ListElement {name:"2154 Vel, Street Peterborough Q33 9HT United Kingdom"} - ListElement {name:"Ap #819-2987 Cursus Street Milnathort BP5E 9CV United Kingdom"} - ListElement {name:"7821 Suspendisse St. Castletown E80 6QU United Kingdom"} - ListElement {name:"5904 Sed Avenue Penicuik TP9J 4UK United Kingdom"} - ListElement{name:"8713 Vitae St. Banchory JF3 7OO United Kingdom"} - ListElement{name:"849-8034 Phasellus St. Felixstowe W96 9VZ United Kingdom"} - ListElement{name:"673-1184 Fringilla Road Hartlepool C23 3MN United Kingdom"} - ListElement{name:"179-927 Diam. Road Banbury G6 2HP United Kingdom"} - ListElement{name:"4041 Non St. Wimborne Minster YI7N 1AA United Kingdom"} - ListElement{name:"3855 Convallis St. Lochranza M6 7MG United Kingdom"} - ListElement{name:"530-2361 Lorem, Avenue Redruth D3 3PF United Kingdom"} - ListElement{name:"863-5481 Vulputate, Road Pontypridd H3 1HZ United Kingdom"} - ListElement{name:"5507 Ut Road St. Andrews W3M 5XL United Kingdom"} - ListElement{name:"693-9635 Ipsum Ave Tobermory ZU26 5EH United Kingdom"} - ListElement{name:"781-1212 Dapibus Rd. Helmsdale GM9K 7FK United Kingdom"} - ListElement{name:"102-1859 Lorem Avenue Southend V6 5IQ United Kingdom"} - } - property ListModel recents: ListModel{ - ListElement {name:"539-2120 Lacus. Avenue Northampton ID1 5XG United Kingdom"} - ListElement {name:"649-2696 Arcu. Street Hartlepool WU1 0CL United Kingdom"} - ListElement {name:"1239 Odio Ave Lochranza XB9L 7JC United Kingdom"} - ListElement {name:"9722 Dui. Avenue Kington GD2N 2XH United Kingdom"} - ListElement {name:"309-9175 Pede St. Millport EQ1O 0FA United Kingdom"} - ListElement {name:"4455 Nunc, Rd. Ellon NL67 1OK United Kingdom"} - ListElement {name:"7176 Pede Road Tain I9 8SF United Kingdom"} - ListElement {name:"310-4519 Nulla Avenue Llanidloes G3K 7ZK United Kingdom"} - ListElement {name:"6786 Sagittis Road Margate C49 3FP United Kingdom"} - ListElement {name:"6456 Ut Av. Melton Mowbray ZH4 5NW United Kingdom"} - ListElement {name:"974-2380 Facilisis Rd. Grimsby YV29 6OT United Kingdom"} - ListElement {name:"5643 Enim. St. Marlborough O7N 1JU United Kingdom"} - ListElement {name:"798-6627 Urna. Ave Inverurie BY43 7NS United Kingdom"} - ListElement {name:"2248 Ipsum St. Southampton AV21 6AW United Kingdom"} - ListElement {name:"499-7436 Nulla Rd. Kingussie V5P 3VS United Kingdom"} - ListElement {name:"4426 Accumsan Av. Matlock I7 8TM United Kingdom"} - ListElement {name:"2829 Orci. St. March NR9Q 7TQ United Kingdom"} - ListElement {name:"1081 Nonummy Road Armadale M17 5AV United Kingdom"} - ListElement {name:"913-5445 Mus. Avenue Eastbourne FZ2 1UQ United Kingdom"} - ListElement {name:"375-2819 Aliquet. Ave Moffat V3 7WI United Kingdom"} - ListElement {name:"8962 Adipiscing Avenue Neath A0 3IH United Kingdom"} - ListElement {name:"9384 Sed, Street New Galloway B4K 1HP United Kingdom"} - ListElement {name:"3522 Feugiat Street Stoke-on-Trent S7Z 0FB United Kingdom"} - ListElement {name:"6383 Aliquam Rd. Kincardine HX8F 0EJ United Kingdom"} - } - } - - NavitRecentsModel { - id:navitRecentsModel - navit: Navit - } - NavitFavouritesModel { - id:navitFavouritesModel - navit: Navit - } - TabBar { id: tabBar height: parent.height * 0.1 @@ -104,8 +42,7 @@ Item { onCheckedChanged: { if(checked){ if(locationListLoader !== null) { - locationListLoader.sourceComponent = placesList - locationListLoader.item.model = navitRecentsModel + locationListLoader.sourceComponent = recentsList } } } @@ -130,9 +67,7 @@ Item { onCheckedChanged: { if(checked){ if(typeof(locationListLoader.status) != "null") { - locationListLoader.sourceComponent = placesList - locationListLoader.item.model = navitFavouritesModel - navitFavouritesModel.showFavourites(); + locationListLoader.sourceComponent = favouritesList } } @@ -171,63 +106,19 @@ Item { anchors.bottomMargin: parent.height * 0.05 anchors.leftMargin: parent.width * 0.05 anchors.rightMargin: parent.width * 0.05 - sourceComponent: placesList + sourceComponent: recentsList } } Component { - id:placesList - ListView { - id:listView - clip: true - model: navitRecentsModel - - anchors.fill: parent - delegate: Item { - id: element - height: 40 - width: parent.width - - Text { - y: 0 - text: model.name - anchors.left: parent.left - font.bold: true - anchors.verticalCenter: parent.verticalCenter - } - - MouseArea { - id: mouseArea - anchors.right: deleteButton.left - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.top: parent.top - onClicked: __root.menuItemClicked(name, action) - } - - - Item { - id: deleteButton - width: height - height: parent.height - anchors.right: parent.right - Image { - id: image - width: height - height: parent.height * 0.75 - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - source: "qrc:/themes/Levy/assets/ionicons/md-trash.svg" - fillMode: Image.PreserveAspectFit - } - - MouseArea { - id: mouseArea1 - anchors.fill: parent - } - } + id:recentsList + SearchDrawerRecentsList { + } + } - } + Component { + id:favouritesList + SearchDrawerFavouritesList { } } } diff --git a/navit/gui/qt5_qml/themes/Levy/SearchDrawerRecentsList.qml b/navit/gui/qt5_qml/themes/Levy/SearchDrawerRecentsList.qml new file mode 100644 index 000000000..2b37a0b52 --- /dev/null +++ b/navit/gui/qt5_qml/themes/Levy/SearchDrawerRecentsList.qml @@ -0,0 +1,67 @@ +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 + +import Navit 1.0 +import Navit.Recents 1.0 +ListView { + id:__root + clip: true + model: NavitRecentsModel { + id:navitRecentsModel + navit: Navit + } + + anchors.fill: parent + delegate: Item { + id: element + height: 40 + width: parent.width + + Text { + y: 0 + text: model.label + anchors.left: parent.left + font.bold: true + anchors.verticalCenter: parent.verticalCenter + } + + MouseArea { + id: mouseArea + anchors.fill: parent + + acceptedButtons: Qt.LeftButton | Qt.RightButton + onClicked: { + if (mouse.button === Qt.LeftButton) + navitRecentsModel.setAsDestination(index) + else if (mouse.button === Qt.RightButton) + contextMenu.popup() + } + onPressAndHold: { + if (mouse.source === Qt.MouseEventNotSynthesized) + contextMenu.popup() + } + SearchDrawerContextMenu { + id: contextMenu + onItemClicked: { + switch(action){ + case "addBookmark": + navitRecentsModel.addAsBookmark(index) + break; + case "pois": + break; + case "setPosition": + navitRecentsModel.setAsPosition(index) + break; + case "addStop": + navitRecentsModel.addStop(index, 0) + break; + case "setDestination": + navitRecentsModel.setAsDestination(index) + break; + } + } + } + } + } +} diff --git a/navit/gui/qt5_qml/themes/Levy/SearchDrawerSearchResults.qml b/navit/gui/qt5_qml/themes/Levy/SearchDrawerSearchResults.qml index 6d1193c38..188a777e3 100644 --- a/navit/gui/qt5_qml/themes/Levy/SearchDrawerSearchResults.qml +++ b/navit/gui/qt5_qml/themes/Levy/SearchDrawerSearchResults.qml @@ -6,26 +6,35 @@ import "icons.js" as Icons Item { id: __root - signal resultClicked() - property alias model: listView.model + signal itemClicked (var index) + property alias results : listView.model + property int boxRadius : 10 + clip: true + + Rectangle { + id: rectangle + color: "#ffffff" + anchors.fill: parent + radius: boxRadius + } ListView { id: listView + clip: true anchors.fill: parent + anchors.topMargin: parent.height * 0.05 + anchors.bottomMargin: parent.height * 0.05 + anchors.leftMargin: parent.width * 0.05 + anchors.rightMargin: parent.width * 0.05 delegate: Item { id: element - x: 5 height: 80 - MouseArea { - anchors.fill: parent - onClicked: __root.resultClicked() - } + width: parent.width Text { id: element1 text: name font.pointSize: 12 - anchors.verticalCenterOffset: -height/2 anchors.left: distanceText.right font.bold: true anchors.verticalCenter: parent.verticalCenter @@ -39,21 +48,52 @@ Item { anchors.bottom: parent.bottom anchors.top: element1.bottom anchors.left: distanceText.right - font.bold: true + font.bold: false } Text { id: distanceText - text: distance - font.pixelSize: parent.height * 0.8 + width: height * 2 + height: parent.height * 0.8 + text: (distance/1000).toFixed(1) + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter anchors.left: parent.left - anchors.leftMargin: 0 + font.pixelSize: height * 0.8 anchors.top: parent.top anchors.topMargin: 0 + } + + Text { + id: awayText + text: qsTr("kilometers away") + anchors.horizontalCenter: distanceText.horizontalCenter + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + anchors.top: distanceText.bottom anchors.bottom: parent.bottom + font.pixelSize: 12 + } + + MouseArea { + id: mouseArea + anchors.fill: parent + onClicked: { + __root.itemClicked(index) + } + + Rectangle { + color: "#33cb0b0b" + anchors.fill: parent + } } } } + } + + + + diff --git a/navit/gui/qt5_qml/themes/Levy/qmldir b/navit/gui/qt5_qml/themes/Levy/qmldir new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/navit/gui/qt5_qml/themes/Levy/qmldir |