Merge lp:~cardinot/stellarium/MeteorShower into lp:stellarium

Proposed by Marcos Cardinot
Status: Merged
Approved by: Marcos Cardinot
Approved revision: 7820
Merged at revision: 7767
Proposed branch: lp:~cardinot/stellarium/MeteorShower
Merge into: lp:stellarium
Diff against target: 10913 lines (+4744/-4557)
41 files modified
plugins/MeteorShowers/CMakeLists.txt (+2/-2)
plugins/MeteorShowers/resources/MeteorShower.qrc (+2/-0)
plugins/MeteorShowers/src/CMakeLists.txt (+11/-5)
plugins/MeteorShowers/src/MeteorObj.cpp (+86/-0)
plugins/MeteorShowers/src/MeteorObj.hpp (+46/-0)
plugins/MeteorShowers/src/MeteorShower.cpp (+500/-379)
plugins/MeteorShowers/src/MeteorShower.hpp (+107/-146)
plugins/MeteorShowers/src/MeteorShowers.cpp (+146/-1229)
plugins/MeteorShowers/src/MeteorShowers.hpp (+45/-373)
plugins/MeteorShowers/src/MeteorShowersMgr.cpp (+611/-0)
plugins/MeteorShowers/src/MeteorShowersMgr.hpp (+288/-0)
plugins/MeteorShowers/src/MeteorStream.cpp (+0/-128)
plugins/MeteorShowers/src/MeteorStream.hpp (+0/-71)
plugins/MeteorShowers/src/gui/MSConfigDialog.cpp (+313/-0)
plugins/MeteorShowers/src/gui/MSConfigDialog.hpp (+76/-0)
plugins/MeteorShowers/src/gui/MSConfigDialog.ui (+657/-0)
plugins/MeteorShowers/src/gui/MSSearchDialog.cpp (+192/-0)
plugins/MeteorShowers/src/gui/MSSearchDialog.hpp (+123/-0)
plugins/MeteorShowers/src/gui/MSSearchDialog.ui (+301/-0)
plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp (+0/-436)
plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp (+0/-110)
plugins/MeteorShowers/src/gui/meteorShowerDialog.ui (+0/-753)
plugins/MeteorShowers/src/translations.h (+199/-0)
po/stellarium-skycultures/stellarium-skycultures.pot (+1/-1)
po/stellarium/POTFILES.in (+8/-3)
po/stellarium/stellarium.pot (+387/-318)
src/CMakeLists.txt (+4/-3)
src/core/StelApp.cpp (+4/-4)
src/core/modules/LandscapeMgr.cpp (+1/-1)
src/core/modules/Meteor.cpp (+236/-241)
src/core/modules/Meteor.hpp (+70/-75)
src/core/modules/MeteorMgr.cpp (+0/-177)
src/core/modules/MeteorMgr.hpp (+0/-94)
src/core/modules/SporadicMeteor.cpp (+67/-0)
src/core/modules/SporadicMeteor.hpp (+40/-0)
src/core/modules/SporadicMeteorMgr.cpp (+141/-0)
src/core/modules/SporadicMeteorMgr.hpp (+72/-0)
src/gui/ConfigurationDialog.cpp (+2/-2)
src/gui/StelGui.cpp (+1/-1)
src/gui/ViewDialog.cpp (+3/-3)
src/scripting/StelMainScriptAPI.cpp (+2/-2)
To merge this branch: bzr merge lp:~cardinot/stellarium/MeteorShower
Reviewer Review Type Date Requested Status
gzotti Approve
Alexander Wolf Approve
Review via email: mp+266370@code.launchpad.net

Description of the change

This branch aims to improve and sort out several bugs of the Meteor Showers plugin and the Meteor module.

* main meteor model and the MS plugin was rewritten
* better management of the active meteors (great performance improvement)
* now we have a SporadicMeteor class, which inherits from the Meteor class
* huge cleanup on the MeteorShowers plugin
* MS plugin now has 2 dilogs: one to settings and another one to search events only
* several bugs with the management of the meteor activities were found and fixed
etc etc etc

To post a comment you must log in.
lp:~cardinot/stellarium/MeteorShower updated
7796. By Marcos Cardinot

conflicts

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

Cannot compile with Qt5.5 and MSVC:
MSConfigDialog.cpp line 55: 'listEvents' and 'aboutTextBrowser': not an element of 'Ui_MSConfigDialog'

I commented that out for now to continue compilation, but don't know what are the replacements.

and line 135: Apparently the name ERROR causes conflicts, even if given with MeteorShowersMgr::. I have replaced with e.g. MSMERROR, then it compiles and runs nicely.

Somewhere in the config panel, can you please describe what's a real/generic/inactive radiant?
And if you have implemented a model from some paper (???) and get the annual data from somewhere, can you please add a reference?

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

Inconsistent behaviour in GUI: "Show buttons on toolbar" ignores settings. Where is "Save settings" button and where is Leonides? :)

And I don't see any meteors :'(

review: Needs Fixing
lp:~cardinot/stellarium/MeteorShower updated
7801. By Marcos Cardinot

fix Kinetic scrolling

7802. By Marcos Cardinot

renames the DownloadStatus from ERROR to FAILED

Revision history for this message
Marcos Cardinot (cardinot) wrote :

Hi Georg, thanks for your review! ;)

> Cannot compile with Qt5.5 and MSVC:
> MSConfigDialog.cpp line 55: 'listEvents' and 'aboutTextBrowser': not an
> element of 'Ui_MSConfigDialog'

fixed!

> I commented that out for now to continue compilation, but don't know what are
> the replacements.
>
> and line 135: Apparently the name ERROR causes conflicts, even if given with
> MeteorShowersMgr::. I have replaced with e.g. MSMERROR, then it compiles and
> runs nicely.

I renamed it to FAILED - could you check if it works fine now please?

> Somewhere in the config panel, can you please describe what's a
> real/generic/inactive radiant?

Yeah, I will include a description on the about tab... but I think we should rename them to something more intuitive...

Real: it means that this data comes from a real IMO catalog - confirmed meteor shower
Generic: it means that this radiant is usually active at this time of year, but it was not confirmed from IMO.
Inactive: it means that this radiant is not active at this time of year.

Maybe we should rename to...
Real -> Confirmed
Generic -> Unconfirmed

ideas?

> And if you have implemented a model from some paper (???)
no
> and get the annual
> data from somewhere, can you please add a reference?

yes, we get the data from the International Meteor Organization catalog (http://imo.net/) - I will include it on the about tab

Revision history for this message
Marcos Cardinot (cardinot) wrote :

Hi Alex,
thanks for your review!

> Inconsistent behaviour in GUI: "Show buttons on toolbar" ignores settings.

fixed!

> Where is "Save settings" button

Now we just save things automatically =D
Since most software have the same behavior, it's far more intuitive than forcing users to click on "save" all the time.

If a user goes to the settings dialog, set something (mainly options like: 'enable buttons', 'enable plugin at startup', colors etc) and closes Stellarium... I bet $1.000.000.000 dollars that he would expect to see their settings there again - so, why ask for save?

> and where is Leonides? :)

please, update your catalog =D

> And I don't see any meteors :'(

could you check it for a radiant with a high ZHR please? (or even set some data on the catalog, only for tests)

lp:~cardinot/stellarium/MeteorShower updated
7803. By Marcos Cardinot

fix bug when setting the buttons on toolbar

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

A fresh catalog has invalid data for Leonids.

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

Hint: current version of plugin did not supports for format of meteor shower with variable ZHR

Revision history for this message
Marcos Cardinot (cardinot) wrote :

> Hint: current version of plugin did not supports for format of meteor shower
> with variable ZHR

Atually it supports - I only added some checkers to see if the "variable" field is in right format, which is "int-int"

On the older catalog, LEO had a activity with something like "int-int*"
http://bazaar.launchpad.net/~stellarium/stellarium/trunk/revision/7751

For the IMO catalog, this * means that his shower may have multiple peaks - but as it's very rare (see that this was the only case on the whole catalog) - we won't accept these "*" anymore...

--

We are loading the default catalog from qrc and it seems that Qt does not clean/refresh it properly - so, to avoid problems I will start loading the default catalog from the installation dir...

For now, you could just remove the "*" from your 'showers.json' and LEO should be available again =D

lp:~cardinot/stellarium/MeteorShower updated
7804. By Marcos Cardinot

restore default showers.json from installation directory instead of qrc

Revision history for this message
Marcos Cardinot (cardinot) wrote :

Hi Alex,
it should be fine now!
Could you also push the 'stellarium-website' branch to the SF? (just to update the showers.json)
thanks

lp:~cardinot/stellarium/MeteorShower updated
7805. By Marcos Cardinot

oops..typo

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

>Could you also push the 'stellarium-website' branch to the SF?

Yes, but not today

I don't understand your last 2 commits. Plugins should not store data into main data directory.

Revision history for this message
Marcos Cardinot (cardinot) wrote :

> >Could you also push the 'stellarium-website' branch to the SF?
>
> Yes, but not today

Ok, but have in mind that if your auto-updates is enabled, the new catalog will be replaced by the old one. (it explains why LEO was invalid for you, even after a fresh build)

> I don't understand your last 2 commits. Plugins should not store data into
> main data directory.

Yeah, you're right! I reverted both commits!

The copy from qrc is working fine. As I said, I was just with my auto-updates enabled, so, after copying the right file, I was replacing it with the old catalog from the web (which is outdated with the "*" issue)... that was the reason why I've thought that the copy was not being done correctly - my bad! - **1000 facepalms to me!** =D

lp:~cardinot/stellarium/MeteorShower updated
7806. By Marcos Cardinot

reverting the last commit - loads the default showers.json from qrc

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

> Hi Georg, thanks for your review! ;)

Hi!

Compilation with MSVC2013 works now.

> > Somewhere in the config panel, can you please describe what's a
> > real/generic/inactive radiant?
>
> Yeah, I will include a description on the about tab... but I think we should
> rename them to something more intuitive...
>
> Real: it means that this data comes from a real IMO catalog - confirmed meteor
> shower
> Generic: it means that this radiant is usually active at this time of year,
> but it was not confirmed from IMO.
> Inactive: it means that this radiant is not active at this time of year.
>
> Maybe we should rename to...
> Real -> Confirmed
> Generic -> Unconfirmed
>
> ideas?

Real->IMO confirmed
Generic -> average data

Another thing: After Searching showers in te search panel, they are sorted by name. I would prefer sort-by-date. ... Oh that works even with a table header click, good!

But if I want to sort now by ZHR (can you change the table heading to ZHR?), I am not sure how sorting works for min-max numbers? It's a minor issue, but just in case it's a simple fix, decide for min/average/max as sort value?

lp:~cardinot/stellarium/MeteorShower updated
7807. By Marcos Cardinot

search dialog - prefer sort-by-date

7808. By Marcos Cardinot

search dialog - fix bug when sorting by ZHR

ZHR is variable ? choose the max value

Revision history for this message
Marcos Cardinot (cardinot) wrote :

> > Hi Georg, thanks for your review! ;)
>
> Hi!
>
> Compilation with MSVC2013 works now.
>
> > > Somewhere in the config panel, can you please describe what's a
> > > real/generic/inactive radiant?
> >
> > Yeah, I will include a description on the about tab... but I think we should
> > rename them to something more intuitive...
> >
> > Real: it means that this data comes from a real IMO catalog - confirmed
> meteor
> > shower
> > Generic: it means that this radiant is usually active at this time of year,
> > but it was not confirmed from IMO.
> > Inactive: it means that this radiant is not active at this time of year.
> >
> > Maybe we should rename to...
> > Real -> Confirmed
> > Generic -> Unconfirmed
> >
> > ideas?
>
> Real->IMO confirmed
> Generic -> average data

Humm... the problem is that sometimes we (or even the user) could add a new shower, in which the data was confirmed by some other catalog - in this way, "IMO confirmed" would be too specific...

>
> Another thing: After Searching showers in te search panel, they are sorted by
> name. I would prefer sort-by-date. ... Oh that works even with a table header
> click, good!

Yeah, it's possible to sort the columns by clicking on the header =D
But I agree with you - I pushed a patch to always prefer sort-by-date...

>
> But if I want to sort now by ZHR (can you change the table heading to ZHR?),

But it's "ZHR" already - not?
http://bazaar.launchpad.net/~mcardinot/stellarium/MeteorShower/view/head:/plugins/MeteorShowers/src/gui/MSSearchDialog.cpp#L180

> I am not sure how sorting works for min-max numbers? It's a minor issue, but
> just in case it's a simple fix, decide for min/average/max as sort value?

good catch - thanks!
I believe that usually users would look for higher ZHRs, so I fixed it to always choose max...

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

> > >
> > > Maybe we should rename to...
> > > Real -> Confirmed
> > > Generic -> Unconfirmed
> > >
> > > ideas?
> >
> > Real->IMO confirmed
> > Generic -> average data
>
> Humm... the problem is that sometimes we (or even the user) could add a new
> shower, in which the data was confirmed by some other catalog - in this way,
> "IMO confirmed" would be too specific...

Ah, OK. (I am not too familiar with the details of this plugin, sorry.)
Real -> Current data
Generic -> Average data

> > But if I want to sort now by ZHR (can you change the table heading to ZHR?),
>
> But it's "ZHR" already - not?

Ouch, translation... --- OMG - it's my own! (Apparently at that time I had seen ZR used in the German literature. But the international "ZHR" may be better also in the German version after all.)

> > I am not sure how sorting works for min-max numbers? It's a minor issue,
> but
> > just in case it's a simple fix, decide for min/average/max as sort value?
>
> good catch - thanks!
> I believe that usually users would look for higher ZHRs, so I fixed it to
> always choose max...

OK

lp:~cardinot/stellarium/MeteorShower updated
7809. By Marcos Cardinot

Merge with trunk

7810. By Marcos Cardinot

fix merge conflicts

7811. By Marcos Cardinot

cosmetic fix

7812. By Marcos Cardinot

update pot

Revision history for this message
Marcos Cardinot (cardinot) wrote :

> > > >
> > > > Maybe we should rename to...
> > > > Real -> Confirmed
> > > > Generic -> Unconfirmed
> > > >
> > > > ideas?
> > >
> > > Real->IMO confirmed
> > > Generic -> average data
> >
> > Humm... the problem is that sometimes we (or even the user) could add a new
> > shower, in which the data was confirmed by some other catalog - in this way,
> > "IMO confirmed" would be too specific...
>
> Ah, OK. (I am not too familiar with the details of this plugin, sorry.)
> Real -> Current data
> Generic -> Average data

I'm ok with "Generic -> Average data", but I'm not sure if "Current data" is a good one... When using the MS plugin, people might be interested to see some historical showers (very high ZHR), so, using "current" would sounds strange... =/

>
> > > But if I want to sort now by ZHR (can you change the table heading to
> ZHR?),
> >
> > But it's "ZHR" already - not?
>
> Ouch, translation... --- OMG - it's my own! (Apparently at that time I had
> seen ZR used in the German literature. But the international "ZHR" may be
> better also in the German version after all.)
>
> > > I am not sure how sorting works for min-max numbers? It's a minor issue,
> > but
> > > just in case it's a simple fix, decide for min/average/max as sort value?
> >
> > good catch - thanks!
> > I believe that usually users would look for higher ZHRs, so I fixed it to
> > always choose max...
>
> OK

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

> > > > >
> > > > > Maybe we should rename to...
> > > > > Real -> Confirmed
> > > > > Generic -> Unconfirmed
> > > > >
> > > > > ideas?
> > > >
> > > > Real->IMO confirmed
> > > > Generic -> average data
> > >
> > > Humm... the problem is that sometimes we (or even the user) could add a
> new
> > > shower, in which the data was confirmed by some other catalog - in this
> way,
> > > "IMO confirmed" would be too specific...
> >
> > Ah, OK. (I am not too familiar with the details of this plugin, sorry.)
> > Real -> Current data
> > Generic -> Average data
>
> I'm ok with "Generic -> Average data", but I'm not sure if "Current data" is a
> good one... When using the MS plugin, people might be interested to see some
> historical showers (very high ZHR), so, using "current" would sounds
> strange... =/

Oh, I was not aware that you simulate historical showers, I had thought the update would only provide e.g. pending shower forecast (IMO) for observers. Now I have seen "generic" and details for particular years in the JSON file.

Detailed/Accurate/Particular?

Revision history for this message
Marcos Cardinot (cardinot) wrote :

> > > > > >
> > > > > > Maybe we should rename to...
> > > > > > Real -> Confirmed
> > > > > > Generic -> Unconfirmed
> > > > > >
> > > > > > ideas?
> > > > >
> > > > > Real->IMO confirmed
> > > > > Generic -> average data
> > > >
> > > > Humm... the problem is that sometimes we (or even the user) could add a
> > new
> > > > shower, in which the data was confirmed by some other catalog - in this
> > way,
> > > > "IMO confirmed" would be too specific...
> > >
> > > Ah, OK. (I am not too familiar with the details of this plugin, sorry.)
> > > Real -> Current data
> > > Generic -> Average data
> >
> > I'm ok with "Generic -> Average data", but I'm not sure if "Current data" is
> a
> > good one... When using the MS plugin, people might be interested to see some
> > historical showers (very high ZHR), so, using "current" would sounds
> > strange... =/
>
> Oh, I was not aware that you simulate historical showers, I had thought the
> update would only provide e.g. pending shower forecast (IMO) for observers.
> Now I have seen "generic" and details for particular years in the JSON file.

Yeah
In general, a meteor shower occur at the same period of time (annually). However, the ZHR is not always the same - also, some showers are harder to predict, in this way, the IMO ends up to confirm the details of some showers which they were able to predicted...

So, in our JSON catalog, for each meteor shower we have an array 'activity', which must have at least one "generic" data, followed by the years in which the shower will really occur (or occurred).

eg.
   "activity":
   [
   {
    "year": "generic",
    "zhr": 3,
    "start": "09.25",
    "finish": "12.06",
    "peak": "11.09"
   },
   {
    "year": "1904",
    "zhr": 20
   },
   {
    "year": "1899",
    "zhr": 100
   }

There we see that the most recent record for this shower was in '1904' - but that in general, some meteor could always come from this radiant between Oct25 and Dec06 with a very low ZHR (3).
So, "generic data" is not exactly an average from all "confirmed data" that we have on our JSON catalog...

> Detailed/Accurate/Particular?

confirmed data?

Alex, do you have any thought?

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

2015-08-06 22:34 GMT+06:00 Marcos CARDINOT <email address hidden>:

> > Detailed/Accurate/Particular?
>
> confirmed data?
>
> Alex, do you have any thought?
>

Historical data because all this ZHR has been in past

--
With best regards, Alexander

Revision history for this message
Marcos Cardinot (cardinot) wrote :

> 2015-08-06 22:34 GMT+06:00 Marcos CARDINOT <email address hidden>:
>
> > > Detailed/Accurate/Particular?
> >
> > confirmed data?
> >
> > Alex, do you have any thought?
> >
>
> Historical data because all this ZHR has been in past

We need something more general, since some showers would also have forecasts (eg. 2016, 2017)

>
> --
> With best regards, Alexander

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

But what if IMO gives a short-time prediction?

I think "Generic" vs. "Concrete" or "Confirmed" data might describes this best.

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

2015-08-06 23:20 GMT+06:00 gzotti <email address hidden>:

> But what if IMO gives a short-time prediction?
>

Not only IMO gives data for meteor showers.

>
> I think "Generic" vs. "Concrete" or "Confirmed" data might describes this
> best.
>

Historical/Predicted?

--
With best regards, Alexander

Revision history for this message
Marcos Cardinot (cardinot) wrote :

> 2015-08-06 23:20 GMT+06:00 gzotti <email address hidden>:
>
> > But what if IMO gives a short-time prediction?
> >
>
> Not only IMO gives data for meteor showers.

Yeah, but I guess that predictions are done/published only 1 or rarely 2 years before the event...

>
> >
> > I think "Generic" vs. "Concrete" or "Confirmed" data might describes this
> > best.
> >
>
> Historical/Predicted?

I don't know if "historical" is a good one, mainly because to see it the user will have to change the sky date - as in Stellarium we simulate the Sky based on the current time sets by the user, a historical shower would always be "actual" or "predicted" at some point...

Currently we use "Real data" and "Generic data" to differentiate the showers which were confirmed and the non-confirmed ones (generic).

Georg, so your vote goes to:
"Real data" -> "Confirmed data"
"Generic data" -> "Generic data"
OR
"Real data" -> "Concrete data"
"Generic data" -> "Generic data"

?

> --
> With best regards, Alexander

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

On Do, 6.08.2015, 19:27, Alexander Wolf wrote:
> 2015-08-06 23:20 GMT+06:00 gzotti <email address hidden>:
>
>> But what if IMO gives a short-time prediction?
>>
>
> Not only IMO gives data for meteor showers.
>

Yes, we had that before. Just that "Historical" alone is not the solution
if there is accurately predicted data, be that by IMO or by other source.

>> I think "Generic" vs. "Concrete" or "Confirmed" data might describes
>> this
>> best.
>>
>
> Historical/Predicted?

Is string length available? Then OK, and close the case?

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

My favorite would be
"Real data" -> "Concrete data"
"Generic data" -> "Generic data"

It says we have some gemeral idea when a shower should be, or better data for the year in question, be that predicted or as post-event information (like Leonids 1966 etc). But I am happy with other solutions as well, as long as it is clear from short documentation (About..., or tooltip) what it means.

lp:~cardinot/stellarium/MeteorShower updated
7813. By Marcos Cardinot

cosmetic fix - renames from 'real data' to 'confirmed data'

7814. By Marcos Cardinot

cosmetic fix - updates the about tab

7815. By Marcos Cardinot

merge with trunk

7816. By Marcos Cardinot

cosmetic fix - removing the html tags from the translatable strings

7817. By Marcos Cardinot

oops... don't use '+' with N_()

7818. By Marcos Cardinot

update pot files

Revision history for this message
Marcos Cardinot (cardinot) wrote :

so, any new comment? Can I merge it?

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

Marcos, I think management of buttons should be splitted - one checkbox for main button and one checkbox for search button.

lp:~cardinot/stellarium/MeteorShower updated
7819. By Marcos Cardinot

splits the visibility management of the buttons

7820. By Marcos Cardinot

fix signal&slot connection

Revision history for this message
Marcos Cardinot (cardinot) wrote :

> Marcos, I think management of buttons should be splitted - one checkbox for
> main button and one checkbox for search button.

Yeah, good catch - thanks ;)

done! =D

Revision history for this message
Alexander Wolf (alexwolf) :
review: Approve
Revision history for this message
gzotti (georg-zotti) wrote :

I think it's fine!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'plugins/MeteorShowers/CMakeLists.txt'
2--- plugins/MeteorShowers/CMakeLists.txt 2015-04-11 13:31:54 +0000
3+++ plugins/MeteorShowers/CMakeLists.txt 2015-08-07 05:13:12 +0000
4@@ -1,6 +1,6 @@
5-SET(METEORSHOWERS_MAJOR "1")
6+SET(METEORSHOWERS_MAJOR "2")
7 SET(METEORSHOWERS_MINOR "0")
8-SET(METEORSHOWERS_PATCH "1")
9+SET(METEORSHOWERS_PATCH "0")
10 SET(METEORSHOWERS_VERSION "${METEORSHOWERS_MAJOR}.${METEORSHOWERS_MINOR}.${METEORSHOWERS_PATCH}")
11
12 IF(APPLE)
13
14=== modified file 'plugins/MeteorShowers/resources/MeteorShower.qrc'
15--- plugins/MeteorShowers/resources/MeteorShower.qrc 2015-04-22 02:34:10 +0000
16+++ plugins/MeteorShowers/resources/MeteorShower.qrc 2015-08-07 05:13:12 +0000
17@@ -4,5 +4,7 @@
18 <file>radiant.png</file>
19 <file>btMS-off.png</file>
20 <file>btMS-on.png</file>
21+ <file>btMS-search-on.png</file>
22+ <file>btMS-search-off.png</file>
23 </qresource>
24 </RCC>
25
26=== added file 'plugins/MeteorShowers/resources/btMS-search-off.png'
27Binary files plugins/MeteorShowers/resources/btMS-search-off.png 1970-01-01 00:00:00 +0000 and plugins/MeteorShowers/resources/btMS-search-off.png 2015-08-07 05:13:12 +0000 differ
28=== added file 'plugins/MeteorShowers/resources/btMS-search-on.png'
29Binary files plugins/MeteorShowers/resources/btMS-search-on.png 1970-01-01 00:00:00 +0000 and plugins/MeteorShowers/resources/btMS-search-on.png 2015-08-07 05:13:12 +0000 differ
30=== modified file 'plugins/MeteorShowers/src/CMakeLists.txt'
31--- plugins/MeteorShowers/src/CMakeLists.txt 2014-03-10 13:17:28 +0000
32+++ plugins/MeteorShowers/src/CMakeLists.txt 2015-08-07 05:13:12 +0000
33@@ -12,14 +12,20 @@
34 MeteorShower.cpp
35 MeteorShowers.hpp
36 MeteorShowers.cpp
37- MeteorStream.hpp
38- MeteorStream.cpp
39- gui/MeteorShowerDialog.hpp
40- gui/MeteorShowerDialog.cpp
41+ MeteorShowersMgr.hpp
42+ MeteorShowersMgr.cpp
43+ MeteorObj.hpp
44+ MeteorObj.cpp
45+ gui/MSConfigDialog.hpp
46+ gui/MSConfigDialog.cpp
47+ gui/MSSearchDialog.hpp
48+ gui/MSSearchDialog.cpp
49+ translations.h
50 )
51
52 SET(MeteorShowersDialog_UIS
53- gui/meteorShowerDialog.ui
54+ gui/MSConfigDialog.ui
55+ gui/MSSearchDialog.ui
56 )
57
58 QT5_WRAP_UI(MeteorShowersDialog_UIS_H ${MeteorShowersDialog_UIS})
59
60=== added file 'plugins/MeteorShowers/src/MeteorObj.cpp'
61--- plugins/MeteorShowers/src/MeteorObj.cpp 1970-01-01 00:00:00 +0000
62+++ plugins/MeteorShowers/src/MeteorObj.cpp 2015-08-07 05:13:12 +0000
63@@ -0,0 +1,86 @@
64+/*
65+ * Stellarium: Meteor Showers Plug-in
66+ * Copyright (C) 2013-2015 Marcos Cardinot
67+ *
68+ * This program is free software; you can redistribute it and/or
69+ * modify it under the terms of the GNU General Public License
70+ * as published by the Free Software Foundation; either version 2
71+ * of the License, or (at your option) any later version.
72+ *
73+ * This program is distributed in the hope that it will be useful,
74+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
75+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
76+ * GNU General Public License for more details.
77+ *
78+ * You should have received a copy of the GNU General Public License
79+ * along with this program; if not, write to the Free Software
80+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
81+ */
82+
83+
84+#include "MeteorObj.hpp"
85+
86+MeteorObj::MeteorObj(const StelCore* core, int speed, const float& radiantAlpha, const float& radiantDelta,
87+ const float& pidx, QList<Meteor::colorPair> colors, const StelTextureSP& bolideTexture)
88+ : Meteor(core, bolideTexture)
89+{
90+ // if speed is zero, use a random value
91+ if (!speed)
92+ {
93+ speed = 11 + (double)qrand() / ((double)RAND_MAX + 1) * 61; // abs range 11-72 km/s
94+ }
95+
96+ // determine the meteor color
97+ if (colors.isEmpty()) {
98+ colors.push_back(Meteor::colorPair("white", 100));
99+ } else {
100+ // handle cases when the total intensity is less than 100
101+ int totalIntensity = 0;
102+ int indexWhite = -1;
103+ for (int i=0; i < colors.size(); ++i) {
104+ totalIntensity += colors.at(i).second;
105+ if (colors.at(i).first == "white") {
106+ indexWhite = i;
107+ }
108+ }
109+
110+ int increaseWhite = 0;
111+ if (totalIntensity > 100) {
112+ qWarning() << "MeteorShowers plugin (showers.json): Total intensity must be less than 100";
113+ colors.clear();
114+ colors.push_back(Meteor::colorPair("white", 100));
115+ } else {
116+ increaseWhite = 100 - totalIntensity;
117+ }
118+
119+ if (increaseWhite > 0) {
120+ if (indexWhite == -1) {
121+ colors.push_back(Meteor::colorPair("white", increaseWhite));
122+ } else {
123+ colors[indexWhite].second = increaseWhite;
124+ }
125+ }
126+ }
127+
128+ // building meteor model
129+ init(radiantAlpha, radiantDelta, speed, colors);
130+
131+ if (!isAlive())
132+ {
133+ return;
134+ }
135+
136+ // implements the population index
137+ float oneMag = -0.2; // negative, working in different scale ( 0 to 1 - where 1 is brighter)
138+ if (pidx) // is not zero
139+ {
140+ if (qrand()%100 < 100.f/pidx) // probability
141+ {
142+ setAbsMag(absMag() + oneMag); // (m+1)
143+ }
144+ }
145+}
146+
147+MeteorObj::~MeteorObj()
148+{
149+}
150
151=== added file 'plugins/MeteorShowers/src/MeteorObj.hpp'
152--- plugins/MeteorShowers/src/MeteorObj.hpp 1970-01-01 00:00:00 +0000
153+++ plugins/MeteorShowers/src/MeteorObj.hpp 2015-08-07 05:13:12 +0000
154@@ -0,0 +1,46 @@
155+/*
156+ * Stellarium: Meteor Showers Plug-in
157+ * Copyright (C) 2013-2015 Marcos Cardinot
158+ *
159+ * This program is free software; you can redistribute it and/or
160+ * modify it under the terms of the GNU General Public License
161+ * as published by the Free Software Foundation; either version 2
162+ * of the License, or (at your option) any later version.
163+ *
164+ * This program is distributed in the hope that it will be useful,
165+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
166+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
167+ * GNU General Public License for more details.
168+ *
169+ * You should have received a copy of the GNU General Public License
170+ * along with this program; if not, write to the Free Software
171+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
172+ */
173+
174+#ifndef _METEOROBJ_HPP_
175+#define _METEOROBJ_HPP_
176+
177+#include "Meteor.hpp"
178+#include "StelCore.hpp"
179+
180+//! @class MeteorObj
181+//! Models a single meteor.
182+//! @author Marcos Cardinot <mcardinot@gmail.com>
183+//! @ingroup meteorShowers
184+class MeteorObj : public Meteor
185+{
186+public:
187+ //! Create a Meteor object.
188+ //! @param core StelCore instance.
189+ //! @param speed Meteor speed in km/s.
190+ //! @param radiantAlpha The radiant alpha in rad.
191+ //! @param radiantDelta The radiant delta in rad.
192+ //! @param pidx Population index.
193+ //! @param colors Meteor color.
194+ //! @param bolideTexture Bolide texture.
195+ MeteorObj(const StelCore*, int speed, const float& radiantAlpha, const float& radiantDelta,
196+ const float& pidx, QList<Meteor::colorPair> colors, const StelTextureSP& bolideTexture);
197+ virtual ~MeteorObj();
198+};
199+
200+#endif // _METEOROBJ_HPP_
201
202=== modified file 'plugins/MeteorShowers/src/MeteorShower.cpp'
203--- plugins/MeteorShowers/src/MeteorShower.cpp 2015-08-03 13:17:06 +0000
204+++ plugins/MeteorShowers/src/MeteorShower.cpp 2015-08-07 05:13:12 +0000
205@@ -1,7 +1,6 @@
206 /*
207 * Stellarium: Meteor Showers Plug-in
208- * Copyright (C) 2013 Marcos Cardinot
209- * Copyright (C) 2011 Alexander Wolf
210+ * Copyright (C) 2013-2015 Marcos Cardinot
211 *
212 * This program is free software; you can redistribute it and/or
213 * modify it under the terms of the GNU General Public License
214@@ -18,60 +17,145 @@
215 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
216 */
217
218+#include <QtMath>
219+
220+#include "LandscapeMgr.hpp"
221 #include "MeteorShower.hpp"
222 #include "MeteorShowers.hpp"
223+#include "SporadicMeteorMgr.hpp"
224 #include "StelApp.hpp"
225 #include "StelCore.hpp"
226 #include "StelModuleMgr.hpp"
227+#include "StelObjectMgr.hpp"
228 #include "StelTexture.hpp"
229 #include "StelUtils.hpp"
230
231-StelTextureSP MeteorShower::radiantTexture;
232-bool MeteorShower::showLabels = true;
233-bool MeteorShower::radiantMarkerEnabled = true;
234-bool MeteorShower::showActiveRadiantsOnly = true;
235-
236-MeteorShower::MeteorShower(const QVariantMap& map)
237- : initialized(false)
238- , active(false)
239- , speed(0)
240- , rAlphaPeak(0)
241- , rDeltaPeak(0)
242- , driftAlpha(0)
243- , driftDelta(0)
244- , pidx(0)
245- , radiantAlpha(0)
246- , radiantDelta(0)
247- , zhr(0)
248- , status(0)
249+MeteorShower::MeteorShower(MeteorShowersMgr* mgr, const QVariantMap& map)
250+ : m_mgr(mgr)
251+ , m_status(INVALID)
252+ , m_speed(0)
253+ , m_rAlphaPeak(0)
254+ , m_rDeltaPeak(0)
255+ , m_driftAlpha(0)
256+ , m_driftDelta(0)
257+ , m_pidx(0)
258+ , m_radiantAlpha(0)
259+ , m_radiantDelta(0)
260 {
261 // return initialized if the mandatory fields are not present
262- if(!map.contains("showerID"))
263+ if(!map.contains("showerID") || !map.contains("activity")
264+ || !map.contains("radiantAlpha") || !map.contains("radiantDelta"))
265+ {
266+ qWarning() << "MeteorShower: INVALID meteor shower!" << map.value("showerID").toString();
267+ qWarning() << "MeteorShower: Please, check your 'showers.json' catalog!";
268 return;
269-
270- showerID = map.value("showerID").toString();
271- designation = map.value("designation").toString();
272- speed = map.value("speed").toInt();
273- rAlphaPeak = radiantAlpha = StelUtils::getDecAngle(map.value("radiantAlpha").toString());
274- rDeltaPeak = radiantDelta = StelUtils::getDecAngle(map.value("radiantDelta").toString());
275- driftAlpha = StelUtils::getDecAngle(map.value("driftAlpha").toString());
276- driftDelta = StelUtils::getDecAngle(map.value("driftDelta").toString());
277- parentObj = map.value("parentObj").toString();
278- pidx = map.value("pidx").toFloat();
279-
280- if(map.contains("activity"))
281- {
282- foreach(const QVariant &ms, map.value("activity").toList())
283- {
284- QVariantMap activityMap = ms.toMap();
285- activityData d;
286- d.year = activityMap.value("year").toString();
287- d.zhr = activityMap.value("zhr").toInt();
288- d.variable = activityMap.value("variable").toString();
289- d.peak = activityMap.value("peak").toString();
290- d.start = activityMap.value("start").toString();
291- d.finish = activityMap.value("finish").toString();
292- activity.append(d);
293+ }
294+
295+ m_showerID = map.value("showerID").toString();
296+ m_designation = map.value("designation").toString();
297+ m_speed = map.value("speed").toInt();
298+ m_radiantAlpha = StelUtils::getDecAngle(map.value("radiantAlpha").toString());
299+ m_radiantDelta = StelUtils::getDecAngle(map.value("radiantDelta").toString());
300+ m_parentObj = map.value("parentObj").toString();
301+ m_pidx = map.value("pidx").toFloat();
302+
303+ // the catalog (IMO) will give us the drift for a five-day interval from peak
304+ m_driftAlpha = StelUtils::getDecAngle(map.value("driftAlpha").toString()) / 5.f;
305+ m_driftDelta = StelUtils::getDecAngle(map.value("driftDelta").toString()) / 5.f;
306+
307+ m_rAlphaPeak = m_radiantAlpha;
308+ m_rDeltaPeak = m_radiantDelta;
309+
310+ int genericYear = 1000;
311+
312+ // build the activity list
313+ QList<QVariant> activities = map.value("activity").toList();
314+ foreach(const QVariant &ms, activities)
315+ {
316+ QVariantMap activityMap = ms.toMap();
317+ Activity d;
318+ d.zhr = activityMap.value("zhr").toInt();
319+
320+ //
321+ // 'variable'field
322+ //
323+ QStringList variable = activityMap.value("variable").toString().split("-");
324+ if (d.zhr == -1) // is variable
325+ {
326+ bool ok = variable.size() == 2;
327+ for (int i=0; i < 2 && ok; i++)
328+ {
329+ d.variable.append(variable.at(i).toInt(&ok));
330+ }
331+
332+ if (!ok)
333+ {
334+ qWarning() << "MeteorShower: INVALID data for " << m_showerID;
335+ qWarning() << "MeteorShower: Please, check your 'showers.json' catalog!";
336+ return;
337+ }
338+ }
339+
340+ //
341+ // 'start', 'finish' and 'peak' fields
342+ //
343+ d.year = activityMap.value("year").toInt();
344+ QString year = QString::number(d.year == 0 ? genericYear : d.year);
345+
346+ QString start = activityMap.value("start").toString();
347+ start = start.isEmpty() ? "" : start + " " + year;
348+ d.start = QDate::fromString(start, "MM.dd yyyy");
349+
350+ QString finish = activityMap.value("finish").toString();
351+ finish = finish.isEmpty() ? "" : finish + " " + year;
352+ d.finish = QDate::fromString(finish, "MM.dd yyyy");
353+
354+ QString peak = activityMap.value("peak").toString();
355+ peak = peak.isEmpty() ? "" : peak + " " + year;
356+ d.peak = QDate::fromString(peak, "MM.dd yyyy");
357+
358+ if (d.start.isValid() && d.finish.isValid() && d.peak.isValid())
359+ {
360+ // Fix the 'finish' year! Handling cases when the shower starts on
361+ // the current year and ends on the next year!
362+ if(d.start.operator >(d.finish))
363+ {
364+ d.finish = d.finish.addYears(1);
365+ }
366+ // Fix the 'peak' year
367+ if(d.start.operator >(d.peak))
368+ {
369+ d.peak = d.peak.addYears(1);
370+ }
371+ }
372+
373+ m_activities.append(d);
374+ }
375+
376+ // filling null values of the activity list with generic data
377+ const Activity& g = m_activities.at(0);
378+ const int activitiesSize = m_activities.size();
379+ for (int i = 1; i < activitiesSize; ++i)
380+ {
381+ Activity a = m_activities.at(i);
382+ if (a.zhr == 0)
383+ {
384+ a.zhr = g.zhr;
385+ a.variable = g.variable;
386+ }
387+
388+ int aux = a.year - genericYear;
389+ a.start = a.start.isValid() ? a.start : g.start.addYears(aux);
390+ a.finish = a.finish.isValid() ? a.finish : g.finish.addYears(aux);
391+ a.peak = a.peak.isValid() ? a.peak : g.peak.addYears(aux);
392+ m_activities.replace(i, a);
393+
394+ if (!a.start.isValid() || !a.finish.isValid() || !a.peak.isValid())
395+ {
396+ qWarning() << "MeteorShower: INVALID data for "
397+ << m_showerID << "Unable to read some dates!";
398+ qWarning() << "MeteorShower: Please, check your 'showers.json' catalog!";
399+ return;
400 }
401 }
402
403@@ -82,258 +166,345 @@
404 QVariantMap colorMap = ms.toMap();
405 QString color = colorMap.value("color").toString();
406 int intensity = colorMap.value("intensity").toInt();
407- colors.append(colorPair(color, intensity));
408+ m_colors.append(Meteor::colorPair(color, intensity));
409 }
410 }
411
412- updateCurrentData(getSkyQDateTime());
413- // ensures that all objects will be drawn once
414- // that's to avoid crashes by trying select a nonexistent object
415- StelPainter painter(StelApp::getInstance().getCore()->getProjection(StelCore::FrameJ2000));
416- draw(painter);
417+ m_status = UNDEFINED;
418
419 qsrand(QDateTime::currentMSecsSinceEpoch());
420-
421- initialized = true;
422 }
423
424 MeteorShower::~MeteorShower()
425 {
426- //
427-}
428-
429-QVariantMap MeteorShower::getMap(void)
430-{
431- QVariantMap map;
432- map["showerID"] = showerID;
433- map["designation"] = designation;
434- map["speed"] = speed;
435- map["radiantAlpha"] = rAlphaPeak;
436- map["radiantDelta"] = rDeltaPeak;
437- map["driftAlpha"] = driftAlpha;
438- map["driftDelta"] = driftDelta;
439- map["parentObj"] = parentObj;
440- map["pidx"] = pidx;
441-
442- QVariantList activityList;
443- foreach(const activityData &p, activity)
444- {
445- QVariantMap activityMap;
446- activityMap["year"] = p.year;
447- activityMap["zhr"] = p.zhr;
448- activityMap["variable"] = p.variable;
449- activityMap["start"] = p.start;
450- activityMap["finish"] = p.finish;
451- activityMap["peak"] = p.peak;
452- activityList << activityMap;
453- }
454- map["activity"] = activityList;
455-
456- QVariantList colorList;
457- foreach(const colorPair &c, colors)
458- {
459- QVariantMap colorMap;
460- colorMap["color"] = c.first;
461- colorMap["intensity"] = c.second;
462- colorList << colorMap;
463- }
464- map["colors"] = colorList;
465-
466- return map;
467-}
468-
469-float MeteorShower::getSelectPriority(const StelCore*) const
470-{
471- return -4.0;
472-}
473-
474-QString MeteorShower::getDesignation() const
475-{
476- if (showerID.toInt()) // if showerID is a number
477- {
478- return "";
479- }
480- return showerID;
481-}
482-
483-QString MeteorShower::getDateFromJSON(QString jsondate) const
484-{
485- QStringList parsedDate = jsondate.split(".");
486-
487- return QString("%1 %2").arg(parsedDate.at(1).toInt()).arg(getMonthName(parsedDate.at(0).toInt()));
488-}
489-
490-QString MeteorShower::getDayFromJSON(QString jsondate) const
491-{
492- QStringList parsedDate = jsondate.split(".");
493-
494- return QString("%1").arg(parsedDate.at(1).toInt());
495-}
496-
497-int MeteorShower::getMonthFromJSON(QString jsondate) const
498-{
499- QStringList parsedDate = jsondate.split(".");
500-
501- return parsedDate.at(0).toInt();
502-}
503-
504-QString MeteorShower::getMonthNameFromJSON(QString jsondate) const
505-{
506- QStringList parsedDate = jsondate.split(".");
507-
508- return QString("%1").arg(getMonthName(parsedDate.at(0).toInt()));
509-}
510-
511-QString MeteorShower::getMonthName(int number) const
512-{
513- QStringList monthList;
514- monthList.append(N_("January"));
515- monthList.append(N_("February"));
516- monthList.append(N_("March"));
517- monthList.append(N_("April"));
518- monthList.append(N_("May"));
519- monthList.append(N_("June"));
520- monthList.append(N_("July"));
521- monthList.append(N_("August"));
522- monthList.append(N_("September"));
523- monthList.append(N_("October"));
524- monthList.append(N_("November"));
525- monthList.append(N_("December"));
526-
527- return q_(monthList.at(number-1));
528-}
529-
530-QDateTime MeteorShower::getSkyQDateTime() const
531-{
532- StelCore* core = StelApp::getInstance().getCore();
533- //get the current sky date (zone time)
534- double JD = core->getJD();
535- return StelUtils::jdToQDateTime(JD+ StelUtils::getGMTShiftFromQT(JD)/24);
536-}
537-
538-void MeteorShower::updateCurrentData(QDateTime skyDate)
539-{
540- //Check if we have real data for the current sky year
541- int index = searchRealData(skyDate.toString("yyyy"));
542-
543- /**************************
544- *ZHR info
545- **************************/
546- zhr = activity[index].zhr == 0 ? activity[0].zhr : activity[index].zhr;
547-
548- if (zhr == -1)
549- variable = activity[index].variable.isEmpty() ? activity[0].variable : activity[index].variable;
550- else
551- variable = "";
552-
553- /***************************
554- *Dates - start/finish/peak
555- ***************************/
556- QString dateStart = activity[index].start.isEmpty() ? activity[0].start : activity[index].start;
557- QString dateFinish = activity[index].finish.isEmpty() ? activity[0].finish : activity[index].finish;
558- QString datePeak = activity[index].peak.isEmpty() ? activity[0].peak : activity[index].peak;
559- QString yearBase = activity[index].year == "generic" ? skyDate.toString("yyyy") : activity[index].year;
560- QString yearS, yearF;
561-
562- int monthStart = getMonthFromJSON(dateStart);
563- int monthFinish = getMonthFromJSON(dateFinish);
564-
565- if(monthStart > monthFinish)
566- {
567- if(monthStart == skyDate.toString("MM").toInt())
568- {
569- yearS = yearBase;
570- yearF = QString("%1").arg(yearBase.toInt() + 1);
571- }
572- else
573- {
574- yearS = QString("%1").arg(yearBase.toInt() - 1);
575- yearF = yearBase;
576- }
577- }
578- else
579- {
580- yearS = yearF = yearBase;
581- }
582-
583- start = QDateTime::fromString(dateStart + " " + yearS, "MM.dd yyyy");
584- finish = QDateTime::fromString(dateFinish + " " + yearF, "MM.dd yyyy");
585- peak = QDateTime::fromString(datePeak + " " + yearS, "MM.dd yyyy");
586-
587- if (peak.operator <(start) || peak.operator >(finish))
588- peak = QDateTime::fromString(datePeak + " " + yearF, "MM.dd yyyy");
589-
590- /***************************
591- *Activity - is active?
592- ***************************/
593- if(skyDate.operator >=(start) && skyDate.operator <=(finish))
594- {
595- if(index)
596- status = ACTIVE_REAL; // real data
597- else
598- status = ACTIVE_GENERIC; // generic data
599- }
600- else
601- {
602- status = INACTIVE; // isn't active
603- }
604- active = (status != INACTIVE) || !showActiveRadiantsOnly;
605-
606- /**************************
607- *Radiant drift
608- *************************/
609- radiantAlpha = rAlphaPeak;
610- radiantDelta = rDeltaPeak;
611-
612- if (status != INACTIVE)
613- {
614- double time = (StelUtils::qDateTimeToJd(skyDate) - StelUtils::qDateTimeToJd(peak))*24;
615- radiantAlpha += (driftAlpha/120)*time;
616- radiantDelta += (driftDelta/120)*time;
617- }
618-}
619-
620-int MeteorShower::searchRealData(QString yyyy) const
621-{
622- int index = -1;
623- foreach(const activityData &p, activity)
624- {
625- index++;
626- if(p.year == yyyy)
627- return index;
628- }
629-
630- return 0;
631-}
632-
633-float MeteorShower::getSolarLongitude(QDateTime QDT) const
634+ qDeleteAll(m_activeMeteors);
635+ m_activeMeteors.clear();
636+}
637+
638+bool MeteorShower::enabled() const
639+{
640+ if (m_status == INVALID)
641+ {
642+ return false;
643+ }
644+ else if (m_status == UNDEFINED)
645+ {
646+ return true;
647+ }
648+ else if (m_mgr->getActiveRadiantOnly())
649+ {
650+ return m_status == ACTIVE_GENERIC || m_status == ACTIVE_CONFIRMED;
651+ }
652+ else
653+ {
654+ return true;
655+ }
656+}
657+
658+void MeteorShower::update(StelCore* core, double deltaTime)
659+{
660+ if (m_status == INVALID)
661+ {
662+ return;
663+ }
664+
665+ // gets the current UTC date
666+ double currentJD = core->getJD();
667+ QDate currentDate = QDate::fromJulianDay(currentJD);
668+
669+ // updating status and activity
670+ bool found = false;
671+ m_status = INACTIVE;
672+ m_activity = hasConfirmedShower(currentDate, found);
673+ if (found)
674+ {
675+ m_status = ACTIVE_CONFIRMED;
676+ }
677+ else
678+ {
679+ m_activity = hasGenericShower(currentDate, found);
680+ if (found)
681+ {
682+ m_status = ACTIVE_GENERIC;
683+ }
684+ }
685+
686+ // will be displayed?
687+ if (!enabled())
688+ {
689+ return;
690+ }
691+
692+ // fix the radiant position (considering drift)
693+ m_radiantAlpha = m_rAlphaPeak;
694+ m_radiantDelta = m_rDeltaPeak;
695+ if (m_status != INACTIVE)
696+ {
697+ double daysToPeak = currentJD - m_activity.peak.toJulianDay();
698+ m_radiantAlpha += m_driftAlpha * daysToPeak;
699+ m_radiantDelta += m_driftDelta * daysToPeak;
700+ }
701+
702+ // step through and update all active meteors
703+ foreach (MeteorObj* m, m_activeMeteors)
704+ {
705+ if (!m->update(deltaTime))
706+ {
707+ m_activeMeteors.removeOne(m);
708+ }
709+ }
710+
711+ // going forward or backward ?
712+ // don't create new meteors
713+ if(!core->getRealTimeSpeed())
714+ {
715+ return;
716+ }
717+
718+ // calculates a ZHR for the current date
719+ int currentZHR = calculateZHR(currentJD);
720+ if (currentZHR < 1)
721+ {
722+ return;
723+ }
724+
725+ // average meteors per frame
726+ float mpf = currentZHR * deltaTime / 3600.f;
727+
728+ // maximum amount of meteors for the current frame
729+ int maxMpf = qRound(mpf);
730+ maxMpf = maxMpf < 1 ? 1 : maxMpf;
731+
732+ float rate = mpf / (float) maxMpf;
733+ for (int i = 0; i < maxMpf; ++i)
734+ {
735+ float prob = (float) qrand() / (float) RAND_MAX;
736+ if (prob < rate)
737+ {
738+ MeteorObj *m = new MeteorObj(core, m_speed, m_radiantAlpha, m_radiantDelta,
739+ m_pidx, m_colors, m_mgr->getBolideTexture());
740+ m_activeMeteors.append(m);
741+ }
742+ }
743+}
744+
745+void MeteorShower::draw(StelCore* core)
746+{
747+ if (!enabled())
748+ {
749+ return;
750+ }
751+ drawRadiant(core);
752+ drawMeteors(core);
753+}
754+
755+void MeteorShower::drawRadiant(StelCore *core)
756+{
757+ StelPainter painter(core->getProjection(StelCore::FrameJ2000));
758+
759+ Vec3d XY;
760+ StelUtils::spheToRect(m_radiantAlpha, m_radiantDelta, m_position);
761+ painter.getProjector()->project(m_position, XY);
762+
763+ glEnable(GL_TEXTURE_2D);
764+ glEnable(GL_BLEND);
765+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
766+
767+ Vec3f rgb;
768+ float alpha = 0.85f + ((float) qrand() / (float) RAND_MAX) / 10.f;
769+ switch(m_status)
770+ {
771+ case ACTIVE_CONFIRMED: //Active, confirmed data
772+ rgb = m_mgr->getColorARC();
773+ break;
774+ case ACTIVE_GENERIC: //Active, generic data
775+ rgb = m_mgr->getColorARG();
776+ break;
777+ default: //Inactive
778+ rgb = m_mgr->getColorIR();
779+ }
780+ rgb /= 255.f;
781+ painter.setColor(rgb[0], rgb[1], rgb[2], alpha);
782+
783+ Vec3d win;
784+ if (m_mgr->getEnableMarker() && painter.getProjector()->projectCheck(m_position, win))
785+ {
786+ m_mgr->getRadiantTexture()->bind();
787+ painter.drawSprite2dMode(XY[0], XY[1], 45);
788+
789+ if (m_mgr->getEnableLabels())
790+ {
791+ painter.setFont(m_mgr->getFont());
792+ float size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter();
793+ float shift = 8.f + size/1.8f;
794+ painter.drawText(XY[0]+shift, XY[1]+shift, getNameI18n(), 0, 0, 0, false);
795+ }
796+ }
797+}
798+
799+void MeteorShower::drawMeteors(StelCore *core)
800+{
801+ if (!core->getSkyDrawer()->getFlagHasAtmosphere())
802+ {
803+ return;
804+ }
805+
806+ LandscapeMgr* landmgr = GETSTELMODULE(LandscapeMgr);
807+ if (landmgr->getFlagAtmosphere() && landmgr->getLuminance() > 5.f)
808+ {
809+ return;
810+ }
811+
812+ // step through and draw all active meteors
813+ StelPainter painter(core->getProjection(StelCore::FrameAltAz));
814+ foreach (MeteorObj* m, m_activeMeteors)
815+ {
816+ m->draw(core, painter);
817+ }
818+}
819+
820+MeteorShower::Activity MeteorShower::hasGenericShower(QDate date, bool &found) const
821+{
822+ int year = date.year();
823+ Activity g = m_activities.at(0);
824+ bool peakOnStart = g.peak.year() == g.start.year(); // 'peak' and 'start' on the same year ?
825+
826+ //Fix the 'generic years'!
827+ // Handling cases when the shower starts on the current year and
828+ // ends on the next year; or when it started on the last year...
829+ if (g.start.year() != g.finish.year()) // edge case?
830+ {
831+ // trying the current year with the next year
832+ g.start.setDate(year, g.start.month(), g.start.day());
833+ g.finish.setDate(year + 1, g.finish.month(), g.finish.day());
834+ found = date.operator >=(g.start) && date.operator <=(g.finish);
835+
836+ if (!found)
837+ {
838+ // trying the last year with the current year
839+ g.start.setDate(year - 1, g.start.month(), g.start.day());
840+ g.finish.setDate(year, g.finish.month(), g.finish.day());
841+ found = date.operator >=(g.start) && date.operator <=(g.finish);
842+ }
843+ }
844+ else
845+ {
846+ g.start.setDate(year, g.start.month(), g.start.day());
847+ g.finish.setDate(year, g.finish.month(), g.finish.day());
848+ found = date.operator >=(g.start) && date.operator <=(g.finish);
849+ }
850+
851+ if (found)
852+ {
853+ g.year = g.start.year();
854+ g.peak.setDate(peakOnStart ? g.start.year() : g.finish.year(),
855+ g.peak.month(),
856+ g.peak.day());
857+ return g;
858+ }
859+ return Activity();
860+}
861+
862+MeteorShower::Activity MeteorShower::hasConfirmedShower(QDate date, bool& found) const
863+{
864+ const int activitiesSize = m_activities.size();
865+ for (int i = 1; i < activitiesSize; ++i)
866+ {
867+ const Activity& a = m_activities.at(i);
868+ if (date.operator >=(a.start) && date.operator <=(a.finish))
869+ {
870+ found = true;
871+ return a;
872+ }
873+ }
874+ return Activity();
875+}
876+
877+int MeteorShower::calculateZHR(const double& currentJD)
878+{
879+ double startJD = m_activity.start.toJulianDay();
880+ double finishJD = m_activity.finish.toJulianDay();
881+ double peakJD = m_activity.peak.toJulianDay();
882+
883+ float sd; //standard deviation
884+ if (currentJD >= startJD && currentJD < peakJD) //left side of gaussian
885+ {
886+ sd = (peakJD - startJD) / 2.f;
887+ }
888+ else
889+ {
890+ sd = (finishJD - peakJD) / 2.f;
891+ }
892+
893+ float maxZHR = m_activity.zhr == -1 ? m_activity.variable.at(1) : m_activity.zhr;
894+ float minZHR = m_activity.zhr == -1 ? m_activity.variable.at(0) : 0;
895+
896+ float gaussian = maxZHR * qExp( - qPow(currentJD - peakJD, 2) / (sd * sd) ) + minZHR;
897+
898+ return qRound(gaussian);
899+}
900+
901+QString MeteorShower::getSolarLongitude(QDate date) const
902 {
903 //The number of days (positive or negative) since Greenwich noon,
904 //Terrestrial Time, on 1 January 2000 (J2000.0)
905- double n = StelUtils::qDateTimeToJd(QDT) - 2451545.0;
906+ double n = date.toJulianDay() - 2451545.0;
907
908 //The mean longitude of the Sun, corrected for the aberration of light
909- float slong = (280.460 + 0.9856474*n) / 360;
910- slong = (slong - (int) slong) * 360 - 1;
911-
912- return slong;
913+ float l = 280.460 + 0.9856474 * n;
914+
915+ // put it in the range 0 to 360 degrees
916+ l /= 360.f;
917+ l = (l - (int) l) * 360.f - 1.f;
918+
919+ return QString::number(l, 'f', 2);
920+}
921+
922+QString MeteorShower::getDesignation() const
923+{
924+ if (m_showerID.toInt()) // if showerID is a number
925+ {
926+ return "";
927+ }
928+ return m_showerID;
929+}
930+
931+Vec3f MeteorShower::getInfoColor(void) const
932+{
933+ return StelApp::getInstance().getVisionModeNight() ? Vec3f(0.6, 0.0, 0.0) : Vec3f(1.0, 1.0, 1.0);
934 }
935
936 QString MeteorShower::getInfoString(const StelCore* core, const InfoStringGroup& flags) const
937 {
938+ if (!enabled())
939+ {
940+ GETSTELMODULE(StelObjectMgr)->unSelect();
941+ return "";
942+ }
943+
944 QString str;
945 QTextStream oss(&str);
946
947- QString mstdata = q_("generic data");
948- if(status == ACTIVE_REAL)
949- mstdata = q_("real data");
950+ QString mstdata;
951+ if (m_status == ACTIVE_GENERIC)
952+ {
953+ mstdata = q_("generic data");
954+ }
955+ else if (m_status == ACTIVE_CONFIRMED)
956+ {
957+ mstdata = q_("confirmed data");
958+ }
959+ else if (m_status == INACTIVE)
960+ {
961+ mstdata = q_("inactive");
962+ }
963
964 if(flags&Name)
965 {
966 oss << "<h2>" << getNameI18n();
967- if (!showerID.toInt())
968+ if (!m_showerID.toInt())
969 {
970- oss << " (" << showerID <<")</h2>";
971+ oss << " (" << m_showerID <<")</h2>";
972 }
973 else
974 {
975@@ -353,59 +524,64 @@
976 {
977 oss << QString("%1: %2/%3")
978 .arg(q_("Radiant drift (per day)"))
979- .arg(StelUtils::radToHmsStr(driftAlpha/5))
980- .arg(StelUtils::radToDmsStr(driftDelta/5));
981- oss << "<br />";
982-
983- if (speed>0)
984- {
985- oss << q_("Geocentric meteoric velocity: %1 km/s").arg(speed) << "<br />";
986- }
987-
988- if(pidx>0)
989- {
990- oss << q_("The population index: %1").arg(pidx) << "<br />";
991- }
992-
993- if(!parentObj.isEmpty())
994- {
995- oss << q_("Parent body: %1").arg(q_(parentObj)) << "<br />";
996- }
997-
998- if(start.toString("M") == finish.toString("M"))
999- {
1000- oss << QString("%1: %2 - %3 %4")
1001- .arg(q_("Active"))
1002- .arg(start.toString("d"))
1003- .arg(finish.toString("d"))
1004- .arg(start.toString("MMMM"));
1005- }
1006- else
1007- {
1008- oss << QString("%1: %2 - %3")
1009- .arg(q_("Activity"))
1010- .arg(start.toString("d MMMM"))
1011- .arg(finish.toString("d MMMM"));
1012- }
1013- oss << "<br />";
1014- oss << q_("Maximum: %1").arg(peak.toString("d MMMM"));
1015-
1016- QString slong = QString::number( MeteorShower::getSolarLongitude(peak), 'f', 2 );
1017- oss << QString(" (%1 %2&deg;)").arg(q_("Solar longitude is")).arg(slong);
1018- oss << "<br />";
1019-
1020- if(zhr>0)
1021- {
1022- oss << QString("ZHR<sub>max</sub>: %1").arg(zhr) << "<br />";
1023- }
1024- else
1025- {
1026- oss << QString("ZHR<sub>max</sub>: %1").arg(q_("variable"));
1027- if(!variable.isEmpty())
1028- {
1029- oss << "; " << variable;
1030- }
1031- oss << "<br />";
1032+ .arg(StelUtils::radToHmsStr(m_driftAlpha))
1033+ .arg(StelUtils::radToDmsStr(m_driftDelta));
1034+ oss << "<br />";
1035+
1036+ if (m_speed > 0)
1037+ {
1038+ oss << q_("Geocentric meteoric velocity: %1 km/s").arg(m_speed) << "<br />";
1039+ }
1040+
1041+ if(m_pidx > 0)
1042+ {
1043+ oss << q_("The population index: %1").arg(m_pidx) << "<br />";
1044+ }
1045+
1046+ if(!m_parentObj.isEmpty())
1047+ {
1048+ oss << q_("Parent body: %1").arg(q_(m_parentObj)) << "<br />";
1049+ }
1050+
1051+ // activity info
1052+ if (m_status != INACTIVE)
1053+ {
1054+ if(m_activity.start.month() == m_activity.finish.month())
1055+ {
1056+ oss << QString("%1: %2 - %3 %4")
1057+ .arg(q_("Active"))
1058+ .arg(m_activity.start.day())
1059+ .arg(m_activity.finish.day())
1060+ .arg(m_activity.start.toString("MMMM"));
1061+ }
1062+ else
1063+ {
1064+ oss << QString("%1: %2 - %3")
1065+ .arg(q_("Activity"))
1066+ .arg(m_activity.start.toString("d MMMM"))
1067+ .arg(m_activity.finish.toString("d MMMM"));
1068+ }
1069+ oss << "<br />";
1070+ oss << q_("Maximum: %1").arg(m_activity.peak.toString("d MMMM"));
1071+
1072+ oss << QString(" (%1 %2&deg;)").arg(q_("Solar longitude"))
1073+ .arg(getSolarLongitude(m_activity.peak));
1074+ oss << "<br />";
1075+
1076+ if(m_activity.zhr > 0)
1077+ {
1078+ oss << QString("ZHR<sub>max</sub>: %1").arg(m_activity.zhr) << "<br />";
1079+ }
1080+ else
1081+ {
1082+ oss << QString("ZHR<sub>max</sub>: %1").arg(q_("variable"));
1083+ if(m_activity.variable.size() == 2)
1084+ {
1085+ oss << QString("; %1-%2").arg(m_activity.variable.at(0))
1086+ .arg(m_activity.variable.at(1));
1087+ }
1088+ oss << "<br />";
1089+ }
1090 }
1091 }
1092
1093@@ -413,58 +589,3 @@
1094
1095 return str;
1096 }
1097-
1098-Vec3f MeteorShower::getInfoColor(void) const
1099-{
1100- return StelApp::getInstance().getVisionModeNight() ? Vec3f(0.6, 0.0, 0.0) : Vec3f(1.0, 1.0, 1.0);
1101-}
1102-
1103-double MeteorShower::getAngularSize(const StelCore*) const
1104-{
1105- return 0.001;
1106-}
1107-
1108-void MeteorShower::update(double deltaTime)
1109-{
1110- labelsFader.update((int)(deltaTime*1000));
1111- updateCurrentData(getSkyQDateTime());
1112-}
1113-
1114-void MeteorShower::draw(StelPainter &painter)
1115-{
1116- StelUtils::spheToRect(radiantAlpha, radiantDelta, XYZ);
1117- painter.getProjector()->project(XYZ, XY);
1118-
1119- glEnable(GL_BLEND);
1120- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1121-
1122- qreal r, g, b;
1123- float alpha = 0.85f + ((double) qrand() / (RAND_MAX))/10;
1124- switch(status)
1125- {
1126- case ACTIVE_REAL: //Active, real data
1127- GETSTELMODULE(MeteorShowers)->getColorARR().getRgbF(&r,&g,&b);
1128- break;
1129- case ACTIVE_GENERIC: //Active, generic data
1130- GETSTELMODULE(MeteorShowers)->getColorARG().getRgbF(&r,&g,&b);
1131- break;
1132- default: //Inactive
1133- GETSTELMODULE(MeteorShowers)->getColorIR().getRgbF(&r,&g,&b);
1134- }
1135-
1136- painter.setColor(r, g, b, alpha);
1137-
1138- Vec3d win;
1139- if (MeteorShower::radiantMarkerEnabled && painter.getProjector()->projectCheck(XYZ, win))
1140- {
1141- MeteorShower::radiantTexture->bind();
1142- painter.drawSprite2dMode(XY[0], XY[1], 45);
1143-
1144- if (MeteorShower::showLabels)
1145- {
1146- float size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter();
1147- float shift = 8.f + size/1.8f;
1148- painter.drawText(XY[0]+shift, XY[1]+shift, getNameI18n(), 0, 0, 0, false);
1149- }
1150- }
1151-}
1152
1153=== modified file 'plugins/MeteorShowers/src/MeteorShower.hpp'
1154--- plugins/MeteorShowers/src/MeteorShower.hpp 2015-05-30 19:56:47 +0000
1155+++ plugins/MeteorShowers/src/MeteorShower.hpp 2015-08-07 05:13:12 +0000
1156@@ -1,7 +1,6 @@
1157 /*
1158 * Stellarium: Meteor Showers Plug-in
1159- * Copyright (C) 2013 Marcos Cardinot
1160- * Copyright (C) 2011 Alexander Wolf
1161+ * Copyright (C) 2013-2015 Marcos Cardinot
1162 *
1163 * This program is free software; you can redistribute it and/or
1164 * modify it under the terms of the GNU General Public License
1165@@ -21,8 +20,8 @@
1166 #ifndef _METEORSHOWER_HPP_
1167 #define _METEORSHOWER_HPP_
1168
1169-#include <QDateTime>
1170-
1171+#include "MeteorObj.hpp"
1172+#include "MeteorShowersMgr.hpp"
1173 #include "StelFader.hpp"
1174 #include "StelObject.hpp"
1175 #include "StelPainter.hpp"
1176@@ -37,160 +36,122 @@
1177
1178 class MeteorShower : public StelObject
1179 {
1180- friend class MeteorShowers;
1181-
1182 public:
1183- enum RadiantStatus {
1184- INACTIVE, // inactive radiant.
1185- ACTIVE_REAL, // active radiant - real data.
1186- ACTIVE_GENERIC // active radiant - generic data.
1187+ //! @enum Meteor Shower status.
1188+ enum Status {
1189+ INVALID, // not initialized properly
1190+ UNDEFINED, // it's loaded but with 'activity' undefined
1191+ INACTIVE, // inactive radiant
1192+ ACTIVE_CONFIRMED, // active radiant - confirmed data
1193+ ACTIVE_GENERIC // active radiant - generic data
1194 };
1195
1196- //! @param id The official ID designation for a meteor shower, e.g. "LYR"
1197- MeteorShower(const QVariantMap& map);
1198+ //! @struct Activity
1199+ typedef struct
1200+ {
1201+ int year; //! The catalog year (0 for generic)
1202+ int zhr; //! The ZHR on peak
1203+ QList<int> variable; //! The ZHR range when it's variable
1204+ QDate start; //! Initial date of activity
1205+ QDate finish; //! Last date of activity
1206+ QDate peak; //! Peak activity
1207+ } Activity;
1208+
1209+ //! Constructor
1210+ //! @param map QVariantMap containing all the data about a Meteor Shower.
1211+ MeteorShower(MeteorShowersMgr* mgr, const QVariantMap& map);
1212+
1213+ //! Destructor
1214 ~MeteorShower();
1215
1216- //! Get a QVariantMap which describes the meteor shower. Could be used to
1217- //! create a duplicate.
1218- QVariantMap getMap(void);
1219-
1220- virtual QString getType(void) const
1221- {
1222- return "MeteorShower";
1223- }
1224- virtual float getSelectPriority(const StelCore* core) const;
1225-
1226- //! Get an HTML string to describe the object
1227- //! @param core A pointer to the core
1228- //! @flags a set of flags with information types to include.
1229+ //! Update
1230+ //! @param deltaTime the time increment in seconds since the last call.
1231+ void update(StelCore *core, double deltaTime);
1232+
1233+ //! Draw
1234+ void draw(StelCore *core);
1235+
1236+ //! Checks if we have generic data for a given date
1237+ //! @param date QDate
1238+ //! @return Activity
1239+ Activity hasGenericShower(QDate date, bool &found) const;
1240+
1241+ //! Checks if we have confirmed data for a given date
1242+ //! @param date QDate
1243+ //! @return Activity
1244+ Activity hasConfirmedShower(QDate date, bool &found) const;
1245+
1246+ //! Checks if this meteor shower is being displayed or not
1247+ //! @return true if it's being displayed
1248+ bool enabled() const;
1249+
1250+ //! Gets the meteor shower id
1251+ //! //! @return designation
1252+ QString getDesignation() const;
1253+
1254+ //! Gets the current meteor shower status
1255+ //! @return status
1256+ Status getStatus() { return m_status; }
1257+
1258+ //! Gets the peak
1259+ //! @return peak
1260+ QDate getPeak() { return m_activity.peak; }
1261+
1262+ //! Gets the current ZHR
1263+ //! @return ZHR
1264+ int getZHR() { return m_activity.zhr; }
1265+
1266+ //
1267+ // Methods defined in StelObject class
1268+ //
1269 virtual QString getInfoString(const StelCore* core, const InfoStringGroup& flags) const;
1270+ virtual QString getType(void) const { return "MeteorShower"; }
1271+ virtual QString getEnglishName(void) const { return m_designation.trimmed(); }
1272+ virtual QString getNameI18n(void) const { return q_(m_designation.trimmed()); }
1273+ virtual Vec3d getJ2000EquatorialPos(const StelCore*) const { return m_position; }
1274+ virtual float getSelectPriority(const StelCore* core) const { return -4.0; }
1275 virtual Vec3f getInfoColor(void) const;
1276- virtual Vec3d getJ2000EquatorialPos(const StelCore*) const
1277- {
1278- return XYZ;
1279- }
1280- virtual double getAngularSize(const StelCore* core) const;
1281- virtual QString getNameI18n(void) const
1282- {
1283- return q_(designation.trimmed());
1284- }
1285- virtual QString getEnglishName(void) const
1286- {
1287- return designation.trimmed();
1288- }
1289- QString getDesignation(void) const;
1290- void update(double deltaTime);
1291- static bool showLabels;
1292-
1293- //! Get current activity status of MS
1294- //! @return 0:inactive 1:activeRealData 2:activeGenericData
1295- int getStatus()
1296- {
1297- return status;
1298- }
1299-
1300- //! Get peak
1301- //! @return peak
1302- QDateTime getPeak()
1303- {
1304- return peak;
1305- }
1306-
1307- //! Get zhr
1308- //! @return ZHR
1309- int getZHR()
1310- {
1311- return zhr;
1312- }
1313-
1314- //! <colorName, intensity>
1315- typedef QPair<QString, int> colorPair;
1316+ virtual double getAngularSize(const StelCore* core) const { return 0.001; }
1317
1318 private:
1319- Vec3d XYZ; //! Cartesian equatorial position
1320- Vec3d XY; //! Store temporary 2D position
1321-
1322- static StelTextureSP radiantTexture;
1323- static bool radiantMarkerEnabled;
1324- static bool showActiveRadiantsOnly;
1325-
1326- LinearFader labelsFader;
1327-
1328- typedef struct
1329- {
1330- QString year; //! Value of year for actual data
1331- int zhr; //! ZHR of shower
1332- QString variable; //! value of variable for ZHR
1333- QString start; //! First day for activity
1334- QString finish; //! Latest day for activity
1335- QString peak; //! Day with maximum for activity
1336- } activityData;
1337-
1338- bool initialized;
1339- bool active;
1340- QString showerID; //! The ID of the meteor shower
1341- QString designation; //! The designation of the meteor shower
1342- QList<activityData> activity; //! List of activity
1343- int speed; //! Speed of meteors
1344- float rAlphaPeak; //! R.A. for radiant of meteor shower on the peak day
1345- float rDeltaPeak; //! Dec. for radiant of meteor shower on the peak day
1346- float driftAlpha; //! Drift of R.A.
1347- float driftDelta; //! Drift of Dec.
1348- QString parentObj; //! Parent object for meteor shower
1349- float pidx; //! The population index
1350- QList<colorPair> colors; //! <colorName, 0-100>
1351+ MeteorShowersMgr* m_mgr; //! MeteorShowersMgr instance
1352+ Status m_status; //! Meteor shower status
1353+
1354+ // data from catalog
1355+ QString m_showerID; //! The ID of the meteor shower
1356+ QString m_designation; //! The designation of the meteor shower
1357+ QList<Activity> m_activities; //! Activity list
1358+ int m_speed; //! Speed of meteors
1359+ float m_rAlphaPeak; //! R.A. for radiant of meteor shower on the peak day
1360+ float m_rDeltaPeak; //! Dec. for radiant of meteor shower on the peak day
1361+ float m_driftAlpha; //! Drift of R.A. for each day from peak
1362+ float m_driftDelta; //! Drift of Dec. for each day from peak
1363+ QString m_parentObj; //! Parent object for meteor shower
1364+ float m_pidx; //! The population index
1365+ QList<Meteor::colorPair> m_colors; //! <colorName, 0-100>
1366
1367 //current information
1368- double radiantAlpha; //! Current R.A. for radiant of meteor shower
1369- double radiantDelta; //! Current Dec. for radiant of meteor shower
1370- int zhr; //! ZHR of shower
1371- QString variable; //! value of variable for ZHR
1372- QDateTime start; //! First day for activity
1373- QDateTime finish; //! Latest day for activity
1374- QDateTime peak; //! Day with maximum for activity
1375-
1376- int status; //! Check if the radiant is active for the current sky date
1377- //! 0=inactive; 1=realData 2=genericData
1378-
1379- void draw(StelPainter &painter);
1380-
1381- //! Get a date string from JSON file and parse it for display in info corner
1382- //! @param jsondate A string from JSON file
1383- QString getDateFromJSON(QString jsondate) const;
1384-
1385- //! Get a day from JSON file and parse it for display in info corner
1386- //! @param jsondate A string from JSON file
1387- QString getDayFromJSON(QString jsondate) const;
1388-
1389- //! Get a month string from JSON file and parse it for display in info corner
1390- //! @param jsondate A string from JSON file
1391- int getMonthFromJSON(QString jsondate) const;
1392-
1393- //! Get a month string from JSON file and parse it for display in info corner
1394- //! @param jsondate A string from JSON file
1395- QString getMonthNameFromJSON(QString jsondate) const;
1396-
1397- //! Get a month name from month number
1398- //! @param jsondate A string from JSON file
1399- QString getMonthName(int number) const;
1400-
1401- //! Get the current sky QDateTime
1402- //! @return Current QDateTime of sky
1403- QDateTime getSkyQDateTime() const;
1404-
1405- //! Update value of current information(zhr, variable, stat, finish and peak)
1406- //! @param current sky QDateTime
1407- void updateCurrentData(QDateTime skyDate);
1408-
1409- //! Check if the JSON file has real data to a given year
1410- //! @param yyyy year to check
1411- //! @return index of the year or 0 to generic data
1412- int searchRealData(QString yyyy) const;
1413-
1414- //! Get the solar longitude for a specified date
1415- //! @param QDT QDateTime
1416+ Vec3d m_position; //! Cartesian equatorial position
1417+ double m_radiantAlpha; //! Current R.A. for radiant of meteor shower
1418+ double m_radiantDelta; //! Current Dec. for radiant of meteor shower
1419+ Activity m_activity; //! Current activity
1420+
1421+ QList<MeteorObj*> m_activeMeteors; //! List with all the active meteors
1422+
1423+ //! Draws the radiant
1424+ void drawRadiant(StelCore* core);
1425+
1426+ //! Draws all active meteors
1427+ void drawMeteors(StelCore* core);
1428+
1429+ //! Calculates the ZHR using normal distribution
1430+ //! @param current julian day
1431+ int calculateZHR(const double& currentJD);
1432+
1433+ //! Gets the solar longitude for a specified date
1434+ //! @param date QDate
1435 //! @return solar longitude in degree
1436- float getSolarLongitude(QDateTime QDT) const;
1437+ QString getSolarLongitude(QDate date) const;
1438 };
1439
1440 #endif /*_METEORSHOWER_HPP_*/
1441
1442=== modified file 'plugins/MeteorShowers/src/MeteorShowers.cpp'
1443--- plugins/MeteorShowers/src/MeteorShowers.cpp 2015-08-03 13:17:06 +0000
1444+++ plugins/MeteorShowers/src/MeteorShowers.cpp 2015-08-07 05:13:12 +0000
1445@@ -1,7 +1,6 @@
1446 /*
1447 * Stellarium: Meteor Showers Plug-in
1448- * Copyright (C) 2013 Marcos Cardinot
1449- * Copyright (C) 2011 Alexander Wolf
1450+ * Copyright (C) 2013-2015 Marcos Cardinot
1451 *
1452 * This program is free software; you can redistribute it and/or
1453 * modify it under the terms of the GNU General Public License
1454@@ -18,679 +17,172 @@
1455 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
1456 */
1457
1458-#include <QDir>
1459-#include <QNetworkReply>
1460-#include <QSettings>
1461-#include <QTimer>
1462+#include <QtMath>
1463
1464-#include "LabelMgr.hpp"
1465-#include "LandscapeMgr.hpp"
1466-#include "MeteorMgr.hpp"
1467-#include "MeteorShowerDialog.hpp"
1468 #include "MeteorShowers.hpp"
1469-#include "Planet.hpp"
1470 #include "StelApp.hpp"
1471-#include "StelCore.hpp"
1472-#include "StelFileMgr.hpp"
1473-#include "StelGui.hpp"
1474-#include "StelGuiItems.hpp"
1475-#include "StelJsonParser.hpp"
1476 #include "StelModuleMgr.hpp"
1477 #include "StelObjectMgr.hpp"
1478-#include "StelProgressController.hpp"
1479 #include "StelTextureMgr.hpp"
1480-
1481-#define CATALOG_FORMAT_VERSION 1 /* Version of format of catalog */
1482-
1483-const double MeteorShowers::zhrToWsr = MeteorMgr::zhrToWsr;
1484-
1485-/*
1486- This method is the one called automatically by the StelModuleMgr just
1487- after loading the dynamic library
1488-*/
1489-StelModule* MeteorShowersStelPluginInterface::getStelModule() const
1490-{
1491- return new MeteorShowers();
1492-}
1493-
1494-StelPluginInfo MeteorShowersStelPluginInterface::getPluginInfo() const
1495-{
1496- // Allow to load the resources when used as a static plugin
1497- Q_INIT_RESOURCE(MeteorShower);
1498-
1499- StelPluginInfo info;
1500- info.id = "MeteorShowers";
1501- info.displayedName = N_("Meteor Showers");
1502- info.authors = "Marcos Cardinot";
1503- info.contact = "mcardinot@gmail.com";
1504- info.description = N_("This plugin displays meteor showers and a marker"
1505- " for each active and inactive radiant, showing"
1506- " real information about its activity.");
1507- info.version = METEORSHOWERS_PLUGIN_VERSION;
1508- return info;
1509-}
1510-
1511-/*
1512- Constructor
1513-*/
1514-MeteorShowers::MeteorShowers()
1515- : flagShowMS(false)
1516- , flagShowMSButton(true)
1517- , OnIcon(NULL)
1518- , OffIcon(NULL)
1519- , GlowIcon(NULL)
1520- , toolbarButton(NULL)
1521- , updateState(CompleteNoUpdates)
1522- , downloadMgr(NULL)
1523- , progressBar(NULL)
1524- , updateTimer(0)
1525- , messageTimer(0)
1526- , updatesEnabled(false)
1527- , updateFrequencyHours(0)
1528- , enableAtStartup(false)
1529- , flagShowARG(true)
1530- , flagShowARR(true)
1531- , flagShowIR(true)
1532-{
1533- setObjectName("MeteorShowers");
1534- configDialog = new MeteorShowerDialog();
1535- conf = StelApp::getInstance().getSettings();
1536- qsrand(QDateTime::currentMSecsSinceEpoch());
1537-}
1538-
1539-/*
1540- Destructor
1541-*/
1542+#include "StelUtils.hpp"
1543+
1544+MeteorShowers::MeteorShowers(MeteorShowersMgr* mgr)
1545+ : m_mgr(mgr)
1546+{
1547+ GETSTELMODULE(StelObjectMgr)->registerStelObjectMgr(this);
1548+}
1549+
1550 MeteorShowers::~MeteorShowers()
1551 {
1552- delete configDialog;
1553-
1554- if (GlowIcon)
1555- {
1556- delete GlowIcon;
1557- }
1558-
1559- if (OnIcon)
1560- {
1561- delete OnIcon;
1562- }
1563-
1564- if (OffIcon)
1565- {
1566- delete OffIcon;
1567- }
1568-
1569- active.clear();
1570- activeInfo.clear();
1571-}
1572-
1573-/*
1574- Reimplementation of the getCallOrder method
1575-*/
1576-double MeteorShowers::getCallOrder(StelModuleActionName actionName) const
1577-{
1578- if (actionName == StelModule::ActionDraw)
1579- {
1580- return GETSTELMODULE(MeteorMgr)->getCallOrder(actionName)+10.;
1581- }
1582-
1583- return 0;
1584-}
1585-
1586-void MeteorShowers::init()
1587-{
1588- upgradeConfigIni();
1589-
1590- try
1591- {
1592- StelFileMgr::makeSureDirExistsAndIsWritable(StelFileMgr::getUserDir()+"/modules/MeteorShowers");
1593-
1594- // If no settings in the main config file, create with defaults
1595- if (!conf->childGroups().contains("MeteorShowers"))
1596- {
1597- qDebug() << "MeteorShowers: no MeteorShower section exists in main config file - creating with defaults";
1598- restoreDefaultConfigIni();
1599- }
1600-
1601- // populate settings from main config file.
1602- readSettingsFromConfig();
1603-
1604- showersJsonPath = StelFileMgr::findFile("modules/MeteorShowers", (StelFileMgr::Flags)(StelFileMgr::Directory|StelFileMgr::Writable)) + "/showers.json";
1605-
1606- texPointer = StelApp::getInstance().getTextureManager().createTexture(StelFileMgr::getInstallationDir()+"/textures/pointeur5.png");
1607- MeteorShower::radiantTexture = StelApp::getInstance().getTextureManager().createTexture(":/MeteorShowers/radiant.png");
1608-
1609- // key bindings and other actions
1610- QString msGroup = N_("Meteor Showers");
1611- addAction("actionShow_MeteorShower", msGroup, N_("Show meteor showers"), "msVisible", "Ctrl+Alt+M");
1612- addAction("actionShow_radiant_Labels", msGroup, N_("Radiant labels"), "labelsVisible", "Shift+M");
1613- addAction("actionShow_MeteorShower_ConfigDialog", msGroup, N_("Meteor Shower configuration window"), configDialog, "visible", "Ctrl+Shift+M");
1614-
1615- GlowIcon = new QPixmap(":/graphicGui/glow32x32.png");
1616- OnIcon = new QPixmap(":/MeteorShowers/btMS-on.png");
1617- OffIcon = new QPixmap(":/MeteorShowers/btMS-off.png");
1618-
1619- setFlagShowMSButton(flagShowMSButton);
1620- setFlagShowMS(getEnableAtStartup());
1621- }
1622- catch(std::runtime_error &e)
1623- {
1624- qWarning() << "MeteorShowers: init error:" << e.what();
1625- return;
1626- }
1627-
1628- // A timer for hiding alert messages
1629- messageTimer = new QTimer(this);
1630- messageTimer->setSingleShot(true); // recurring check for update
1631- messageTimer->setInterval(9000); // 6 seconds should be enough time
1632- messageTimer->stop();
1633- connect(messageTimer, SIGNAL(timeout()), this, SLOT(messageTimeout()));
1634-
1635- // If the json file does not already exist, create it from the resource in the QT resource
1636- if (!QFileInfo(showersJsonPath).exists())
1637- {
1638- qDebug() << "MeteorShowers: showers.json does not exist - copying default file to" << QDir::toNativeSeparators(showersJsonPath);
1639- restoreDefaultJsonFile();
1640- }
1641- // Validate JSON format and data
1642- if (!checkJsonFileFormat() || getJsonFileFormatVersion()<CATALOG_FORMAT_VERSION)
1643- {
1644- displayMessage(q_("The old showers.json file is no longer compatible - using default file"), "#bb0000");
1645- restoreDefaultJsonFile();
1646- }
1647-
1648- qDebug() << "MeteorShowers: loading catalog file:" << QDir::toNativeSeparators(showersJsonPath);
1649-
1650- // create meteor Showers according to content os Showers.json file
1651- readJsonFile();
1652-
1653- // Set up download manager and the update schedule
1654- downloadMgr = new QNetworkAccessManager(this);
1655- connect(downloadMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(updateDownloadComplete(QNetworkReply*)));
1656- updateState = CompleteNoUpdates;
1657- updateTimer = new QTimer(this);
1658- updateTimer->setSingleShot(false); // recurring check for update
1659- updateTimer->setInterval(13000); // check once every 13 seconds to see if it is time for an update
1660- connect(updateTimer, SIGNAL(timeout()), this, SLOT(checkForUpdate()));
1661- updateTimer->start();
1662-
1663- // skyDate startup
1664- // GZ JDfix for 0.14 I am not sure how skyDate is used. It used to be set to JDE, so again:
1665- skyDate = StelUtils::jdToQDateTime(StelApp::getInstance().getCore()->getJDE());
1666-
1667- GETSTELMODULE(StelObjectMgr)->registerStelObjectMgr(this);
1668-}
1669-
1670-void MeteorShowers::deinit()
1671-{
1672- MeteorShower::radiantTexture.clear();
1673- texPointer.clear();
1674-}
1675-
1676-void MeteorShowers::upgradeConfigIni(void)
1677-{
1678- // Upgrade settings for MeteorShower plugin
1679- if (conf->contains("MeteorShowers/flag_show_ms"))
1680- {
1681- bool b = conf->value("MeteorShowers/flag_show_ms", false).toBool();
1682- if (!conf->contains("MeteorShowers/enable_at_startup"))
1683- conf->setValue("MeteorShowers/enable_at_startup", b);
1684- conf->remove("MeteorShowers/flag_show_ms");
1685- }
1686-}
1687-
1688-void MeteorShowers::setFlagShowMS(bool b)
1689-{
1690- if (toolbarButton != NULL)
1691- {
1692- toolbarButton->setChecked(b);
1693- }
1694-
1695- flagShowMS=b;
1696-}
1697-
1698-// Define whether the button toggling meteor showers should be visible
1699-void MeteorShowers::setFlagShowMSButton(bool b)
1700-{
1701- StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
1702- if (gui != NULL)
1703- {
1704- if (b)
1705- {
1706- if (toolbarButton == NULL)
1707- {
1708- // Create the MeteorShowers button
1709- toolbarButton = new StelButton(NULL, *OnIcon, *OffIcon, *GlowIcon, "actionShow_MeteorShower");
1710- }
1711- gui->getButtonBar()->addButton(toolbarButton, "065-pluginsGroup");
1712- }
1713- else
1714- {
1715- gui->getButtonBar()->hideButton("actionShow_MeteorShower");
1716- }
1717- flagShowMSButton = b;
1718- }
1719-}
1720-
1721-bool MeteorShowers::changedSkyDate(StelCore* core)
1722-{
1723- double JD = core->getJD();
1724- skyDate = StelUtils::jdToQDateTime(JD+StelUtils::getGMTShiftFromQT(JD)/24);
1725- if (skyDate.toString("MM.dd.yyyy") != lastSkyDate.toString("MM.dd.yyyy")) //if the sky date changed
1726- {
1727- return true;
1728- }
1729- else
1730- {
1731- return false;
1732+ m_meteorShowers.clear();
1733+}
1734+
1735+void MeteorShowers::update(StelCore* core, double deltaTime)
1736+{
1737+ foreach (const MeteorShowerP& ms, m_meteorShowers)
1738+ {
1739+ ms->update(core, deltaTime);
1740 }
1741 }
1742
1743 void MeteorShowers::draw(StelCore* core)
1744 {
1745- if (!getFlagShowMS())
1746+ foreach (const MeteorShowerP& ms, m_meteorShowers)
1747+ {
1748+ ms->draw(core);
1749+ }
1750+
1751+ if (GETSTELMODULE(StelObjectMgr)->getFlagSelectedObjectPointer())
1752+ {
1753+ drawPointer(core);
1754+ }
1755+}
1756+
1757+void MeteorShowers::drawPointer(StelCore* core)
1758+{
1759+ const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("MeteorShower");
1760+ if (newSelected.empty())
1761 {
1762 return;
1763 }
1764
1765+ const StelObjectP obj = newSelected[0];
1766+ Vec3d pos = obj->getJ2000EquatorialPos(core);
1767+
1768+ // Compute 2D pos and return if outside screen
1769+ Vec3d screenpos;
1770 StelPainter painter(core->getProjection(StelCore::FrameJ2000));
1771- drawMarker(core, painter);
1772-
1773- if (GETSTELMODULE(StelObjectMgr)->getFlagSelectedObjectPointer())
1774+ if (!painter.getProjector()->project(pos, screenpos))
1775 {
1776- drawPointer(core, painter);
1777+ return;
1778 }
1779
1780- painter.setProjector(core->getProjection(StelCore::FrameAltAz));
1781- drawStream(core, painter);
1782-}
1783-
1784-void MeteorShowers::drawMarker(StelCore* core, StelPainter& painter)
1785-{
1786- Q_UNUSED(core);
1787- painter.setFont(labelFont);
1788-
1789- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1790+ const Vec3f& c(obj->getInfoColor());
1791+ painter.setColor(c[0],c[1],c[2]);
1792+ m_mgr->getPointerTexture()->bind();
1793+ painter.enableTexture2d(true);
1794 glEnable(GL_BLEND);
1795- glEnable(GL_TEXTURE_2D);
1796-
1797- foreach (const MeteorShowerP& ms, mShowers)
1798- {
1799- ms->updateCurrentData(skyDate);
1800-
1801- if (ms && ms->initialized && ms->active)
1802- {
1803- ms->draw(painter);
1804- }
1805- }
1806- glDisable(GL_TEXTURE_2D);
1807-}
1808-
1809-void MeteorShowers::drawPointer(StelCore* core, StelPainter& painter)
1810-{
1811- const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
1812-
1813- const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("MeteorShower");
1814- if (!newSelected.empty())
1815- {
1816- const StelObjectP obj = newSelected[0];
1817- Vec3d pos=obj->getJ2000EquatorialPos(core);
1818-
1819- Vec3d screenpos;
1820- // Compute 2D pos and return if outside screen
1821- if (!painter.getProjector()->project(pos, screenpos))
1822- {
1823- return;
1824- }
1825-
1826- const Vec3f& c(obj->getInfoColor());
1827- painter.setColor(c[0],c[1],c[2]);
1828- texPointer->bind();
1829- painter.enableTexture2d(true);
1830- glEnable(GL_BLEND);
1831- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode
1832-
1833- float size = obj->getAngularSize(core)*M_PI/180.*prj->getPixelPerRadAtCenter();
1834- size+=20.f + 10.f*std::sin(2.f * StelApp::getInstance().getTotalRunTime());
1835-
1836- painter.drawSprite2dMode(screenpos[0]-size/2, screenpos[1]-size/2, 10.f, 90);
1837- painter.drawSprite2dMode(screenpos[0]-size/2, screenpos[1]+size/2, 10.f, 0);
1838- painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]+size/2, 10.f, -90);
1839- painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]-size/2, 10.f, -180);
1840- painter.setColor(1,1,1,0);
1841- }
1842-}
1843-
1844-void MeteorShowers::drawStream(StelCore* core, StelPainter& painter)
1845-{
1846- if (!core->getSkyDrawer()->getFlagHasAtmosphere())
1847- {
1848- return;
1849- }
1850-
1851- LandscapeMgr* landmgr = GETSTELMODULE(LandscapeMgr);
1852- if (landmgr->getFlagAtmosphere() && landmgr->getLuminance()>5)
1853- {
1854- return;
1855- }
1856-
1857- int index = 0;
1858- if (active.size() > 0)
1859- {
1860- foreach (const activeData &a, activeInfo)
1861- {
1862- Q_UNUSED(a);
1863- // step through and draw all active meteors
1864- std::vector<MeteorStream*>::iterator iter;
1865- for (iter = active[index].begin(); iter != active[index].end(); ++iter)
1866- {
1867- (*iter)->draw(core, painter);
1868- }
1869- index++;
1870- }
1871- }
1872-}
1873-
1874-int MeteorShowers::calculateZHR(int zhr, QString variable, QDateTime start, QDateTime finish, QDateTime peak)
1875-{
1876- /***************************************
1877- * Get ZHR ranges
1878- ***************************************/
1879- int highZHR;
1880- int lowZHR;
1881- //bool multPeak = false; //multiple peaks
1882- if (zhr != -1) //isn't variable
1883- {
1884- highZHR = zhr;
1885- lowZHR = 0;
1886- }
1887- else
1888- {
1889- QStringList varZHR = variable.split("-");
1890- lowZHR = varZHR.at(0).toInt();
1891- if (varZHR.at(1).contains("*"))
1892- {
1893- //multPeak = true;
1894- highZHR = varZHR[1].replace("*", "").toInt();
1895- }
1896- else
1897- {
1898- highZHR = varZHR.at(1).toInt();
1899- }
1900- }
1901-
1902- /***************************************
1903- * Convert time intervals
1904- ***************************************/
1905- double startJD = StelUtils::qDateTimeToJd(start);
1906- double finishJD = StelUtils::qDateTimeToJd(finish);
1907- double peakJD = StelUtils::qDateTimeToJd(peak);
1908- double currentJD = StelUtils::qDateTimeToJd(skyDate);
1909-
1910- /***************************************
1911- * Gaussian distribution
1912- ***************************************/
1913- double sd; //standard deviation
1914- if (currentJD >= startJD && currentJD < peakJD) //left side of gaussian
1915- sd = (peakJD - startJD)/2;
1916- else
1917- sd = (finishJD - peakJD)/2;
1918-
1919- double gaussian = highZHR * std::exp( - std::pow(currentJD - peakJD, 2) / (sd*sd) ) + lowZHR;
1920-
1921- return (int) ((int) ((gaussian - (int) gaussian) * 10) >= 5 ? gaussian+1 : gaussian);
1922-}
1923-
1924-void MeteorShowers::updateActiveInfo(void)
1925-{
1926- foreach (const MeteorShowerP& ms, mShowers)
1927- {
1928- if (ms && ms->initialized)
1929- {
1930- //if the meteor shower is active, get data
1931- if (ms->getStatus())
1932- {
1933- //First, check if there is already data about the constellation in "activeInfo"
1934- //The var "index" will be updated to show the correct place do put the new information
1935- int index = 0;
1936- foreach(const activeData &a, activeInfo)
1937- {
1938- if (a.showerID == ms->showerID) //exists
1939- break;
1940- index++;
1941- }
1942-
1943- if (activeInfo.size() < index + 1) //new?, put in the end
1944- {
1945- activeData newData;
1946- newData.showerID = ms->showerID;
1947- newData.speed = ms->speed;
1948- newData.radiantAlpha = ms->radiantAlpha;
1949- newData.radiantDelta = ms->radiantDelta;
1950- newData.pidx = ms->pidx;
1951- newData.zhr = ms->zhr;
1952- newData.variable = ms->variable;
1953- newData.start = ms->start;
1954- newData.finish = ms->finish;
1955- newData.peak = ms->peak;
1956- newData.status = ms->status;
1957- newData.colors = ms->colors;
1958- activeInfo.append(newData);
1959- }
1960- else //just overwrites
1961- {
1962- activeInfo[index].zhr = ms->zhr;
1963- activeInfo[index].variable = ms->variable;
1964- activeInfo[index].start = ms->start;
1965- activeInfo[index].finish = ms->finish;
1966- activeInfo[index].peak = ms->peak;
1967- activeInfo[index].status = ms->status;
1968- }
1969- }
1970- }
1971- }
1972- lastSkyDate = skyDate;
1973-}
1974-
1975-void MeteorShowers::update(double deltaTime)
1976-{
1977- if (!getFlagShowMS())
1978- {
1979- return;
1980- }
1981-
1982- StelCore* core = StelApp::getInstance().getCore();
1983-
1984- double tspeed = core->getTimeRate()*86400; // sky seconds per actual second
1985- if (!tspeed) { // is paused?
1986- return; // freeze meteors at the current position
1987- }
1988-
1989- deltaTime*=1000;
1990- // if stellarium has been suspended, don't create huge number of meteors to
1991- // make up for lost time!
1992- if (deltaTime > 500)
1993- {
1994- deltaTime = 500;
1995- }
1996-
1997- QList<activeData> old_activeInfo;
1998-
1999- //check if the sky date changed
2000- if (changedSkyDate(core))
2001- {
2002- // clear data of all MS active
2003- old_activeInfo = activeInfo;
2004- activeInfo.clear();
2005-
2006- // Is GUI visible and the year changed? refresh ranges
2007- if (configDialog->visible() && lastSkyDate.toString("yyyy") != skyDate.toString("yyyy"))
2008- configDialog->refreshRangeDates();
2009- }
2010-
2011- // fill `activeInfo` with all current active meteor showers
2012- updateActiveInfo();
2013- // counting index of `active`
2014- int index = 0;
2015- // something changed? check if we have some MS to remove from `active`
2016- if (!old_activeInfo.isEmpty())
2017- {
2018- for (int i=0; i<old_activeInfo.size(); i++)
2019- {
2020- bool found = false;
2021- for (int j=0; j<activeInfo.size(); j++)
2022- {
2023- if (old_activeInfo[i].showerID == activeInfo[j].showerID)
2024- {
2025- found = true;
2026- break;
2027- }
2028- }
2029- if (!found)
2030- {
2031- active.erase(active.begin().operator +(index));
2032- index--;
2033- }
2034- index++;
2035- }
2036- }
2037-
2038- std::vector<std::vector<MeteorStream*> >::iterator iterOut;
2039- std::vector<MeteorStream*>::iterator iterIn;
2040- index = 0;
2041- if (active.size() > 0)
2042- {
2043- // step through and update all active meteors
2044- for (iterOut = active.begin(); iterOut != active.end(); ++iterOut)
2045- {
2046- for (iterIn = active[index].begin(); iterIn != active[index].end(); ++iterIn)
2047- {
2048- if (!(*iterIn)->update(deltaTime))
2049- {
2050- delete *iterIn;
2051- iterIn = active[index].erase(iterIn);
2052- iterIn--;
2053- }
2054- }
2055- if (active[index].empty())
2056- {
2057- iterOut = active.erase(iterOut);
2058- iterOut--;
2059- index--;
2060- }
2061- index++;
2062- }
2063- }
2064-
2065- index = 0;
2066- foreach (const activeData &current, activeInfo)
2067- {
2068- std::vector<MeteorStream*> aux;
2069- if (active.empty() || active.size() < (unsigned) activeInfo.size())
2070- {
2071- if(tspeed<0 || fabs(tspeed)>1.)
2072- {
2073- activeInfo.removeAt(index);
2074- continue; // don't create new meteors
2075- }
2076- active.push_back(aux);
2077- }
2078-
2079- int ZHR = calculateZHR(current.zhr,
2080- current.variable,
2081- current.start,
2082- current.finish,
2083- current.peak);
2084-
2085- // determine average meteors per frame needing to be created
2086- int mpf = (int)((double)ZHR*zhrToWsr*deltaTime/1000.0 + 0.5);
2087- if (mpf<1)
2088- {
2089- mpf = 1;
2090- }
2091-
2092- for (int i=0; i<mpf; ++i)
2093- {
2094- // start new meteor based on ZHR time probability
2095- double prob = ((double)qrand())/RAND_MAX;
2096- if (ZHR>0 && prob<((double)ZHR*zhrToWsr*deltaTime/1000.0/(double)mpf))
2097- {
2098- MeteorStream *m = new MeteorStream(core,
2099- current.speed,
2100- current.radiantAlpha,
2101- current.radiantDelta,
2102- current.pidx,
2103- current.colors);
2104- active[index].push_back(m);
2105- }
2106- }
2107- index++;
2108- }
2109-}
2110-
2111-QList<MeteorShowerP> MeteorShowers::searchEvents(QDate dateFrom, QDate dateTo) const
2112-{
2113- QList<MeteorShowerP> result;
2114+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode
2115+
2116+ float size = obj->getAngularSize(core) * M_PI / 180. * painter.getProjector()->getPixelPerRadAtCenter();
2117+ size += 20.f + 10.f * qSin(2.f * StelApp::getInstance().getTotalRunTime());
2118+
2119+ painter.drawSprite2dMode(screenpos[0]-size/2, screenpos[1]-size/2, 10.f, 90);
2120+ painter.drawSprite2dMode(screenpos[0]-size/2, screenpos[1]+size/2, 10.f, 0);
2121+ painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]+size/2, 10.f, -90);
2122+ painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]-size/2, 10.f, -180);
2123+ painter.setColor(1, 1, 1, 0);
2124+}
2125+
2126+void MeteorShowers::loadMeteorShowers(const QVariantMap& map)
2127+{
2128+ m_meteorShowers.clear();
2129+ foreach(QString msKey, map.keys())
2130+ {
2131+ QVariantMap msData = map.value(msKey).toMap();
2132+ msData["showerID"] = msKey;
2133+
2134+ MeteorShowerP ms(new MeteorShower(m_mgr, msData));
2135+ if (ms->getStatus() != MeteorShower::INVALID)
2136+ {
2137+ m_meteorShowers.append(ms);
2138+ }
2139+ }
2140+}
2141+
2142+QList<MeteorShowers::SearchResult> MeteorShowers::searchEvents(QDate dateFrom, QDate dateTo) const
2143+{
2144+ QList<SearchResult> result;
2145+ bool found;
2146 QDate date;
2147-
2148- foreach(const MeteorShowerP& ms, mShowers)
2149+ MeteorShower::Activity a;
2150+ SearchResult r;
2151+ foreach(const MeteorShowerP& ms, m_meteorShowers)
2152 {
2153 date = dateFrom;
2154 while(date.operator <=(dateTo))
2155 {
2156- ms->updateCurrentData((QDateTime) date);
2157- if (ms->initialized && ms->status)
2158- {
2159- result.append(ms);
2160+ found = false;
2161+ a = ms->hasConfirmedShower(date, found);
2162+ if (!found)
2163+ {
2164+ a = ms->hasGenericShower(date, found);
2165+ }
2166+
2167+ if (found)
2168+ {
2169+ r.name = ms->getNameI18n();
2170+ r.peak = a.peak;
2171+ r.type = a.year > 0 ? q_("Confirmed") : q_("Generic");
2172+ r.zhr = a.zhr == -1
2173+ ? QString("%1-%2").arg(a.variable.at(0)).arg(a.variable.at(1))
2174+ : QString::number(a.zhr);
2175+ result.append(r);
2176 break;
2177 }
2178 date = date.addDays(1);
2179 }
2180 }
2181-
2182 return result;
2183 }
2184
2185 QList<StelObjectP> MeteorShowers::searchAround(const Vec3d& av, double limitFov, const StelCore*) const
2186 {
2187 QList<StelObjectP> result;
2188-
2189- if (!getFlagShowMS() || !getFlagRadiant())
2190+ if (!m_mgr->getEnablePlugin())
2191 {
2192 return result;
2193 }
2194
2195 Vec3d v(av);
2196 v.normalize();
2197- double cosLimFov = cos(limitFov * M_PI/180.);
2198+ double cosLimFov = qCos(limitFov * M_PI/180.);
2199 Vec3d equPos;
2200-
2201- foreach(const MeteorShowerP& ms, mShowers)
2202+ foreach(const MeteorShowerP& ms, m_meteorShowers)
2203 {
2204- if (ms->initialized && ms->active)
2205+ if (ms->enabled())
2206 {
2207- equPos = ms->XYZ;
2208+ equPos = ms->getJ2000EquatorialPos(NULL);
2209 equPos.normalize();
2210- if (equPos[0]*v[0] + equPos[1]*v[1] + equPos[2]*v[2]>=cosLimFov)
2211+ if (equPos[0]*v[0] + equPos[1]*v[1] + equPos[2]*v[2] >= cosLimFov)
2212 {
2213 result.append(qSharedPointerCast<StelObject>(ms));
2214 }
2215 }
2216 }
2217-
2218 return result;
2219 }
2220
2221 StelObjectP MeteorShowers::searchByName(const QString& englishName) const
2222 {
2223- if (!getFlagShowMS() || !getFlagRadiant())
2224+ if (!m_mgr->getEnablePlugin())
2225 {
2226 return NULL;
2227 }
2228
2229- foreach(const MeteorShowerP& ms, mShowers)
2230+ foreach(const MeteorShowerP& ms, m_meteorShowers)
2231 {
2232- if (ms->initialized)
2233+ if (ms->enabled())
2234 {
2235 bool sameEngName = ms->getEnglishName().toUpper() == englishName.toUpper();
2236 bool desigIsEngName = ms->getDesignation().toUpper() == englishName.toUpper();
2237@@ -701,20 +193,19 @@
2238 }
2239 }
2240 }
2241-
2242 return NULL;
2243 }
2244
2245 StelObjectP MeteorShowers::searchByNameI18n(const QString& nameI18n) const
2246 {
2247- if (!getFlagShowMS() || !getFlagRadiant())
2248+ if (!m_mgr->getEnablePlugin())
2249 {
2250 return NULL;
2251 }
2252
2253- foreach(const MeteorShowerP& ms, mShowers)
2254+ foreach(const MeteorShowerP& ms, m_meteorShowers)
2255 {
2256- if (ms->initialized)
2257+ if (ms->enabled())
2258 {
2259 if (ms->getNameI18n().toUpper() == nameI18n.toUpper())
2260 {
2261@@ -722,52 +213,44 @@
2262 }
2263 }
2264 }
2265-
2266 return NULL;
2267 }
2268
2269 QStringList MeteorShowers::listMatchingObjectsI18n(const QString& objPrefix, int maxNbItem, bool useStartOfWords) const
2270 {
2271 QStringList result;
2272- if (!getFlagShowMS() || !getFlagRadiant())
2273- {
2274- return result;
2275- }
2276-
2277- if (maxNbItem==0)
2278+ if (!m_mgr->getEnablePlugin() || maxNbItem == 0)
2279 {
2280 return result;
2281 }
2282
2283 QString sn;
2284- bool find;
2285-
2286- foreach(const MeteorShowerP& ms, mShowers)
2287+ bool found = false;
2288+ foreach(const MeteorShowerP& ms, m_meteorShowers)
2289 {
2290- if (ms->initialized && ms->active)
2291+ if (ms->enabled())
2292 {
2293 sn = ms->getNameI18n();
2294- find = false;
2295 if (useStartOfWords)
2296 {
2297- if (sn.toUpper().left(objPrefix.length()) == objPrefix.toUpper())
2298- find = true;
2299+ found = sn.toUpper().left(objPrefix.length()) == objPrefix.toUpper();
2300 }
2301 else
2302 {
2303- if (sn.contains(objPrefix, Qt::CaseInsensitive))
2304- find = true;
2305- }
2306- if (find)
2307- result << sn;
2308+ found = sn.contains(objPrefix, Qt::CaseInsensitive);
2309+ }
2310+
2311+ if (found)
2312+ {
2313+ result.append(sn);
2314+ }
2315 }
2316 }
2317
2318 result.sort();
2319-
2320- if (result.size()>maxNbItem)
2321+ if (result.size() > maxNbItem)
2322 {
2323- result.erase(result.begin()+maxNbItem, result.end());
2324+ result.erase(result.begin() + maxNbItem, result.end());
2325 }
2326
2327 return result;
2328@@ -776,642 +259,76 @@
2329 QStringList MeteorShowers::listMatchingObjects(const QString& objPrefix, int maxNbItem, bool useStartOfWords) const
2330 {
2331 QStringList result;
2332- if (!getFlagShowMS() || !getFlagRadiant())
2333- {
2334- return result;
2335- }
2336-
2337- if (maxNbItem==0)
2338+ if (!m_mgr->getEnablePlugin() || maxNbItem == 0)
2339 {
2340 return result;
2341 }
2342
2343 QString sn;
2344- bool find;
2345- foreach(const MeteorShowerP& ms, mShowers)
2346+ bool found = false;
2347+ foreach(const MeteorShowerP& ms, m_meteorShowers)
2348 {
2349- if (ms->initialized && ms->active)
2350+ if (ms->enabled())
2351 {
2352 sn = ms->getEnglishName();
2353- find = false;
2354 if (useStartOfWords)
2355 {
2356- if (objPrefix.toUpper()==sn.toUpper().left(objPrefix.length()))
2357- find = true;
2358+ found = objPrefix.toUpper()==sn.toUpper().left(objPrefix.length());
2359 }
2360 else
2361 {
2362- if (sn.contains(objPrefix, Qt::CaseInsensitive))
2363- find = true;
2364+ found = sn.contains(objPrefix, Qt::CaseInsensitive);
2365 }
2366- if (find)
2367+ if (found)
2368 {
2369- result << sn;
2370+ result.append(sn);
2371 }
2372
2373 sn = ms->getDesignation();
2374- find = false;
2375 if (useStartOfWords)
2376 {
2377- if (objPrefix.toUpper()==sn.toUpper().left(objPrefix.length()))
2378- find = true;
2379+ found = objPrefix.toUpper()==sn.toUpper().left(objPrefix.length());
2380 }
2381 else
2382 {
2383- if (sn.contains(objPrefix, Qt::CaseInsensitive))
2384- find = true;
2385+ found = sn.contains(objPrefix, Qt::CaseInsensitive);
2386 }
2387- if (find)
2388+ if (found)
2389 {
2390- result << sn;
2391+ result.append(sn);
2392 }
2393 }
2394 }
2395
2396 result.sort();
2397- if (result.size()>maxNbItem)
2398- result.erase(result.begin()+maxNbItem, result.end());
2399-
2400+ if (result.size() > maxNbItem)
2401+ {
2402+ result.erase(result.begin() + maxNbItem, result.end());
2403+ }
2404 return result;
2405 }
2406
2407 QStringList MeteorShowers::listAllObjects(bool inEnglish) const
2408 {
2409 QStringList result;
2410+ if (!m_mgr->getEnablePlugin())
2411+ {
2412+ return result;
2413+ }
2414+
2415 if (inEnglish)
2416 {
2417- foreach(const MeteorShowerP& ms, mShowers)
2418+ foreach(const MeteorShowerP& ms, m_meteorShowers)
2419 {
2420- result << ms->getEnglishName();
2421+ result.append(ms->getEnglishName());
2422 }
2423 }
2424 else
2425 {
2426- foreach(const MeteorShowerP& ms, mShowers)
2427+ foreach(const MeteorShowerP& ms, m_meteorShowers)
2428 {
2429- result << ms->getNameI18n();
2430+ result.append(ms->getNameI18n());
2431 }
2432 }
2433 return result;
2434 }
2435-
2436-bool MeteorShowers::configureGui(bool show)
2437-{
2438- if (show)
2439- {
2440- configDialog->setVisible(true);
2441- }
2442-
2443- return true;
2444-}
2445-
2446-QVariantMap MeteorShowers::loadShowersMap(QString path)
2447-{
2448- if (path.isEmpty())
2449- {
2450- path = showersJsonPath;
2451- }
2452-
2453- QVariantMap map;
2454- QFile jsonFile(path);
2455- if (!jsonFile.open(QIODevice::ReadOnly))
2456- {
2457- qWarning() << "MeteorShowers: cannot open" << path;
2458- }
2459- else
2460- {
2461- map = StelJsonParser::parse(jsonFile.readAll()).toMap();
2462- jsonFile.close();
2463- }
2464- return map;
2465-}
2466-
2467-void MeteorShowers::readJsonFile(void)
2468-{
2469- setShowersMap(loadShowersMap());
2470-}
2471-
2472-void MeteorShowers::setShowersMap(const QVariantMap& map)
2473-{
2474- mShowers.clear();
2475- QVariantMap msMap = map.value("showers").toMap();
2476- foreach(QString msKey, msMap.keys())
2477- {
2478- QVariantMap msData = msMap.value(msKey).toMap();
2479- msData["showerID"] = msKey;
2480-
2481- MeteorShowerP ms(new MeteorShower(msData));
2482- if (ms->initialized)
2483- {
2484- mShowers.append(ms);
2485- }
2486- }
2487-}
2488-
2489-void MeteorShowers::restoreDefaults(void)
2490-{
2491- restoreDefaultConfigIni();
2492- restoreDefaultJsonFile();
2493- readJsonFile();
2494- readSettingsFromConfig();
2495-}
2496-
2497-void MeteorShowers::restoreDefaultConfigIni(void)
2498-{
2499- conf->beginGroup("MeteorShowers");
2500-
2501- // delete all existing MeteorShower settings...
2502- conf->remove("");
2503-
2504- conf->setValue("enable_at_startup", true);
2505- conf->setValue("updates_enabled", true);
2506- conf->setValue("url", "http://stellarium.org/json/showers.json");
2507- conf->setValue("update_frequency_hours", 100);
2508- conf->setValue("flag_show_ms_button", true);
2509- conf->setValue("flag_show_radiants", true);
2510- conf->setValue("flag_active_radiants", true);
2511-
2512- conf->setValue("colorARG", "0, 255, 240");
2513- conf->setValue("colorARR", "255, 240, 0");
2514- conf->setValue("colorIR", "255, 255, 255");
2515-
2516- conf->setValue("show_radiant_labels", true);
2517-
2518- conf->endGroup();
2519-}
2520-
2521-void MeteorShowers::restoreDefaultJsonFile(void)
2522-{
2523- if (QFileInfo(showersJsonPath).exists())
2524- {
2525- backupJsonFile(true);
2526- }
2527-
2528- QFile src(":/MeteorShowers/showers.json");
2529- if (!src.copy(showersJsonPath))
2530- {
2531- qWarning() << "MeteorShowers: cannot copy JSON resource to" << showersJsonPath;
2532- }
2533- else
2534- {
2535- qDebug() << "MeteorShowers: copied default showers.json to" << showersJsonPath;
2536- // The resource is read only, and the new file inherits this... make sure the new file
2537- // is writable by the Stellarium process so that updates can be done.
2538- QFile dest(showersJsonPath);
2539- dest.setPermissions(dest.permissions() | QFile::WriteOwner);
2540-
2541- // Make sure that in the case where an online update has previously been done, but
2542- // the json file has been manually removed, that an update is schreduled in a timely
2543- // manner
2544- conf->remove("MeteorShowers/last_update");
2545- lastUpdate = QDateTime::fromString("2013-12-31T12:00:00", Qt::ISODate);
2546- }
2547-}
2548-
2549-bool MeteorShowers::backupJsonFile(bool deleteOriginal)
2550-{
2551- QFile old(showersJsonPath);
2552- if (!old.exists())
2553- {
2554- qWarning() << "MeteorShowers: no file to backup";
2555- return false;
2556- }
2557-
2558- QString backupPath = showersJsonPath + ".old";
2559- if (QFileInfo(backupPath).exists())
2560- {
2561- QFile(backupPath).remove();
2562- }
2563-
2564- if (old.copy(backupPath))
2565- {
2566- if (deleteOriginal)
2567- {
2568- if (!old.remove())
2569- {
2570- qWarning() << "MeteorShowers: WARNING - could not remove old showers.json file";
2571- return false;
2572- }
2573- }
2574- }
2575- else
2576- {
2577- qWarning() << "MeteorShowers: WARNING - failed to copy showers.json to showers.json.old";
2578- return false;
2579- }
2580-
2581- return true;
2582-}
2583-
2584-int MeteorShowers::getJsonFileFormatVersion(void)
2585-{
2586- int jsonVersion = -1;
2587- QFile showersJsonFile(showersJsonPath);
2588- if (!showersJsonFile.open(QIODevice::ReadOnly))
2589- {
2590- qWarning() << "MeteorShowers: cannot open" << QDir::toNativeSeparators(showersJsonPath);
2591- return jsonVersion;
2592- }
2593-
2594- QVariantMap map;
2595- map = StelJsonParser::parse(&showersJsonFile).toMap();
2596- if (map.contains("version"))
2597- {
2598- jsonVersion = map.value("version").toInt();
2599- }
2600-
2601- showersJsonFile.close();
2602- qDebug() << "MeteorShowers: version of the format of the catalog:" << jsonVersion;
2603- return jsonVersion;
2604-}
2605-
2606-bool MeteorShowers::checkJsonFileFormat()
2607-{
2608- QFile showersJsonFile(showersJsonPath);
2609- if (!showersJsonFile.open(QIODevice::ReadOnly))
2610- {
2611- qWarning() << "MeteorShowers: cannot open" << QDir::toNativeSeparators(showersJsonPath);
2612- return false;
2613- }
2614-
2615- QVariantMap map;
2616- try
2617- {
2618- map = StelJsonParser::parse(&showersJsonFile).toMap();
2619- showersJsonFile.close();
2620- }
2621- catch(std::runtime_error& e)
2622- {
2623- qDebug() << "MeteorShowers: file format is wrong! Error:" << e.what();
2624- return false;
2625- }
2626-
2627- return true;
2628-}
2629-
2630-void MeteorShowers::readSettingsFromConfig(void)
2631-{
2632- conf->beginGroup("MeteorShowers");
2633-
2634- updateUrl = conf->value("url", "http://stellarium.org/json/showers.json").toString();
2635- updateFrequencyHours = conf->value("update_frequency_hours", 720).toInt();
2636- lastUpdate = QDateTime::fromString(conf->value("last_update", "2013-12-10T12:00:00").toString(), Qt::ISODate);
2637- updatesEnabled = conf->value("updates_enabled", true).toBool();
2638- enableAtStartup = conf->value("enable_at_startup", true).toBool();
2639- flagShowMSButton = conf->value("flag_show_ms_button", true).toBool();
2640- setFlagRadiant(conf->value("flag_show_radiants", true).toBool());
2641- setFlagActiveRadiant(conf->value("flag_active_radiants", true).toBool());
2642-
2643- Vec3f color;
2644- color = StelUtils::strToVec3f(conf->value("colorARG", "0, 255, 240").toString());
2645- colorARG = QColor(color[0],color[1],color[2]);
2646- color = StelUtils::strToVec3f(conf->value("colorARR", "255, 240, 0").toString());
2647- colorARR = QColor(color[0],color[1],color[2]);
2648- color = StelUtils::strToVec3f(conf->value("colorIR", "255, 255, 255").toString());
2649- colorIR = QColor(color[0],color[1],color[2]);
2650-
2651- MeteorShower::showLabels = conf->value("show_radiant_labels", true).toBool();
2652- labelFont.setPixelSize(conf->value("font_size", 13).toInt());
2653-
2654- conf->endGroup();
2655-}
2656-
2657-void MeteorShowers::saveSettingsToConfig(void)
2658-{
2659- conf->beginGroup("MeteorShowers");
2660-
2661- conf->setValue("url", updateUrl);
2662- conf->setValue("update_frequency_hours", updateFrequencyHours);
2663- conf->setValue("updates_enabled", updatesEnabled);
2664- conf->setValue("enable_at_startup", enableAtStartup);
2665- conf->setValue("flag_show_ms_button", flagShowMSButton);
2666- conf->setValue("flag_show_radiants", getFlagRadiant());
2667- conf->setValue("flag_active_radiants", getFlagActiveRadiant());
2668-
2669- int r,g,b;
2670- colorARG.getRgb(&r,&g,&b);
2671- conf->setValue("colorARG", QString("%1, %2, %3").arg(r).arg(g).arg(b));
2672- colorARR.getRgb(&r,&g,&b);
2673- conf->setValue("colorARR", QString("%1, %2, %3").arg(r).arg(g).arg(b));
2674- colorIR.getRgb(&r,&g,&b);
2675- conf->setValue("colorIR", QString("%1, %2, %3").arg(r).arg(g).arg(b));
2676-
2677- conf->setValue("show_radiant_labels", MeteorShower::showLabels);
2678- conf->setValue("font_size", labelFont.pixelSize());
2679-
2680- conf->endGroup();
2681-}
2682-
2683-int MeteorShowers::getSecondsToUpdate(void)
2684-{
2685- QDateTime nextUpdate = lastUpdate.addSecs(updateFrequencyHours * 3600);
2686- return QDateTime::currentDateTime().secsTo(nextUpdate);
2687-}
2688-
2689-void MeteorShowers::checkForUpdate(void)
2690-{
2691- if (updatesEnabled && lastUpdate.addSecs(updateFrequencyHours * 3600) <= QDateTime::currentDateTime())
2692- {
2693- updateJSON();
2694- }
2695-}
2696-
2697-void MeteorShowers::updateJSON(void)
2698-{
2699- if (updateState == MeteorShowers::Updating)
2700- {
2701- qWarning() << "MeteorShowers: already updating... will not start again current update is complete.";
2702- return;
2703- }
2704- else
2705- {
2706- qDebug() << "MeteorShowers: starting update...";
2707- }
2708-
2709- lastUpdate = QDateTime::currentDateTime();
2710- conf->setValue("MeteorShowers/last_update", lastUpdate.toString(Qt::ISODate));
2711-
2712- emit(jsonUpdateComplete());
2713-
2714- updateState = MeteorShowers::Updating;
2715-
2716- emit(updateStateChanged(updateState));
2717- updateFile.clear();
2718-
2719- if (progressBar == NULL)
2720- {
2721- progressBar = StelApp::getInstance().addProgressBar();
2722- }
2723-
2724- progressBar->setValue(0);
2725- progressBar->setRange(0, 100);
2726- progressBar->setFormat("Update meteor showers");
2727-
2728- QNetworkRequest request;
2729- request.setUrl(QUrl(updateUrl));
2730- request.setRawHeader("User-Agent", QString("Mozilla/5.0 (Stellarium Meteor Showers Plugin %1; http://stellarium.org/)").arg(METEORSHOWERS_PLUGIN_VERSION).toUtf8());
2731- downloadMgr->get(request);
2732-
2733- updateState = MeteorShowers::CompleteUpdates;
2734- emit(updateStateChanged(updateState));
2735- emit(jsonUpdateComplete());
2736-}
2737-
2738-void MeteorShowers::updateDownloadComplete(QNetworkReply* reply)
2739-{
2740- // check the download worked, and save the data to file if this is the case.
2741- if (reply->error() != QNetworkReply::NoError)
2742- {
2743- qWarning() << "MeteorShowers: FAILED to download" << reply->url() << " Error:" << reply->errorString();
2744- }
2745- else
2746- {
2747- // download completed successfully.
2748- QString jsonFilePath = StelFileMgr::findFile("modules/MeteorShowers", StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::Directory)) + "/showers.json";
2749- if (jsonFilePath.isEmpty())
2750- {
2751- qWarning() << "MeteorShowers: cannot write JSON data to file";
2752- }
2753- else
2754- {
2755- QFile jsonFile(jsonFilePath);
2756- if (jsonFile.exists())
2757- {
2758- jsonFile.remove();
2759- }
2760-
2761- if (jsonFile.open(QIODevice::WriteOnly | QIODevice::Text))
2762- {
2763- jsonFile.write(reply->readAll());
2764- jsonFile.close();
2765- }
2766- }
2767- }
2768-
2769- if (progressBar)
2770- {
2771- progressBar->setValue(100);
2772- StelApp::getInstance().removeProgressBar(progressBar);
2773- progressBar = NULL;
2774- }
2775-
2776- readJsonFile();
2777-}
2778-
2779-void MeteorShowers::displayMessage(const QString& message, const QString hexColor)
2780-{
2781- messageIDs << GETSTELMODULE(LabelMgr)->labelScreen(message, 30, 30 + (20*messageIDs.count()), true, 16, hexColor);
2782- messageTimer->start();
2783-}
2784-
2785-void MeteorShowers::messageTimeout(void)
2786-{
2787- foreach(int i, messageIDs)
2788- {
2789- GETSTELMODULE(LabelMgr)->deleteLabel(i);
2790- }
2791-}
2792-
2793-bool MeteorShowers::getFlagLabels()
2794-{
2795- return MeteorShower::showLabels;
2796-}
2797-
2798-void MeteorShowers::setFlagLabels(bool b)
2799-{
2800- if (MeteorShower::showLabels != b)
2801- MeteorShower::showLabels = b;
2802-}
2803-
2804-void MeteorShowers::setLabelFontSize(int size)
2805-{
2806- if (labelFont.pixelSize() != size)
2807- labelFont.setPixelSize(size);
2808-}
2809-
2810-bool MeteorShowers::getFlagShowMS(void) const
2811-{
2812- if (StelApp::getInstance().getCore()->getCurrentPlanet().data()->getEnglishName()!="Earth")
2813- return false;
2814- else
2815- return flagShowMS;
2816-}
2817-
2818-void MeteorShowers::translations()
2819-{
2820-#if 0
2821- // Meteor showers
2822- // TRANSLATORS: Name of meteor shower
2823- N_("Quadrantids");
2824- // TRANSLATORS: Name of meteor shower
2825- N_("Lyrids");
2826- // TRANSLATORS: Name of meteor shower
2827- N_("α-Centaurids");
2828- // TRANSLATORS: Name of meteor shower
2829- N_("γ-Normids");
2830- // TRANSLATORS: Name of meteor shower
2831- N_("η-Aquariids");
2832- // TRANSLATORS: Name of meteor shower
2833- N_("June Bootids");
2834- // TRANSLATORS: Name of meteor shower
2835- N_("Piscis Austrinids");
2836- // TRANSLATORS: Name of meteor shower
2837- N_("Southern δ-Aquariids");
2838- // TRANSLATORS: Name of meteor shower
2839- N_("α-Capricornids");
2840- // TRANSLATORS: Name of meteor shower
2841- N_("α-Aurigids");
2842- // TRANSLATORS: Name of meteor shower
2843- N_("September ε-Perseids");
2844- // TRANSLATORS: Name of meteor shower
2845- N_("Draconids");
2846- // TRANSLATORS: Name of meteor shower
2847- N_("Leonids");
2848- // TRANSLATORS: Name of meteor shower
2849- N_("Phoenicids");
2850- // TRANSLATORS: Name of meteor shower
2851- N_("Puppid-Velids");
2852- // TRANSLATORS: Name of meteor shower
2853- N_("Ursids");
2854- // TRANSLATORS: Name of meteor shower
2855- N_("Perseids");
2856- // TRANSLATORS: Name of meteor shower
2857- N_("δ-Leonids");
2858- // TRANSLATORS: Name of meteor shower
2859- N_("π-Puppids");
2860- // TRANSLATORS: Name of meteor shower
2861- N_("June Lyrids");
2862- // TRANSLATORS: Name of meteor shower
2863- N_("κ-Cygnids");
2864- // TRANSLATORS: Name of meteor shower
2865- N_("ε-Lyrids");
2866- // TRANSLATORS: Name of meteor shower
2867- N_("δ-Aurigids");
2868- // TRANSLATORS: Name of meteor shower
2869- N_("ε-Geminids");
2870- // TRANSLATORS: Name of meteor shower
2871- N_("Southern Taurids");
2872- // TRANSLATORS: Name of meteor shower
2873- N_("Northern Taurids");
2874- // TRANSLATORS: Name of meteor shower
2875- N_("Monocerotids");
2876- // TRANSLATORS: Name of meteor shower
2877- N_("α-Monocerotids");
2878- // TRANSLATORS: Name of meteor shower
2879- N_("σ-Hydrids");
2880- // TRANSLATORS: Name of meteor shower
2881- N_("Geminids");
2882- // TRANSLATORS: Name of meteor shower
2883- N_("Leonis Minorids");
2884- // TRANSLATORS: Name of meteor shower
2885- N_("December Leonis Minorids");
2886- // TRANSLATORS: Name of meteor shower
2887- N_("Comae Berenicids");
2888- // TRANSLATORS: Name of meteor shower
2889- N_("Orionids");
2890- // TRANSLATORS: Name of meteor shower
2891- N_("Andromedids");
2892- // TRANSLATORS: Name of meteor shower
2893- N_("η-Lyrids");
2894- // TRANSLATORS: Name of meteor shower
2895- N_("α-Scorpiids");
2896- // TRANSLATORS: Name of meteor shower
2897- N_("Ophiuchids");
2898- // TRANSLATORS: Name of meteor shower
2899- N_("θ-Ophiuchids");
2900- // TRANSLATORS: Name of meteor shower
2901- N_("κ-Serpentids");
2902- // TRANSLATORS: Name of meteor shower
2903- N_("θ-Centaurids");
2904- // TRANSLATORS: Name of meteor shower
2905- N_("ω-Cetids");
2906- // TRANSLATORS: Name of meteor shower
2907- N_("Southern ω-Scorpiids");
2908- // TRANSLATORS: Name of meteor shower
2909- N_("Northern ω-Scorpiids");
2910- // TRANSLATORS: Name of meteor shower
2911- N_("Arietids");
2912- // TRANSLATORS: Name of meteor shower
2913- N_("π-Cetids");
2914- // TRANSLATORS: Name of meteor shower
2915- N_("δ-Cancrids");
2916- // TRANSLATORS: Name of meteor shower
2917- N_("τ-Herculids");
2918- // TRANSLATORS: Name of meteor shower
2919- N_("ρ-Geminids");
2920- // TRANSLATORS: Name of meteor shower
2921- N_("η-Carinids");
2922- // TRANSLATORS: Name of meteor shower
2923- N_("η-Craterids");
2924- // TRANSLATORS: Name of meteor shower
2925- N_("π-Virginids");
2926- // TRANSLATORS: Name of meteor shower
2927- N_("θ-Virginids");
2928- // TRANSLATORS: Name of meteor shower
2929- N_("May Librids");
2930- // TRANSLATORS: Name of meteor shower
2931- N_("June Scutids");
2932- // TRANSLATORS: Name of meteor shower
2933- N_("α-Pisces Australids");
2934- // TRANSLATORS: Name of meteor shower
2935- N_("Southern ι-Aquariids");
2936- // TRANSLATORS: Name of meteor shower
2937- N_("Northern ι-Aquariids");
2938- // TRANSLATORS: Name of meteor shower
2939- N_("γ-Aquariids");
2940- // TRANSLATORS: Name of meteor shower
2941- N_("Autumn Arietids");
2942- // TRANSLATORS: Name of meteor shower
2943- N_("χ-Orionids");
2944-
2945- // List of parent objects for meteor showers
2946- // TRANSLATORS: Name of parent object for meteor shower
2947- N_("Comet 1P/Halley");
2948- // TRANSLATORS: Name of parent object for meteor shower
2949- N_("Comet 7P/Pons-Winnecke");
2950- // TRANSLATORS: Name of parent object for meteor shower
2951- N_("Comet 55P/Tempel-Tuttle");
2952- // TRANSLATORS: Name of parent object for meteor shower
2953- N_("Comet 96P/Machholz");
2954- // TRANSLATORS: Name of parent object for meteor shower
2955- N_("Comet 109P/Swift-Tuttle");
2956- // TRANSLATORS: Name of parent object for meteor shower
2957- N_("Comet Thatcher (1861 I)");
2958- // TRANSLATORS: Name of parent object for meteor shower
2959- N_("Comet 26P/Grigg-Skjellerup");
2960- // TRANSLATORS: Name of parent object for meteor shower
2961- N_("Comet 21P/Giacobini-Zinner");
2962- // TRANSLATORS: Name of parent object for meteor shower
2963- N_("Comet 169P/NEAT");
2964- // TRANSLATORS: Name of parent object for meteor shower
2965- N_("Comet 289P/Blanpain");
2966- // TRANSLATORS: Name of parent object for meteor shower
2967- N_("Comet 8P/Tuttle");
2968- // TRANSLATORS: Name of parent object for meteor shower
2969- N_("Comet 3D/Biela");
2970- // TRANSLATORS: Name of parent object for meteor shower
2971- N_("Comet C/1917 F1 (Mellish)");
2972- // TRANSLATORS: Name of parent object for meteor shower
2973- N_("Comet C/1964 N1 (Ikeya)");
2974- // TRANSLATORS: Name of parent object for meteor shower
2975- N_("Comet Schwassmann-Wachmann 3");
2976- // TRANSLATORS: Name of parent object for meteor shower
2977- N_("Minor planet 2003 EH1 and Comet C/1490 Y1");
2978- // TRANSLATORS: Name of parent object for meteor shower
2979- N_("Minor planet (4450) Pan");
2980- // TRANSLATORS: Name of parent object for meteor shower
2981- N_("Minor planet 2008 ED69");
2982- // TRANSLATORS: Name of parent object for meteor shower
2983- N_("Comet 2P/Encke");
2984- // TRANSLATORS: Name of parent object for meteor shower
2985- N_("Minor planet 2004 TG10");
2986- // TRANSLATORS: Name of parent object for meteor shower
2987- N_("Minor planet (3200) Phaethon");
2988-
2989- /* For copy/paste:
2990- // TRANSLATORS: Name of meteor shower
2991- N_("");
2992- */
2993-
2994-#endif
2995-}
2996
2997=== modified file 'plugins/MeteorShowers/src/MeteorShowers.hpp'
2998--- plugins/MeteorShowers/src/MeteorShowers.hpp 2015-05-31 09:35:00 +0000
2999+++ plugins/MeteorShowers/src/MeteorShowers.hpp 2015-08-07 05:13:12 +0000
3000@@ -1,7 +1,6 @@
3001 /*
3002 * Stellarium: Meteor Showers Plug-in
3003- * Copyright (C) 2013 Marcos Cardinot
3004- * Copyright (C) 2011 Alexander Wolf
3005+ * Copyright (C) 2013-2015 Marcos Cardinot
3006 *
3007 * This program is free software; you can redistribute it and/or
3008 * modify it under the terms of the GNU General Public License
3009@@ -21,397 +20,70 @@
3010 #ifndef METEORSHOWERS_HPP_
3011 #define METEORSHOWERS_HPP_
3012
3013-#include <QColor>
3014-
3015 #include "MeteorShower.hpp"
3016-#include "MeteorStream.hpp"
3017-#include "StelObjectModule.hpp"
3018-
3019-class MeteorShowerDialog;
3020-class QNetworkAccessManager;
3021-class QNetworkReply;
3022-class StelButton;
3023+#include "MeteorShowersMgr.hpp"
3024
3025 typedef QSharedPointer<MeteorShower> MeteorShowerP;
3026
3027-/*! @defgroup meteorShowers Meteor Showers Plug-in
3028-@{
3029-The %Meteor Showers plugin displays meteor showers and a marker for each
3030-active and inactive radiant, showing real information about its activity.
3031-
3032-<b>Configuration</b>
3033-
3034-The plug-ins' configuration data is stored in Stellarium's main configuration
3035-file (section [MeteorShowers]).
3036-
3037-@}
3038-*/
3039-
3040 //! @class MeteorShowers
3041-//! Main class of the %Meteor Showers plugin.
3042-//! @author Marcos Cardinot
3043+//! This class manages a collection of MeteorShower objects.
3044+//! It inherits from MeteorShowersMgr and is basically used to
3045+//! reimplement the methods defined in the StelObjectModule class.
3046+//! @author Marcos Cardinot <mcardinot@gmail.com>
3047 //! @ingroup meteorShowers
3048-class MeteorShowers : public StelObjectModule
3049+class MeteorShowers : public MeteorShowersMgr
3050 {
3051 Q_OBJECT
3052- Q_PROPERTY(bool msVisible READ getFlagShowMS WRITE setFlagShowMS)
3053- Q_PROPERTY(bool labelsVisible READ getFlagLabels WRITE setFlagLabels)
3054 public:
3055- //! @enum UpdateState
3056- //! Used for keeping track of the download/update status
3057- enum UpdateState
3058+ //! @struct SearchResult
3059+ typedef struct
3060 {
3061- Updating, //!< Update in progress
3062- CompleteNoUpdates, //!< Update completed, there we no updates
3063- CompleteUpdates, //!< Update completed, there were updates
3064- DownloadError, //!< Error during download phase
3065- OtherError //!< Other error
3066- };
3067-
3068- MeteorShowers();
3069+ QString name;
3070+ QString zhr;
3071+ QString type;
3072+ QDate peak;
3073+ } SearchResult;
3074+
3075+ //! Constructor
3076+ MeteorShowers(MeteorShowersMgr *mgr);
3077+
3078+ //! Destructor
3079 virtual ~MeteorShowers();
3080
3081- ///////////////////////////////////////////////////////////////////////////
3082- // Methods defined in the StelModule class
3083- virtual void init();
3084- //! called before the plug-in is un-loaded.
3085- //! Useful for stopping processes, unloading textures, etc.
3086- virtual void deinit();
3087- virtual void update(double deltaTime);
3088- virtual void draw(StelCore* core);
3089- virtual void drawMarker(StelCore* core, StelPainter& painter);
3090- virtual void drawPointer(StelCore* core, StelPainter& painter);
3091- virtual void drawStream(StelCore* core, StelPainter& painter);
3092- virtual double getCallOrder(StelModuleActionName actionName) const;
3093-
3094- ///////////////////////////////////////////////////////////////////////////
3095- // Methods defined in StelObjectManager class
3096- //! Used to get a list of objects which are near to some position.
3097- //! @param v a vector representing the position in th sky around which to search for nebulae.
3098- //! @param limitFov the field of view around the position v in which to search for satellites.
3099- //! @param core the StelCore to use for computations.
3100- //! @return an list containing the satellites located inside the limitFov circle around position v.
3101+ //! Update
3102+ //! @param deltaTime the time increment in seconds since the last call.
3103+ void update(StelCore *core, double deltaTime);
3104+
3105+ //! Draw
3106+ void draw(StelCore* core);
3107+
3108+ //! Loads all meteor showers contained in a QVariantMap.
3109+ //! @param map
3110+ void loadMeteorShowers(const QVariantMap& map);
3111+
3112+ //! Find all meteor_shower events in a given date interval
3113+ //! @param dateFrom
3114+ //! @param dateTo
3115+ //! @return list
3116+ QList<SearchResult> searchEvents(QDate dateFrom, QDate dateTo) const;
3117+
3118+ //
3119+ // Methods defined in StelObjectModule class
3120+ //
3121 virtual QList<StelObjectP> searchAround(const Vec3d& v, double limitFov, const StelCore* core) const;
3122-
3123- //! Return the matching satellite object's pointer if exists or NULL.
3124- //! @param nameI18n The case in-sensistive satellite name
3125 virtual StelObjectP searchByNameI18n(const QString& nameI18n) const;
3126-
3127- //! Return the matching satellite if exists or NULL.
3128- //! @param name The case in-sensistive standard program name
3129 virtual StelObjectP searchByName(const QString& name) const;
3130-
3131- //! Find and return the list of at most maxNbItem objects auto-completing the passed object I18n name.
3132- //! @param objPrefix the case insensitive first letters of the searched object
3133- //! @param maxNbItem the maximum number of returned object names
3134- //! @return a list of matching object name by order of relevance, or an empty list if nothing match
3135 virtual QStringList listMatchingObjectsI18n(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const;
3136 virtual QStringList listMatchingObjects(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const;
3137 virtual QStringList listAllObjects(bool inEnglish) const;
3138- virtual QStringList listAllObjectsByType(const QString& objType, bool inEnglish) const { Q_UNUSED(objType) Q_UNUSED(inEnglish) return QStringList(); }
3139- virtual QString getName() const
3140- {
3141- return "Meteor Showers";
3142- }
3143-
3144- //! get a ms object by identifier
3145- MeteorShowerP getByID(const QString& id);
3146-
3147- //! Implment this to tell the main Stellarium GUI that there is a GUI element to configure this
3148- //! plugin.
3149- virtual bool configureGui(bool show=true);
3150-
3151- //! Set up the plugin with default values. This means clearing out the MeteorShower section in the
3152- //! main config.ini (if one already exists), and populating it with default values. It also
3153- //! creates the default showers.json file from the resource embedded in the plugin lib/dll file.
3154- void restoreDefaults(void);
3155-
3156- //! Read (or re-read) settings from the main config file. This will be called from init and also
3157- //! when restoring defaults (i.e. from the configuration dialog / restore defaults button).
3158- void readSettingsFromConfig(void);
3159-
3160- //! Save the settings to the main configuration file.
3161- void saveSettingsToConfig(void);
3162-
3163- //! get whether or not the plugin will try to update TLE data from the internet
3164- //! @return true if updates are set to be done, false otherwise
3165- bool getUpdatesEnabled(void)
3166- {
3167- return updatesEnabled;
3168- }
3169- //! set whether or not the plugin will try to update TLE data from the internet
3170- //! @param b if true, updates will be enabled, else they will be disabled
3171- void setUpdatesEnabled(bool b)
3172- {
3173- updatesEnabled=b;
3174- }
3175-
3176- //! get the date and time the TLE elements were updated
3177- QDateTime getLastUpdate(void)
3178- {
3179- return lastUpdate;
3180- }
3181-
3182- //! get the update frequency in hours
3183- int getUpdateFrequencyHours(void)
3184- {
3185- return updateFrequencyHours;
3186- }
3187- void setUpdateFrequencyHours(int hours)
3188- {
3189- updateFrequencyHours = hours;
3190- }
3191-
3192- //! get the number of seconds till the next update
3193- int getSecondsToUpdate(void);
3194-
3195- //! Get the current updateState
3196- UpdateState getUpdateState(void)
3197- {
3198- return updateState;
3199- }
3200-
3201- //! Get current color of active radiant based in generic data
3202- QColor getColorARG()
3203- {
3204- return colorARG;
3205- }
3206- void setColorARG(QColor color)
3207- {
3208- colorARG = color;
3209- }
3210-
3211- //! Get current color of active radiant based in real data
3212- QColor getColorARR()
3213- {
3214- return colorARR;
3215- }
3216- void setColorARR(QColor color)
3217- {
3218- colorARR = color;
3219- }
3220-
3221- //! Get current inactive radiant color
3222- QColor getColorIR()
3223- {
3224- return colorIR;
3225- }
3226- void setColorIR(QColor color)
3227- {
3228- colorIR = color;
3229- }
3230-
3231- //! get the label font size.
3232- //! @return the pixel size of the font
3233- int getLabelFontSize()
3234- {
3235- return labelFont.pixelSize();
3236- }
3237-
3238- //! Get status of labels
3239- //! @return false: hidden
3240- bool getFlagLabels();
3241-
3242- //! Get current sky date.
3243- //! @return current sky date
3244- QDateTime getSkyDate()
3245- {
3246- return skyDate;
3247- }
3248-
3249- //! Find all meteor_shower events in a given date interval
3250- //! @param dateFrom
3251- //! @param dateTo
3252- //! @return meteor_shower list
3253- QList<MeteorShowerP> searchEvents(QDate dateFrom, QDate dateTo) const;
3254-
3255-signals:
3256- //! @param state the new update state.
3257- void updateStateChanged(MeteorShowers::UpdateState state);
3258-
3259- //! emitted after a JSON update has run.
3260- void jsonUpdateComplete(void);
3261-
3262-public slots:
3263- //! Download JSON from web recources described in the module section of the
3264- //! module.ini file and update the local JSON file.
3265- void updateJSON(void);
3266-
3267- void setFlagShowMS(bool b);
3268- bool getFlagShowMS(void) const;
3269-
3270- //! Display a message. This is used for plugin-specific warnings and such
3271- void displayMessage(const QString& message, const QString hexColor="#999999");
3272- void messageTimeout(void);
3273-
3274- //! Define whether the button toggling meteor showers should be visible
3275- void setFlagShowMSButton(bool b);
3276- bool getFlagShowMSButton(void) { return flagShowMSButton; }
3277-
3278- //! set the label font size.
3279- //! @param size the pixel size of the font
3280- void setLabelFontSize(int size);
3281-
3282- //! Set whether text labels should be displayed next to radiant.
3283- //! @param false: hidden
3284- void setFlagLabels(bool b);
3285-
3286- bool getFlagActiveRadiant(void)
3287- {
3288- return MeteorShower::showActiveRadiantsOnly;
3289- }
3290- void setFlagActiveRadiant(bool b)
3291- {
3292- MeteorShower::showActiveRadiantsOnly=b;
3293- }
3294-
3295- bool getEnableAtStartup(void) {return enableAtStartup;}
3296- void setEnableAtStartup(bool b) {enableAtStartup=b;}
3297-
3298- bool getFlagRadiant(void) const { return MeteorShower::radiantMarkerEnabled; }
3299- void setFlagRadiant(bool b) { MeteorShower::radiantMarkerEnabled=b; }
3300+ virtual QString getName() const { return "Meteor Showers"; }
3301
3302 private:
3303- // Upgrade config.ini: rename old key settings to new
3304- void upgradeConfigIni(void);
3305-
3306- //! Check if the sky date was changed
3307- //! @param core
3308- //! @return if changed, return true
3309- bool changedSkyDate(StelCore* core);
3310-
3311- //! Calculate value of ZHR using normal distribution
3312- //! @param zhr
3313- //! @param variable
3314- //! @param start
3315- //! @param finish
3316- //! @param peak
3317- int calculateZHR(int zhr, QString variable, QDateTime start, QDateTime finish, QDateTime peak);
3318-
3319- //! Update the list with information about active meteors
3320- //! @param core
3321- void updateActiveInfo(void);
3322-
3323- //! Set up the plugin with default values.
3324- void restoreDefaultConfigIni(void);
3325-
3326- //! replace the json file with the default from the compiled-in resource
3327- void restoreDefaultJsonFile(void);
3328-
3329- //! read the json file and create the meteor Showers.
3330- void readJsonFile(void);
3331-
3332- //! Creates a backup of the showers.json file called showers.json.old
3333- //! @param deleteOriginal if true, the original file is removed, else not
3334- //! @return true on OK, false on failure
3335- bool backupJsonFile(bool deleteOriginal=false);
3336-
3337- //! Get the version from the "version of format" value in the showers.json file
3338- //! @return version, e.g. "1"
3339- int getJsonFileFormatVersion(void);
3340-
3341- //! Check format of the catalog of meteor showers
3342- //! @return valid boolean, e.g. "true"
3343- bool checkJsonFileFormat(void);
3344-
3345- //! Parse JSON file and load showers to map
3346- QVariantMap loadShowersMap(QString path=QString());
3347-
3348- //! Set items for list of struct from data map
3349- void setShowersMap(const QVariantMap& map);
3350-
3351- //! A fake method for strings marked for translation.
3352- //! Use it instead of translations.h for N_() strings, except perhaps for
3353- //! keyboard action descriptions. (It's better for them to be in a single
3354- //! place.)
3355- static void translations();
3356-
3357- //! Font used for displaying our text
3358- QFont labelFont;
3359-
3360- QString showersJsonPath;
3361-
3362- StelTextureSP texPointer;
3363- QList<MeteorShowerP> mShowers;
3364-
3365- // GUI
3366- MeteorShowerDialog* configDialog;
3367- bool flagShowMS;
3368- bool flagShowMSButton;
3369- QPixmap* OnIcon;
3370- QPixmap* OffIcon;
3371- QPixmap* GlowIcon;
3372- StelButton* toolbarButton;
3373- QColor colorARR; //color of active radiant based on real data
3374- QColor colorARG; //color of active radiant based on generic data
3375- QColor colorIR; //color of inactive radiant
3376-
3377- // variables and functions for the updater
3378- UpdateState updateState;
3379- QNetworkAccessManager* downloadMgr;
3380- QString updateUrl;
3381- QString updateFile;
3382- class StelProgressController* progressBar;
3383- QTimer* updateTimer;
3384- QTimer* messageTimer;
3385- QList<int> messageIDs;
3386- bool updatesEnabled;
3387- QDateTime lastUpdate;
3388- int updateFrequencyHours;
3389- bool enableAtStartup;
3390-
3391- QSettings* conf;
3392-
3393- //MS
3394- std::vector<std::vector<MeteorStream*> > active; // Matrix containing all active meteors
3395- static const double zhrToWsr; // factor to convert from zhr to whole earth per second rate
3396-
3397- bool flagShowARG; //! Show marker of active radiant based on generic data
3398- bool flagShowARR; //! Show marker of active radiant based on generic data
3399- bool flagShowIR; //! Show marker of inactive radiant
3400-
3401- typedef struct
3402- {
3403- QString showerID; //! The ID of the meteor shower
3404- QDateTime start; //! First day for activity
3405- QDateTime finish; //! Latest day for activity
3406- QDateTime peak; //! Day with maximum for activity
3407- int status; //! 0:inactive 1:activeRealData 2:activeGenericData
3408- int zhr; //! ZHR of shower
3409- QString variable; //! value of variable for ZHR
3410- int speed; //! Speed of meteors
3411- float radiantAlpha; //! R.A. for radiant of meteor shower
3412- float radiantDelta; //! Dec. for radiant of meteor shower
3413- float pidx; //! Population index
3414- QList<MeteorShower::colorPair> colors; //! Population index
3415- } activeData;
3416-
3417- QList<activeData> activeInfo; //! List of active meteors
3418- QDateTime skyDate; //! Current sky date
3419- QDateTime lastSkyDate; //! Last sky date
3420-
3421-private slots:
3422- //! check to see if an update is required. This is called periodically by a timer
3423- //! if the last update was longer than updateFrequencyHours ago then the update is
3424- //! done.
3425- void checkForUpdate(void);
3426- void updateDownloadComplete(QNetworkReply* reply);
3427-};
3428-
3429-
3430-//#include "fixx11h.h"
3431-#include <QObject>
3432-#include "StelPluginInterface.hpp"
3433-
3434-//! This class is used by Qt to manage a plug-in interface
3435-class MeteorShowersStelPluginInterface : public QObject, public StelPluginInterface
3436-{
3437- Q_OBJECT
3438- Q_PLUGIN_METADATA(IID StelPluginInterface_iid)
3439- Q_INTERFACES(StelPluginInterface)
3440-public:
3441- virtual StelModule* getStelModule() const;
3442- virtual StelPluginInfo getPluginInfo() const;
3443+ MeteorShowersMgr* m_mgr;
3444+ QList<MeteorShowerP> m_meteorShowers;
3445+
3446+ //! Draw pointer
3447+ void drawPointer(StelCore* core);
3448 };
3449
3450 #endif /*METEORSHOWERS_HPP_*/
3451
3452=== added file 'plugins/MeteorShowers/src/MeteorShowersMgr.cpp'
3453--- plugins/MeteorShowers/src/MeteorShowersMgr.cpp 1970-01-01 00:00:00 +0000
3454+++ plugins/MeteorShowers/src/MeteorShowersMgr.cpp 2015-08-07 05:13:12 +0000
3455@@ -0,0 +1,611 @@
3456+/*
3457+ * Stellarium: Meteor Showers Plug-in
3458+ * Copyright (C) 2013-2015 Marcos Cardinot
3459+ *
3460+ * This program is free software; you can redistribute it and/or
3461+ * modify it under the terms of the GNU General Public License
3462+ * as published by the Free Software Foundation; either version 2
3463+ * of the License, or (at your option) any later version.
3464+ *
3465+ * This program is distributed in the hope that it will be useful,
3466+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3467+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3468+ * GNU General Public License for more details.
3469+ *
3470+ * You should have received a copy of the GNU General Public License
3471+ * along with this program; if not, write to the Free Software
3472+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
3473+ */
3474+
3475+#include <QDir>
3476+#include <QJsonDocument>
3477+#include <QSettings>
3478+#include <QTimer>
3479+
3480+#include "LabelMgr.hpp"
3481+#include "MSConfigDialog.hpp"
3482+#include "MSSearchDialog.hpp"
3483+#include "MeteorShowersMgr.hpp"
3484+#include "Planet.hpp"
3485+#include "StelActionMgr.hpp"
3486+#include "StelApp.hpp"
3487+#include "StelFileMgr.hpp"
3488+#include "StelGui.hpp"
3489+#include "StelModuleMgr.hpp"
3490+#include "StelProgressController.hpp"
3491+#include "StelTextureMgr.hpp"
3492+#include "StelUtils.hpp"
3493+#include "SporadicMeteorMgr.hpp"
3494+
3495+MeteorShowersMgr::MeteorShowersMgr()
3496+ : m_meteorShowers(NULL)
3497+ , m_configDialog(NULL)
3498+ , m_searchDialog(NULL)
3499+ , m_conf(StelApp::getInstance().getSettings())
3500+ , m_onEarth(false)
3501+ , m_enablePlugin(false)
3502+ , m_activeRadiantOnly(false)
3503+ , m_enableAtStartup(true)
3504+ , m_enableLabels(true)
3505+ , m_enableMarker(true)
3506+ , m_showEnableButton(true)
3507+ , m_showSearchButton(true)
3508+ , m_messageTimer(NULL)
3509+ , m_enableAutoUpdates(true)
3510+ , m_updateFrequencyHours(0)
3511+ , m_statusOfLastUpdate(OUTDATED)
3512+ , m_downloadMgr(NULL)
3513+ , m_progressBar(NULL)
3514+{
3515+ setObjectName("MeteorShowers");
3516+ qsrand(QDateTime::currentMSecsSinceEpoch());
3517+}
3518+
3519+MeteorShowersMgr::~MeteorShowersMgr()
3520+{
3521+ delete m_configDialog;
3522+ delete m_searchDialog;
3523+ delete m_downloadMgr;
3524+}
3525+
3526+void MeteorShowersMgr::init()
3527+{
3528+ loadTextures();
3529+
3530+ m_meteorShowers = new MeteorShowers(this);
3531+ m_configDialog = new MSConfigDialog(this);
3532+ m_searchDialog = new MSSearchDialog(this);
3533+
3534+ createActions();
3535+ loadConfig();
3536+
3537+ // timer to hide the alert messages
3538+ m_messageTimer = new QTimer(this);
3539+ m_messageTimer->setSingleShot(true);
3540+ m_messageTimer->setInterval(9000);
3541+ m_messageTimer->stop();
3542+ connect(m_messageTimer, SIGNAL(timeout()), this, SLOT(messageTimeout()));
3543+
3544+ // MeteorShowers directory
3545+ QString userDir = StelFileMgr::getUserDir() + "/modules/MeteorShowers";
3546+ StelFileMgr::makeSureDirExistsAndIsWritable(userDir);
3547+
3548+ // Loads the JSON catalog
3549+ m_catalogPath = userDir + "/showers.json";
3550+ if (!loadCatalog(m_catalogPath))
3551+ {
3552+ displayMessage(q_("The current catalog of Meteor Showers is invalid!"), "#bb0000");
3553+ restoreDefaultCatalog(m_catalogPath);
3554+ }
3555+
3556+ // Sets up the download manager
3557+ m_downloadMgr = new QNetworkAccessManager(this);
3558+ connect(m_downloadMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(updateFinished(QNetworkReply*)));
3559+
3560+ // every 5 min, check if it's time to update
3561+ QTimer* updateTimer = new QTimer(this);
3562+ updateTimer->setInterval(300000);
3563+ connect(updateTimer, SIGNAL(timeout()), this, SLOT(checkForUpdates()));
3564+ updateTimer->start();
3565+ checkForUpdates();
3566+
3567+ // always check if we are on Earth
3568+ StelCore* core = StelApp::getInstance().getCore();
3569+ m_onEarth = core->getCurrentPlanet().data()->getEnglishName() == "Earth";
3570+ connect(core, SIGNAL(locationChanged(StelLocation)),
3571+ this, SLOT(locationChanged(StelLocation)));
3572+
3573+ // enable at startup?
3574+ setEnablePlugin(getEnableAtStartup());
3575+}
3576+
3577+void MeteorShowersMgr::deinit()
3578+{
3579+ m_bolideTexture.clear();
3580+ m_radiantTexture.clear();
3581+ m_pointerTexture.clear();
3582+}
3583+
3584+double MeteorShowersMgr::getCallOrder(StelModuleActionName actionName) const
3585+{
3586+ if (actionName == StelModule::ActionDraw)
3587+ {
3588+ return GETSTELMODULE(SporadicMeteorMgr)->getCallOrder(actionName) + 10.;
3589+ }
3590+ return 0.;
3591+}
3592+
3593+bool MeteorShowersMgr::configureGui(bool show)
3594+{
3595+ if (show)
3596+ {
3597+ m_configDialog->setVisible(show);
3598+ }
3599+ return true;
3600+}
3601+
3602+void MeteorShowersMgr::createActions()
3603+{
3604+ QString msGroup = N_("Meteor Showers");
3605+ addAction("actionShow_MeteorShowers", msGroup, N_("Toggle meteor showers"), this, "enablePlugin", "Ctrl+Alt+M");
3606+ addAction("actionShow_MeteorShowers_labels", msGroup, N_("Toggle radiant labels"), this, "enableLabels", "Shift+M");
3607+ addAction("actionShow_MeteorShowers_config_dialog", msGroup, N_("Show settings dialog"), m_configDialog, "visible", "Ctrl+Shift+M");
3608+ addAction("actionShow_MeteorShowers_search_dialog", msGroup, N_("Show search dialog"), m_searchDialog, "visible", "Ctrl+Shift+S");
3609+}
3610+
3611+void MeteorShowersMgr::loadConfig()
3612+{
3613+ setActiveRadiantOnly(m_conf->value(MS_CONFIG_PREFIX + "/flag_active_radiant_only", true).toBool());
3614+ setShowEnableButton(m_conf->value(MS_CONFIG_PREFIX + "/show_enable_button", true).toBool());
3615+ setShowSearchButton(m_conf->value(MS_CONFIG_PREFIX + "/show_search_button", true).toBool());
3616+ setColorARG(StelUtils::strToVec3f(m_conf->value(MS_CONFIG_PREFIX + "/colorARG", "0,255,240").toString()));
3617+ setColorARC(StelUtils::strToVec3f(m_conf->value(MS_CONFIG_PREFIX + "/colorARC", "255,240,0").toString()));
3618+ setColorIR(StelUtils::strToVec3f(m_conf->value(MS_CONFIG_PREFIX + "/colorIR", "255,255,255").toString()));
3619+ setEnableAtStartup(m_conf->value(MS_CONFIG_PREFIX + "/enable_at_startup", true).toBool());
3620+ setFontSize(m_conf->value(MS_CONFIG_PREFIX + "/font_size", 13).toInt());
3621+ setEnableLabels(m_conf->value(MS_CONFIG_PREFIX + "/flag_radiant_labels", true).toBool());
3622+ setEnableMarker(m_conf->value(MS_CONFIG_PREFIX + "/flag_radiant_marker", true).toBool());
3623+ setUpdateFrequencyHours(m_conf->value(MS_CONFIG_PREFIX + "/update_frequency_hours", 720).toInt());
3624+ setEnableAutoUpdates(m_conf->value(MS_CONFIG_PREFIX + "/automatic_updates_enabled", true).toBool());
3625+ setUrl(m_conf->value(MS_CONFIG_PREFIX + "/url", "http://stellarium.org/json/showers.json").toString());
3626+ setLastUpdate(m_conf->value(MS_CONFIG_PREFIX + "/last_update", "2015-07-01T00:00:00").toDateTime());
3627+ setStatusOfLastUpdate(m_conf->value(MS_CONFIG_PREFIX + "/last_update_status", 0).toInt());
3628+}
3629+
3630+void MeteorShowersMgr::loadTextures()
3631+{
3632+ m_bolideTexture = StelApp::getInstance().getTextureManager().createTextureThread(
3633+ StelFileMgr::getInstallationDir() + "/textures/cometComa.png",
3634+ StelTexture::StelTextureParams(true, GL_LINEAR, GL_CLAMP_TO_EDGE));
3635+
3636+ m_pointerTexture = StelApp::getInstance().getTextureManager().createTexture(
3637+ StelFileMgr::getInstallationDir() + "/textures/pointeur5.png");
3638+
3639+ m_radiantTexture = StelApp::getInstance().getTextureManager().createTexture(
3640+ ":/MeteorShowers/radiant.png");
3641+}
3642+
3643+bool MeteorShowersMgr::loadCatalog(const QString& jsonPath)
3644+{
3645+ qDebug() << "MeteorShowersMgr: Loading catalog file:"
3646+ << QDir::toNativeSeparators(jsonPath);
3647+
3648+ QFile jsonFile(jsonPath);
3649+ if (!jsonFile.exists())
3650+ {
3651+ restoreDefaultCatalog(jsonPath);
3652+ }
3653+
3654+ if (!jsonFile.open(QIODevice::ReadOnly))
3655+ {
3656+ qWarning() << "MeteorShowersMgr: Cannot to open the catalog file!";
3657+ return false;
3658+ }
3659+
3660+ QJsonObject json(QJsonDocument::fromJson(jsonFile.readAll()).object());
3661+ jsonFile.close();
3662+
3663+ if (json["shortName"].toString() != "meteor showers data"
3664+ || json["version"].toInt() != MS_CATALOG_VERSION)
3665+ {
3666+ qWarning() << "MeteorShowersMgr: The current catalog is not compatible!";
3667+ return false;
3668+ }
3669+
3670+ QVariantMap map = json["showers"].toObject().toVariantMap();
3671+ m_meteorShowers->loadMeteorShowers(map);
3672+
3673+ return true;
3674+}
3675+
3676+void MeteorShowersMgr::restoreDefaultSettings()
3677+{
3678+ qDebug() << "MeteorShowersMgr: Restoring default settings";
3679+ m_conf->beginGroup(MS_CONFIG_PREFIX);
3680+ m_conf->remove("");
3681+ m_conf->endGroup();
3682+ loadConfig();
3683+ restoreDefaultCatalog(m_catalogPath);
3684+ m_configDialog->init();
3685+}
3686+
3687+bool MeteorShowersMgr::restoreDefaultCatalog(const QString& destination)
3688+{
3689+ qDebug() << "MeteorShowersMgr: Trying to restore the default catalog to"
3690+ << QDir::toNativeSeparators(destination);
3691+
3692+ QFile d(destination);
3693+ if (d.exists() && !d.remove())
3694+ {
3695+ qWarning() << "MeteorShowersMgr: Cannot remove the current catalog file!";
3696+ return false;
3697+ }
3698+
3699+ QFile defaultJson(":/MeteorShowers/showers.json");
3700+ if (!defaultJson.copy(destination))
3701+ {
3702+ qWarning() << "MeteorShowersMgr: Cannot copy the default catalog!";
3703+ return false;
3704+ }
3705+
3706+ // The resource is read only, and the new file inherits this... make sure the
3707+ // new file is writable by the Stellarium process so that updates can be done.
3708+ QFile dest(destination);
3709+ dest.setPermissions(dest.permissions() | QFile::WriteOwner);
3710+
3711+ setLastUpdate(QDateTime::fromString("2015-07-01T00:00:00"));
3712+
3713+ qDebug() << "MeteorShowersMgr: The default catalog was copied!";
3714+ displayMessage(q_("Using the default Meteor Showers catalog."), "#bb0000");
3715+
3716+ return true;
3717+}
3718+
3719+void MeteorShowersMgr::update(double deltaTime)
3720+{
3721+ if (!m_enablePlugin || !m_onEarth)
3722+ {
3723+ return;
3724+ }
3725+
3726+ StelCore* core = StelApp::getInstance().getCore();
3727+
3728+ // is paused?
3729+ // freeze meteors at the current position
3730+ if (!core->getTimeRate()) {
3731+ return;
3732+ }
3733+
3734+ // is GUI visible? refresh dates
3735+ if (m_searchDialog->visible())
3736+ {
3737+ m_searchDialog->refreshRangeDates();
3738+ }
3739+
3740+ m_meteorShowers->update(core, deltaTime);
3741+}
3742+
3743+void MeteorShowersMgr::draw(StelCore* core)
3744+{
3745+ if (m_enablePlugin && m_onEarth)
3746+ {
3747+ m_meteorShowers->draw(core);
3748+ }
3749+}
3750+
3751+void MeteorShowersMgr::repaint()
3752+{
3753+ update(1.0);
3754+ draw(StelApp::getInstance().getCore());
3755+}
3756+
3757+void MeteorShowersMgr::checkForUpdates()
3758+{
3759+ if (m_enableAutoUpdates && m_lastUpdate.addSecs(m_updateFrequencyHours * 3600.) <= QDateTime::currentDateTime())
3760+ {
3761+ updateCatalog();
3762+ }
3763+}
3764+
3765+void MeteorShowersMgr::updateCatalog()
3766+{
3767+ if (m_statusOfLastUpdate == UPDATING)
3768+ {
3769+ qWarning() << "MeteorShowersMgr: The catalog is being updated already!";
3770+ return;
3771+ }
3772+
3773+ qDebug() << "MeteorShowersMgr: Starting to update the catalog...";
3774+ setStatusOfLastUpdate(UPDATING);
3775+
3776+ setLastUpdate(QDateTime::currentDateTime());
3777+
3778+ m_progressBar = StelApp::getInstance().addProgressBar();
3779+ m_progressBar->setValue(0);
3780+ m_progressBar->setRange(0, 100);
3781+ m_progressBar->setFormat("Meteor Showers Catalog");
3782+
3783+ QNetworkRequest request;
3784+ request.setUrl(QUrl(m_url));
3785+ request.setRawHeader("User-Agent", QString("Mozilla/5.0 (Stellarium Meteor Showers Plugin %1; http://stellarium.org/)").arg(METEORSHOWERS_PLUGIN_VERSION).toUtf8());
3786+ m_downloadMgr->get(request);
3787+}
3788+
3789+void MeteorShowersMgr::updateFinished(QNetworkReply* reply)
3790+{
3791+ if (m_progressBar)
3792+ {
3793+ m_progressBar->setValue(100);
3794+ StelApp::getInstance().removeProgressBar(m_progressBar);
3795+ m_progressBar = NULL;
3796+ }
3797+
3798+ if (reply->error() != QNetworkReply::NoError)
3799+ {
3800+ qWarning() << "MeteorShowersMgr: Failed to download!" << reply->url();
3801+ qWarning() << "MeteorShowersMgr: Error " << reply->errorString();
3802+ setStatusOfLastUpdate(FAILED);
3803+ return;
3804+ }
3805+
3806+ QString tempPath(m_catalogPath + "_new.json");
3807+ QFile newCatalog(tempPath);
3808+ newCatalog.remove(); // always overwrites
3809+ if (!newCatalog.open(QIODevice::ReadWrite | QIODevice::Text))
3810+ {
3811+ qWarning() << "MeteorShowersMgr: Cannot write the downloaded catalog!";
3812+ setStatusOfLastUpdate(FAILED);
3813+ return;
3814+ }
3815+
3816+ newCatalog.write(reply->readAll());
3817+ newCatalog.close();
3818+
3819+ if (!loadCatalog(tempPath))
3820+ {
3821+ setStatusOfLastUpdate(FAILED);
3822+ return;
3823+ }
3824+
3825+ QFile(m_catalogPath).remove();
3826+ newCatalog.rename(tempPath.remove("_new.json"));
3827+
3828+ qDebug() << "MeteorShowersMgr: The catalog was updated!";
3829+ setStatusOfLastUpdate(UPDATED);
3830+}
3831+
3832+void MeteorShowersMgr::setEnablePlugin(const bool& b)
3833+{
3834+ // we should never change the 'm_enablePlugin' member directly!
3835+ // as it's a button on the toolbar, it must be sync with its StelAction
3836+ StelActionMgr* actionMgr = StelApp::getInstance().getStelActionManager();
3837+ StelAction* action = actionMgr->findAction("actionShow_MeteorShowers");
3838+ action->setChecked(b);
3839+}
3840+
3841+void MeteorShowersMgr::setActiveRadiantOnly(const bool& b)
3842+{
3843+ m_activeRadiantOnly = b;
3844+ m_conf->setValue(MS_CONFIG_PREFIX + "/flag_active_radiant_only", b);
3845+}
3846+
3847+void MeteorShowersMgr::setShowEnableButton(const bool& show)
3848+{
3849+ try
3850+ {
3851+ StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
3852+ if (!gui)
3853+ {
3854+ return;
3855+ }
3856+
3857+ if (show)
3858+ {
3859+ StelButton* enablePlugin = new StelButton(NULL,
3860+ QPixmap(":/MeteorShowers/btMS-on.png"),
3861+ QPixmap(":/MeteorShowers/btMS-off.png"),
3862+ QPixmap(":/graphicGui/glow32x32.png"),
3863+ "actionShow_MeteorShowers");
3864+ gui->getButtonBar()->addButton(enablePlugin, "065-pluginsGroup");
3865+ }
3866+ else
3867+ {
3868+ gui->getButtonBar()->hideButton("actionShow_MeteorShowers");
3869+ }
3870+ }
3871+ catch (std::runtime_error& e)
3872+ {
3873+ qWarning() << "MeteorShowersMgr : unable to create toolbar buttons for MeteorShowers plugin!"
3874+ << e.what();
3875+ }
3876+ m_showEnableButton = show;
3877+ m_conf->setValue(MS_CONFIG_PREFIX + "/show_enable_button", show);
3878+}
3879+
3880+void MeteorShowersMgr::setShowSearchButton(const bool& show)
3881+{
3882+ try
3883+ {
3884+ StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
3885+ if (!gui)
3886+ {
3887+ return;
3888+ }
3889+
3890+ if (show)
3891+ {
3892+ StelButton* searchMS = new StelButton(NULL,
3893+ QPixmap(":/MeteorShowers/btMS-search-on.png"),
3894+ QPixmap(":/MeteorShowers/btMS-search-off.png"),
3895+ QPixmap(":/graphicGui/glow32x32.png"),
3896+ "actionShow_MeteorShowers_search_dialog");
3897+ gui->getButtonBar()->addButton(searchMS, "065-pluginsGroup");
3898+ }
3899+ else
3900+ {
3901+ gui->getButtonBar()->hideButton("actionShow_MeteorShowers_search_dialog");
3902+ }
3903+ }
3904+ catch (std::runtime_error& e)
3905+ {
3906+ qWarning() << "MeteorShowersMgr : unable to create toolbar buttons for MeteorShowers plugin!"
3907+ << e.what();
3908+ }
3909+ m_showSearchButton = show;
3910+ m_conf->setValue(MS_CONFIG_PREFIX + "/show_search_button", show);
3911+}
3912+
3913+void MeteorShowersMgr::setColorARG(const Vec3f& rgb)
3914+{
3915+ m_colorARG = rgb;
3916+ QString rgbStr = QString("%1,%2,%3").arg(rgb[0]).arg(rgb[1]).arg(rgb[2]);
3917+ m_conf->setValue(MS_CONFIG_PREFIX + "/colorARG", rgbStr);
3918+}
3919+
3920+void MeteorShowersMgr::setColorARC(const Vec3f& rgb)
3921+{
3922+ m_colorARC = rgb;
3923+ QString rgbStr = QString("%1,%2,%3").arg(rgb[0]).arg(rgb[1]).arg(rgb[2]);
3924+ m_conf->setValue(MS_CONFIG_PREFIX + "/colorARC", rgbStr);
3925+}
3926+
3927+void MeteorShowersMgr::setColorIR(const Vec3f& rgb)
3928+{
3929+ m_colorIR = rgb;
3930+ QString rgbStr = QString("%1,%2,%3").arg(rgb[0]).arg(rgb[1]).arg(rgb[2]);
3931+ m_conf->setValue(MS_CONFIG_PREFIX + "/colorIR", rgbStr);
3932+}
3933+
3934+void MeteorShowersMgr::setEnableAtStartup(const bool& b)
3935+{
3936+ m_enableAtStartup = b;
3937+ m_conf->setValue(MS_CONFIG_PREFIX + "/enable_at_startup", b);
3938+}
3939+
3940+void MeteorShowersMgr::setFontSize(int pixelSize)
3941+{
3942+ pixelSize = pixelSize < 1 ? 13 : pixelSize;
3943+ m_font.setPixelSize(pixelSize);
3944+ m_conf->setValue(MS_CONFIG_PREFIX + "/font_size", pixelSize);
3945+}
3946+
3947+void MeteorShowersMgr::setEnableLabels(const bool& b)
3948+{
3949+ m_enableLabels = b;
3950+ m_conf->setValue(MS_CONFIG_PREFIX + "/flag_radiant_labels", b);
3951+}
3952+
3953+void MeteorShowersMgr::setEnableMarker(const bool& b)
3954+{
3955+ m_enableMarker = b;
3956+ m_conf->setValue(MS_CONFIG_PREFIX + "/flag_radiant_marker", b);
3957+}
3958+
3959+void MeteorShowersMgr::setUpdateFrequencyHours(const int& hours)
3960+{
3961+ m_updateFrequencyHours = hours;
3962+ m_conf->setValue(MS_CONFIG_PREFIX + "/update_frequency_hours", hours);
3963+}
3964+
3965+void MeteorShowersMgr::setEnableAutoUpdates(const bool& b)
3966+{
3967+ m_enableAutoUpdates = b;
3968+ m_conf->setValue(MS_CONFIG_PREFIX + "/automatic_updates_enabled", b);
3969+}
3970+
3971+void MeteorShowersMgr::setUrl(const QString& url)
3972+{
3973+ m_url = url;
3974+ m_conf->setValue(MS_CONFIG_PREFIX + "/url", url);
3975+}
3976+
3977+void MeteorShowersMgr::setLastUpdate(const QDateTime &datetime)
3978+{
3979+ m_lastUpdate = datetime;
3980+ m_conf->setValue(MS_CONFIG_PREFIX + "/last_update", m_lastUpdate.toString(Qt::ISODate));
3981+}
3982+
3983+void MeteorShowersMgr::setStatusOfLastUpdate(const int &downloadStatus)
3984+{
3985+ m_statusOfLastUpdate = (DownloadStatus) downloadStatus;
3986+ if (m_statusOfLastUpdate != UPDATING)
3987+ {
3988+ m_conf->setValue(MS_CONFIG_PREFIX + "/last_update_status", downloadStatus);
3989+ }
3990+ emit(downloadStatusChanged(m_statusOfLastUpdate));
3991+}
3992+
3993+QDateTime MeteorShowersMgr::getNextUpdate()
3994+{
3995+ return m_lastUpdate.addSecs(m_updateFrequencyHours * 3600);
3996+}
3997+
3998+void MeteorShowersMgr::displayMessage(const QString& message, const QString hexColor)
3999+{
4000+ m_messageIDs << GETSTELMODULE(LabelMgr)->labelScreen(message, 30, 30 + (20 * m_messageIDs.count()), true, 16, hexColor);
4001+ m_messageTimer->start();
4002+}
4003+
4004+void MeteorShowersMgr::messageTimeout()
4005+{
4006+ foreach(int i, m_messageIDs)
4007+ {
4008+ GETSTELMODULE(LabelMgr)->deleteLabel(i);
4009+ }
4010+}
4011+
4012+void MeteorShowersMgr::locationChanged(StelLocation location)
4013+{
4014+ m_onEarth = location.planetName == "Earth";
4015+}
4016+
4017+/////////////////////////////////////////////////////////////////////////////////////////
4018+
4019+StelModule* MeteorShowersStelPluginInterface::getStelModule() const
4020+{
4021+ return new MeteorShowersMgr();
4022+}
4023+
4024+StelPluginInfo MeteorShowersStelPluginInterface::getPluginInfo() const
4025+{
4026+ // Allow to load the resources when used as a static plugin
4027+ Q_INIT_RESOURCE(MeteorShower);
4028+
4029+ StelPluginInfo info;
4030+ info.id = "MeteorShowers";
4031+ info.displayedName = N_("Meteor Showers");
4032+ info.authors = "Marcos Cardinot";
4033+ info.contact = "mcardinot@gmail.com";
4034+ info.description =
4035+ "<p>"
4036+ N_("This plugin enables you to simulate periodic meteor showers and "
4037+ "to display a marker for each active and inactive radiant.")
4038+ "</p>"
4039+ N_("By a single click on the radiant's marker, you can see all the "
4040+ "details about its position and activity. Most data used on this "
4041+ "plugin comes from the oficial <a href=\"http://imo.net\">International "
4042+ "Meteor Organization</a> catalog.")
4043+ "</p>"
4044+ N_("It has three types of markers:")
4045+ "<ul>"
4046+ "<li>"
4047+ "<b>" N_("Confirmed:") "</b> "
4048+ N_("the radiant is active and its data was confirmed."
4049+ " Thus, this is a historical (really occurred in the past) or predicted"
4050+ " meteor shower.")
4051+ "</li>"
4052+ "<li>"
4053+ "<b>" N_("Generic:") "</b> "
4054+ N_("the radiant is active, but its data was not confirmed."
4055+ " It means that this can occur on real life, but that we do not have real"
4056+ " data about its activity for the current sky year.")
4057+ "</li>"
4058+ "<li>"
4059+ "<b>" N_("Inactive:") "</b> "
4060+ N_("the radiant is inactive for the current sky date.")
4061+ "</li>"
4062+ "</ul>"
4063+ "</p>";
4064+ info.version = METEORSHOWERS_PLUGIN_VERSION;
4065+ return info;
4066+}
4067
4068=== added file 'plugins/MeteorShowers/src/MeteorShowersMgr.hpp'
4069--- plugins/MeteorShowers/src/MeteorShowersMgr.hpp 1970-01-01 00:00:00 +0000
4070+++ plugins/MeteorShowers/src/MeteorShowersMgr.hpp 2015-08-07 05:13:12 +0000
4071@@ -0,0 +1,288 @@
4072+/*
4073+ * Stellarium: Meteor Showers Plug-in
4074+ * Copyright (C) 2013-2015 Marcos Cardinot
4075+ *
4076+ * This program is free software; you can redistribute it and/or
4077+ * modify it under the terms of the GNU General Public License
4078+ * as published by the Free Software Foundation; either version 2
4079+ * of the License, or (at your option) any later version.
4080+ *
4081+ * This program is distributed in the hope that it will be useful,
4082+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4083+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4084+ * GNU General Public License for more details.
4085+ *
4086+ * You should have received a copy of the GNU General Public License
4087+ * along with this program; if not, write to the Free Software
4088+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
4089+ */
4090+
4091+#ifndef METEORSHOWERSMGR_HPP_
4092+#define METEORSHOWERSMGR_HPP_
4093+
4094+#include <QNetworkReply>
4095+
4096+#include "StelGuiItems.hpp"
4097+#include "StelObjectModule.hpp"
4098+
4099+#define MS_CATALOG_VERSION 1
4100+#define MS_CONFIG_PREFIX QString("MeteorShowers")
4101+
4102+class MeteorShowers;
4103+class MSConfigDialog;
4104+class MSSearchDialog;
4105+
4106+/*! @defgroup meteorShowers Meteor Showers Plug-in
4107+@{
4108+The %Meteor Showers plugin displays meteor showers and a marker for each
4109+active and inactive radiant, showing real information about its activity.
4110+
4111+<b>Configuration</b>
4112+
4113+The plug-ins' configuration data is stored in Stellarium's main configuration
4114+file (section [MeteorShowers]).
4115+
4116+@}
4117+*/
4118+
4119+//! @class MeteorShowersMgr
4120+//! Main class of the %Meteor Showers plugin, inherits from StelObjectModule.
4121+//! @author Marcos Cardinot <mcardinot@gmail.com>
4122+//! @ingroup meteorShowers
4123+class MeteorShowersMgr : public StelObjectModule
4124+{
4125+ Q_OBJECT
4126+ Q_PROPERTY(bool enablePlugin READ getEnablePlugin WRITE actionEnablePlugin)
4127+ Q_PROPERTY(bool enableLabels READ getEnableLabels WRITE setEnableLabels)
4128+
4129+public:
4130+ //! @enum DownloadStatus
4131+ enum DownloadStatus {
4132+ OUTDATED,
4133+ UPDATING,
4134+ UPDATED,
4135+ FAILED
4136+ };
4137+
4138+ //! Constructor.
4139+ MeteorShowersMgr();
4140+
4141+ //! Destructor.
4142+ virtual ~MeteorShowersMgr();
4143+
4144+ //! Restore default catalog.
4145+ bool restoreDefaultCatalog(const QString& destination);
4146+
4147+ //! Gets the bolide texture.
4148+ //! @return texture
4149+ StelTextureSP getBolideTexture() { return m_bolideTexture; }
4150+
4151+ //! Gets the pointer texture.
4152+ //! @return texture
4153+ StelTextureSP getPointerTexture() { return m_pointerTexture; }
4154+
4155+ //! Gets the radiant texture
4156+ //! @return texture
4157+ StelTextureSP getRadiantTexture() { return m_radiantTexture; }
4158+
4159+ //! Gets the MeteorShowers instance
4160+ //! @return MeteorShowers instance
4161+ MeteorShowers* getMeteorShowers() { return m_meteorShowers; }
4162+
4163+ //! Enable/disable the meteor showers plugin.
4164+ void setEnablePlugin(const bool& b);
4165+ bool getEnablePlugin() { return m_enablePlugin; }
4166+
4167+ //! True if user wants to see the active radiants only.
4168+ bool getActiveRadiantOnly() { return m_activeRadiantOnly; }
4169+
4170+ //! Get the status of the enable button on the toolbar.
4171+ //! @return true if it's visible
4172+ bool getShowEnableButton() { return m_showEnableButton; }
4173+
4174+ //! Get the status of the search button on the toolbar.
4175+ //! @return true if it's visible
4176+ bool getShowSearchButton() { return m_showSearchButton; }
4177+
4178+ //! Set the color of the active radiant based on generic data.
4179+ void setColorARG(const Vec3f& rgb);
4180+ Vec3f getColorARG() { return m_colorARG; }
4181+
4182+ //! Set the color of the active radiant based on confirmed data.
4183+ void setColorARC(const Vec3f& rgb);
4184+ Vec3f getColorARC() { return m_colorARC; }
4185+
4186+ //! Set the color of the inactive radiant.
4187+ void setColorIR(const Vec3f& rgb);
4188+ Vec3f getColorIR() { return m_colorIR; }
4189+
4190+ //! True if the plugin is enabled at Stellarium startup.
4191+ bool getEnableAtStartup() { return m_enableAtStartup; }
4192+
4193+ //! Set the font size (used on radiant labels).
4194+ int getFontSize() { return m_font.pixelSize(); }
4195+
4196+ //! Get the font.
4197+ QFont getFont() { return m_font; }
4198+
4199+ //! Enable/disable radiant labels
4200+ bool getEnableLabels() { return m_enableLabels; }
4201+
4202+ //! Enable/disable radiant marker.
4203+ bool getEnableMarker() { return m_enableMarker; }
4204+
4205+ //! Gets the update frequency in hours.
4206+ int getUpdateFrequencyHours() { return m_updateFrequencyHours; }
4207+
4208+ //! Enable/disable catalog updates from the internet.
4209+ bool getEnableAutoUpdates() { return m_enableAutoUpdates; }
4210+
4211+ //! Set the URL for downloading the meteor showers catalog.
4212+ void setUrl(const QString& url);
4213+ QString getUrl() { return m_url; }
4214+
4215+ //! Set the date and time of last update.
4216+ void setLastUpdate(const QDateTime& datetime);
4217+ QDateTime getLastUpdate() { return m_lastUpdate; }
4218+
4219+ //! Set the status of the last update
4220+ void setStatusOfLastUpdate(const int &downloadStatus);
4221+ DownloadStatus getStatusOfLastUpdate() { return m_statusOfLastUpdate; }
4222+
4223+ //! Gets the date of the next update.
4224+ QDateTime getNextUpdate();
4225+
4226+ //! It's useful to force the update() and draw().
4227+ void repaint();
4228+
4229+ //
4230+ // Methods defined in the StelModule class
4231+ //
4232+ virtual void init();
4233+ virtual void deinit();
4234+ virtual void update(double deltaTime);
4235+ virtual void draw(StelCore* core);
4236+ virtual double getCallOrder(StelModuleActionName actionName) const;
4237+ virtual bool configureGui(bool show=true);
4238+
4239+ //
4240+ // Methods defined in StelObjectModule class
4241+ //
4242+ virtual QList<StelObjectP> searchAround(const Vec3d& v, double limitFov, const StelCore* core) const { return QList<StelObjectP>();}
4243+ virtual StelObjectP searchByNameI18n(const QString& nameI18n) const { return StelObjectP();}
4244+ virtual StelObjectP searchByName(const QString& name) const { return StelObjectP();}
4245+ virtual QStringList listMatchingObjectsI18n(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const { return QStringList();}
4246+ virtual QStringList listMatchingObjects(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const { return QStringList();}
4247+ virtual QStringList listAllObjects(bool inEnglish) const { return QStringList();}
4248+ virtual QStringList listAllObjectsByType(const QString& objType, bool inEnglish) const { Q_UNUSED(objType) Q_UNUSED(inEnglish) return QStringList(); }
4249+ virtual QString getName() const { return QString();}
4250+
4251+signals:
4252+ void downloadStatusChanged(DownloadStatus);
4253+
4254+public slots:
4255+ //! Enable the meteor showers plugin at Stellarium startup.
4256+ void setEnableAtStartup(const bool& b);
4257+
4258+ //! Show/hide the button that enable/disable the meteor showers plugin.
4259+ void setShowEnableButton(const bool& show);
4260+
4261+ //! Show/hide the button that opens the search dialog.
4262+ void setShowSearchButton(const bool& show);
4263+
4264+ //! Enable/disable radiant marker.
4265+ void setEnableMarker(const bool& b);
4266+
4267+ //! True if user wants to see the active radiants only.
4268+ void setActiveRadiantOnly(const bool& b);
4269+
4270+ //! Enable/disable radiant labels
4271+ void setEnableLabels(const bool& b);
4272+
4273+ //! Set the font size (used on radiant labels).
4274+ void setFontSize(int pixelSize);
4275+
4276+ //! Set the update frequency in hours.
4277+ void setUpdateFrequencyHours(const int& hours);
4278+
4279+ //! Enable/disable automatic catalog updates from the internet.
4280+ void setEnableAutoUpdates(const bool& b);
4281+
4282+ //! Download the Meteor Showers catalog from the Internet.
4283+ void updateCatalog();
4284+
4285+ //! Restore default settings.
4286+ void restoreDefaultSettings();
4287+
4288+ //! Display a message. This is used for plugin-specific warnings and such
4289+ void displayMessage(const QString& message, const QString hexColor="#999999");
4290+ void messageTimeout();
4291+
4292+private slots:
4293+ void checkForUpdates();
4294+ void updateFinished(QNetworkReply* reply);
4295+ void locationChanged(StelLocation location);
4296+
4297+private:
4298+ MeteorShowers* m_meteorShowers;
4299+ MSConfigDialog* m_configDialog;
4300+ MSSearchDialog* m_searchDialog;
4301+
4302+ QFont m_font;
4303+ QSettings* m_conf;
4304+ QString m_catalogPath;
4305+
4306+ bool m_onEarth;
4307+ bool m_enablePlugin;
4308+ bool m_activeRadiantOnly;
4309+ bool m_enableAtStartup;
4310+ bool m_enableLabels;
4311+ bool m_enableMarker;
4312+ bool m_showEnableButton;
4313+ bool m_showSearchButton;
4314+
4315+ Vec3f m_colorARG; //! color of active radiant based on generic data
4316+ Vec3f m_colorARC; //! color of active radiant based on confirmed data
4317+ Vec3f m_colorIR; //! color of inactive radiant
4318+
4319+ QTimer* m_messageTimer;
4320+ QList<int> m_messageIDs;
4321+
4322+ StelTextureSP m_bolideTexture; //! Meteor bolide texture
4323+ StelTextureSP m_pointerTexture; //! Pointer texture
4324+ StelTextureSP m_radiantTexture; //! Radiant texture
4325+
4326+ bool m_isUpdating;
4327+ bool m_enableAutoUpdates;
4328+ int m_updateFrequencyHours;
4329+ QString m_url;
4330+ QDateTime m_lastUpdate;
4331+ DownloadStatus m_statusOfLastUpdate;
4332+ QNetworkAccessManager* m_downloadMgr;
4333+ class StelProgressController* m_progressBar;
4334+
4335+ void createActions();
4336+ void loadConfig();
4337+ void loadTextures();
4338+ bool loadCatalog(const QString& jsonPath);
4339+
4340+ //! Enable/disable the Meteor Showers plugin.
4341+ //! It'll be triggered by a StelAction! So, it should NOT be called directly!
4342+ void actionEnablePlugin(const bool& b) { m_enablePlugin = b; }
4343+};
4344+
4345+#include <QObject>
4346+#include "StelPluginInterface.hpp"
4347+
4348+//! This class is used by Qt to manage a plug-in interface
4349+class MeteorShowersStelPluginInterface : public QObject, public StelPluginInterface
4350+{
4351+ Q_OBJECT
4352+ Q_PLUGIN_METADATA(IID StelPluginInterface_iid)
4353+ Q_INTERFACES(StelPluginInterface)
4354+public:
4355+ virtual StelModule* getStelModule() const;
4356+ virtual StelPluginInfo getPluginInfo() const;
4357+};
4358+
4359+#endif /*METEORSHOWERSMGR_HPP_*/
4360
4361=== removed file 'plugins/MeteorShowers/src/MeteorStream.cpp'
4362--- plugins/MeteorShowers/src/MeteorStream.cpp 2015-03-22 09:33:56 +0000
4363+++ plugins/MeteorShowers/src/MeteorStream.cpp 1970-01-01 00:00:00 +0000
4364@@ -1,128 +0,0 @@
4365-/*
4366- * Stellarium: Meteor Showers Plug-in
4367- * Copyright (C) 2013 Marcos Cardinot
4368- *
4369- * This program is free software; you can redistribute it and/or
4370- * modify it under the terms of the GNU General Public License
4371- * as published by the Free Software Foundation; either version 2
4372- * of the License, or (at your option) any later version.
4373- *
4374- * This program is distributed in the hope that it will be useful,
4375- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4376- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4377- * GNU General Public License for more details.
4378- *
4379- * You should have received a copy of the GNU General Public License
4380- * along with this program; if not, write to the Free Software
4381- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
4382- */
4383-
4384-#include "MeteorShowers.hpp"
4385-#include "MeteorStream.hpp"
4386-
4387-MeteorStream::MeteorStream(const StelCore* core,
4388- int speed,
4389- float radiantAlpha,
4390- float radiantDelta,
4391- float pidx,
4392- QList<MeteorShower::colorPair> colors)
4393- : m_speed(speed)
4394- , m_segments(10)
4395-{
4396- qsrand (QDateTime::currentMSecsSinceEpoch());
4397- // if speed is zero, use a random value
4398- if (!speed)
4399- {
4400- m_speed = 11+(double)qrand()/((double)RAND_MAX+1)*61; // abs range 11-72 km/s
4401- }
4402-
4403- // view matrix of meteor model
4404- m_viewMatrix = Mat4d::zrotation(radiantAlpha) * Mat4d::yrotation(M_PI_2 - radiantDelta);
4405-
4406- // building meteor model
4407- m_alive = Meteor::initMeteorModel(core, m_segments, m_viewMatrix, meteor);
4408- if (!m_alive)
4409- {
4410- return;
4411- }
4412-
4413- // implements the population index
4414- float oneMag = -0.2; // negative, working in different scale ( 0 to 1 - where 1 is brighter)
4415- if (pidx) // is not zero
4416- {
4417- if (qrand()%100 < 100.f/pidx) // probability
4418- {
4419- meteor.mag += oneMag; // (m+1)
4420- }
4421- }
4422-
4423- // determine the meteor color
4424- if (colors.isEmpty()) {
4425- colors.push_back(MeteorShower::colorPair("white", 100));
4426- } else {
4427- // handle cases when the total intensity is less than 100
4428- int totalIntensity = 0;
4429- int indexWhite = -1;
4430- for (int i=0; i<colors.size(); i++) {
4431- totalIntensity += colors.at(i).second;
4432- if (colors.at(i).first == "white") {
4433- indexWhite = i;
4434- }
4435- }
4436-
4437- int increaseWhite = 0;
4438- if (totalIntensity > 100) {
4439- qDebug() << "MeteorShowers plugin (showers.json): Total intensity must be less than 100";
4440- colors.clear();
4441- colors.push_back(MeteorShower::colorPair("white", 100));
4442- } else {
4443- increaseWhite = 100 - totalIntensity;
4444- }
4445-
4446- if (increaseWhite > 0) {
4447- if (indexWhite == -1) {
4448- colors.push_back(MeteorShower::colorPair("white", increaseWhite));
4449- } else {
4450- colors[indexWhite].second = increaseWhite;
4451- }
4452- }
4453- }
4454-
4455- // building lineColorArray and trainColorArray
4456- Meteor::buildColorArrays(m_segments, colors, m_lineColorArray, m_trainColorArray);
4457-}
4458-
4459-MeteorStream::~MeteorStream()
4460-{
4461-}
4462-
4463-// returns true if alive
4464-bool MeteorStream::update(double deltaTime)
4465-{
4466- if (!m_alive)
4467- {
4468- return false;
4469- }
4470-
4471- m_alive = Meteor::updateMeteorModel(deltaTime, m_speed, meteor);
4472-
4473- return m_alive;
4474-}
4475-
4476-// returns true if visible
4477-// Assumes that we are in local frame
4478-void MeteorStream::draw(const StelCore* core, StelPainter& sPainter)
4479-{
4480- if (!m_alive)
4481- {
4482- return;
4483- }
4484-
4485- float thickness, bolideSize;
4486- Meteor::calculateThickness(core, thickness, bolideSize);
4487-
4488- Meteor::drawTrain(core, sPainter, meteor, m_viewMatrix, thickness,
4489- m_segments, m_lineColorArray, m_trainColorArray);
4490-
4491- Meteor::drawBolide(core, sPainter, meteor, m_viewMatrix, bolideSize);
4492-}
4493
4494=== removed file 'plugins/MeteorShowers/src/MeteorStream.hpp'
4495--- plugins/MeteorShowers/src/MeteorStream.hpp 2015-05-30 19:56:47 +0000
4496+++ plugins/MeteorShowers/src/MeteorStream.hpp 1970-01-01 00:00:00 +0000
4497@@ -1,71 +0,0 @@
4498-/*
4499- * Stellarium: Meteor Showers Plug-in
4500- * Copyright (C) 2013 Marcos Cardinot
4501- *
4502- * This program is free software; you can redistribute it and/or
4503- * modify it under the terms of the GNU General Public License
4504- * as published by the Free Software Foundation; either version 2
4505- * of the License, or (at your option) any later version.
4506- *
4507- * This program is distributed in the hope that it will be useful,
4508- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4509- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4510- * GNU General Public License for more details.
4511- *
4512- * You should have received a copy of the GNU General Public License
4513- * along with this program; if not, write to the Free Software
4514- * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
4515- */
4516-
4517-#ifndef _METEORSTREAM_HPP_
4518-#define _METEORSTREAM_HPP_
4519-
4520-#include "Meteor.hpp"
4521-#include "VecMath.hpp"
4522-
4523-class StelCore;
4524-class StelPainter;
4525-
4526-//! @class MeteorStream
4527-//! Models a single meteor.
4528-//! Control of the meteor rate is performed in the MeteorShowers class. Once
4529-//! created, a meteor object only lasts for some amount of time, and then
4530-//! "dies", after which, the update() member returns false.
4531-//! @ingroup meteorShowers
4532-class MeteorStream
4533-{
4534-public:
4535- //! Create a Meteor object.
4536- //! @param the speed of the meteor in km/s.
4537- //! @param rAlpha the radiant alpha in rad
4538- //! @param rDelta the radiant delta in rad
4539- //! @param pidx population index
4540- MeteorStream(const StelCore*,
4541- int speed,
4542- float radiantAlpha,
4543- float radiantDelta,
4544- float pidx,
4545- QList<MeteorShower::colorPair> colors);
4546-
4547- virtual ~MeteorStream();
4548-
4549- //! Updates the position of the meteor, and expires it if necessary.
4550- //! @return true of the meteor is still alive, else false.
4551- bool update(double deltaTime);
4552-
4553- //! Draws the meteor.
4554- void draw(const StelCore* core, StelPainter& sPainter);
4555-
4556-private:
4557- bool m_alive; //! Indicate if the meteor it still visible
4558-
4559- float m_speed; //! Velocity of meteor in km/s
4560- Mat4d m_viewMatrix; //! View Matrix
4561- Meteor::MeteorModel meteor; //! Parameters of meteor model
4562-
4563- QList<Vec4f> m_trainColorArray;
4564- QList<Vec4f> m_lineColorArray;
4565- int m_segments; //! Number of segments along the train
4566-};
4567-
4568-#endif // _METEORSTREAM_HPP_
4569
4570=== added file 'plugins/MeteorShowers/src/gui/MSConfigDialog.cpp'
4571--- plugins/MeteorShowers/src/gui/MSConfigDialog.cpp 1970-01-01 00:00:00 +0000
4572+++ plugins/MeteorShowers/src/gui/MSConfigDialog.cpp 2015-08-07 05:13:12 +0000
4573@@ -0,0 +1,313 @@
4574+/*
4575+ * Stellarium: Meteor Showers Plug-in
4576+ * Copyright (C) 2013-2015 Marcos Cardinot
4577+ *
4578+ * This program is free software; you can redistribute it and/or
4579+ * modify it under the terms of the GNU General Public License
4580+ * as published by the Free Software Foundation; either version 2
4581+ * of the License, or (at your option) any later version.
4582+ *
4583+ * This program is distributed in the hope that it will be useful,
4584+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4585+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4586+ * GNU General Public License for more details.
4587+ *
4588+ * You should have received a copy of the GNU General Public License
4589+ * along with this program; if not, write to the Free Software
4590+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
4591+*/
4592+
4593+#include <QColorDialog>
4594+
4595+#include "MSConfigDialog.hpp"
4596+#include "StelApp.hpp"
4597+#include "StelGui.hpp"
4598+#include "ui_MSConfigDialog.h"
4599+
4600+MSConfigDialog::MSConfigDialog(MeteorShowersMgr* mgr)
4601+ : m_mgr(mgr)
4602+ , m_ui(new Ui_MSConfigDialog)
4603+{
4604+}
4605+
4606+MSConfigDialog::~MSConfigDialog()
4607+{
4608+ delete m_ui;
4609+}
4610+
4611+void MSConfigDialog::retranslate()
4612+{
4613+ if (dialog)
4614+ {
4615+ m_ui->retranslateUi(dialog);
4616+ setAboutHtml();
4617+ }
4618+}
4619+
4620+void MSConfigDialog::createDialogContent()
4621+{
4622+ m_ui->setupUi(dialog);
4623+ m_ui->tabs->setCurrentIndex(0);
4624+
4625+#ifdef Q_OS_WIN
4626+ // Kinetic scrolling for tablet pc and pc
4627+ QList<QWidget *> addscroll;
4628+ addscroll << m_ui->about;
4629+ installKineticScrolling(addscroll);
4630+#endif
4631+
4632+ connect(&StelApp::getInstance(), SIGNAL(languageChanged()), this, SLOT(retranslate()));
4633+ connect(m_ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close()));
4634+ connect(m_ui->bRestoreDefaults, SIGNAL(clicked()), m_mgr, SLOT(restoreDefaultSettings()));
4635+
4636+ // General tab
4637+ connect(m_ui->enableAtStartUp, SIGNAL(clicked(bool)), m_mgr, SLOT(setEnableAtStartup(bool)));
4638+ connect(m_ui->showEnableButton, SIGNAL(clicked(bool)), m_mgr, SLOT(setShowEnableButton(bool)));
4639+ connect(m_ui->showSearchButton, SIGNAL(clicked(bool)), m_mgr, SLOT(setShowSearchButton(bool)));
4640+
4641+ // Radiant tab
4642+ connect(m_ui->enableMarker, SIGNAL(clicked(bool)), m_mgr, SLOT(setEnableMarker(bool)));
4643+ connect(m_ui->activeRadiantsOnly, SIGNAL(clicked(bool)), m_mgr, SLOT(setActiveRadiantOnly(bool)));
4644+ connect(m_ui->enableLabels, SIGNAL(clicked(bool)), m_mgr, SLOT(setEnableLabels(bool)));
4645+ connect(m_ui->fontSize, SIGNAL(valueChanged(int)), m_mgr, SLOT(setFontSize(int)));
4646+
4647+ connect(m_ui->setColorARG, SIGNAL(clicked()), this, SLOT(setColorARG()));
4648+ connect(m_ui->setColorARC, SIGNAL(clicked()), this, SLOT(setColorARC()));
4649+ connect(m_ui->setColorIR, SIGNAL(clicked()), this, SLOT(setColorIR()));
4650+
4651+ // Update tab
4652+ connect(m_ui->enableUpdates, SIGNAL(clicked(bool)), m_mgr, SLOT(setEnableAutoUpdates(bool)));
4653+ connect(m_ui->updateFrequency, SIGNAL(valueChanged(int)), m_mgr, SLOT(setUpdateFrequencyHours(int)));
4654+ connect(m_ui->bUpdate, SIGNAL(clicked()), m_mgr, SLOT(updateCatalog()));
4655+
4656+ connect(m_ui->enableUpdates, SIGNAL(clicked()), this, SLOT(refreshUpdateTab()));
4657+ connect(m_ui->updateFrequency, SIGNAL(valueChanged(int)), this, SLOT(refreshUpdateTab()));
4658+ connect(m_ui->bUpdate, SIGNAL(clicked()), this, SLOT(refreshUpdateTab()));
4659+ connect(m_mgr, SIGNAL(downloadStatusChanged(DownloadStatus)), this, SLOT(refreshUpdateTab()));
4660+
4661+ // About tab
4662+ setAboutHtml();
4663+ StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
4664+ if (gui)
4665+ {
4666+ m_ui->about->document()->setDefaultStyleSheet(QString(gui->getStelStyle().htmlStyleSheet));
4667+ }
4668+
4669+ init();
4670+}
4671+
4672+void MSConfigDialog::init()
4673+{
4674+ // General tab
4675+ m_ui->enableAtStartUp->setChecked(m_mgr->getEnableAtStartup());
4676+ m_ui->showEnableButton->setChecked(m_mgr->getShowEnableButton());
4677+ m_ui->showSearchButton->setChecked(m_mgr->getShowSearchButton());
4678+
4679+ // Radiant tab
4680+ m_ui->enableMarker->setChecked(m_mgr->getEnableMarker());
4681+ m_ui->activeRadiantsOnly->setChecked(m_mgr->getActiveRadiantOnly());
4682+ m_ui->enableLabels->setChecked(m_mgr->getEnableLabels());
4683+ m_ui->fontSize->setValue(m_mgr->getFontSize());
4684+ refreshMarkersColor();
4685+
4686+ // Update tab
4687+ refreshUpdateTab();
4688+}
4689+
4690+void MSConfigDialog::refreshUpdateTab()
4691+{
4692+ m_ui->enableUpdates->setChecked(m_mgr->getEnableAutoUpdates());
4693+ m_ui->updateFrequency->setValue(m_mgr->getUpdateFrequencyHours());
4694+ m_ui->nextUpdate->setDateTime(m_mgr->getNextUpdate());
4695+
4696+ m_ui->lastUpdate->setDateTime(m_mgr->getLastUpdate());
4697+ m_ui->bUpdate->setEnabled(true);
4698+
4699+ QString msg;
4700+ MeteorShowersMgr::DownloadStatus s = m_mgr->getStatusOfLastUpdate();
4701+ if (s == MeteorShowersMgr::UPDATING)
4702+ {
4703+ msg = q_("Updating...");
4704+ m_ui->bUpdate->setEnabled(false);
4705+ }
4706+ else if (s == MeteorShowersMgr::UPDATED)
4707+ {
4708+ msg = q_("Successfully updated!");
4709+ }
4710+ else if (s == MeteorShowersMgr::FAILED)
4711+ {
4712+ msg = q_("Failed!");
4713+ }
4714+ else
4715+ {
4716+ msg = q_("Outdated!");
4717+ }
4718+ m_ui->status->setText(msg);
4719+}
4720+
4721+void MSConfigDialog::refreshMarkersColor()
4722+{
4723+ Vec3f c = m_mgr->getColorARG();
4724+ QColor color(c[0], c[1], c[2]);
4725+ m_ui->setColorARG->setStyleSheet("background-color:" + color.name() + ";");
4726+
4727+ c = m_mgr->getColorARC();
4728+ color = QColor(c[0], c[1], c[2]);
4729+ m_ui->setColorARC->setStyleSheet("background-color:" + color.name() + ";");
4730+
4731+ c = m_mgr->getColorIR();
4732+ color = QColor(c[0], c[1], c[2]);
4733+ m_ui->setColorIR->setStyleSheet("background-color:" + color.name() + ";");
4734+}
4735+
4736+void MSConfigDialog::setColorARG()
4737+{
4738+ Vec3f c = m_mgr->getColorARG();
4739+ QColor color(c[0], c[1], c[2]);
4740+ color = QColorDialog::getColor(color);
4741+ if (color.isValid())
4742+ {
4743+ m_ui->setColorARG->setStyleSheet("background-color:" + color.name() + ";");
4744+ m_mgr->setColorARG(Vec3f(color.red(), color.green(), color.blue()));
4745+ }
4746+}
4747+
4748+void MSConfigDialog::setColorARC()
4749+{
4750+ Vec3f c = m_mgr->getColorARC();
4751+ QColor color(c[0], c[1], c[2]);
4752+ color = QColorDialog::getColor(color);
4753+ if (color.isValid())
4754+ {
4755+ m_ui->setColorARC->setStyleSheet("background-color:" + color.name() + ";");
4756+ m_mgr->setColorARC(Vec3f(color.red(), color.green(), color.blue()));
4757+ }
4758+}
4759+
4760+void MSConfigDialog::setColorIR()
4761+{
4762+ Vec3f c = m_mgr->getColorIR();
4763+ QColor color(c[0], c[1], c[2]);
4764+ color = QColorDialog::getColor(color);
4765+ if (color.isValid())
4766+ {
4767+ m_ui->setColorIR->setStyleSheet("background-color:" + color.name() + ";");
4768+ m_mgr->setColorIR(Vec3f(color.red(), color.green(), color.blue()));
4769+ }
4770+}
4771+
4772+void MSConfigDialog::setAboutHtml()
4773+{
4774+ QString html = "<html><head></head><body>"
4775+ "<h2>" + q_("Meteor Showers Plug-in") + "</h2>"
4776+ "<table width=\"90%\">"
4777+ "<tr width=\"30%\">"
4778+ "<td><strong>" + q_("Version") + ":</strong></td>"
4779+ "<td>" + METEORSHOWERS_PLUGIN_VERSION + "</td>"
4780+ "</tr>"
4781+ "<tr>"
4782+ "<td><strong>" + q_("Author") + ":</strong></td>"
4783+ "<td>Marcos Cardinot &lt;mcardinot@gmail.com&gt;</td>"
4784+ "</tr>"
4785+ "</table>"
4786+ "<p>"
4787+ + q_(""
4788+ "This plugin enables you to simulate periodic meteor showers and "
4789+ "to display a marker for each active and inactive radiant."
4790+ "") +
4791+ "</p>"
4792+ + q_(""
4793+ "By a single click on the radiant's marker, you can see all the "
4794+ "details about its position and activity. Most data used on this "
4795+ "plugin comes from the oficial <a href=\"http://imo.net\">International "
4796+ "Meteor Organization</a> catalog."
4797+ "") +
4798+ "</p>"
4799+ + q_("It has three types of markers:") +
4800+ "<ul>"
4801+ "<li>"
4802+ "<b>" + q_("Confirmed:") + "</b> " +
4803+ q_("the radiant is active and its data was confirmed."
4804+ " Thus, this is a historical (really occurred in the past) or predicted"
4805+ " meteor shower.") +
4806+ "</li>"
4807+ "<li>"
4808+ "<b>" + q_("Generic:") + "</b> " +
4809+ q_("the radiant is active, but its data was not confirmed."
4810+ " It means that this can occur on real life, but that we do not have real"
4811+ " data about its activity for the current sky year.") +
4812+ "</li>"
4813+ "<li>"
4814+ "<b>" + q_("Inactive:") + "</b> " +
4815+ q_("the radiant is inactive for the current sky date.") +
4816+ "</li>"
4817+ "</ul>"
4818+ "</p>"
4819+ "<h3>" + q_("Terms") + "</h3>"
4820+ "<p><b>" + q_("Meteor shower") + "</b>"
4821+ "<br />" +
4822+ q_("A meteor shower is a celestial event in which a number of meteors are observed to "
4823+ "radiate, or originate, from one point in the night sky. These meteors are caused by "
4824+ "streams of cosmic debris called meteoroids entering Earth's atmosphere at extremely "
4825+ "high speeds on parallel trajectories. Most meteors are smaller than a grain of sand, "
4826+ "so almost all of them disintegrate and never hit the Earth's surface. Intense or "
4827+ "unusual meteor showers are known as meteor outbursts and meteor storms, which may "
4828+ "produce greater than 1,000 meteors an hour.") +
4829+ "</p>"
4830+ "<p><b>" + q_("Radiant") + "</b>"
4831+ "<br />" +
4832+ q_("The radiant or apparent radiant of a meteor shower is the point in the sky, from "
4833+ "which (to a planetary observer) meteors appear to originate. The Perseids, for "
4834+ "example, are meteors which appear to come from a point within the constellation "
4835+ "of Perseus.") +
4836+ "</p>"
4837+ "<p>" +
4838+ q_("An observer might see such a meteor anywhere in the sky but the direction of motion, "
4839+ "when traced back, will point to the radiant. A meteor that does not point back to the "
4840+ "known radiant for a given shower is known as a sporadic and is not considered part of "
4841+ "that shower.") +
4842+ "</p>"
4843+ "<p>" + q_("Many showers have a radiant point that changes position during the interval when it "
4844+ "appears. For example, the radiant point for the Delta Aurigids drifts by more than a "
4845+ "degree per night.") +
4846+ "</p>"
4847+ "<p><b>" + q_("Zenithal Hourly Rate (ZHR)") + "</b>"
4848+ "<br />" +
4849+ q_("In astronomy, the Zenithal Hourly Rate (ZHR) of a meteor shower is the number of meteors "
4850+ "a single observer would see in one hour under a clear, dark sky (limiting apparent "
4851+ "magnitude of 6.5) if the radiant of the shower were at the zenith. The rate that can "
4852+ "effectively be seen is nearly always lower and decreases the closer the radiant is to "
4853+ "the horizon.") +
4854+ "</p>"
4855+ "<p><b>" + q_("Population index") + "</b>"
4856+ "<br />" +
4857+ q_("The population index indicates the magnitude distribution of the meteor showers. The "
4858+ "values below 2.5 correspond to distributions where bright meteors are more frequent "
4859+ "than average, while values above 3.0 mean that the share of faint meteors is larger "
4860+ "than usual.") +
4861+ "</p>"
4862+ "<h3>" + q_("Notes") + "</h3>"
4863+ "<p>" + q_("This plugin was initially created as a project of the ESA Summer of Code in Space 2013.") + "</p>"
4864+ "<h3>" + q_("Info") + "</h3>"
4865+ "<p>" + q_("Info about meteor showers you can get here:") + "</p>"
4866+ "<ul>"
4867+ // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
4868+ "<li>" + QString(q_("%1Meteor shower%2 - article in Wikipedia").arg("<a href=\"https://en.wikipedia.org/wiki/Meteor_Showers\">")).arg("</a>") + "</li>"
4869+ // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
4870+ "<li>" + QString(q_("%1International Meteor Organization%2").arg("<a href=\"http://www.imo.net/\">")).arg("</a>") + "</li>"
4871+ "</ul>"
4872+ "<h3>" + q_("Links") + "</h3>"
4873+ "<p>" + QString(q_("Support is provided via the Launchpad website. Be sure to put \"%1\" in the subject when posting.")).arg("Meteor Showers Plugin") + "</p>"
4874+ "<ul>"
4875+ // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
4876+ "<li>" + QString(q_("If you have a question, you can %1get an answer here%2").arg("<a href=\"https://answers.launchpad.net/stellarium\">")).arg("</a>") + "</li>"
4877+ // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
4878+ "<li>" + QString(q_("Bug reports can be made %1here%2.")).arg("<a href=\"https://bugs.launchpad.net/stellarium\">").arg("</a>") + "</li>"
4879+ // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
4880+ "<li>" + q_("If you would like to make a feature request, you can create a bug report, and set the severity to \"wishlist\".") + "</li>"
4881+ // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
4882+ "<li>" + q_("If you want to read full information about the plugin, its history and format of the catalog you can %1get info here%2.").arg("<a href=\"http://stellarium.org/wiki/index.php/Meteor_Showers_plugin\">").arg("</a>") + "</li>"
4883+ "</ul></body></html>";
4884+
4885+ m_ui->about->setHtml(html);
4886+}
4887
4888=== added file 'plugins/MeteorShowers/src/gui/MSConfigDialog.hpp'
4889--- plugins/MeteorShowers/src/gui/MSConfigDialog.hpp 1970-01-01 00:00:00 +0000
4890+++ plugins/MeteorShowers/src/gui/MSConfigDialog.hpp 2015-08-07 05:13:12 +0000
4891@@ -0,0 +1,76 @@
4892+/*
4893+ * Stellarium: Meteor Showers Plug-in
4894+ * Copyright (C) 2013-2015 Marcos Cardinot
4895+ *
4896+ * This program is free software; you can redistribute it and/or
4897+ * modify it under the terms of the GNU General Public License
4898+ * as published by the Free Software Foundation; either version 2
4899+ * of the License, or (at your option) any later version.
4900+ *
4901+ * This program is distributed in the hope that it will be useful,
4902+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4903+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4904+ * GNU General Public License for more details.
4905+ *
4906+ * You should have received a copy of the GNU General Public License
4907+ * along with this program; if not, write to the Free Software
4908+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
4909+*/
4910+
4911+#ifndef _MSCONFIGDIALOG_HPP_
4912+#define _MSCONFIGDIALOG_HPP_
4913+
4914+#include "MeteorShowers.hpp"
4915+#include "StelDialog.hpp"
4916+
4917+class Ui_MSConfigDialog;
4918+
4919+//! @class MSConfigDialog
4920+//! Configuration window.
4921+//! @author Marcos Cardinot <mcardinot@gmail.com>
4922+//! @ingroup meteorShowers
4923+class MSConfigDialog : public StelDialog
4924+{
4925+ Q_OBJECT
4926+
4927+public:
4928+ //! Constructor
4929+ MSConfigDialog(MeteorShowersMgr *mgr);
4930+
4931+ //! Destructor
4932+ ~MSConfigDialog();
4933+
4934+ //! Initializes the components based on the current settings
4935+ void init();
4936+
4937+protected:
4938+ //! Initializes the dialog and connect the signals/slots
4939+ void createDialogContent();
4940+
4941+public slots:
4942+ void retranslate();
4943+
4944+private slots:
4945+ //! Refresh details about the last update
4946+ void refreshUpdateTab();
4947+
4948+ //! Refresh the color of all markers
4949+ void refreshMarkersColor();
4950+
4951+ //! Sets the color of the active radiant based on confirmed data.
4952+ void setColorARC();
4953+
4954+ //! Sets the color of the active radiant based on generic data.
4955+ void setColorARG();
4956+
4957+ //! Sets the color of the inactive radiant.
4958+ void setColorIR();
4959+
4960+private:
4961+ MeteorShowersMgr* m_mgr;
4962+ Ui_MSConfigDialog* m_ui;
4963+
4964+ void setAboutHtml();
4965+};
4966+
4967+#endif // _MSCONFIGDIALOG_HPP_
4968
4969=== added file 'plugins/MeteorShowers/src/gui/MSConfigDialog.ui'
4970--- plugins/MeteorShowers/src/gui/MSConfigDialog.ui 1970-01-01 00:00:00 +0000
4971+++ plugins/MeteorShowers/src/gui/MSConfigDialog.ui 2015-08-07 05:13:12 +0000
4972@@ -0,0 +1,657 @@
4973+<?xml version="1.0" encoding="UTF-8"?>
4974+<ui version="4.0">
4975+ <class>MSConfigDialog</class>
4976+ <widget class="QWidget" name="MSConfigDialog">
4977+ <property name="geometry">
4978+ <rect>
4979+ <x>0</x>
4980+ <y>0</y>
4981+ <width>530</width>
4982+ <height>404</height>
4983+ </rect>
4984+ </property>
4985+ <property name="windowTitle">
4986+ <string>Meteor Showers Configuration</string>
4987+ </property>
4988+ <layout class="QVBoxLayout" name="verticalLayout_2">
4989+ <property name="spacing">
4990+ <number>0</number>
4991+ </property>
4992+ <property name="leftMargin">
4993+ <number>0</number>
4994+ </property>
4995+ <property name="topMargin">
4996+ <number>0</number>
4997+ </property>
4998+ <property name="rightMargin">
4999+ <number>0</number>
5000+ </property>
The diff has been truncated for viewing.