1 /********************************************************************************************** 2 Copyright (C) 2014 Oliver Eichler <oliver.eichler@gmx.de> 3 Copyright (C) 2017 Norbert Truchsess <norbert.truchsess@t-online.de> 4 5 This program is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 **********************************************************************************************/ 19 20 #ifndef CGISWORKSPACE_H 21 #define CGISWORKSPACE_H 22 23 #include "ui_IGisWorkspace.h" 24 #include <QEvent> 25 #include <QSqlDatabase> 26 #include <QWidget> 27 28 #include "db/IDBFolder.h" 29 #include "gis/IGisItem.h" 30 #include "gis/rte/router/IRouter.h" 31 #include "gis/search/CSearchLineEdit.h" 32 #include "helpers/Tristate.h" 33 34 35 class CGisDraw; 36 class IGisProject; 37 class CSearchExplanationDialog; 38 struct poi_t; 39 40 enum event_types_e 41 { 42 eEvtD2WReqInfo = QEvent::User + 1 43 , eEvtD2WShowFolder = QEvent::User + 2 44 , eEvtD2WHideFolder = QEvent::User + 3 45 , eEvtD2WShowItems = QEvent::User + 4 46 , eEvtD2WHideItems = QEvent::User + 5 47 , eEvtD2WUpdateLnF = QEvent::User + 6 48 , eEvtD2WUpdateItems = QEvent::User + 7 49 , eEvtD2WReload = QEvent::User + 8 50 51 , eEvtW2DAckInfo = QEvent::User + 100 52 , eEvtW2DCreate = QEvent::User + 101 53 54 , eEvtA2WCutTrk = QEvent::User + 200 55 , eEvtA2WSave = QEvent::User + 201 56 , eEvtA2WSync = QEvent::User + 202 57 }; 58 59 struct evt_item_t 60 { evt_item_tevt_item_t61 evt_item_t(quint64 id, quint32 type) : id(id), type(type) 62 { 63 } 64 quint64 id; 65 quint32 type; 66 }; 67 68 class CEvtD2WReqInfo : public QEvent 69 { 70 public: CEvtD2WReqInfo(quint64 id,const QString & db)71 CEvtD2WReqInfo(quint64 id, const QString& db) : QEvent(QEvent::Type(eEvtD2WReqInfo)), id(id), db(db) 72 { 73 } 74 75 quint64 id; 76 QString db; 77 }; 78 79 class CEvtD2WShowFolder : public QEvent 80 { 81 public: CEvtD2WShowFolder(quint64 id,const QString & db)82 CEvtD2WShowFolder(quint64 id, const QString& db) : QEvent(QEvent::Type(eEvtD2WShowFolder)), id(id), db(db) 83 { 84 } 85 86 quint64 id; 87 QString db; 88 }; 89 90 class CEvtD2WHideFolder : public QEvent 91 { 92 public: CEvtD2WHideFolder(quint64 id,const QString & db)93 CEvtD2WHideFolder(quint64 id, const QString& db) : QEvent(QEvent::Type(eEvtD2WHideFolder)), id(id), db(db) 94 { 95 } 96 97 quint64 id; 98 QString db; 99 }; 100 101 class CEvtD2WShowItems : public QEvent 102 { 103 public: CEvtD2WShowItems(quint64 id,const QString & db)104 CEvtD2WShowItems(quint64 id, const QString& db) : QEvent(QEvent::Type(eEvtD2WShowItems)), id(id), db(db) 105 { 106 } 107 108 /// if true only the items in the list are loaded. Any other item loaded but not part of the list will be removed. 109 bool addItemsExclusively = false; 110 quint64 id; 111 QString db; 112 QList<evt_item_t> items; 113 }; 114 115 class CEvtD2WHideItems : public QEvent 116 { 117 public: CEvtD2WHideItems(quint64 id,const QString & db)118 CEvtD2WHideItems(quint64 id, const QString& db) : QEvent(QEvent::Type(eEvtD2WHideItems)), id(id), db(db) 119 { 120 } 121 122 quint64 id; 123 QString db; 124 QSet<QString> keys; 125 }; 126 127 class CEvtW2DAckInfo : public QEvent 128 { 129 public: CEvtW2DAckInfo(Qt::CheckState checkState,quint64 id,const QString & db,const QString & host)130 CEvtW2DAckInfo(Qt::CheckState checkState, quint64 id, const QString& db, const QString& host) 131 : QEvent(QEvent::Type(eEvtW2DAckInfo)) 132 , checkState(checkState) 133 , id(id) 134 , db(db) 135 , host(host) 136 { 137 } 138 CEvtW2DAckInfo(quint64 id,const QString & db,const QString & host)139 CEvtW2DAckInfo(quint64 id, const QString& db, const QString& host) 140 : QEvent(QEvent::Type(eEvtW2DAckInfo)) 141 , id(id) 142 , db(db) 143 , host(host) 144 { 145 } 146 147 Qt::CheckState checkState = Qt::Unchecked; 148 bool updateLostFound = false; 149 quint64 id; 150 QString db; 151 QString host; 152 QSet<QString> keysChildren; 153 }; 154 155 class CEvtD2WUpdateLnF : public QEvent 156 { 157 public: CEvtD2WUpdateLnF(quint64 id,const QString & db)158 CEvtD2WUpdateLnF(quint64 id, const QString& db) : QEvent(QEvent::Type(eEvtD2WUpdateLnF)), id(id), db(db) 159 { 160 } 161 162 quint64 id; 163 QString db; 164 }; 165 166 class CEvtW2DCreate : public QEvent 167 { 168 public: CEvtW2DCreate(const QString & name,IDBFolder::type_e type,quint64 id,const QString & db,const QString & host)169 CEvtW2DCreate(const QString& name, IDBFolder::type_e type, quint64 id, const QString& db, const QString& host) 170 : QEvent(QEvent::Type(eEvtW2DCreate)) 171 , name(name) 172 , type(type) 173 , idParent(id) 174 , db(db) 175 , host(host) 176 { 177 } 178 179 QString name; 180 IDBFolder::type_e type; 181 quint64 idParent; 182 quint64 idChild = 0; 183 QString db; 184 QString host; 185 }; 186 187 class CEvtD2WUpdateItems : public QEvent 188 { 189 public: CEvtD2WUpdateItems(quint64 id,const QString & db)190 CEvtD2WUpdateItems(quint64 id, const QString& db) : QEvent(QEvent::Type(eEvtD2WUpdateItems)), id(id), db(db) 191 { 192 } 193 194 quint64 id; 195 QString db; 196 }; 197 198 class CEvtD2WReload : public QEvent 199 { 200 public: CEvtD2WReload(const QString & db)201 CEvtD2WReload(const QString& db) : QEvent(QEvent::Type(eEvtD2WReload)), db(db) 202 { 203 } 204 205 QString db; 206 }; 207 208 209 class CEvtA2WCutTrk : public QEvent 210 { 211 public: CEvtA2WCutTrk(const IGisItem::key_t & key)212 CEvtA2WCutTrk(const IGisItem::key_t& key) : QEvent(QEvent::Type(eEvtA2WCutTrk)), key(key) 213 { 214 } 215 216 const IGisItem::key_t key; 217 }; 218 219 class CEvtA2WSave : public QEvent 220 { 221 public: CEvtA2WSave(const QString & key)222 CEvtA2WSave(const QString& key) : QEvent(QEvent::Type(eEvtA2WSave)), key(key) 223 { 224 } 225 226 const QString key; 227 }; 228 229 class CEvtA2WSync : public QEvent 230 { 231 public: CEvtA2WSync(const QString & key)232 CEvtA2WSync(const QString& key) : QEvent(QEvent::Type(eEvtA2WSync)), key(key) 233 { 234 } 235 236 const QString key; 237 }; 238 239 240 class CGisWorkspace : public QWidget, private Ui::IGisWorkspace 241 { 242 Q_OBJECT 243 public: self()244 static CGisWorkspace& self() 245 { 246 return *pSelf; 247 } 248 virtual ~CGisWorkspace(); 249 250 void loadGisProject(const QString& filename); 251 /** 252 @brief Draw all loaded data in the workspace that is visible 253 254 This method is called from The CGisDraw thread. The thread has to make sure 255 that everything is thread safe. 256 257 @param p the painter to be used 258 @param viewport the viewport in units of rad 259 @param gis the draw context to be used 260 */ 261 void draw(QPainter& p, const QPolygonF& viewport, CGisDraw* gis); 262 263 /** 264 @brief Receive the current mouse position 265 266 Iterate over all projects and pass the position 267 268 @param pos the mouse position on the screen in pixel 269 */ 270 void mouseMove(const QPointF& pos); 271 /** 272 @brief Draw all data that is time variant and can't wait for a full update 273 274 This method is called directly from the main thread's paintEvent() method. 275 276 @param p the painter to be used 277 @param viewport the viewport in units of rad 278 @param gis the draw context to be used 279 */ 280 void fastDraw(QPainter& p, const QRectF& viewport, CGisDraw* gis); 281 282 /** 283 @brief Get items close to the given point 284 285 Note: Do not store the pointers of items permanently as they can become invalid 286 once you reach the main event loop again. Store the key instead. 287 288 @param pos the position in pixel 289 @param items an empty item list that will get filled with temporary pointers 290 */ 291 void getItemsByPos(const QPointF& pos, QList<IGisItem*>& items); 292 293 /** 294 @brief Get items matching the given area 295 296 @param area a rectangle in screen pixel coordinates 297 @param flags flag field with IGisItem::selection_e flags set 298 @param items a list to receive the temporary pointers to the found items 299 */ 300 void getItemsByArea(const QRectF& area, IGisItem::selflags_t flags, QList<IGisItem*>& items); 301 302 /** 303 @brief Find first item with matching key 304 @param key the item's key as it is returned from IGisItem::getKey() 305 @return If no item is found 0 is returned. 306 */ 307 IGisItem* getItemByKey(const IGisItem::key_t& key); 308 309 void getItemsByKeys(const QList<IGisItem::key_t>& keys, QList<IGisItem*>& items); 310 311 void getNogoAreas(QList<IGisItem*>& nogos); 312 313 /** 314 @brief Delete all items with matching key from workspace 315 316 @param key the item's key as it is returned from IGisItem::getKey() 317 */ 318 void delItemByKey(const IGisItem::key_t& key); 319 320 void delItemsByKey(const QList<IGisItem::key_t>& keys); 321 322 /** 323 @brief Edit / view item details 324 @param key the item's key as it is returned from IGisItem::getKey() 325 */ 326 void editItemByKey(const IGisItem::key_t& key); 327 328 /** 329 @brief Select a project and add a copy of the item to the project 330 @param key the item's key as it is returned from IGisItem::getKey() 331 */ 332 void copyItemByKey(const IGisItem::key_t& key); 333 334 /** 335 @brief Select a project and add a copy of all items in the list 336 @param keys a list of item keys to copy 337 */ 338 IGisProject* copyItemsByKey(const QList<IGisItem::key_t>& keys); 339 340 /** 341 @brief Clone waypoint and move clone 342 @param key the item's key as it is returned from IGisItem::getKey() 343 */ 344 void projWptByKey(const IGisItem::key_t& key); 345 346 /** 347 @brief Move waypoint via mouse 348 @param key the item's key as it is returned from IGisItem::getKey() 349 */ 350 void moveWptByKey(const IGisItem::key_t& key); 351 352 /** 353 @brief Add a new waypoint by Position 354 @param pt the position in degrees 355 */ 356 void addWptByPos(const QPointF& pt, const QString& name = QString::Null(), const QString& desc = QString::Null()) const; 357 358 void addPoisAsWpt(const QSet<poi_t>& pois, IGisProject* project = nullptr) const; 359 void addPoiAsWpt(const poi_t& poi, IGisProject* project = nullptr) const; 360 void addPoiAsWpt(const poi_t& poi, tristate_e& openEditWindow, IGisProject* project = nullptr) const; 361 362 void toggleWptBubble(const IGisItem::key_t& key); 363 364 void deleteWptRadius(const IGisItem::key_t& key); 365 366 void toggleNogoItem(const IGisItem::key_t& key); 367 368 void editWptRadius(const IGisItem::key_t& key); 369 370 void copyWptCoordByKey(const IGisItem::key_t& key); 371 372 /** 373 @brief Set user focus to track 374 @param yes true if focus is set 375 @param key the item's key as it is returned from IGisItem::getKey() 376 */ 377 void focusTrkByKey(bool yes, const IGisItem::key_t& key); 378 379 void focusRteByKey(bool yes, const IGisItem::key_t& key); 380 381 void convertRouteToTrack(const IGisItem::key_t& key); 382 383 void convertTrackToRoute(const IGisItem::key_t& key); 384 385 void cutTrkByKey(const IGisItem::key_t& key); 386 387 void addTrkInfoByKey(const IGisItem::key_t& key); 388 389 void editTrkByKey(const IGisItem::key_t& key); 390 391 void reverseTrkByKey(const IGisItem::key_t& key); 392 393 /** 394 @brief Combine all tracks in a given track's project 395 396 This will collect all tracks in a project and pass them 397 to the track combine dialog. 398 399 @param keyTrk the key of the first track 400 */ 401 void combineTrkByKey(const IGisItem::key_t& keyTrk); 402 403 /** 404 @brief Combine al tracks in the given list of keys. 405 406 @param keys a list of GIS item keys 407 */ 408 void combineTrkByKey(const QList<IGisItem::key_t>& keys, const QList<IGisItem::key_t>& keysPreSel); 409 410 void colorTrkByKey(const QList<IGisItem::key_t>& keys); 411 412 void rangeTrkByKey(const IGisItem::key_t& key); 413 414 void copyTrkWithWptByKey(const IGisItem::key_t& key); 415 416 void editRteByKey(const IGisItem::key_t& key); 417 418 void reverseRteByKey(const IGisItem::key_t& key); 419 420 void calcRteByKey(const IGisItem::key_t& key); 421 422 void resetRteByKey(const IGisItem::key_t& key); 423 424 void editAreaByKey(const IGisItem::key_t& key); 425 426 void makeRteFromWpt(const QList<IGisItem::key_t>& keys); 427 428 void editPrxWpt(const QList<IGisItem::key_t>& keys); 429 430 void changeWptSymByKey(const QList<IGisItem::key_t>& keys, const QString& sym); 431 432 void addEleToWptTrkByKey(const QList<IGisItem::key_t>& keys); 433 434 void searchWebByKey(const IGisItem::key_t& key); 435 436 /** 437 @brief Select a project via dialog 438 439 If a new project name is entered a new project is created. Else the pointer 440 to an existing project is passed back. 441 442 @return 0 if no project was selected. 443 */ 444 IGisProject* selectProject(bool forceSelect); 445 446 void postEventForWks(QEvent* event); 447 448 void setOpacity(qreal val); 449 450 bool findPolylineCloseBy(const QPointF& pt1, const QPointF& pt2, qint32 threshold, QPolygonF& polyline); 451 452 bool areTagsHidden() const; 453 void setTagsHidden(bool hidden); 454 455 void tagItemsByKey(const QList<IGisItem::key_t>& keys); 456 getCurrentSearch()457 const CSearch& getCurrentSearch() const 458 { 459 return currentSearch; 460 } 461 462 signals: 463 void sigChanged(); 464 465 public slots: 466 void slotLateInit(); 467 void slotSaveAll(); 468 void slotWksItemSelectionReset(); 469 void slotActivityTrkByKey(const QList<IGisItem::key_t>& keys, trkact_t act); 470 471 private slots: 472 void slotSetGisLayerOpacity(int val); 473 void slotSearch(const CSearch& currentSearch); 474 475 void slotWksItemSelectionChanged(); 476 void slotWksItemPressed(QTreeWidgetItem* item); 477 478 private: 479 friend class CMainWindow; 480 CGisWorkspace(QMenu* menuProject, QWidget* parent); 481 482 static CGisWorkspace* pSelf; 483 484 /** 485 The item key of last item pressed in the workspace list. 486 The key will be reset by getItemsByPos() which is used by 487 the mouse object to find items close by for highlight. 488 */ 489 IGisItem::key_t keyWksSelection; 490 CSearch currentSearch; 491 492 enum tags_hidden_e 493 { 494 eTagsHiddenTrue, 495 eTagsHiddenFalse, 496 eTagsHiddenUnknown 497 }; 498 }; 499 500 #endif //CGISWORKSPACE_H 501 502