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

Proposed by Marcos Cardinot
Status: Merged
Merged at revision: 6627
Proposed branch: lp:~cardinot/stellarium/MeteorShowers
Merge into: lp:stellarium
Diff against target: 5431 lines (+5318/-1)
17 files modified
CMakeLists.txt (+1/-0)
plugins/MeteorShowers/CMakeLists.txt (+16/-0)
plugins/MeteorShowers/COPYING (+340/-0)
plugins/MeteorShowers/resources/MeteorShower.qrc (+9/-0)
plugins/MeteorShowers/resources/showers.json (+976/-0)
plugins/MeteorShowers/src/CMakeLists.txt (+37/-0)
plugins/MeteorShowers/src/MeteorShower.cpp (+417/-0)
plugins/MeteorShowers/src/MeteorShower.hpp (+186/-0)
plugins/MeteorShowers/src/MeteorShowers.cpp (+1225/-0)
plugins/MeteorShowers/src/MeteorShowers.hpp (+412/-0)
plugins/MeteorShowers/src/MeteorStream.cpp (+239/-0)
plugins/MeteorShowers/src/MeteorStream.hpp (+84/-0)
plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp (+389/-0)
plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp (+111/-0)
plugins/MeteorShowers/src/gui/meteorShowerDialog.ui (+867/-0)
po/stellarium/POTFILES.in (+5/-1)
src/core/StelApp.cpp (+4/-0)
To merge this branch: bzr merge lp:~cardinot/stellarium/MeteorShowers
Reviewer Review Type Date Requested Status
Alexander Wolf Approve
Stellarium Pending
Review via email: mp+210260@code.launchpad.net

Description of the change

This plugin give visualization of the meteor showers, show information about meteor showers and displays marker for radiants in activity range for each meteor showers.

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

The population index does not used in model right now - it's used for info only. I guess we can use this parameter in model for calculation of brightness of meteors (via alpha channel possible).

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

That's true, but IMHO it is just about an improvement and not a "real bug" (to be fixed),
actually I have some ideas to improve the meteor design (color, brightness...), I started to write something in the past and I have plans to push new revisions soon... Anyway, for now I think it's not an issue to block the merge and maybe if the plugin is in trunk, We'd have more users helping with new ideas to build a good wishlist and keep in progress before the next release. =D

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

Of course, it's not a real bug. But it's a good point for TODO list. Right now plugin ready for merge with trunk and for public testing.

I guess in this plugin can be introduce some optimization of code in near future, after merge.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2014-03-01 15:42:49 +0000
+++ CMakeLists.txt 2014-03-10 17:28:07 +0000
@@ -161,6 +161,7 @@
161ADD_PLUGIN(EquationOfTime 1)161ADD_PLUGIN(EquationOfTime 1)
162ADD_PLUGIN(FOV 1)162ADD_PLUGIN(FOV 1)
163ADD_PLUGIN(LogBook 0)163ADD_PLUGIN(LogBook 0)
164ADD_PLUGIN(MeteorShowers 1)
164ADD_PLUGIN(NavStars 1)165ADD_PLUGIN(NavStars 1)
165ADD_PLUGIN(Novae 1)166ADD_PLUGIN(Novae 1)
166ADD_PLUGIN(Observability 1)167ADD_PLUGIN(Observability 1)
167168
=== added directory 'plugins/MeteorShowers'
=== added file 'plugins/MeteorShowers/CMakeLists.txt'
--- plugins/MeteorShowers/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/CMakeLists.txt 2014-03-10 17:28:07 +0000
@@ -0,0 +1,16 @@
1SET(METEORSHOWERS_MAJOR "1")
2SET(METEORSHOWERS_MINOR "0")
3SET(METEORSHOWERS_PATCH "0")
4SET(METEORSHOWERS_VERSION "${METEORSHOWERS_MAJOR}.${METEORSHOWERS_MINOR}.${METEORSHOWERS_PATCH}")
5
6IF(APPLE)
7 SET(CMAKE_INSTALL_PREFIX $ENV{HOME}/Library/Application\ Support/Stellarium)
8ELSE(APPLE)
9 SET(CMAKE_INSTALL_PREFIX $ENV{HOME}/.stellarium)
10ENDIF(APPLE)
11
12ADD_DEFINITIONS(-DMETEORSHOWERS_PLUGIN_VERSION="${METEORSHOWERS_VERSION}")
13
14ADD_SUBDIRECTORY( src )
15
16INSTALL(FILES DESTINATION "modules/MeteorShowers")
017
=== added file 'plugins/MeteorShowers/COPYING'
--- plugins/MeteorShowers/COPYING 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/COPYING 2014-03-10 17:28:07 +0000
@@ -0,0 +1,340 @@
1 GNU GENERAL PUBLIC LICENSE
2 Version 2, June 1991
3
4 Copyright (C) 1989, 1991 Free Software Foundation, Inc.
5 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
6 Everyone is permitted to copy and distribute verbatim copies
7 of this license document, but changing it is not allowed.
8
9 Preamble
10
11 The licenses for most software are designed to take away your
12freedom to share and change it. By contrast, the GNU General Public
13License is intended to guarantee your freedom to share and change free
14software--to make sure the software is free for all its users. This
15General Public License applies to most of the Free Software
16Foundation's software and to any other program whose authors commit to
17using it. (Some other Free Software Foundation software is covered by
18the GNU Library General Public License instead.) You can apply it to
19your programs, too.
20
21 When we speak of free software, we are referring to freedom, not
22price. Our General Public Licenses are designed to make sure that you
23have the freedom to distribute copies of free software (and charge for
24this service if you wish), that you receive source code or can get it
25if you want it, that you can change the software or use pieces of it
26in new free programs; and that you know you can do these things.
27
28 To protect your rights, we need to make restrictions that forbid
29anyone to deny you these rights or to ask you to surrender the rights.
30These restrictions translate to certain responsibilities for you if you
31distribute copies of the software, or if you modify it.
32
33 For example, if you distribute copies of such a program, whether
34gratis or for a fee, you must give the recipients all the rights that
35you have. You must make sure that they, too, receive or can get the
36source code. And you must show them these terms so they know their
37rights.
38
39 We protect your rights with two steps: (1) copyright the software, and
40(2) offer you this license which gives you legal permission to copy,
41distribute and/or modify the software.
42
43 Also, for each author's protection and ours, we want to make certain
44that everyone understands that there is no warranty for this free
45software. If the software is modified by someone else and passed on, we
46want its recipients to know that what they have is not the original, so
47that any problems introduced by others will not reflect on the original
48authors' reputations.
49
50 Finally, any free program is threatened constantly by software
51patents. We wish to avoid the danger that redistributors of a free
52program will individually obtain patent licenses, in effect making the
53program proprietary. To prevent this, we have made it clear that any
54patent must be licensed for everyone's free use or not licensed at all.
55
56 The precise terms and conditions for copying, distribution and
57modification follow.
58
059
60 GNU GENERAL PUBLIC LICENSE
61 TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
62
63 0. This License applies to any program or other work which contains
64a notice placed by the copyright holder saying it may be distributed
65under the terms of this General Public License. The "Program", below,
66refers to any such program or work, and a "work based on the Program"
67means either the Program or any derivative work under copyright law:
68that is to say, a work containing the Program or a portion of it,
69either verbatim or with modifications and/or translated into another
70language. (Hereinafter, translation is included without limitation in
71the term "modification".) Each licensee is addressed as "you".
72
73Activities other than copying, distribution and modification are not
74covered by this License; they are outside its scope. The act of
75running the Program is not restricted, and the output from the Program
76is covered only if its contents constitute a work based on the
77Program (independent of having been made by running the Program).
78Whether that is true depends on what the Program does.
79
80 1. You may copy and distribute verbatim copies of the Program's
81source code as you receive it, in any medium, provided that you
82conspicuously and appropriately publish on each copy an appropriate
83copyright notice and disclaimer of warranty; keep intact all the
84notices that refer to this License and to the absence of any warranty;
85and give any other recipients of the Program a copy of this License
86along with the Program.
87
88You may charge a fee for the physical act of transferring a copy, and
89you may at your option offer warranty protection in exchange for a fee.
90
91 2. You may modify your copy or copies of the Program or any portion
92of it, thus forming a work based on the Program, and copy and
93distribute such modifications or work under the terms of Section 1
94above, provided that you also meet all of these conditions:
95
96 a) You must cause the modified files to carry prominent notices
97 stating that you changed the files and the date of any change.
98
99 b) You must cause any work that you distribute or publish, that in
100 whole or in part contains or is derived from the Program or any
101 part thereof, to be licensed as a whole at no charge to all third
102 parties under the terms of this License.
103
104 c) If the modified program normally reads commands interactively
105 when run, you must cause it, when started running for such
106 interactive use in the most ordinary way, to print or display an
107 announcement including an appropriate copyright notice and a
108 notice that there is no warranty (or else, saying that you provide
109 a warranty) and that users may redistribute the program under
110 these conditions, and telling the user how to view a copy of this
111 License. (Exception: if the Program itself is interactive but
112 does not normally print such an announcement, your work based on
113 the Program is not required to print an announcement.)
114
1115
116These requirements apply to the modified work as a whole. If
117identifiable sections of that work are not derived from the Program,
118and can be reasonably considered independent and separate works in
119themselves, then this License, and its terms, do not apply to those
120sections when you distribute them as separate works. But when you
121distribute the same sections as part of a whole which is a work based
122on the Program, the distribution of the whole must be on the terms of
123this License, whose permissions for other licensees extend to the
124entire whole, and thus to each and every part regardless of who wrote it.
125
126Thus, it is not the intent of this section to claim rights or contest
127your rights to work written entirely by you; rather, the intent is to
128exercise the right to control the distribution of derivative or
129collective works based on the Program.
130
131In addition, mere aggregation of another work not based on the Program
132with the Program (or with a work based on the Program) on a volume of
133a storage or distribution medium does not bring the other work under
134the scope of this License.
135
136 3. You may copy and distribute the Program (or a work based on it,
137under Section 2) in object code or executable form under the terms of
138Sections 1 and 2 above provided that you also do one of the following:
139
140 a) Accompany it with the complete corresponding machine-readable
141 source code, which must be distributed under the terms of Sections
142 1 and 2 above on a medium customarily used for software interchange; or,
143
144 b) Accompany it with a written offer, valid for at least three
145 years, to give any third party, for a charge no more than your
146 cost of physically performing source distribution, a complete
147 machine-readable copy of the corresponding source code, to be
148 distributed under the terms of Sections 1 and 2 above on a medium
149 customarily used for software interchange; or,
150
151 c) Accompany it with the information you received as to the offer
152 to distribute corresponding source code. (This alternative is
153 allowed only for noncommercial distribution and only if you
154 received the program in object code or executable form with such
155 an offer, in accord with Subsection b above.)
156
157The source code for a work means the preferred form of the work for
158making modifications to it. For an executable work, complete source
159code means all the source code for all modules it contains, plus any
160associated interface definition files, plus the scripts used to
161control compilation and installation of the executable. However, as a
162special exception, the source code distributed need not include
163anything that is normally distributed (in either source or binary
164form) with the major components (compiler, kernel, and so on) of the
165operating system on which the executable runs, unless that component
166itself accompanies the executable.
167
168If distribution of executable or object code is made by offering
169access to copy from a designated place, then offering equivalent
170access to copy the source code from the same place counts as
171distribution of the source code, even though third parties are not
172compelled to copy the source along with the object code.
173
2174
175 4. You may not copy, modify, sublicense, or distribute the Program
176except as expressly provided under this License. Any attempt
177otherwise to copy, modify, sublicense or distribute the Program is
178void, and will automatically terminate your rights under this License.
179However, parties who have received copies, or rights, from you under
180this License will not have their licenses terminated so long as such
181parties remain in full compliance.
182
183 5. You are not required to accept this License, since you have not
184signed it. However, nothing else grants you permission to modify or
185distribute the Program or its derivative works. These actions are
186prohibited by law if you do not accept this License. Therefore, by
187modifying or distributing the Program (or any work based on the
188Program), you indicate your acceptance of this License to do so, and
189all its terms and conditions for copying, distributing or modifying
190the Program or works based on it.
191
192 6. Each time you redistribute the Program (or any work based on the
193Program), the recipient automatically receives a license from the
194original licensor to copy, distribute or modify the Program subject to
195these terms and conditions. You may not impose any further
196restrictions on the recipients' exercise of the rights granted herein.
197You are not responsible for enforcing compliance by third parties to
198this License.
199
200 7. If, as a consequence of a court judgment or allegation of patent
201infringement or for any other reason (not limited to patent issues),
202conditions are imposed on you (whether by court order, agreement or
203otherwise) that contradict the conditions of this License, they do not
204excuse you from the conditions of this License. If you cannot
205distribute so as to satisfy simultaneously your obligations under this
206License and any other pertinent obligations, then as a consequence you
207may not distribute the Program at all. For example, if a patent
208license would not permit royalty-free redistribution of the Program by
209all those who receive copies directly or indirectly through you, then
210the only way you could satisfy both it and this License would be to
211refrain entirely from distribution of the Program.
212
213If any portion of this section is held invalid or unenforceable under
214any particular circumstance, the balance of the section is intended to
215apply and the section as a whole is intended to apply in other
216circumstances.
217
218It is not the purpose of this section to induce you to infringe any
219patents or other property right claims or to contest validity of any
220such claims; this section has the sole purpose of protecting the
221integrity of the free software distribution system, which is
222implemented by public license practices. Many people have made
223generous contributions to the wide range of software distributed
224through that system in reliance on consistent application of that
225system; it is up to the author/donor to decide if he or she is willing
226to distribute software through any other system and a licensee cannot
227impose that choice.
228
229This section is intended to make thoroughly clear what is believed to
230be a consequence of the rest of this License.
231
3232
233 8. If the distribution and/or use of the Program is restricted in
234certain countries either by patents or by copyrighted interfaces, the
235original copyright holder who places the Program under this License
236may add an explicit geographical distribution limitation excluding
237those countries, so that distribution is permitted only in or among
238countries not thus excluded. In such case, this License incorporates
239the limitation as if written in the body of this License.
240
241 9. The Free Software Foundation may publish revised and/or new versions
242of the General Public License from time to time. Such new versions will
243be similar in spirit to the present version, but may differ in detail to
244address new problems or concerns.
245
246Each version is given a distinguishing version number. If the Program
247specifies a version number of this License which applies to it and "any
248later version", you have the option of following the terms and conditions
249either of that version or of any later version published by the Free
250Software Foundation. If the Program does not specify a version number of
251this License, you may choose any version ever published by the Free Software
252Foundation.
253
254 10. If you wish to incorporate parts of the Program into other free
255programs whose distribution conditions are different, write to the author
256to ask for permission. For software which is copyrighted by the Free
257Software Foundation, write to the Free Software Foundation; we sometimes
258make exceptions for this. Our decision will be guided by the two goals
259of preserving the free status of all derivatives of our free software and
260of promoting the sharing and reuse of software generally.
261
262 NO WARRANTY
263
264 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
265FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
266OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
267PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
268OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
269MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
270TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
271PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
272REPAIR OR CORRECTION.
273
274 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
275WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
276REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
277INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
278OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
279TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
280YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
281PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
282POSSIBILITY OF SUCH DAMAGES.
283
284 END OF TERMS AND CONDITIONS
285
4286
287 How to Apply These Terms to Your New Programs
288
289 If you develop a new program, and you want it to be of the greatest
290possible use to the public, the best way to achieve this is to make it
291free software which everyone can redistribute and change under these terms.
292
293 To do so, attach the following notices to the program. It is safest
294to attach them to the start of each source file to most effectively
295convey the exclusion of warranty; and each file should have at least
296the "copyright" line and a pointer to where the full notice is found.
297
298 <one line to give the program's name and a brief idea of what it does.>
299 Copyright (C) <year> <name of author>
300
301 This program is free software; you can redistribute it and/or modify
302 it under the terms of the GNU General Public License as published by
303 the Free Software Foundation; either version 2 of the License, or
304 (at your option) any later version.
305
306 This program is distributed in the hope that it will be useful,
307 but WITHOUT ANY WARRANTY; without even the implied warranty of
308 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
309 GNU General Public License for more details.
310
311 You should have received a copy of the GNU General Public License
312 along with this program; if not, write to the Free Software
313 Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
314
315
316Also add information on how to contact you by electronic and paper mail.
317
318If the program is interactive, make it output a short notice like this
319when it starts in an interactive mode:
320
321 Gnomovision version 69, Copyright (C) year name of author
322 Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
323 This is free software, and you are welcome to redistribute it
324 under certain conditions; type `show c' for details.
325
326The hypothetical commands `show w' and `show c' should show the appropriate
327parts of the General Public License. Of course, the commands you use may
328be called something other than `show w' and `show c'; they could even be
329mouse-clicks or menu items--whatever suits your program.
330
331You should also get your employer (if you work as a programmer) or your
332school, if any, to sign a "copyright disclaimer" for the program, if
333necessary. Here is a sample; alter the names:
334
335 Yoyodyne, Inc., hereby disclaims all copyright interest in the program
336 `Gnomovision' (which makes passes at compilers) written by James Hacker.
337
338 <signature of Ty Coon>, 1 April 1989
339 Ty Coon, President of Vice
340
341This General Public License does not permit incorporating your program into
342proprietary programs. If your program is a subroutine library, you may
343consider it more useful to permit linking proprietary applications with the
344library. If this is what you want to do, use the GNU Library General
345Public License instead of this License.
5346
=== added directory 'plugins/MeteorShowers/resources'
=== added file 'plugins/MeteorShowers/resources/MeteorShower.qrc'
--- plugins/MeteorShowers/resources/MeteorShower.qrc 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/resources/MeteorShower.qrc 2014-03-10 17:28:07 +0000
@@ -0,0 +1,9 @@
1<RCC>
2 <qresource prefix="/MeteorShowers">
3 <file>showers.json</file>
4 <file>radiant.png</file>
5 <file>btMS-off.png</file>
6 <file>btMS-on.png</file>
7 <file>radiantSetting.png</file>
8 </qresource>
9</RCC>
010
=== added file 'plugins/MeteorShowers/resources/btMS-off.png'
1Binary files plugins/MeteorShowers/resources/btMS-off.png 1970-01-01 00:00:00 +0000 and plugins/MeteorShowers/resources/btMS-off.png 2014-03-10 17:28:07 +0000 differ11Binary files plugins/MeteorShowers/resources/btMS-off.png 1970-01-01 00:00:00 +0000 and plugins/MeteorShowers/resources/btMS-off.png 2014-03-10 17:28:07 +0000 differ
=== added file 'plugins/MeteorShowers/resources/btMS-on.png'
2Binary files plugins/MeteorShowers/resources/btMS-on.png 1970-01-01 00:00:00 +0000 and plugins/MeteorShowers/resources/btMS-on.png 2014-03-10 17:28:07 +0000 differ12Binary files plugins/MeteorShowers/resources/btMS-on.png 1970-01-01 00:00:00 +0000 and plugins/MeteorShowers/resources/btMS-on.png 2014-03-10 17:28:07 +0000 differ
=== added file 'plugins/MeteorShowers/resources/radiant.png'
3Binary files plugins/MeteorShowers/resources/radiant.png 1970-01-01 00:00:00 +0000 and plugins/MeteorShowers/resources/radiant.png 2014-03-10 17:28:07 +0000 differ13Binary files plugins/MeteorShowers/resources/radiant.png 1970-01-01 00:00:00 +0000 and plugins/MeteorShowers/resources/radiant.png 2014-03-10 17:28:07 +0000 differ
=== added file 'plugins/MeteorShowers/resources/radiantSetting.png'
4Binary files plugins/MeteorShowers/resources/radiantSetting.png 1970-01-01 00:00:00 +0000 and plugins/MeteorShowers/resources/radiantSetting.png 2014-03-10 17:28:07 +0000 differ14Binary files plugins/MeteorShowers/resources/radiantSetting.png 1970-01-01 00:00:00 +0000 and plugins/MeteorShowers/resources/radiantSetting.png 2014-03-10 17:28:07 +0000 differ
=== added file 'plugins/MeteorShowers/resources/showers.json'
--- plugins/MeteorShowers/resources/showers.json 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/resources/showers.json 2014-03-10 17:28:07 +0000
@@ -0,0 +1,976 @@
1{
2 "shortName": "meteor showers data",
3 "version": 1,
4 "showers":
5 {
6 "QUA":
7 {
8 "designation": "Quadrantids",
9 "activity":
10 [
11 {
12 "year": "generic",
13 "zhr": -1,
14 "variable": "60-200",
15 "start": "12.28",
16 "finish": "01.12",
17 "peak": "01.04"
18 },
19 {
20 "year": "2008",
21 "zhr": 120
22 },
23 {
24 "year": "2009",
25 "start": "01.01",
26 "finish": "01.05",
27 "peak": "01.03",
28 "zhr": 120
29 },
30 {
31 "year": "2011",
32 "zhr": 120
33 },
34 {
35 "year": "2012",
36 "zhr": 120
37 }
38 ],
39 "speed": 41,
40 "radiantAlpha": "230",
41 "radiantDelta": "49",
42 "driftAlpha": "3",
43 "driftDelta": "-1",
44 "parentObj": "Asteroid 2003 EH1",
45 "pidx": 2.1
46 },
47 "ACE":
48 {
49 "designation": "α-Centaurids",
50 "activity":
51 [
52 {
53 "year": "generic",
54 "zhr": -1,
55 "variable": "5-20",
56 "start": "01.28",
57 "finish": "02.21",
58 "peak": "02.08"
59 },
60 {
61 "year": "2008",
62 "zhr": 5
63 },
64 {
65 "year": "2010",
66 "zhr": 6
67 },
68 {
69 "year": "2011",
70 "zhr": 6
71 }
72 ],
73 "speed": 56,
74 "radiantAlpha": "210",
75 "radiantDelta": "-59",
76 "driftAlpha": "6.25",
77 "driftDelta": "-1.5",
78 "pidx": 2.0
79 },
80 "GNO":
81 {
82 "designation": "γ-Normids",
83 "activity":
84 [
85 {
86 "year": "generic",
87 "zhr": 6,
88 "start": "02.25",
89 "finish": "03.22",
90 "peak": "03.15"
91 },
92 {
93 "year": "2008",
94 "zhr": 4
95 },
96 {
97 "year": "2010",
98 "zhr": 6
99 },
100 {
101 "year": "2011",
102 "zhr": 6
103 }
104 ],
105 "speed": 56,
106 "radiantAlpha": "239",
107 "radiantDelta": "-50",
108 "driftAlpha": "5",
109 "driftDelta": "-0.3",
110 "pidx": 2.4
111 },
112 "ETA":
113 {
114 "designation": "η-Aquariids",
115 "activity":
116 [
117 {
118 "year": "generic",
119 "zhr": -1,
120 "variable": "40-85",
121 "start": "04.19",
122 "finish": "05.28",
123 "peak": "05.06"
124 },
125 {
126 "year": "2008",
127 "zhr": 70
128 },
129 {
130 "year": "2009",
131 "zhr": 85
132 },
133 {
134 "year": "2011",
135 "zhr": 70
136 }
137 ],
138 "speed": 66,
139 "radiantAlpha": "338",
140 "radiantDelta": "-1",
141 "driftAlpha": "5",
142 "driftDelta": "2",
143 "parentObj": "Comet 1P/Halley",
144 "pidx": 2.4
145 },
146 "PAU":
147 {
148 "designation": "Piscis Austrinids",
149 "activity":
150 [
151 {
152 "year": "generic",
153 "zhr": 5,
154 "start": "06.15",
155 "finish": "08.10",
156 "peak": "07.28"
157 },
158 {
159 "year": "2008",
160 "zhr": 5
161 },
162 {
163 "year": "2009",
164 "zhr": 5
165 }
166 ],
167 "speed": 35,
168 "radiantAlpha": "341",
169 "radiantDelta": "-30",
170 "driftAlpha": "4",
171 "driftDelta": "1",
172 "pidx": 3.2
173 },
174 "LYR":
175 {
176 "designation": "Lyrids",
177 "activity":
178 [
179 {
180 "year": "generic",
181 "zhr": -1,
182 "variable": "0-90",
183 "start": "04.16",
184 "finish": "04.25",
185 "peak": "04.22"
186 },
187 {
188 "year": "1922",
189 "zhr": 96
190 },
191 {
192 "year": "1945",
193 "zhr": 112
194 },
195 {
196 "year": "1982",
197 "zhr": 100
198 },
199 {
200 "year": "2007",
201 "zhr": 18
202 },
203 {
204 "year": "2008",
205 "zhr": 18
206 },
207 {
208 "year": "2010",
209 "zhr": 18
210 },
211 {
212 "year": "2011",
213 "zhr": 20
214 },
215 {
216 "year": "2012",
217 "zhr": 18
218 }
219 ],
220 "speed": 49,
221 "radiantAlpha": "271",
222 "radiantDelta": "34",
223 "driftAlpha": "3",
224 "driftDelta": "0",
225 "parentObj": "Comet Thatcher (1861 I)",
226 "pidx": 2.1
227 },
228 "JBO":
229 {
230 "designation": "June Bootids",
231 "activity":
232 [
233 {
234 "year": "generic",
235 "zhr": -1,
236 "variable": "0-100",
237 "start": "06.22",
238 "finish": "07.02",
239 "peak": "06.27"
240 }
241 ],
242 "speed": 18,
243 "radiantAlpha": "224",
244 "radiantDelta": "48",
245 "driftAlpha": "2",
246 "driftDelta": "-1",
247 "parentObj": "Comet 7P/Pons-Winnecke",
248 "pidx": 2.2
249 },
250 "SDA":
251 {
252 "designation": "Southern δ-Aquariids",
253 "activity":
254 [
255 {
256 "year": "generic",
257 "zhr": 16,
258 "start": "07.12",
259 "finish": "08.23",
260 "peak": "07.30"
261 },
262 {
263 "year": "2007",
264 "zhr": 20,
265 "start": "07.12",
266 "finish": "08.19",
267 "peak": "07.28"
268 },
269 {
270 "year": "2008",
271 "zhr": 20,
272 "start": "07.12",
273 "finish": "08.19",
274 "peak": "07.27"
275 },
276 {
277 "year": "2009",
278 "zhr": 20,
279 "start": "07.12",
280 "finish": "08.19",
281 "peak": "07.28"
282 }
283 ],
284 "speed": 41,
285 "radiantAlpha": "339",
286 "radiantDelta": "-16",
287 "driftAlpha": "4",
288 "driftDelta": "0.5",
289 "parentObj": "Comet 96P/Machholz",
290 "pidx": 3.2
291 },
292 "CAP":
293 {
294 "designation": "α-Capricornids",
295 "activity":
296 [
297 {
298 "year": "generic",
299 "zhr": 5,
300 "start": "07.03",
301 "finish": "08.15",
302 "peak": "07.30"
303 },
304 {
305 "year": "2007",
306 "zhr": 4
307 },
308 {
309 "year": "2008",
310 "zhr": 4
311 },
312 {
313 "year": "2009",
314 "zhr": 4
315 }
316 ],
317 "speed": 23,
318 "radiantAlpha": "307",
319 "radiantDelta": "-10",
320 "driftAlpha": "5",
321 "driftDelta": "1",
322 "pidx": 2.5
323 },
324 "AUR":
325 {
326 "designation": "α-Aurigids",
327 "activity":
328 [
329 {
330 "year": "generic",
331 "zhr": 6,
332 "start": "08.28",
333 "finish": "09.05",
334 "peak": "09.01"
335 },
336 {
337 "year": "2009",
338 "zhr": 7
339 }
340 ],
341 "speed": 66,
342 "radiantAlpha": "91",
343 "radiantDelta": "+39",
344 "driftAlpha": "5",
345 "driftDelta": "0.7",
346 "pidx": 2.6
347 },
348 "SPE":
349 {
350 "designation": "September ε-Perseids",
351 "activity":
352 [
353 {
354 "year": "generic",
355 "zhr": 5,
356 "start": "09.04",
357 "finish": "09.14",
358 "peak": "09.09"
359 }
360 ],
361 "speed": 64,
362 "radiantAlpha": "47",
363 "radiantDelta": "+40",
364 "driftAlpha": "5",
365 "driftDelta": "0.1",
366 "pidx": 3.0
367 },
368 "DRA":
369 {
370 "designation": "Draconids",
371 "activity":
372 [
373 {
374 "year": "generic",
375 "zhr": -1,
376 "variable": "20-700",
377 "start": "10.06",
378 "finish": "10.10",
379 "peak": "10.08"
380 },
381 {
382 "year": "1933",
383 "zhr": 6000
384 },
385 {
386 "year": "1946",
387 "zhr": 6800
388 }
389 ],
390 "speed": 20,
391 "radiantAlpha": "262",
392 "radiantDelta": "+54",
393 "driftAlpha": "0",
394 "driftDelta": "0",
395 "parentObj": "Comet 21P/Giacobini-Zinner",
396 "pidx": 2.6
397 },
398 "LEO":
399 {
400 "designation": "Leonids",
401 "activity":
402 [
403 {
404 "year": "generic",
405 "zhr": -1,
406 "variable": "5-20*",
407 "start": "11.06",
408 "finish": "11.30",
409 "peak": "11.18"
410 },
411 {
412 "year": "1833",
413 "zhr": 240000
414 },
415 {
416 "year": "1866",
417 "zhr": 5000
418 },
419 {
420 "year": "1867",
421 "zhr": 1000
422 },
423 {
424 "year": "1868",
425 "zhr": 1000
426 },
427 {
428 "year": "1898",
429 "zhr": 100
430 },
431 {
432 "year": "1901",
433 "zhr": 400
434 },
435 {
436 "year": "1966",
437 "zhr": 144000
438 },
439 {
440 "year": "1998",
441 "zhr": 2000
442 },
443 {
444 "year": "1999",
445 "zhr": 5000
446 },
447 {
448 "year": "2000",
449 "zhr": 480
450 },
451 {
452 "year": "2001",
453 "zhr": 3700
454 },
455 {
456 "year": "2002",
457 "zhr": 3000
458 },
459 {
460 "year": "2006",
461 "zhr": 78
462 },
463 {
464 "year": "2007",
465 "zhr": 35
466 },
467 {
468 "year": "2008",
469 "start": "11.14",
470 "finish": "11.22",
471 "peak": "11.17",
472 "zhr": 99
473 },
474 {
475 "year": "2009",
476 "start": "11.10",
477 "finish": "11.21",
478 "peak": "11.17",
479 "zhr": 79
480 },
481 {
482 "year": "2010",
483 "start": "11.10",
484 "finish": "11.23",
485 "peak": "11.17",
486 "zhr": 32
487 },
488 {
489 "year": "2011",
490 "zhr": 22
491 },
492 {
493 "year": 2012,
494 "start": "11.06",
495 "finish": "11.30",
496 "peak": "11.17",
497 "zhr": 61
498 }
499 ],
500 "speed": 71,
501 "radiantAlpha": "152",
502 "radiantDelta": "+22",
503 "driftAlpha": "3",
504 "driftDelta": "-1.25",
505 "parentObj": "Comet 55P/Tempel-Tuttle",
506 "pidx": 2.5
507 },
508 "PHO":
509 {
510 "designation": "Phoenicids",
511 "activity":
512 [
513 {
514 "year": "generic",
515 "zhr": -1,
516 "variable": "0-100",
517 "start": "11.28",
518 "finish": "12.09",
519 "peak": "12.06"
520 }
521 ],
522 "speed": 18,
523 "radiantAlpha": "18",
524 "radiantDelta": "-53",
525 "driftAlpha": "4",
526 "driftDelta": "-0.5",
527 "pidx": 2.8
528 },
529 "PUP":
530 {
531 "designation": "Puppid-Velids",
532 "activity":
533 [
534 {
535 "year": "generic",
536 "zhr": 10,
537 "start": "12.01",
538 "finish": "12.15",
539 "peak": "12.07"
540 }
541 ],
542 "speed": 40,
543 "radiantAlpha": "123",
544 "radiantDelta": "-45",
545 "driftAlpha": "3",
546 "driftDelta": "0",
547 "pidx": 2.9
548 },
549 "URS":
550 {
551 "designation": "Ursids",
552 "activity":
553 [
554 {
555 "year": "generic",
556 "zhr": -1,
557 "variable": "10-50",
558 "start": "12.17",
559 "finish": "12.26",
560 "peak": "12.23"
561 }
562 ],
563 "speed": 33,
564 "radiantAlpha": "217",
565 "radiantDelta": "+76",
566 "driftAlpha": "0",
567 "driftDelta": "-2",
568 "pidx": 3.0
569 },
570 "PER":
571 {
572 "designation": "Perseids",
573 "activity":
574 [
575 {
576 "year": "generic",
577 "zhr": 100,
578 "start": "07.17",
579 "finish": "08.24",
580 "peak": "08.13"
581 },
582 {
583 "year": "1863",
584 "zhr": 215
585 },
586 {
587 "year": "2004",
588 "zhr": 200
589 },
590 {
591 "year": "2007",
592 "zhr": 93
593 },
594 {
595 "year": "2008",
596 "zhr": 116
597 },
598 {
599 "year": "2009",
600 "zhr": 173
601 },
602 {
603 "year": "2010",
604 "zhr": 142
605 },
606 {
607 "year": "2011",
608 "zhr": 100
609 },
610 {
611 "year": "2012",
612 "zhr": 100
613 }
614 ],
615 "speed": 59,
616 "radiantAlpha": "48",
617 "radiantDelta": "+58",
618 "driftAlpha": "6",
619 "driftDelta": "1",
620 "parentObj": "Comet 109P/Swift-Tuttle",
621 "pidx": 2.2
622 },
623 "DLE":
624 {
625 "designation": "δ-Leonids",
626 "activity":
627 [
628 {
629 "year": "generic",
630 "zhr": 2,
631 "start": "02.15",
632 "finish": "03.10",
633 "peak": "02.24"
634 }
635 ],
636 "speed": 23,
637 "radiantAlpha": "168",
638 "radiantDelta": "+16",
639 "driftAlpha": "0",
640 "driftDelta": "0",
641 "parentObj": "Asteroid (4450) Pan",
642 "pidx": 3.0
643 },
644 "PPU":
645 {
646 "designation": "π-Puppids",
647 "activity":
648 [
649 {
650 "year": "generic",
651 "zhr": -1,
652 "variable": "0-40",
653 "start": "04.15",
654 "finish": "04.28",
655 "peak": "04.24"
656 }
657 ],
658 "speed": 18,
659 "radiantAlpha": "110",
660 "radiantDelta": "-45",
661 "driftAlpha": "2.5",
662 "driftDelta": "-0.5",
663 "parentObj": "Comet 26P/Grigg-Skjellerup",
664 "pidx": 2.0
665 },
666 "JLY":
667 {
668 "designation": "June Lyrids",
669 "activity":
670 [
671 {
672 "year": "generic",
673 "zhr": -1,
674 "variable": "0-5",
675 "start": "06.11",
676 "finish": "06.21",
677 "peak": "06.16"
678 }
679 ],
680 "speed": 31,
681 "radiantAlpha": "277",
682 "radiantDelta": "+35",
683 "driftAlpha": "4",
684 "driftDelta": "0",
685 "pidx": 3.0
686 },
687 "KCG":
688 {
689 "designation": "κ-Cygnids",
690 "activity":
691 [
692 {
693 "year": "generic",
694 "zhr": 3,
695 "start": "08.03",
696 "finish": "08.25",
697 "peak": "08.18"
698 }
699 ],
700 "speed": 25,
701 "radiantAlpha": "286",
702 "radiantDelta": "+59",
703 "driftAlpha": "1",
704 "driftDelta": "0.5",
705 "pidx": 3.0
706 },
707 "ELY":
708 {
709 "designation": "ε-Lyrids",
710 "activity":
711 [
712 {
713 "year": "generic",
714 "zhr": 3,
715 "start": "03.03",
716 "finish": "03.12",
717 "peak": "03.08"
718 }
719 ],
720 "speed": 44,
721 "radiantAlpha": "287",
722 "radiantDelta": "+44",
723 "driftAlpha": "5",
724 "driftDelta": "0.5",
725 "pidx": 3.0
726 },
727 "DAU":
728 {
729 "designation": "δ-Aurigids",
730 "activity":
731 [
732 {
733 "year": "generic",
734 "zhr": 3,
735 "start": "09.18",
736 "finish": "10.10",
737 "peak": "09.28"
738 }
739 ],
740 "speed": 64,
741 "radiantAlpha": "82",
742 "radiantDelta": "+49",
743 "driftAlpha": "5",
744 "driftDelta": "-2",
745 "pidx": 2.9
746 },
747 "EGE":
748 {
749 "designation": "ε-Geminids",
750 "activity":
751 [
752 {
753 "year": "generic",
754 "zhr": 3,
755 "start": "10.14",
756 "finish": "10.27",
757 "peak": "10.18"
758 }
759 ],
760 "speed": 70,
761 "radiantAlpha": "102",
762 "radiantDelta": "+27",
763 "driftAlpha": "5",
764 "driftDelta": "0",
765 "pidx": 3.0
766 },
767 "STA":
768 {
769 "designation": "Southern Taurids",
770 "activity":
771 [
772 {
773 "year": "generic",
774 "zhr": 5,
775 "start": "09.25",
776 "finish": "11.25",
777 "peak": "11.05"
778 }
779 ],
780 "speed": 27,
781 "radiantAlpha": "52",
782 "radiantDelta": "+15",
783 "driftAlpha": "3",
784 "driftDelta": "1",
785 "pidx": 2.3
786 },
787 "NTA":
788 {
789 "designation": "Northern Taurids",
790 "activity":
791 [
792 {
793 "year": "generic",
794 "zhr": 5,
795 "start": "09.25",
796 "finish": "11.25",
797 "peak": "11.12"
798 }
799 ],
800 "speed": 29,
801 "radiantAlpha": "58",
802 "radiantDelta": "+22",
803 "driftAlpha": "5",
804 "driftDelta": "1",
805 "pidx": 2.3
806 },
807 "MON":
808 {
809 "designation": "Monocerotids",
810 "activity":
811 [
812 {
813 "year": "generic",
814 "zhr": 2,
815 "start": "11.27",
816 "finish": "12.17",
817 "peak": "12.09"
818 }
819 ],
820 "speed": 42,
821 "radiantAlpha": "100",
822 "radiantDelta": "+8",
823 "driftAlpha": "4",
824 "driftDelta": "0",
825 "pidx": 3.0
826 },
827 "HYD":
828 {
829 "designation": "σ-Hydrids",
830 "activity":
831 [
832 {
833 "year": "generic",
834 "zhr": 3,
835 "start": "12.03",
836 "finish": "12.15",
837 "peak": "12.12"
838 }
839 ],
840 "speed": 58,
841 "radiantAlpha": "127",
842 "radiantDelta": "+2",
843 "driftAlpha": "4",
844 "driftDelta": "-1",
845 "pidx": 3.0
846 },
847 "GEM":
848 {
849 "designation": "Geminids",
850 "activity":
851 [
852 {
853 "year": "generic",
854 "zhr": 120,
855 "start": "12.07",
856 "finish": "12.17",
857 "peak": "12.14"
858 },
859 {
860 "year": "2006",
861 "zhr": 115
862 },
863 {
864 "year": "2007",
865 "zhr": 122
866 },
867 {
868 "year": "2008",
869 "zhr": 139
870 },
871 {
872 "year": "2009",
873 "zhr": 120
874 },
875 {
876 "year": "2010",
877 "zhr": 127
878 },
879 {
880 "year": "2011",
881 "zhr": 198
882 },
883 {
884 "year": "2012",
885 "zhr": 109
886 }
887 ],
888 "speed": 35,
889 "radiantAlpha": "112",
890 "radiantDelta": "+33",
891 "driftAlpha": "5",
892 "driftDelta": "-0.1",
893 "pidx": 2.6
894 },
895 "LMI":
896 {
897 "designation": "Leonis Minorids",
898 "activity":
899 [
900 {
901 "year": "generic",
902 "zhr": 2,
903 "start": "10.19",
904 "finish": "10.27",
905 "peak": "10.24"
906 }
907 ],
908 "speed": 62,
909 "radiantAlpha": "162",
910 "radiantDelta": "+37",
911 "driftAlpha": "5",
912 "driftDelta": "-2",
913 "pidx": 3.0
914 },
915 "DLM":
916 {
917 "designation": "December Leonis Minorids",
918 "activity":
919 [
920 {
921 "year": "generic",
922 "zhr": 5,
923 "start": "12.05",
924 "finish": "02.04",
925 "peak": "12.20"
926 }
927 ],
928 "speed": 64,
929 "radiantAlpha": "161",
930 "radiantDelta": "+30",
931 "driftAlpha": "5",
932 "driftDelta": "-2",
933 "pidx": 3.0
934 },
935 "COM":
936 {
937 "designation": "Comae Berenicids",
938 "activity":
939 [
940 {
941 "year": "generic",
942 "zhr": 3,
943 "start": "12.12",
944 "finish": "12.23",
945 "peak": "12.16"
946 }
947 ],
948 "speed": 65,
949 "radiantAlpha": "175",
950 "radiantDelta": "+18",
951 "driftAlpha": "2.5",
952 "driftDelta": "-1.5",
953 "pidx": 3.0
954 },
955 "ORI":
956 {
957 "designation": "Orionids",
958 "activity":
959 [
960 {
961 "year": "generic",
962 "zhr": 25,
963 "start": "10.02",
964 "finish": "11.07",
965 "peak": "10.21"
966 }
967 ],
968 "speed": 66,
969 "radiantAlpha": "95",
970 "radiantDelta": "+16",
971 "driftAlpha": "3",
972 "driftDelta": "0.5",
973 "pidx": 2.5
974 }
975 }
976}
0977
=== added directory 'plugins/MeteorShowers/src'
=== added file 'plugins/MeteorShowers/src/CMakeLists.txt'
--- plugins/MeteorShowers/src/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/src/CMakeLists.txt 2014-03-10 17:28:07 +0000
@@ -0,0 +1,37 @@
1INCLUDE_DIRECTORIES(
2 .
3 gui
4 ${CMAKE_BINARY_DIR}/plugins/MeteorShowers/src
5 ${CMAKE_BINARY_DIR}/plugins/MeteorShowers/src/gui
6)
7
8LINK_DIRECTORIES(${BUILD_DIR}/src)
9
10SET(MeteorShowers_SRCS
11 MeteorShower.hpp
12 MeteorShower.cpp
13 MeteorShowers.hpp
14 MeteorShowers.cpp
15 MeteorStream.hpp
16 MeteorStream.cpp
17 gui/MeteorShowerDialog.hpp
18 gui/MeteorShowerDialog.cpp
19)
20
21SET(MeteorShowersDialog_UIS
22 gui/meteorShowerDialog.ui
23)
24
25QT5_WRAP_UI(MeteorShowersDialog_UIS_H ${MeteorShowersDialog_UIS})
26
27SET(MeteorShowers_RES ../resources/MeteorShower.qrc)
28QT5_ADD_RESOURCES(MeteorShowers_RES_CXX ${MeteorShowers_RES})
29
30SET(extLinkerOption ${QT_LIBRARIES} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${OPENGL_LIBRARIES} ${ICONV_LIBRARIES} ${INTL_LIBRARIES})
31
32ADD_LIBRARY(MeteorShowers-static STATIC ${MeteorShowers_SRCS} ${MeteorShowers_MOC_SRCS} ${MeteorShowers_RES_CXX} ${MeteorShowersDialog_UIS_H})
33QT5_USE_MODULES(MeteorShowers-static Core Declarative Network)
34SET_TARGET_PROPERTIES(MeteorShowers-static PROPERTIES OUTPUT_NAME "MeteorShowers")
35TARGET_LINK_LIBRARIES(MeteorShowers-static ${extLinkerOption})
36SET_TARGET_PROPERTIES(MeteorShowers-static PROPERTIES COMPILE_FLAGS "-DQT_STATICPLUGIN")
37ADD_DEPENDENCIES(AllStaticPlugins MeteorShowers-static)
038
=== added file 'plugins/MeteorShowers/src/MeteorShower.cpp'
--- plugins/MeteorShowers/src/MeteorShower.cpp 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/src/MeteorShower.cpp 2014-03-10 17:28:07 +0000
@@ -0,0 +1,417 @@
1/*
2 * Copyright (C) 2013 Marcos Cardinot
3 * Copyright (C) 2011 Alexander Wolf
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 */
19
20#include "MeteorShower.hpp"
21#include "MeteorShowers.hpp"
22#include "StelApp.hpp"
23#include "StelCore.hpp"
24#include "StelModuleMgr.hpp"
25#include "StelObject.hpp"
26#include "StelPainter.hpp"
27#include "StelTexture.hpp"
28#include "StelUtils.hpp"
29
30#include <QDebug>
31#include <QList>
32#include <QOpenGLFunctions>
33#include <QTextStream>
34#include <QVariant>
35#include <QVariantMap>
36
37StelTextureSP MeteorShower::radiantTexture;
38float MeteorShower::showLabels = true;
39bool MeteorShower::radiantMarkerEnabled = true;
40
41MeteorShower::MeteorShower(const QVariantMap& map)
42 : initialized(false)
43{
44 // return initialized if the mandatory fields are not present
45 if(!map.contains("showerID"))
46 return;
47
48 showerID = map.value("showerID").toString();
49 designation = map.value("designation").toString();
50 speed = map.value("speed").toInt();
51 rAlphaPeak = radiantAlpha = StelUtils::getDecAngle(map.value("radiantAlpha").toString());
52 rDeltaPeak = radiantDelta = StelUtils::getDecAngle(map.value("radiantDelta").toString());
53 driftAlpha = StelUtils::getDecAngle(map.value("driftAlpha").toString());
54 driftDelta = StelUtils::getDecAngle(map.value("driftDelta").toString());
55 parentObj = map.value("parentObj").toString();
56 pidx = map.value("pidx").toFloat();
57
58 if(map.contains("activity"))
59 {
60 foreach(const QVariant &ms, map.value("activity").toList())
61 {
62 QVariantMap activityMap = ms.toMap();
63 activityData d;
64 d.year = activityMap.value("year").toString();
65 d.zhr = activityMap.value("zhr").toInt();
66 d.variable = activityMap.value("variable").toString();
67 d.peak = activityMap.value("peak").toString();
68 d.start = activityMap.value("start").toString();
69 d.finish = activityMap.value("finish").toString();
70 activity.append(d);
71 }
72 }
73
74 updateCurrentData(getSkyQDateTime());
75
76 initialized = true;
77}
78
79MeteorShower::~MeteorShower()
80{
81 //
82}
83
84QVariantMap MeteorShower::getMap(void)
85{
86 QVariantMap map;
87 map["showerID"] = showerID;
88 map["designation"] = designation;
89 map["speed"] = speed;
90 map["radiantAlpha"] = rAlphaPeak;
91 map["radiantDelta"] = rDeltaPeak;
92 map["driftAlpha"] = driftAlpha;
93 map["driftDelta"] = driftDelta;
94 map["parentObj"] = parentObj;
95 map["pidx"] = pidx;
96
97 QVariantList activityList;
98 foreach(const activityData &p, activity)
99 {
100 QVariantMap activityMap;
101 activityMap["year"] = p.year;
102 activityMap["zhr"] = p.zhr;
103 activityMap["variable"] = p.variable;
104 activityMap["start"] = p.start;
105 activityMap["finish"] = p.finish;
106 activityMap["peak"] = p.peak;
107 activityList << activityMap;
108 }
109 map["activity"] = activityList;
110
111 return map;
112}
113
114float MeteorShower::getSelectPriority(const StelCore*) const
115{
116 return -2.0;
117}
118
119QString MeteorShower::getDesignation() const
120{
121 return designation;
122}
123
124QString MeteorShower::getDateFromJSON(QString jsondate) const
125{
126 QStringList parsedDate = jsondate.split(".");
127
128 return QString("%1 %2").arg(parsedDate.at(1).toInt()).arg(getMonthName(parsedDate.at(0).toInt()));
129}
130
131QString MeteorShower::getDayFromJSON(QString jsondate) const
132{
133 QStringList parsedDate = jsondate.split(".");
134
135 return QString("%1").arg(parsedDate.at(1).toInt());
136}
137
138int MeteorShower::getMonthFromJSON(QString jsondate) const
139{
140 QStringList parsedDate = jsondate.split(".");
141
142 return parsedDate.at(0).toInt();
143}
144
145QString MeteorShower::getMonthNameFromJSON(QString jsondate) const
146{
147 QStringList parsedDate = jsondate.split(".");
148
149 return QString("%1").arg(getMonthName(parsedDate.at(0).toInt()));
150}
151
152QString MeteorShower::getMonthName(int number) const
153{
154 QStringList monthList;
155 monthList.append(N_("January"));
156 monthList.append(N_("February"));
157 monthList.append(N_("March"));
158 monthList.append(N_("April"));
159 monthList.append(N_("May"));
160 monthList.append(N_("June"));
161 monthList.append(N_("July"));
162 monthList.append(N_("August"));
163 monthList.append(N_("September"));
164 monthList.append(N_("October"));
165 monthList.append(N_("November"));
166 monthList.append(N_("December"));
167
168 return q_(monthList.at(number-1));
169}
170
171QDateTime MeteorShower::getSkyQDateTime() const
172{
173 StelCore* core = StelApp::getInstance().getCore();
174 //get the current sky date
175 double JD = core->getJDay();
176 return StelUtils::jdToQDateTime(JD+StelUtils::getGMTShiftFromQT(JD)/24-core->getDeltaT(JD)/86400);
177}
178
179void MeteorShower::updateCurrentData(QDateTime skyDate)
180{
181 //Check if we have real data for the current sky year
182 int index = searchRealData(skyDate.toString("yyyy"));
183
184 /**************************
185 *ZHR info
186 **************************/
187 zhr = activity[index].zhr == 0 ? activity[0].zhr : activity[index].zhr;
188
189 if (zhr == -1)
190 variable = activity[index].variable.isEmpty() ? activity[0].variable : activity[index].variable;
191 else
192 variable = "";
193
194 /***************************
195 *Dates - start/finish/peak
196 ***************************/
197 QString dateStart = activity[index].start.isEmpty() ? activity[0].start : activity[index].start;
198 QString dateFinish = activity[index].finish.isEmpty() ? activity[0].finish : activity[index].finish;
199 QString datePeak = activity[index].peak.isEmpty() ? activity[0].peak : activity[index].peak;
200 QString yearBase = activity[index].year == "generic" ? skyDate.toString("yyyy") : activity[index].year;
201 QString yearS, yearF;
202
203 int monthStart = getMonthFromJSON(dateStart);
204 int monthFinish = getMonthFromJSON(dateFinish);
205
206 if(monthStart > monthFinish)
207 {
208 if(monthStart == skyDate.toString("MM").toInt())
209 {
210 yearS = yearBase;
211 yearF = QString("%1").arg(yearBase.toInt() + 1);
212 }
213 else
214 {
215 yearS = QString("%1").arg(yearBase.toInt() - 1);
216 yearF = yearBase;
217 }
218 }
219 else
220 {
221 yearS = yearF = yearBase;
222 }
223
224 start = QDateTime::fromString(dateStart + " " + yearS, "MM.dd yyyy");
225 finish = QDateTime::fromString(dateFinish + " " + yearF, "MM.dd yyyy");
226 peak = QDateTime::fromString(datePeak + " " + yearS, "MM.dd yyyy");
227
228 if (peak.operator <(start) || peak.operator >(finish))
229 peak = QDateTime::fromString(datePeak + " " + yearF, "MM.dd yyyy");
230
231 /***************************
232 *Activity - is active?
233 ***************************/
234 if(skyDate.operator >=(start) && skyDate.operator <=(finish))
235 {
236 if(index)
237 isActive = 1; // real data
238 else
239 isActive = 2; // generic data
240 }
241 else
242 {
243 isActive = 0; // isn't active
244 }
245
246 /**************************
247 *Radiant drift
248 *************************/
249 radiantAlpha = rAlphaPeak;
250 radiantDelta = rDeltaPeak;
251
252 if (isActive)
253 {
254 double time = (StelUtils::qDateTimeToJd(skyDate) - StelUtils::qDateTimeToJd(peak))*24;
255 radiantAlpha += (driftAlpha/120)*time;
256 radiantDelta += (driftDelta/120)*time;
257 }
258}
259
260int MeteorShower::searchRealData(QString yyyy) const
261{
262 int index = -1;
263 foreach(const activityData &p, activity)
264 {
265 index++;
266 if(p.year == yyyy)
267 return index;
268 }
269
270 return 0;
271}
272
273float MeteorShower::getSolarLongitude(QDateTime QDT) const
274{
275 //The number of days (positive or negative) since Greenwich noon,
276 //Terrestrial Time, on 1 January 2000 (J2000.0)
277 double n = StelUtils::qDateTimeToJd(QDT) - 2451545.0;
278
279 //The mean longitude of the Sun, corrected for the aberration of light
280 float slong = (280.460 + 0.9856474*n) / 360;
281 slong = (slong - (int) slong) * 360 - 1;
282
283 return slong;
284}
285
286QString MeteorShower::getInfoString(const StelCore* core, const InfoStringGroup& flags) const
287{
288 QString str;
289 QTextStream oss(&str);
290
291 QString mstdata = q_("generic data");
292 if(isActive == 1)
293 mstdata = q_("real data");
294
295 if(flags&Name)
296 oss << "<h2>" << getNameI18n() << " (" << showerID <<")</h2>";
297
298 if(flags&Extra)
299 oss << q_("Type: <b>%1</b> (%2)").arg(q_("meteor shower"), mstdata) << "<br />";
300
301 // Ra/Dec etc.
302 oss << getPositionInfoString(core, flags);
303
304 if(flags&Extra)
305 {
306 oss << QString("%1: %2/%3")
307 .arg(q_("Radiant drift (per day)"))
308 .arg(StelUtils::radToHmsStr(driftAlpha/5))
309 .arg(StelUtils::radToDmsStr(driftDelta/5));
310 oss << "<br />";
311
312 oss << q_("Geocentric meteoric velocity: %1 km/s").arg(speed) << "<br />";
313 if(pidx>0)
314 {
315 oss << q_("The population index: %1").arg(pidx) << "<br />";
316 }
317
318 if(!parentObj.isEmpty())
319 {
320 oss << q_("Parent body: %1").arg(parentObj) << "<br />";
321 }
322
323 if(start.toString("M") == finish.toString("M"))
324 {
325 oss << QString("%1: %2 - %3 %4")
326 .arg(q_("Active"))
327 .arg(start.toString("d"))
328 .arg(finish.toString("d"))
329 .arg(start.toString("MMMM"));
330 }
331 else
332 {
333 oss << QString("%1: %2 - %3")
334 .arg(q_("Active"))
335 .arg(start.toString("d MMMM"))
336 .arg(finish.toString("d MMMM"));
337 }
338 oss << "<br />";
339 oss << q_("Maximum: %1").arg(peak.toString("d MMMM"));
340
341 QString slong = QString::number( MeteorShower::getSolarLongitude(peak), 'f', 2 );
342 oss << QString(" (%1 %2&deg;)").arg(q_("Solar longitude is")).arg(slong);
343 oss << "<br />";
344
345 if(zhr>0)
346 {
347 oss << QString("ZHR<sub>max</sub>: %1").arg(zhr) << "<br />";
348 }
349 else
350 {
351 oss << QString("ZHR<sub>max</sub>: %1").arg(q_("variable"));
352 if(!variable.isEmpty())
353 {
354 oss << "; " << variable;
355 }
356 oss << "<br />";
357 }
358 }
359
360 postProcessInfoString(str, flags);
361
362 return str;
363}
364
365Vec3f MeteorShower::getInfoColor(void) const
366{
367 return StelApp::getInstance().getVisionModeNight() ? Vec3f(0.6, 0.0, 0.0) : Vec3f(1.0, 1.0, 1.0);
368}
369
370double MeteorShower::getAngularSize(const StelCore*) const
371{
372 return 0.001;
373}
374
375void MeteorShower::update(double deltaTime)
376{
377 labelsFader.update((int)(deltaTime*1000));
378 updateCurrentData(getSkyQDateTime());
379}
380
381void MeteorShower::draw(StelPainter& painter)
382{
383 StelUtils::spheToRect(radiantAlpha, radiantDelta, XYZ);
384 painter.getProjector()->project(XYZ, XY);
385
386 glEnable(GL_BLEND);
387 glBlendFunc(GL_SRC_ALPHA, GL_ONE);
388
389 qreal r, g, b;
390 float alpha = 0.85f + ((double) rand() / (RAND_MAX))/10;
391 switch(isActive)
392 {
393 case 1: //Active, real data
394 GETSTELMODULE(MeteorShowers)->getColorARR().getRgbF(&r,&g,&b);
395 break;
396 case 2: //Active, generic data
397 GETSTELMODULE(MeteorShowers)->getColorARG().getRgbF(&r,&g,&b);
398 break;
399 default: //Inactive
400 GETSTELMODULE(MeteorShowers)->getColorIR().getRgbF(&r,&g,&b);
401 }
402
403 painter.setColor(r, g, b, alpha);
404
405 if (MeteorShower::radiantMarkerEnabled)
406 {
407 MeteorShower::radiantTexture->bind();
408 painter.drawSprite2dMode(XY[0], XY[1], 10);
409
410 if (MeteorShower::showLabels)
411 {
412 float size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter();
413 float shift = 8.f + size/1.8f;
414 painter.drawText(XY[0]+shift, XY[1]+shift, getNameI18n(), 0, 0, 0, false);
415 }
416 }
417}
0418
=== added file 'plugins/MeteorShowers/src/MeteorShower.hpp'
--- plugins/MeteorShowers/src/MeteorShower.hpp 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/src/MeteorShower.hpp 2014-03-10 17:28:07 +0000
@@ -0,0 +1,186 @@
1/*
2 * Copyright (C) 2013 Marcos Cardinot
3 * Copyright (C) 2011 Alexander Wolf
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 */
19
20#ifndef _METEORSHOWER_HPP_
21#define _METEORSHOWER_HPP_
22
23#include <QDateTime>
24#include <QVariantMap>
25#include <QString>
26
27#include "StelFader.hpp"
28#include "StelObject.hpp"
29#include "StelPainter.hpp"
30#include "StelTextureTypes.hpp"
31#include "StelTranslator.hpp"
32
33class StelPainter;
34
35//! @class MeteorShower
36//! A MeteorShower object represents one meteor shower on the sky.
37//! Details about the meteor showers are passed using a QVariant which contains
38//! a map of data from the json file.
39
40class MeteorShower : public StelObject
41{
42 friend class MeteorShowers;
43
44public:
45 //! @param id The official ID designation for a meteor shower, e.g. "LYR"
46 MeteorShower(const QVariantMap& map);
47 ~MeteorShower();
48
49 //! Get a QVariantMap which describes the meteor shower. Could be used to
50 //! create a duplicate.
51 QVariantMap getMap(void);
52
53 virtual QString getType(void) const
54 {
55 return "MeteorShower";
56 }
57 virtual float getSelectPriority(const StelCore* core) const;
58
59 //! Get an HTML string to describe the object
60 //! @param core A pointer to the core
61 //! @flags a set of flags with information types to include.
62 virtual QString getInfoString(const StelCore* core, const InfoStringGroup& flags) const;
63 virtual Vec3f getInfoColor(void) const;
64 virtual Vec3d getJ2000EquatorialPos(const StelCore*) const
65 {
66 return XYZ;
67 }
68 virtual double getAngularSize(const StelCore* core) const;
69 virtual QString getNameI18n(void) const
70 {
71 return q_(designation);
72 }
73 virtual QString getEnglishName(void) const
74 {
75 return designation;
76 }
77 QString getDesignation(void) const;
78 void update(double deltaTime);
79 static float showLabels;
80
81 //! Get current activity status of MS
82 //! @return 0:inactive 1:activeRealData 2:activeGenericData
83 int getStatus()
84 {
85 return isActive;
86 }
87
88 //! Get peak
89 //! @return peak
90 QDateTime getPeak()
91 {
92 return peak;
93 }
94
95 //! Get zhr
96 //! @return ZHR
97 int getZHR()
98 {
99 return zhr;
100 }
101
102private:
103 Vec3d XYZ; //! Cartesian equatorial position
104 Vec3d XY; //! Store temporary 2D position
105
106 static StelTextureSP radiantTexture;
107 static bool radiantMarkerEnabled;
108
109 LinearFader labelsFader;
110
111 typedef struct
112 {
113 QString year; //! Value of year for actual data
114 int zhr; //! ZHR of shower
115 QString variable; //! value of variable for ZHR
116 QString start; //! First day for activity
117 QString finish; //! Latest day for activity
118 QString peak; //! Day with maximum for activity
119 } activityData;
120
121 bool initialized;
122 QString showerID; //! The ID of the meteor shower
123 QString designation; //! The designation of the meteor shower
124 QList<activityData> activity; //! List of activity
125 int speed; //! Speed of meteors
126 double rAlphaPeak; //! R.A. for radiant of meteor shower on the peak day
127 double rDeltaPeak; //! Dec. for radiant of meteor shower on the peak day
128 double driftAlpha; //! Drift of R.A.
129 double driftDelta; //! Drift of Dec.
130 QString parentObj; //! Parent object for meteor shower
131 float pidx; //! The population index
132
133 //current information
134 double radiantAlpha; //! Current R.A. for radiant of meteor shower
135 double radiantDelta; //! Current Dec. for radiant of meteor shower
136 int zhr; //! ZHR of shower
137 QString variable; //! value of variable for ZHR
138 QDateTime start; //! First day for activity
139 QDateTime finish; //! Latest day for activity
140 QDateTime peak; //! Day with maximum for activity
141
142 int isActive; //! Check if the radiant is active for the current sky date
143 //! 0=inactive; 1=realData 2=genericData
144
145 void draw(StelPainter &painter);
146
147 //! Get a date string from JSON file and parse it for display in info corner
148 //! @param jsondate A string from JSON file
149 QString getDateFromJSON(QString jsondate) const;
150
151 //! Get a day from JSON file and parse it for display in info corner
152 //! @param jsondate A string from JSON file
153 QString getDayFromJSON(QString jsondate) const;
154
155 //! Get a month string from JSON file and parse it for display in info corner
156 //! @param jsondate A string from JSON file
157 int getMonthFromJSON(QString jsondate) const;
158
159 //! Get a month string from JSON file and parse it for display in info corner
160 //! @param jsondate A string from JSON file
161 QString getMonthNameFromJSON(QString jsondate) const;
162
163 //! Get a month name from month number
164 //! @param jsondate A string from JSON file
165 QString getMonthName(int number) const;
166
167 //! Get the current sky QDateTime
168 //! @return Current QDateTime of sky
169 QDateTime getSkyQDateTime() const;
170
171 //! Update value of current information(zhr, variable, stat, finish and peak)
172 //! @param current sky QDateTime
173 void updateCurrentData(QDateTime skyDate);
174
175 //! Check if the JSON file has real data to a given year
176 //! @param yyyy year to check
177 //! @return index of the year or 0 to generic data
178 int searchRealData(QString yyyy) const;
179
180 //! Get the solar longitude for a specified date
181 //! @param QDT QDateTime
182 //! @return solar longitude in degree
183 float getSolarLongitude(QDateTime QDT) const;
184};
185
186#endif /*_METEORSHOWER_HPP_*/
0187
=== added file 'plugins/MeteorShowers/src/MeteorShowers.cpp'
--- plugins/MeteorShowers/src/MeteorShowers.cpp 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/src/MeteorShowers.cpp 2014-03-10 17:28:07 +0000
@@ -0,0 +1,1225 @@
1/*
2 * Copyright (C) 2013 Marcos Cardinot
3 * Copyright (C) 2011 Alexander Wolf
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 */
19
20#include "StelProjector.hpp"
21#include "StelPainter.hpp"
22#include "StelApp.hpp"
23#include "StelCore.hpp"
24#include "StelGui.hpp"
25#include "StelGuiItems.hpp"
26#include "StelLocaleMgr.hpp"
27#include "StelObjectMgr.hpp"
28#include "StelModuleMgr.hpp"
29#include "StelTextureMgr.hpp"
30#include "StelJsonParser.hpp"
31#include "StelIniParser.hpp"
32#include "StelFileMgr.hpp"
33#include "LabelMgr.hpp"
34#include "LandscapeMgr.hpp"
35#include "StelTranslator.hpp"
36#include "StelUtils.hpp"
37#include "MeteorShower.hpp"
38#include "MeteorShowers.hpp"
39#include "MeteorShowerDialog.hpp"
40#include "MeteorStream.hpp"
41#include "StelProgressController.hpp"
42
43#include <QAction>
44#include <QColor>
45#include <QDebug>
46#include <QDir>
47#include <QFile>
48#include <QFileInfo>
49#include <QKeyEvent>
50#include <QList>
51#include <QNetworkAccessManager>
52#include <QNetworkReply>
53#include <QProgressBar>
54#include <QSharedPointer>
55#include <QStringList>
56#include <QTimer>
57#include <QVariant>
58#include <QVariantMap>
59
60#define CATALOG_FORMAT_VERSION 1 /* Version of format of catalog */
61
62/*
63 This method is the one called automatically by the StelModuleMgr just
64 after loading the dynamic library
65*/
66StelModule* MeteorShowersStelPluginInterface::getStelModule() const
67{
68 return new MeteorShowers();
69}
70
71StelPluginInfo MeteorShowersStelPluginInterface::getPluginInfo() const
72{
73 // Allow to load the resources when used as a static plugin
74 Q_INIT_RESOURCE(MeteorShower);
75
76 StelPluginInfo info;
77 info.id = "MeteorShowers";
78 info.displayedName = N_("Meteor Showers");
79 info.authors = "Marcos Cardinot";
80 info.contact = "mcardinot@gmail.com";
81 info.description = N_("This plugin give visualization of the meteor showers, show information about meteor showers and displays marker for radiants in activity range for each meteor showers.");
82 info.version = METEORSHOWERS_PLUGIN_VERSION;
83 return info;
84}
85
86/*
87 Constructor
88*/
89MeteorShowers::MeteorShowers()
90 : flagShowMS(false)
91 , OnIcon(NULL)
92 , OffIcon(NULL)
93 , GlowIcon(NULL)
94 , toolbarButton(NULL)
95 , progressBar(NULL)
96{
97 setObjectName("MeteorShowers");
98 configDialog = new MeteorShowerDialog();
99 conf = StelApp::getInstance().getSettings();
100}
101
102/*
103 Destructor
104*/
105MeteorShowers::~MeteorShowers()
106{
107 delete configDialog;
108
109 if(GlowIcon)
110 delete GlowIcon;
111 if(OnIcon)
112 delete OnIcon;
113 if(OffIcon)
114 delete OffIcon;
115
116 active.clear();
117 activeInfo.clear();
118}
119
120/*
121 Reimplementation of the getCallOrder method
122*/
123double MeteorShowers::getCallOrder(StelModuleActionName actionName) const
124{
125 if(actionName == StelModule::ActionDraw)
126 return StelApp::getInstance().getModuleMgr().getModule("MeteorMgr")->getCallOrder(actionName)+0;
127 return 0;
128}
129
130void MeteorShowers::init()
131{
132 upgradeConfigIni();
133
134 try
135 {
136 StelFileMgr::makeSureDirExistsAndIsWritable(StelFileMgr::getUserDir()+"/modules/MeteorShowers");
137
138 // If no settings in the main config file, create with defaults
139 if(!conf->childGroups().contains("MeteorShowers"))
140 {
141 qDebug() << "MeteorShowers: no MeteorShower section exists in main config file - creating with defaults";
142 restoreDefaultConfigIni();
143 }
144
145 // populate settings from main config file.
146 readSettingsFromConfig();
147
148 showersJsonPath = StelFileMgr::findFile("modules/MeteorShowers", (StelFileMgr::Flags)(StelFileMgr::Directory|StelFileMgr::Writable)) + "/showers.json";
149
150 texPointer = StelApp::getInstance().getTextureManager().createTexture(StelFileMgr::getInstallationDir()+"/textures/pointeur5.png");
151 MeteorShower::radiantTexture = StelApp::getInstance().getTextureManager().createTexture(":/MeteorShowers/radiant.png");
152
153 // key bindings and other actions
154 QString msGroup = N_("Meteor Shower");
155 addAction("actionShow_MeteorShower", msGroup, N_("Show meteor showers"), "msVisible", "Ctrl+Alt+M");
156 addAction("actionShow_radiant_Labels", msGroup, N_("Radiant labels"), "labelsVisible", "Shift+M");
157 addAction("actionShow_MeteorShower_ConfigDialog", msGroup, N_("Meteor Shower configuration window"), configDialog, "visible", "Alt+M");
158
159 GlowIcon = new QPixmap(":/graphicGui/glow32x32.png");
160 OnIcon = new QPixmap(":/MeteorShowers/btMS-on.png");
161 OffIcon = new QPixmap(":/MeteorShowers/btMS-off.png");
162
163 setFlagShowMSButton(flagShowMSButton);
164 setFlagShowMS(getEnableAtStartup());
165 }
166 catch(std::runtime_error &e)
167 {
168 qWarning() << "MeteorShowers: init error:" << e.what();
169 return;
170 }
171
172 // A timer for hiding alert messages
173 messageTimer = new QTimer(this);
174 messageTimer->setSingleShot(true); // recurring check for update
175 messageTimer->setInterval(9000); // 6 seconds should be enough time
176 messageTimer->stop();
177 connect(messageTimer, SIGNAL(timeout()), this, SLOT(messageTimeout()));
178
179 // If the json file does not already exist, create it from the resource in the QT resource
180 if(!QFileInfo(showersJsonPath).exists())
181 {
182 if(!checkJsonFileFormat() || getJsonFileFormatVersion()<CATALOG_FORMAT_VERSION)
183 {
184 displayMessage(q_("The old showers.json file is no longer compatible - using default file"), "#bb0000");
185 restoreDefaultJsonFile();
186 }
187 else
188 {
189 qDebug() << "MeteorShowers: showers.json does not exist - copying default file to" << QDir::toNativeSeparators(showersJsonPath);
190 restoreDefaultJsonFile();
191 }
192 }
193
194 qDebug() << "MeteorShowers: loading catalog file:" << QDir::toNativeSeparators(showersJsonPath);
195
196 // create meteor Showers according to content os Showers.json file
197 readJsonFile();
198
199 // Set up download manager and the update schedule
200 downloadMgr = new QNetworkAccessManager(this);
201 connect(downloadMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(updateDownloadComplete(QNetworkReply*)));
202 updateState = CompleteNoUpdates;
203 updateTimer = new QTimer(this);
204 updateTimer->setSingleShot(false); // recurring check for update
205 updateTimer->setInterval(13000); // check once every 13 seconds to see if it is time for an update
206 connect(updateTimer, SIGNAL(timeout()), this, SLOT(checkForUpdate()));
207 updateTimer->start();
208
209 // skyDate startup
210 skyDate = StelUtils::jdToQDateTime(StelApp::getInstance().getCore()->getJDay());
211
212 GETSTELMODULE(StelObjectMgr)->registerStelObjectMgr(this);
213}
214
215void MeteorShowers::deinit()
216{
217 MeteorShower::radiantTexture.clear();
218 texPointer.clear();
219}
220
221void MeteorShowers::upgradeConfigIni(void)
222{
223 // Upgrade settings for MeteorShower plugin
224 if (conf->contains("MeteorShowers/flag_show_ms"))
225 {
226 bool b = conf->value("MeteorShowers/flag_show_ms", false).toBool();
227 if (!conf->contains("MeteorShowers/enable_at_startup"))
228 conf->setValue("MeteorShowers/enable_at_startup", b);
229 conf->remove("MeteorShowers/flag_show_ms");
230 }
231}
232
233void MeteorShowers::setFlagShowMS(bool b)
234{
235 if(toolbarButton != NULL)
236 toolbarButton->setChecked(b);
237
238 flagShowMS=b;
239}
240
241// Define whether the button toggling meteor showers should be visible
242void MeteorShowers::setFlagShowMSButton(bool b)
243{
244 StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
245 if(b)
246 {
247 if(toolbarButton==NULL)
248 {
249 // Create the MeteorShowers button
250 toolbarButton = new StelButton(NULL, *OnIcon, *OffIcon, *GlowIcon, "actionShow_MeteorShower");
251 }
252 gui->getButtonBar()->addButton(toolbarButton, "065-pluginsGroup");
253 }
254 else
255 {
256 gui->getButtonBar()->hideButton("actionShow_MeteorShower");
257 }
258 flagShowMSButton = b;
259}
260
261bool MeteorShowers::changedSkyDate(StelCore* core)
262{
263 double JD = core->getJDay();
264 skyDate = StelUtils::jdToQDateTime(JD+StelUtils::getGMTShiftFromQT(JD)/24-core->getDeltaT(JD)/86400);
265 if(skyDate.toString("MM.dd.yyyy") != lastSkyDate.toString("MM.dd.yyyy")) //if the sky date changed
266 return true;
267 else
268 return false;
269}
270
271void MeteorShowers::draw(StelCore* core)
272{
273 if(!getFlagShowMS())
274 return;
275
276 StelPainter painter(core->getProjection(StelCore::FrameJ2000));
277 drawMarker(core, painter);
278
279 if(GETSTELMODULE(StelObjectMgr)->getFlagSelectedObjectPointer())
280 drawPointer(core, painter);
281
282 painter.setProjector(core->getProjection(StelCore::FrameAltAz));
283 drawStream(core, painter);
284}
285
286void MeteorShowers::drawMarker(StelCore* core, StelPainter& painter)
287{
288 Q_UNUSED(core);
289 painter.setFont(labelFont);
290
291 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
292 glEnable(GL_BLEND);
293 glEnable(GL_TEXTURE_2D);
294
295 foreach(const MeteorShowerP& ms, mShowers)
296 {
297 ms->updateCurrentData(skyDate);
298
299 bool flag=true;
300 if (ms->getStatus()==0 && getFlagActiveRadiant())
301 flag = false;
302
303 if(ms && ms->initialized && flag)
304 ms->draw(painter);
305 }
306 glDisable(GL_TEXTURE_2D);
307}
308
309void MeteorShowers::drawPointer(StelCore* core, StelPainter& painter)
310{
311 const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
312
313 const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("MeteorShower");
314 if(!newSelected.empty())
315 {
316 const StelObjectP obj = newSelected[0];
317 Vec3d pos=obj->getJ2000EquatorialPos(core);
318
319 Vec3d screenpos;
320 // Compute 2D pos and return if outside screen
321 if(!painter.getProjector()->project(pos, screenpos))
322 return;
323
324 const Vec3f& c(obj->getInfoColor());
325 painter.setColor(c[0],c[1],c[2]);
326 texPointer->bind();
327 painter.enableTexture2d(true);
328 glEnable(GL_BLEND);
329 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode
330
331 float size = obj->getAngularSize(core)*M_PI/180.*prj->getPixelPerRadAtCenter();
332 size+=20.f + 10.f*std::sin(2.f * StelApp::getInstance().getTotalRunTime());
333
334 painter.drawSprite2dMode(screenpos[0]-size/2, screenpos[1]-size/2, 10.f, 90);
335 painter.drawSprite2dMode(screenpos[0]-size/2, screenpos[1]+size/2, 10.f, 0);
336 painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]+size/2, 10.f, -90);
337 painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]-size/2, 10.f, -180);
338 painter.setColor(1,1,1,0);
339 }
340}
341
342void MeteorShowers::drawStream(StelCore* core, StelPainter& painter)
343{
344 LandscapeMgr* landmgr = (LandscapeMgr*)StelApp::getInstance().getModuleMgr().getModule("LandscapeMgr");
345 if(landmgr->getFlagAtmosphere() && landmgr->getLuminance()>5)
346 return;
347
348 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
349 glEnable(GL_BLEND);
350 painter.enableTexture2d(false);
351
352 int index = 0;
353 if(active.size() > 0)
354 {
355 foreach(const activeData &a, activeInfo)
356 {
357 Q_UNUSED(a);
358 // step through and draw all active meteors
359 for(std::vector<MeteorStream*>::iterator iter = active[index].begin(); iter != active[index].end(); ++iter)
360 {
361 (*iter)->draw(core, painter);
362 }
363 index++;
364 }
365 }
366}
367
368int MeteorShowers::calculateZHR(int zhr, QString variable, QDateTime start, QDateTime finish, QDateTime peak)
369{
370 /***************************************
371 * Get ZHR ranges
372 ***************************************/
373 int highZHR;
374 int lowZHR;
375 //bool multPeak = false; //multiple peaks
376 if(zhr != -1) //isn't variable
377 {
378 highZHR = zhr;
379 lowZHR = 0;
380 }
381 else
382 {
383 QStringList varZHR = variable.split("-");
384 lowZHR = varZHR.at(0).toInt();
385 if(varZHR.at(1).contains("*"))
386 {
387 //multPeak = true;
388 highZHR = varZHR[1].replace("*", "").toInt();
389 }
390 else
391 {
392 highZHR = varZHR.at(1).toInt();
393 }
394 }
395
396 /***************************************
397 * Convert time intervals
398 ***************************************/
399 double startJD = StelUtils::qDateTimeToJd(start);
400 double finishJD = StelUtils::qDateTimeToJd(finish);
401 double peakJD = StelUtils::qDateTimeToJd(peak);
402 double currentJD = StelUtils::qDateTimeToJd(skyDate);
403
404 /***************************************
405 * Gaussian distribution
406 ***************************************/
407 double sd; //standard deviation
408 if (currentJD >= startJD && currentJD < peakJD) //left side of gaussian
409 sd = (peakJD - startJD)/2;
410 else
411 sd = (finishJD - peakJD)/2;
412
413 double gaussian = highZHR * std::exp( - std::pow(currentJD - peakJD, 2) / (sd*sd) ) + lowZHR;
414
415 return (int) ((int) ((gaussian - (int) gaussian) * 10) >= 5 ? gaussian+1 : gaussian);
416}
417
418void MeteorShowers::updateActiveInfo(void)
419{
420 foreach(const MeteorShowerP& ms, mShowers)
421 {
422 if(ms && ms->initialized)
423 {
424 //if the meteor shower is active, get data
425 if(ms->isActive)
426 {
427 //First, check if there is already data about the constellation in "activeInfo"
428 //The var "index" will be updated to show the correct place do put the new information
429 int index = 0;
430 foreach(const activeData &a, activeInfo)
431 {
432 if(a.showerID == ms->showerID) //exists
433 break;
434 index++;
435 }
436
437 if(activeInfo.size() < index + 1) //new?, put in the end
438 {
439 activeData newData;
440 newData.showerID = ms->showerID;
441 newData.speed = ms->speed;
442 newData.radiantAlpha = ms->radiantAlpha;
443 newData.radiantDelta = ms->radiantDelta;
444 newData.zhr = ms->zhr;
445 newData.variable = ms->variable;
446 newData.start = ms->start;
447 newData.finish = ms->finish;
448 newData.peak = ms->peak;
449 newData.status = ms->isActive;
450 activeInfo.append(newData);
451 }
452 else //just overwrites
453 {
454 activeInfo[index].zhr = ms->zhr;
455 activeInfo[index].variable = ms->variable;
456 activeInfo[index].start = ms->start;
457 activeInfo[index].finish = ms->finish;
458 activeInfo[index].peak = ms->peak;
459 activeInfo[index].status = ms->isActive;
460 }
461 }
462 }
463 }
464 lastSkyDate = skyDate;
465}
466
467void MeteorShowers::update(double deltaTime)
468{
469 if(!getFlagShowMS())
470 return;
471
472 StelCore* core = StelApp::getInstance().getCore();
473
474 double timeRate = core->getTimeRate();
475 if(timeRate > 0.2)
476 return;
477
478 //check if the sky date changed
479 bool changedDate = changedSkyDate(core);
480
481 if(changedDate)
482 {
483 // clear data of all MS active
484 activeInfo.clear();
485
486 // Is GUI visible and the year changed? refresh ranges
487 if(configDialog->visible() && lastSkyDate.toString("yyyy") != skyDate.toString("yyyy"))
488 configDialog->refreshRangeDates();
489 }
490
491 updateActiveInfo();
492
493 deltaTime*=1000;
494
495 std::vector<std::vector<MeteorStream*> >::iterator iterOut;
496 std::vector<MeteorStream*>::iterator iterIn;
497 int index = 0;
498 if(active.size() > 0)
499 {
500 // step through and update all active meteors
501 for(iterOut = active.begin(); iterOut != active.end(); ++iterOut)
502 {
503 for(iterIn = active[index].begin(); iterIn != active[index].end(); ++iterIn)
504 {
505 if(!(*iterIn)->update(deltaTime))
506 {
507 delete *iterIn;
508 active[index].erase(iterIn);
509 iterIn--;
510 }
511 }
512 if(active[index].empty())
513 {
514 active.erase(iterOut);
515 iterOut--;
516 index--;
517 }
518 index++;
519 }
520 }
521
522 index = 0;
523 foreach(const activeData &a, activeInfo)
524 {
525 ZHR = calculateZHR(a.zhr, a.variable, a.start, a.finish, a.peak);
526
527 // only makes sense given lifetimes of meteors to draw when timeSpeed is realtime
528 // otherwise high overhead of large numbers of meteors
529 double tspeed = timeRate*86400; // sky seconds per actual second
530 if(tspeed<=0 || fabs(tspeed)>1.)
531 return; // don't start any more meteors
532
533 // if stellarium has been suspended, don't create huge number of meteors to
534 // make up for lost time!
535 if(deltaTime > 500)
536 deltaTime = 500;
537
538 // determine average meteors per frame needing to be created
539 int mpf = (int)((double)ZHR*zhrToWsr*deltaTime/1000.0 + 0.5);
540 if(mpf<1)
541 mpf = 1;
542
543 std::vector<MeteorStream*> aux;
544 if(active.empty() || active.size() < (unsigned) index+1)
545 active.push_back(aux);
546
547 for(int i=0; i<mpf; ++i)
548 {
549 // start new meteor based on ZHR time probability
550 double prob = ((double)rand())/RAND_MAX;
551 if(ZHR>0 && prob<((double)ZHR*zhrToWsr*deltaTime/1000.0/(double)mpf))
552 {
553 MeteorStream *m = new MeteorStream(core, a.speed, a.radiantAlpha, a.radiantDelta);
554 active[index].push_back(m);
555 }
556 }
557 index++;
558 }
559}
560
561QList<MeteorShowerP> MeteorShowers::searchEvents(QDate dateFrom, QDate dateTo) const
562{
563 QList<MeteorShowerP> result;
564 QDate date;
565
566 foreach(const MeteorShowerP& ms, mShowers)
567 {
568 date = dateFrom;
569 while(date.operator <=(dateTo))
570 {
571 ms->updateCurrentData((QDateTime) date);
572 if(ms->isActive)
573 {
574 result.append(ms);
575 break;
576 }
577 date = date.addDays(1);
578 }
579 }
580
581 return result;
582}
583
584QList<StelObjectP> MeteorShowers::searchAround(const Vec3d& av, double limitFov, const StelCore*) const
585{
586 QList<StelObjectP> result;
587
588 if(!getFlagRadiant())
589 return result;
590
591 Vec3d v(av);
592 v.normalize();
593 double cosLimFov = cos(limitFov * M_PI/180.);
594 Vec3d equPos;
595
596 foreach(const MeteorShowerP& ms, mShowers)
597 {
598 if(ms->initialized)
599 {
600 equPos = ms->XYZ;
601 equPos.normalize();
602 if(equPos[0]*v[0] + equPos[1]*v[1] + equPos[2]*v[2]>=cosLimFov)
603 {
604 result.append(qSharedPointerCast<StelObject>(ms));
605 }
606 }
607 }
608
609 return result;
610}
611
612StelObjectP MeteorShowers::searchByName(const QString& englishName) const
613{
614 if(!getFlagRadiant())
615 return NULL;
616
617 foreach(const MeteorShowerP& ms, mShowers)
618 {
619 if(ms->getEnglishName().toUpper() == englishName.toUpper())
620 return qSharedPointerCast<StelObject>(ms);
621 }
622
623 return NULL;
624}
625
626StelObjectP MeteorShowers::searchByNameI18n(const QString& nameI18n) const
627{
628 if(!getFlagRadiant())
629 return NULL;
630
631 foreach(const MeteorShowerP& ms, mShowers)
632 {
633 if(ms->getNameI18n().toUpper() == nameI18n.toUpper())
634 return qSharedPointerCast<StelObject>(ms);
635 }
636
637 return NULL;
638}
639
640QStringList MeteorShowers::listMatchingObjectsI18n(const QString& objPrefix, int maxNbItem, bool useStartOfWords) const
641{
642 QStringList result;
643 if(!getFlagRadiant())
644 return result;
645
646 if(maxNbItem==0)
647 return result;
648
649 QString sn;
650 bool find;
651
652 foreach(const MeteorShowerP& ms, mShowers)
653 {
654 sn = ms->getNameI18n();
655 find = false;
656 if (useStartOfWords)
657 {
658 if (sn.toUpper().left(objPrefix.length()) == objPrefix.toUpper())
659 find = true;
660 }
661 else
662 {
663 if (sn.contains(objPrefix, Qt::CaseInsensitive))
664 find = true;
665 }
666 if (find)
667 result << sn;
668
669
670 }
671
672 result.sort();
673
674 if(result.size()>maxNbItem)
675 result.erase(result.begin()+maxNbItem, result.end());
676
677 return result;
678}
679
680QStringList MeteorShowers::listMatchingObjects(const QString& objPrefix, int maxNbItem, bool useStartOfWords) const
681{
682 QStringList result;
683 if(!getFlagRadiant())
684 return result;
685
686 if(maxNbItem==0)
687 return result;
688
689 QString sn;
690 bool find;
691 foreach(const MeteorShowerP& ms, mShowers)
692 {
693 sn = ms->getEnglishName();
694 find = false;
695 if(useStartOfWords)
696 {
697 if(objPrefix.toUpper()==sn.toUpper().left(objPrefix.length()))
698 find = true;
699 }
700 else
701 {
702 if(sn.contains(objPrefix, Qt::CaseInsensitive))
703 find = true;
704 }
705 if(find)
706 {
707 result << sn;
708 }
709
710 sn = ms->getDesignation();
711 find = false;
712 if(useStartOfWords)
713 {
714 if(objPrefix.toUpper()==sn.toUpper().left(objPrefix.length()))
715 find = true;
716 }
717 else
718 {
719 if(sn.contains(objPrefix, Qt::CaseInsensitive))
720 find = true;
721 }
722 if(find)
723 {
724 result << sn;
725 }
726 }
727
728 result.sort();
729 if(result.size()>maxNbItem)
730 result.erase(result.begin()+maxNbItem, result.end());
731
732 return result;
733}
734
735QStringList MeteorShowers::listAllObjects(bool inEnglish) const
736{
737 QStringList result;
738 if(inEnglish)
739 {
740 foreach(const MeteorShowerP& ms, mShowers)
741 {
742 result << ms->getEnglishName();
743 }
744 }
745 else
746 {
747 foreach(const MeteorShowerP& ms, mShowers)
748 {
749 result << ms->getNameI18n();
750 }
751 }
752 return result;
753}
754
755bool MeteorShowers::configureGui(bool show)
756{
757 if(show)
758 configDialog->setVisible(true);
759
760 return true;
761}
762
763QVariantMap MeteorShowers::loadShowersMap(QString path)
764{
765 if(path.isEmpty())
766 path = showersJsonPath;
767
768 QVariantMap map;
769 QFile jsonFile(path);
770 if(!jsonFile.open(QIODevice::ReadOnly))
771 qWarning() << "MeteorShowers: cannot open" << path;
772 else
773 map = StelJsonParser::parse(jsonFile.readAll()).toMap();
774
775 jsonFile.close();
776 return map;
777}
778
779void MeteorShowers::readJsonFile(void)
780{
781 setShowersMap(loadShowersMap());
782}
783
784void MeteorShowers::setShowersMap(const QVariantMap& map)
785{
786 mShowers.clear();
787 QVariantMap msMap = map.value("showers").toMap();
788 foreach(QString msKey, msMap.keys())
789 {
790 QVariantMap msData = msMap.value(msKey).toMap();
791 msData["showerID"] = msKey;
792
793 MeteorShowerP ms(new MeteorShower(msData));
794 if(ms->initialized)
795 mShowers.append(ms);
796 }
797}
798
799void MeteorShowers::restoreDefaults(void)
800{
801 restoreDefaultConfigIni();
802 restoreDefaultJsonFile();
803 readJsonFile();
804 readSettingsFromConfig();
805}
806
807void MeteorShowers::restoreDefaultConfigIni(void)
808{
809 conf->beginGroup("MeteorShowers");
810
811 // delete all existing MeteorShower settings...
812 conf->remove("");
813
814 conf->setValue("enable_at_startup", false);
815 conf->setValue("updates_enabled", true);
816 conf->setValue("url", "http://stellarium.org/json/showers.json");
817 conf->setValue("update_frequency_hours", 100);
818 conf->setValue("flag_show_ms_button", true);
819 conf->setValue("flag_show_radiants", true);
820 conf->setValue("flag_active_radiants", false);
821
822 conf->setValue("colorARG", "0, 255, 240");
823 conf->setValue("colorARR", "255, 240, 0");
824 conf->setValue("colorIR", "255, 255, 255");
825
826 conf->setValue("show_radiant_labels", true);
827
828 conf->endGroup();
829}
830
831void MeteorShowers::restoreDefaultJsonFile(void)
832{
833 if(QFileInfo(showersJsonPath).exists())
834 backupJsonFile(true);
835
836 QFile src(":/MeteorShowers/showers.json");
837 if(!src.copy(showersJsonPath))
838 {
839 qWarning() << "MeteorShowers: cannot copy JSON resource to" << showersJsonPath;
840 }
841 else
842 {
843 qDebug() << "MeteorShowers: copied default showers.json to" << showersJsonPath;
844 // The resource is read only, and the new file inherits this... make sure the new file
845 // is writable by the Stellarium process so that updates can be done.
846 QFile dest(showersJsonPath);
847 dest.setPermissions(dest.permissions() | QFile::WriteOwner);
848
849 // Make sure that in the case where an online update has previously been done, but
850 // the json file has been manually removed, that an update is schreduled in a timely
851 // manner
852 conf->remove("MeteorShowers/last_update");
853 lastUpdate = QDateTime::fromString("2013-12-31T12:00:00", Qt::ISODate);
854 }
855}
856
857bool MeteorShowers::backupJsonFile(bool deleteOriginal)
858{
859 QFile old(showersJsonPath);
860 if(!old.exists())
861 {
862 qWarning() << "MeteorShowers: no file to backup";
863 return false;
864 }
865
866 QString backupPath = showersJsonPath + ".old";
867 if(QFileInfo(backupPath).exists())
868 QFile(backupPath).remove();
869
870 if(old.copy(backupPath))
871 {
872 if(deleteOriginal)
873 {
874 if(!old.remove())
875 {
876 qWarning() << "MeteorShowers: WARNING - could not remove old showers.json file";
877 return false;
878 }
879 }
880 }
881 else
882 {
883 qWarning() << "MeteorShowers: WARNING - failed to copy showers.json to showers.json.old";
884 return false;
885 }
886
887 return true;
888}
889
890int MeteorShowers::getJsonFileFormatVersion(void)
891{
892 int jsonVersion = -1;
893 QFile showersJsonFile(showersJsonPath);
894 if(!showersJsonFile.open(QIODevice::ReadOnly))
895 {
896 qWarning() << "MeteorShowers: cannot open" << QDir::toNativeSeparators(showersJsonPath);
897 return jsonVersion;
898 }
899
900 QVariantMap map;
901 map = StelJsonParser::parse(&showersJsonFile).toMap();
902 if(map.contains("version"))
903 {
904 jsonVersion = map.value("version").toInt();
905 }
906
907 showersJsonFile.close();
908 qDebug() << "MeteorShowers: version of the format of the catalog:" << jsonVersion;
909 return jsonVersion;
910}
911
912bool MeteorShowers::checkJsonFileFormat()
913{
914 QFile showersJsonFile(showersJsonPath);
915 if(!showersJsonFile.open(QIODevice::ReadOnly))
916 {
917 qWarning() << "MeteorShowers: cannot open" << QDir::toNativeSeparators(showersJsonPath);
918 return false;
919 }
920
921 QVariantMap map;
922 try
923 {
924 map = StelJsonParser::parse(&showersJsonFile).toMap();
925 showersJsonFile.close();
926 }
927 catch(std::runtime_error& e)
928 {
929 qDebug() << "MeteorShowers: file format is wrong! Error:" << e.what();
930 return false;
931 }
932
933 return true;
934}
935
936void MeteorShowers::readSettingsFromConfig(void)
937{
938 conf->beginGroup("MeteorShowers");
939
940 updateUrl = conf->value("url", "http://stellarium.org/json/showers.json").toString();
941 updateFrequencyHours = conf->value("update_frequency_hours", 720).toInt();
942 lastUpdate = QDateTime::fromString(conf->value("last_update", "2013-12-10T12:00:00").toString(), Qt::ISODate);
943 updatesEnabled = conf->value("updates_enabled", true).toBool();
944 enableAtStartup = conf->value("enable_at_startup", false).toBool();
945 flagShowMSButton = conf->value("flag_show_ms_button", true).toBool();
946 setFlagRadiant(conf->value("flag_show_radiants", true).toBool());
947 flagShowAR = conf->value("flag_active_radiants", false).toBool();
948
949 Vec3f color;
950 color = StelUtils::strToVec3f(conf->value("colorARG", "0, 255, 240").toString());
951 colorARG = QColor(color[0],color[1],color[2]);
952 color = StelUtils::strToVec3f(conf->value("colorARR", "255, 240, 0").toString());
953 colorARR = QColor(color[0],color[1],color[2]);
954 color = StelUtils::strToVec3f(conf->value("colorIR", "255, 255, 255").toString());
955 colorIR = QColor(color[0],color[1],color[2]);
956
957 MeteorShower::showLabels = conf->value("show_radiant_labels", true).toBool();
958 labelFont.setPixelSize(conf->value("font_size", 13).toInt());
959
960 conf->endGroup();
961}
962
963void MeteorShowers::saveSettingsToConfig(void)
964{
965 conf->beginGroup("MeteorShowers");
966
967 conf->setValue("url", updateUrl);
968 conf->setValue("update_frequency_hours", updateFrequencyHours);
969 conf->setValue("updates_enabled", updatesEnabled);
970 conf->setValue("enable_at_startup", enableAtStartup);
971 conf->setValue("flag_show_ms_button", flagShowMSButton);
972 conf->setValue("flag_show_radiants", getFlagRadiant());
973 conf->setValue("flag_active_radiants", flagShowAR);
974
975 int r,g,b;
976 colorARG.getRgb(&r,&g,&b);
977 conf->setValue("colorARG", QString("%1, %2, %3").arg(r).arg(g).arg(b));
978 colorARR.getRgb(&r,&g,&b);
979 conf->setValue("colorARR", QString("%1, %2, %3").arg(r).arg(g).arg(b));
980 colorIR.getRgb(&r,&g,&b);
981 conf->setValue("colorIR", QString("%1, %2, %3").arg(r).arg(g).arg(b));
982
983 conf->setValue("show_radiant_labels", MeteorShower::showLabels);
984 conf->setValue("font_size", labelFont.pixelSize());
985
986 conf->endGroup();
987}
988
989int MeteorShowers::getSecondsToUpdate(void)
990{
991 QDateTime nextUpdate = lastUpdate.addSecs(updateFrequencyHours * 3600);
992 return QDateTime::currentDateTime().secsTo(nextUpdate);
993}
994
995void MeteorShowers::checkForUpdate(void)
996{
997 if(updatesEnabled && lastUpdate.addSecs(updateFrequencyHours * 3600) <= QDateTime::currentDateTime())
998 updateJSON();
999}
1000
1001void MeteorShowers::updateJSON(void)
1002{
1003 if(updateState==MeteorShowers::Updating)
1004 {
1005 qWarning() << "MeteorShowers: already updating... will not start again current update is complete.";
1006 return;
1007 }
1008 else
1009 {
1010 qDebug() << "MeteorShowers: starting update...";
1011 }
1012
1013 lastUpdate = QDateTime::currentDateTime();
1014 conf->setValue("MeteorShowers/last_update", lastUpdate.toString(Qt::ISODate));
1015
1016 emit(jsonUpdateComplete());
1017
1018 updateState = MeteorShowers::Updating;
1019
1020 emit(updateStateChanged(updateState));
1021 updateFile.clear();
1022
1023 if(progressBar==NULL)
1024 progressBar = StelApp::getInstance().addProgressBar();
1025
1026 progressBar->setValue(0);
1027 progressBar->setRange(0, 100);
1028 progressBar->setFormat("Update meteor showers");
1029
1030 QNetworkRequest request;
1031 request.setUrl(QUrl(updateUrl));
1032 request.setRawHeader("User-Agent", QString("Mozilla/5.0 (Stellarium Meteor Showers Plugin %1; http://stellarium.org/)").arg(METEORSHOWERS_PLUGIN_VERSION).toUtf8());
1033 downloadMgr->get(request);
1034
1035 updateState = MeteorShowers::CompleteUpdates;
1036 emit(updateStateChanged(updateState));
1037 emit(jsonUpdateComplete());
1038}
1039
1040void MeteorShowers::updateDownloadComplete(QNetworkReply* reply)
1041{
1042 // check the download worked, and save the data to file if this is the case.
1043 if(reply->error() != QNetworkReply::NoError)
1044 {
1045 qWarning() << "MeteorShowers: FAILED to download" << reply->url() << " Error:" << reply->errorString();
1046 }
1047 else
1048 {
1049 // download completed successfully.
1050 QString jsonFilePath = StelFileMgr::findFile("modules/MeteorShowers", StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::Directory)) + "/showers.json";
1051 if(jsonFilePath.isEmpty())
1052 {
1053 qWarning() << "MeteorShowers: cannot write JSON data to file";
1054 }
1055 else
1056 {
1057 QFile jsonFile(jsonFilePath);
1058 if(jsonFile.exists())
1059 jsonFile.remove();
1060
1061 jsonFile.open(QIODevice::WriteOnly | QIODevice::Text);
1062 jsonFile.write(reply->readAll());
1063 jsonFile.close();
1064 }
1065 }
1066
1067 if(progressBar)
1068 {
1069 progressBar->setValue(100);
1070 StelApp::getInstance().removeProgressBar(progressBar);
1071 progressBar = NULL;
1072 }
1073
1074 readJsonFile();
1075}
1076
1077void MeteorShowers::displayMessage(const QString& message, const QString hexColor)
1078{
1079 messageIDs << GETSTELMODULE(LabelMgr)->labelScreen(message, 30, 30 + (20*messageIDs.count()), true, 16, hexColor);
1080 messageTimer->start();
1081}
1082
1083void MeteorShowers::messageTimeout(void)
1084{
1085 foreach(int i, messageIDs)
1086 {
1087 GETSTELMODULE(LabelMgr)->deleteLabel(i);
1088 }
1089}
1090
1091bool MeteorShowers::getFlagLabels()
1092{
1093 return MeteorShower::showLabels;
1094}
1095
1096void MeteorShowers::setFlagLabels(bool b)
1097{
1098 if (MeteorShower::showLabels != b)
1099 MeteorShower::showLabels = b;
1100}
1101
1102void MeteorShowers::setLabelFontSize(int size)
1103{
1104 if (labelFont.pixelSize() != size)
1105 labelFont.setPixelSize(size);
1106}
1107
1108void MeteorShowers::translations()
1109{
1110#if 0
1111 // Meteor showers
1112 // TRANSLATORS: Name of meteor shower
1113 N_("Quadrantids");
1114 // TRANSLATORS: Name of meteor shower
1115 N_("Lyrids");
1116 // TRANSLATORS: Name of meteor shower
1117 N_("α-Centaurids");
1118 // TRANSLATORS: Name of meteor shower
1119 N_("γ-Normids");
1120 // TRANSLATORS: Name of meteor shower
1121 N_("η-Aquariids");
1122 // TRANSLATORS: Name of meteor shower
1123 N_("June Bootids");
1124 // TRANSLATORS: Name of meteor shower
1125 N_("Piscis Austrinids");
1126 // TRANSLATORS: Name of meteor shower
1127 N_("Southern δ-Aquariids");
1128 // TRANSLATORS: Name of meteor shower
1129 N_("α-Capricornids");
1130 // TRANSLATORS: Name of meteor shower
1131 N_("α-Aurigids");
1132 // TRANSLATORS: Name of meteor shower
1133 N_("September ε-Perseids");
1134 // TRANSLATORS: Name of meteor shower
1135 N_("Draconids");
1136 // TRANSLATORS: Name of meteor shower
1137 N_("Leonids");
1138 // TRANSLATORS: Name of meteor shower
1139 N_("Phoenicids");
1140 // TRANSLATORS: Name of meteor shower
1141 N_("Puppid-Velids");
1142 // TRANSLATORS: Name of meteor shower
1143 N_("Ursids");
1144 // TRANSLATORS: Name of meteor shower
1145 N_("Perseids");
1146 // TRANSLATORS: Name of meteor shower
1147 N_("δ-Leonids");
1148 // TRANSLATORS: Name of meteor shower
1149 N_("π-Puppids");
1150 // TRANSLATORS: Name of meteor shower
1151 N_("June Lyrids");
1152 // TRANSLATORS: Name of meteor shower
1153 N_("κ-Cygnids");
1154 // TRANSLATORS: Name of meteor shower
1155 N_("ε-Lyrids");
1156 // TRANSLATORS: Name of meteor shower
1157 N_("δ-Aurigids");
1158 // TRANSLATORS: Name of meteor shower
1159 N_("ε-Geminids");
1160 // TRANSLATORS: Name of meteor shower
1161 N_("Southern Taurids");
1162 // TRANSLATORS: Name of meteor shower
1163 N_("Northern Taurids");
1164 // TRANSLATORS: Name of meteor shower
1165 N_("Monocerotids");
1166 // TRANSLATORS: Name of meteor shower
1167 N_("σ-Hydrids");
1168 // TRANSLATORS: Name of meteor shower
1169 N_("Geminids");
1170 // TRANSLATORS: Name of meteor shower
1171 N_("Leonis Minorids");
1172 // TRANSLATORS: Name of meteor shower
1173 N_("December Leonis Minorids");
1174 // TRANSLATORS: Name of meteor shower
1175 N_("Comae Berenicids");
1176 // TRANSLATORS: Name of meteor shower
1177 N_("Orionids");
1178 // TRANSLATORS: Name of meteor shower
1179 N_("Andromedids");
1180
1181 // List of parent objects for meteor showers
1182 // TRANSLATORS: Name of parent object for meteor shower
1183 N_("Minor planet 2003 EH1 and Comet C/1490 Y1");
1184 // TRANSLATORS: Name of parent object for meteor shower
1185 N_("Comet 1P/Halley");
1186 // TRANSLATORS: Name of parent object for meteor shower
1187 N_("Comet 7P/Pons-Winnecke");
1188 // TRANSLATORS: Name of parent object for meteor shower
1189 N_("Comet 55P/Tempel-Tuttle");
1190 // TRANSLATORS: Name of parent object for meteor shower
1191 N_("Comet 96P/Machholz");
1192 // TRANSLATORS: Name of parent object for meteor shower
1193 N_("Comet 109P/Swift-Tuttle");
1194 // TRANSLATORS: Name of parent object for meteor shower
1195 N_("Comet Thatcher (1861 I)");
1196 // TRANSLATORS: Name of parent object for meteor shower
1197 N_("Minor planet (4450) Pan");
1198 // TRANSLATORS: Name of parent object for meteor shower
1199 N_("Comet 26P/Grigg-Skjellerup");
1200 // TRANSLATORS: Name of parent object for meteor shower
1201 N_("Comet 21P/Giacobini-Zinner");
1202 // TRANSLATORS: Name of parent object for meteor shower
1203 N_("Comet 169P/NEAT");
1204 // TRANSLATORS: Name of parent object for meteor shower
1205 N_("Comet 289P/Blanpain");
1206 // TRANSLATORS: Name of parent object for meteor shower
1207 N_("Comet 8P/Tuttle");
1208 // TRANSLATORS: Name of parent object for meteor shower
1209 N_("Minor planet 2008 ED69");
1210 // TRANSLATORS: Name of parent object for meteor shower
1211 N_("Comet 2P/Encke");
1212 // TRANSLATORS: Name of parent object for meteor shower
1213 N_("Comet 3D/Biela");
1214 // TRANSLATORS: Name of parent object for meteor shower
1215 N_("Minor planet 2004 TG10");
1216 // TRANSLATORS: Name of parent object for meteor shower
1217 N_("Minor planet (3200) Phaethon");
1218
1219 /* For copy/paste:
1220 // TRANSLATORS: Name of meteor shower
1221 N_("");
1222 */
1223
1224#endif
1225}
01226
=== added file 'plugins/MeteorShowers/src/MeteorShowers.hpp'
--- plugins/MeteorShowers/src/MeteorShowers.hpp 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/src/MeteorShowers.hpp 2014-03-10 17:28:07 +0000
@@ -0,0 +1,412 @@
1/*
2 * Copyright (C) 2013 Marcos Cardinot
3 * Copyright (C) 2011 Alexander Wolf
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 */
19
20#ifndef METEORSHOWERS_HPP_
21#define METEORSHOWERS_HPP_
22
23#include "MeteorShower.hpp"
24#include "MeteorStream.hpp"
25#include "StelFader.hpp"
26#include "StelModule.hpp"
27#include "StelObjectModule.hpp"
28#include "StelTextureTypes.hpp"
29
30#include <QColor>
31#include <QDateTime>
32#include <QFont>
33#include <QSharedPointer>
34#include <QVariantMap>
35
36class QNetworkAccessManager;
37class QNetworkReply;
38class QProgressBar;
39class QSettings;
40class QTimer;
41class MeteorShowerDialog;
42class StelButton;
43class StelPainter;
44
45typedef QSharedPointer<MeteorShower> MeteorShowerP;
46
47//! This is an example of a plug-in which can be dynamically loaded into stellarium
48class MeteorShowers : public StelObjectModule
49{
50 Q_OBJECT
51 Q_PROPERTY(bool msVisible READ getFlagShowMS WRITE setFlagShowMS)
52 Q_PROPERTY(bool labelsVisible READ getFlagLabels WRITE setFlagLabels)
53public:
54 //! @enum UpdateState
55 //! Used for keeping track of the download/update status
56 enum UpdateState
57 {
58 Updating, //!< Update in progress
59 CompleteNoUpdates, //!< Update completed, there we no updates
60 CompleteUpdates, //!< Update completed, there were updates
61 DownloadError, //!< Error during download phase
62 OtherError //!< Other error
63 };
64
65 MeteorShowers();
66 virtual ~MeteorShowers();
67
68 ///////////////////////////////////////////////////////////////////////////
69 // Methods defined in the StelModule class
70 virtual void init();
71 //! called before the plug-in is un-loaded.
72 //! Useful for stopping processes, unloading textures, etc.
73 virtual void deinit();
74 virtual void update(double deltaTime);
75 virtual void draw(StelCore* core);
76 virtual void drawMarker(StelCore* core, StelPainter& painter);
77 virtual void drawPointer(StelCore* core, StelPainter& painter);
78 virtual void drawStream(StelCore* core, StelPainter& painter);
79 virtual double getCallOrder(StelModuleActionName actionName) const;
80
81 ///////////////////////////////////////////////////////////////////////////
82 // Methods defined in StelObjectManager class
83 //! Used to get a list of objects which are near to some position.
84 //! @param v a vector representing the position in th sky around which to search for nebulae.
85 //! @param limitFov the field of view around the position v in which to search for satellites.
86 //! @param core the StelCore to use for computations.
87 //! @return an list containing the satellites located inside the limitFov circle around position v.
88 virtual QList<StelObjectP> searchAround(const Vec3d& v, double limitFov, const StelCore* core) const;
89
90 //! Return the matching satellite object's pointer if exists or NULL.
91 //! @param nameI18n The case in-sensistive satellite name
92 virtual StelObjectP searchByNameI18n(const QString& nameI18n) const;
93
94 //! Return the matching satellite if exists or NULL.
95 //! @param name The case in-sensistive standard program name
96 virtual StelObjectP searchByName(const QString& name) const;
97
98 //! Find and return the list of at most maxNbItem objects auto-completing the passed object I18n name.
99 //! @param objPrefix the case insensitive first letters of the searched object
100 //! @param maxNbItem the maximum number of returned object names
101 //! @return a list of matching object name by order of relevance, or an empty list if nothing match
102 virtual QStringList listMatchingObjectsI18n(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const;
103 virtual QStringList listMatchingObjects(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const;
104 virtual QStringList listAllObjects(bool inEnglish) const;
105 virtual QString getName() const
106 {
107 return "Meteor Showers";
108 }
109
110 //! get a ms object by identifier
111 MeteorShowerP getByID(const QString& id);
112
113 //! Implment this to tell the main Stellarium GUI that there is a GUI element to configure this
114 //! plugin.
115 virtual bool configureGui(bool show=true);
116
117 //! Set up the plugin with default values. This means clearing out the MeteorShower section in the
118 //! main config.ini (if one already exists), and populating it with default values. It also
119 //! creates the default showers.json file from the resource embedded in the plugin lib/dll file.
120 void restoreDefaults(void);
121
122 //! Read (or re-read) settings from the main config file. This will be called from init and also
123 //! when restoring defaults (i.e. from the configuration dialog / restore defaults button).
124 void readSettingsFromConfig(void);
125
126 //! Save the settings to the main configuration file.
127 void saveSettingsToConfig(void);
128
129 //! get whether or not the plugin will try to update TLE data from the internet
130 //! @return true if updates are set to be done, false otherwise
131 bool getUpdatesEnabled(void)
132 {
133 return updatesEnabled;
134 }
135 //! set whether or not the plugin will try to update TLE data from the internet
136 //! @param b if true, updates will be enabled, else they will be disabled
137 void setUpdatesEnabled(bool b)
138 {
139 updatesEnabled=b;
140 }
141
142 //! get the date and time the TLE elements were updated
143 QDateTime getLastUpdate(void)
144 {
145 return lastUpdate;
146 }
147
148 //! get the update frequency in hours
149 int getUpdateFrequencyHours(void)
150 {
151 return updateFrequencyHours;
152 }
153 void setUpdateFrequencyHours(int hours)
154 {
155 updateFrequencyHours = hours;
156 }
157
158 //! get the number of seconds till the next update
159 int getSecondsToUpdate(void);
160
161 //! Get the current updateState
162 UpdateState getUpdateState(void)
163 {
164 return updateState;
165 }
166
167 //! Get current color of active radiant based in generic data
168 QColor getColorARG()
169 {
170 return colorARG;
171 }
172 void setColorARG(QColor color)
173 {
174 colorARG = color;
175 }
176
177 //! Get current color of active radiant based in real data
178 QColor getColorARR()
179 {
180 return colorARR;
181 }
182 void setColorARR(QColor color)
183 {
184 colorARR = color;
185 }
186
187 //! Get current inactive radiant color
188 QColor getColorIR()
189 {
190 return colorIR;
191 }
192 void setColorIR(QColor color)
193 {
194 colorIR = color;
195 }
196
197 //! get the label font size.
198 //! @return the pixel size of the font
199 int getLabelFontSize()
200 {
201 return labelFont.pixelSize();
202 }
203
204 //! Get status of labels
205 //! @return false: hidden
206 bool getFlagLabels();
207
208 //! Get current sky date.
209 //! @return current sky date
210 QDateTime getSkyDate()
211 {
212 return skyDate;
213 }
214
215 //! Find all meteor_shower events in a given date interval
216 //! @param dateFrom
217 //! @param dateTo
218 //! @return meteor_shower list
219 QList<MeteorShowerP> searchEvents(QDate dateFrom, QDate dateTo) const;
220
221signals:
222 //! @param state the new update state.
223 void updateStateChanged(MeteorShowers::UpdateState state);
224
225 //! emitted after a JSON update has run.
226 void jsonUpdateComplete(void);
227
228public slots:
229 //! Download JSON from web recources described in the module section of the
230 //! module.ini file and update the local JSON file.
231 void updateJSON(void);
232
233 void setFlagShowMS(bool b);
234 bool getFlagShowMS(void)
235 {
236 return flagShowMS;
237 }
238
239 //! Display a message. This is used for plugin-specific warnings and such
240 void displayMessage(const QString& message, const QString hexColor="#999999");
241 void messageTimeout(void);
242
243 //! Define whether the button toggling meteor showers should be visible
244 void setFlagShowMSButton(bool b);
245 bool getFlagShowMSButton(void) { return flagShowMSButton; }
246
247 //! set the label font size.
248 //! @param size the pixel size of the font
249 void setLabelFontSize(int size);
250
251 //! Set whether text labels should be displayed next to radiant.
252 //! @param false: hidden
253 void setFlagLabels(bool b);
254
255 bool getFlagActiveRadiant(void) { return flagShowAR; }
256 void setFlagActiveRadiant(bool b) { flagShowAR=b; }
257
258 bool getEnableAtStartup(void) {return enableAtStartup;}
259 void setEnableAtStartup(bool b) {enableAtStartup=b;}
260
261 bool getFlagRadiant(void) const { return MeteorShower::radiantMarkerEnabled; }
262 void setFlagRadiant(bool b) { MeteorShower::radiantMarkerEnabled=b; }
263
264private:
265 // Upgrade config.ini: rename old key settings to new
266 void upgradeConfigIni(void);
267
268 //! Check if the sky date was changed
269 //! @param core
270 //! @return if changed, return true
271 bool changedSkyDate(StelCore* core);
272
273 //! Calculate value of ZHR using normal distribution
274 //! @param zhr
275 //! @param variable
276 //! @param start
277 //! @param finish
278 //! @param peak
279 int calculateZHR(int zhr, QString variable, QDateTime start, QDateTime finish, QDateTime peak);
280
281 //! Update the list with information about active meteors
282 //! @param core
283 void updateActiveInfo(void);
284
285 //! Set up the plugin with default values.
286 void restoreDefaultConfigIni(void);
287
288 //! replace the json file with the default from the compiled-in resource
289 void restoreDefaultJsonFile(void);
290
291 //! read the json file and create the meteor Showers.
292 void readJsonFile(void);
293
294 //! Creates a backup of the showers.json file called showers.json.old
295 //! @param deleteOriginal if true, the original file is removed, else not
296 //! @return true on OK, false on failure
297 bool backupJsonFile(bool deleteOriginal=false);
298
299 //! Get the version from the "version of format" value in the showers.json file
300 //! @return version, e.g. "1"
301 int getJsonFileFormatVersion(void);
302
303 //! Check format of the catalog of meteor showers
304 //! @return valid boolean, e.g. "true"
305 bool checkJsonFileFormat(void);
306
307 //! Parse JSON file and load showers to map
308 QVariantMap loadShowersMap(QString path=QString());
309
310 //! Set items for list of struct from data map
311 void setShowersMap(const QVariantMap& map);
312
313 //! A fake method for strings marked for translation.
314 //! Use it instead of translations.h for N_() strings, except perhaps for
315 //! keyboard action descriptions. (It's better for them to be in a single
316 //! place.)
317 static void translations();
318
319 //! Font used for displaying our text
320 QFont labelFont;
321
322 QString showersJsonPath;
323
324 StelTextureSP texPointer;
325 QList<MeteorShowerP> mShowers;
326
327 // GUI
328 MeteorShowerDialog* configDialog;
329 bool flagShowMS;
330 bool flagShowMSButton;
331 QPixmap* OnIcon;
332 QPixmap* OffIcon;
333 QPixmap* GlowIcon;
334 StelButton* toolbarButton;
335 QColor colorARR; //color of active radiant based on real data
336 QColor colorARG; //color of active radiant based on generic data
337 QColor colorIR; //color of inactive radiant
338
339 // variables and functions for the updater
340 UpdateState updateState;
341 QNetworkAccessManager* downloadMgr;
342 QString updateUrl;
343 QString updateFile;
344 class StelProgressController* progressBar;
345 QTimer* updateTimer;
346 QTimer* messageTimer;
347 QList<int> messageIDs;
348 bool updatesEnabled;
349 QDateTime lastUpdate;
350 int updateFrequencyHours;
351 bool enableAtStartup;
352
353 QSettings* conf;
354
355 //MS
356 std::vector<std::vector<MeteorStream*> > active; // Matrix containing all active meteors
357 int ZHR;
358 const static double zhrToWsr = 1.6667f/3600.f; // factor to convert from zhr to whole earth per second rate
359
360 bool flagShowAR; //! Show marker of active radiant
361
362 bool flagShow;
363 bool flagShowARG; //! Show marker of active radiant based on generic data
364 bool flagShowARR; //! Show marker of active radiant based on generic data
365 bool flagShowIR; //! Show marker of inactive radiant
366
367 bool flagShowStreamARG; //! Show meteor stream of active radiant based on generic data
368 bool flagShowStreamARR; //! Show meteor stream of active radiant based on generic data
369
370 typedef struct
371 {
372 QString showerID; //! The ID of the meteor shower
373 QDateTime start; //! First day for activity
374 QDateTime finish; //! Latest day for activity
375 QDateTime peak; //! Day with maximum for activity
376 int status; //! 0:inactive 1:activeRealData 2:activeGenericData
377 int zhr; //! ZHR of shower
378 QString variable; //! value of variable for ZHR
379 int speed; //! Speed of meteors
380 double radiantAlpha; //! R.A. for radiant of meteor shower
381 double radiantDelta; //! Dec. for radiant of meteor shower
382 } activeData;
383
384 QList<activeData> activeInfo; //! List of active meteors
385 QDateTime skyDate; //! Current sky date
386 QDateTime lastSkyDate; //! Last sky date
387
388private slots:
389 //! check to see if an update is required. This is called periodically by a timer
390 //! if the last update was longer than updateFrequencyHours ago then the update is
391 //! done.
392 void checkForUpdate(void);
393 void updateDownloadComplete(QNetworkReply* reply);
394};
395
396
397//#include "fixx11h.h"
398#include <QObject>
399#include "StelPluginInterface.hpp"
400
401//! This class is used by Qt to manage a plug-in interface
402class MeteorShowersStelPluginInterface : public QObject, public StelPluginInterface
403{
404 Q_OBJECT
405 Q_PLUGIN_METADATA(IID "stellarium.StelGuiPluginInterface/1.0")
406 Q_INTERFACES(StelPluginInterface)
407public:
408 virtual StelModule* getStelModule() const;
409 virtual StelPluginInfo getPluginInfo() const;
410};
411
412#endif /*METEORSHOWERS_HPP_*/
0413
=== added file 'plugins/MeteorShowers/src/MeteorStream.cpp'
--- plugins/MeteorShowers/src/MeteorStream.cpp 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/src/MeteorStream.cpp 2014-03-10 17:28:07 +0000
@@ -0,0 +1,239 @@
1/*
2 * Copyright (C) 2013 Marcos Cardinot
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
17 */
18
19#include <cstdlib>
20#include "MeteorShowers.hpp"
21#include "MeteorStream.hpp"
22#include "StelCore.hpp"
23#include "StelUtils.hpp"
24
25#include "StelToneReproducer.hpp"
26#include "StelMovementMgr.hpp"
27#include "StelPainter.hpp"
28
29MeteorStream::MeteorStream(const StelCore* core, double velocity, double radiantAlpha, double radiantDelta)
30{
31 speed = velocity;
32
33 maxMag = 1; //start with the maximum mag
34
35 //the meteor starts dead, after we'll calculate the position
36 //if the position is within the bounds, this parameter will be changed to TRUE
37 alive = false;
38
39 double high_range = EARTH_RADIUS+HIGH_ALTITUDE;
40 double low_range = EARTH_RADIUS+LOW_ALTITUDE;
41
42 // view matrix of meteor model
43 viewMatrix = Mat4d::zrotation(radiantAlpha) * Mat4d::yrotation(M_PI_2 - radiantDelta);
44
45 // find observer position in meteor coordinate system
46 obs = core->altAzToJ2000(Vec3d(0,0,EARTH_RADIUS));
47 obs.transfo4d(viewMatrix.transpose());
48
49 // select random trajectory using polar coordinates in XY plane, centered on observer
50 xydistance = (double)rand() / ((double)RAND_MAX+1)*(VISIBLE_RADIUS);
51 double angle = (double)rand() / ((double)RAND_MAX+1)*2*M_PI;
52
53 // set meteor start x,y
54 position[0] = posInternal[0] = posTrain[0] = xydistance*cos(angle) + obs[0];
55 position[1] = posInternal[1] = posTrain[1] = xydistance*sin(angle) + obs[1];
56
57 // D is distance from center of earth
58 double D = sqrt(position[0]*position[0] + position[1]*position[1]);
59
60 if(D > high_range) // won't be visible, meteor still dead
61 {
62 return;
63 }
64
65 posTrain[2] = position[2] = startH = sqrt(high_range*high_range - D*D);
66
67 // determine end of burn point, and nearest point to observer for distance mag calculation
68 // mag should be max at nearest point still burning
69 endH = -startH; // earth grazing
70 minDist = xydistance;
71 if(D <= low_range)
72 {
73 endH = sqrt(low_range*low_range - D*D);
74 minDist = sqrt(xydistance*xydistance + pow(endH - obs[2], 2));
75 }
76
77 if(minDist > VISIBLE_RADIUS)
78 {
79 // on average, not visible (although if were zoomed ...)
80 return; //meteor still dead
81 }
82
83 //If everything is ok until here,
84 alive = true; //the meteor is alive
85 train = false; //and initially it is only a point
86
87 // Determine drawing color given magnitude and eye
88 // (won't be visible during daylight)
89
90 // *** color varies somewhat based on speed, plus atmosphere reddening
91
92 // determine intensity
93 float Mag1 = (double)rand()/((double)RAND_MAX+1)*6.75f - 3;
94 float Mag2 = (double)rand()/((double)RAND_MAX+1)*6.75f - 3;
95 float Mag = (Mag1 + Mag2)/2.0f;
96
97 mag = (5. + Mag) / 256.0;
98 if(mag>250) mag = mag - 256;
99
100 float term1 = std::exp(-0.92103f*(mag + 12.12331f)) * 108064.73f;
101
102 float cmag=1.f;
103 float rmag;
104
105 // Compute the equivalent star luminance for a 5 arc min circle and convert it
106 // in function of the eye adaptation
107 const StelToneReproducer* eye = core->getToneReproducer();
108 rmag = eye->adaptLuminanceScaled(term1);
109 rmag = rmag/powf(core->getMovementMgr()->getCurrentFov(),0.85f)*500.f;
110
111 // if size of star is too small (blink) we put its size to 1.2 --> no more blink
112 // And we compensate the difference of brighteness with cmag
113 if(rmag<1.2f)
114 {
115 cmag=rmag*rmag/1.44f;
116 }
117
118 mag = cmag; // assumes white
119
120 // most visible meteors are under about 180km distant
121 // scale max mag down if outside this range
122 float scale = 1;
123 if(minDist!=0) scale = 180*180/(minDist*minDist);
124 if(scale < 1) mag *= scale;
125}
126
127MeteorStream::~MeteorStream()
128{
129}
130
131// returns true if alive
132bool MeteorStream::update(double deltaTime)
133{
134 if(!alive)
135 return(0);
136
137 if(position[2] < endH)
138 {
139 // burning has stopped so magnitude fades out
140 // assume linear fade out
141
142 mag -= maxMag * deltaTime/500.0f;
143 if(mag < 0)
144 alive=0; // no longer visible
145
146 }
147
148 // *** would need time direction multiplier to allow reverse time replay
149 position[2] = position[2] - speed*deltaTime/1000.0f;
150
151 // train doesn't extend beyond start of burn
152 if(position[2] + speed*0.5f > startH)
153 {
154 posTrain[2] = startH ;
155 }
156 else
157 {
158 posTrain[2] -= speed*deltaTime/1000.0f;
159 }
160
161 // determine visual magnitude based on distance to observer
162 double dist = sqrt(xydistance*xydistance + pow(position[2]-obs[2], 2));
163
164 if(dist == 0) dist = .01; // just to be cautious (meteor hits observer!)
165
166 distMultiplier = minDist*minDist / (dist*dist);
167
168 return(alive);
169}
170
171
172// returns true if visible
173// Assumes that we are in local frame
174void MeteorStream::draw(const StelCore* core, StelPainter& sPainter)
175{
176 if(!alive)
177 return;
178
179 const StelProjectorP proj = sPainter.getProjector();
180
181 Vec3d spos = position;
182 Vec3d epos = posTrain;
183
184 // convert to equ
185 spos.transfo4d(viewMatrix);
186 epos.transfo4d(viewMatrix);
187
188 // convert to local and correct for earth radius
189 //[since equ and local coordinates in stellarium use same 0 point!]
190 spos = core->j2000ToAltAz(spos);
191 epos = core->j2000ToAltAz(epos);
192 spos[2] -= EARTH_RADIUS;
193 epos[2] -= EARTH_RADIUS;
194 // 1216 is to scale down under 1 for desktop version
195 spos/=1216;
196 epos/=1216;
197
198 if(train)
199 {
200 // connect this point with last drawn point
201 double tmag = mag*distMultiplier;
202
203 // compute an intermediate point so can curve slightly along projection distortions
204 Vec3d posi = posInternal;
205 posi[2] = position[2] + (posTrain[2] - position[2])/2;
206 posi.transfo4d(viewMatrix);
207 posi = core->j2000ToAltAz(posi);
208 posi[2] -= EARTH_RADIUS;
209 posi/=1216;
210
211 // draw dark to light
212 Vec4f colorArray[3];
213 colorArray[0].set(0,0,0,0);
214 colorArray[1].set(1,1,1,tmag*0.5);
215 colorArray[2].set(1,1,1,tmag);
216 Vec3d vertexArray[3];
217 vertexArray[0]=epos;
218 vertexArray[1]=posi;
219 vertexArray[2]=spos;
220 sPainter.setColorPointer(4, GL_FLOAT, colorArray);
221 sPainter.setVertexPointer(3, GL_DOUBLE, vertexArray);
222 sPainter.enableClientStates(true, false, true);
223 sPainter.drawFromArray(StelPainter::LineStrip, 3, 0, true);
224 sPainter.enableClientStates(false);
225 }
226 else
227 {
228 Vec3d start;
229 proj->project(spos, start);
230 sPainter.drawPoint2d(start[0],start[1]);
231 }
232
233 train = 1;
234}
235
236bool MeteorStream::isAlive(void)
237{
238 return(alive);
239}
0240
=== added file 'plugins/MeteorShowers/src/MeteorStream.hpp'
--- plugins/MeteorShowers/src/MeteorStream.hpp 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/src/MeteorStream.hpp 2014-03-10 17:28:07 +0000
@@ -0,0 +1,84 @@
1/*
2 * Copyright (C) 2013 Marcos Cardinot
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
17 */
18
19#ifndef _METEORSTREAM_HPP_
20#define _METEORSTREAM_HPP_
21
22#include "VecMath.hpp"
23class StelCore;
24class StelPainter;
25
26// all in km - altitudes make up meteor range
27#define EARTH_RADIUS 6369.f
28#define VISIBLE_RADIUS 457.8f
29#define HIGH_ALTITUDE 115.f
30#define LOW_ALTITUDE 70.f
31
32//! @class MeteorStream
33//! Models a single meteor.
34//! Control of the meteor rate is performed in the MeteorShowers class. Once
35//! created, a meteor object only lasts for some amount of time, and then
36//! "dies", after which, the update() member returns false. The live/dead
37//! status of a meteor may also be determined using the isAlive member.
38class MeteorStream
39{
40public:
41 //! Create a Meteor object.
42 //! @param velocity the speed of the meteor in km/s.
43 //! @param rAlpha the radiant alpha in rad
44 //! @param rDelta the radiant delta in rad
45 MeteorStream(const StelCore*, double velocity, double radiantAlpha, double radiantDelta);
46 virtual ~MeteorStream();
47
48 //! Updates the position of the meteor, and expires it if necessary.
49 //! @return true of the meteor is still alive, else false.
50 bool update(double deltaTime);
51
52 //! Draws the meteor.
53 void draw(const StelCore* core, StelPainter& sPainter);
54
55 //! Determine if a meteor is alive or has burned out.
56 //! @return true if alive, else false.
57 bool isAlive(void);
58
59private:
60 bool alive; //! Indicate if the meteor it still visible
61 bool train; //! Indicate if the point or train is visible
62
63 Mat4d viewMatrix; //! View Matrix
64 Vec3d obs; //! Observer position
65 Vec3d position; //! Equatorial coordinate position
66 Vec3d posInternal; //! Middle of train
67 Vec3d posTrain; //! End of train
68
69 double speed; //! Velocity of meteor in km/s
70 double xydistance; //! Distance in XY plane (orthogonal to meteor path) from observer to meteor
71 double initDist; //! Initial distance from observer
72 double minDist; //! Nearest point to observer along path
73 double distMultiplier; //! Scale magnitude due to changes in distance
74
75 double startH; //! Start height above center of earth
76 double endH; //! End height
77
78 float mag; //! Apparent magnitude at head, 0-1
79 float maxMag; //! 0-1
80 float absMag; //! Absolute magnitude
81 float visMag; //! Visual magnitude at observer
82};
83
84#endif // _METEORSTREAM_HPP_
085
=== added directory 'plugins/MeteorShowers/src/gui'
=== added file 'plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp'
--- plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp 2014-03-10 17:28:07 +0000
@@ -0,0 +1,389 @@
1/*
2 * Stellarium Meteor Shower plugin config dialog
3 *
4 * Copyright (C) 2013 Marcos Cardinot
5 * Copyright (C) 2011 Alexander Wolf
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
20*/
21
22#include <QColorDialog>
23#include <QDateTime>
24#include <QDebug>
25#include <QFileDialog>
26#include <QGraphicsColorizeEffect>
27#include <QMessageBox>
28#include <QTimer>
29#include <QUrl>
30
31#include "MeteorShowerDialog.hpp"
32#include "MeteorShowers.hpp"
33#include "StelApp.hpp"
34#include "StelCore.hpp"
35#include "StelFileMgr.hpp"
36#include "StelGui.hpp"
37#include "StelMainView.hpp"
38#include "StelModuleMgr.hpp"
39#include "StelMovementMgr.hpp"
40#include "StelObjectMgr.hpp"
41#include "StelStyle.hpp"
42#include "StelTranslator.hpp"
43#include "StelUtils.hpp"
44#include "ui_meteorShowerDialog.h"
45
46MeteorShowerDialog::MeteorShowerDialog() : updateTimer(NULL)
47{
48 ui = new Ui_meteorShowerDialog;
49}
50
51MeteorShowerDialog::~MeteorShowerDialog()
52{
53 if (updateTimer)
54 {
55 updateTimer->stop();
56 delete updateTimer;
57 updateTimer = NULL;
58 }
59 delete ui;
60}
61
62void MeteorShowerDialog::retranslate()
63{
64 if (dialog)
65 {
66 ui->retranslateUi(dialog);
67 refreshUpdateValues();
68 setAboutHtml();
69 setHeaderNames();
70
71 //Retranslate name and datatype strings
72 QTreeWidgetItemIterator it(treeWidget);
73 while (*it) {
74 //Name
75 (*it)->setText(ColumnName, q_((*it)->text(ColumnName)));
76 //Data type
77 (*it)->setText(ColumnDataType, q_((*it)->text(ColumnDataType)));
78 ++it;
79 }
80 }
81}
82
83// Initialize the dialog widgets and connect the signals/slots
84void MeteorShowerDialog::createDialogContent()
85{
86 ui->setupUi(dialog);
87 ui->tabs->setCurrentIndex(0);
88 connect(&StelApp::getInstance(), SIGNAL(languageChanged()), this, SLOT(retranslate()));
89 plugin = GETSTELMODULE(MeteorShowers);
90
91 // Settings tab / updates group
92 connect(ui->internetUpdates, SIGNAL(clicked(bool)), this, SLOT(setUpdatesEnabled(bool)));
93 connect(ui->updateButton, SIGNAL(clicked()), this, SLOT(updateJSON()));
94 connect(plugin, SIGNAL(updateStateChanged(MeteorShowers::UpdateState)), this, SLOT(updateStateReceiver(MeteorShowers::UpdateState)));
95 connect(plugin, SIGNAL(jsonUpdateComplete(void)), this, SLOT(updateCompleteReceiver(void)));
96 connect(ui->updateFrequencySpinBox, SIGNAL(valueChanged(int)), this, SLOT(setUpdateValues(int)));
97 refreshUpdateValues(); // fetch values for last updated and so on
98
99 updateTimer = new QTimer(this);
100 connect(updateTimer, SIGNAL(timeout()), this, SLOT(refreshUpdateValues()));
101 updateTimer->start(7000);
102
103 // Settings tab / event group
104 connect(ui->searchButton, SIGNAL(clicked()), this, SLOT(checkDates()));
105 refreshRangeDates();
106
107 treeWidget = ui->listEvents;
108 initListEvents();
109 connect(treeWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(selectEvent(QModelIndex)));
110
111 // Settings tab / radiant group
112 ui->displayRadiant->setChecked(plugin->getFlagRadiant());
113 connect(ui->displayRadiant, SIGNAL(clicked(bool)), plugin, SLOT(setFlagRadiant(bool)));
114 ui->activeRadiantsOnly->setChecked(plugin->getFlagActiveRadiant());
115 connect(ui->activeRadiantsOnly, SIGNAL(clicked(bool)), plugin, SLOT(setFlagActiveRadiant(bool)));
116 ui->radiantLabels->setChecked(plugin->getFlagLabels());
117 connect(ui->radiantLabels, SIGNAL(clicked(bool)), plugin, SLOT(setFlagLabels(bool)));
118 ui->fontSizeSpinBox->setValue(plugin->getLabelFontSize());
119 connect(ui->fontSizeSpinBox, SIGNAL(valueChanged(int)), plugin, SLOT(setLabelFontSize(int)));
120
121 // Settings tab / meteor showers group
122 ui->displayMeteorShower->setChecked(plugin->getEnableAtStartup());
123 connect(ui->displayMeteorShower, SIGNAL(clicked(bool)), plugin, SLOT(setEnableAtStartup(bool)));
124 ui->displayShowMeteorShowerButton->setChecked(plugin->getFlagShowMSButton());
125 connect(ui->displayShowMeteorShowerButton, SIGNAL(clicked(bool)), plugin, SLOT(setFlagShowMSButton(bool)));
126
127 // /////////////////////////////////////////
128
129 connect(ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close()));
130
131 connect(ui->restoreDefaultsButton, SIGNAL(clicked()), this, SLOT(restoreDefaults()));
132 connect(ui->saveSettingsButton, SIGNAL(clicked()), this, SLOT(saveSettings()));
133
134 // Markers tab
135 refreshColorMarkers();
136 connect(ui->changeColorARG, SIGNAL(clicked()), this, SLOT(setColorARG()));
137 connect(ui->changeColorARR, SIGNAL(clicked()), this, SLOT(setColorARR()));
138 connect(ui->changeColorIR, SIGNAL(clicked()), this, SLOT(setColorIR()));
139
140 // About tab
141 setAboutHtml();
142 StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
143 Q_ASSERT(gui);
144 ui->aboutTextBrowser->document()->setDefaultStyleSheet(QString(gui->getStelStyle().htmlStyleSheet));
145
146 updateGuiFromSettings();
147}
148
149void MeteorShowerDialog::initListEvents(void)
150{
151 treeWidget->clear();
152 treeWidget->setColumnCount(ColumnCount);
153 setHeaderNames();
154 treeWidget->header()->setSectionsMovable(false);
155 treeWidget->header()->setStretchLastSection(true);
156}
157
158void MeteorShowerDialog::setHeaderNames(void)
159{
160 QStringList headerStrings;
161 headerStrings << q_("Name");
162 headerStrings << q_("ZHR");
163 headerStrings << q_("Data Type");
164 headerStrings << q_("Peak");
165 treeWidget->setHeaderLabels(headerStrings);
166}
167
168void MeteorShowerDialog::checkDates(void)
169{
170 double jdFrom = StelUtils::qDateTimeToJd((QDateTime) ui->dateFrom->date());
171 double jdTo = StelUtils::qDateTimeToJd((QDateTime) ui->dateTo->date());
172
173 if(jdFrom > jdTo)
174 QMessageBox::warning(0, "Stellarium", q_("Start date greater than end date!"));
175 else if (jdTo-jdFrom > 365)
176 QMessageBox::warning(0, "Stellarium", q_("Time interval must be less than one year!"));
177 else
178 searchEvents();
179}
180
181void MeteorShowerDialog::searchEvents(void)
182{
183 QList<MeteorShowerP> searchResult = plugin->searchEvents(ui->dateFrom->date(), ui->dateTo->date());
184
185 //Fill list of events
186 initListEvents();
187 foreach(const MeteorShowerP& r, searchResult)
188 {
189 TreeWidgetItem *treeItem = new TreeWidgetItem(treeWidget);
190 //Name
191 treeItem->setText(ColumnName, r->getNameI18n());
192 //ZHR
193 QString zhr = r->getZHR()==-1?q_("Variable"):QString::number(r->getZHR());
194 treeItem->setText(ColumnZHR, zhr);
195 //Data Type
196 QString dataType = r->getStatus()==1?q_("Real"):q_("Generic");
197 treeItem->setText(ColumnDataType, dataType);
198 //Peak
199 QString peak = r->getPeak().toString("dd/MMM/yyyy");
200 treeItem->setText(ColumnPeak, peak);
201 }
202}
203
204void MeteorShowerDialog::selectEvent(const QModelIndex &modelIndex)
205{
206 StelCore *core = StelApp::getInstance().getCore();
207
208 //Change date
209 QString dateString = treeWidget->currentItem()->text(ColumnPeak);
210 QDateTime qDateTime = QDateTime::fromString(dateString, "dd/MMM/yyyy");
211 core->setJDay(StelUtils::qDateTimeToJd(qDateTime));
212
213 //Select object
214 QString namel18n = treeWidget->currentItem()->text(ColumnName);
215 StelObjectMgr* objectMgr = GETSTELMODULE(StelObjectMgr);
216 if((objectMgr->findAndSelectI18n(namel18n) || objectMgr->findAndSelect(namel18n)) && plugin->getFlagShowMS())
217 {
218 //Move to object
219 StelMovementMgr* mvmgr = GETSTELMODULE(StelMovementMgr);
220 mvmgr->moveToObject(objectMgr->getSelectedObject()[0], mvmgr->getAutoMoveDuration());
221 mvmgr->setFlagTracking(true);
222 }
223}
224
225void MeteorShowerDialog::refreshRangeDates(void)
226{
227 int year = plugin->getSkyDate().toString("yyyy").toInt();
228 ui->dateFrom->setDate(QDate(year, 1, 1)); // first date in the range - first day of the year
229 ui->dateTo->setDate(QDate(year, 12, 31)); // second date in the range - last day of the year
230}
231
232void MeteorShowerDialog::setAboutHtml(void)
233{
234 QString html = "<html><head></head><body>";
235 html += "<h2>" + q_("Meteor Showers Plugin") + "</h2><table width=\"90%\">";
236 html += "<tr width=\"30%\"><td>" + q_("Version:") + "</td><td>" + METEORSHOWERS_PLUGIN_VERSION + "</td></tr>";
237 html += "<tr><td>" + q_("Author:") + "</td><td>Marcos Cardinot &lt;mcardinot@gmail.com&gt;</td></tr></table>";
238
239 html += "<p>" + q_("The Meteor Showers plugin give visualization of the meteor showers, show information about meteor showers and displays marker for radiants in activity range for each meteor showers.") + "</p>";
240 html += "<h3>" + q_("Terms") + "</h3>";
241 html += "<p><b>" + q_("Meteor shower") + "</b>";
242 html += "<br />" + q_("A meteor shower is a celestial event in which a number of meteors are observed to radiate, or originate, from one point in the night sky. These meteors are caused by streams of cosmic debris called meteoroids entering Earth's atmosphere at extremely high speeds on parallel trajectories. Most meteors are smaller than a grain of sand, so almost all of them disintegrate and never hit the Earth's surface. Intense or unusual meteor showers are known as meteor outbursts and meteor storms, which may produce greater than 1,000 meteors an hour.") + "</p>";
243 html += "<p><b>" + q_("Radiant") + "</b>";
244 html += "<br />" + q_("The radiant or apparent radiant of a meteor shower is the point in the sky, from which (to a planetary observer) meteors appear to originate. The Perseids, for example, are meteors which appear to come from a point within the constellation of Perseus.") + "</p>";
245 html += "<p>" + q_("An observer might see such a meteor anywhere in the sky but the direction of motion, when traced back, will point to the radiant. A meteor that does not point back to the known radiant for a given shower is known as a sporadic and is not considered part of that shower.") + "</p>";
246 html += "<p>" + q_("Many showers have a radiant point that changes position during the interval when it appears. For example, the radiant point for the Delta Aurigids drifts by more than a degree per night.") + "</p>";
247 html += "<p><b>" + q_("Zenithal Hourly Rate (ZHR)") + "</b>";
248 html += "<br />" + q_("In astronomy, the Zenithal Hourly Rate (ZHR) of a meteor shower is the number of meteors a single observer would see in one hour under a clear, dark sky (limiting apparent magnitude of 6.5) if the radiant of the shower were at the zenith. The rate that can effectively be seen is nearly always lower and decreases the closer the radiant is to the horizon.") + "</p>";
249 html += "<p><b>" + q_("Population index") + "</b>";
250 html += "<br />" + q_("The population index indicates the magnitude distribution of the meteor showers. The values below 2.5 correspond to distributions where bright meteors are more frequent than average, while values above 3.0 mean that the share of faint meteors is larger than usual.") + "</p>";
251 html += "<h3>" + q_("Notes") + "</h3>";
252 html += "<p>" + q_("This plugin was created as project of ESA Summer of Code in Space 2013.") + "</p>";
253 html += "<h3>" + q_("Info") + "</h3>";
254 html += "<p>" + q_("Info about meteor showers you can get here:") + "</p>";
255 html += "<ul>";
256 html += "<li>" + QString(q_("%1Meteor shower%2 - article in Wikipedia").arg("<a href=\"https://en.wikipedia.org/wiki/Meteor_Showers\">")).arg("</a>") + "</li>";
257 html += "<li>" + QString(q_("%1International Meteor Organization%2").arg("<a href=\"http://www.imo.net/\">")).arg("</a>") + "</li>";
258 html += "</ul>";
259 html += "<h3>" + q_("Links") + "</h3>";
260 html += "<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>";
261 html += "<ul>";
262 // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
263 html += "<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>";
264 // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
265 html += "<li>" + QString(q_("Bug reports can be made %1here%2.")).arg("<a href=\"https://bugs.launchpad.net/stellarium\">").arg("</a>") + "</li>";
266 // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
267 html += "<li>" + q_("If you would like to make a feature request, you can create a bug report, and set the severity to \"wishlist\".") + "</li>";
268 // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
269 html += "<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>";
270 html += "</ul></body></html>";
271
272 ui->aboutTextBrowser->setHtml(html);
273}
274
275void MeteorShowerDialog::refreshUpdateValues(void)
276{
277 ui->lastUpdateDateTimeEdit->setDateTime(plugin->getLastUpdate());
278 ui->updateFrequencySpinBox->setValue(plugin->getUpdateFrequencyHours());
279 int secondsToUpdate = plugin->getSecondsToUpdate();
280 if (!plugin->getUpdatesEnabled())
281 ui->nextUpdateLabel->setText(q_("Internet updates disabled"));
282 else if (plugin->getUpdateState() == MeteorShowers::Updating)
283 ui->nextUpdateLabel->setText(q_("Updating now..."));
284 else if (secondsToUpdate <= 60)
285 ui->nextUpdateLabel->setText(q_("Next update: < 1 minute"));
286 else if (secondsToUpdate < 3600)
287 ui->nextUpdateLabel->setText(QString(q_("Next update: %1 minutes")).arg((secondsToUpdate/60)+1));
288 else
289 ui->nextUpdateLabel->setText(QString(q_("Next update: %1 hours")).arg((secondsToUpdate/3600)+1));
290}
291
292void MeteorShowerDialog::setUpdateValues(int hours)
293{
294 plugin->setUpdateFrequencyHours(hours);
295 refreshUpdateValues();
296}
297
298void MeteorShowerDialog::setUpdatesEnabled(bool checkState)
299{
300 plugin->setUpdatesEnabled(checkState);
301 ui->updateFrequencySpinBox->setEnabled(checkState);
302 ui->updateButton->setText(q_("Update now"));
303 refreshUpdateValues();
304}
305
306
307void MeteorShowerDialog::updateStateReceiver(MeteorShowers::UpdateState state)
308{
309 //qDebug() << "MeteorShowerDialog::updateStateReceiver got a signal";
310 if (state==MeteorShowers::Updating)
311 ui->nextUpdateLabel->setText(q_("Updating now..."));
312 else if (state==MeteorShowers::DownloadError || state==MeteorShowers::OtherError)
313 {
314 ui->nextUpdateLabel->setText(q_("Update error"));
315 updateTimer->start(); // make sure message is displayed for a while...
316 }
317}
318
319void MeteorShowerDialog::updateCompleteReceiver(void)
320{
321 ui->nextUpdateLabel->setText(QString(q_("Meteor showers is updated")));
322 // display the status for another full interval before refreshing status
323 updateTimer->start();
324 ui->lastUpdateDateTimeEdit->setDateTime(GETSTELMODULE(MeteorShowers)->getLastUpdate());
325 QTimer *timer = new QTimer(this);
326 connect(timer, SIGNAL(timeout()), this, SLOT(refreshUpdateValues()));
327}
328
329void MeteorShowerDialog::restoreDefaults(void)
330{
331 qDebug() << "MeteorShowers::restoreDefaults";
332 plugin->restoreDefaults();
333 plugin->readSettingsFromConfig();
334 updateGuiFromSettings();
335}
336
337void MeteorShowerDialog::updateGuiFromSettings(void)
338{
339 refreshUpdateValues();
340 refreshColorMarkers();
341}
342
343void MeteorShowerDialog::saveSettings(void)
344{
345 plugin->saveSettingsToConfig();
346}
347
348void MeteorShowerDialog::updateJSON(void)
349{
350 if(plugin->getUpdatesEnabled())
351 {
352 plugin->updateJSON();
353 }
354}
355
356void MeteorShowerDialog::refreshColorMarkers(void)
357{
358 setTextureColor(ui->textureARG, plugin->getColorARG());
359 setTextureColor(ui->textureARR, plugin->getColorARR());
360 setTextureColor(ui->textureIR, plugin->getColorIR());
361}
362
363void MeteorShowerDialog::setTextureColor(QLabel *texture, QColor color)
364{
365 QGraphicsColorizeEffect *e = new QGraphicsColorizeEffect(texture);
366 e->setColor(color);
367 texture->setGraphicsEffect(e);
368}
369
370void MeteorShowerDialog::setColorARG()
371{
372 QColor color = QColorDialog::getColor();
373 setTextureColor(ui->textureARG, color);
374 plugin->setColorARG(color);
375}
376
377void MeteorShowerDialog::setColorARR()
378{
379 QColor color = QColorDialog::getColor();
380 setTextureColor(ui->textureARR, color);
381 plugin->setColorARR(color);
382}
383
384void MeteorShowerDialog::setColorIR()
385{
386 QColor color = QColorDialog::getColor();
387 setTextureColor(ui->textureIR, color);
388 plugin->setColorIR(color);
389}
0390
=== added file 'plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp'
--- plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp 2014-03-10 17:28:07 +0000
@@ -0,0 +1,111 @@
1/*
2 * Stellarium Meteor Shower Plug-in GUI
3 *
4 * Copyright (C) 2013 Marcos Cardinot
5 * Copyright (C) 2011 Alexander Wolf
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
20*/
21
22#ifndef _METEORSHOWERDIALOG_HPP_
23#define _METEORSHOWERDIALOG_HPP_
24
25#include <QColor>
26#include <QLabel>
27#include <QObject>
28#include <QTreeWidget>
29
30#include "MeteorShowers.hpp"
31#include "StelDialog.hpp"
32
33class MeteorShowers;
34class QTimer;
35class Ui_meteorShowerDialog;
36
37class MeteorShowerDialog : public StelDialog
38{
39 Q_OBJECT
40
41public:
42 MeteorShowerDialog();
43 ~MeteorShowerDialog();
44
45protected:
46 //! Initialize the dialog widgets and connect the signals/slots
47 void createDialogContent();
48
49public slots:
50 void retranslate();
51 void refreshUpdateValues(void); //! Refresh details about the last update
52 void refreshColorMarkers(void); //! Refresh the color of all markers
53 void refreshRangeDates(void); //! Refresh dates range when year in main app change
54
55private slots:
56 void setUpdateValues(int hours);
57 void setUpdatesEnabled(bool checkState);
58 void updateStateReceiver(MeteorShowers::UpdateState state);
59 void updateCompleteReceiver();
60 void restoreDefaults(void);
61 void saveSettings(void);
62 void updateJSON(void);
63 void setColorARR(void); //! Set color of active radiant based on real data.
64 void setColorARG(void); //! Set color of active radiant based on generic data.
65 void setColorIR(void); //! Set color of inactive radiant.
66 void checkDates(void); //! Checks if the inputed dates are valid for use.
67 void searchEvents(void); //! Search events and fill the list.
68 void selectEvent(const QModelIndex &modelIndex); //! If an event is selected by user, the current date change and the object is selected.
69
70private:
71 Ui_meteorShowerDialog* ui;
72 MeteorShowers* plugin;
73 void setAboutHtml(void);
74 void updateGuiFromSettings(void);
75 QTimer* updateTimer;
76 void setTextureColor(QLabel* texture, QColor color);
77
78 //! Defines the number and the order of the columns in the table that lists active meteor showers
79 //! @enum ModelColumns
80 enum ModelColumns {
81 ColumnName, //! name column
82 ColumnZHR, //! zhr column
83 ColumnDataType, //! data type column
84 ColumnPeak, //! peak date column
85 ColumnCount //! total number of columns
86 };
87 QTreeWidget* treeWidget; //! list of events
88 void initListEvents(void); //! Init header and list of events
89 void setHeaderNames(void); //! Update header names
90
91 // Reimplementation of QTreeWidgetItem class to fix the sorting bug
92 class TreeWidgetItem : public QTreeWidgetItem
93 {
94 public:
95 TreeWidgetItem(QTreeWidget* parent):QTreeWidgetItem(parent){}
96
97 private:
98 bool operator<(const QTreeWidgetItem &other)const {
99 int column = treeWidget()->sortColumn();
100
101 if (column == ColumnPeak)
102 return QDateTime::fromString(text(column),"dd/MMM/yyyy").operator <(QDateTime::fromString(other.text(column),"dd/MMM/yyyy"));
103 else if (column == ColumnZHR)
104 return text(column).toInt() < other.text(column).toInt();
105 else //ColumnName or ColumnDataType
106 return text(column).toLower() < other.text(column).toLower();
107 }
108 };
109};
110
111#endif // _METEORSHOWERDIALOG_HPP_
0112
=== added file 'plugins/MeteorShowers/src/gui/meteorShowerDialog.ui'
--- plugins/MeteorShowers/src/gui/meteorShowerDialog.ui 1970-01-01 00:00:00 +0000
+++ plugins/MeteorShowers/src/gui/meteorShowerDialog.ui 2014-03-10 17:28:07 +0000
@@ -0,0 +1,867 @@
1<?xml version="1.0" encoding="UTF-8"?>
2<ui version="4.0">
3 <class>meteorShowerDialog</class>
4 <widget class="QWidget" name="meteorShowerDialog">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>530</width>
10 <height>404</height>
11 </rect>
12 </property>
13 <property name="windowTitle">
14 <string>Meteor Showers Configuration</string>
15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout_2">
17 <property name="spacing">
18 <number>0</number>
19 </property>
20 <property name="leftMargin">
21 <number>0</number>
22 </property>
23 <property name="topMargin">
24 <number>0</number>
25 </property>
26 <property name="rightMargin">
27 <number>0</number>
28 </property>
29 <property name="bottomMargin">
30 <number>0</number>
31 </property>
32 <item>
33 <widget class="BarFrame" name="TitleBar">
34 <property name="sizePolicy">
35 <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
36 <horstretch>0</horstretch>
37 <verstretch>0</verstretch>
38 </sizepolicy>
39 </property>
40 <property name="minimumSize">
41 <size>
42 <width>530</width>
43 <height>25</height>
44 </size>
45 </property>
46 <property name="maximumSize">
47 <size>
48 <width>16777215</width>
49 <height>25</height>
50 </size>
51 </property>
52 <property name="focusPolicy">
53 <enum>Qt::NoFocus</enum>
54 </property>
55 <property name="autoFillBackground">
56 <bool>false</bool>
57 </property>
58 <property name="frameShape">
59 <enum>QFrame::StyledPanel</enum>
60 </property>
61 <layout class="QHBoxLayout">
62 <property name="spacing">
63 <number>0</number>
64 </property>
65 <property name="leftMargin">
66 <number>0</number>
67 </property>
68 <property name="topMargin">
69 <number>0</number>
70 </property>
71 <property name="rightMargin">
72 <number>4</number>
73 </property>
74 <property name="bottomMargin">
75 <number>0</number>
76 </property>
77 <item>
78 <spacer>
79 <property name="orientation">
80 <enum>Qt::Horizontal</enum>
81 </property>
82 <property name="sizeHint" stdset="0">
83 <size>
84 <width>40</width>
85 <height>20</height>
86 </size>
87 </property>
88 </spacer>
89 </item>
90 <item>
91 <widget class="QLabel" name="stelWindowTitle">
92 <property name="text">
93 <string>Meteor Showers Plug-in Configuration</string>
94 </property>
95 </widget>
96 </item>
97 <item>
98 <spacer>
99 <property name="orientation">
100 <enum>Qt::Horizontal</enum>
101 </property>
102 <property name="sizeHint" stdset="0">
103 <size>
104 <width>40</width>
105 <height>20</height>
106 </size>
107 </property>
108 </spacer>
109 </item>
110 <item>
111 <widget class="QPushButton" name="closeStelWindow">
112 <property name="minimumSize">
113 <size>
114 <width>16</width>
115 <height>16</height>
116 </size>
117 </property>
118 <property name="maximumSize">
119 <size>
120 <width>16</width>
121 <height>16</height>
122 </size>
123 </property>
124 <property name="focusPolicy">
125 <enum>Qt::NoFocus</enum>
126 </property>
127 <property name="text">
128 <string/>
129 </property>
130 </widget>
131 </item>
132 </layout>
133 </widget>
134 </item>
135 <item>
136 <widget class="QTabWidget" name="tabs">
137 <property name="currentIndex">
138 <number>2</number>
139 </property>
140 <property name="documentMode">
141 <bool>false</bool>
142 </property>
143 <widget class="QWidget" name="settingsTab">
144 <attribute name="title">
145 <string>Settings</string>
146 </attribute>
147 <layout class="QVBoxLayout" name="verticalLayout_3">
148 <item>
149 <widget class="QGroupBox" name="internetUpdates">
150 <property name="title">
151 <string>Update data from Internet</string>
152 </property>
153 <property name="flat">
154 <bool>true</bool>
155 </property>
156 <property name="checkable">
157 <bool>true</bool>
158 </property>
159 <property name="checked">
160 <bool>true</bool>
161 </property>
162 <layout class="QVBoxLayout" name="verticalLayout_12">
163 <item>
164 <layout class="QGridLayout" name="gridLayout">
165 <item row="0" column="0">
166 <widget class="QLabel" name="lastUpdateLabel">
167 <property name="text">
168 <string>Last update:</string>
169 </property>
170 </widget>
171 </item>
172 <item row="0" column="2">
173 <widget class="QDateTimeEdit" name="lastUpdateDateTimeEdit">
174 <property name="enabled">
175 <bool>false</bool>
176 </property>
177 <property name="sizePolicy">
178 <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
179 <horstretch>0</horstretch>
180 <verstretch>0</verstretch>
181 </sizepolicy>
182 </property>
183 <property name="frame">
184 <bool>false</bool>
185 </property>
186 <property name="buttonSymbols">
187 <enum>QAbstractSpinBox::NoButtons</enum>
188 </property>
189 </widget>
190 </item>
191 <item row="1" column="0">
192 <widget class="QLabel" name="updateFrequencyLabel">
193 <property name="text">
194 <string>Update frequency (hours):</string>
195 </property>
196 </widget>
197 </item>
198 <item row="1" column="2">
199 <widget class="QSpinBox" name="updateFrequencySpinBox">
200 <property name="sizePolicy">
201 <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
202 <horstretch>0</horstretch>
203 <verstretch>0</verstretch>
204 </sizepolicy>
205 </property>
206 <property name="minimum">
207 <number>1</number>
208 </property>
209 <property name="maximum">
210 <number>9999</number>
211 </property>
212 <property name="value">
213 <number>1</number>
214 </property>
215 </widget>
216 </item>
217 <item row="2" column="0">
218 <widget class="QLabel" name="nextUpdateLabel">
219 <property name="text">
220 <string>[next update info]</string>
221 </property>
222 </widget>
223 </item>
224 <item row="2" column="1">
225 <spacer name="horizontalSpacer">
226 <property name="orientation">
227 <enum>Qt::Horizontal</enum>
228 </property>
229 <property name="sizeHint" stdset="0">
230 <size>
231 <width>17</width>
232 <height>20</height>
233 </size>
234 </property>
235 </spacer>
236 </item>
237 <item row="2" column="2">
238 <widget class="QPushButton" name="updateButton">
239 <property name="sizePolicy">
240 <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
241 <horstretch>0</horstretch>
242 <verstretch>0</verstretch>
243 </sizepolicy>
244 </property>
245 <property name="text">
246 <string>Update now</string>
247 </property>
248 </widget>
249 </item>
250 </layout>
251 </item>
252 </layout>
253 </widget>
254 </item>
255 <item>
256 <widget class="QGroupBox" name="displayMeteorShowerBox">
257 <property name="toolTip">
258 <string/>
259 </property>
260 <property name="title">
261 <string>Meteor showers</string>
262 </property>
263 <property name="flat">
264 <bool>true</bool>
265 </property>
266 <property name="checkable">
267 <bool>false</bool>
268 </property>
269 <layout class="QGridLayout" name="gridLayout_8">
270 <item row="1" column="0">
271 <widget class="QCheckBox" name="displayShowMeteorShowerButton">
272 <property name="text">
273 <string>Show meteor showers button on toolbar</string>
274 </property>
275 </widget>
276 </item>
277 <item row="0" column="0">
278 <widget class="QCheckBox" name="displayMeteorShower">
279 <property name="text">
280 <string>Enable display of meteor showers at startup</string>
281 </property>
282 </widget>
283 </item>
284 </layout>
285 </widget>
286 </item>
287 <item>
288 <spacer name="verticalSpacer_3">
289 <property name="orientation">
290 <enum>Qt::Vertical</enum>
291 </property>
292 <property name="sizeHint" stdset="0">
293 <size>
294 <width>20</width>
295 <height>120</height>
296 </size>
297 </property>
298 </spacer>
299 </item>
300 <item>
301 <layout class="QHBoxLayout" name="horizontalLayout_7">
302 <item>
303 <widget class="QPushButton" name="restoreDefaultsButton">
304 <property name="sizePolicy">
305 <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
306 <horstretch>0</horstretch>
307 <verstretch>0</verstretch>
308 </sizepolicy>
309 </property>
310 <property name="text">
311 <string>Restore default settings</string>
312 </property>
313 </widget>
314 </item>
315 <item>
316 <widget class="QPushButton" name="saveSettingsButton">
317 <property name="sizePolicy">
318 <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
319 <horstretch>0</horstretch>
320 <verstretch>0</verstretch>
321 </sizepolicy>
322 </property>
323 <property name="text">
324 <string>Save settings as default</string>
325 </property>
326 </widget>
327 </item>
328 </layout>
329 </item>
330 </layout>
331 </widget>
332 <widget class="QWidget" name="radiantTab">
333 <property name="enabled">
334 <bool>true</bool>
335 </property>
336 <attribute name="title">
337 <string>Radiants</string>
338 </attribute>
339 <layout class="QVBoxLayout" name="verticalLayout_4">
340 <item>
341 <widget class="QGroupBox" name="groupBox">
342 <property name="title">
343 <string>Color of radiants markers</string>
344 </property>
345 <layout class="QGridLayout" name="gridLayout_5">
346 <property name="leftMargin">
347 <number>0</number>
348 </property>
349 <property name="topMargin">
350 <number>0</number>
351 </property>
352 <property name="rightMargin">
353 <number>0</number>
354 </property>
355 <property name="bottomMargin">
356 <number>0</number>
357 </property>
358 <property name="spacing">
359 <number>0</number>
360 </property>
361 <item row="0" column="1" alignment="Qt::AlignHCenter">
362 <widget class="QGroupBox" name="activeGenericData">
363 <property name="minimumSize">
364 <size>
365 <width>86</width>
366 <height>0</height>
367 </size>
368 </property>
369 <property name="toolTip">
370 <string>Active Radiant - Generic Data</string>
371 </property>
372 <property name="alignment">
373 <set>Qt::AlignCenter</set>
374 </property>
375 <layout class="QGridLayout" name="gridLayout_3">
376 <property name="leftMargin">
377 <number>0</number>
378 </property>
379 <property name="topMargin">
380 <number>0</number>
381 </property>
382 <property name="rightMargin">
383 <number>0</number>
384 </property>
385 <property name="bottomMargin">
386 <number>0</number>
387 </property>
388 <property name="spacing">
389 <number>0</number>
390 </property>
391 <item row="1" column="0">
392 <widget class="QPushButton" name="changeColorARG">
393 <property name="toolTip">
394 <string>Change Color</string>
395 </property>
396 <property name="text">
397 <string notr="true">...</string>
398 </property>
399 </widget>
400 </item>
401 <item row="0" column="0">
402 <widget class="QFrame" name="frame_4">
403 <property name="minimumSize">
404 <size>
405 <width>64</width>
406 <height>64</height>
407 </size>
408 </property>
409 <property name="maximumSize">
410 <size>
411 <width>64</width>
412 <height>64</height>
413 </size>
414 </property>
415 <property name="frameShape">
416 <enum>QFrame::StyledPanel</enum>
417 </property>
418 <property name="frameShadow">
419 <enum>QFrame::Raised</enum>
420 </property>
421 <widget class="QLabel" name="textureARG">
422 <property name="geometry">
423 <rect>
424 <x>0</x>
425 <y>0</y>
426 <width>64</width>
427 <height>64</height>
428 </rect>
429 </property>
430 <property name="minimumSize">
431 <size>
432 <width>64</width>
433 <height>64</height>
434 </size>
435 </property>
436 <property name="maximumSize">
437 <size>
438 <width>64</width>
439 <height>64</height>
440 </size>
441 </property>
442 <property name="styleSheet">
443 <string notr="true">background-image: url(:/MeteorShowers/radiantSetting.png);</string>
444 </property>
445 <property name="text">
446 <string/>
447 </property>
448 </widget>
449 </widget>
450 </item>
451 </layout>
452 </widget>
453 </item>
454 <item row="0" column="2" alignment="Qt::AlignHCenter">
455 <widget class="QGroupBox" name="inactive">
456 <property name="minimumSize">
457 <size>
458 <width>86</width>
459 <height>0</height>
460 </size>
461 </property>
The diff has been truncated for viewing.