Merge lp:~stellarium/stellarium/ip-query-location into lp:stellarium
- ip-query-location
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~stellarium/stellarium/ip-query-location |
Merge into: | lp:stellarium |
Diff against target: |
866 lines (+435/-164) 9 files modified
data/default_config.ini.cmake (+1/-1) src/core/StelCore.cpp (+11/-2) src/core/StelLocation.cpp (+7/-0) src/core/StelLocation.hpp (+3/-0) src/core/StelLocationMgr.cpp (+115/-1) src/core/StelLocationMgr.hpp (+25/-0) src/gui/LocationDialog.cpp (+122/-31) src/gui/LocationDialog.hpp (+11/-1) src/gui/locationDialogGui.ui (+140/-128) |
To merge this branch: | bzr merge lp:~stellarium/stellarium/ip-query-location |
Related bugs: | |
Related blueprints: |
Location dialog redesign
(Medium)
Enhanced Location Window
(Low)
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Marcos Cardinot | Approve | ||
Fabien Chéreau | Needs Fixing | ||
Alexander Wolf | Approve | ||
gzotti | Needs Resubmitting | ||
Review via email: mp+227418@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-08-06.
Commit message
1) Added IP-based location query for location panel and optionally at program start.
2) Improved location GUI:
(a) clicking on the map reduces site list to sites in 3 degrees vicinity.
(b) selecting a country in the combo box reduces site list to sites in that country.
(c) selecting a planet other than earth reduces site list to sites on that planet.
Description of the change
1) Added IP-based location query for location panel and optionally at program start.
2) Improved location GUI:
(a) clicking on the map reduces site list to sites in 3 degrees vicinity.
(b) selecting a country in the combo box reduces site list to sites in that country.
(c) selecting a planet other than earth reduces site list to sites on that planet.
Alexander Wolf (alexwolf) wrote : | # |
The second feature is OK for me. Are you want merge it yourself?
Alexander Wolf (alexwolf) wrote : | # |
Wait! What about non-Earth location?
Fabien Chéreau (xalioth) wrote : | # |
Hi Please cleanup The code. Also use the regular event loop to make a non
blocking call to the service.
Le 19 juil. 2014 15:58, "Alexander Wolf" <email address hidden> a écrit :
> Alexander Wolf has proposed merging
> lp:~georg-zotti/stellarium/ip-query-location into lp:stellarium.
>
> Requested reviews:
> Alexander Wolf (alexwolf)
>
> For more details, see:
>
> https:/
>
> This branch introduces new feature - automatic finding approximate
> location of Stellarium from IP address.
> --
>
> https:/
> You are subscribed to branch lp:stellarium.
>
> === modified file 'src/core/
> --- src/core/
> +++ src/core/
> @@ -114,7 +114,14 @@
> defaultLocationID =
> conf->value(
> bool ok;
> StelLocationMgr* locationMgr =
> &StelApp:
> - StelLocation location =
> locationMgr-
> + StelLocation location;
> + if (conf->
> "false").toBool()
> + && locationMgr-
> + {
> + location=
> + }
> +
> + else location = locationMgr-
> if (!location.
> {
> qWarning() << "Warning: location" << defaultLocationID <<
> "is unknown.";
>
> === modified file 'src/core/
> --- src/core/
> +++ src/core/
> @@ -25,6 +25,13 @@
> #include <QDebug>
> #include <QFile>
> #include <QDir>
> +#include <QtNetwork/
> +#include <QtNetwork/
> +#include <QEventLoop>
> +#include <QNetworkRequest>
> +#include <QNetworkReply>
> +#include <QUrl>
> +#include <QUrlQuery>
>
> StelLocationMgr
> {
> @@ -307,3 +314,99 @@
> sourcefile.close();
> return true;
> }
> +
> +
> +//! check if there is an IP connection.
> +// Along the lines of
> +//
> http://
> +//#define DEBUG 1
> +bool StelLocationMgr
> +{
> + QList<QNetworkI
> + bool connectionExists = false;
> +
> + for (int i = 0; i < ifaces.count(); i++) {
> +
> + QNetworkInterface iface = ifaces.at(i);
> + if ( iface.flags(
> + && !iface.
> +
> +#ifdef DEBUG
> + // details of connection
> + qDebug() << "name:" << iface.name() << endl
> + << "mac:" << iface.hardwareA
> + << "ip addresses:" << endl;
> +#endif
> + for (int j=0; j<iface.
gzotti (georg-zotti) wrote : | # |
Hm, I was surprised that the site list mixes all sites anyhow. I will try
to reduce selection to the currently set planet...
G.
On Sa, 19.07.2014, 14:26, Alexander Wolf wrote:
> Review: Needs Fixing
>
> Wait! What about non-Earth location?
> --
> https:/
> You are the owner of lp:~georg-zotti/stellarium/ip-query-location.
>
Alexander Wolf (alexwolf) wrote : | # |
This list is "correct". I meant new features. If I change the planet and picked some point on the map (as example on Mars) then I get locations from Earth!
gzotti (georg-zotti) wrote : | # |
Sure. This context info did not exist previously...
I filter also by current planet name now. And I want to add a filter for
country as next step towards better usability.
G.
On Sa, 19.07.2014, 18:42, Alexander Wolf wrote:
> This list is "correct". I meant new features. If I change the planet and
> picked some point on the map (as example on Mars) then I get locations
> from Earth!
> --
> https:/
> You are the owner of lp:~georg-zotti/stellarium/ip-query-location.
>
Alexander Wolf (alexwolf) wrote : | # |
2014-07-20 1:33 GMT+07:00 gzotti <email address hidden>:
> Sure. This context info did not exist previously...
>
> I filter also by current planet name now. And I want to add a filter for
> country as next step towards better usability.
>
It's introduces important problem: search tool will search location in full
list or in filtered list?
--
With best regards, Alexander
gzotti (georg-zotti) wrote : | # |
The list box gets filled with a preselected short list of nearby locations
on the current planet. If the user selects Earth, the complete list will
be shown at the moment (50 non-Earth entries in 15000 locations, should
not matter...)
The search tool is directly connected to the list, so it only searches in
the pre-filtered list.
There is a reset list button to recreate all entries.
I am not yet sure if I shouldn't clear out the country combobox if
planet!=Earth. This was always quite strange...
G.
On Sa, 19.07.2014, 20:45, Alexander Wolf wrote:
> 2014-07-20 1:33 GMT+07:00 gzotti <email address hidden>:
>
>> Sure. This context info did not exist previously...
>>
>> I filter also by current planet name now. And I want to add a filter for
>> country as next step towards better usability.
>>
>
> It's introduces important problem: search tool will search location in
> full
> list or in filtered list?
>
> --
> With best regards, Alexander
>
> https:/
> You are the owner of lp:~georg-zotti/stellarium/ip-query-location.
>
gzotti (georg-zotti) wrote : | # |
I have added the requested improvements. I think it works all now.
Alexander Wolf (alexwolf) wrote : | # |
OK. It work correct now and I think it ready to merge. Fabien?
Fabien Chéreau (xalioth) wrote : | # |
Please see comments
Marcos Cardinot (cardinot) wrote : | # |
Hello Georg,
congrats for the excellent work!
I have just a couple of things to suggest (nitpicks)... see comments + I noticed that you are using spaces instead of tabs...
Marcos Cardinot (cardinot) : | # |
gzotti (georg-zotti) wrote : | # |
Dear Fabien,
I fixed these items on Monday. Do you approve a merge now?
Kind regards,
Georg
On Mo, 21.07.2014, 19:07, Fabien Chéreau wrote:
> Review: Needs Fixing
>
> Please see comments
>
> Diff comments:
>
>> === modified file 'src/core/
>> --- src/core/
>> +++ src/core/
>> @@ -114,7 +114,13 @@
>> defaultLocationID =
>> conf->value(
>> bool ok;
>> StelLocationMgr* locationMgr =
>> &StelApp:
>> - StelLocation location =
>> locationMgr-
>> + StelLocation location;
>> + if (conf->
>> "false").toBool())
>> + {
>> + locationMgr-
>> + }
>> +
>> + else location = locationMgr-
>> if (!location.
>> {
>> qWarning() << "Warning: location" << defaultLocationID << "is
>> unknown.";
>>
>> === modified file 'src/core/
>> --- src/core/
>> +++ src/core/
>> @@ -125,3 +125,10 @@
>> return loc;
>> }
>>
>> +// Compute great-circle distance between two locations
>> +float StelLocation:
>> lat1, const float long2, const float lat2)
>> +{
>> + const float DEGREES=
>> + return std::acos( std::sin(
>> +
>> std::cos(
>> ) / DEGREES;
>> +}
>>
>> === modified file 'src/core/
>> --- src/core/
>> +++ src/core/
>> @@ -74,6 +74,9 @@
>> //! Parse a location from a line serialization
>> static StelLocation createFromLine(
>>
>> + //! Compute great-circle distance between two locations
>> + static float distanceDegrees
>> const float long2, const float lat2);
>> +
>> //! Used privately by the StelLocationMgr
>> bool isUserLocation;
>>
>>
>> === modified file 'src/core/
>> --- src/core/
>> +++ src/core/
>> @@ -17,6 +17,7 @@
>> */
>>
>> #include "StelApp.hpp"
>> +#include "StelCore.hpp"
>> #include "StelFileMgr.hpp"
>> #include "StelLocationMg
>> #include "StelUtils.hpp"
>> @@ -25,6 +26,12 @@
>> #include <QDebug>
>> #include <QFile>
>> #include <QDir>
>> +#include <QtNetwork/
>> +#include <QtNetwork/
>> +#include <QNetworkRequest>
>> +#include <QNetworkReply>
>> +#include <QUrl>
>> +#include <QUrlQuery>
>>
>> StelLocationMgr
>> {
>> @@ -36,9 +43,12 @@
>>
>> modelAllLocation = new QStringListMode
>> modelAllLocatio
>> + modelPickedLocation = new QStringListMode
>> now.
>>
>> // Init to Paris France because it's the center of the world.
>> lastResortLocation =...
Fabien Chéreau (xalioth) wrote : | # |
Hi Georg,
now that I'm back from holidays, I could acutally try the code, and I have
some more general comments about your (very very good!) work:
- we should rename "IP Query" to something less technical, like "Get
location from Network"
- I think the IP location is such an improvement that it should be the
default for all new install, and also probably used by default for installs
where the location was never set (set to Paris). This would imply that we
transform at startup all older config.ini from location = Paris, France to
location = auto. And use this "auto" value to trigger IP Lookup instead of
adding a new "init_location/
- Also when the lookup is successful, we could save the last know location
into an "init_location/
without network.
Sorry to give these feedbacks so late, I hope they make sense, what do you
think? In any case, I think the lack of auto location feature was the most
annoying problem of Stellarium for an average user living in US, so thanks
a lot again!
Fabien
On Sat, Jul 26, 2014 at 12:24 PM, gzotti <email address hidden> wrote:
> Dear Fabien,
>
> I fixed these items on Monday. Do you approve a merge now?
>
> Kind regards,
> Georg
>
> On Mo, 21.07.2014, 19:07, Fabien Chéreau wrote:
> > Review: Needs Fixing
> >
> > Please see comments
> >
> > Diff comments:
> >
> >> === modified file 'src/core/
> >> --- src/core/
> >> +++ src/core/
> >> @@ -114,7 +114,13 @@
> >> defaultLocationID =
> >> conf->value(
> >> bool ok;
> >> StelLocationMgr* locationMgr =
> >> &StelApp:
> >> - StelLocation location =
> >> locationMgr-
> >> + StelLocation location;
> >> + if (conf->
> >> "false").toBool())
> >> + {
> >> + locationMgr-
> >> + }
> >> +
> >> + else location = locationMgr-
> >> if (!location.
> >> {
> >> qWarning() << "Warning: location" << defaultLocationID <<
> "is
> >> unknown.";
> >>
> >> === modified file 'src/core/
> >> --- src/core/
> >> +++ src/core/
> >> @@ -125,3 +125,10 @@
> >> return loc;
> >> }
> >>
> >> +// Compute great-circle distance between two locations
> >> +float StelLocation:
> >> lat1, const float long2, const float lat2)
> >> +{
> >> + const float DEGREES=
> >> + return std::acos( std::sin(
> >> +
> >>
> std::cos(
> >> ) / DEGREES;
> >> +}
> >>
> >> === modified file 'src/core/
> >> --- src/core/
> >> +++ src/core/
> >> ...
gzotti (georg-zotti) wrote : | # |
Dear Fabien,
thanks for your friendly words.
I know "IP query" is very technical. But what to write on a 6-letter
button? Else, the button must stretch over the whole window, I did not
want to make it too intrusive. If there is space, it should be
"approximate location", my own query is about 50km off... But it's still
quite a good start.
A default IP lookup for new installs seems fine, as long as there remains
a fallback location in case someone travels to his offline PC with an USB
stick with the latest version. (When I traveled to Namibia for some
astrophotos with a Stellarium-guided telescope, my Atom netbook was also
definitely offline...)
Having the always-
possible to set and keep a home position as well, even if we are online at
startup. (And if somebody in Paris is happy with startup location, he will
be surprised to find his place renamed to IPxxxx :-)
The other changes are with finding a location near map-click point and
with the country/planet comboboxes. I think they are much more functional
now. What may still be done is to deactivate and empty the country box if
we are not on Earth.
My short slot of time is unfortunately over for this weekend. So, if you
like it, please merge and feel free to tweak these small details.
I just tried your brother's no-bit-field branch. It compiles on my Atom
450 netbook (MSVC2012/Angle; takes ages...), but the shader programs are
too long. I cannot find any info on how to programmatically check shader
support from the GPU: is Angle limited to pixelshader2, vertexshader2 and
fails on every system, or would it compile ps_3, vs_3 if the graphics card
supports this? Going for Angle was the hope to support simpler/older
hardware, so if there would be a way to support ps_2+vs_2 hardware like
Atom or older Radeon or Intel GMA by utilizing simpler shader programs
(e.g. no ring shadows, normal maps, etc.?) after some tests, there would
be less users having to use super-slow MESA. (But I'm happy at least MESA
is a stable fallback...)
What I still don't know is why my both NVidias on WinXP fail. Both should
support OpenGL3.3.
Kind regards,
Georg
On Sa, 26.07.2014, 18:24, Fabien Chéreau wrote:
> Hi Georg,
>
> now that I'm back from holidays, I could acutally try the code, and I have
> some more general comments about your (very very good!) work:
>
> - we should rename "IP Query" to something less technical, like "Get
> location from Network"
>
> - I think the IP location is such an improvement that it should be the
> default for all new install, and also probably used by default for
> installs
> where the location was never set (set to Paris). This would imply that we
> transform at startup all older config.ini from location = Paris, France to
> location = auto. And use this "auto" value to trigger IP Lookup instead of
> adding a new "init_location/
>
> - Also when the lookup is successful, we could save the last know location
> into an "init_location/
> without network.
>
> Sorry to give these feedbacks so late, I hope they make sense, what do you
> think? In ...
Alexander Wolf (alexwolf) wrote : | # |
IMHO we can merge this branch and improve some features.
- 6937. By Alexander Wolf
-
Stellarium will be get location from network by default for fresh installation now. Location dialog was changed for new feature support.
Alexander Wolf (alexwolf) wrote : | # |
OK. I updated code to usage of this feature by default.
- 6938. By Alexander Wolf
-
avoid Antautorina's bug
- 6939. By Alexander Wolf
-
avoid unknown location's bug (location not exists in stellarium database)
- 6940. By Alexander Wolf
-
renamed last_resort_
location to last_location - 6941. By Alexander Wolf
-
fixed issue of display coordinates of location
- 6942. By Alexander Wolf
-
avoid rounding issue and extend unit tests
Unmerged revisions
Preview Diff
1 | === modified file 'data/default_config.ini.cmake' | |||
2 | --- data/default_config.ini.cmake 2014-07-31 19:02:38 +0000 | |||
3 | +++ data/default_config.ini.cmake 2014-08-06 17:11:24 +0000 | |||
4 | @@ -242,7 +242,7 @@ | |||
5 | 242 | nebula_magnitude_limit = 8.5 | 242 | nebula_magnitude_limit = 8.5 |
6 | 243 | 243 | ||
7 | 244 | [init_location] | 244 | [init_location] |
9 | 245 | location = Paris, France | 245 | location = auto |
10 | 246 | landscape_name = guereins | 246 | landscape_name = guereins |
11 | 247 | 247 | ||
12 | 248 | [files] | 248 | [files] |
13 | 249 | 249 | ||
14 | === modified file 'src/core/StelCore.cpp' | |||
15 | --- src/core/StelCore.cpp 2014-04-14 17:55:46 +0000 | |||
16 | +++ src/core/StelCore.cpp 2014-08-06 17:11:24 +0000 | |||
17 | @@ -111,10 +111,19 @@ | |||
18 | 111 | { | 111 | { |
19 | 112 | QSettings* conf = StelApp::getInstance().getSettings(); | 112 | QSettings* conf = StelApp::getInstance().getSettings(); |
20 | 113 | 113 | ||
22 | 114 | defaultLocationID = conf->value("init_location/location","error").toString(); | 114 | defaultLocationID = conf->value("init_location/location", "auto").toString(); |
23 | 115 | bool ok; | 115 | bool ok; |
24 | 116 | StelLocationMgr* locationMgr = &StelApp::getInstance().getLocationMgr(); | 116 | StelLocationMgr* locationMgr = &StelApp::getInstance().getLocationMgr(); |
26 | 117 | StelLocation location = locationMgr->locationForString(defaultLocationID); | 117 | StelLocation location; |
27 | 118 | if (defaultLocationID.contains("auto")) | ||
28 | 119 | { | ||
29 | 120 | locationMgr->locationFromIP(); | ||
30 | 121 | } | ||
31 | 122 | else | ||
32 | 123 | { | ||
33 | 124 | location = locationMgr->locationForString(defaultLocationID); | ||
34 | 125 | } | ||
35 | 126 | |||
36 | 118 | if (!location.isValid()) | 127 | if (!location.isValid()) |
37 | 119 | { | 128 | { |
38 | 120 | qWarning() << "Warning: location" << defaultLocationID << "is unknown."; | 129 | qWarning() << "Warning: location" << defaultLocationID << "is unknown."; |
39 | 121 | 130 | ||
40 | === modified file 'src/core/StelLocation.cpp' | |||
41 | --- src/core/StelLocation.cpp 2014-02-15 15:37:23 +0000 | |||
42 | +++ src/core/StelLocation.cpp 2014-08-06 17:11:24 +0000 | |||
43 | @@ -125,3 +125,10 @@ | |||
44 | 125 | return loc; | 125 | return loc; |
45 | 126 | } | 126 | } |
46 | 127 | 127 | ||
47 | 128 | // Compute great-circle distance between two locations | ||
48 | 129 | float StelLocation::distanceDegrees(const float long1, const float lat1, const float long2, const float lat2) | ||
49 | 130 | { | ||
50 | 131 | const float DEGREES=M_PI/180.0f; | ||
51 | 132 | return std::acos( std::sin(lat1*DEGREES)*std::sin(lat2*DEGREES) + | ||
52 | 133 | std::cos(lat1*DEGREES)*std::cos(lat2*DEGREES)*std::cos((long1-long2)*DEGREES) ) / DEGREES; | ||
53 | 134 | } | ||
54 | 128 | 135 | ||
55 | === modified file 'src/core/StelLocation.hpp' | |||
56 | --- src/core/StelLocation.hpp 2014-04-15 17:10:07 +0000 | |||
57 | +++ src/core/StelLocation.hpp 2014-08-06 17:11:24 +0000 | |||
58 | @@ -74,6 +74,9 @@ | |||
59 | 74 | //! Parse a location from a line serialization | 74 | //! Parse a location from a line serialization |
60 | 75 | static StelLocation createFromLine(const QString& line); | 75 | static StelLocation createFromLine(const QString& line); |
61 | 76 | 76 | ||
62 | 77 | //! Compute great-circle distance between two locations | ||
63 | 78 | static float distanceDegrees(const float long1, const float lat1, const float long2, const float lat2); | ||
64 | 79 | |||
65 | 77 | //! Used privately by the StelLocationMgr | 80 | //! Used privately by the StelLocationMgr |
66 | 78 | bool isUserLocation; | 81 | bool isUserLocation; |
67 | 79 | 82 | ||
68 | 80 | 83 | ||
69 | === modified file 'src/core/StelLocationMgr.cpp' | |||
70 | --- src/core/StelLocationMgr.cpp 2014-06-12 15:47:22 +0000 | |||
71 | +++ src/core/StelLocationMgr.cpp 2014-08-06 17:11:24 +0000 | |||
72 | @@ -17,6 +17,7 @@ | |||
73 | 17 | */ | 17 | */ |
74 | 18 | 18 | ||
75 | 19 | #include "StelApp.hpp" | 19 | #include "StelApp.hpp" |
76 | 20 | #include "StelCore.hpp" | ||
77 | 20 | #include "StelFileMgr.hpp" | 21 | #include "StelFileMgr.hpp" |
78 | 21 | #include "StelLocationMgr.hpp" | 22 | #include "StelLocationMgr.hpp" |
79 | 22 | #include "StelUtils.hpp" | 23 | #include "StelUtils.hpp" |
80 | @@ -25,9 +26,18 @@ | |||
81 | 25 | #include <QDebug> | 26 | #include <QDebug> |
82 | 26 | #include <QFile> | 27 | #include <QFile> |
83 | 27 | #include <QDir> | 28 | #include <QDir> |
84 | 29 | #include <QtNetwork/QNetworkInterface> | ||
85 | 30 | #include <QtNetwork/QNetworkAccessManager> | ||
86 | 31 | #include <QNetworkRequest> | ||
87 | 32 | #include <QNetworkReply> | ||
88 | 33 | #include <QUrl> | ||
89 | 34 | #include <QUrlQuery> | ||
90 | 35 | #include <QSettings> | ||
91 | 28 | 36 | ||
92 | 29 | StelLocationMgr::StelLocationMgr() | 37 | StelLocationMgr::StelLocationMgr() |
93 | 30 | { | 38 | { |
94 | 39 | QSettings* conf = StelApp::getInstance().getSettings(); | ||
95 | 40 | |||
96 | 31 | // The line below allows to re-generate the location file, you still need to gunzip it manually afterward. | 41 | // The line below allows to re-generate the location file, you still need to gunzip it manually afterward. |
97 | 32 | // generateBinaryLocationFile("data/base_locations.txt", false, "data/base_locations.bin"); | 42 | // generateBinaryLocationFile("data/base_locations.txt", false, "data/base_locations.bin"); |
98 | 33 | 43 | ||
99 | @@ -36,9 +46,10 @@ | |||
100 | 36 | 46 | ||
101 | 37 | modelAllLocation = new QStringListModel(this); | 47 | modelAllLocation = new QStringListModel(this); |
102 | 38 | modelAllLocation->setStringList(locations.keys()); | 48 | modelAllLocation->setStringList(locations.keys()); |
103 | 49 | modelPickedLocation = new QStringListModel(this); // keep empty for now. | ||
104 | 39 | 50 | ||
105 | 40 | // Init to Paris France because it's the center of the world. | 51 | // Init to Paris France because it's the center of the world. |
107 | 41 | lastResortLocation = locationForString("Paris, France"); | 52 | lastResortLocation = locationForString(conf->value("init_location/last_resort_location", "Paris, France").toString()); |
108 | 42 | } | 53 | } |
109 | 43 | 54 | ||
110 | 44 | void StelLocationMgr::generateBinaryLocationFile(const QString& fileName, bool isUserLocation, const QString& binFilePath) const | 55 | void StelLocationMgr::generateBinaryLocationFile(const QString& fileName, bool isUserLocation, const QString& binFilePath) const |
111 | @@ -144,6 +155,10 @@ | |||
112 | 144 | 155 | ||
113 | 145 | StelLocationMgr::~StelLocationMgr() | 156 | StelLocationMgr::~StelLocationMgr() |
114 | 146 | { | 157 | { |
115 | 158 | delete modelPickedLocation; | ||
116 | 159 | modelPickedLocation=NULL; | ||
117 | 160 | delete modelAllLocation; | ||
118 | 161 | modelAllLocation=NULL; | ||
119 | 147 | } | 162 | } |
120 | 148 | 163 | ||
121 | 149 | static float parseAngle(const QString& s, bool* ok) | 164 | static float parseAngle(const QString& s, bool* ok) |
122 | @@ -307,3 +322,102 @@ | |||
123 | 307 | sourcefile.close(); | 322 | sourcefile.close(); |
124 | 308 | return true; | 323 | return true; |
125 | 309 | } | 324 | } |
126 | 325 | |||
127 | 326 | // lookup location from IP address. | ||
128 | 327 | void StelLocationMgr::locationFromIP() | ||
129 | 328 | { | ||
130 | 329 | QNetworkRequest req( QUrl( QString("http://freegeoip.net/csv/") ) ); | ||
131 | 330 | networkReply=StelApp::getInstance().getNetworkAccessManager()->get(req); | ||
132 | 331 | connect(networkReply, SIGNAL(finished()), this, SLOT(changeLocationFromNetworkLookup())); | ||
133 | 332 | } | ||
134 | 333 | |||
135 | 334 | // slot that receives IP-based location data from the network. | ||
136 | 335 | void StelLocationMgr::changeLocationFromNetworkLookup() | ||
137 | 336 | { | ||
138 | 337 | StelLocation location; | ||
139 | 338 | StelCore *core=StelApp::getInstance().getCore(); | ||
140 | 339 | if (networkReply->error() == QNetworkReply::NoError) { | ||
141 | 340 | //success | ||
142 | 341 | // Tested with and without working network connection. | ||
143 | 342 | QByteArray answer=networkReply->readAll(); | ||
144 | 343 | // answer/splitline example: "222.222.222.222","AT","Austria","","","","","47.3333","13.3333","","" | ||
145 | 344 | // The parts from freegeoip are: ip,country_code,country_name,region_code,region_name,city,zipcode,latitude,longitude,metro_code,area_code | ||
146 | 345 | // longitude and latitude should always be filled. | ||
147 | 346 | // A few tests: | ||
148 | 347 | if ((answer.count('"') != 22 ) || (answer.count(',') != 10 )) | ||
149 | 348 | { | ||
150 | 349 | qDebug() << "StelLocationMgr: Malformatted answer in IP-based location lookup: \n\t" << answer; | ||
151 | 350 | qDebug() << "StelLocationMgr: Will not change location."; | ||
152 | 351 | networkReply->deleteLater(); | ||
153 | 352 | return; | ||
154 | 353 | } | ||
155 | 354 | const QStringList& splitline = QString(answer).split(","); | ||
156 | 355 | if (splitline.count() != 11 ) | ||
157 | 356 | { | ||
158 | 357 | qDebug() << "StelLocationMgr: Unexpected answer in IP-based location lookup: \n\t" << answer; | ||
159 | 358 | qDebug() << "StelLocationMgr: Will not change location."; | ||
160 | 359 | networkReply->deleteLater(); | ||
161 | 360 | return; | ||
162 | 361 | } | ||
163 | 362 | if ((splitline.at(7)=="\"\"") || (splitline.at(8)=="\"\"")) // empty coordinates? | ||
164 | 363 | { | ||
165 | 364 | qDebug() << "StelLocationMgr: Invalid coordinates from IP-based lookup. Ignoring: \n\t" << answer; | ||
166 | 365 | networkReply->deleteLater(); | ||
167 | 366 | return; | ||
168 | 367 | } | ||
169 | 368 | float latitude=splitline.at(7).mid(1, splitline.at(7).length()-2).toFloat(); | ||
170 | 369 | float longitude=splitline.at(8).mid(1, splitline.at(8).length()-2).toFloat(); | ||
171 | 370 | QString locLine= // we re-pack into a new line that will be parsed back by StelLocation... | ||
172 | 371 | QString("%1\t%2\t%3\t%4\t%5\t%6\t%7\t0") | ||
173 | 372 | .arg(splitline.at(5).length()>2 ? splitline.at(5).mid(1, splitline.at(5).length()-2) : QString("IP%1").arg(splitline.at(0).mid(1, splitline.at(0).length()-2))) | ||
174 | 373 | .arg(splitline.at(4).length()>2 ? splitline.at(4).mid(1, splitline.at(4).length()-2) : "IPregion") | ||
175 | 374 | .arg(splitline.at(2).length()>2 ? splitline.at(2).mid(1, splitline.at(2).length()-2) : "IPcountry") // country | ||
176 | 375 | .arg("X") // role: X=user-defined | ||
177 | 376 | .arg(0) // population: unknown | ||
178 | 377 | .arg(latitude<0 ? QString("%1S").arg(-latitude, 0, 'f', 6) : QString("%1N").arg(latitude, 0, 'f', 6)) | ||
179 | 378 | .arg(longitude<0 ? QString("%1W").arg(-longitude, 0, 'f', 6) : QString("%1E").arg(longitude, 0, 'f', 6)); | ||
180 | 379 | location=StelLocation::createFromLine(locLine); // in lack of a regular constructor ;-) | ||
181 | 380 | core->moveObserverTo(location, 0.0f, 0.0f); | ||
182 | 381 | QSettings* conf = StelApp::getInstance().getSettings(); | ||
183 | 382 | conf->setValue("init_location/last_resort_location", QString("%1, %2").arg(location.name).arg(location.country)); | ||
184 | 383 | } | ||
185 | 384 | else | ||
186 | 385 | { | ||
187 | 386 | qDebug() << "Failure getting IP-based location: \n\t" <<networkReply->errorString(); | ||
188 | 387 | core->moveObserverTo(lastResortLocation, 0.0f, 0.0f); | ||
189 | 388 | } | ||
190 | 389 | networkReply->deleteLater(); | ||
191 | 390 | } | ||
192 | 391 | |||
193 | 392 | void StelLocationMgr::pickLocationsNearby(const QString planetName, const float longitude, const float latitude, const float radiusDegrees) | ||
194 | 393 | { | ||
195 | 394 | pickedLocations.clear(); | ||
196 | 395 | QMapIterator<QString, StelLocation> iter(locations); | ||
197 | 396 | while (iter.hasNext()) | ||
198 | 397 | { | ||
199 | 398 | iter.next(); | ||
200 | 399 | const StelLocation *loc=&iter.value(); | ||
201 | 400 | if ( (loc->planetName == planetName) && | ||
202 | 401 | (StelLocation::distanceDegrees(longitude, latitude, loc->longitude, loc->latitude) <= radiusDegrees) ) | ||
203 | 402 | { | ||
204 | 403 | pickedLocations.insert(iter.key(), iter.value()); | ||
205 | 404 | } | ||
206 | 405 | } | ||
207 | 406 | modelPickedLocation->setStringList(pickedLocations.keys()); | ||
208 | 407 | } | ||
209 | 408 | |||
210 | 409 | void StelLocationMgr::pickLocationsInCountry(const QString country) | ||
211 | 410 | { | ||
212 | 411 | pickedLocations.clear(); | ||
213 | 412 | QMapIterator<QString, StelLocation> iter(locations); | ||
214 | 413 | while (iter.hasNext()) | ||
215 | 414 | { | ||
216 | 415 | iter.next(); | ||
217 | 416 | const StelLocation *loc=&iter.value(); | ||
218 | 417 | if (loc->country == country) | ||
219 | 418 | { | ||
220 | 419 | pickedLocations.insert(iter.key(), iter.value()); | ||
221 | 420 | } | ||
222 | 421 | } | ||
223 | 422 | modelPickedLocation->setStringList(pickedLocations.keys()); | ||
224 | 423 | } | ||
225 | 310 | 424 | ||
226 | === modified file 'src/core/StelLocationMgr.hpp' | |||
227 | --- src/core/StelLocationMgr.hpp 2013-10-14 07:43:06 +0000 | |||
228 | +++ src/core/StelLocationMgr.hpp 2014-08-06 17:11:24 +0000 | |||
229 | @@ -26,6 +26,7 @@ | |||
230 | 26 | #include <QMap> | 26 | #include <QMap> |
231 | 27 | 27 | ||
232 | 28 | class QStringListModel; | 28 | class QStringListModel; |
233 | 29 | class QNetworkReply; | ||
234 | 29 | 30 | ||
235 | 30 | //! @class StelLocationMgr | 31 | //! @class StelLocationMgr |
236 | 31 | //! Manage the list of available location. | 32 | //! Manage the list of available location. |
237 | @@ -41,6 +42,8 @@ | |||
238 | 41 | 42 | ||
239 | 42 | //! Return the model containing all the city | 43 | //! Return the model containing all the city |
240 | 43 | QStringListModel* getModelAll() {return modelAllLocation;} | 44 | QStringListModel* getModelAll() {return modelAllLocation;} |
241 | 45 | //! Return the model containing picked (nearby) cities or cities from a single country, or other preselection. | ||
242 | 46 | QStringListModel* getModelPicked() {return modelPickedLocation;} | ||
243 | 44 | 47 | ||
244 | 45 | //! Return the list of all loaded locations | 48 | //! Return the list of all loaded locations |
245 | 46 | QList<StelLocation> getAll() const {return locations.values();} | 49 | QList<StelLocation> getAll() const {return locations.values();} |
246 | @@ -70,6 +73,20 @@ | |||
247 | 70 | //! @param id the location ID | 73 | //! @param id the location ID |
248 | 71 | bool deleteUserLocation(const QString& id); | 74 | bool deleteUserLocation(const QString& id); |
249 | 72 | 75 | ||
250 | 76 | //! Find location via online lookup of IP address | ||
251 | 77 | void locationFromIP(); | ||
252 | 78 | |||
253 | 79 | //! Preselect list of locations within @param radiusDegrees of selected (usually screen-clicked) coordinates. | ||
254 | 80 | //! The list can be retrieved by calling @name getModelPicked(). | ||
255 | 81 | void pickLocationsNearby(const QString planetName, const float longitude, const float latitude, const float radiusDegrees); | ||
256 | 82 | //! Preselect list of locations in a particular country only. | ||
257 | 83 | //! The list can be retrieved by calling @name getModelPicked(). | ||
258 | 84 | void pickLocationsInCountry(const QString country); | ||
259 | 85 | |||
260 | 86 | public slots: | ||
261 | 87 | //! Process answer from online lookup of IP address | ||
262 | 88 | void changeLocationFromNetworkLookup(); | ||
263 | 89 | |||
264 | 73 | private: | 90 | private: |
265 | 74 | void generateBinaryLocationFile(const QString& txtFile, bool isUserLocation, const QString& binFile) const; | 91 | void generateBinaryLocationFile(const QString& txtFile, bool isUserLocation, const QString& binFile) const; |
266 | 75 | 92 | ||
267 | @@ -79,11 +96,19 @@ | |||
268 | 79 | 96 | ||
269 | 80 | //! Model containing all the city information | 97 | //! Model containing all the city information |
270 | 81 | QStringListModel* modelAllLocation; | 98 | QStringListModel* modelAllLocation; |
271 | 99 | //! Model containing selected city information | ||
272 | 100 | QStringListModel* modelPickedLocation; | ||
273 | 82 | 101 | ||
274 | 83 | //! The list of all loaded locations | 102 | //! The list of all loaded locations |
275 | 84 | QMap<QString, StelLocation> locations; | 103 | QMap<QString, StelLocation> locations; |
276 | 104 | //! A list of locations generated on-the-fly by filtering from @name locations | ||
277 | 105 | QMap<QString, StelLocation> pickedLocations; | ||
278 | 85 | 106 | ||
279 | 86 | StelLocation lastResortLocation; | 107 | StelLocation lastResortLocation; |
280 | 108 | |||
281 | 109 | //! For IP-based location lookup | ||
282 | 110 | QNetworkReply *networkReply; | ||
283 | 111 | |||
284 | 87 | }; | 112 | }; |
285 | 88 | 113 | ||
286 | 89 | #endif // _STELLOCATIONMGR_HPP_ | 114 | #endif // _STELLOCATIONMGR_HPP_ |
287 | 90 | 115 | ||
288 | === modified file 'src/gui/LocationDialog.cpp' | |||
289 | --- src/gui/LocationDialog.cpp 2014-03-21 18:03:55 +0000 | |||
290 | +++ src/gui/LocationDialog.cpp 2014-08-06 17:11:24 +0000 | |||
291 | @@ -99,22 +99,30 @@ | |||
292 | 99 | connect(ui->mapLabel, SIGNAL(positionChanged(double, double)), this, SLOT(setPositionFromMap(double, double))); | 99 | connect(ui->mapLabel, SIGNAL(positionChanged(double, double)), this, SLOT(setPositionFromMap(double, double))); |
293 | 100 | 100 | ||
294 | 101 | connect(ui->addLocationToListPushButton, SIGNAL(clicked()), this, SLOT(addCurrentLocationToList())); | 101 | connect(ui->addLocationToListPushButton, SIGNAL(clicked()), this, SLOT(addCurrentLocationToList())); |
296 | 102 | connect(ui->deleteLocationFromListPushButton, SIGNAL(clicked()), this, SLOT(deleteCurrentLocationFromList())); | 102 | connect(ui->deleteLocationFromListPushButton, SIGNAL(clicked()), this, SLOT(deleteCurrentLocationFromList())); |
297 | 103 | connect(ui->resetListPushButton, SIGNAL(clicked()), this, SLOT(resetCompleteList())); | ||
298 | 104 | connect(ui->countryNameComboBox, SIGNAL(activated(const QString &)), this, SLOT(filterSitesByCountry())); | ||
299 | 103 | 105 | ||
300 | 104 | StelCore* core = StelApp::getInstance().getCore(); | 106 | StelCore* core = StelApp::getInstance().getCore(); |
301 | 105 | const StelLocation& currentLocation = core->getCurrentLocation(); | 107 | const StelLocation& currentLocation = core->getCurrentLocation(); |
302 | 108 | bool b = (currentLocation.getID() == core->getDefaultLocationID()); | ||
303 | 109 | QSettings* conf = StelApp::getInstance().getSettings(); | ||
304 | 110 | if (conf->value("init_location/location", "auto").toString().contains("auto")) | ||
305 | 111 | { | ||
306 | 112 | ui->useIpQueryCheckBox->setChecked(true); | ||
307 | 113 | b = false; | ||
308 | 114 | } | ||
309 | 115 | |||
310 | 106 | setFieldsFromLocation(currentLocation); | 116 | setFieldsFromLocation(currentLocation); |
311 | 107 | |||
312 | 108 | const bool b = (currentLocation.getID() == core->getDefaultLocationID()); | ||
313 | 109 | updateDefaultLocationControls(b); | 117 | updateDefaultLocationControls(b); |
317 | 110 | connect(ui->useAsDefaultLocationCheckBox, SIGNAL(clicked()), this, SLOT(setDefaultLocation())); | 118 | |
318 | 111 | connect(ui->pushButtonReturnToDefault, SIGNAL(clicked()), | 119 | connect(ui->useIpQueryCheckBox, SIGNAL(clicked(bool)), this, SLOT(ipQueryLocation(bool))); |
319 | 112 | core, SLOT(returnToDefaultLocation())); | 120 | connect(ui->useAsDefaultLocationCheckBox, SIGNAL(clicked(bool)), this, SLOT(setDefaultLocation(bool))); |
320 | 121 | connect(ui->pushButtonReturnToDefault, SIGNAL(clicked()), core, SLOT(returnToDefaultLocation())); | ||
321 | 113 | 122 | ||
322 | 114 | connectEditSignals(); | 123 | connectEditSignals(); |
323 | 115 | 124 | ||
326 | 116 | connect(core, SIGNAL(locationChanged(StelLocation)), | 125 | connect(core, SIGNAL(locationChanged(StelLocation)), this, SLOT(updateFromProgram(StelLocation))); |
325 | 117 | this, SLOT(updateFromProgram(StelLocation))); | ||
327 | 118 | 126 | ||
328 | 119 | ui->citySearchLineEdit->setFocus(); | 127 | ui->citySearchLineEdit->setFocus(); |
329 | 120 | } | 128 | } |
330 | @@ -138,7 +146,12 @@ | |||
331 | 138 | // Check that the use as default check box needs to be updated | 146 | // Check that the use as default check box needs to be updated |
332 | 139 | // Move to setFieldsFromLocation()? --BM? | 147 | // Move to setFieldsFromLocation()? --BM? |
333 | 140 | const bool b = currentLocation.getID() == stelCore->getDefaultLocationID(); | 148 | const bool b = currentLocation.getID() == stelCore->getDefaultLocationID(); |
335 | 141 | updateDefaultLocationControls(b); | 149 | QSettings* conf = StelApp::getInstance().getSettings(); |
336 | 150 | if (!conf->value("init_location/location", "auto").toString().contains("auto")) | ||
337 | 151 | { | ||
338 | 152 | updateDefaultLocationControls(b); | ||
339 | 153 | ui->pushButtonReturnToDefault->setEnabled(!b); | ||
340 | 154 | } | ||
341 | 142 | 155 | ||
342 | 143 | const QString& key1 = currentLocation.getID(); | 156 | const QString& key1 = currentLocation.getID(); |
343 | 144 | const QString& key2 = locationFromFields().getID(); | 157 | const QString& key2 = locationFromFields().getID(); |
344 | @@ -169,8 +182,7 @@ | |||
345 | 169 | disconnect(ui->countryNameComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(reportEdit())); | 182 | disconnect(ui->countryNameComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(reportEdit())); |
346 | 170 | // Why an edit should be reported even if the country is not changed? --BM | 183 | // Why an edit should be reported even if the country is not changed? --BM |
347 | 171 | //disconnect(ui->countryNameComboBox, SIGNAL(activated(const QString&)), this, SLOT(comboBoxChanged(const QString&))); | 184 | //disconnect(ui->countryNameComboBox, SIGNAL(activated(const QString&)), this, SLOT(comboBoxChanged(const QString&))); |
350 | 172 | disconnect(ui->cityNameLineEdit, SIGNAL(textEdited(const QString&)), | 185 | disconnect(ui->cityNameLineEdit, SIGNAL(textEdited(const QString&)), this, SLOT(reportEdit())); |
349 | 173 | this, SLOT(reportEdit())); | ||
351 | 174 | } | 186 | } |
352 | 175 | 187 | ||
353 | 176 | void LocationDialog::connectEditSignals() | 188 | void LocationDialog::connectEditSignals() |
354 | @@ -182,8 +194,7 @@ | |||
355 | 182 | connect(ui->countryNameComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(reportEdit())); | 194 | connect(ui->countryNameComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(reportEdit())); |
356 | 183 | // Why an edit should be reported even if the country is not changed? --BM | 195 | // Why an edit should be reported even if the country is not changed? --BM |
357 | 184 | //connect(ui->countryNameComboBox, SIGNAL(activated(const QString&)), this, SLOT(comboBoxChanged(const QString&))); | 196 | //connect(ui->countryNameComboBox, SIGNAL(activated(const QString&)), this, SLOT(comboBoxChanged(const QString&))); |
360 | 185 | connect(ui->cityNameLineEdit, SIGNAL(textEdited(const QString&)), | 197 | connect(ui->cityNameLineEdit, SIGNAL(textEdited(const QString&)), this, SLOT(reportEdit())); |
359 | 186 | this, SLOT(reportEdit())); | ||
361 | 187 | } | 198 | } |
362 | 188 | 199 | ||
363 | 189 | void LocationDialog::setFieldsFromLocation(const StelLocation& loc) | 200 | void LocationDialog::setFieldsFromLocation(const StelLocation& loc) |
364 | @@ -235,7 +246,7 @@ | |||
365 | 235 | // Update the map for the given location. | 246 | // Update the map for the given location. |
366 | 236 | void LocationDialog::setMapForLocation(const StelLocation& loc) | 247 | void LocationDialog::setMapForLocation(const StelLocation& loc) |
367 | 237 | { | 248 | { |
369 | 238 | // Avoids usless processing | 249 | // Avoids useless processing |
370 | 239 | if (lastPlanet==loc.planetName) | 250 | if (lastPlanet==loc.planetName) |
371 | 240 | return; | 251 | return; |
372 | 241 | 252 | ||
373 | @@ -358,6 +369,15 @@ | |||
374 | 358 | loc.longitude = longitude; | 369 | loc.longitude = longitude; |
375 | 359 | setFieldsFromLocation(loc); | 370 | setFieldsFromLocation(loc); |
376 | 360 | StelApp::getInstance().getCore()->moveObserverTo(loc, 0.); | 371 | StelApp::getInstance().getCore()->moveObserverTo(loc, 0.); |
377 | 372 | // GZ: Filter location list for nearby sites. I assume Earth locations are better known. With only few locations on other planets in the list, 30 degrees seem OK. | ||
378 | 373 | StelApp::getInstance().getLocationMgr().pickLocationsNearby(loc.planetName, longitude, latitude, loc.planetName=="Earth" ? 3.0f: 30.0f); | ||
379 | 374 | QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this); | ||
380 | 375 | proxyModel->setSourceModel((QAbstractItemModel*)StelApp::getInstance().getLocationMgr().getModelPicked()); | ||
381 | 376 | proxyModel->sort(0, Qt::AscendingOrder); | ||
382 | 377 | proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); | ||
383 | 378 | ui->citiesListView->setModel(proxyModel); | ||
384 | 379 | ui->citySearchLineEdit->clear(); | ||
385 | 380 | connect(ui->citySearchLineEdit, SIGNAL(textChanged(const QString&)), proxyModel, SLOT(setFilterWildcard(const QString&))); | ||
386 | 361 | } | 381 | } |
387 | 362 | 382 | ||
388 | 363 | // Called when the planet name is changed by hand | 383 | // Called when the planet name is changed by hand |
389 | @@ -380,6 +400,24 @@ | |||
390 | 380 | ls->setCurrentLandscapeID(ls->getDefaultLandscapeID()); | 400 | ls->setCurrentLandscapeID(ls->getDefaultLandscapeID()); |
391 | 381 | } | 401 | } |
392 | 382 | 402 | ||
393 | 403 | // GZ populate site list with sites only from that planet, or full list for Earth (faster than removing the ~50 non-Earth positions...). | ||
394 | 404 | StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr(); | ||
395 | 405 | QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this); | ||
396 | 406 | if (loc.planetName == "Earth") | ||
397 | 407 | { | ||
398 | 408 | proxyModel->setSourceModel((QAbstractItemModel*)locMgr.getModelAll()); | ||
399 | 409 | } | ||
400 | 410 | else | ||
401 | 411 | { | ||
402 | 412 | locMgr.pickLocationsNearby(loc.planetName, 0.0f, 0.0f, 180.0f); | ||
403 | 413 | proxyModel->setSourceModel((QAbstractItemModel*)locMgr.getModelPicked()); | ||
404 | 414 | } | ||
405 | 415 | proxyModel->sort(0, Qt::AscendingOrder); | ||
406 | 416 | proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); | ||
407 | 417 | ui->citiesListView->setModel(proxyModel); | ||
408 | 418 | ui->citySearchLineEdit->clear(); | ||
409 | 419 | connect(ui->citySearchLineEdit, SIGNAL(textChanged(const QString&)), proxyModel, SLOT(setFilterWildcard(const QString&))); | ||
410 | 420 | ui->citySearchLineEdit->setFocus(); | ||
411 | 383 | } | 421 | } |
412 | 384 | // Planet transition time also set to null to prevent uglyness when | 422 | // Planet transition time also set to null to prevent uglyness when |
413 | 385 | // "use landscape location" is enabled for that planet's landscape. --BM | 423 | // "use landscape location" is enabled for that planet's landscape. --BM |
414 | @@ -429,7 +467,7 @@ | |||
415 | 429 | ui->deleteLocationFromListPushButton->setEnabled(locationMgr.canDeleteUserLocation(loc.getID())); | 467 | ui->deleteLocationFromListPushButton->setEnabled(locationMgr.canDeleteUserLocation(loc.getID())); |
416 | 430 | } | 468 | } |
417 | 431 | 469 | ||
419 | 432 | // Called when the user clic on the save button | 470 | // Called when the user clicks on the save button |
420 | 433 | void LocationDialog::addCurrentLocationToList() | 471 | void LocationDialog::addCurrentLocationToList() |
421 | 434 | { | 472 | { |
422 | 435 | const StelLocation& loc = locationFromFields(); | 473 | const StelLocation& loc = locationFromFields(); |
423 | @@ -456,22 +494,27 @@ | |||
424 | 456 | } | 494 | } |
425 | 457 | 495 | ||
426 | 458 | // Called when the user wants to use the current location as default | 496 | // Called when the user wants to use the current location as default |
428 | 459 | void LocationDialog::setDefaultLocation() | 497 | void LocationDialog::setDefaultLocation(bool state) |
429 | 460 | { | 498 | { |
433 | 461 | StelCore* core = StelApp::getInstance().getCore(); | 499 | if (state) |
434 | 462 | QString currentLocationId = core->getCurrentLocation().getID(); | 500 | { |
435 | 463 | core->setDefaultLocationID(currentLocationId); | 501 | StelCore* core = StelApp::getInstance().getCore(); |
436 | 502 | QString currentLocationId = core->getCurrentLocation().getID(); | ||
437 | 503 | core->setDefaultLocationID(currentLocationId); | ||
438 | 464 | 504 | ||
449 | 465 | // Why this code even exists? After the previous code, this should always | 505 | // Why this code even exists? After the previous code, this should always |
450 | 466 | // be true, except if setting the default location somehow fails. --BM | 506 | // be true, except if setting the default location somehow fails. --BM |
451 | 467 | bool isDefault = (currentLocationId == core->getDefaultLocationID()); | 507 | bool isDefault = (currentLocationId == core->getDefaultLocationID()); |
452 | 468 | disconnectEditSignals(); | 508 | disconnectEditSignals(); |
453 | 469 | updateDefaultLocationControls(isDefault); | 509 | updateDefaultLocationControls(isDefault); |
454 | 470 | //The focus need to be switched to another control, otherwise | 510 | ui->pushButtonReturnToDefault->setEnabled(!isDefault); |
455 | 471 | //ui->latitudeSpinBox receives it and emits a valueChanged() signal when | 511 | ui->useIpQueryCheckBox->setChecked(!state); |
456 | 472 | //the window is closed. | 512 | //The focus need to be switched to another control, otherwise |
457 | 473 | ui->citySearchLineEdit->setFocus(); | 513 | //ui->latitudeSpinBox receives it and emits a valueChanged() signal when |
458 | 474 | connectEditSignals(); | 514 | //the window is closed. |
459 | 515 | ui->citySearchLineEdit->setFocus(); | ||
460 | 516 | connectEditSignals(); | ||
461 | 517 | } | ||
462 | 475 | } | 518 | } |
463 | 476 | 519 | ||
464 | 477 | // Called when the user clicks on the delete button | 520 | // Called when the user clicks on the delete button |
465 | @@ -484,6 +527,54 @@ | |||
466 | 484 | void LocationDialog::updateDefaultLocationControls(bool currentIsDefault) | 527 | void LocationDialog::updateDefaultLocationControls(bool currentIsDefault) |
467 | 485 | { | 528 | { |
468 | 486 | ui->useAsDefaultLocationCheckBox->setChecked(currentIsDefault); | 529 | ui->useAsDefaultLocationCheckBox->setChecked(currentIsDefault); |
471 | 487 | ui->useAsDefaultLocationCheckBox->setEnabled(!currentIsDefault); | 530 | ui->useAsDefaultLocationCheckBox->setEnabled(!currentIsDefault); |
472 | 488 | ui->pushButtonReturnToDefault->setEnabled(!currentIsDefault); | 531 | } |
473 | 532 | |||
474 | 533 | // called when the user clicks on the IP Query button | ||
475 | 534 | void LocationDialog::ipQueryLocation(bool state) | ||
476 | 535 | { | ||
477 | 536 | if (state) | ||
478 | 537 | { | ||
479 | 538 | QSettings* conf = StelApp::getInstance().getSettings(); | ||
480 | 539 | conf->setValue("init_location/location", "auto"); | ||
481 | 540 | disconnectEditSignals(); | ||
482 | 541 | resetCompleteList(); // in case we are on Moon/Mars, we must get list back to show all (earth) locations... | ||
483 | 542 | StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr(); | ||
484 | 543 | locMgr.locationFromIP(); // This just triggers asynchronous lookup. | ||
485 | 544 | ui->useAsDefaultLocationCheckBox->setChecked(!state); | ||
486 | 545 | ui->pushButtonReturnToDefault->setEnabled(!state); | ||
487 | 546 | connectEditSignals(); | ||
488 | 547 | ui->citySearchLineEdit->setFocus(); | ||
489 | 548 | } | ||
490 | 549 | } | ||
491 | 550 | |||
492 | 551 | // called when user clicks "reset list" | ||
493 | 552 | void LocationDialog::resetCompleteList() | ||
494 | 553 | { | ||
495 | 554 | QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this); | ||
496 | 555 | proxyModel->setSourceModel((QAbstractItemModel*)StelApp::getInstance().getLocationMgr().getModelAll()); | ||
497 | 556 | proxyModel->sort(0, Qt::AscendingOrder); | ||
498 | 557 | proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); | ||
499 | 558 | ui->citiesListView->setModel(proxyModel); | ||
500 | 559 | ui->citySearchLineEdit->clear(); | ||
501 | 560 | connect(ui->citySearchLineEdit, SIGNAL(textChanged(const QString&)), proxyModel, SLOT(setFilterWildcard(const QString&))); | ||
502 | 561 | ui->citySearchLineEdit->setFocus(); | ||
503 | 562 | } | ||
504 | 563 | |||
505 | 564 | // called when user clicks in the country combobox and selects a country. The locations in the list are updated to select only sites in that country. | ||
506 | 565 | void LocationDialog::filterSitesByCountry() | ||
507 | 566 | { | ||
508 | 567 | QString country=ui->countryNameComboBox->currentData().toString(); | ||
509 | 568 | QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this); | ||
510 | 569 | StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr(); | ||
511 | 570 | |||
512 | 571 | locMgr.pickLocationsInCountry(country); | ||
513 | 572 | proxyModel->setSourceModel((QAbstractItemModel*)locMgr.getModelPicked()); | ||
514 | 573 | |||
515 | 574 | proxyModel->sort(0, Qt::AscendingOrder); | ||
516 | 575 | proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); | ||
517 | 576 | ui->citiesListView->setModel(proxyModel); | ||
518 | 577 | ui->citySearchLineEdit->clear(); | ||
519 | 578 | connect(ui->citySearchLineEdit, SIGNAL(textChanged(const QString&)), proxyModel, SLOT(setFilterWildcard(const QString&))); | ||
520 | 579 | ui->citySearchLineEdit->setFocus(); | ||
521 | 489 | } | 580 | } |
522 | 490 | 581 | ||
523 | === modified file 'src/gui/LocationDialog.hpp' | |||
524 | --- src/gui/LocationDialog.hpp 2013-10-14 09:27:54 +0000 | |||
525 | +++ src/gui/LocationDialog.hpp 2014-08-06 17:11:24 +0000 | |||
526 | @@ -82,6 +82,7 @@ | |||
527 | 82 | void updateFromProgram(const StelLocation& location); | 82 | void updateFromProgram(const StelLocation& location); |
528 | 83 | 83 | ||
529 | 84 | //! Called when the map is clicked. | 84 | //! Called when the map is clicked. |
530 | 85 | //! GZ_New: create new list for places nearby and feed into location list box. | ||
531 | 85 | void setPositionFromMap(double longitude, double latitude); | 86 | void setPositionFromMap(double longitude, double latitude); |
532 | 86 | 87 | ||
533 | 87 | //! Called when the user activates an item from the locations list. | 88 | //! Called when the user activates an item from the locations list. |
534 | @@ -97,9 +98,18 @@ | |||
535 | 97 | 98 | ||
536 | 98 | //! Called when the user clicks on the delete button | 99 | //! Called when the user clicks on the delete button |
537 | 99 | void deleteCurrentLocationFromList(); | 100 | void deleteCurrentLocationFromList(); |
538 | 101 | |||
539 | 102 | //! filter city list to show entries from single country only | ||
540 | 103 | void filterSitesByCountry(); | ||
541 | 104 | |||
542 | 105 | //! reset city list to complete list (may have been reduced to picked list) | ||
543 | 106 | void resetCompleteList(); | ||
544 | 107 | |||
545 | 108 | //! called when the user wants get location from network | ||
546 | 109 | void ipQueryLocation(bool state); | ||
547 | 100 | 110 | ||
548 | 101 | //! Called when the user wants to use the current location as default | 111 | //! Called when the user wants to use the current location as default |
550 | 102 | void setDefaultLocation(); | 112 | void setDefaultLocation(bool state); |
551 | 103 | 113 | ||
552 | 104 | private: | 114 | private: |
553 | 105 | QString lastPlanet; | 115 | QString lastPlanet; |
554 | 106 | 116 | ||
555 | === modified file 'src/gui/locationDialogGui.ui' | |||
556 | --- src/gui/locationDialogGui.ui 2014-06-16 13:43:31 +0000 | |||
557 | +++ src/gui/locationDialogGui.ui 2014-08-06 17:11:24 +0000 | |||
558 | @@ -7,7 +7,7 @@ | |||
559 | 7 | <x>0</x> | 7 | <x>0</x> |
560 | 8 | <y>0</y> | 8 | <y>0</y> |
561 | 9 | <width>700</width> | 9 | <width>700</width> |
563 | 10 | <height>452</height> | 10 | <height>460</height> |
564 | 11 | </rect> | 11 | </rect> |
565 | 12 | </property> | 12 | </property> |
566 | 13 | <property name="styleSheet"> | 13 | <property name="styleSheet"> |
567 | @@ -359,6 +359,16 @@ | |||
568 | 359 | </property> | 359 | </property> |
569 | 360 | </widget> | 360 | </widget> |
570 | 361 | </item> | 361 | </item> |
571 | 362 | <item> | ||
572 | 363 | <widget class="QPushButton" name="resetListPushButton"> | ||
573 | 364 | <property name="toolTip"> | ||
574 | 365 | <string>Reset location list to show all known locations</string> | ||
575 | 366 | </property> | ||
576 | 367 | <property name="text"> | ||
577 | 368 | <string>Reset Location List</string> | ||
578 | 369 | </property> | ||
579 | 370 | </widget> | ||
580 | 371 | </item> | ||
581 | 362 | </layout> | 372 | </layout> |
582 | 363 | </widget> | 373 | </widget> |
583 | 364 | </item> | 374 | </item> |
584 | @@ -383,113 +393,20 @@ | |||
585 | 383 | <property name="bottomMargin"> | 393 | <property name="bottomMargin"> |
586 | 384 | <number>0</number> | 394 | <number>0</number> |
587 | 385 | </property> | 395 | </property> |
591 | 386 | <item row="2" column="0" colspan="3"> | 396 | <item row="1" column="2" colspan="2"> |
592 | 387 | <widget class="QFrame" name="frame_3"> | 397 | <spacer name="verticalSpacer"> |
593 | 388 | <property name="minimumSize"> | 398 | <property name="orientation"> |
594 | 399 | <enum>Qt::Vertical</enum> | ||
595 | 400 | </property> | ||
596 | 401 | <property name="sizeHint" stdset="0"> | ||
597 | 389 | <size> | 402 | <size> |
600 | 390 | <width>0</width> | 403 | <width>20</width> |
601 | 391 | <height>0</height> | 404 | <height>40</height> |
602 | 392 | </size> | 405 | </size> |
603 | 393 | </property> | 406 | </property> |
701 | 394 | <property name="frameShape"> | 407 | </spacer> |
605 | 395 | <enum>QFrame::StyledPanel</enum> | ||
606 | 396 | </property> | ||
607 | 397 | <property name="frameShadow"> | ||
608 | 398 | <enum>QFrame::Raised</enum> | ||
609 | 399 | </property> | ||
610 | 400 | <layout class="QHBoxLayout" name="horizontalLayout"> | ||
611 | 401 | <property name="leftMargin"> | ||
612 | 402 | <number>0</number> | ||
613 | 403 | </property> | ||
614 | 404 | <property name="topMargin"> | ||
615 | 405 | <number>0</number> | ||
616 | 406 | </property> | ||
617 | 407 | <property name="rightMargin"> | ||
618 | 408 | <number>0</number> | ||
619 | 409 | </property> | ||
620 | 410 | <property name="bottomMargin"> | ||
621 | 411 | <number>0</number> | ||
622 | 412 | </property> | ||
623 | 413 | <item> | ||
624 | 414 | <widget class="QCheckBox" name="useAsDefaultLocationCheckBox"> | ||
625 | 415 | <property name="font"> | ||
626 | 416 | <font> | ||
627 | 417 | <stylestrategy>PreferDefault</stylestrategy> | ||
628 | 418 | </font> | ||
629 | 419 | </property> | ||
630 | 420 | <property name="focusPolicy"> | ||
631 | 421 | <enum>Qt::NoFocus</enum> | ||
632 | 422 | </property> | ||
633 | 423 | <property name="text"> | ||
634 | 424 | <string>Use as default</string> | ||
635 | 425 | </property> | ||
636 | 426 | </widget> | ||
637 | 427 | </item> | ||
638 | 428 | <item> | ||
639 | 429 | <widget class="QPushButton" name="pushButtonReturnToDefault"> | ||
640 | 430 | <property name="focusPolicy"> | ||
641 | 431 | <enum>Qt::NoFocus</enum> | ||
642 | 432 | </property> | ||
643 | 433 | <property name="text"> | ||
644 | 434 | <string>Return to default</string> | ||
645 | 435 | </property> | ||
646 | 436 | </widget> | ||
647 | 437 | </item> | ||
648 | 438 | <item> | ||
649 | 439 | <spacer name="horizontalSpacer"> | ||
650 | 440 | <property name="orientation"> | ||
651 | 441 | <enum>Qt::Horizontal</enum> | ||
652 | 442 | </property> | ||
653 | 443 | <property name="sizeHint" stdset="0"> | ||
654 | 444 | <size> | ||
655 | 445 | <width>40</width> | ||
656 | 446 | <height>20</height> | ||
657 | 447 | </size> | ||
658 | 448 | </property> | ||
659 | 449 | </spacer> | ||
660 | 450 | </item> | ||
661 | 451 | <item> | ||
662 | 452 | <widget class="QPushButton" name="deleteLocationFromListPushButton"> | ||
663 | 453 | <property name="enabled"> | ||
664 | 454 | <bool>false</bool> | ||
665 | 455 | </property> | ||
666 | 456 | <property name="minimumSize"> | ||
667 | 457 | <size> | ||
668 | 458 | <width>60</width> | ||
669 | 459 | <height>0</height> | ||
670 | 460 | </size> | ||
671 | 461 | </property> | ||
672 | 462 | <property name="focusPolicy"> | ||
673 | 463 | <enum>Qt::NoFocus</enum> | ||
674 | 464 | </property> | ||
675 | 465 | <property name="text"> | ||
676 | 466 | <string>Delete</string> | ||
677 | 467 | </property> | ||
678 | 468 | </widget> | ||
679 | 469 | </item> | ||
680 | 470 | <item> | ||
681 | 471 | <widget class="QPushButton" name="addLocationToListPushButton"> | ||
682 | 472 | <property name="enabled"> | ||
683 | 473 | <bool>false</bool> | ||
684 | 474 | </property> | ||
685 | 475 | <property name="minimumSize"> | ||
686 | 476 | <size> | ||
687 | 477 | <width>100</width> | ||
688 | 478 | <height>0</height> | ||
689 | 479 | </size> | ||
690 | 480 | </property> | ||
691 | 481 | <property name="focusPolicy"> | ||
692 | 482 | <enum>Qt::NoFocus</enum> | ||
693 | 483 | </property> | ||
694 | 484 | <property name="text"> | ||
695 | 485 | <string>Add to list</string> | ||
696 | 486 | </property> | ||
697 | 487 | </widget> | ||
698 | 488 | </item> | ||
699 | 489 | </layout> | ||
700 | 490 | </widget> | ||
702 | 491 | </item> | 408 | </item> |
704 | 492 | <item row="0" column="0"> | 409 | <item row="0" column="1"> |
705 | 493 | <widget class="QFrame" name="frame_4"> | 410 | <widget class="QFrame" name="frame_4"> |
706 | 494 | <property name="minimumSize"> | 411 | <property name="minimumSize"> |
707 | 495 | <size> | 412 | <size> |
708 | @@ -603,7 +520,114 @@ | |||
709 | 603 | </layout> | 520 | </layout> |
710 | 604 | </widget> | 521 | </widget> |
711 | 605 | </item> | 522 | </item> |
712 | 523 | <item row="2" column="1" colspan="3"> | ||
713 | 524 | <widget class="QFrame" name="frame_3"> | ||
714 | 525 | <property name="minimumSize"> | ||
715 | 526 | <size> | ||
716 | 527 | <width>0</width> | ||
717 | 528 | <height>0</height> | ||
718 | 529 | </size> | ||
719 | 530 | </property> | ||
720 | 531 | <property name="frameShape"> | ||
721 | 532 | <enum>QFrame::StyledPanel</enum> | ||
722 | 533 | </property> | ||
723 | 534 | <property name="frameShadow"> | ||
724 | 535 | <enum>QFrame::Raised</enum> | ||
725 | 536 | </property> | ||
726 | 537 | <layout class="QHBoxLayout" name="horizontalLayout"> | ||
727 | 538 | <property name="leftMargin"> | ||
728 | 539 | <number>0</number> | ||
729 | 540 | </property> | ||
730 | 541 | <property name="topMargin"> | ||
731 | 542 | <number>0</number> | ||
732 | 543 | </property> | ||
733 | 544 | <property name="rightMargin"> | ||
734 | 545 | <number>0</number> | ||
735 | 546 | </property> | ||
736 | 547 | <property name="bottomMargin"> | ||
737 | 548 | <number>0</number> | ||
738 | 549 | </property> | ||
739 | 550 | <item> | ||
740 | 551 | <spacer name="horizontalSpacer"> | ||
741 | 552 | <property name="orientation"> | ||
742 | 553 | <enum>Qt::Horizontal</enum> | ||
743 | 554 | </property> | ||
744 | 555 | <property name="sizeHint" stdset="0"> | ||
745 | 556 | <size> | ||
746 | 557 | <width>40</width> | ||
747 | 558 | <height>20</height> | ||
748 | 559 | </size> | ||
749 | 560 | </property> | ||
750 | 561 | </spacer> | ||
751 | 562 | </item> | ||
752 | 563 | <item> | ||
753 | 564 | <widget class="QPushButton" name="pushButtonReturnToDefault"> | ||
754 | 565 | <property name="enabled"> | ||
755 | 566 | <bool>false</bool> | ||
756 | 567 | </property> | ||
757 | 568 | <property name="focusPolicy"> | ||
758 | 569 | <enum>Qt::NoFocus</enum> | ||
759 | 570 | </property> | ||
760 | 571 | <property name="text"> | ||
761 | 572 | <string>Return to default location</string> | ||
762 | 573 | </property> | ||
763 | 574 | </widget> | ||
764 | 575 | </item> | ||
765 | 576 | <item> | ||
766 | 577 | <widget class="QPushButton" name="deleteLocationFromListPushButton"> | ||
767 | 578 | <property name="enabled"> | ||
768 | 579 | <bool>false</bool> | ||
769 | 580 | </property> | ||
770 | 581 | <property name="minimumSize"> | ||
771 | 582 | <size> | ||
772 | 583 | <width>60</width> | ||
773 | 584 | <height>0</height> | ||
774 | 585 | </size> | ||
775 | 586 | </property> | ||
776 | 587 | <property name="focusPolicy"> | ||
777 | 588 | <enum>Qt::NoFocus</enum> | ||
778 | 589 | </property> | ||
779 | 590 | <property name="text"> | ||
780 | 591 | <string>Delete</string> | ||
781 | 592 | </property> | ||
782 | 593 | </widget> | ||
783 | 594 | </item> | ||
784 | 595 | <item> | ||
785 | 596 | <widget class="QPushButton" name="addLocationToListPushButton"> | ||
786 | 597 | <property name="enabled"> | ||
787 | 598 | <bool>false</bool> | ||
788 | 599 | </property> | ||
789 | 600 | <property name="minimumSize"> | ||
790 | 601 | <size> | ||
791 | 602 | <width>100</width> | ||
792 | 603 | <height>0</height> | ||
793 | 604 | </size> | ||
794 | 605 | </property> | ||
795 | 606 | <property name="focusPolicy"> | ||
796 | 607 | <enum>Qt::NoFocus</enum> | ||
797 | 608 | </property> | ||
798 | 609 | <property name="text"> | ||
799 | 610 | <string>Add to list</string> | ||
800 | 611 | </property> | ||
801 | 612 | </widget> | ||
802 | 613 | </item> | ||
803 | 614 | </layout> | ||
804 | 615 | </widget> | ||
805 | 616 | </item> | ||
806 | 606 | <item row="0" column="2"> | 617 | <item row="0" column="2"> |
807 | 618 | <spacer name="horizontalSpacer_2"> | ||
808 | 619 | <property name="orientation"> | ||
809 | 620 | <enum>Qt::Horizontal</enum> | ||
810 | 621 | </property> | ||
811 | 622 | <property name="sizeHint" stdset="0"> | ||
812 | 623 | <size> | ||
813 | 624 | <width>40</width> | ||
814 | 625 | <height>20</height> | ||
815 | 626 | </size> | ||
816 | 627 | </property> | ||
817 | 628 | </spacer> | ||
818 | 629 | </item> | ||
819 | 630 | <item row="0" column="3"> | ||
820 | 607 | <widget class="QFrame" name="frame_5"> | 631 | <widget class="QFrame" name="frame_5"> |
821 | 608 | <property name="minimumSize"> | 632 | <property name="minimumSize"> |
822 | 609 | <size> | 633 | <size> |
823 | @@ -717,31 +741,19 @@ | |||
824 | 717 | </layout> | 741 | </layout> |
825 | 718 | </widget> | 742 | </widget> |
826 | 719 | </item> | 743 | </item> |
839 | 720 | <item row="1" column="1" colspan="2"> | 744 | <item row="3" column="1"> |
840 | 721 | <spacer name="verticalSpacer"> | 745 | <widget class="QCheckBox" name="useAsDefaultLocationCheckBox"> |
841 | 722 | <property name="orientation"> | 746 | <property name="text"> |
842 | 723 | <enum>Qt::Vertical</enum> | 747 | <string>Use current location as default</string> |
843 | 724 | </property> | 748 | </property> |
844 | 725 | <property name="sizeHint" stdset="0"> | 749 | </widget> |
833 | 726 | <size> | ||
834 | 727 | <width>20</width> | ||
835 | 728 | <height>40</height> | ||
836 | 729 | </size> | ||
837 | 730 | </property> | ||
838 | 731 | </spacer> | ||
845 | 732 | </item> | 750 | </item> |
858 | 733 | <item row="0" column="1"> | 751 | <item row="3" column="3"> |
859 | 734 | <spacer name="horizontalSpacer_2"> | 752 | <widget class="QCheckBox" name="useIpQueryCheckBox"> |
860 | 735 | <property name="orientation"> | 753 | <property name="text"> |
861 | 736 | <enum>Qt::Horizontal</enum> | 754 | <string>Get location from Network</string> |
862 | 737 | </property> | 755 | </property> |
863 | 738 | <property name="sizeHint" stdset="0"> | 756 | </widget> |
852 | 739 | <size> | ||
853 | 740 | <width>40</width> | ||
854 | 741 | <height>20</height> | ||
855 | 742 | </size> | ||
856 | 743 | </property> | ||
857 | 744 | </spacer> | ||
864 | 745 | </item> | 757 | </item> |
865 | 746 | </layout> | 758 | </layout> |
866 | 747 | </widget> | 759 | </widget> |
I checked this feature and it good work! But one moment: I think that label "IP Query" on button is not very informative and we should add tooltip and describe it.