1 /* 2 SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org> 3 4 SPDX-License-Identifier: GPL-2.0-or-later 5 */ 6 7 #pragma once 8 9 #include "geolocation.h" 10 #include "ui_locationdialog.h" 11 12 #include <QPointer> 13 #ifdef HAVE_GEOCLUE2 14 #include <QGeoPositionInfo> 15 #include <QGeoPositionInfoSource> 16 #endif 17 #include <QDialog> 18 #include <QList> 19 20 class QTimer; 21 class QNetworkAccessManager; 22 class QNetworkReply; 23 24 class LocationDialogUI : public QFrame, public Ui::LocationDialog 25 { 26 Q_OBJECT 27 public: 28 explicit LocationDialogUI(QWidget *parent = nullptr); 29 }; 30 31 /** 32 * @class LocationDialog 33 * Dialog for changing the geographic location of the observer. The 34 * dialog is divided into two sections. 35 * 36 * The top section allows the location to be selected from a database 37 * of 2000 cities. It contains a MapCanvas (showing map of the globe 38 * with cities overlaid, with a handler for mouse clicks), a QListBox 39 * containing the names of cities in the database, and three QLineEdit 40 * widgets, which allow the user to filter the List by the name of the 41 * City, Province, and Country. In addition, the List 42 * can be filtered by location, by clicking anywhere in the MapCanvas. 43 * Doing so will display cities within 2 degrees of the clicked position. 44 * 45 * The bottom section allows the location to be specified manually. 46 * The Longitude, Latitude, City name, Province/State name, and Country name 47 * are entered into KLineEdits. There is also a QPushButton for adding the 48 * location to the custom Cities database. If the user selects "Add" without 49 * filling in all of the manual entry fields, an error message is displayed. 50 * 51 * The user can fetch current geographic location from QtPosition system. The actual 52 * underlying location source depends on the OS and what modules are currently available, if any. 53 * 54 * @short Geographic Location dialog 55 * @author Jason Harris 56 * @author Jasem Mutlaq 57 * @author Artem Fedoskin 58 * @version 1.1 59 */ 60 class LocationDialog : public QDialog 61 { 62 Q_OBJECT 63 64 public: 65 typedef enum { CITY_ADD, CITY_UPDATE, CITY_REMOVE } CityOperation; 66 67 /** 68 * Constructor. Create all widgets, and pack them into QLayouts. 69 * Connect Signals to Slots. Run initCityList(). 70 */ 71 explicit LocationDialog(QWidget *parent); 72 73 /** 74 * Initialize list of cities. Note that the database is not read in here, 75 * that is done in the KStars constructor. This simply loads the local QListBox 76 * with the names of the cities from the kstarsData object. 77 */ 78 void initCityList(void); 79 80 /** @return pointer to the highlighted city in the List. */ selectedCity()81 GeoLocation *selectedCity() const { return SelectedCity; } 82 83 /** @return pointer to the List of filtered city pointers. */ filteredList()84 QList<GeoLocation *> filteredList() { return filteredCityList; } 85 86 /** 87 * @short Show only cities within 3 degrees of point specified by arguments 88 * @param longitude the longitude of the search point (int) 89 * @param latitude the latitude of the search point (int) 90 */ 91 void findCitiesNear(int longitude, int latitude); 92 93 /** @return the city name of the selected location. */ selectedCityName()94 QString selectedCityName() const { return SelectedCity->translatedName(); } 95 96 /** @return the province name of the selected location. */ selectedProvinceName()97 QString selectedProvinceName() const { return SelectedCity->translatedProvince(); } 98 99 /** @return the country name of the selected location. */ selectedCountryName()100 QString selectedCountryName() const { return SelectedCity->translatedCountry(); } 101 102 public slots: 103 /** 104 * When text is entered in the City/Province/Country Filter KLineEdits, the List of cities is 105 * trimmed to show only cities beginning with the entered text. Also, the QMemArray of ID 106 * numbers is kept in sync with the filtered list. 107 */ 108 void filterCity(); 109 110 /** 111 * @short Filter by city / province / country only after a few milliseconds 112 */ 113 void enqueueFilterCity(); 114 115 /** 116 * When the selected city in the QListBox changes, repaint the MapCanvas 117 * so that the crosshairs icon appears on the newly selected city. 118 */ 119 void changeCity(); 120 121 /** 122 * When the "Add new city" QPushButton is clicked, add the manually-entered 123 * city information to the user's custom city database. 124 * @return true on success 125 */ 126 bool addCity(); 127 128 /** 129 * When the "Update City" QPushButton is clicked, update the city 130 * information in the user's custom city database. 131 * @return true on success 132 */ 133 bool updateCity(); 134 135 /** 136 * When the "Remove City" QPushButton is clicked, remove the 137 * city information from the user's custom city database. 138 * @return true on success 139 */ 140 bool removeCity(); 141 142 /** 143 * @brief updateCity Adds, updates, or removes a city from the user's database. 144 * @param operation Add, update, or remove city 145 * @return true on success 146 */ 147 bool updateCity(LocationDialog::CityOperation operation); 148 149 // FIXME Disable this until Qt5 works with Geoclue2 150 #ifdef HAVE_GEOCLUE_2 151 /** 152 * @brief getNameFromCoordinates Given the current latitude and longitude, use Google Location API services to reverse lookup 153 * the city, province, and country located at the requested position. 154 * @param latitude Latitude in degrees 155 * @param longitude Longitude is degrees 156 */ 157 void getNameFromCoordinates(double latitude, double longitude); 158 #endif 159 160 void clearFields(); 161 void showTZRules(); 162 void nameChanged(); 163 void dataChanged(); 164 void slotOk(); 165 166 protected slots: 167 // FIXME Disable this until Qt5 works with Geoclue2 168 #ifdef HAVE_GEOCLUE_2 169 void processLocationNameData(QNetworkReply *rep); 170 void requestUpdate(); 171 void positionUpdated(const QGeoPositionInfo &info); 172 void positionUpdateError(QGeoPositionInfoSource::Error error); 173 void positionUpdateTimeout(); 174 #endif 175 176 private: 177 /** Make sure Longitude and Latitude values are valid. */ 178 bool checkLongLat(); 179 180 bool dataModified { false }; 181 bool nameModified { false }; 182 183 LocationDialogUI *ld { nullptr }; 184 GeoLocation *SelectedCity { nullptr }; 185 QList<GeoLocation *> filteredCityList; 186 QTimer *timer { nullptr }; 187 //Retrieve the name of city 188 189 #ifdef HAVE_GEOCLUE_2 190 QNetworkAccessManager *nam { nullptr }; 191 QPointer<QGeoPositionInfoSource> source; 192 #endif 193 }; 194