File indexing completed on 2025-02-09 04:07:18
0001 /* 0002 SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #pragma once 0008 0009 #include "geolocation.h" 0010 #include "ui_locationdialog.h" 0011 0012 #include <QPointer> 0013 #ifdef HAVE_GEOCLUE2 0014 #include <QGeoPositionInfo> 0015 #include <QGeoPositionInfoSource> 0016 #endif 0017 #include <QDialog> 0018 #include <QList> 0019 0020 class QTimer; 0021 class QNetworkAccessManager; 0022 class QNetworkReply; 0023 0024 class LocationDialogUI : public QFrame, public Ui::LocationDialog 0025 { 0026 Q_OBJECT 0027 public: 0028 explicit LocationDialogUI(QWidget *parent = nullptr); 0029 }; 0030 0031 /** 0032 * @class LocationDialog 0033 * Dialog for changing the geographic location of the observer. The 0034 * dialog is divided into two sections. 0035 * 0036 * The top section allows the location to be selected from a database 0037 * of 2000 cities. It contains a MapCanvas (showing map of the globe 0038 * with cities overlaid, with a handler for mouse clicks), a QListBox 0039 * containing the names of cities in the database, and three QLineEdit 0040 * widgets, which allow the user to filter the List by the name of the 0041 * City, Province, and Country. In addition, the List 0042 * can be filtered by location, by clicking anywhere in the MapCanvas. 0043 * Doing so will display cities within 2 degrees of the clicked position. 0044 * 0045 * The bottom section allows the location to be specified manually. 0046 * The Longitude, Latitude, City name, Province/State name, and Country name 0047 * are entered into KLineEdits. There is also a QPushButton for adding the 0048 * location to the custom Cities database. If the user selects "Add" without 0049 * filling in all of the manual entry fields, an error message is displayed. 0050 * 0051 * The user can fetch current geographic location from QtPosition system. The actual 0052 * underlying location source depends on the OS and what modules are currently available, if any. 0053 * 0054 * @short Geographic Location dialog 0055 * @author Jason Harris 0056 * @author Jasem Mutlaq 0057 * @author Artem Fedoskin 0058 * @version 1.1 0059 */ 0060 class LocationDialog : public QDialog 0061 { 0062 Q_OBJECT 0063 0064 public: 0065 typedef enum { CITY_ADD, CITY_UPDATE, CITY_REMOVE } CityOperation; 0066 0067 /** 0068 * Constructor. Create all widgets, and pack them into QLayouts. 0069 * Connect Signals to Slots. Run initCityList(). 0070 */ 0071 explicit LocationDialog(QWidget *parent); 0072 0073 /** 0074 * Initialize list of cities. Note that the database is not read in here, 0075 * that is done in the KStars constructor. This simply loads the local QListBox 0076 * with the names of the cities from the kstarsData object. 0077 */ 0078 void initCityList(void); 0079 0080 /** @return pointer to the highlighted city in the List. */ 0081 GeoLocation *selectedCity() const { return SelectedCity; } 0082 0083 /** @return pointer to the List of filtered city pointers. */ 0084 QList<GeoLocation *> filteredList() { return filteredCityList; } 0085 0086 /** 0087 * @short Show only cities within 3 degrees of point specified by arguments 0088 * @param longitude the longitude of the search point (int) 0089 * @param latitude the latitude of the search point (int) 0090 */ 0091 void findCitiesNear(int longitude, int latitude); 0092 0093 /** @return the city name of the selected location. */ 0094 QString selectedCityName() const { return SelectedCity->translatedName(); } 0095 0096 /** @return the province name of the selected location. */ 0097 QString selectedProvinceName() const { return SelectedCity->translatedProvince(); } 0098 0099 /** @return the country name of the selected location. */ 0100 QString selectedCountryName() const { return SelectedCity->translatedCountry(); } 0101 0102 public slots: 0103 /** 0104 * When text is entered in the City/Province/Country Filter KLineEdits, the List of cities is 0105 * trimmed to show only cities beginning with the entered text. Also, the QMemArray of ID 0106 * numbers is kept in sync with the filtered list. 0107 */ 0108 void filterCity(); 0109 0110 /** 0111 * @short Filter by city / province / country only after a few milliseconds 0112 */ 0113 void enqueueFilterCity(); 0114 0115 /** 0116 * When the selected city in the QListBox changes, repaint the MapCanvas 0117 * so that the crosshairs icon appears on the newly selected city. 0118 */ 0119 void changeCity(); 0120 0121 /** 0122 * When the "Add new city" QPushButton is clicked, add the manually-entered 0123 * city information to the user's custom city database. 0124 * @return true on success 0125 */ 0126 bool addCity(); 0127 0128 /** 0129 * When the "Update City" QPushButton is clicked, update the city 0130 * information in the user's custom city database. 0131 * @return true on success 0132 */ 0133 bool updateCity(); 0134 0135 /** 0136 * When the "Remove City" QPushButton is clicked, remove the 0137 * city information from the user's custom city database. 0138 * @return true on success 0139 */ 0140 bool removeCity(); 0141 0142 /** 0143 * @brief updateCity Adds, updates, or removes a city from the user's database. 0144 * @param operation Add, update, or remove city 0145 * @return true on success 0146 */ 0147 bool updateCity(LocationDialog::CityOperation operation); 0148 0149 // FIXME Disable this until Qt5 works with Geoclue2 0150 #ifdef HAVE_GEOCLUE_2 0151 /** 0152 * @brief getNameFromCoordinates Given the current latitude and longitude, use Google Location API services to reverse lookup 0153 * the city, province, and country located at the requested position. 0154 * @param latitude Latitude in degrees 0155 * @param longitude Longitude is degrees 0156 */ 0157 void getNameFromCoordinates(double latitude, double longitude); 0158 #endif 0159 0160 void clearFields(); 0161 void showTZRules(); 0162 void nameChanged(); 0163 void dataChanged(); 0164 void slotOk(); 0165 0166 protected slots: 0167 // FIXME Disable this until Qt5 works with Geoclue2 0168 #ifdef HAVE_GEOCLUE_2 0169 void processLocationNameData(QNetworkReply *rep); 0170 void requestUpdate(); 0171 void positionUpdated(const QGeoPositionInfo &info); 0172 void positionUpdateError(QGeoPositionInfoSource::Error error); 0173 void positionUpdateTimeout(); 0174 #endif 0175 0176 private: 0177 /** Make sure Longitude and Latitude values are valid. */ 0178 bool checkLongLat(); 0179 0180 bool dataModified { false }; 0181 bool nameModified { false }; 0182 0183 LocationDialogUI *ld { nullptr }; 0184 GeoLocation *SelectedCity { nullptr }; 0185 QList<GeoLocation *> filteredCityList; 0186 QTimer *timer { nullptr }; 0187 //Retrieve the name of city 0188 0189 #ifdef HAVE_GEOCLUE_2 0190 QNetworkAccessManager *nam { nullptr }; 0191 QPointer<QGeoPositionInfoSource> source; 0192 #endif 0193 };