Merge lp:~stellarium/stellarium/ip-query-location into lp:stellarium

Proposed by Alexander Wolf
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
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.

To post a comment you must log in.
Revision history for this message
Alexander Wolf (alexwolf) wrote :

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.

review: Approve
Revision history for this message
Alexander Wolf (alexwolf) wrote :

The second feature is OK for me. Are you want merge it yourself?

Revision history for this message
Alexander Wolf (alexwolf) wrote :

Wait! What about non-Earth location?

review: Needs Fixing
Revision history for this message
Fabien Chéreau (xalioth) wrote :
Download full text (11.0 KiB)

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://code.launchpad.net/~georg-zotti/stellarium/ip-query-location/+merge/227418
>
> This branch introduces new feature - automatic finding approximate
> location of Stellarium from IP address.
> --
>
> https://code.launchpad.net/~georg-zotti/stellarium/ip-query-location/+merge/227418
> You are subscribed to branch lp:stellarium.
>
> === modified file 'src/core/StelCore.cpp'
> --- src/core/StelCore.cpp 2014-04-14 17:55:46 +0000
> +++ src/core/StelCore.cpp 2014-07-19 07:57:49 +0000
> @@ -114,7 +114,14 @@
> defaultLocationID =
> conf->value("init_location/location","error").toString();
> bool ok;
> StelLocationMgr* locationMgr =
> &StelApp::getInstance().getLocationMgr();
> - StelLocation location =
> locationMgr->locationForString(defaultLocationID);
> + StelLocation location;
> + if (conf->value("init_location/use_ip_geolocation_if_available",
> "false").toBool()
> + && locationMgr->ipConnectionExists())
> + {
> + location=locationMgr->locationFromIP();
> + }
> +
> + else location = locationMgr->locationForString(defaultLocationID);
> if (!location.isValid())
> {
> qWarning() << "Warning: location" << defaultLocationID <<
> "is unknown.";
>
> === modified file 'src/core/StelLocationMgr.cpp'
> --- src/core/StelLocationMgr.cpp 2014-06-12 15:47:22 +0000
> +++ src/core/StelLocationMgr.cpp 2014-07-19 07:57:49 +0000
> @@ -25,6 +25,13 @@
> #include <QDebug>
> #include <QFile>
> #include <QDir>
> +#include <QtNetwork/QNetworkInterface>
> +#include <QtNetwork/QNetworkAccessManager>
> +#include <QEventLoop>
> +#include <QNetworkRequest>
> +#include <QNetworkReply>
> +#include <QUrl>
> +#include <QUrlQuery>
>
> StelLocationMgr::StelLocationMgr()
> {
> @@ -307,3 +314,99 @@
> sourcefile.close();
> return true;
> }
> +
> +
> +//! check if there is an IP connection.
> +// Along the lines of
> +//
> http://karanbalkar.com/2014/02/detect-internet-connection-using-qt-5-framework/
> +//#define DEBUG 1
> +bool StelLocationMgr::ipConnectionExists() const
> +{
> + QList<QNetworkInterface> ifaces = QNetworkInterface::allInterfaces();
> + bool connectionExists = false;
> +
> + for (int i = 0; i < ifaces.count(); i++) {
> +
> + QNetworkInterface iface = ifaces.at(i);
> + if ( iface.flags().testFlag(QNetworkInterface::IsUp)
> + && !iface.flags().testFlag(QNetworkInterface::IsLoopBack)) {
> +
> +#ifdef DEBUG
> + // details of connection
> + qDebug() << "name:" << iface.name() << endl
> + << "mac:" << iface.hardwareAddress() << endl
> + << "ip addresses:" << endl;
> +#endif
> + for (int j=0; j<iface.addressEntries().count...

Revision history for this message
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://code.launchpad.net/~georg-zotti/stellarium/ip-query-location/+merge/227418
> You are the owner of lp:~georg-zotti/stellarium/ip-query-location.
>

Revision history for this message
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!

Revision history for this message
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://code.launchpad.net/~georg-zotti/stellarium/ip-query-location/+merge/227418
> You are the owner of lp:~georg-zotti/stellarium/ip-query-location.
>

Revision history for this message
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

Revision history for this message
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://code.launchpad.net/~georg-zotti/stellarium/ip-query-location/+merge/227418
> You are the owner of lp:~georg-zotti/stellarium/ip-query-location.
>

Revision history for this message
gzotti (georg-zotti) wrote :

I have added the requested improvements. I think it works all now.

review: Needs Resubmitting
Revision history for this message
Alexander Wolf (alexwolf) wrote :

OK. It work correct now and I think it ready to merge. Fabien?

review: Approve
Revision history for this message
Fabien Chéreau (xalioth) wrote :

Please see comments

review: Needs Fixing
6935. By gzotti

removed include no longer required

Revision history for this message
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...

review: Needs Fixing
6936. By gzotti

Added braces for Marcos Cardinot.
Fixed indentation (space/tab; 3 files worked, one didn't?)

Revision history for this message
Marcos Cardinot (cardinot) :
review: Approve
Revision history for this message
gzotti (georg-zotti) wrote :
Download full text (19.3 KiB)

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/StelCore.cpp'
>> --- src/core/StelCore.cpp 2014-04-14 17:55:46 +0000
>> +++ src/core/StelCore.cpp 2014-07-20 13:42:31 +0000
>> @@ -114,7 +114,13 @@
>> defaultLocationID =
>> conf->value("init_location/location","error").toString();
>> bool ok;
>> StelLocationMgr* locationMgr =
>> &StelApp::getInstance().getLocationMgr();
>> - StelLocation location =
>> locationMgr->locationForString(defaultLocationID);
>> + StelLocation location;
>> + if (conf->value("init_location/use_ip_geolocation_if_available",
>> "false").toBool())
>> + {
>> + locationMgr->locationFromIP();
>> + }
>> +
>> + else location = locationMgr->locationForString(defaultLocationID);
>> if (!location.isValid())
>> {
>> qWarning() << "Warning: location" << defaultLocationID << "is
>> unknown.";
>>
>> === modified file 'src/core/StelLocation.cpp'
>> --- src/core/StelLocation.cpp 2014-02-15 15:37:23 +0000
>> +++ src/core/StelLocation.cpp 2014-07-20 13:42:31 +0000
>> @@ -125,3 +125,10 @@
>> return loc;
>> }
>>
>> +// Compute great-circle distance between two locations
>> +float StelLocation::distanceDegrees(const float long1, const float
>> lat1, const float long2, const float lat2)
>> +{
>> + const float DEGREES=M_PI/180.0f;
>> + return std::acos( std::sin(lat1*DEGREES)*std::sin(lat2*DEGREES) +
>> +
>> std::cos(lat1*DEGREES)*std::cos(lat2*DEGREES)*std::cos((long1-long2)*DEGREES)
>> ) / DEGREES;
>> +}
>>
>> === modified file 'src/core/StelLocation.hpp'
>> --- src/core/StelLocation.hpp 2014-04-15 17:10:07 +0000
>> +++ src/core/StelLocation.hpp 2014-07-20 13:42:31 +0000
>> @@ -74,6 +74,9 @@
>> //! Parse a location from a line serialization
>> static StelLocation createFromLine(const QString& line);
>>
>> + //! Compute great-circle distance between two locations
>> + static float distanceDegrees(const float long1, const float lat1,
>> const float long2, const float lat2);
>> +
>> //! Used privately by the StelLocationMgr
>> bool isUserLocation;
>>
>>
>> === modified file 'src/core/StelLocationMgr.cpp'
>> --- src/core/StelLocationMgr.cpp 2014-06-12 15:47:22 +0000
>> +++ src/core/StelLocationMgr.cpp 2014-07-20 13:42:31 +0000
>> @@ -17,6 +17,7 @@
>> */
>>
>> #include "StelApp.hpp"
>> +#include "StelCore.hpp"
>> #include "StelFileMgr.hpp"
>> #include "StelLocationMgr.hpp"
>> #include "StelUtils.hpp"
>> @@ -25,6 +26,12 @@
>> #include <QDebug>
>> #include <QFile>
>> #include <QDir>
>> +#include <QtNetwork/QNetworkInterface>
>> +#include <QtNetwork/QNetworkAccessManager>
>> +#include <QNetworkRequest>
>> +#include <QNetworkReply>
>> +#include <QUrl>
>> +#include <QUrlQuery>
>>
>> StelLocationMgr::StelLocationMgr()
>> {
>> @@ -36,9 +43,12 @@
>>
>> modelAllLocation = new QStringListModel(this);
>> modelAllLocation->setStringList(locations.keys());
>> + modelPickedLocation = new QStringListModel(this); // keep empty for
>> now.
>>
>> // Init to Paris France because it's the center of the world.
>> lastResortLocation =...

Revision history for this message
Fabien Chéreau (xalioth) wrote :
Download full text (22.3 KiB)

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/use_ip_geolocation_if_available" key.

- Also when the lookup is successful, we could save the last know location
into an "init_location/last_resort_location" for the next time we start
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/StelCore.cpp'
> >> --- src/core/StelCore.cpp 2014-04-14 17:55:46 +0000
> >> +++ src/core/StelCore.cpp 2014-07-20 13:42:31 +0000
> >> @@ -114,7 +114,13 @@
> >> defaultLocationID =
> >> conf->value("init_location/location","error").toString();
> >> bool ok;
> >> StelLocationMgr* locationMgr =
> >> &StelApp::getInstance().getLocationMgr();
> >> - StelLocation location =
> >> locationMgr->locationForString(defaultLocationID);
> >> + StelLocation location;
> >> + if (conf->value("init_location/use_ip_geolocation_if_available",
> >> "false").toBool())
> >> + {
> >> + locationMgr->locationFromIP();
> >> + }
> >> +
> >> + else location = locationMgr->locationForString(defaultLocationID);
> >> if (!location.isValid())
> >> {
> >> qWarning() << "Warning: location" << defaultLocationID <<
> "is
> >> unknown.";
> >>
> >> === modified file 'src/core/StelLocation.cpp'
> >> --- src/core/StelLocation.cpp 2014-02-15 15:37:23 +0000
> >> +++ src/core/StelLocation.cpp 2014-07-20 13:42:31 +0000
> >> @@ -125,3 +125,10 @@
> >> return loc;
> >> }
> >>
> >> +// Compute great-circle distance between two locations
> >> +float StelLocation::distanceDegrees(const float long1, const float
> >> lat1, const float long2, const float lat2)
> >> +{
> >> + const float DEGREES=M_PI/180.0f;
> >> + return std::acos( std::sin(lat1*DEGREES)*std::sin(lat2*DEGREES) +
> >> +
> >>
> std::cos(lat1*DEGREES)*std::cos(lat2*DEGREES)*std::cos((long1-long2)*DEGREES)
> >> ) / DEGREES;
> >> +}
> >>
> >> === modified file 'src/core/StelLocation.hpp'
> >> --- src/core/StelLocation.hpp 2014-04-15 17:10:07 +0000
> >> +++ src/core/StelLocation.hpp 2014-07-20 13:42:31 +0000
> >> ...

Revision history for this message
gzotti (georg-zotti) wrote :
Download full text (3.3 KiB)

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-auto-lookup-at-start feature is OK. But It must be
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/use_ip_geolocation_if_available" key.
>
> - Also when the lookup is successful, we could save the last know location
> into an "init_location/last_resort_location" for the next time we start
> without network.
>
> Sorry to give these feedbacks so late, I hope they make sense, what do you
> think? In ...

Read more...

Revision history for this message
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.

Revision history for this message
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

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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 nebula_magnitude_limit = 8.5
6
7 [init_location]
8-location = Paris, France
9+location = auto
10 landscape_name = guereins
11
12 [files]
13
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 {
19 QSettings* conf = StelApp::getInstance().getSettings();
20
21- defaultLocationID = conf->value("init_location/location","error").toString();
22+ defaultLocationID = conf->value("init_location/location", "auto").toString();
23 bool ok;
24 StelLocationMgr* locationMgr = &StelApp::getInstance().getLocationMgr();
25- StelLocation location = locationMgr->locationForString(defaultLocationID);
26+ StelLocation location;
27+ if (defaultLocationID.contains("auto"))
28+ {
29+ locationMgr->locationFromIP();
30+ }
31+ else
32+ {
33+ location = locationMgr->locationForString(defaultLocationID);
34+ }
35+
36 if (!location.isValid())
37 {
38 qWarning() << "Warning: location" << defaultLocationID << "is unknown.";
39
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 return loc;
45 }
46
47+// Compute great-circle distance between two locations
48+float StelLocation::distanceDegrees(const float long1, const float lat1, const float long2, const float lat2)
49+{
50+ const float DEGREES=M_PI/180.0f;
51+ return std::acos( std::sin(lat1*DEGREES)*std::sin(lat2*DEGREES) +
52+ std::cos(lat1*DEGREES)*std::cos(lat2*DEGREES)*std::cos((long1-long2)*DEGREES) ) / DEGREES;
53+}
54
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 //! Parse a location from a line serialization
60 static StelLocation createFromLine(const QString& line);
61
62+ //! Compute great-circle distance between two locations
63+ static float distanceDegrees(const float long1, const float lat1, const float long2, const float lat2);
64+
65 //! Used privately by the StelLocationMgr
66 bool isUserLocation;
67
68
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 */
74
75 #include "StelApp.hpp"
76+#include "StelCore.hpp"
77 #include "StelFileMgr.hpp"
78 #include "StelLocationMgr.hpp"
79 #include "StelUtils.hpp"
80@@ -25,9 +26,18 @@
81 #include <QDebug>
82 #include <QFile>
83 #include <QDir>
84+#include <QtNetwork/QNetworkInterface>
85+#include <QtNetwork/QNetworkAccessManager>
86+#include <QNetworkRequest>
87+#include <QNetworkReply>
88+#include <QUrl>
89+#include <QUrlQuery>
90+#include <QSettings>
91
92 StelLocationMgr::StelLocationMgr()
93 {
94+ QSettings* conf = StelApp::getInstance().getSettings();
95+
96 // The line below allows to re-generate the location file, you still need to gunzip it manually afterward.
97 // generateBinaryLocationFile("data/base_locations.txt", false, "data/base_locations.bin");
98
99@@ -36,9 +46,10 @@
100
101 modelAllLocation = new QStringListModel(this);
102 modelAllLocation->setStringList(locations.keys());
103+ modelPickedLocation = new QStringListModel(this); // keep empty for now.
104
105 // Init to Paris France because it's the center of the world.
106- lastResortLocation = locationForString("Paris, France");
107+ lastResortLocation = locationForString(conf->value("init_location/last_resort_location", "Paris, France").toString());
108 }
109
110 void StelLocationMgr::generateBinaryLocationFile(const QString& fileName, bool isUserLocation, const QString& binFilePath) const
111@@ -144,6 +155,10 @@
112
113 StelLocationMgr::~StelLocationMgr()
114 {
115+ delete modelPickedLocation;
116+ modelPickedLocation=NULL;
117+ delete modelAllLocation;
118+ modelAllLocation=NULL;
119 }
120
121 static float parseAngle(const QString& s, bool* ok)
122@@ -307,3 +322,102 @@
123 sourcefile.close();
124 return true;
125 }
126+
127+// lookup location from IP address.
128+void StelLocationMgr::locationFromIP()
129+{
130+ QNetworkRequest req( QUrl( QString("http://freegeoip.net/csv/") ) );
131+ networkReply=StelApp::getInstance().getNetworkAccessManager()->get(req);
132+ connect(networkReply, SIGNAL(finished()), this, SLOT(changeLocationFromNetworkLookup()));
133+}
134+
135+// slot that receives IP-based location data from the network.
136+void StelLocationMgr::changeLocationFromNetworkLookup()
137+{
138+ StelLocation location;
139+ StelCore *core=StelApp::getInstance().getCore();
140+ if (networkReply->error() == QNetworkReply::NoError) {
141+ //success
142+ // Tested with and without working network connection.
143+ QByteArray answer=networkReply->readAll();
144+ // answer/splitline example: "222.222.222.222","AT","Austria","","","","","47.3333","13.3333","",""
145+ // The parts from freegeoip are: ip,country_code,country_name,region_code,region_name,city,zipcode,latitude,longitude,metro_code,area_code
146+ // longitude and latitude should always be filled.
147+ // A few tests:
148+ if ((answer.count('"') != 22 ) || (answer.count(',') != 10 ))
149+ {
150+ qDebug() << "StelLocationMgr: Malformatted answer in IP-based location lookup: \n\t" << answer;
151+ qDebug() << "StelLocationMgr: Will not change location.";
152+ networkReply->deleteLater();
153+ return;
154+ }
155+ const QStringList& splitline = QString(answer).split(",");
156+ if (splitline.count() != 11 )
157+ {
158+ qDebug() << "StelLocationMgr: Unexpected answer in IP-based location lookup: \n\t" << answer;
159+ qDebug() << "StelLocationMgr: Will not change location.";
160+ networkReply->deleteLater();
161+ return;
162+ }
163+ if ((splitline.at(7)=="\"\"") || (splitline.at(8)=="\"\"")) // empty coordinates?
164+ {
165+ qDebug() << "StelLocationMgr: Invalid coordinates from IP-based lookup. Ignoring: \n\t" << answer;
166+ networkReply->deleteLater();
167+ return;
168+ }
169+ float latitude=splitline.at(7).mid(1, splitline.at(7).length()-2).toFloat();
170+ float longitude=splitline.at(8).mid(1, splitline.at(8).length()-2).toFloat();
171+ QString locLine= // we re-pack into a new line that will be parsed back by StelLocation...
172+ QString("%1\t%2\t%3\t%4\t%5\t%6\t%7\t0")
173+ .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+ .arg(splitline.at(4).length()>2 ? splitline.at(4).mid(1, splitline.at(4).length()-2) : "IPregion")
175+ .arg(splitline.at(2).length()>2 ? splitline.at(2).mid(1, splitline.at(2).length()-2) : "IPcountry") // country
176+ .arg("X") // role: X=user-defined
177+ .arg(0) // population: unknown
178+ .arg(latitude<0 ? QString("%1S").arg(-latitude, 0, 'f', 6) : QString("%1N").arg(latitude, 0, 'f', 6))
179+ .arg(longitude<0 ? QString("%1W").arg(-longitude, 0, 'f', 6) : QString("%1E").arg(longitude, 0, 'f', 6));
180+ location=StelLocation::createFromLine(locLine); // in lack of a regular constructor ;-)
181+ core->moveObserverTo(location, 0.0f, 0.0f);
182+ QSettings* conf = StelApp::getInstance().getSettings();
183+ conf->setValue("init_location/last_resort_location", QString("%1, %2").arg(location.name).arg(location.country));
184+ }
185+ else
186+ {
187+ qDebug() << "Failure getting IP-based location: \n\t" <<networkReply->errorString();
188+ core->moveObserverTo(lastResortLocation, 0.0f, 0.0f);
189+ }
190+ networkReply->deleteLater();
191+}
192+
193+void StelLocationMgr::pickLocationsNearby(const QString planetName, const float longitude, const float latitude, const float radiusDegrees)
194+{
195+ pickedLocations.clear();
196+ QMapIterator<QString, StelLocation> iter(locations);
197+ while (iter.hasNext())
198+ {
199+ iter.next();
200+ const StelLocation *loc=&iter.value();
201+ if ( (loc->planetName == planetName) &&
202+ (StelLocation::distanceDegrees(longitude, latitude, loc->longitude, loc->latitude) <= radiusDegrees) )
203+ {
204+ pickedLocations.insert(iter.key(), iter.value());
205+ }
206+ }
207+ modelPickedLocation->setStringList(pickedLocations.keys());
208+}
209+
210+void StelLocationMgr::pickLocationsInCountry(const QString country)
211+{
212+ pickedLocations.clear();
213+ QMapIterator<QString, StelLocation> iter(locations);
214+ while (iter.hasNext())
215+ {
216+ iter.next();
217+ const StelLocation *loc=&iter.value();
218+ if (loc->country == country)
219+ {
220+ pickedLocations.insert(iter.key(), iter.value());
221+ }
222+ }
223+ modelPickedLocation->setStringList(pickedLocations.keys());
224+}
225
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 #include <QMap>
231
232 class QStringListModel;
233+class QNetworkReply;
234
235 //! @class StelLocationMgr
236 //! Manage the list of available location.
237@@ -41,6 +42,8 @@
238
239 //! Return the model containing all the city
240 QStringListModel* getModelAll() {return modelAllLocation;}
241+ //! Return the model containing picked (nearby) cities or cities from a single country, or other preselection.
242+ QStringListModel* getModelPicked() {return modelPickedLocation;}
243
244 //! Return the list of all loaded locations
245 QList<StelLocation> getAll() const {return locations.values();}
246@@ -70,6 +73,20 @@
247 //! @param id the location ID
248 bool deleteUserLocation(const QString& id);
249
250+ //! Find location via online lookup of IP address
251+ void locationFromIP();
252+
253+ //! Preselect list of locations within @param radiusDegrees of selected (usually screen-clicked) coordinates.
254+ //! The list can be retrieved by calling @name getModelPicked().
255+ void pickLocationsNearby(const QString planetName, const float longitude, const float latitude, const float radiusDegrees);
256+ //! Preselect list of locations in a particular country only.
257+ //! The list can be retrieved by calling @name getModelPicked().
258+ void pickLocationsInCountry(const QString country);
259+
260+public slots:
261+ //! Process answer from online lookup of IP address
262+ void changeLocationFromNetworkLookup();
263+
264 private:
265 void generateBinaryLocationFile(const QString& txtFile, bool isUserLocation, const QString& binFile) const;
266
267@@ -79,11 +96,19 @@
268
269 //! Model containing all the city information
270 QStringListModel* modelAllLocation;
271+ //! Model containing selected city information
272+ QStringListModel* modelPickedLocation;
273
274 //! The list of all loaded locations
275 QMap<QString, StelLocation> locations;
276+ //! A list of locations generated on-the-fly by filtering from @name locations
277+ QMap<QString, StelLocation> pickedLocations;
278
279 StelLocation lastResortLocation;
280+
281+ //! For IP-based location lookup
282+ QNetworkReply *networkReply;
283+
284 };
285
286 #endif // _STELLOCATIONMGR_HPP_
287
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 connect(ui->mapLabel, SIGNAL(positionChanged(double, double)), this, SLOT(setPositionFromMap(double, double)));
293
294 connect(ui->addLocationToListPushButton, SIGNAL(clicked()), this, SLOT(addCurrentLocationToList()));
295- connect(ui->deleteLocationFromListPushButton, SIGNAL(clicked()), this, SLOT(deleteCurrentLocationFromList()));
296+ connect(ui->deleteLocationFromListPushButton, SIGNAL(clicked()), this, SLOT(deleteCurrentLocationFromList()));
297+ connect(ui->resetListPushButton, SIGNAL(clicked()), this, SLOT(resetCompleteList()));
298+ connect(ui->countryNameComboBox, SIGNAL(activated(const QString &)), this, SLOT(filterSitesByCountry()));
299
300 StelCore* core = StelApp::getInstance().getCore();
301 const StelLocation& currentLocation = core->getCurrentLocation();
302+ bool b = (currentLocation.getID() == core->getDefaultLocationID());
303+ QSettings* conf = StelApp::getInstance().getSettings();
304+ if (conf->value("init_location/location", "auto").toString().contains("auto"))
305+ {
306+ ui->useIpQueryCheckBox->setChecked(true);
307+ b = false;
308+ }
309+
310 setFieldsFromLocation(currentLocation);
311-
312- const bool b = (currentLocation.getID() == core->getDefaultLocationID());
313 updateDefaultLocationControls(b);
314- connect(ui->useAsDefaultLocationCheckBox, SIGNAL(clicked()), this, SLOT(setDefaultLocation()));
315- connect(ui->pushButtonReturnToDefault, SIGNAL(clicked()),
316- core, SLOT(returnToDefaultLocation()));
317+
318+ connect(ui->useIpQueryCheckBox, SIGNAL(clicked(bool)), this, SLOT(ipQueryLocation(bool)));
319+ connect(ui->useAsDefaultLocationCheckBox, SIGNAL(clicked(bool)), this, SLOT(setDefaultLocation(bool)));
320+ connect(ui->pushButtonReturnToDefault, SIGNAL(clicked()), core, SLOT(returnToDefaultLocation()));
321
322 connectEditSignals();
323
324- connect(core, SIGNAL(locationChanged(StelLocation)),
325- this, SLOT(updateFromProgram(StelLocation)));
326+ connect(core, SIGNAL(locationChanged(StelLocation)), this, SLOT(updateFromProgram(StelLocation)));
327
328 ui->citySearchLineEdit->setFocus();
329 }
330@@ -138,7 +146,12 @@
331 // Check that the use as default check box needs to be updated
332 // Move to setFieldsFromLocation()? --BM?
333 const bool b = currentLocation.getID() == stelCore->getDefaultLocationID();
334- updateDefaultLocationControls(b);
335+ QSettings* conf = StelApp::getInstance().getSettings();
336+ if (!conf->value("init_location/location", "auto").toString().contains("auto"))
337+ {
338+ updateDefaultLocationControls(b);
339+ ui->pushButtonReturnToDefault->setEnabled(!b);
340+ }
341
342 const QString& key1 = currentLocation.getID();
343 const QString& key2 = locationFromFields().getID();
344@@ -169,8 +182,7 @@
345 disconnect(ui->countryNameComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(reportEdit()));
346 // Why an edit should be reported even if the country is not changed? --BM
347 //disconnect(ui->countryNameComboBox, SIGNAL(activated(const QString&)), this, SLOT(comboBoxChanged(const QString&)));
348- disconnect(ui->cityNameLineEdit, SIGNAL(textEdited(const QString&)),
349- this, SLOT(reportEdit()));
350+ disconnect(ui->cityNameLineEdit, SIGNAL(textEdited(const QString&)), this, SLOT(reportEdit()));
351 }
352
353 void LocationDialog::connectEditSignals()
354@@ -182,8 +194,7 @@
355 connect(ui->countryNameComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(reportEdit()));
356 // Why an edit should be reported even if the country is not changed? --BM
357 //connect(ui->countryNameComboBox, SIGNAL(activated(const QString&)), this, SLOT(comboBoxChanged(const QString&)));
358- connect(ui->cityNameLineEdit, SIGNAL(textEdited(const QString&)),
359- this, SLOT(reportEdit()));
360+ connect(ui->cityNameLineEdit, SIGNAL(textEdited(const QString&)), this, SLOT(reportEdit()));
361 }
362
363 void LocationDialog::setFieldsFromLocation(const StelLocation& loc)
364@@ -235,7 +246,7 @@
365 // Update the map for the given location.
366 void LocationDialog::setMapForLocation(const StelLocation& loc)
367 {
368- // Avoids usless processing
369+ // Avoids useless processing
370 if (lastPlanet==loc.planetName)
371 return;
372
373@@ -358,6 +369,15 @@
374 loc.longitude = longitude;
375 setFieldsFromLocation(loc);
376 StelApp::getInstance().getCore()->moveObserverTo(loc, 0.);
377+ // 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+ StelApp::getInstance().getLocationMgr().pickLocationsNearby(loc.planetName, longitude, latitude, loc.planetName=="Earth" ? 3.0f: 30.0f);
379+ QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
380+ proxyModel->setSourceModel((QAbstractItemModel*)StelApp::getInstance().getLocationMgr().getModelPicked());
381+ proxyModel->sort(0, Qt::AscendingOrder);
382+ proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
383+ ui->citiesListView->setModel(proxyModel);
384+ ui->citySearchLineEdit->clear();
385+ connect(ui->citySearchLineEdit, SIGNAL(textChanged(const QString&)), proxyModel, SLOT(setFilterWildcard(const QString&)));
386 }
387
388 // Called when the planet name is changed by hand
389@@ -380,6 +400,24 @@
390 ls->setCurrentLandscapeID(ls->getDefaultLandscapeID());
391 }
392
393+ // GZ populate site list with sites only from that planet, or full list for Earth (faster than removing the ~50 non-Earth positions...).
394+ StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr();
395+ QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
396+ if (loc.planetName == "Earth")
397+ {
398+ proxyModel->setSourceModel((QAbstractItemModel*)locMgr.getModelAll());
399+ }
400+ else
401+ {
402+ locMgr.pickLocationsNearby(loc.planetName, 0.0f, 0.0f, 180.0f);
403+ proxyModel->setSourceModel((QAbstractItemModel*)locMgr.getModelPicked());
404+ }
405+ proxyModel->sort(0, Qt::AscendingOrder);
406+ proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
407+ ui->citiesListView->setModel(proxyModel);
408+ ui->citySearchLineEdit->clear();
409+ connect(ui->citySearchLineEdit, SIGNAL(textChanged(const QString&)), proxyModel, SLOT(setFilterWildcard(const QString&)));
410+ ui->citySearchLineEdit->setFocus();
411 }
412 // Planet transition time also set to null to prevent uglyness when
413 // "use landscape location" is enabled for that planet's landscape. --BM
414@@ -429,7 +467,7 @@
415 ui->deleteLocationFromListPushButton->setEnabled(locationMgr.canDeleteUserLocation(loc.getID()));
416 }
417
418-// Called when the user clic on the save button
419+// Called when the user clicks on the save button
420 void LocationDialog::addCurrentLocationToList()
421 {
422 const StelLocation& loc = locationFromFields();
423@@ -456,22 +494,27 @@
424 }
425
426 // Called when the user wants to use the current location as default
427-void LocationDialog::setDefaultLocation()
428+void LocationDialog::setDefaultLocation(bool state)
429 {
430- StelCore* core = StelApp::getInstance().getCore();
431- QString currentLocationId = core->getCurrentLocation().getID();
432- core->setDefaultLocationID(currentLocationId);
433+ if (state)
434+ {
435+ StelCore* core = StelApp::getInstance().getCore();
436+ QString currentLocationId = core->getCurrentLocation().getID();
437+ core->setDefaultLocationID(currentLocationId);
438
439- // Why this code even exists? After the previous code, this should always
440- // be true, except if setting the default location somehow fails. --BM
441- bool isDefault = (currentLocationId == core->getDefaultLocationID());
442- disconnectEditSignals();
443- updateDefaultLocationControls(isDefault);
444- //The focus need to be switched to another control, otherwise
445- //ui->latitudeSpinBox receives it and emits a valueChanged() signal when
446- //the window is closed.
447- ui->citySearchLineEdit->setFocus();
448- connectEditSignals();
449+ // Why this code even exists? After the previous code, this should always
450+ // be true, except if setting the default location somehow fails. --BM
451+ bool isDefault = (currentLocationId == core->getDefaultLocationID());
452+ disconnectEditSignals();
453+ updateDefaultLocationControls(isDefault);
454+ ui->pushButtonReturnToDefault->setEnabled(!isDefault);
455+ ui->useIpQueryCheckBox->setChecked(!state);
456+ //The focus need to be switched to another control, otherwise
457+ //ui->latitudeSpinBox receives it and emits a valueChanged() signal when
458+ //the window is closed.
459+ ui->citySearchLineEdit->setFocus();
460+ connectEditSignals();
461+ }
462 }
463
464 // Called when the user clicks on the delete button
465@@ -484,6 +527,54 @@
466 void LocationDialog::updateDefaultLocationControls(bool currentIsDefault)
467 {
468 ui->useAsDefaultLocationCheckBox->setChecked(currentIsDefault);
469- ui->useAsDefaultLocationCheckBox->setEnabled(!currentIsDefault);
470- ui->pushButtonReturnToDefault->setEnabled(!currentIsDefault);
471+ ui->useAsDefaultLocationCheckBox->setEnabled(!currentIsDefault);
472+}
473+
474+// called when the user clicks on the IP Query button
475+void LocationDialog::ipQueryLocation(bool state)
476+{
477+ if (state)
478+ {
479+ QSettings* conf = StelApp::getInstance().getSettings();
480+ conf->setValue("init_location/location", "auto");
481+ disconnectEditSignals();
482+ resetCompleteList(); // in case we are on Moon/Mars, we must get list back to show all (earth) locations...
483+ StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr();
484+ locMgr.locationFromIP(); // This just triggers asynchronous lookup.
485+ ui->useAsDefaultLocationCheckBox->setChecked(!state);
486+ ui->pushButtonReturnToDefault->setEnabled(!state);
487+ connectEditSignals();
488+ ui->citySearchLineEdit->setFocus();
489+ }
490+}
491+
492+// called when user clicks "reset list"
493+void LocationDialog::resetCompleteList()
494+{
495+ QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
496+ proxyModel->setSourceModel((QAbstractItemModel*)StelApp::getInstance().getLocationMgr().getModelAll());
497+ proxyModel->sort(0, Qt::AscendingOrder);
498+ proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
499+ ui->citiesListView->setModel(proxyModel);
500+ ui->citySearchLineEdit->clear();
501+ connect(ui->citySearchLineEdit, SIGNAL(textChanged(const QString&)), proxyModel, SLOT(setFilterWildcard(const QString&)));
502+ ui->citySearchLineEdit->setFocus();
503+}
504+
505+// 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+void LocationDialog::filterSitesByCountry()
507+{
508+ QString country=ui->countryNameComboBox->currentData().toString();
509+ QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel(this);
510+ StelLocationMgr &locMgr=StelApp::getInstance().getLocationMgr();
511+
512+ locMgr.pickLocationsInCountry(country);
513+ proxyModel->setSourceModel((QAbstractItemModel*)locMgr.getModelPicked());
514+
515+ proxyModel->sort(0, Qt::AscendingOrder);
516+ proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
517+ ui->citiesListView->setModel(proxyModel);
518+ ui->citySearchLineEdit->clear();
519+ connect(ui->citySearchLineEdit, SIGNAL(textChanged(const QString&)), proxyModel, SLOT(setFilterWildcard(const QString&)));
520+ ui->citySearchLineEdit->setFocus();
521 }
522
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 void updateFromProgram(const StelLocation& location);
528
529 //! Called when the map is clicked.
530+ //! GZ_New: create new list for places nearby and feed into location list box.
531 void setPositionFromMap(double longitude, double latitude);
532
533 //! Called when the user activates an item from the locations list.
534@@ -97,9 +98,18 @@
535
536 //! Called when the user clicks on the delete button
537 void deleteCurrentLocationFromList();
538+
539+ //! filter city list to show entries from single country only
540+ void filterSitesByCountry();
541+
542+ //! reset city list to complete list (may have been reduced to picked list)
543+ void resetCompleteList();
544+
545+ //! called when the user wants get location from network
546+ void ipQueryLocation(bool state);
547
548 //! Called when the user wants to use the current location as default
549- void setDefaultLocation();
550+ void setDefaultLocation(bool state);
551
552 private:
553 QString lastPlanet;
554
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 <x>0</x>
560 <y>0</y>
561 <width>700</width>
562- <height>452</height>
563+ <height>460</height>
564 </rect>
565 </property>
566 <property name="styleSheet">
567@@ -359,6 +359,16 @@
568 </property>
569 </widget>
570 </item>
571+ <item>
572+ <widget class="QPushButton" name="resetListPushButton">
573+ <property name="toolTip">
574+ <string>Reset location list to show all known locations</string>
575+ </property>
576+ <property name="text">
577+ <string>Reset Location List</string>
578+ </property>
579+ </widget>
580+ </item>
581 </layout>
582 </widget>
583 </item>
584@@ -383,113 +393,20 @@
585 <property name="bottomMargin">
586 <number>0</number>
587 </property>
588- <item row="2" column="0" colspan="3">
589- <widget class="QFrame" name="frame_3">
590- <property name="minimumSize">
591+ <item row="1" column="2" colspan="2">
592+ <spacer name="verticalSpacer">
593+ <property name="orientation">
594+ <enum>Qt::Vertical</enum>
595+ </property>
596+ <property name="sizeHint" stdset="0">
597 <size>
598- <width>0</width>
599- <height>0</height>
600+ <width>20</width>
601+ <height>40</height>
602 </size>
603 </property>
604- <property name="frameShape">
605- <enum>QFrame::StyledPanel</enum>
606- </property>
607- <property name="frameShadow">
608- <enum>QFrame::Raised</enum>
609- </property>
610- <layout class="QHBoxLayout" name="horizontalLayout">
611- <property name="leftMargin">
612- <number>0</number>
613- </property>
614- <property name="topMargin">
615- <number>0</number>
616- </property>
617- <property name="rightMargin">
618- <number>0</number>
619- </property>
620- <property name="bottomMargin">
621- <number>0</number>
622- </property>
623- <item>
624- <widget class="QCheckBox" name="useAsDefaultLocationCheckBox">
625- <property name="font">
626- <font>
627- <stylestrategy>PreferDefault</stylestrategy>
628- </font>
629- </property>
630- <property name="focusPolicy">
631- <enum>Qt::NoFocus</enum>
632- </property>
633- <property name="text">
634- <string>Use as default</string>
635- </property>
636- </widget>
637- </item>
638- <item>
639- <widget class="QPushButton" name="pushButtonReturnToDefault">
640- <property name="focusPolicy">
641- <enum>Qt::NoFocus</enum>
642- </property>
643- <property name="text">
644- <string>Return to default</string>
645- </property>
646- </widget>
647- </item>
648- <item>
649- <spacer name="horizontalSpacer">
650- <property name="orientation">
651- <enum>Qt::Horizontal</enum>
652- </property>
653- <property name="sizeHint" stdset="0">
654- <size>
655- <width>40</width>
656- <height>20</height>
657- </size>
658- </property>
659- </spacer>
660- </item>
661- <item>
662- <widget class="QPushButton" name="deleteLocationFromListPushButton">
663- <property name="enabled">
664- <bool>false</bool>
665- </property>
666- <property name="minimumSize">
667- <size>
668- <width>60</width>
669- <height>0</height>
670- </size>
671- </property>
672- <property name="focusPolicy">
673- <enum>Qt::NoFocus</enum>
674- </property>
675- <property name="text">
676- <string>Delete</string>
677- </property>
678- </widget>
679- </item>
680- <item>
681- <widget class="QPushButton" name="addLocationToListPushButton">
682- <property name="enabled">
683- <bool>false</bool>
684- </property>
685- <property name="minimumSize">
686- <size>
687- <width>100</width>
688- <height>0</height>
689- </size>
690- </property>
691- <property name="focusPolicy">
692- <enum>Qt::NoFocus</enum>
693- </property>
694- <property name="text">
695- <string>Add to list</string>
696- </property>
697- </widget>
698- </item>
699- </layout>
700- </widget>
701+ </spacer>
702 </item>
703- <item row="0" column="0">
704+ <item row="0" column="1">
705 <widget class="QFrame" name="frame_4">
706 <property name="minimumSize">
707 <size>
708@@ -603,7 +520,114 @@
709 </layout>
710 </widget>
711 </item>
712+ <item row="2" column="1" colspan="3">
713+ <widget class="QFrame" name="frame_3">
714+ <property name="minimumSize">
715+ <size>
716+ <width>0</width>
717+ <height>0</height>
718+ </size>
719+ </property>
720+ <property name="frameShape">
721+ <enum>QFrame::StyledPanel</enum>
722+ </property>
723+ <property name="frameShadow">
724+ <enum>QFrame::Raised</enum>
725+ </property>
726+ <layout class="QHBoxLayout" name="horizontalLayout">
727+ <property name="leftMargin">
728+ <number>0</number>
729+ </property>
730+ <property name="topMargin">
731+ <number>0</number>
732+ </property>
733+ <property name="rightMargin">
734+ <number>0</number>
735+ </property>
736+ <property name="bottomMargin">
737+ <number>0</number>
738+ </property>
739+ <item>
740+ <spacer name="horizontalSpacer">
741+ <property name="orientation">
742+ <enum>Qt::Horizontal</enum>
743+ </property>
744+ <property name="sizeHint" stdset="0">
745+ <size>
746+ <width>40</width>
747+ <height>20</height>
748+ </size>
749+ </property>
750+ </spacer>
751+ </item>
752+ <item>
753+ <widget class="QPushButton" name="pushButtonReturnToDefault">
754+ <property name="enabled">
755+ <bool>false</bool>
756+ </property>
757+ <property name="focusPolicy">
758+ <enum>Qt::NoFocus</enum>
759+ </property>
760+ <property name="text">
761+ <string>Return to default location</string>
762+ </property>
763+ </widget>
764+ </item>
765+ <item>
766+ <widget class="QPushButton" name="deleteLocationFromListPushButton">
767+ <property name="enabled">
768+ <bool>false</bool>
769+ </property>
770+ <property name="minimumSize">
771+ <size>
772+ <width>60</width>
773+ <height>0</height>
774+ </size>
775+ </property>
776+ <property name="focusPolicy">
777+ <enum>Qt::NoFocus</enum>
778+ </property>
779+ <property name="text">
780+ <string>Delete</string>
781+ </property>
782+ </widget>
783+ </item>
784+ <item>
785+ <widget class="QPushButton" name="addLocationToListPushButton">
786+ <property name="enabled">
787+ <bool>false</bool>
788+ </property>
789+ <property name="minimumSize">
790+ <size>
791+ <width>100</width>
792+ <height>0</height>
793+ </size>
794+ </property>
795+ <property name="focusPolicy">
796+ <enum>Qt::NoFocus</enum>
797+ </property>
798+ <property name="text">
799+ <string>Add to list</string>
800+ </property>
801+ </widget>
802+ </item>
803+ </layout>
804+ </widget>
805+ </item>
806 <item row="0" column="2">
807+ <spacer name="horizontalSpacer_2">
808+ <property name="orientation">
809+ <enum>Qt::Horizontal</enum>
810+ </property>
811+ <property name="sizeHint" stdset="0">
812+ <size>
813+ <width>40</width>
814+ <height>20</height>
815+ </size>
816+ </property>
817+ </spacer>
818+ </item>
819+ <item row="0" column="3">
820 <widget class="QFrame" name="frame_5">
821 <property name="minimumSize">
822 <size>
823@@ -717,31 +741,19 @@
824 </layout>
825 </widget>
826 </item>
827- <item row="1" column="1" colspan="2">
828- <spacer name="verticalSpacer">
829- <property name="orientation">
830- <enum>Qt::Vertical</enum>
831- </property>
832- <property name="sizeHint" stdset="0">
833- <size>
834- <width>20</width>
835- <height>40</height>
836- </size>
837- </property>
838- </spacer>
839+ <item row="3" column="1">
840+ <widget class="QCheckBox" name="useAsDefaultLocationCheckBox">
841+ <property name="text">
842+ <string>Use current location as default</string>
843+ </property>
844+ </widget>
845 </item>
846- <item row="0" column="1">
847- <spacer name="horizontalSpacer_2">
848- <property name="orientation">
849- <enum>Qt::Horizontal</enum>
850- </property>
851- <property name="sizeHint" stdset="0">
852- <size>
853- <width>40</width>
854- <height>20</height>
855- </size>
856- </property>
857- </spacer>
858+ <item row="3" column="3">
859+ <widget class="QCheckBox" name="useIpQueryCheckBox">
860+ <property name="text">
861+ <string>Get location from Network</string>
862+ </property>
863+ </widget>
864 </item>
865 </layout>
866 </widget>