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
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2014-03-01 15:42:49 +0000
3+++ CMakeLists.txt 2014-03-10 17:28:07 +0000
4@@ -161,6 +161,7 @@
5 ADD_PLUGIN(EquationOfTime 1)
6 ADD_PLUGIN(FOV 1)
7 ADD_PLUGIN(LogBook 0)
8+ADD_PLUGIN(MeteorShowers 1)
9 ADD_PLUGIN(NavStars 1)
10 ADD_PLUGIN(Novae 1)
11 ADD_PLUGIN(Observability 1)
12
13=== added directory 'plugins/MeteorShowers'
14=== added file 'plugins/MeteorShowers/CMakeLists.txt'
15--- plugins/MeteorShowers/CMakeLists.txt 1970-01-01 00:00:00 +0000
16+++ plugins/MeteorShowers/CMakeLists.txt 2014-03-10 17:28:07 +0000
17@@ -0,0 +1,16 @@
18+SET(METEORSHOWERS_MAJOR "1")
19+SET(METEORSHOWERS_MINOR "0")
20+SET(METEORSHOWERS_PATCH "0")
21+SET(METEORSHOWERS_VERSION "${METEORSHOWERS_MAJOR}.${METEORSHOWERS_MINOR}.${METEORSHOWERS_PATCH}")
22+
23+IF(APPLE)
24+ SET(CMAKE_INSTALL_PREFIX $ENV{HOME}/Library/Application\ Support/Stellarium)
25+ELSE(APPLE)
26+ SET(CMAKE_INSTALL_PREFIX $ENV{HOME}/.stellarium)
27+ENDIF(APPLE)
28+
29+ADD_DEFINITIONS(-DMETEORSHOWERS_PLUGIN_VERSION="${METEORSHOWERS_VERSION}")
30+
31+ADD_SUBDIRECTORY( src )
32+
33+INSTALL(FILES DESTINATION "modules/MeteorShowers")
34
35=== added file 'plugins/MeteorShowers/COPYING'
36--- plugins/MeteorShowers/COPYING 1970-01-01 00:00:00 +0000
37+++ plugins/MeteorShowers/COPYING 2014-03-10 17:28:07 +0000
38@@ -0,0 +1,340 @@
39+ GNU GENERAL PUBLIC LICENSE
40+ Version 2, June 1991
41+
42+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
43+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
44+ Everyone is permitted to copy and distribute verbatim copies
45+ of this license document, but changing it is not allowed.
46+
47+ Preamble
48+
49+ The licenses for most software are designed to take away your
50+freedom to share and change it. By contrast, the GNU General Public
51+License is intended to guarantee your freedom to share and change free
52+software--to make sure the software is free for all its users. This
53+General Public License applies to most of the Free Software
54+Foundation's software and to any other program whose authors commit to
55+using it. (Some other Free Software Foundation software is covered by
56+the GNU Library General Public License instead.) You can apply it to
57+your programs, too.
58+
59+ When we speak of free software, we are referring to freedom, not
60+price. Our General Public Licenses are designed to make sure that you
61+have the freedom to distribute copies of free software (and charge for
62+this service if you wish), that you receive source code or can get it
63+if you want it, that you can change the software or use pieces of it
64+in new free programs; and that you know you can do these things.
65+
66+ To protect your rights, we need to make restrictions that forbid
67+anyone to deny you these rights or to ask you to surrender the rights.
68+These restrictions translate to certain responsibilities for you if you
69+distribute copies of the software, or if you modify it.
70+
71+ For example, if you distribute copies of such a program, whether
72+gratis or for a fee, you must give the recipients all the rights that
73+you have. You must make sure that they, too, receive or can get the
74+source code. And you must show them these terms so they know their
75+rights.
76+
77+ We protect your rights with two steps: (1) copyright the software, and
78+(2) offer you this license which gives you legal permission to copy,
79+distribute and/or modify the software.
80+
81+ Also, for each author's protection and ours, we want to make certain
82+that everyone understands that there is no warranty for this free
83+software. If the software is modified by someone else and passed on, we
84+want its recipients to know that what they have is not the original, so
85+that any problems introduced by others will not reflect on the original
86+authors' reputations.
87+
88+ Finally, any free program is threatened constantly by software
89+patents. We wish to avoid the danger that redistributors of a free
90+program will individually obtain patent licenses, in effect making the
91+program proprietary. To prevent this, we have made it clear that any
92+patent must be licensed for everyone's free use or not licensed at all.
93+
94+ The precise terms and conditions for copying, distribution and
95+modification follow.
96+
97
98+ GNU GENERAL PUBLIC LICENSE
99+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
100+
101+ 0. This License applies to any program or other work which contains
102+a notice placed by the copyright holder saying it may be distributed
103+under the terms of this General Public License. The "Program", below,
104+refers to any such program or work, and a "work based on the Program"
105+means either the Program or any derivative work under copyright law:
106+that is to say, a work containing the Program or a portion of it,
107+either verbatim or with modifications and/or translated into another
108+language. (Hereinafter, translation is included without limitation in
109+the term "modification".) Each licensee is addressed as "you".
110+
111+Activities other than copying, distribution and modification are not
112+covered by this License; they are outside its scope. The act of
113+running the Program is not restricted, and the output from the Program
114+is covered only if its contents constitute a work based on the
115+Program (independent of having been made by running the Program).
116+Whether that is true depends on what the Program does.
117+
118+ 1. You may copy and distribute verbatim copies of the Program's
119+source code as you receive it, in any medium, provided that you
120+conspicuously and appropriately publish on each copy an appropriate
121+copyright notice and disclaimer of warranty; keep intact all the
122+notices that refer to this License and to the absence of any warranty;
123+and give any other recipients of the Program a copy of this License
124+along with the Program.
125+
126+You may charge a fee for the physical act of transferring a copy, and
127+you may at your option offer warranty protection in exchange for a fee.
128+
129+ 2. You may modify your copy or copies of the Program or any portion
130+of it, thus forming a work based on the Program, and copy and
131+distribute such modifications or work under the terms of Section 1
132+above, provided that you also meet all of these conditions:
133+
134+ a) You must cause the modified files to carry prominent notices
135+ stating that you changed the files and the date of any change.
136+
137+ b) You must cause any work that you distribute or publish, that in
138+ whole or in part contains or is derived from the Program or any
139+ part thereof, to be licensed as a whole at no charge to all third
140+ parties under the terms of this License.
141+
142+ c) If the modified program normally reads commands interactively
143+ when run, you must cause it, when started running for such
144+ interactive use in the most ordinary way, to print or display an
145+ announcement including an appropriate copyright notice and a
146+ notice that there is no warranty (or else, saying that you provide
147+ a warranty) and that users may redistribute the program under
148+ these conditions, and telling the user how to view a copy of this
149+ License. (Exception: if the Program itself is interactive but
150+ does not normally print such an announcement, your work based on
151+ the Program is not required to print an announcement.)
152+
153
154+These requirements apply to the modified work as a whole. If
155+identifiable sections of that work are not derived from the Program,
156+and can be reasonably considered independent and separate works in
157+themselves, then this License, and its terms, do not apply to those
158+sections when you distribute them as separate works. But when you
159+distribute the same sections as part of a whole which is a work based
160+on the Program, the distribution of the whole must be on the terms of
161+this License, whose permissions for other licensees extend to the
162+entire whole, and thus to each and every part regardless of who wrote it.
163+
164+Thus, it is not the intent of this section to claim rights or contest
165+your rights to work written entirely by you; rather, the intent is to
166+exercise the right to control the distribution of derivative or
167+collective works based on the Program.
168+
169+In addition, mere aggregation of another work not based on the Program
170+with the Program (or with a work based on the Program) on a volume of
171+a storage or distribution medium does not bring the other work under
172+the scope of this License.
173+
174+ 3. You may copy and distribute the Program (or a work based on it,
175+under Section 2) in object code or executable form under the terms of
176+Sections 1 and 2 above provided that you also do one of the following:
177+
178+ a) Accompany it with the complete corresponding machine-readable
179+ source code, which must be distributed under the terms of Sections
180+ 1 and 2 above on a medium customarily used for software interchange; or,
181+
182+ b) Accompany it with a written offer, valid for at least three
183+ years, to give any third party, for a charge no more than your
184+ cost of physically performing source distribution, a complete
185+ machine-readable copy of the corresponding source code, to be
186+ distributed under the terms of Sections 1 and 2 above on a medium
187+ customarily used for software interchange; or,
188+
189+ c) Accompany it with the information you received as to the offer
190+ to distribute corresponding source code. (This alternative is
191+ allowed only for noncommercial distribution and only if you
192+ received the program in object code or executable form with such
193+ an offer, in accord with Subsection b above.)
194+
195+The source code for a work means the preferred form of the work for
196+making modifications to it. For an executable work, complete source
197+code means all the source code for all modules it contains, plus any
198+associated interface definition files, plus the scripts used to
199+control compilation and installation of the executable. However, as a
200+special exception, the source code distributed need not include
201+anything that is normally distributed (in either source or binary
202+form) with the major components (compiler, kernel, and so on) of the
203+operating system on which the executable runs, unless that component
204+itself accompanies the executable.
205+
206+If distribution of executable or object code is made by offering
207+access to copy from a designated place, then offering equivalent
208+access to copy the source code from the same place counts as
209+distribution of the source code, even though third parties are not
210+compelled to copy the source along with the object code.
211+
212
213+ 4. You may not copy, modify, sublicense, or distribute the Program
214+except as expressly provided under this License. Any attempt
215+otherwise to copy, modify, sublicense or distribute the Program is
216+void, and will automatically terminate your rights under this License.
217+However, parties who have received copies, or rights, from you under
218+this License will not have their licenses terminated so long as such
219+parties remain in full compliance.
220+
221+ 5. You are not required to accept this License, since you have not
222+signed it. However, nothing else grants you permission to modify or
223+distribute the Program or its derivative works. These actions are
224+prohibited by law if you do not accept this License. Therefore, by
225+modifying or distributing the Program (or any work based on the
226+Program), you indicate your acceptance of this License to do so, and
227+all its terms and conditions for copying, distributing or modifying
228+the Program or works based on it.
229+
230+ 6. Each time you redistribute the Program (or any work based on the
231+Program), the recipient automatically receives a license from the
232+original licensor to copy, distribute or modify the Program subject to
233+these terms and conditions. You may not impose any further
234+restrictions on the recipients' exercise of the rights granted herein.
235+You are not responsible for enforcing compliance by third parties to
236+this License.
237+
238+ 7. If, as a consequence of a court judgment or allegation of patent
239+infringement or for any other reason (not limited to patent issues),
240+conditions are imposed on you (whether by court order, agreement or
241+otherwise) that contradict the conditions of this License, they do not
242+excuse you from the conditions of this License. If you cannot
243+distribute so as to satisfy simultaneously your obligations under this
244+License and any other pertinent obligations, then as a consequence you
245+may not distribute the Program at all. For example, if a patent
246+license would not permit royalty-free redistribution of the Program by
247+all those who receive copies directly or indirectly through you, then
248+the only way you could satisfy both it and this License would be to
249+refrain entirely from distribution of the Program.
250+
251+If any portion of this section is held invalid or unenforceable under
252+any particular circumstance, the balance of the section is intended to
253+apply and the section as a whole is intended to apply in other
254+circumstances.
255+
256+It is not the purpose of this section to induce you to infringe any
257+patents or other property right claims or to contest validity of any
258+such claims; this section has the sole purpose of protecting the
259+integrity of the free software distribution system, which is
260+implemented by public license practices. Many people have made
261+generous contributions to the wide range of software distributed
262+through that system in reliance on consistent application of that
263+system; it is up to the author/donor to decide if he or she is willing
264+to distribute software through any other system and a licensee cannot
265+impose that choice.
266+
267+This section is intended to make thoroughly clear what is believed to
268+be a consequence of the rest of this License.
269+
270
271+ 8. If the distribution and/or use of the Program is restricted in
272+certain countries either by patents or by copyrighted interfaces, the
273+original copyright holder who places the Program under this License
274+may add an explicit geographical distribution limitation excluding
275+those countries, so that distribution is permitted only in or among
276+countries not thus excluded. In such case, this License incorporates
277+the limitation as if written in the body of this License.
278+
279+ 9. The Free Software Foundation may publish revised and/or new versions
280+of the General Public License from time to time. Such new versions will
281+be similar in spirit to the present version, but may differ in detail to
282+address new problems or concerns.
283+
284+Each version is given a distinguishing version number. If the Program
285+specifies a version number of this License which applies to it and "any
286+later version", you have the option of following the terms and conditions
287+either of that version or of any later version published by the Free
288+Software Foundation. If the Program does not specify a version number of
289+this License, you may choose any version ever published by the Free Software
290+Foundation.
291+
292+ 10. If you wish to incorporate parts of the Program into other free
293+programs whose distribution conditions are different, write to the author
294+to ask for permission. For software which is copyrighted by the Free
295+Software Foundation, write to the Free Software Foundation; we sometimes
296+make exceptions for this. Our decision will be guided by the two goals
297+of preserving the free status of all derivatives of our free software and
298+of promoting the sharing and reuse of software generally.
299+
300+ NO WARRANTY
301+
302+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
303+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
304+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
305+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
306+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
307+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
308+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
309+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
310+REPAIR OR CORRECTION.
311+
312+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
313+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
314+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
315+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
316+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
317+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
318+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
319+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
320+POSSIBILITY OF SUCH DAMAGES.
321+
322+ END OF TERMS AND CONDITIONS
323+
324
325+ How to Apply These Terms to Your New Programs
326+
327+ If you develop a new program, and you want it to be of the greatest
328+possible use to the public, the best way to achieve this is to make it
329+free software which everyone can redistribute and change under these terms.
330+
331+ To do so, attach the following notices to the program. It is safest
332+to attach them to the start of each source file to most effectively
333+convey the exclusion of warranty; and each file should have at least
334+the "copyright" line and a pointer to where the full notice is found.
335+
336+ <one line to give the program's name and a brief idea of what it does.>
337+ Copyright (C) <year> <name of author>
338+
339+ This program is free software; you can redistribute it and/or modify
340+ it under the terms of the GNU General Public License as published by
341+ the Free Software Foundation; either version 2 of the License, or
342+ (at your option) any later version.
343+
344+ This program is distributed in the hope that it will be useful,
345+ but WITHOUT ANY WARRANTY; without even the implied warranty of
346+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
347+ GNU General Public License for more details.
348+
349+ You should have received a copy of the GNU General Public License
350+ along with this program; if not, write to the Free Software
351+ Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
352+
353+
354+Also add information on how to contact you by electronic and paper mail.
355+
356+If the program is interactive, make it output a short notice like this
357+when it starts in an interactive mode:
358+
359+ Gnomovision version 69, Copyright (C) year name of author
360+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
361+ This is free software, and you are welcome to redistribute it
362+ under certain conditions; type `show c' for details.
363+
364+The hypothetical commands `show w' and `show c' should show the appropriate
365+parts of the General Public License. Of course, the commands you use may
366+be called something other than `show w' and `show c'; they could even be
367+mouse-clicks or menu items--whatever suits your program.
368+
369+You should also get your employer (if you work as a programmer) or your
370+school, if any, to sign a "copyright disclaimer" for the program, if
371+necessary. Here is a sample; alter the names:
372+
373+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
374+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
375+
376+ <signature of Ty Coon>, 1 April 1989
377+ Ty Coon, President of Vice
378+
379+This General Public License does not permit incorporating your program into
380+proprietary programs. If your program is a subroutine library, you may
381+consider it more useful to permit linking proprietary applications with the
382+library. If this is what you want to do, use the GNU Library General
383+Public License instead of this License.
384
385=== added directory 'plugins/MeteorShowers/resources'
386=== added file 'plugins/MeteorShowers/resources/MeteorShower.qrc'
387--- plugins/MeteorShowers/resources/MeteorShower.qrc 1970-01-01 00:00:00 +0000
388+++ plugins/MeteorShowers/resources/MeteorShower.qrc 2014-03-10 17:28:07 +0000
389@@ -0,0 +1,9 @@
390+<RCC>
391+ <qresource prefix="/MeteorShowers">
392+ <file>showers.json</file>
393+ <file>radiant.png</file>
394+ <file>btMS-off.png</file>
395+ <file>btMS-on.png</file>
396+ <file>radiantSetting.png</file>
397+ </qresource>
398+</RCC>
399
400=== added file 'plugins/MeteorShowers/resources/btMS-off.png'
401Binary 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
402=== added file 'plugins/MeteorShowers/resources/btMS-on.png'
403Binary 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
404=== added file 'plugins/MeteorShowers/resources/radiant.png'
405Binary 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
406=== added file 'plugins/MeteorShowers/resources/radiantSetting.png'
407Binary 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
408=== added file 'plugins/MeteorShowers/resources/showers.json'
409--- plugins/MeteorShowers/resources/showers.json 1970-01-01 00:00:00 +0000
410+++ plugins/MeteorShowers/resources/showers.json 2014-03-10 17:28:07 +0000
411@@ -0,0 +1,976 @@
412+{
413+ "shortName": "meteor showers data",
414+ "version": 1,
415+ "showers":
416+ {
417+ "QUA":
418+ {
419+ "designation": "Quadrantids",
420+ "activity":
421+ [
422+ {
423+ "year": "generic",
424+ "zhr": -1,
425+ "variable": "60-200",
426+ "start": "12.28",
427+ "finish": "01.12",
428+ "peak": "01.04"
429+ },
430+ {
431+ "year": "2008",
432+ "zhr": 120
433+ },
434+ {
435+ "year": "2009",
436+ "start": "01.01",
437+ "finish": "01.05",
438+ "peak": "01.03",
439+ "zhr": 120
440+ },
441+ {
442+ "year": "2011",
443+ "zhr": 120
444+ },
445+ {
446+ "year": "2012",
447+ "zhr": 120
448+ }
449+ ],
450+ "speed": 41,
451+ "radiantAlpha": "230",
452+ "radiantDelta": "49",
453+ "driftAlpha": "3",
454+ "driftDelta": "-1",
455+ "parentObj": "Asteroid 2003 EH1",
456+ "pidx": 2.1
457+ },
458+ "ACE":
459+ {
460+ "designation": "α-Centaurids",
461+ "activity":
462+ [
463+ {
464+ "year": "generic",
465+ "zhr": -1,
466+ "variable": "5-20",
467+ "start": "01.28",
468+ "finish": "02.21",
469+ "peak": "02.08"
470+ },
471+ {
472+ "year": "2008",
473+ "zhr": 5
474+ },
475+ {
476+ "year": "2010",
477+ "zhr": 6
478+ },
479+ {
480+ "year": "2011",
481+ "zhr": 6
482+ }
483+ ],
484+ "speed": 56,
485+ "radiantAlpha": "210",
486+ "radiantDelta": "-59",
487+ "driftAlpha": "6.25",
488+ "driftDelta": "-1.5",
489+ "pidx": 2.0
490+ },
491+ "GNO":
492+ {
493+ "designation": "γ-Normids",
494+ "activity":
495+ [
496+ {
497+ "year": "generic",
498+ "zhr": 6,
499+ "start": "02.25",
500+ "finish": "03.22",
501+ "peak": "03.15"
502+ },
503+ {
504+ "year": "2008",
505+ "zhr": 4
506+ },
507+ {
508+ "year": "2010",
509+ "zhr": 6
510+ },
511+ {
512+ "year": "2011",
513+ "zhr": 6
514+ }
515+ ],
516+ "speed": 56,
517+ "radiantAlpha": "239",
518+ "radiantDelta": "-50",
519+ "driftAlpha": "5",
520+ "driftDelta": "-0.3",
521+ "pidx": 2.4
522+ },
523+ "ETA":
524+ {
525+ "designation": "η-Aquariids",
526+ "activity":
527+ [
528+ {
529+ "year": "generic",
530+ "zhr": -1,
531+ "variable": "40-85",
532+ "start": "04.19",
533+ "finish": "05.28",
534+ "peak": "05.06"
535+ },
536+ {
537+ "year": "2008",
538+ "zhr": 70
539+ },
540+ {
541+ "year": "2009",
542+ "zhr": 85
543+ },
544+ {
545+ "year": "2011",
546+ "zhr": 70
547+ }
548+ ],
549+ "speed": 66,
550+ "radiantAlpha": "338",
551+ "radiantDelta": "-1",
552+ "driftAlpha": "5",
553+ "driftDelta": "2",
554+ "parentObj": "Comet 1P/Halley",
555+ "pidx": 2.4
556+ },
557+ "PAU":
558+ {
559+ "designation": "Piscis Austrinids",
560+ "activity":
561+ [
562+ {
563+ "year": "generic",
564+ "zhr": 5,
565+ "start": "06.15",
566+ "finish": "08.10",
567+ "peak": "07.28"
568+ },
569+ {
570+ "year": "2008",
571+ "zhr": 5
572+ },
573+ {
574+ "year": "2009",
575+ "zhr": 5
576+ }
577+ ],
578+ "speed": 35,
579+ "radiantAlpha": "341",
580+ "radiantDelta": "-30",
581+ "driftAlpha": "4",
582+ "driftDelta": "1",
583+ "pidx": 3.2
584+ },
585+ "LYR":
586+ {
587+ "designation": "Lyrids",
588+ "activity":
589+ [
590+ {
591+ "year": "generic",
592+ "zhr": -1,
593+ "variable": "0-90",
594+ "start": "04.16",
595+ "finish": "04.25",
596+ "peak": "04.22"
597+ },
598+ {
599+ "year": "1922",
600+ "zhr": 96
601+ },
602+ {
603+ "year": "1945",
604+ "zhr": 112
605+ },
606+ {
607+ "year": "1982",
608+ "zhr": 100
609+ },
610+ {
611+ "year": "2007",
612+ "zhr": 18
613+ },
614+ {
615+ "year": "2008",
616+ "zhr": 18
617+ },
618+ {
619+ "year": "2010",
620+ "zhr": 18
621+ },
622+ {
623+ "year": "2011",
624+ "zhr": 20
625+ },
626+ {
627+ "year": "2012",
628+ "zhr": 18
629+ }
630+ ],
631+ "speed": 49,
632+ "radiantAlpha": "271",
633+ "radiantDelta": "34",
634+ "driftAlpha": "3",
635+ "driftDelta": "0",
636+ "parentObj": "Comet Thatcher (1861 I)",
637+ "pidx": 2.1
638+ },
639+ "JBO":
640+ {
641+ "designation": "June Bootids",
642+ "activity":
643+ [
644+ {
645+ "year": "generic",
646+ "zhr": -1,
647+ "variable": "0-100",
648+ "start": "06.22",
649+ "finish": "07.02",
650+ "peak": "06.27"
651+ }
652+ ],
653+ "speed": 18,
654+ "radiantAlpha": "224",
655+ "radiantDelta": "48",
656+ "driftAlpha": "2",
657+ "driftDelta": "-1",
658+ "parentObj": "Comet 7P/Pons-Winnecke",
659+ "pidx": 2.2
660+ },
661+ "SDA":
662+ {
663+ "designation": "Southern δ-Aquariids",
664+ "activity":
665+ [
666+ {
667+ "year": "generic",
668+ "zhr": 16,
669+ "start": "07.12",
670+ "finish": "08.23",
671+ "peak": "07.30"
672+ },
673+ {
674+ "year": "2007",
675+ "zhr": 20,
676+ "start": "07.12",
677+ "finish": "08.19",
678+ "peak": "07.28"
679+ },
680+ {
681+ "year": "2008",
682+ "zhr": 20,
683+ "start": "07.12",
684+ "finish": "08.19",
685+ "peak": "07.27"
686+ },
687+ {
688+ "year": "2009",
689+ "zhr": 20,
690+ "start": "07.12",
691+ "finish": "08.19",
692+ "peak": "07.28"
693+ }
694+ ],
695+ "speed": 41,
696+ "radiantAlpha": "339",
697+ "radiantDelta": "-16",
698+ "driftAlpha": "4",
699+ "driftDelta": "0.5",
700+ "parentObj": "Comet 96P/Machholz",
701+ "pidx": 3.2
702+ },
703+ "CAP":
704+ {
705+ "designation": "α-Capricornids",
706+ "activity":
707+ [
708+ {
709+ "year": "generic",
710+ "zhr": 5,
711+ "start": "07.03",
712+ "finish": "08.15",
713+ "peak": "07.30"
714+ },
715+ {
716+ "year": "2007",
717+ "zhr": 4
718+ },
719+ {
720+ "year": "2008",
721+ "zhr": 4
722+ },
723+ {
724+ "year": "2009",
725+ "zhr": 4
726+ }
727+ ],
728+ "speed": 23,
729+ "radiantAlpha": "307",
730+ "radiantDelta": "-10",
731+ "driftAlpha": "5",
732+ "driftDelta": "1",
733+ "pidx": 2.5
734+ },
735+ "AUR":
736+ {
737+ "designation": "α-Aurigids",
738+ "activity":
739+ [
740+ {
741+ "year": "generic",
742+ "zhr": 6,
743+ "start": "08.28",
744+ "finish": "09.05",
745+ "peak": "09.01"
746+ },
747+ {
748+ "year": "2009",
749+ "zhr": 7
750+ }
751+ ],
752+ "speed": 66,
753+ "radiantAlpha": "91",
754+ "radiantDelta": "+39",
755+ "driftAlpha": "5",
756+ "driftDelta": "0.7",
757+ "pidx": 2.6
758+ },
759+ "SPE":
760+ {
761+ "designation": "September ε-Perseids",
762+ "activity":
763+ [
764+ {
765+ "year": "generic",
766+ "zhr": 5,
767+ "start": "09.04",
768+ "finish": "09.14",
769+ "peak": "09.09"
770+ }
771+ ],
772+ "speed": 64,
773+ "radiantAlpha": "47",
774+ "radiantDelta": "+40",
775+ "driftAlpha": "5",
776+ "driftDelta": "0.1",
777+ "pidx": 3.0
778+ },
779+ "DRA":
780+ {
781+ "designation": "Draconids",
782+ "activity":
783+ [
784+ {
785+ "year": "generic",
786+ "zhr": -1,
787+ "variable": "20-700",
788+ "start": "10.06",
789+ "finish": "10.10",
790+ "peak": "10.08"
791+ },
792+ {
793+ "year": "1933",
794+ "zhr": 6000
795+ },
796+ {
797+ "year": "1946",
798+ "zhr": 6800
799+ }
800+ ],
801+ "speed": 20,
802+ "radiantAlpha": "262",
803+ "radiantDelta": "+54",
804+ "driftAlpha": "0",
805+ "driftDelta": "0",
806+ "parentObj": "Comet 21P/Giacobini-Zinner",
807+ "pidx": 2.6
808+ },
809+ "LEO":
810+ {
811+ "designation": "Leonids",
812+ "activity":
813+ [
814+ {
815+ "year": "generic",
816+ "zhr": -1,
817+ "variable": "5-20*",
818+ "start": "11.06",
819+ "finish": "11.30",
820+ "peak": "11.18"
821+ },
822+ {
823+ "year": "1833",
824+ "zhr": 240000
825+ },
826+ {
827+ "year": "1866",
828+ "zhr": 5000
829+ },
830+ {
831+ "year": "1867",
832+ "zhr": 1000
833+ },
834+ {
835+ "year": "1868",
836+ "zhr": 1000
837+ },
838+ {
839+ "year": "1898",
840+ "zhr": 100
841+ },
842+ {
843+ "year": "1901",
844+ "zhr": 400
845+ },
846+ {
847+ "year": "1966",
848+ "zhr": 144000
849+ },
850+ {
851+ "year": "1998",
852+ "zhr": 2000
853+ },
854+ {
855+ "year": "1999",
856+ "zhr": 5000
857+ },
858+ {
859+ "year": "2000",
860+ "zhr": 480
861+ },
862+ {
863+ "year": "2001",
864+ "zhr": 3700
865+ },
866+ {
867+ "year": "2002",
868+ "zhr": 3000
869+ },
870+ {
871+ "year": "2006",
872+ "zhr": 78
873+ },
874+ {
875+ "year": "2007",
876+ "zhr": 35
877+ },
878+ {
879+ "year": "2008",
880+ "start": "11.14",
881+ "finish": "11.22",
882+ "peak": "11.17",
883+ "zhr": 99
884+ },
885+ {
886+ "year": "2009",
887+ "start": "11.10",
888+ "finish": "11.21",
889+ "peak": "11.17",
890+ "zhr": 79
891+ },
892+ {
893+ "year": "2010",
894+ "start": "11.10",
895+ "finish": "11.23",
896+ "peak": "11.17",
897+ "zhr": 32
898+ },
899+ {
900+ "year": "2011",
901+ "zhr": 22
902+ },
903+ {
904+ "year": 2012,
905+ "start": "11.06",
906+ "finish": "11.30",
907+ "peak": "11.17",
908+ "zhr": 61
909+ }
910+ ],
911+ "speed": 71,
912+ "radiantAlpha": "152",
913+ "radiantDelta": "+22",
914+ "driftAlpha": "3",
915+ "driftDelta": "-1.25",
916+ "parentObj": "Comet 55P/Tempel-Tuttle",
917+ "pidx": 2.5
918+ },
919+ "PHO":
920+ {
921+ "designation": "Phoenicids",
922+ "activity":
923+ [
924+ {
925+ "year": "generic",
926+ "zhr": -1,
927+ "variable": "0-100",
928+ "start": "11.28",
929+ "finish": "12.09",
930+ "peak": "12.06"
931+ }
932+ ],
933+ "speed": 18,
934+ "radiantAlpha": "18",
935+ "radiantDelta": "-53",
936+ "driftAlpha": "4",
937+ "driftDelta": "-0.5",
938+ "pidx": 2.8
939+ },
940+ "PUP":
941+ {
942+ "designation": "Puppid-Velids",
943+ "activity":
944+ [
945+ {
946+ "year": "generic",
947+ "zhr": 10,
948+ "start": "12.01",
949+ "finish": "12.15",
950+ "peak": "12.07"
951+ }
952+ ],
953+ "speed": 40,
954+ "radiantAlpha": "123",
955+ "radiantDelta": "-45",
956+ "driftAlpha": "3",
957+ "driftDelta": "0",
958+ "pidx": 2.9
959+ },
960+ "URS":
961+ {
962+ "designation": "Ursids",
963+ "activity":
964+ [
965+ {
966+ "year": "generic",
967+ "zhr": -1,
968+ "variable": "10-50",
969+ "start": "12.17",
970+ "finish": "12.26",
971+ "peak": "12.23"
972+ }
973+ ],
974+ "speed": 33,
975+ "radiantAlpha": "217",
976+ "radiantDelta": "+76",
977+ "driftAlpha": "0",
978+ "driftDelta": "-2",
979+ "pidx": 3.0
980+ },
981+ "PER":
982+ {
983+ "designation": "Perseids",
984+ "activity":
985+ [
986+ {
987+ "year": "generic",
988+ "zhr": 100,
989+ "start": "07.17",
990+ "finish": "08.24",
991+ "peak": "08.13"
992+ },
993+ {
994+ "year": "1863",
995+ "zhr": 215
996+ },
997+ {
998+ "year": "2004",
999+ "zhr": 200
1000+ },
1001+ {
1002+ "year": "2007",
1003+ "zhr": 93
1004+ },
1005+ {
1006+ "year": "2008",
1007+ "zhr": 116
1008+ },
1009+ {
1010+ "year": "2009",
1011+ "zhr": 173
1012+ },
1013+ {
1014+ "year": "2010",
1015+ "zhr": 142
1016+ },
1017+ {
1018+ "year": "2011",
1019+ "zhr": 100
1020+ },
1021+ {
1022+ "year": "2012",
1023+ "zhr": 100
1024+ }
1025+ ],
1026+ "speed": 59,
1027+ "radiantAlpha": "48",
1028+ "radiantDelta": "+58",
1029+ "driftAlpha": "6",
1030+ "driftDelta": "1",
1031+ "parentObj": "Comet 109P/Swift-Tuttle",
1032+ "pidx": 2.2
1033+ },
1034+ "DLE":
1035+ {
1036+ "designation": "δ-Leonids",
1037+ "activity":
1038+ [
1039+ {
1040+ "year": "generic",
1041+ "zhr": 2,
1042+ "start": "02.15",
1043+ "finish": "03.10",
1044+ "peak": "02.24"
1045+ }
1046+ ],
1047+ "speed": 23,
1048+ "radiantAlpha": "168",
1049+ "radiantDelta": "+16",
1050+ "driftAlpha": "0",
1051+ "driftDelta": "0",
1052+ "parentObj": "Asteroid (4450) Pan",
1053+ "pidx": 3.0
1054+ },
1055+ "PPU":
1056+ {
1057+ "designation": "π-Puppids",
1058+ "activity":
1059+ [
1060+ {
1061+ "year": "generic",
1062+ "zhr": -1,
1063+ "variable": "0-40",
1064+ "start": "04.15",
1065+ "finish": "04.28",
1066+ "peak": "04.24"
1067+ }
1068+ ],
1069+ "speed": 18,
1070+ "radiantAlpha": "110",
1071+ "radiantDelta": "-45",
1072+ "driftAlpha": "2.5",
1073+ "driftDelta": "-0.5",
1074+ "parentObj": "Comet 26P/Grigg-Skjellerup",
1075+ "pidx": 2.0
1076+ },
1077+ "JLY":
1078+ {
1079+ "designation": "June Lyrids",
1080+ "activity":
1081+ [
1082+ {
1083+ "year": "generic",
1084+ "zhr": -1,
1085+ "variable": "0-5",
1086+ "start": "06.11",
1087+ "finish": "06.21",
1088+ "peak": "06.16"
1089+ }
1090+ ],
1091+ "speed": 31,
1092+ "radiantAlpha": "277",
1093+ "radiantDelta": "+35",
1094+ "driftAlpha": "4",
1095+ "driftDelta": "0",
1096+ "pidx": 3.0
1097+ },
1098+ "KCG":
1099+ {
1100+ "designation": "κ-Cygnids",
1101+ "activity":
1102+ [
1103+ {
1104+ "year": "generic",
1105+ "zhr": 3,
1106+ "start": "08.03",
1107+ "finish": "08.25",
1108+ "peak": "08.18"
1109+ }
1110+ ],
1111+ "speed": 25,
1112+ "radiantAlpha": "286",
1113+ "radiantDelta": "+59",
1114+ "driftAlpha": "1",
1115+ "driftDelta": "0.5",
1116+ "pidx": 3.0
1117+ },
1118+ "ELY":
1119+ {
1120+ "designation": "ε-Lyrids",
1121+ "activity":
1122+ [
1123+ {
1124+ "year": "generic",
1125+ "zhr": 3,
1126+ "start": "03.03",
1127+ "finish": "03.12",
1128+ "peak": "03.08"
1129+ }
1130+ ],
1131+ "speed": 44,
1132+ "radiantAlpha": "287",
1133+ "radiantDelta": "+44",
1134+ "driftAlpha": "5",
1135+ "driftDelta": "0.5",
1136+ "pidx": 3.0
1137+ },
1138+ "DAU":
1139+ {
1140+ "designation": "δ-Aurigids",
1141+ "activity":
1142+ [
1143+ {
1144+ "year": "generic",
1145+ "zhr": 3,
1146+ "start": "09.18",
1147+ "finish": "10.10",
1148+ "peak": "09.28"
1149+ }
1150+ ],
1151+ "speed": 64,
1152+ "radiantAlpha": "82",
1153+ "radiantDelta": "+49",
1154+ "driftAlpha": "5",
1155+ "driftDelta": "-2",
1156+ "pidx": 2.9
1157+ },
1158+ "EGE":
1159+ {
1160+ "designation": "ε-Geminids",
1161+ "activity":
1162+ [
1163+ {
1164+ "year": "generic",
1165+ "zhr": 3,
1166+ "start": "10.14",
1167+ "finish": "10.27",
1168+ "peak": "10.18"
1169+ }
1170+ ],
1171+ "speed": 70,
1172+ "radiantAlpha": "102",
1173+ "radiantDelta": "+27",
1174+ "driftAlpha": "5",
1175+ "driftDelta": "0",
1176+ "pidx": 3.0
1177+ },
1178+ "STA":
1179+ {
1180+ "designation": "Southern Taurids",
1181+ "activity":
1182+ [
1183+ {
1184+ "year": "generic",
1185+ "zhr": 5,
1186+ "start": "09.25",
1187+ "finish": "11.25",
1188+ "peak": "11.05"
1189+ }
1190+ ],
1191+ "speed": 27,
1192+ "radiantAlpha": "52",
1193+ "radiantDelta": "+15",
1194+ "driftAlpha": "3",
1195+ "driftDelta": "1",
1196+ "pidx": 2.3
1197+ },
1198+ "NTA":
1199+ {
1200+ "designation": "Northern Taurids",
1201+ "activity":
1202+ [
1203+ {
1204+ "year": "generic",
1205+ "zhr": 5,
1206+ "start": "09.25",
1207+ "finish": "11.25",
1208+ "peak": "11.12"
1209+ }
1210+ ],
1211+ "speed": 29,
1212+ "radiantAlpha": "58",
1213+ "radiantDelta": "+22",
1214+ "driftAlpha": "5",
1215+ "driftDelta": "1",
1216+ "pidx": 2.3
1217+ },
1218+ "MON":
1219+ {
1220+ "designation": "Monocerotids",
1221+ "activity":
1222+ [
1223+ {
1224+ "year": "generic",
1225+ "zhr": 2,
1226+ "start": "11.27",
1227+ "finish": "12.17",
1228+ "peak": "12.09"
1229+ }
1230+ ],
1231+ "speed": 42,
1232+ "radiantAlpha": "100",
1233+ "radiantDelta": "+8",
1234+ "driftAlpha": "4",
1235+ "driftDelta": "0",
1236+ "pidx": 3.0
1237+ },
1238+ "HYD":
1239+ {
1240+ "designation": "σ-Hydrids",
1241+ "activity":
1242+ [
1243+ {
1244+ "year": "generic",
1245+ "zhr": 3,
1246+ "start": "12.03",
1247+ "finish": "12.15",
1248+ "peak": "12.12"
1249+ }
1250+ ],
1251+ "speed": 58,
1252+ "radiantAlpha": "127",
1253+ "radiantDelta": "+2",
1254+ "driftAlpha": "4",
1255+ "driftDelta": "-1",
1256+ "pidx": 3.0
1257+ },
1258+ "GEM":
1259+ {
1260+ "designation": "Geminids",
1261+ "activity":
1262+ [
1263+ {
1264+ "year": "generic",
1265+ "zhr": 120,
1266+ "start": "12.07",
1267+ "finish": "12.17",
1268+ "peak": "12.14"
1269+ },
1270+ {
1271+ "year": "2006",
1272+ "zhr": 115
1273+ },
1274+ {
1275+ "year": "2007",
1276+ "zhr": 122
1277+ },
1278+ {
1279+ "year": "2008",
1280+ "zhr": 139
1281+ },
1282+ {
1283+ "year": "2009",
1284+ "zhr": 120
1285+ },
1286+ {
1287+ "year": "2010",
1288+ "zhr": 127
1289+ },
1290+ {
1291+ "year": "2011",
1292+ "zhr": 198
1293+ },
1294+ {
1295+ "year": "2012",
1296+ "zhr": 109
1297+ }
1298+ ],
1299+ "speed": 35,
1300+ "radiantAlpha": "112",
1301+ "radiantDelta": "+33",
1302+ "driftAlpha": "5",
1303+ "driftDelta": "-0.1",
1304+ "pidx": 2.6
1305+ },
1306+ "LMI":
1307+ {
1308+ "designation": "Leonis Minorids",
1309+ "activity":
1310+ [
1311+ {
1312+ "year": "generic",
1313+ "zhr": 2,
1314+ "start": "10.19",
1315+ "finish": "10.27",
1316+ "peak": "10.24"
1317+ }
1318+ ],
1319+ "speed": 62,
1320+ "radiantAlpha": "162",
1321+ "radiantDelta": "+37",
1322+ "driftAlpha": "5",
1323+ "driftDelta": "-2",
1324+ "pidx": 3.0
1325+ },
1326+ "DLM":
1327+ {
1328+ "designation": "December Leonis Minorids",
1329+ "activity":
1330+ [
1331+ {
1332+ "year": "generic",
1333+ "zhr": 5,
1334+ "start": "12.05",
1335+ "finish": "02.04",
1336+ "peak": "12.20"
1337+ }
1338+ ],
1339+ "speed": 64,
1340+ "radiantAlpha": "161",
1341+ "radiantDelta": "+30",
1342+ "driftAlpha": "5",
1343+ "driftDelta": "-2",
1344+ "pidx": 3.0
1345+ },
1346+ "COM":
1347+ {
1348+ "designation": "Comae Berenicids",
1349+ "activity":
1350+ [
1351+ {
1352+ "year": "generic",
1353+ "zhr": 3,
1354+ "start": "12.12",
1355+ "finish": "12.23",
1356+ "peak": "12.16"
1357+ }
1358+ ],
1359+ "speed": 65,
1360+ "radiantAlpha": "175",
1361+ "radiantDelta": "+18",
1362+ "driftAlpha": "2.5",
1363+ "driftDelta": "-1.5",
1364+ "pidx": 3.0
1365+ },
1366+ "ORI":
1367+ {
1368+ "designation": "Orionids",
1369+ "activity":
1370+ [
1371+ {
1372+ "year": "generic",
1373+ "zhr": 25,
1374+ "start": "10.02",
1375+ "finish": "11.07",
1376+ "peak": "10.21"
1377+ }
1378+ ],
1379+ "speed": 66,
1380+ "radiantAlpha": "95",
1381+ "radiantDelta": "+16",
1382+ "driftAlpha": "3",
1383+ "driftDelta": "0.5",
1384+ "pidx": 2.5
1385+ }
1386+ }
1387+}
1388
1389=== added directory 'plugins/MeteorShowers/src'
1390=== added file 'plugins/MeteorShowers/src/CMakeLists.txt'
1391--- plugins/MeteorShowers/src/CMakeLists.txt 1970-01-01 00:00:00 +0000
1392+++ plugins/MeteorShowers/src/CMakeLists.txt 2014-03-10 17:28:07 +0000
1393@@ -0,0 +1,37 @@
1394+INCLUDE_DIRECTORIES(
1395+ .
1396+ gui
1397+ ${CMAKE_BINARY_DIR}/plugins/MeteorShowers/src
1398+ ${CMAKE_BINARY_DIR}/plugins/MeteorShowers/src/gui
1399+)
1400+
1401+LINK_DIRECTORIES(${BUILD_DIR}/src)
1402+
1403+SET(MeteorShowers_SRCS
1404+ MeteorShower.hpp
1405+ MeteorShower.cpp
1406+ MeteorShowers.hpp
1407+ MeteorShowers.cpp
1408+ MeteorStream.hpp
1409+ MeteorStream.cpp
1410+ gui/MeteorShowerDialog.hpp
1411+ gui/MeteorShowerDialog.cpp
1412+)
1413+
1414+SET(MeteorShowersDialog_UIS
1415+ gui/meteorShowerDialog.ui
1416+)
1417+
1418+QT5_WRAP_UI(MeteorShowersDialog_UIS_H ${MeteorShowersDialog_UIS})
1419+
1420+SET(MeteorShowers_RES ../resources/MeteorShower.qrc)
1421+QT5_ADD_RESOURCES(MeteorShowers_RES_CXX ${MeteorShowers_RES})
1422+
1423+SET(extLinkerOption ${QT_LIBRARIES} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${OPENGL_LIBRARIES} ${ICONV_LIBRARIES} ${INTL_LIBRARIES})
1424+
1425+ADD_LIBRARY(MeteorShowers-static STATIC ${MeteorShowers_SRCS} ${MeteorShowers_MOC_SRCS} ${MeteorShowers_RES_CXX} ${MeteorShowersDialog_UIS_H})
1426+QT5_USE_MODULES(MeteorShowers-static Core Declarative Network)
1427+SET_TARGET_PROPERTIES(MeteorShowers-static PROPERTIES OUTPUT_NAME "MeteorShowers")
1428+TARGET_LINK_LIBRARIES(MeteorShowers-static ${extLinkerOption})
1429+SET_TARGET_PROPERTIES(MeteorShowers-static PROPERTIES COMPILE_FLAGS "-DQT_STATICPLUGIN")
1430+ADD_DEPENDENCIES(AllStaticPlugins MeteorShowers-static)
1431
1432=== added file 'plugins/MeteorShowers/src/MeteorShower.cpp'
1433--- plugins/MeteorShowers/src/MeteorShower.cpp 1970-01-01 00:00:00 +0000
1434+++ plugins/MeteorShowers/src/MeteorShower.cpp 2014-03-10 17:28:07 +0000
1435@@ -0,0 +1,417 @@
1436+/*
1437+ * Copyright (C) 2013 Marcos Cardinot
1438+ * Copyright (C) 2011 Alexander Wolf
1439+ *
1440+ * This program is free software; you can redistribute it and/or
1441+ * modify it under the terms of the GNU General Public License
1442+ * as published by the Free Software Foundation; either version 2
1443+ * of the License, or (at your option) any later version.
1444+ *
1445+ * This program is distributed in the hope that it will be useful,
1446+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1447+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1448+ * GNU General Public License for more details.
1449+ *
1450+ * You should have received a copy of the GNU General Public License
1451+ * along with this program; if not, write to the Free Software
1452+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
1453+ */
1454+
1455+#include "MeteorShower.hpp"
1456+#include "MeteorShowers.hpp"
1457+#include "StelApp.hpp"
1458+#include "StelCore.hpp"
1459+#include "StelModuleMgr.hpp"
1460+#include "StelObject.hpp"
1461+#include "StelPainter.hpp"
1462+#include "StelTexture.hpp"
1463+#include "StelUtils.hpp"
1464+
1465+#include <QDebug>
1466+#include <QList>
1467+#include <QOpenGLFunctions>
1468+#include <QTextStream>
1469+#include <QVariant>
1470+#include <QVariantMap>
1471+
1472+StelTextureSP MeteorShower::radiantTexture;
1473+float MeteorShower::showLabels = true;
1474+bool MeteorShower::radiantMarkerEnabled = true;
1475+
1476+MeteorShower::MeteorShower(const QVariantMap& map)
1477+ : initialized(false)
1478+{
1479+ // return initialized if the mandatory fields are not present
1480+ if(!map.contains("showerID"))
1481+ return;
1482+
1483+ showerID = map.value("showerID").toString();
1484+ designation = map.value("designation").toString();
1485+ speed = map.value("speed").toInt();
1486+ rAlphaPeak = radiantAlpha = StelUtils::getDecAngle(map.value("radiantAlpha").toString());
1487+ rDeltaPeak = radiantDelta = StelUtils::getDecAngle(map.value("radiantDelta").toString());
1488+ driftAlpha = StelUtils::getDecAngle(map.value("driftAlpha").toString());
1489+ driftDelta = StelUtils::getDecAngle(map.value("driftDelta").toString());
1490+ parentObj = map.value("parentObj").toString();
1491+ pidx = map.value("pidx").toFloat();
1492+
1493+ if(map.contains("activity"))
1494+ {
1495+ foreach(const QVariant &ms, map.value("activity").toList())
1496+ {
1497+ QVariantMap activityMap = ms.toMap();
1498+ activityData d;
1499+ d.year = activityMap.value("year").toString();
1500+ d.zhr = activityMap.value("zhr").toInt();
1501+ d.variable = activityMap.value("variable").toString();
1502+ d.peak = activityMap.value("peak").toString();
1503+ d.start = activityMap.value("start").toString();
1504+ d.finish = activityMap.value("finish").toString();
1505+ activity.append(d);
1506+ }
1507+ }
1508+
1509+ updateCurrentData(getSkyQDateTime());
1510+
1511+ initialized = true;
1512+}
1513+
1514+MeteorShower::~MeteorShower()
1515+{
1516+ //
1517+}
1518+
1519+QVariantMap MeteorShower::getMap(void)
1520+{
1521+ QVariantMap map;
1522+ map["showerID"] = showerID;
1523+ map["designation"] = designation;
1524+ map["speed"] = speed;
1525+ map["radiantAlpha"] = rAlphaPeak;
1526+ map["radiantDelta"] = rDeltaPeak;
1527+ map["driftAlpha"] = driftAlpha;
1528+ map["driftDelta"] = driftDelta;
1529+ map["parentObj"] = parentObj;
1530+ map["pidx"] = pidx;
1531+
1532+ QVariantList activityList;
1533+ foreach(const activityData &p, activity)
1534+ {
1535+ QVariantMap activityMap;
1536+ activityMap["year"] = p.year;
1537+ activityMap["zhr"] = p.zhr;
1538+ activityMap["variable"] = p.variable;
1539+ activityMap["start"] = p.start;
1540+ activityMap["finish"] = p.finish;
1541+ activityMap["peak"] = p.peak;
1542+ activityList << activityMap;
1543+ }
1544+ map["activity"] = activityList;
1545+
1546+ return map;
1547+}
1548+
1549+float MeteorShower::getSelectPriority(const StelCore*) const
1550+{
1551+ return -2.0;
1552+}
1553+
1554+QString MeteorShower::getDesignation() const
1555+{
1556+ return designation;
1557+}
1558+
1559+QString MeteorShower::getDateFromJSON(QString jsondate) const
1560+{
1561+ QStringList parsedDate = jsondate.split(".");
1562+
1563+ return QString("%1 %2").arg(parsedDate.at(1).toInt()).arg(getMonthName(parsedDate.at(0).toInt()));
1564+}
1565+
1566+QString MeteorShower::getDayFromJSON(QString jsondate) const
1567+{
1568+ QStringList parsedDate = jsondate.split(".");
1569+
1570+ return QString("%1").arg(parsedDate.at(1).toInt());
1571+}
1572+
1573+int MeteorShower::getMonthFromJSON(QString jsondate) const
1574+{
1575+ QStringList parsedDate = jsondate.split(".");
1576+
1577+ return parsedDate.at(0).toInt();
1578+}
1579+
1580+QString MeteorShower::getMonthNameFromJSON(QString jsondate) const
1581+{
1582+ QStringList parsedDate = jsondate.split(".");
1583+
1584+ return QString("%1").arg(getMonthName(parsedDate.at(0).toInt()));
1585+}
1586+
1587+QString MeteorShower::getMonthName(int number) const
1588+{
1589+ QStringList monthList;
1590+ monthList.append(N_("January"));
1591+ monthList.append(N_("February"));
1592+ monthList.append(N_("March"));
1593+ monthList.append(N_("April"));
1594+ monthList.append(N_("May"));
1595+ monthList.append(N_("June"));
1596+ monthList.append(N_("July"));
1597+ monthList.append(N_("August"));
1598+ monthList.append(N_("September"));
1599+ monthList.append(N_("October"));
1600+ monthList.append(N_("November"));
1601+ monthList.append(N_("December"));
1602+
1603+ return q_(monthList.at(number-1));
1604+}
1605+
1606+QDateTime MeteorShower::getSkyQDateTime() const
1607+{
1608+ StelCore* core = StelApp::getInstance().getCore();
1609+ //get the current sky date
1610+ double JD = core->getJDay();
1611+ return StelUtils::jdToQDateTime(JD+StelUtils::getGMTShiftFromQT(JD)/24-core->getDeltaT(JD)/86400);
1612+}
1613+
1614+void MeteorShower::updateCurrentData(QDateTime skyDate)
1615+{
1616+ //Check if we have real data for the current sky year
1617+ int index = searchRealData(skyDate.toString("yyyy"));
1618+
1619+ /**************************
1620+ *ZHR info
1621+ **************************/
1622+ zhr = activity[index].zhr == 0 ? activity[0].zhr : activity[index].zhr;
1623+
1624+ if (zhr == -1)
1625+ variable = activity[index].variable.isEmpty() ? activity[0].variable : activity[index].variable;
1626+ else
1627+ variable = "";
1628+
1629+ /***************************
1630+ *Dates - start/finish/peak
1631+ ***************************/
1632+ QString dateStart = activity[index].start.isEmpty() ? activity[0].start : activity[index].start;
1633+ QString dateFinish = activity[index].finish.isEmpty() ? activity[0].finish : activity[index].finish;
1634+ QString datePeak = activity[index].peak.isEmpty() ? activity[0].peak : activity[index].peak;
1635+ QString yearBase = activity[index].year == "generic" ? skyDate.toString("yyyy") : activity[index].year;
1636+ QString yearS, yearF;
1637+
1638+ int monthStart = getMonthFromJSON(dateStart);
1639+ int monthFinish = getMonthFromJSON(dateFinish);
1640+
1641+ if(monthStart > monthFinish)
1642+ {
1643+ if(monthStart == skyDate.toString("MM").toInt())
1644+ {
1645+ yearS = yearBase;
1646+ yearF = QString("%1").arg(yearBase.toInt() + 1);
1647+ }
1648+ else
1649+ {
1650+ yearS = QString("%1").arg(yearBase.toInt() - 1);
1651+ yearF = yearBase;
1652+ }
1653+ }
1654+ else
1655+ {
1656+ yearS = yearF = yearBase;
1657+ }
1658+
1659+ start = QDateTime::fromString(dateStart + " " + yearS, "MM.dd yyyy");
1660+ finish = QDateTime::fromString(dateFinish + " " + yearF, "MM.dd yyyy");
1661+ peak = QDateTime::fromString(datePeak + " " + yearS, "MM.dd yyyy");
1662+
1663+ if (peak.operator <(start) || peak.operator >(finish))
1664+ peak = QDateTime::fromString(datePeak + " " + yearF, "MM.dd yyyy");
1665+
1666+ /***************************
1667+ *Activity - is active?
1668+ ***************************/
1669+ if(skyDate.operator >=(start) && skyDate.operator <=(finish))
1670+ {
1671+ if(index)
1672+ isActive = 1; // real data
1673+ else
1674+ isActive = 2; // generic data
1675+ }
1676+ else
1677+ {
1678+ isActive = 0; // isn't active
1679+ }
1680+
1681+ /**************************
1682+ *Radiant drift
1683+ *************************/
1684+ radiantAlpha = rAlphaPeak;
1685+ radiantDelta = rDeltaPeak;
1686+
1687+ if (isActive)
1688+ {
1689+ double time = (StelUtils::qDateTimeToJd(skyDate) - StelUtils::qDateTimeToJd(peak))*24;
1690+ radiantAlpha += (driftAlpha/120)*time;
1691+ radiantDelta += (driftDelta/120)*time;
1692+ }
1693+}
1694+
1695+int MeteorShower::searchRealData(QString yyyy) const
1696+{
1697+ int index = -1;
1698+ foreach(const activityData &p, activity)
1699+ {
1700+ index++;
1701+ if(p.year == yyyy)
1702+ return index;
1703+ }
1704+
1705+ return 0;
1706+}
1707+
1708+float MeteorShower::getSolarLongitude(QDateTime QDT) const
1709+{
1710+ //The number of days (positive or negative) since Greenwich noon,
1711+ //Terrestrial Time, on 1 January 2000 (J2000.0)
1712+ double n = StelUtils::qDateTimeToJd(QDT) - 2451545.0;
1713+
1714+ //The mean longitude of the Sun, corrected for the aberration of light
1715+ float slong = (280.460 + 0.9856474*n) / 360;
1716+ slong = (slong - (int) slong) * 360 - 1;
1717+
1718+ return slong;
1719+}
1720+
1721+QString MeteorShower::getInfoString(const StelCore* core, const InfoStringGroup& flags) const
1722+{
1723+ QString str;
1724+ QTextStream oss(&str);
1725+
1726+ QString mstdata = q_("generic data");
1727+ if(isActive == 1)
1728+ mstdata = q_("real data");
1729+
1730+ if(flags&Name)
1731+ oss << "<h2>" << getNameI18n() << " (" << showerID <<")</h2>";
1732+
1733+ if(flags&Extra)
1734+ oss << q_("Type: <b>%1</b> (%2)").arg(q_("meteor shower"), mstdata) << "<br />";
1735+
1736+ // Ra/Dec etc.
1737+ oss << getPositionInfoString(core, flags);
1738+
1739+ if(flags&Extra)
1740+ {
1741+ oss << QString("%1: %2/%3")
1742+ .arg(q_("Radiant drift (per day)"))
1743+ .arg(StelUtils::radToHmsStr(driftAlpha/5))
1744+ .arg(StelUtils::radToDmsStr(driftDelta/5));
1745+ oss << "<br />";
1746+
1747+ oss << q_("Geocentric meteoric velocity: %1 km/s").arg(speed) << "<br />";
1748+ if(pidx>0)
1749+ {
1750+ oss << q_("The population index: %1").arg(pidx) << "<br />";
1751+ }
1752+
1753+ if(!parentObj.isEmpty())
1754+ {
1755+ oss << q_("Parent body: %1").arg(parentObj) << "<br />";
1756+ }
1757+
1758+ if(start.toString("M") == finish.toString("M"))
1759+ {
1760+ oss << QString("%1: %2 - %3 %4")
1761+ .arg(q_("Active"))
1762+ .arg(start.toString("d"))
1763+ .arg(finish.toString("d"))
1764+ .arg(start.toString("MMMM"));
1765+ }
1766+ else
1767+ {
1768+ oss << QString("%1: %2 - %3")
1769+ .arg(q_("Active"))
1770+ .arg(start.toString("d MMMM"))
1771+ .arg(finish.toString("d MMMM"));
1772+ }
1773+ oss << "<br />";
1774+ oss << q_("Maximum: %1").arg(peak.toString("d MMMM"));
1775+
1776+ QString slong = QString::number( MeteorShower::getSolarLongitude(peak), 'f', 2 );
1777+ oss << QString(" (%1 %2&deg;)").arg(q_("Solar longitude is")).arg(slong);
1778+ oss << "<br />";
1779+
1780+ if(zhr>0)
1781+ {
1782+ oss << QString("ZHR<sub>max</sub>: %1").arg(zhr) << "<br />";
1783+ }
1784+ else
1785+ {
1786+ oss << QString("ZHR<sub>max</sub>: %1").arg(q_("variable"));
1787+ if(!variable.isEmpty())
1788+ {
1789+ oss << "; " << variable;
1790+ }
1791+ oss << "<br />";
1792+ }
1793+ }
1794+
1795+ postProcessInfoString(str, flags);
1796+
1797+ return str;
1798+}
1799+
1800+Vec3f MeteorShower::getInfoColor(void) const
1801+{
1802+ return StelApp::getInstance().getVisionModeNight() ? Vec3f(0.6, 0.0, 0.0) : Vec3f(1.0, 1.0, 1.0);
1803+}
1804+
1805+double MeteorShower::getAngularSize(const StelCore*) const
1806+{
1807+ return 0.001;
1808+}
1809+
1810+void MeteorShower::update(double deltaTime)
1811+{
1812+ labelsFader.update((int)(deltaTime*1000));
1813+ updateCurrentData(getSkyQDateTime());
1814+}
1815+
1816+void MeteorShower::draw(StelPainter& painter)
1817+{
1818+ StelUtils::spheToRect(radiantAlpha, radiantDelta, XYZ);
1819+ painter.getProjector()->project(XYZ, XY);
1820+
1821+ glEnable(GL_BLEND);
1822+ glBlendFunc(GL_SRC_ALPHA, GL_ONE);
1823+
1824+ qreal r, g, b;
1825+ float alpha = 0.85f + ((double) rand() / (RAND_MAX))/10;
1826+ switch(isActive)
1827+ {
1828+ case 1: //Active, real data
1829+ GETSTELMODULE(MeteorShowers)->getColorARR().getRgbF(&r,&g,&b);
1830+ break;
1831+ case 2: //Active, generic data
1832+ GETSTELMODULE(MeteorShowers)->getColorARG().getRgbF(&r,&g,&b);
1833+ break;
1834+ default: //Inactive
1835+ GETSTELMODULE(MeteorShowers)->getColorIR().getRgbF(&r,&g,&b);
1836+ }
1837+
1838+ painter.setColor(r, g, b, alpha);
1839+
1840+ if (MeteorShower::radiantMarkerEnabled)
1841+ {
1842+ MeteorShower::radiantTexture->bind();
1843+ painter.drawSprite2dMode(XY[0], XY[1], 10);
1844+
1845+ if (MeteorShower::showLabels)
1846+ {
1847+ float size = getAngularSize(NULL)*M_PI/180.*painter.getProjector()->getPixelPerRadAtCenter();
1848+ float shift = 8.f + size/1.8f;
1849+ painter.drawText(XY[0]+shift, XY[1]+shift, getNameI18n(), 0, 0, 0, false);
1850+ }
1851+ }
1852+}
1853
1854=== added file 'plugins/MeteorShowers/src/MeteorShower.hpp'
1855--- plugins/MeteorShowers/src/MeteorShower.hpp 1970-01-01 00:00:00 +0000
1856+++ plugins/MeteorShowers/src/MeteorShower.hpp 2014-03-10 17:28:07 +0000
1857@@ -0,0 +1,186 @@
1858+/*
1859+ * Copyright (C) 2013 Marcos Cardinot
1860+ * Copyright (C) 2011 Alexander Wolf
1861+ *
1862+ * This program is free software; you can redistribute it and/or
1863+ * modify it under the terms of the GNU General Public License
1864+ * as published by the Free Software Foundation; either version 2
1865+ * of the License, or (at your option) any later version.
1866+ *
1867+ * This program is distributed in the hope that it will be useful,
1868+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1869+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1870+ * GNU General Public License for more details.
1871+ *
1872+ * You should have received a copy of the GNU General Public License
1873+ * along with this program; if not, write to the Free Software
1874+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
1875+ */
1876+
1877+#ifndef _METEORSHOWER_HPP_
1878+#define _METEORSHOWER_HPP_
1879+
1880+#include <QDateTime>
1881+#include <QVariantMap>
1882+#include <QString>
1883+
1884+#include "StelFader.hpp"
1885+#include "StelObject.hpp"
1886+#include "StelPainter.hpp"
1887+#include "StelTextureTypes.hpp"
1888+#include "StelTranslator.hpp"
1889+
1890+class StelPainter;
1891+
1892+//! @class MeteorShower
1893+//! A MeteorShower object represents one meteor shower on the sky.
1894+//! Details about the meteor showers are passed using a QVariant which contains
1895+//! a map of data from the json file.
1896+
1897+class MeteorShower : public StelObject
1898+{
1899+ friend class MeteorShowers;
1900+
1901+public:
1902+ //! @param id The official ID designation for a meteor shower, e.g. "LYR"
1903+ MeteorShower(const QVariantMap& map);
1904+ ~MeteorShower();
1905+
1906+ //! Get a QVariantMap which describes the meteor shower. Could be used to
1907+ //! create a duplicate.
1908+ QVariantMap getMap(void);
1909+
1910+ virtual QString getType(void) const
1911+ {
1912+ return "MeteorShower";
1913+ }
1914+ virtual float getSelectPriority(const StelCore* core) const;
1915+
1916+ //! Get an HTML string to describe the object
1917+ //! @param core A pointer to the core
1918+ //! @flags a set of flags with information types to include.
1919+ virtual QString getInfoString(const StelCore* core, const InfoStringGroup& flags) const;
1920+ virtual Vec3f getInfoColor(void) const;
1921+ virtual Vec3d getJ2000EquatorialPos(const StelCore*) const
1922+ {
1923+ return XYZ;
1924+ }
1925+ virtual double getAngularSize(const StelCore* core) const;
1926+ virtual QString getNameI18n(void) const
1927+ {
1928+ return q_(designation);
1929+ }
1930+ virtual QString getEnglishName(void) const
1931+ {
1932+ return designation;
1933+ }
1934+ QString getDesignation(void) const;
1935+ void update(double deltaTime);
1936+ static float showLabels;
1937+
1938+ //! Get current activity status of MS
1939+ //! @return 0:inactive 1:activeRealData 2:activeGenericData
1940+ int getStatus()
1941+ {
1942+ return isActive;
1943+ }
1944+
1945+ //! Get peak
1946+ //! @return peak
1947+ QDateTime getPeak()
1948+ {
1949+ return peak;
1950+ }
1951+
1952+ //! Get zhr
1953+ //! @return ZHR
1954+ int getZHR()
1955+ {
1956+ return zhr;
1957+ }
1958+
1959+private:
1960+ Vec3d XYZ; //! Cartesian equatorial position
1961+ Vec3d XY; //! Store temporary 2D position
1962+
1963+ static StelTextureSP radiantTexture;
1964+ static bool radiantMarkerEnabled;
1965+
1966+ LinearFader labelsFader;
1967+
1968+ typedef struct
1969+ {
1970+ QString year; //! Value of year for actual data
1971+ int zhr; //! ZHR of shower
1972+ QString variable; //! value of variable for ZHR
1973+ QString start; //! First day for activity
1974+ QString finish; //! Latest day for activity
1975+ QString peak; //! Day with maximum for activity
1976+ } activityData;
1977+
1978+ bool initialized;
1979+ QString showerID; //! The ID of the meteor shower
1980+ QString designation; //! The designation of the meteor shower
1981+ QList<activityData> activity; //! List of activity
1982+ int speed; //! Speed of meteors
1983+ double rAlphaPeak; //! R.A. for radiant of meteor shower on the peak day
1984+ double rDeltaPeak; //! Dec. for radiant of meteor shower on the peak day
1985+ double driftAlpha; //! Drift of R.A.
1986+ double driftDelta; //! Drift of Dec.
1987+ QString parentObj; //! Parent object for meteor shower
1988+ float pidx; //! The population index
1989+
1990+ //current information
1991+ double radiantAlpha; //! Current R.A. for radiant of meteor shower
1992+ double radiantDelta; //! Current Dec. for radiant of meteor shower
1993+ int zhr; //! ZHR of shower
1994+ QString variable; //! value of variable for ZHR
1995+ QDateTime start; //! First day for activity
1996+ QDateTime finish; //! Latest day for activity
1997+ QDateTime peak; //! Day with maximum for activity
1998+
1999+ int isActive; //! Check if the radiant is active for the current sky date
2000+ //! 0=inactive; 1=realData 2=genericData
2001+
2002+ void draw(StelPainter &painter);
2003+
2004+ //! Get a date string from JSON file and parse it for display in info corner
2005+ //! @param jsondate A string from JSON file
2006+ QString getDateFromJSON(QString jsondate) const;
2007+
2008+ //! Get a day from JSON file and parse it for display in info corner
2009+ //! @param jsondate A string from JSON file
2010+ QString getDayFromJSON(QString jsondate) const;
2011+
2012+ //! Get a month string from JSON file and parse it for display in info corner
2013+ //! @param jsondate A string from JSON file
2014+ int getMonthFromJSON(QString jsondate) const;
2015+
2016+ //! Get a month string from JSON file and parse it for display in info corner
2017+ //! @param jsondate A string from JSON file
2018+ QString getMonthNameFromJSON(QString jsondate) const;
2019+
2020+ //! Get a month name from month number
2021+ //! @param jsondate A string from JSON file
2022+ QString getMonthName(int number) const;
2023+
2024+ //! Get the current sky QDateTime
2025+ //! @return Current QDateTime of sky
2026+ QDateTime getSkyQDateTime() const;
2027+
2028+ //! Update value of current information(zhr, variable, stat, finish and peak)
2029+ //! @param current sky QDateTime
2030+ void updateCurrentData(QDateTime skyDate);
2031+
2032+ //! Check if the JSON file has real data to a given year
2033+ //! @param yyyy year to check
2034+ //! @return index of the year or 0 to generic data
2035+ int searchRealData(QString yyyy) const;
2036+
2037+ //! Get the solar longitude for a specified date
2038+ //! @param QDT QDateTime
2039+ //! @return solar longitude in degree
2040+ float getSolarLongitude(QDateTime QDT) const;
2041+};
2042+
2043+#endif /*_METEORSHOWER_HPP_*/
2044
2045=== added file 'plugins/MeteorShowers/src/MeteorShowers.cpp'
2046--- plugins/MeteorShowers/src/MeteorShowers.cpp 1970-01-01 00:00:00 +0000
2047+++ plugins/MeteorShowers/src/MeteorShowers.cpp 2014-03-10 17:28:07 +0000
2048@@ -0,0 +1,1225 @@
2049+/*
2050+ * Copyright (C) 2013 Marcos Cardinot
2051+ * Copyright (C) 2011 Alexander Wolf
2052+ *
2053+ * This program is free software; you can redistribute it and/or
2054+ * modify it under the terms of the GNU General Public License
2055+ * as published by the Free Software Foundation; either version 2
2056+ * of the License, or (at your option) any later version.
2057+ *
2058+ * This program is distributed in the hope that it will be useful,
2059+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2060+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2061+ * GNU General Public License for more details.
2062+ *
2063+ * You should have received a copy of the GNU General Public License
2064+ * along with this program; if not, write to the Free Software
2065+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
2066+ */
2067+
2068+#include "StelProjector.hpp"
2069+#include "StelPainter.hpp"
2070+#include "StelApp.hpp"
2071+#include "StelCore.hpp"
2072+#include "StelGui.hpp"
2073+#include "StelGuiItems.hpp"
2074+#include "StelLocaleMgr.hpp"
2075+#include "StelObjectMgr.hpp"
2076+#include "StelModuleMgr.hpp"
2077+#include "StelTextureMgr.hpp"
2078+#include "StelJsonParser.hpp"
2079+#include "StelIniParser.hpp"
2080+#include "StelFileMgr.hpp"
2081+#include "LabelMgr.hpp"
2082+#include "LandscapeMgr.hpp"
2083+#include "StelTranslator.hpp"
2084+#include "StelUtils.hpp"
2085+#include "MeteorShower.hpp"
2086+#include "MeteorShowers.hpp"
2087+#include "MeteorShowerDialog.hpp"
2088+#include "MeteorStream.hpp"
2089+#include "StelProgressController.hpp"
2090+
2091+#include <QAction>
2092+#include <QColor>
2093+#include <QDebug>
2094+#include <QDir>
2095+#include <QFile>
2096+#include <QFileInfo>
2097+#include <QKeyEvent>
2098+#include <QList>
2099+#include <QNetworkAccessManager>
2100+#include <QNetworkReply>
2101+#include <QProgressBar>
2102+#include <QSharedPointer>
2103+#include <QStringList>
2104+#include <QTimer>
2105+#include <QVariant>
2106+#include <QVariantMap>
2107+
2108+#define CATALOG_FORMAT_VERSION 1 /* Version of format of catalog */
2109+
2110+/*
2111+ This method is the one called automatically by the StelModuleMgr just
2112+ after loading the dynamic library
2113+*/
2114+StelModule* MeteorShowersStelPluginInterface::getStelModule() const
2115+{
2116+ return new MeteorShowers();
2117+}
2118+
2119+StelPluginInfo MeteorShowersStelPluginInterface::getPluginInfo() const
2120+{
2121+ // Allow to load the resources when used as a static plugin
2122+ Q_INIT_RESOURCE(MeteorShower);
2123+
2124+ StelPluginInfo info;
2125+ info.id = "MeteorShowers";
2126+ info.displayedName = N_("Meteor Showers");
2127+ info.authors = "Marcos Cardinot";
2128+ info.contact = "mcardinot@gmail.com";
2129+ 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.");
2130+ info.version = METEORSHOWERS_PLUGIN_VERSION;
2131+ return info;
2132+}
2133+
2134+/*
2135+ Constructor
2136+*/
2137+MeteorShowers::MeteorShowers()
2138+ : flagShowMS(false)
2139+ , OnIcon(NULL)
2140+ , OffIcon(NULL)
2141+ , GlowIcon(NULL)
2142+ , toolbarButton(NULL)
2143+ , progressBar(NULL)
2144+{
2145+ setObjectName("MeteorShowers");
2146+ configDialog = new MeteorShowerDialog();
2147+ conf = StelApp::getInstance().getSettings();
2148+}
2149+
2150+/*
2151+ Destructor
2152+*/
2153+MeteorShowers::~MeteorShowers()
2154+{
2155+ delete configDialog;
2156+
2157+ if(GlowIcon)
2158+ delete GlowIcon;
2159+ if(OnIcon)
2160+ delete OnIcon;
2161+ if(OffIcon)
2162+ delete OffIcon;
2163+
2164+ active.clear();
2165+ activeInfo.clear();
2166+}
2167+
2168+/*
2169+ Reimplementation of the getCallOrder method
2170+*/
2171+double MeteorShowers::getCallOrder(StelModuleActionName actionName) const
2172+{
2173+ if(actionName == StelModule::ActionDraw)
2174+ return StelApp::getInstance().getModuleMgr().getModule("MeteorMgr")->getCallOrder(actionName)+0;
2175+ return 0;
2176+}
2177+
2178+void MeteorShowers::init()
2179+{
2180+ upgradeConfigIni();
2181+
2182+ try
2183+ {
2184+ StelFileMgr::makeSureDirExistsAndIsWritable(StelFileMgr::getUserDir()+"/modules/MeteorShowers");
2185+
2186+ // If no settings in the main config file, create with defaults
2187+ if(!conf->childGroups().contains("MeteorShowers"))
2188+ {
2189+ qDebug() << "MeteorShowers: no MeteorShower section exists in main config file - creating with defaults";
2190+ restoreDefaultConfigIni();
2191+ }
2192+
2193+ // populate settings from main config file.
2194+ readSettingsFromConfig();
2195+
2196+ showersJsonPath = StelFileMgr::findFile("modules/MeteorShowers", (StelFileMgr::Flags)(StelFileMgr::Directory|StelFileMgr::Writable)) + "/showers.json";
2197+
2198+ texPointer = StelApp::getInstance().getTextureManager().createTexture(StelFileMgr::getInstallationDir()+"/textures/pointeur5.png");
2199+ MeteorShower::radiantTexture = StelApp::getInstance().getTextureManager().createTexture(":/MeteorShowers/radiant.png");
2200+
2201+ // key bindings and other actions
2202+ QString msGroup = N_("Meteor Shower");
2203+ addAction("actionShow_MeteorShower", msGroup, N_("Show meteor showers"), "msVisible", "Ctrl+Alt+M");
2204+ addAction("actionShow_radiant_Labels", msGroup, N_("Radiant labels"), "labelsVisible", "Shift+M");
2205+ addAction("actionShow_MeteorShower_ConfigDialog", msGroup, N_("Meteor Shower configuration window"), configDialog, "visible", "Alt+M");
2206+
2207+ GlowIcon = new QPixmap(":/graphicGui/glow32x32.png");
2208+ OnIcon = new QPixmap(":/MeteorShowers/btMS-on.png");
2209+ OffIcon = new QPixmap(":/MeteorShowers/btMS-off.png");
2210+
2211+ setFlagShowMSButton(flagShowMSButton);
2212+ setFlagShowMS(getEnableAtStartup());
2213+ }
2214+ catch(std::runtime_error &e)
2215+ {
2216+ qWarning() << "MeteorShowers: init error:" << e.what();
2217+ return;
2218+ }
2219+
2220+ // A timer for hiding alert messages
2221+ messageTimer = new QTimer(this);
2222+ messageTimer->setSingleShot(true); // recurring check for update
2223+ messageTimer->setInterval(9000); // 6 seconds should be enough time
2224+ messageTimer->stop();
2225+ connect(messageTimer, SIGNAL(timeout()), this, SLOT(messageTimeout()));
2226+
2227+ // If the json file does not already exist, create it from the resource in the QT resource
2228+ if(!QFileInfo(showersJsonPath).exists())
2229+ {
2230+ if(!checkJsonFileFormat() || getJsonFileFormatVersion()<CATALOG_FORMAT_VERSION)
2231+ {
2232+ displayMessage(q_("The old showers.json file is no longer compatible - using default file"), "#bb0000");
2233+ restoreDefaultJsonFile();
2234+ }
2235+ else
2236+ {
2237+ qDebug() << "MeteorShowers: showers.json does not exist - copying default file to" << QDir::toNativeSeparators(showersJsonPath);
2238+ restoreDefaultJsonFile();
2239+ }
2240+ }
2241+
2242+ qDebug() << "MeteorShowers: loading catalog file:" << QDir::toNativeSeparators(showersJsonPath);
2243+
2244+ // create meteor Showers according to content os Showers.json file
2245+ readJsonFile();
2246+
2247+ // Set up download manager and the update schedule
2248+ downloadMgr = new QNetworkAccessManager(this);
2249+ connect(downloadMgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(updateDownloadComplete(QNetworkReply*)));
2250+ updateState = CompleteNoUpdates;
2251+ updateTimer = new QTimer(this);
2252+ updateTimer->setSingleShot(false); // recurring check for update
2253+ updateTimer->setInterval(13000); // check once every 13 seconds to see if it is time for an update
2254+ connect(updateTimer, SIGNAL(timeout()), this, SLOT(checkForUpdate()));
2255+ updateTimer->start();
2256+
2257+ // skyDate startup
2258+ skyDate = StelUtils::jdToQDateTime(StelApp::getInstance().getCore()->getJDay());
2259+
2260+ GETSTELMODULE(StelObjectMgr)->registerStelObjectMgr(this);
2261+}
2262+
2263+void MeteorShowers::deinit()
2264+{
2265+ MeteorShower::radiantTexture.clear();
2266+ texPointer.clear();
2267+}
2268+
2269+void MeteorShowers::upgradeConfigIni(void)
2270+{
2271+ // Upgrade settings for MeteorShower plugin
2272+ if (conf->contains("MeteorShowers/flag_show_ms"))
2273+ {
2274+ bool b = conf->value("MeteorShowers/flag_show_ms", false).toBool();
2275+ if (!conf->contains("MeteorShowers/enable_at_startup"))
2276+ conf->setValue("MeteorShowers/enable_at_startup", b);
2277+ conf->remove("MeteorShowers/flag_show_ms");
2278+ }
2279+}
2280+
2281+void MeteorShowers::setFlagShowMS(bool b)
2282+{
2283+ if(toolbarButton != NULL)
2284+ toolbarButton->setChecked(b);
2285+
2286+ flagShowMS=b;
2287+}
2288+
2289+// Define whether the button toggling meteor showers should be visible
2290+void MeteorShowers::setFlagShowMSButton(bool b)
2291+{
2292+ StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
2293+ if(b)
2294+ {
2295+ if(toolbarButton==NULL)
2296+ {
2297+ // Create the MeteorShowers button
2298+ toolbarButton = new StelButton(NULL, *OnIcon, *OffIcon, *GlowIcon, "actionShow_MeteorShower");
2299+ }
2300+ gui->getButtonBar()->addButton(toolbarButton, "065-pluginsGroup");
2301+ }
2302+ else
2303+ {
2304+ gui->getButtonBar()->hideButton("actionShow_MeteorShower");
2305+ }
2306+ flagShowMSButton = b;
2307+}
2308+
2309+bool MeteorShowers::changedSkyDate(StelCore* core)
2310+{
2311+ double JD = core->getJDay();
2312+ skyDate = StelUtils::jdToQDateTime(JD+StelUtils::getGMTShiftFromQT(JD)/24-core->getDeltaT(JD)/86400);
2313+ if(skyDate.toString("MM.dd.yyyy") != lastSkyDate.toString("MM.dd.yyyy")) //if the sky date changed
2314+ return true;
2315+ else
2316+ return false;
2317+}
2318+
2319+void MeteorShowers::draw(StelCore* core)
2320+{
2321+ if(!getFlagShowMS())
2322+ return;
2323+
2324+ StelPainter painter(core->getProjection(StelCore::FrameJ2000));
2325+ drawMarker(core, painter);
2326+
2327+ if(GETSTELMODULE(StelObjectMgr)->getFlagSelectedObjectPointer())
2328+ drawPointer(core, painter);
2329+
2330+ painter.setProjector(core->getProjection(StelCore::FrameAltAz));
2331+ drawStream(core, painter);
2332+}
2333+
2334+void MeteorShowers::drawMarker(StelCore* core, StelPainter& painter)
2335+{
2336+ Q_UNUSED(core);
2337+ painter.setFont(labelFont);
2338+
2339+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2340+ glEnable(GL_BLEND);
2341+ glEnable(GL_TEXTURE_2D);
2342+
2343+ foreach(const MeteorShowerP& ms, mShowers)
2344+ {
2345+ ms->updateCurrentData(skyDate);
2346+
2347+ bool flag=true;
2348+ if (ms->getStatus()==0 && getFlagActiveRadiant())
2349+ flag = false;
2350+
2351+ if(ms && ms->initialized && flag)
2352+ ms->draw(painter);
2353+ }
2354+ glDisable(GL_TEXTURE_2D);
2355+}
2356+
2357+void MeteorShowers::drawPointer(StelCore* core, StelPainter& painter)
2358+{
2359+ const StelProjectorP prj = core->getProjection(StelCore::FrameJ2000);
2360+
2361+ const QList<StelObjectP> newSelected = GETSTELMODULE(StelObjectMgr)->getSelectedObject("MeteorShower");
2362+ if(!newSelected.empty())
2363+ {
2364+ const StelObjectP obj = newSelected[0];
2365+ Vec3d pos=obj->getJ2000EquatorialPos(core);
2366+
2367+ Vec3d screenpos;
2368+ // Compute 2D pos and return if outside screen
2369+ if(!painter.getProjector()->project(pos, screenpos))
2370+ return;
2371+
2372+ const Vec3f& c(obj->getInfoColor());
2373+ painter.setColor(c[0],c[1],c[2]);
2374+ texPointer->bind();
2375+ painter.enableTexture2d(true);
2376+ glEnable(GL_BLEND);
2377+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode
2378+
2379+ float size = obj->getAngularSize(core)*M_PI/180.*prj->getPixelPerRadAtCenter();
2380+ size+=20.f + 10.f*std::sin(2.f * StelApp::getInstance().getTotalRunTime());
2381+
2382+ painter.drawSprite2dMode(screenpos[0]-size/2, screenpos[1]-size/2, 10.f, 90);
2383+ painter.drawSprite2dMode(screenpos[0]-size/2, screenpos[1]+size/2, 10.f, 0);
2384+ painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]+size/2, 10.f, -90);
2385+ painter.drawSprite2dMode(screenpos[0]+size/2, screenpos[1]-size/2, 10.f, -180);
2386+ painter.setColor(1,1,1,0);
2387+ }
2388+}
2389+
2390+void MeteorShowers::drawStream(StelCore* core, StelPainter& painter)
2391+{
2392+ LandscapeMgr* landmgr = (LandscapeMgr*)StelApp::getInstance().getModuleMgr().getModule("LandscapeMgr");
2393+ if(landmgr->getFlagAtmosphere() && landmgr->getLuminance()>5)
2394+ return;
2395+
2396+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2397+ glEnable(GL_BLEND);
2398+ painter.enableTexture2d(false);
2399+
2400+ int index = 0;
2401+ if(active.size() > 0)
2402+ {
2403+ foreach(const activeData &a, activeInfo)
2404+ {
2405+ Q_UNUSED(a);
2406+ // step through and draw all active meteors
2407+ for(std::vector<MeteorStream*>::iterator iter = active[index].begin(); iter != active[index].end(); ++iter)
2408+ {
2409+ (*iter)->draw(core, painter);
2410+ }
2411+ index++;
2412+ }
2413+ }
2414+}
2415+
2416+int MeteorShowers::calculateZHR(int zhr, QString variable, QDateTime start, QDateTime finish, QDateTime peak)
2417+{
2418+ /***************************************
2419+ * Get ZHR ranges
2420+ ***************************************/
2421+ int highZHR;
2422+ int lowZHR;
2423+ //bool multPeak = false; //multiple peaks
2424+ if(zhr != -1) //isn't variable
2425+ {
2426+ highZHR = zhr;
2427+ lowZHR = 0;
2428+ }
2429+ else
2430+ {
2431+ QStringList varZHR = variable.split("-");
2432+ lowZHR = varZHR.at(0).toInt();
2433+ if(varZHR.at(1).contains("*"))
2434+ {
2435+ //multPeak = true;
2436+ highZHR = varZHR[1].replace("*", "").toInt();
2437+ }
2438+ else
2439+ {
2440+ highZHR = varZHR.at(1).toInt();
2441+ }
2442+ }
2443+
2444+ /***************************************
2445+ * Convert time intervals
2446+ ***************************************/
2447+ double startJD = StelUtils::qDateTimeToJd(start);
2448+ double finishJD = StelUtils::qDateTimeToJd(finish);
2449+ double peakJD = StelUtils::qDateTimeToJd(peak);
2450+ double currentJD = StelUtils::qDateTimeToJd(skyDate);
2451+
2452+ /***************************************
2453+ * Gaussian distribution
2454+ ***************************************/
2455+ double sd; //standard deviation
2456+ if (currentJD >= startJD && currentJD < peakJD) //left side of gaussian
2457+ sd = (peakJD - startJD)/2;
2458+ else
2459+ sd = (finishJD - peakJD)/2;
2460+
2461+ double gaussian = highZHR * std::exp( - std::pow(currentJD - peakJD, 2) / (sd*sd) ) + lowZHR;
2462+
2463+ return (int) ((int) ((gaussian - (int) gaussian) * 10) >= 5 ? gaussian+1 : gaussian);
2464+}
2465+
2466+void MeteorShowers::updateActiveInfo(void)
2467+{
2468+ foreach(const MeteorShowerP& ms, mShowers)
2469+ {
2470+ if(ms && ms->initialized)
2471+ {
2472+ //if the meteor shower is active, get data
2473+ if(ms->isActive)
2474+ {
2475+ //First, check if there is already data about the constellation in "activeInfo"
2476+ //The var "index" will be updated to show the correct place do put the new information
2477+ int index = 0;
2478+ foreach(const activeData &a, activeInfo)
2479+ {
2480+ if(a.showerID == ms->showerID) //exists
2481+ break;
2482+ index++;
2483+ }
2484+
2485+ if(activeInfo.size() < index + 1) //new?, put in the end
2486+ {
2487+ activeData newData;
2488+ newData.showerID = ms->showerID;
2489+ newData.speed = ms->speed;
2490+ newData.radiantAlpha = ms->radiantAlpha;
2491+ newData.radiantDelta = ms->radiantDelta;
2492+ newData.zhr = ms->zhr;
2493+ newData.variable = ms->variable;
2494+ newData.start = ms->start;
2495+ newData.finish = ms->finish;
2496+ newData.peak = ms->peak;
2497+ newData.status = ms->isActive;
2498+ activeInfo.append(newData);
2499+ }
2500+ else //just overwrites
2501+ {
2502+ activeInfo[index].zhr = ms->zhr;
2503+ activeInfo[index].variable = ms->variable;
2504+ activeInfo[index].start = ms->start;
2505+ activeInfo[index].finish = ms->finish;
2506+ activeInfo[index].peak = ms->peak;
2507+ activeInfo[index].status = ms->isActive;
2508+ }
2509+ }
2510+ }
2511+ }
2512+ lastSkyDate = skyDate;
2513+}
2514+
2515+void MeteorShowers::update(double deltaTime)
2516+{
2517+ if(!getFlagShowMS())
2518+ return;
2519+
2520+ StelCore* core = StelApp::getInstance().getCore();
2521+
2522+ double timeRate = core->getTimeRate();
2523+ if(timeRate > 0.2)
2524+ return;
2525+
2526+ //check if the sky date changed
2527+ bool changedDate = changedSkyDate(core);
2528+
2529+ if(changedDate)
2530+ {
2531+ // clear data of all MS active
2532+ activeInfo.clear();
2533+
2534+ // Is GUI visible and the year changed? refresh ranges
2535+ if(configDialog->visible() && lastSkyDate.toString("yyyy") != skyDate.toString("yyyy"))
2536+ configDialog->refreshRangeDates();
2537+ }
2538+
2539+ updateActiveInfo();
2540+
2541+ deltaTime*=1000;
2542+
2543+ std::vector<std::vector<MeteorStream*> >::iterator iterOut;
2544+ std::vector<MeteorStream*>::iterator iterIn;
2545+ int index = 0;
2546+ if(active.size() > 0)
2547+ {
2548+ // step through and update all active meteors
2549+ for(iterOut = active.begin(); iterOut != active.end(); ++iterOut)
2550+ {
2551+ for(iterIn = active[index].begin(); iterIn != active[index].end(); ++iterIn)
2552+ {
2553+ if(!(*iterIn)->update(deltaTime))
2554+ {
2555+ delete *iterIn;
2556+ active[index].erase(iterIn);
2557+ iterIn--;
2558+ }
2559+ }
2560+ if(active[index].empty())
2561+ {
2562+ active.erase(iterOut);
2563+ iterOut--;
2564+ index--;
2565+ }
2566+ index++;
2567+ }
2568+ }
2569+
2570+ index = 0;
2571+ foreach(const activeData &a, activeInfo)
2572+ {
2573+ ZHR = calculateZHR(a.zhr, a.variable, a.start, a.finish, a.peak);
2574+
2575+ // only makes sense given lifetimes of meteors to draw when timeSpeed is realtime
2576+ // otherwise high overhead of large numbers of meteors
2577+ double tspeed = timeRate*86400; // sky seconds per actual second
2578+ if(tspeed<=0 || fabs(tspeed)>1.)
2579+ return; // don't start any more meteors
2580+
2581+ // if stellarium has been suspended, don't create huge number of meteors to
2582+ // make up for lost time!
2583+ if(deltaTime > 500)
2584+ deltaTime = 500;
2585+
2586+ // determine average meteors per frame needing to be created
2587+ int mpf = (int)((double)ZHR*zhrToWsr*deltaTime/1000.0 + 0.5);
2588+ if(mpf<1)
2589+ mpf = 1;
2590+
2591+ std::vector<MeteorStream*> aux;
2592+ if(active.empty() || active.size() < (unsigned) index+1)
2593+ active.push_back(aux);
2594+
2595+ for(int i=0; i<mpf; ++i)
2596+ {
2597+ // start new meteor based on ZHR time probability
2598+ double prob = ((double)rand())/RAND_MAX;
2599+ if(ZHR>0 && prob<((double)ZHR*zhrToWsr*deltaTime/1000.0/(double)mpf))
2600+ {
2601+ MeteorStream *m = new MeteorStream(core, a.speed, a.radiantAlpha, a.radiantDelta);
2602+ active[index].push_back(m);
2603+ }
2604+ }
2605+ index++;
2606+ }
2607+}
2608+
2609+QList<MeteorShowerP> MeteorShowers::searchEvents(QDate dateFrom, QDate dateTo) const
2610+{
2611+ QList<MeteorShowerP> result;
2612+ QDate date;
2613+
2614+ foreach(const MeteorShowerP& ms, mShowers)
2615+ {
2616+ date = dateFrom;
2617+ while(date.operator <=(dateTo))
2618+ {
2619+ ms->updateCurrentData((QDateTime) date);
2620+ if(ms->isActive)
2621+ {
2622+ result.append(ms);
2623+ break;
2624+ }
2625+ date = date.addDays(1);
2626+ }
2627+ }
2628+
2629+ return result;
2630+}
2631+
2632+QList<StelObjectP> MeteorShowers::searchAround(const Vec3d& av, double limitFov, const StelCore*) const
2633+{
2634+ QList<StelObjectP> result;
2635+
2636+ if(!getFlagRadiant())
2637+ return result;
2638+
2639+ Vec3d v(av);
2640+ v.normalize();
2641+ double cosLimFov = cos(limitFov * M_PI/180.);
2642+ Vec3d equPos;
2643+
2644+ foreach(const MeteorShowerP& ms, mShowers)
2645+ {
2646+ if(ms->initialized)
2647+ {
2648+ equPos = ms->XYZ;
2649+ equPos.normalize();
2650+ if(equPos[0]*v[0] + equPos[1]*v[1] + equPos[2]*v[2]>=cosLimFov)
2651+ {
2652+ result.append(qSharedPointerCast<StelObject>(ms));
2653+ }
2654+ }
2655+ }
2656+
2657+ return result;
2658+}
2659+
2660+StelObjectP MeteorShowers::searchByName(const QString& englishName) const
2661+{
2662+ if(!getFlagRadiant())
2663+ return NULL;
2664+
2665+ foreach(const MeteorShowerP& ms, mShowers)
2666+ {
2667+ if(ms->getEnglishName().toUpper() == englishName.toUpper())
2668+ return qSharedPointerCast<StelObject>(ms);
2669+ }
2670+
2671+ return NULL;
2672+}
2673+
2674+StelObjectP MeteorShowers::searchByNameI18n(const QString& nameI18n) const
2675+{
2676+ if(!getFlagRadiant())
2677+ return NULL;
2678+
2679+ foreach(const MeteorShowerP& ms, mShowers)
2680+ {
2681+ if(ms->getNameI18n().toUpper() == nameI18n.toUpper())
2682+ return qSharedPointerCast<StelObject>(ms);
2683+ }
2684+
2685+ return NULL;
2686+}
2687+
2688+QStringList MeteorShowers::listMatchingObjectsI18n(const QString& objPrefix, int maxNbItem, bool useStartOfWords) const
2689+{
2690+ QStringList result;
2691+ if(!getFlagRadiant())
2692+ return result;
2693+
2694+ if(maxNbItem==0)
2695+ return result;
2696+
2697+ QString sn;
2698+ bool find;
2699+
2700+ foreach(const MeteorShowerP& ms, mShowers)
2701+ {
2702+ sn = ms->getNameI18n();
2703+ find = false;
2704+ if (useStartOfWords)
2705+ {
2706+ if (sn.toUpper().left(objPrefix.length()) == objPrefix.toUpper())
2707+ find = true;
2708+ }
2709+ else
2710+ {
2711+ if (sn.contains(objPrefix, Qt::CaseInsensitive))
2712+ find = true;
2713+ }
2714+ if (find)
2715+ result << sn;
2716+
2717+
2718+ }
2719+
2720+ result.sort();
2721+
2722+ if(result.size()>maxNbItem)
2723+ result.erase(result.begin()+maxNbItem, result.end());
2724+
2725+ return result;
2726+}
2727+
2728+QStringList MeteorShowers::listMatchingObjects(const QString& objPrefix, int maxNbItem, bool useStartOfWords) const
2729+{
2730+ QStringList result;
2731+ if(!getFlagRadiant())
2732+ return result;
2733+
2734+ if(maxNbItem==0)
2735+ return result;
2736+
2737+ QString sn;
2738+ bool find;
2739+ foreach(const MeteorShowerP& ms, mShowers)
2740+ {
2741+ sn = ms->getEnglishName();
2742+ find = false;
2743+ if(useStartOfWords)
2744+ {
2745+ if(objPrefix.toUpper()==sn.toUpper().left(objPrefix.length()))
2746+ find = true;
2747+ }
2748+ else
2749+ {
2750+ if(sn.contains(objPrefix, Qt::CaseInsensitive))
2751+ find = true;
2752+ }
2753+ if(find)
2754+ {
2755+ result << sn;
2756+ }
2757+
2758+ sn = ms->getDesignation();
2759+ find = false;
2760+ if(useStartOfWords)
2761+ {
2762+ if(objPrefix.toUpper()==sn.toUpper().left(objPrefix.length()))
2763+ find = true;
2764+ }
2765+ else
2766+ {
2767+ if(sn.contains(objPrefix, Qt::CaseInsensitive))
2768+ find = true;
2769+ }
2770+ if(find)
2771+ {
2772+ result << sn;
2773+ }
2774+ }
2775+
2776+ result.sort();
2777+ if(result.size()>maxNbItem)
2778+ result.erase(result.begin()+maxNbItem, result.end());
2779+
2780+ return result;
2781+}
2782+
2783+QStringList MeteorShowers::listAllObjects(bool inEnglish) const
2784+{
2785+ QStringList result;
2786+ if(inEnglish)
2787+ {
2788+ foreach(const MeteorShowerP& ms, mShowers)
2789+ {
2790+ result << ms->getEnglishName();
2791+ }
2792+ }
2793+ else
2794+ {
2795+ foreach(const MeteorShowerP& ms, mShowers)
2796+ {
2797+ result << ms->getNameI18n();
2798+ }
2799+ }
2800+ return result;
2801+}
2802+
2803+bool MeteorShowers::configureGui(bool show)
2804+{
2805+ if(show)
2806+ configDialog->setVisible(true);
2807+
2808+ return true;
2809+}
2810+
2811+QVariantMap MeteorShowers::loadShowersMap(QString path)
2812+{
2813+ if(path.isEmpty())
2814+ path = showersJsonPath;
2815+
2816+ QVariantMap map;
2817+ QFile jsonFile(path);
2818+ if(!jsonFile.open(QIODevice::ReadOnly))
2819+ qWarning() << "MeteorShowers: cannot open" << path;
2820+ else
2821+ map = StelJsonParser::parse(jsonFile.readAll()).toMap();
2822+
2823+ jsonFile.close();
2824+ return map;
2825+}
2826+
2827+void MeteorShowers::readJsonFile(void)
2828+{
2829+ setShowersMap(loadShowersMap());
2830+}
2831+
2832+void MeteorShowers::setShowersMap(const QVariantMap& map)
2833+{
2834+ mShowers.clear();
2835+ QVariantMap msMap = map.value("showers").toMap();
2836+ foreach(QString msKey, msMap.keys())
2837+ {
2838+ QVariantMap msData = msMap.value(msKey).toMap();
2839+ msData["showerID"] = msKey;
2840+
2841+ MeteorShowerP ms(new MeteorShower(msData));
2842+ if(ms->initialized)
2843+ mShowers.append(ms);
2844+ }
2845+}
2846+
2847+void MeteorShowers::restoreDefaults(void)
2848+{
2849+ restoreDefaultConfigIni();
2850+ restoreDefaultJsonFile();
2851+ readJsonFile();
2852+ readSettingsFromConfig();
2853+}
2854+
2855+void MeteorShowers::restoreDefaultConfigIni(void)
2856+{
2857+ conf->beginGroup("MeteorShowers");
2858+
2859+ // delete all existing MeteorShower settings...
2860+ conf->remove("");
2861+
2862+ conf->setValue("enable_at_startup", false);
2863+ conf->setValue("updates_enabled", true);
2864+ conf->setValue("url", "http://stellarium.org/json/showers.json");
2865+ conf->setValue("update_frequency_hours", 100);
2866+ conf->setValue("flag_show_ms_button", true);
2867+ conf->setValue("flag_show_radiants", true);
2868+ conf->setValue("flag_active_radiants", false);
2869+
2870+ conf->setValue("colorARG", "0, 255, 240");
2871+ conf->setValue("colorARR", "255, 240, 0");
2872+ conf->setValue("colorIR", "255, 255, 255");
2873+
2874+ conf->setValue("show_radiant_labels", true);
2875+
2876+ conf->endGroup();
2877+}
2878+
2879+void MeteorShowers::restoreDefaultJsonFile(void)
2880+{
2881+ if(QFileInfo(showersJsonPath).exists())
2882+ backupJsonFile(true);
2883+
2884+ QFile src(":/MeteorShowers/showers.json");
2885+ if(!src.copy(showersJsonPath))
2886+ {
2887+ qWarning() << "MeteorShowers: cannot copy JSON resource to" << showersJsonPath;
2888+ }
2889+ else
2890+ {
2891+ qDebug() << "MeteorShowers: copied default showers.json to" << showersJsonPath;
2892+ // The resource is read only, and the new file inherits this... make sure the new file
2893+ // is writable by the Stellarium process so that updates can be done.
2894+ QFile dest(showersJsonPath);
2895+ dest.setPermissions(dest.permissions() | QFile::WriteOwner);
2896+
2897+ // Make sure that in the case where an online update has previously been done, but
2898+ // the json file has been manually removed, that an update is schreduled in a timely
2899+ // manner
2900+ conf->remove("MeteorShowers/last_update");
2901+ lastUpdate = QDateTime::fromString("2013-12-31T12:00:00", Qt::ISODate);
2902+ }
2903+}
2904+
2905+bool MeteorShowers::backupJsonFile(bool deleteOriginal)
2906+{
2907+ QFile old(showersJsonPath);
2908+ if(!old.exists())
2909+ {
2910+ qWarning() << "MeteorShowers: no file to backup";
2911+ return false;
2912+ }
2913+
2914+ QString backupPath = showersJsonPath + ".old";
2915+ if(QFileInfo(backupPath).exists())
2916+ QFile(backupPath).remove();
2917+
2918+ if(old.copy(backupPath))
2919+ {
2920+ if(deleteOriginal)
2921+ {
2922+ if(!old.remove())
2923+ {
2924+ qWarning() << "MeteorShowers: WARNING - could not remove old showers.json file";
2925+ return false;
2926+ }
2927+ }
2928+ }
2929+ else
2930+ {
2931+ qWarning() << "MeteorShowers: WARNING - failed to copy showers.json to showers.json.old";
2932+ return false;
2933+ }
2934+
2935+ return true;
2936+}
2937+
2938+int MeteorShowers::getJsonFileFormatVersion(void)
2939+{
2940+ int jsonVersion = -1;
2941+ QFile showersJsonFile(showersJsonPath);
2942+ if(!showersJsonFile.open(QIODevice::ReadOnly))
2943+ {
2944+ qWarning() << "MeteorShowers: cannot open" << QDir::toNativeSeparators(showersJsonPath);
2945+ return jsonVersion;
2946+ }
2947+
2948+ QVariantMap map;
2949+ map = StelJsonParser::parse(&showersJsonFile).toMap();
2950+ if(map.contains("version"))
2951+ {
2952+ jsonVersion = map.value("version").toInt();
2953+ }
2954+
2955+ showersJsonFile.close();
2956+ qDebug() << "MeteorShowers: version of the format of the catalog:" << jsonVersion;
2957+ return jsonVersion;
2958+}
2959+
2960+bool MeteorShowers::checkJsonFileFormat()
2961+{
2962+ QFile showersJsonFile(showersJsonPath);
2963+ if(!showersJsonFile.open(QIODevice::ReadOnly))
2964+ {
2965+ qWarning() << "MeteorShowers: cannot open" << QDir::toNativeSeparators(showersJsonPath);
2966+ return false;
2967+ }
2968+
2969+ QVariantMap map;
2970+ try
2971+ {
2972+ map = StelJsonParser::parse(&showersJsonFile).toMap();
2973+ showersJsonFile.close();
2974+ }
2975+ catch(std::runtime_error& e)
2976+ {
2977+ qDebug() << "MeteorShowers: file format is wrong! Error:" << e.what();
2978+ return false;
2979+ }
2980+
2981+ return true;
2982+}
2983+
2984+void MeteorShowers::readSettingsFromConfig(void)
2985+{
2986+ conf->beginGroup("MeteorShowers");
2987+
2988+ updateUrl = conf->value("url", "http://stellarium.org/json/showers.json").toString();
2989+ updateFrequencyHours = conf->value("update_frequency_hours", 720).toInt();
2990+ lastUpdate = QDateTime::fromString(conf->value("last_update", "2013-12-10T12:00:00").toString(), Qt::ISODate);
2991+ updatesEnabled = conf->value("updates_enabled", true).toBool();
2992+ enableAtStartup = conf->value("enable_at_startup", false).toBool();
2993+ flagShowMSButton = conf->value("flag_show_ms_button", true).toBool();
2994+ setFlagRadiant(conf->value("flag_show_radiants", true).toBool());
2995+ flagShowAR = conf->value("flag_active_radiants", false).toBool();
2996+
2997+ Vec3f color;
2998+ color = StelUtils::strToVec3f(conf->value("colorARG", "0, 255, 240").toString());
2999+ colorARG = QColor(color[0],color[1],color[2]);
3000+ color = StelUtils::strToVec3f(conf->value("colorARR", "255, 240, 0").toString());
3001+ colorARR = QColor(color[0],color[1],color[2]);
3002+ color = StelUtils::strToVec3f(conf->value("colorIR", "255, 255, 255").toString());
3003+ colorIR = QColor(color[0],color[1],color[2]);
3004+
3005+ MeteorShower::showLabels = conf->value("show_radiant_labels", true).toBool();
3006+ labelFont.setPixelSize(conf->value("font_size", 13).toInt());
3007+
3008+ conf->endGroup();
3009+}
3010+
3011+void MeteorShowers::saveSettingsToConfig(void)
3012+{
3013+ conf->beginGroup("MeteorShowers");
3014+
3015+ conf->setValue("url", updateUrl);
3016+ conf->setValue("update_frequency_hours", updateFrequencyHours);
3017+ conf->setValue("updates_enabled", updatesEnabled);
3018+ conf->setValue("enable_at_startup", enableAtStartup);
3019+ conf->setValue("flag_show_ms_button", flagShowMSButton);
3020+ conf->setValue("flag_show_radiants", getFlagRadiant());
3021+ conf->setValue("flag_active_radiants", flagShowAR);
3022+
3023+ int r,g,b;
3024+ colorARG.getRgb(&r,&g,&b);
3025+ conf->setValue("colorARG", QString("%1, %2, %3").arg(r).arg(g).arg(b));
3026+ colorARR.getRgb(&r,&g,&b);
3027+ conf->setValue("colorARR", QString("%1, %2, %3").arg(r).arg(g).arg(b));
3028+ colorIR.getRgb(&r,&g,&b);
3029+ conf->setValue("colorIR", QString("%1, %2, %3").arg(r).arg(g).arg(b));
3030+
3031+ conf->setValue("show_radiant_labels", MeteorShower::showLabels);
3032+ conf->setValue("font_size", labelFont.pixelSize());
3033+
3034+ conf->endGroup();
3035+}
3036+
3037+int MeteorShowers::getSecondsToUpdate(void)
3038+{
3039+ QDateTime nextUpdate = lastUpdate.addSecs(updateFrequencyHours * 3600);
3040+ return QDateTime::currentDateTime().secsTo(nextUpdate);
3041+}
3042+
3043+void MeteorShowers::checkForUpdate(void)
3044+{
3045+ if(updatesEnabled && lastUpdate.addSecs(updateFrequencyHours * 3600) <= QDateTime::currentDateTime())
3046+ updateJSON();
3047+}
3048+
3049+void MeteorShowers::updateJSON(void)
3050+{
3051+ if(updateState==MeteorShowers::Updating)
3052+ {
3053+ qWarning() << "MeteorShowers: already updating... will not start again current update is complete.";
3054+ return;
3055+ }
3056+ else
3057+ {
3058+ qDebug() << "MeteorShowers: starting update...";
3059+ }
3060+
3061+ lastUpdate = QDateTime::currentDateTime();
3062+ conf->setValue("MeteorShowers/last_update", lastUpdate.toString(Qt::ISODate));
3063+
3064+ emit(jsonUpdateComplete());
3065+
3066+ updateState = MeteorShowers::Updating;
3067+
3068+ emit(updateStateChanged(updateState));
3069+ updateFile.clear();
3070+
3071+ if(progressBar==NULL)
3072+ progressBar = StelApp::getInstance().addProgressBar();
3073+
3074+ progressBar->setValue(0);
3075+ progressBar->setRange(0, 100);
3076+ progressBar->setFormat("Update meteor showers");
3077+
3078+ QNetworkRequest request;
3079+ request.setUrl(QUrl(updateUrl));
3080+ request.setRawHeader("User-Agent", QString("Mozilla/5.0 (Stellarium Meteor Showers Plugin %1; http://stellarium.org/)").arg(METEORSHOWERS_PLUGIN_VERSION).toUtf8());
3081+ downloadMgr->get(request);
3082+
3083+ updateState = MeteorShowers::CompleteUpdates;
3084+ emit(updateStateChanged(updateState));
3085+ emit(jsonUpdateComplete());
3086+}
3087+
3088+void MeteorShowers::updateDownloadComplete(QNetworkReply* reply)
3089+{
3090+ // check the download worked, and save the data to file if this is the case.
3091+ if(reply->error() != QNetworkReply::NoError)
3092+ {
3093+ qWarning() << "MeteorShowers: FAILED to download" << reply->url() << " Error:" << reply->errorString();
3094+ }
3095+ else
3096+ {
3097+ // download completed successfully.
3098+ QString jsonFilePath = StelFileMgr::findFile("modules/MeteorShowers", StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::Directory)) + "/showers.json";
3099+ if(jsonFilePath.isEmpty())
3100+ {
3101+ qWarning() << "MeteorShowers: cannot write JSON data to file";
3102+ }
3103+ else
3104+ {
3105+ QFile jsonFile(jsonFilePath);
3106+ if(jsonFile.exists())
3107+ jsonFile.remove();
3108+
3109+ jsonFile.open(QIODevice::WriteOnly | QIODevice::Text);
3110+ jsonFile.write(reply->readAll());
3111+ jsonFile.close();
3112+ }
3113+ }
3114+
3115+ if(progressBar)
3116+ {
3117+ progressBar->setValue(100);
3118+ StelApp::getInstance().removeProgressBar(progressBar);
3119+ progressBar = NULL;
3120+ }
3121+
3122+ readJsonFile();
3123+}
3124+
3125+void MeteorShowers::displayMessage(const QString& message, const QString hexColor)
3126+{
3127+ messageIDs << GETSTELMODULE(LabelMgr)->labelScreen(message, 30, 30 + (20*messageIDs.count()), true, 16, hexColor);
3128+ messageTimer->start();
3129+}
3130+
3131+void MeteorShowers::messageTimeout(void)
3132+{
3133+ foreach(int i, messageIDs)
3134+ {
3135+ GETSTELMODULE(LabelMgr)->deleteLabel(i);
3136+ }
3137+}
3138+
3139+bool MeteorShowers::getFlagLabels()
3140+{
3141+ return MeteorShower::showLabels;
3142+}
3143+
3144+void MeteorShowers::setFlagLabels(bool b)
3145+{
3146+ if (MeteorShower::showLabels != b)
3147+ MeteorShower::showLabels = b;
3148+}
3149+
3150+void MeteorShowers::setLabelFontSize(int size)
3151+{
3152+ if (labelFont.pixelSize() != size)
3153+ labelFont.setPixelSize(size);
3154+}
3155+
3156+void MeteorShowers::translations()
3157+{
3158+#if 0
3159+ // Meteor showers
3160+ // TRANSLATORS: Name of meteor shower
3161+ N_("Quadrantids");
3162+ // TRANSLATORS: Name of meteor shower
3163+ N_("Lyrids");
3164+ // TRANSLATORS: Name of meteor shower
3165+ N_("α-Centaurids");
3166+ // TRANSLATORS: Name of meteor shower
3167+ N_("γ-Normids");
3168+ // TRANSLATORS: Name of meteor shower
3169+ N_("η-Aquariids");
3170+ // TRANSLATORS: Name of meteor shower
3171+ N_("June Bootids");
3172+ // TRANSLATORS: Name of meteor shower
3173+ N_("Piscis Austrinids");
3174+ // TRANSLATORS: Name of meteor shower
3175+ N_("Southern δ-Aquariids");
3176+ // TRANSLATORS: Name of meteor shower
3177+ N_("α-Capricornids");
3178+ // TRANSLATORS: Name of meteor shower
3179+ N_("α-Aurigids");
3180+ // TRANSLATORS: Name of meteor shower
3181+ N_("September ε-Perseids");
3182+ // TRANSLATORS: Name of meteor shower
3183+ N_("Draconids");
3184+ // TRANSLATORS: Name of meteor shower
3185+ N_("Leonids");
3186+ // TRANSLATORS: Name of meteor shower
3187+ N_("Phoenicids");
3188+ // TRANSLATORS: Name of meteor shower
3189+ N_("Puppid-Velids");
3190+ // TRANSLATORS: Name of meteor shower
3191+ N_("Ursids");
3192+ // TRANSLATORS: Name of meteor shower
3193+ N_("Perseids");
3194+ // TRANSLATORS: Name of meteor shower
3195+ N_("δ-Leonids");
3196+ // TRANSLATORS: Name of meteor shower
3197+ N_("π-Puppids");
3198+ // TRANSLATORS: Name of meteor shower
3199+ N_("June Lyrids");
3200+ // TRANSLATORS: Name of meteor shower
3201+ N_("κ-Cygnids");
3202+ // TRANSLATORS: Name of meteor shower
3203+ N_("ε-Lyrids");
3204+ // TRANSLATORS: Name of meteor shower
3205+ N_("δ-Aurigids");
3206+ // TRANSLATORS: Name of meteor shower
3207+ N_("ε-Geminids");
3208+ // TRANSLATORS: Name of meteor shower
3209+ N_("Southern Taurids");
3210+ // TRANSLATORS: Name of meteor shower
3211+ N_("Northern Taurids");
3212+ // TRANSLATORS: Name of meteor shower
3213+ N_("Monocerotids");
3214+ // TRANSLATORS: Name of meteor shower
3215+ N_("σ-Hydrids");
3216+ // TRANSLATORS: Name of meteor shower
3217+ N_("Geminids");
3218+ // TRANSLATORS: Name of meteor shower
3219+ N_("Leonis Minorids");
3220+ // TRANSLATORS: Name of meteor shower
3221+ N_("December Leonis Minorids");
3222+ // TRANSLATORS: Name of meteor shower
3223+ N_("Comae Berenicids");
3224+ // TRANSLATORS: Name of meteor shower
3225+ N_("Orionids");
3226+ // TRANSLATORS: Name of meteor shower
3227+ N_("Andromedids");
3228+
3229+ // List of parent objects for meteor showers
3230+ // TRANSLATORS: Name of parent object for meteor shower
3231+ N_("Minor planet 2003 EH1 and Comet C/1490 Y1");
3232+ // TRANSLATORS: Name of parent object for meteor shower
3233+ N_("Comet 1P/Halley");
3234+ // TRANSLATORS: Name of parent object for meteor shower
3235+ N_("Comet 7P/Pons-Winnecke");
3236+ // TRANSLATORS: Name of parent object for meteor shower
3237+ N_("Comet 55P/Tempel-Tuttle");
3238+ // TRANSLATORS: Name of parent object for meteor shower
3239+ N_("Comet 96P/Machholz");
3240+ // TRANSLATORS: Name of parent object for meteor shower
3241+ N_("Comet 109P/Swift-Tuttle");
3242+ // TRANSLATORS: Name of parent object for meteor shower
3243+ N_("Comet Thatcher (1861 I)");
3244+ // TRANSLATORS: Name of parent object for meteor shower
3245+ N_("Minor planet (4450) Pan");
3246+ // TRANSLATORS: Name of parent object for meteor shower
3247+ N_("Comet 26P/Grigg-Skjellerup");
3248+ // TRANSLATORS: Name of parent object for meteor shower
3249+ N_("Comet 21P/Giacobini-Zinner");
3250+ // TRANSLATORS: Name of parent object for meteor shower
3251+ N_("Comet 169P/NEAT");
3252+ // TRANSLATORS: Name of parent object for meteor shower
3253+ N_("Comet 289P/Blanpain");
3254+ // TRANSLATORS: Name of parent object for meteor shower
3255+ N_("Comet 8P/Tuttle");
3256+ // TRANSLATORS: Name of parent object for meteor shower
3257+ N_("Minor planet 2008 ED69");
3258+ // TRANSLATORS: Name of parent object for meteor shower
3259+ N_("Comet 2P/Encke");
3260+ // TRANSLATORS: Name of parent object for meteor shower
3261+ N_("Comet 3D/Biela");
3262+ // TRANSLATORS: Name of parent object for meteor shower
3263+ N_("Minor planet 2004 TG10");
3264+ // TRANSLATORS: Name of parent object for meteor shower
3265+ N_("Minor planet (3200) Phaethon");
3266+
3267+ /* For copy/paste:
3268+ // TRANSLATORS: Name of meteor shower
3269+ N_("");
3270+ */
3271+
3272+#endif
3273+}
3274
3275=== added file 'plugins/MeteorShowers/src/MeteorShowers.hpp'
3276--- plugins/MeteorShowers/src/MeteorShowers.hpp 1970-01-01 00:00:00 +0000
3277+++ plugins/MeteorShowers/src/MeteorShowers.hpp 2014-03-10 17:28:07 +0000
3278@@ -0,0 +1,412 @@
3279+/*
3280+ * Copyright (C) 2013 Marcos Cardinot
3281+ * Copyright (C) 2011 Alexander Wolf
3282+ *
3283+ * This program is free software; you can redistribute it and/or
3284+ * modify it under the terms of the GNU General Public License
3285+ * as published by the Free Software Foundation; either version 2
3286+ * of the License, or (at your option) any later version.
3287+ *
3288+ * This program is distributed in the hope that it will be useful,
3289+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3290+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3291+ * GNU General Public License for more details.
3292+ *
3293+ * You should have received a copy of the GNU General Public License
3294+ * along with this program; if not, write to the Free Software
3295+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
3296+ */
3297+
3298+#ifndef METEORSHOWERS_HPP_
3299+#define METEORSHOWERS_HPP_
3300+
3301+#include "MeteorShower.hpp"
3302+#include "MeteorStream.hpp"
3303+#include "StelFader.hpp"
3304+#include "StelModule.hpp"
3305+#include "StelObjectModule.hpp"
3306+#include "StelTextureTypes.hpp"
3307+
3308+#include <QColor>
3309+#include <QDateTime>
3310+#include <QFont>
3311+#include <QSharedPointer>
3312+#include <QVariantMap>
3313+
3314+class QNetworkAccessManager;
3315+class QNetworkReply;
3316+class QProgressBar;
3317+class QSettings;
3318+class QTimer;
3319+class MeteorShowerDialog;
3320+class StelButton;
3321+class StelPainter;
3322+
3323+typedef QSharedPointer<MeteorShower> MeteorShowerP;
3324+
3325+//! This is an example of a plug-in which can be dynamically loaded into stellarium
3326+class MeteorShowers : public StelObjectModule
3327+{
3328+ Q_OBJECT
3329+ Q_PROPERTY(bool msVisible READ getFlagShowMS WRITE setFlagShowMS)
3330+ Q_PROPERTY(bool labelsVisible READ getFlagLabels WRITE setFlagLabels)
3331+public:
3332+ //! @enum UpdateState
3333+ //! Used for keeping track of the download/update status
3334+ enum UpdateState
3335+ {
3336+ Updating, //!< Update in progress
3337+ CompleteNoUpdates, //!< Update completed, there we no updates
3338+ CompleteUpdates, //!< Update completed, there were updates
3339+ DownloadError, //!< Error during download phase
3340+ OtherError //!< Other error
3341+ };
3342+
3343+ MeteorShowers();
3344+ virtual ~MeteorShowers();
3345+
3346+ ///////////////////////////////////////////////////////////////////////////
3347+ // Methods defined in the StelModule class
3348+ virtual void init();
3349+ //! called before the plug-in is un-loaded.
3350+ //! Useful for stopping processes, unloading textures, etc.
3351+ virtual void deinit();
3352+ virtual void update(double deltaTime);
3353+ virtual void draw(StelCore* core);
3354+ virtual void drawMarker(StelCore* core, StelPainter& painter);
3355+ virtual void drawPointer(StelCore* core, StelPainter& painter);
3356+ virtual void drawStream(StelCore* core, StelPainter& painter);
3357+ virtual double getCallOrder(StelModuleActionName actionName) const;
3358+
3359+ ///////////////////////////////////////////////////////////////////////////
3360+ // Methods defined in StelObjectManager class
3361+ //! Used to get a list of objects which are near to some position.
3362+ //! @param v a vector representing the position in th sky around which to search for nebulae.
3363+ //! @param limitFov the field of view around the position v in which to search for satellites.
3364+ //! @param core the StelCore to use for computations.
3365+ //! @return an list containing the satellites located inside the limitFov circle around position v.
3366+ virtual QList<StelObjectP> searchAround(const Vec3d& v, double limitFov, const StelCore* core) const;
3367+
3368+ //! Return the matching satellite object's pointer if exists or NULL.
3369+ //! @param nameI18n The case in-sensistive satellite name
3370+ virtual StelObjectP searchByNameI18n(const QString& nameI18n) const;
3371+
3372+ //! Return the matching satellite if exists or NULL.
3373+ //! @param name The case in-sensistive standard program name
3374+ virtual StelObjectP searchByName(const QString& name) const;
3375+
3376+ //! Find and return the list of at most maxNbItem objects auto-completing the passed object I18n name.
3377+ //! @param objPrefix the case insensitive first letters of the searched object
3378+ //! @param maxNbItem the maximum number of returned object names
3379+ //! @return a list of matching object name by order of relevance, or an empty list if nothing match
3380+ virtual QStringList listMatchingObjectsI18n(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const;
3381+ virtual QStringList listMatchingObjects(const QString& objPrefix, int maxNbItem=5, bool useStartOfWords=false) const;
3382+ virtual QStringList listAllObjects(bool inEnglish) const;
3383+ virtual QString getName() const
3384+ {
3385+ return "Meteor Showers";
3386+ }
3387+
3388+ //! get a ms object by identifier
3389+ MeteorShowerP getByID(const QString& id);
3390+
3391+ //! Implment this to tell the main Stellarium GUI that there is a GUI element to configure this
3392+ //! plugin.
3393+ virtual bool configureGui(bool show=true);
3394+
3395+ //! Set up the plugin with default values. This means clearing out the MeteorShower section in the
3396+ //! main config.ini (if one already exists), and populating it with default values. It also
3397+ //! creates the default showers.json file from the resource embedded in the plugin lib/dll file.
3398+ void restoreDefaults(void);
3399+
3400+ //! Read (or re-read) settings from the main config file. This will be called from init and also
3401+ //! when restoring defaults (i.e. from the configuration dialog / restore defaults button).
3402+ void readSettingsFromConfig(void);
3403+
3404+ //! Save the settings to the main configuration file.
3405+ void saveSettingsToConfig(void);
3406+
3407+ //! get whether or not the plugin will try to update TLE data from the internet
3408+ //! @return true if updates are set to be done, false otherwise
3409+ bool getUpdatesEnabled(void)
3410+ {
3411+ return updatesEnabled;
3412+ }
3413+ //! set whether or not the plugin will try to update TLE data from the internet
3414+ //! @param b if true, updates will be enabled, else they will be disabled
3415+ void setUpdatesEnabled(bool b)
3416+ {
3417+ updatesEnabled=b;
3418+ }
3419+
3420+ //! get the date and time the TLE elements were updated
3421+ QDateTime getLastUpdate(void)
3422+ {
3423+ return lastUpdate;
3424+ }
3425+
3426+ //! get the update frequency in hours
3427+ int getUpdateFrequencyHours(void)
3428+ {
3429+ return updateFrequencyHours;
3430+ }
3431+ void setUpdateFrequencyHours(int hours)
3432+ {
3433+ updateFrequencyHours = hours;
3434+ }
3435+
3436+ //! get the number of seconds till the next update
3437+ int getSecondsToUpdate(void);
3438+
3439+ //! Get the current updateState
3440+ UpdateState getUpdateState(void)
3441+ {
3442+ return updateState;
3443+ }
3444+
3445+ //! Get current color of active radiant based in generic data
3446+ QColor getColorARG()
3447+ {
3448+ return colorARG;
3449+ }
3450+ void setColorARG(QColor color)
3451+ {
3452+ colorARG = color;
3453+ }
3454+
3455+ //! Get current color of active radiant based in real data
3456+ QColor getColorARR()
3457+ {
3458+ return colorARR;
3459+ }
3460+ void setColorARR(QColor color)
3461+ {
3462+ colorARR = color;
3463+ }
3464+
3465+ //! Get current inactive radiant color
3466+ QColor getColorIR()
3467+ {
3468+ return colorIR;
3469+ }
3470+ void setColorIR(QColor color)
3471+ {
3472+ colorIR = color;
3473+ }
3474+
3475+ //! get the label font size.
3476+ //! @return the pixel size of the font
3477+ int getLabelFontSize()
3478+ {
3479+ return labelFont.pixelSize();
3480+ }
3481+
3482+ //! Get status of labels
3483+ //! @return false: hidden
3484+ bool getFlagLabels();
3485+
3486+ //! Get current sky date.
3487+ //! @return current sky date
3488+ QDateTime getSkyDate()
3489+ {
3490+ return skyDate;
3491+ }
3492+
3493+ //! Find all meteor_shower events in a given date interval
3494+ //! @param dateFrom
3495+ //! @param dateTo
3496+ //! @return meteor_shower list
3497+ QList<MeteorShowerP> searchEvents(QDate dateFrom, QDate dateTo) const;
3498+
3499+signals:
3500+ //! @param state the new update state.
3501+ void updateStateChanged(MeteorShowers::UpdateState state);
3502+
3503+ //! emitted after a JSON update has run.
3504+ void jsonUpdateComplete(void);
3505+
3506+public slots:
3507+ //! Download JSON from web recources described in the module section of the
3508+ //! module.ini file and update the local JSON file.
3509+ void updateJSON(void);
3510+
3511+ void setFlagShowMS(bool b);
3512+ bool getFlagShowMS(void)
3513+ {
3514+ return flagShowMS;
3515+ }
3516+
3517+ //! Display a message. This is used for plugin-specific warnings and such
3518+ void displayMessage(const QString& message, const QString hexColor="#999999");
3519+ void messageTimeout(void);
3520+
3521+ //! Define whether the button toggling meteor showers should be visible
3522+ void setFlagShowMSButton(bool b);
3523+ bool getFlagShowMSButton(void) { return flagShowMSButton; }
3524+
3525+ //! set the label font size.
3526+ //! @param size the pixel size of the font
3527+ void setLabelFontSize(int size);
3528+
3529+ //! Set whether text labels should be displayed next to radiant.
3530+ //! @param false: hidden
3531+ void setFlagLabels(bool b);
3532+
3533+ bool getFlagActiveRadiant(void) { return flagShowAR; }
3534+ void setFlagActiveRadiant(bool b) { flagShowAR=b; }
3535+
3536+ bool getEnableAtStartup(void) {return enableAtStartup;}
3537+ void setEnableAtStartup(bool b) {enableAtStartup=b;}
3538+
3539+ bool getFlagRadiant(void) const { return MeteorShower::radiantMarkerEnabled; }
3540+ void setFlagRadiant(bool b) { MeteorShower::radiantMarkerEnabled=b; }
3541+
3542+private:
3543+ // Upgrade config.ini: rename old key settings to new
3544+ void upgradeConfigIni(void);
3545+
3546+ //! Check if the sky date was changed
3547+ //! @param core
3548+ //! @return if changed, return true
3549+ bool changedSkyDate(StelCore* core);
3550+
3551+ //! Calculate value of ZHR using normal distribution
3552+ //! @param zhr
3553+ //! @param variable
3554+ //! @param start
3555+ //! @param finish
3556+ //! @param peak
3557+ int calculateZHR(int zhr, QString variable, QDateTime start, QDateTime finish, QDateTime peak);
3558+
3559+ //! Update the list with information about active meteors
3560+ //! @param core
3561+ void updateActiveInfo(void);
3562+
3563+ //! Set up the plugin with default values.
3564+ void restoreDefaultConfigIni(void);
3565+
3566+ //! replace the json file with the default from the compiled-in resource
3567+ void restoreDefaultJsonFile(void);
3568+
3569+ //! read the json file and create the meteor Showers.
3570+ void readJsonFile(void);
3571+
3572+ //! Creates a backup of the showers.json file called showers.json.old
3573+ //! @param deleteOriginal if true, the original file is removed, else not
3574+ //! @return true on OK, false on failure
3575+ bool backupJsonFile(bool deleteOriginal=false);
3576+
3577+ //! Get the version from the "version of format" value in the showers.json file
3578+ //! @return version, e.g. "1"
3579+ int getJsonFileFormatVersion(void);
3580+
3581+ //! Check format of the catalog of meteor showers
3582+ //! @return valid boolean, e.g. "true"
3583+ bool checkJsonFileFormat(void);
3584+
3585+ //! Parse JSON file and load showers to map
3586+ QVariantMap loadShowersMap(QString path=QString());
3587+
3588+ //! Set items for list of struct from data map
3589+ void setShowersMap(const QVariantMap& map);
3590+
3591+ //! A fake method for strings marked for translation.
3592+ //! Use it instead of translations.h for N_() strings, except perhaps for
3593+ //! keyboard action descriptions. (It's better for them to be in a single
3594+ //! place.)
3595+ static void translations();
3596+
3597+ //! Font used for displaying our text
3598+ QFont labelFont;
3599+
3600+ QString showersJsonPath;
3601+
3602+ StelTextureSP texPointer;
3603+ QList<MeteorShowerP> mShowers;
3604+
3605+ // GUI
3606+ MeteorShowerDialog* configDialog;
3607+ bool flagShowMS;
3608+ bool flagShowMSButton;
3609+ QPixmap* OnIcon;
3610+ QPixmap* OffIcon;
3611+ QPixmap* GlowIcon;
3612+ StelButton* toolbarButton;
3613+ QColor colorARR; //color of active radiant based on real data
3614+ QColor colorARG; //color of active radiant based on generic data
3615+ QColor colorIR; //color of inactive radiant
3616+
3617+ // variables and functions for the updater
3618+ UpdateState updateState;
3619+ QNetworkAccessManager* downloadMgr;
3620+ QString updateUrl;
3621+ QString updateFile;
3622+ class StelProgressController* progressBar;
3623+ QTimer* updateTimer;
3624+ QTimer* messageTimer;
3625+ QList<int> messageIDs;
3626+ bool updatesEnabled;
3627+ QDateTime lastUpdate;
3628+ int updateFrequencyHours;
3629+ bool enableAtStartup;
3630+
3631+ QSettings* conf;
3632+
3633+ //MS
3634+ std::vector<std::vector<MeteorStream*> > active; // Matrix containing all active meteors
3635+ int ZHR;
3636+ const static double zhrToWsr = 1.6667f/3600.f; // factor to convert from zhr to whole earth per second rate
3637+
3638+ bool flagShowAR; //! Show marker of active radiant
3639+
3640+ bool flagShow;
3641+ bool flagShowARG; //! Show marker of active radiant based on generic data
3642+ bool flagShowARR; //! Show marker of active radiant based on generic data
3643+ bool flagShowIR; //! Show marker of inactive radiant
3644+
3645+ bool flagShowStreamARG; //! Show meteor stream of active radiant based on generic data
3646+ bool flagShowStreamARR; //! Show meteor stream of active radiant based on generic data
3647+
3648+ typedef struct
3649+ {
3650+ QString showerID; //! The ID of the meteor shower
3651+ QDateTime start; //! First day for activity
3652+ QDateTime finish; //! Latest day for activity
3653+ QDateTime peak; //! Day with maximum for activity
3654+ int status; //! 0:inactive 1:activeRealData 2:activeGenericData
3655+ int zhr; //! ZHR of shower
3656+ QString variable; //! value of variable for ZHR
3657+ int speed; //! Speed of meteors
3658+ double radiantAlpha; //! R.A. for radiant of meteor shower
3659+ double radiantDelta; //! Dec. for radiant of meteor shower
3660+ } activeData;
3661+
3662+ QList<activeData> activeInfo; //! List of active meteors
3663+ QDateTime skyDate; //! Current sky date
3664+ QDateTime lastSkyDate; //! Last sky date
3665+
3666+private slots:
3667+ //! check to see if an update is required. This is called periodically by a timer
3668+ //! if the last update was longer than updateFrequencyHours ago then the update is
3669+ //! done.
3670+ void checkForUpdate(void);
3671+ void updateDownloadComplete(QNetworkReply* reply);
3672+};
3673+
3674+
3675+//#include "fixx11h.h"
3676+#include <QObject>
3677+#include "StelPluginInterface.hpp"
3678+
3679+//! This class is used by Qt to manage a plug-in interface
3680+class MeteorShowersStelPluginInterface : public QObject, public StelPluginInterface
3681+{
3682+ Q_OBJECT
3683+ Q_PLUGIN_METADATA(IID "stellarium.StelGuiPluginInterface/1.0")
3684+ Q_INTERFACES(StelPluginInterface)
3685+public:
3686+ virtual StelModule* getStelModule() const;
3687+ virtual StelPluginInfo getPluginInfo() const;
3688+};
3689+
3690+#endif /*METEORSHOWERS_HPP_*/
3691
3692=== added file 'plugins/MeteorShowers/src/MeteorStream.cpp'
3693--- plugins/MeteorShowers/src/MeteorStream.cpp 1970-01-01 00:00:00 +0000
3694+++ plugins/MeteorShowers/src/MeteorStream.cpp 2014-03-10 17:28:07 +0000
3695@@ -0,0 +1,239 @@
3696+/*
3697+ * Copyright (C) 2013 Marcos Cardinot
3698+ *
3699+ * This program is free software; you can redistribute it and/or
3700+ * modify it under the terms of the GNU General Public License
3701+ * as published by the Free Software Foundation; either version 2
3702+ * of the License, or (at your option) any later version.
3703+ *
3704+ * This program is distributed in the hope that it will be useful,
3705+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3706+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3707+ * GNU General Public License for more details.
3708+ *
3709+ * You should have received a copy of the GNU General Public License
3710+ * along with this program; if not, write to the Free Software
3711+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
3712+ */
3713+
3714+#include <cstdlib>
3715+#include "MeteorShowers.hpp"
3716+#include "MeteorStream.hpp"
3717+#include "StelCore.hpp"
3718+#include "StelUtils.hpp"
3719+
3720+#include "StelToneReproducer.hpp"
3721+#include "StelMovementMgr.hpp"
3722+#include "StelPainter.hpp"
3723+
3724+MeteorStream::MeteorStream(const StelCore* core, double velocity, double radiantAlpha, double radiantDelta)
3725+{
3726+ speed = velocity;
3727+
3728+ maxMag = 1; //start with the maximum mag
3729+
3730+ //the meteor starts dead, after we'll calculate the position
3731+ //if the position is within the bounds, this parameter will be changed to TRUE
3732+ alive = false;
3733+
3734+ double high_range = EARTH_RADIUS+HIGH_ALTITUDE;
3735+ double low_range = EARTH_RADIUS+LOW_ALTITUDE;
3736+
3737+ // view matrix of meteor model
3738+ viewMatrix = Mat4d::zrotation(radiantAlpha) * Mat4d::yrotation(M_PI_2 - radiantDelta);
3739+
3740+ // find observer position in meteor coordinate system
3741+ obs = core->altAzToJ2000(Vec3d(0,0,EARTH_RADIUS));
3742+ obs.transfo4d(viewMatrix.transpose());
3743+
3744+ // select random trajectory using polar coordinates in XY plane, centered on observer
3745+ xydistance = (double)rand() / ((double)RAND_MAX+1)*(VISIBLE_RADIUS);
3746+ double angle = (double)rand() / ((double)RAND_MAX+1)*2*M_PI;
3747+
3748+ // set meteor start x,y
3749+ position[0] = posInternal[0] = posTrain[0] = xydistance*cos(angle) + obs[0];
3750+ position[1] = posInternal[1] = posTrain[1] = xydistance*sin(angle) + obs[1];
3751+
3752+ // D is distance from center of earth
3753+ double D = sqrt(position[0]*position[0] + position[1]*position[1]);
3754+
3755+ if(D > high_range) // won't be visible, meteor still dead
3756+ {
3757+ return;
3758+ }
3759+
3760+ posTrain[2] = position[2] = startH = sqrt(high_range*high_range - D*D);
3761+
3762+ // determine end of burn point, and nearest point to observer for distance mag calculation
3763+ // mag should be max at nearest point still burning
3764+ endH = -startH; // earth grazing
3765+ minDist = xydistance;
3766+ if(D <= low_range)
3767+ {
3768+ endH = sqrt(low_range*low_range - D*D);
3769+ minDist = sqrt(xydistance*xydistance + pow(endH - obs[2], 2));
3770+ }
3771+
3772+ if(minDist > VISIBLE_RADIUS)
3773+ {
3774+ // on average, not visible (although if were zoomed ...)
3775+ return; //meteor still dead
3776+ }
3777+
3778+ //If everything is ok until here,
3779+ alive = true; //the meteor is alive
3780+ train = false; //and initially it is only a point
3781+
3782+ // Determine drawing color given magnitude and eye
3783+ // (won't be visible during daylight)
3784+
3785+ // *** color varies somewhat based on speed, plus atmosphere reddening
3786+
3787+ // determine intensity
3788+ float Mag1 = (double)rand()/((double)RAND_MAX+1)*6.75f - 3;
3789+ float Mag2 = (double)rand()/((double)RAND_MAX+1)*6.75f - 3;
3790+ float Mag = (Mag1 + Mag2)/2.0f;
3791+
3792+ mag = (5. + Mag) / 256.0;
3793+ if(mag>250) mag = mag - 256;
3794+
3795+ float term1 = std::exp(-0.92103f*(mag + 12.12331f)) * 108064.73f;
3796+
3797+ float cmag=1.f;
3798+ float rmag;
3799+
3800+ // Compute the equivalent star luminance for a 5 arc min circle and convert it
3801+ // in function of the eye adaptation
3802+ const StelToneReproducer* eye = core->getToneReproducer();
3803+ rmag = eye->adaptLuminanceScaled(term1);
3804+ rmag = rmag/powf(core->getMovementMgr()->getCurrentFov(),0.85f)*500.f;
3805+
3806+ // if size of star is too small (blink) we put its size to 1.2 --> no more blink
3807+ // And we compensate the difference of brighteness with cmag
3808+ if(rmag<1.2f)
3809+ {
3810+ cmag=rmag*rmag/1.44f;
3811+ }
3812+
3813+ mag = cmag; // assumes white
3814+
3815+ // most visible meteors are under about 180km distant
3816+ // scale max mag down if outside this range
3817+ float scale = 1;
3818+ if(minDist!=0) scale = 180*180/(minDist*minDist);
3819+ if(scale < 1) mag *= scale;
3820+}
3821+
3822+MeteorStream::~MeteorStream()
3823+{
3824+}
3825+
3826+// returns true if alive
3827+bool MeteorStream::update(double deltaTime)
3828+{
3829+ if(!alive)
3830+ return(0);
3831+
3832+ if(position[2] < endH)
3833+ {
3834+ // burning has stopped so magnitude fades out
3835+ // assume linear fade out
3836+
3837+ mag -= maxMag * deltaTime/500.0f;
3838+ if(mag < 0)
3839+ alive=0; // no longer visible
3840+
3841+ }
3842+
3843+ // *** would need time direction multiplier to allow reverse time replay
3844+ position[2] = position[2] - speed*deltaTime/1000.0f;
3845+
3846+ // train doesn't extend beyond start of burn
3847+ if(position[2] + speed*0.5f > startH)
3848+ {
3849+ posTrain[2] = startH ;
3850+ }
3851+ else
3852+ {
3853+ posTrain[2] -= speed*deltaTime/1000.0f;
3854+ }
3855+
3856+ // determine visual magnitude based on distance to observer
3857+ double dist = sqrt(xydistance*xydistance + pow(position[2]-obs[2], 2));
3858+
3859+ if(dist == 0) dist = .01; // just to be cautious (meteor hits observer!)
3860+
3861+ distMultiplier = minDist*minDist / (dist*dist);
3862+
3863+ return(alive);
3864+}
3865+
3866+
3867+// returns true if visible
3868+// Assumes that we are in local frame
3869+void MeteorStream::draw(const StelCore* core, StelPainter& sPainter)
3870+{
3871+ if(!alive)
3872+ return;
3873+
3874+ const StelProjectorP proj = sPainter.getProjector();
3875+
3876+ Vec3d spos = position;
3877+ Vec3d epos = posTrain;
3878+
3879+ // convert to equ
3880+ spos.transfo4d(viewMatrix);
3881+ epos.transfo4d(viewMatrix);
3882+
3883+ // convert to local and correct for earth radius
3884+ //[since equ and local coordinates in stellarium use same 0 point!]
3885+ spos = core->j2000ToAltAz(spos);
3886+ epos = core->j2000ToAltAz(epos);
3887+ spos[2] -= EARTH_RADIUS;
3888+ epos[2] -= EARTH_RADIUS;
3889+ // 1216 is to scale down under 1 for desktop version
3890+ spos/=1216;
3891+ epos/=1216;
3892+
3893+ if(train)
3894+ {
3895+ // connect this point with last drawn point
3896+ double tmag = mag*distMultiplier;
3897+
3898+ // compute an intermediate point so can curve slightly along projection distortions
3899+ Vec3d posi = posInternal;
3900+ posi[2] = position[2] + (posTrain[2] - position[2])/2;
3901+ posi.transfo4d(viewMatrix);
3902+ posi = core->j2000ToAltAz(posi);
3903+ posi[2] -= EARTH_RADIUS;
3904+ posi/=1216;
3905+
3906+ // draw dark to light
3907+ Vec4f colorArray[3];
3908+ colorArray[0].set(0,0,0,0);
3909+ colorArray[1].set(1,1,1,tmag*0.5);
3910+ colorArray[2].set(1,1,1,tmag);
3911+ Vec3d vertexArray[3];
3912+ vertexArray[0]=epos;
3913+ vertexArray[1]=posi;
3914+ vertexArray[2]=spos;
3915+ sPainter.setColorPointer(4, GL_FLOAT, colorArray);
3916+ sPainter.setVertexPointer(3, GL_DOUBLE, vertexArray);
3917+ sPainter.enableClientStates(true, false, true);
3918+ sPainter.drawFromArray(StelPainter::LineStrip, 3, 0, true);
3919+ sPainter.enableClientStates(false);
3920+ }
3921+ else
3922+ {
3923+ Vec3d start;
3924+ proj->project(spos, start);
3925+ sPainter.drawPoint2d(start[0],start[1]);
3926+ }
3927+
3928+ train = 1;
3929+}
3930+
3931+bool MeteorStream::isAlive(void)
3932+{
3933+ return(alive);
3934+}
3935
3936=== added file 'plugins/MeteorShowers/src/MeteorStream.hpp'
3937--- plugins/MeteorShowers/src/MeteorStream.hpp 1970-01-01 00:00:00 +0000
3938+++ plugins/MeteorShowers/src/MeteorStream.hpp 2014-03-10 17:28:07 +0000
3939@@ -0,0 +1,84 @@
3940+/*
3941+ * Copyright (C) 2013 Marcos Cardinot
3942+ *
3943+ * This program is free software; you can redistribute it and/or
3944+ * modify it under the terms of the GNU General Public License
3945+ * as published by the Free Software Foundation; either version 2
3946+ * of the License, or (at your option) any later version.
3947+ *
3948+ * This program is distributed in the hope that it will be useful,
3949+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3950+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3951+ * GNU General Public License for more details.
3952+ *
3953+ * You should have received a copy of the GNU General Public License
3954+ * along with this program; if not, write to the Free Software
3955+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
3956+ */
3957+
3958+#ifndef _METEORSTREAM_HPP_
3959+#define _METEORSTREAM_HPP_
3960+
3961+#include "VecMath.hpp"
3962+class StelCore;
3963+class StelPainter;
3964+
3965+// all in km - altitudes make up meteor range
3966+#define EARTH_RADIUS 6369.f
3967+#define VISIBLE_RADIUS 457.8f
3968+#define HIGH_ALTITUDE 115.f
3969+#define LOW_ALTITUDE 70.f
3970+
3971+//! @class MeteorStream
3972+//! Models a single meteor.
3973+//! Control of the meteor rate is performed in the MeteorShowers class. Once
3974+//! created, a meteor object only lasts for some amount of time, and then
3975+//! "dies", after which, the update() member returns false. The live/dead
3976+//! status of a meteor may also be determined using the isAlive member.
3977+class MeteorStream
3978+{
3979+public:
3980+ //! Create a Meteor object.
3981+ //! @param velocity the speed of the meteor in km/s.
3982+ //! @param rAlpha the radiant alpha in rad
3983+ //! @param rDelta the radiant delta in rad
3984+ MeteorStream(const StelCore*, double velocity, double radiantAlpha, double radiantDelta);
3985+ virtual ~MeteorStream();
3986+
3987+ //! Updates the position of the meteor, and expires it if necessary.
3988+ //! @return true of the meteor is still alive, else false.
3989+ bool update(double deltaTime);
3990+
3991+ //! Draws the meteor.
3992+ void draw(const StelCore* core, StelPainter& sPainter);
3993+
3994+ //! Determine if a meteor is alive or has burned out.
3995+ //! @return true if alive, else false.
3996+ bool isAlive(void);
3997+
3998+private:
3999+ bool alive; //! Indicate if the meteor it still visible
4000+ bool train; //! Indicate if the point or train is visible
4001+
4002+ Mat4d viewMatrix; //! View Matrix
4003+ Vec3d obs; //! Observer position
4004+ Vec3d position; //! Equatorial coordinate position
4005+ Vec3d posInternal; //! Middle of train
4006+ Vec3d posTrain; //! End of train
4007+
4008+ double speed; //! Velocity of meteor in km/s
4009+ double xydistance; //! Distance in XY plane (orthogonal to meteor path) from observer to meteor
4010+ double initDist; //! Initial distance from observer
4011+ double minDist; //! Nearest point to observer along path
4012+ double distMultiplier; //! Scale magnitude due to changes in distance
4013+
4014+ double startH; //! Start height above center of earth
4015+ double endH; //! End height
4016+
4017+ float mag; //! Apparent magnitude at head, 0-1
4018+ float maxMag; //! 0-1
4019+ float absMag; //! Absolute magnitude
4020+ float visMag; //! Visual magnitude at observer
4021+};
4022+
4023+#endif // _METEORSTREAM_HPP_
4024
4025=== added directory 'plugins/MeteorShowers/src/gui'
4026=== added file 'plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp'
4027--- plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp 1970-01-01 00:00:00 +0000
4028+++ plugins/MeteorShowers/src/gui/MeteorShowerDialog.cpp 2014-03-10 17:28:07 +0000
4029@@ -0,0 +1,389 @@
4030+/*
4031+ * Stellarium Meteor Shower plugin config dialog
4032+ *
4033+ * Copyright (C) 2013 Marcos Cardinot
4034+ * Copyright (C) 2011 Alexander Wolf
4035+ *
4036+ * This program is free software; you can redistribute it and/or
4037+ * modify it under the terms of the GNU General Public License
4038+ * as published by the Free Software Foundation; either version 2
4039+ * of the License, or (at your option) any later version.
4040+ *
4041+ * This program is distributed in the hope that it will be useful,
4042+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4043+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4044+ * GNU General Public License for more details.
4045+ *
4046+ * You should have received a copy of the GNU General Public License
4047+ * along with this program; if not, write to the Free Software
4048+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
4049+*/
4050+
4051+#include <QColorDialog>
4052+#include <QDateTime>
4053+#include <QDebug>
4054+#include <QFileDialog>
4055+#include <QGraphicsColorizeEffect>
4056+#include <QMessageBox>
4057+#include <QTimer>
4058+#include <QUrl>
4059+
4060+#include "MeteorShowerDialog.hpp"
4061+#include "MeteorShowers.hpp"
4062+#include "StelApp.hpp"
4063+#include "StelCore.hpp"
4064+#include "StelFileMgr.hpp"
4065+#include "StelGui.hpp"
4066+#include "StelMainView.hpp"
4067+#include "StelModuleMgr.hpp"
4068+#include "StelMovementMgr.hpp"
4069+#include "StelObjectMgr.hpp"
4070+#include "StelStyle.hpp"
4071+#include "StelTranslator.hpp"
4072+#include "StelUtils.hpp"
4073+#include "ui_meteorShowerDialog.h"
4074+
4075+MeteorShowerDialog::MeteorShowerDialog() : updateTimer(NULL)
4076+{
4077+ ui = new Ui_meteorShowerDialog;
4078+}
4079+
4080+MeteorShowerDialog::~MeteorShowerDialog()
4081+{
4082+ if (updateTimer)
4083+ {
4084+ updateTimer->stop();
4085+ delete updateTimer;
4086+ updateTimer = NULL;
4087+ }
4088+ delete ui;
4089+}
4090+
4091+void MeteorShowerDialog::retranslate()
4092+{
4093+ if (dialog)
4094+ {
4095+ ui->retranslateUi(dialog);
4096+ refreshUpdateValues();
4097+ setAboutHtml();
4098+ setHeaderNames();
4099+
4100+ //Retranslate name and datatype strings
4101+ QTreeWidgetItemIterator it(treeWidget);
4102+ while (*it) {
4103+ //Name
4104+ (*it)->setText(ColumnName, q_((*it)->text(ColumnName)));
4105+ //Data type
4106+ (*it)->setText(ColumnDataType, q_((*it)->text(ColumnDataType)));
4107+ ++it;
4108+ }
4109+ }
4110+}
4111+
4112+// Initialize the dialog widgets and connect the signals/slots
4113+void MeteorShowerDialog::createDialogContent()
4114+{
4115+ ui->setupUi(dialog);
4116+ ui->tabs->setCurrentIndex(0);
4117+ connect(&StelApp::getInstance(), SIGNAL(languageChanged()), this, SLOT(retranslate()));
4118+ plugin = GETSTELMODULE(MeteorShowers);
4119+
4120+ // Settings tab / updates group
4121+ connect(ui->internetUpdates, SIGNAL(clicked(bool)), this, SLOT(setUpdatesEnabled(bool)));
4122+ connect(ui->updateButton, SIGNAL(clicked()), this, SLOT(updateJSON()));
4123+ connect(plugin, SIGNAL(updateStateChanged(MeteorShowers::UpdateState)), this, SLOT(updateStateReceiver(MeteorShowers::UpdateState)));
4124+ connect(plugin, SIGNAL(jsonUpdateComplete(void)), this, SLOT(updateCompleteReceiver(void)));
4125+ connect(ui->updateFrequencySpinBox, SIGNAL(valueChanged(int)), this, SLOT(setUpdateValues(int)));
4126+ refreshUpdateValues(); // fetch values for last updated and so on
4127+
4128+ updateTimer = new QTimer(this);
4129+ connect(updateTimer, SIGNAL(timeout()), this, SLOT(refreshUpdateValues()));
4130+ updateTimer->start(7000);
4131+
4132+ // Settings tab / event group
4133+ connect(ui->searchButton, SIGNAL(clicked()), this, SLOT(checkDates()));
4134+ refreshRangeDates();
4135+
4136+ treeWidget = ui->listEvents;
4137+ initListEvents();
4138+ connect(treeWidget, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(selectEvent(QModelIndex)));
4139+
4140+ // Settings tab / radiant group
4141+ ui->displayRadiant->setChecked(plugin->getFlagRadiant());
4142+ connect(ui->displayRadiant, SIGNAL(clicked(bool)), plugin, SLOT(setFlagRadiant(bool)));
4143+ ui->activeRadiantsOnly->setChecked(plugin->getFlagActiveRadiant());
4144+ connect(ui->activeRadiantsOnly, SIGNAL(clicked(bool)), plugin, SLOT(setFlagActiveRadiant(bool)));
4145+ ui->radiantLabels->setChecked(plugin->getFlagLabels());
4146+ connect(ui->radiantLabels, SIGNAL(clicked(bool)), plugin, SLOT(setFlagLabels(bool)));
4147+ ui->fontSizeSpinBox->setValue(plugin->getLabelFontSize());
4148+ connect(ui->fontSizeSpinBox, SIGNAL(valueChanged(int)), plugin, SLOT(setLabelFontSize(int)));
4149+
4150+ // Settings tab / meteor showers group
4151+ ui->displayMeteorShower->setChecked(plugin->getEnableAtStartup());
4152+ connect(ui->displayMeteorShower, SIGNAL(clicked(bool)), plugin, SLOT(setEnableAtStartup(bool)));
4153+ ui->displayShowMeteorShowerButton->setChecked(plugin->getFlagShowMSButton());
4154+ connect(ui->displayShowMeteorShowerButton, SIGNAL(clicked(bool)), plugin, SLOT(setFlagShowMSButton(bool)));
4155+
4156+ // /////////////////////////////////////////
4157+
4158+ connect(ui->closeStelWindow, SIGNAL(clicked()), this, SLOT(close()));
4159+
4160+ connect(ui->restoreDefaultsButton, SIGNAL(clicked()), this, SLOT(restoreDefaults()));
4161+ connect(ui->saveSettingsButton, SIGNAL(clicked()), this, SLOT(saveSettings()));
4162+
4163+ // Markers tab
4164+ refreshColorMarkers();
4165+ connect(ui->changeColorARG, SIGNAL(clicked()), this, SLOT(setColorARG()));
4166+ connect(ui->changeColorARR, SIGNAL(clicked()), this, SLOT(setColorARR()));
4167+ connect(ui->changeColorIR, SIGNAL(clicked()), this, SLOT(setColorIR()));
4168+
4169+ // About tab
4170+ setAboutHtml();
4171+ StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
4172+ Q_ASSERT(gui);
4173+ ui->aboutTextBrowser->document()->setDefaultStyleSheet(QString(gui->getStelStyle().htmlStyleSheet));
4174+
4175+ updateGuiFromSettings();
4176+}
4177+
4178+void MeteorShowerDialog::initListEvents(void)
4179+{
4180+ treeWidget->clear();
4181+ treeWidget->setColumnCount(ColumnCount);
4182+ setHeaderNames();
4183+ treeWidget->header()->setSectionsMovable(false);
4184+ treeWidget->header()->setStretchLastSection(true);
4185+}
4186+
4187+void MeteorShowerDialog::setHeaderNames(void)
4188+{
4189+ QStringList headerStrings;
4190+ headerStrings << q_("Name");
4191+ headerStrings << q_("ZHR");
4192+ headerStrings << q_("Data Type");
4193+ headerStrings << q_("Peak");
4194+ treeWidget->setHeaderLabels(headerStrings);
4195+}
4196+
4197+void MeteorShowerDialog::checkDates(void)
4198+{
4199+ double jdFrom = StelUtils::qDateTimeToJd((QDateTime) ui->dateFrom->date());
4200+ double jdTo = StelUtils::qDateTimeToJd((QDateTime) ui->dateTo->date());
4201+
4202+ if(jdFrom > jdTo)
4203+ QMessageBox::warning(0, "Stellarium", q_("Start date greater than end date!"));
4204+ else if (jdTo-jdFrom > 365)
4205+ QMessageBox::warning(0, "Stellarium", q_("Time interval must be less than one year!"));
4206+ else
4207+ searchEvents();
4208+}
4209+
4210+void MeteorShowerDialog::searchEvents(void)
4211+{
4212+ QList<MeteorShowerP> searchResult = plugin->searchEvents(ui->dateFrom->date(), ui->dateTo->date());
4213+
4214+ //Fill list of events
4215+ initListEvents();
4216+ foreach(const MeteorShowerP& r, searchResult)
4217+ {
4218+ TreeWidgetItem *treeItem = new TreeWidgetItem(treeWidget);
4219+ //Name
4220+ treeItem->setText(ColumnName, r->getNameI18n());
4221+ //ZHR
4222+ QString zhr = r->getZHR()==-1?q_("Variable"):QString::number(r->getZHR());
4223+ treeItem->setText(ColumnZHR, zhr);
4224+ //Data Type
4225+ QString dataType = r->getStatus()==1?q_("Real"):q_("Generic");
4226+ treeItem->setText(ColumnDataType, dataType);
4227+ //Peak
4228+ QString peak = r->getPeak().toString("dd/MMM/yyyy");
4229+ treeItem->setText(ColumnPeak, peak);
4230+ }
4231+}
4232+
4233+void MeteorShowerDialog::selectEvent(const QModelIndex &modelIndex)
4234+{
4235+ StelCore *core = StelApp::getInstance().getCore();
4236+
4237+ //Change date
4238+ QString dateString = treeWidget->currentItem()->text(ColumnPeak);
4239+ QDateTime qDateTime = QDateTime::fromString(dateString, "dd/MMM/yyyy");
4240+ core->setJDay(StelUtils::qDateTimeToJd(qDateTime));
4241+
4242+ //Select object
4243+ QString namel18n = treeWidget->currentItem()->text(ColumnName);
4244+ StelObjectMgr* objectMgr = GETSTELMODULE(StelObjectMgr);
4245+ if((objectMgr->findAndSelectI18n(namel18n) || objectMgr->findAndSelect(namel18n)) && plugin->getFlagShowMS())
4246+ {
4247+ //Move to object
4248+ StelMovementMgr* mvmgr = GETSTELMODULE(StelMovementMgr);
4249+ mvmgr->moveToObject(objectMgr->getSelectedObject()[0], mvmgr->getAutoMoveDuration());
4250+ mvmgr->setFlagTracking(true);
4251+ }
4252+}
4253+
4254+void MeteorShowerDialog::refreshRangeDates(void)
4255+{
4256+ int year = plugin->getSkyDate().toString("yyyy").toInt();
4257+ ui->dateFrom->setDate(QDate(year, 1, 1)); // first date in the range - first day of the year
4258+ ui->dateTo->setDate(QDate(year, 12, 31)); // second date in the range - last day of the year
4259+}
4260+
4261+void MeteorShowerDialog::setAboutHtml(void)
4262+{
4263+ QString html = "<html><head></head><body>";
4264+ html += "<h2>" + q_("Meteor Showers Plugin") + "</h2><table width=\"90%\">";
4265+ html += "<tr width=\"30%\"><td>" + q_("Version:") + "</td><td>" + METEORSHOWERS_PLUGIN_VERSION + "</td></tr>";
4266+ html += "<tr><td>" + q_("Author:") + "</td><td>Marcos Cardinot &lt;mcardinot@gmail.com&gt;</td></tr></table>";
4267+
4268+ 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>";
4269+ html += "<h3>" + q_("Terms") + "</h3>";
4270+ html += "<p><b>" + q_("Meteor shower") + "</b>";
4271+ 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>";
4272+ html += "<p><b>" + q_("Radiant") + "</b>";
4273+ 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>";
4274+ 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>";
4275+ 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>";
4276+ html += "<p><b>" + q_("Zenithal Hourly Rate (ZHR)") + "</b>";
4277+ 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>";
4278+ html += "<p><b>" + q_("Population index") + "</b>";
4279+ 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>";
4280+ html += "<h3>" + q_("Notes") + "</h3>";
4281+ html += "<p>" + q_("This plugin was created as project of ESA Summer of Code in Space 2013.") + "</p>";
4282+ html += "<h3>" + q_("Info") + "</h3>";
4283+ html += "<p>" + q_("Info about meteor showers you can get here:") + "</p>";
4284+ html += "<ul>";
4285+ html += "<li>" + QString(q_("%1Meteor shower%2 - article in Wikipedia").arg("<a href=\"https://en.wikipedia.org/wiki/Meteor_Showers\">")).arg("</a>") + "</li>";
4286+ html += "<li>" + QString(q_("%1International Meteor Organization%2").arg("<a href=\"http://www.imo.net/\">")).arg("</a>") + "</li>";
4287+ html += "</ul>";
4288+ html += "<h3>" + q_("Links") + "</h3>";
4289+ 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>";
4290+ html += "<ul>";
4291+ // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
4292+ 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>";
4293+ // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
4294+ html += "<li>" + QString(q_("Bug reports can be made %1here%2.")).arg("<a href=\"https://bugs.launchpad.net/stellarium\">").arg("</a>") + "</li>";
4295+ // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
4296+ 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>";
4297+ // TRANSLATORS: The numbers contain the opening and closing tag of an HTML link
4298+ 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>";
4299+ html += "</ul></body></html>";
4300+
4301+ ui->aboutTextBrowser->setHtml(html);
4302+}
4303+
4304+void MeteorShowerDialog::refreshUpdateValues(void)
4305+{
4306+ ui->lastUpdateDateTimeEdit->setDateTime(plugin->getLastUpdate());
4307+ ui->updateFrequencySpinBox->setValue(plugin->getUpdateFrequencyHours());
4308+ int secondsToUpdate = plugin->getSecondsToUpdate();
4309+ if (!plugin->getUpdatesEnabled())
4310+ ui->nextUpdateLabel->setText(q_("Internet updates disabled"));
4311+ else if (plugin->getUpdateState() == MeteorShowers::Updating)
4312+ ui->nextUpdateLabel->setText(q_("Updating now..."));
4313+ else if (secondsToUpdate <= 60)
4314+ ui->nextUpdateLabel->setText(q_("Next update: < 1 minute"));
4315+ else if (secondsToUpdate < 3600)
4316+ ui->nextUpdateLabel->setText(QString(q_("Next update: %1 minutes")).arg((secondsToUpdate/60)+1));
4317+ else
4318+ ui->nextUpdateLabel->setText(QString(q_("Next update: %1 hours")).arg((secondsToUpdate/3600)+1));
4319+}
4320+
4321+void MeteorShowerDialog::setUpdateValues(int hours)
4322+{
4323+ plugin->setUpdateFrequencyHours(hours);
4324+ refreshUpdateValues();
4325+}
4326+
4327+void MeteorShowerDialog::setUpdatesEnabled(bool checkState)
4328+{
4329+ plugin->setUpdatesEnabled(checkState);
4330+ ui->updateFrequencySpinBox->setEnabled(checkState);
4331+ ui->updateButton->setText(q_("Update now"));
4332+ refreshUpdateValues();
4333+}
4334+
4335+
4336+void MeteorShowerDialog::updateStateReceiver(MeteorShowers::UpdateState state)
4337+{
4338+ //qDebug() << "MeteorShowerDialog::updateStateReceiver got a signal";
4339+ if (state==MeteorShowers::Updating)
4340+ ui->nextUpdateLabel->setText(q_("Updating now..."));
4341+ else if (state==MeteorShowers::DownloadError || state==MeteorShowers::OtherError)
4342+ {
4343+ ui->nextUpdateLabel->setText(q_("Update error"));
4344+ updateTimer->start(); // make sure message is displayed for a while...
4345+ }
4346+}
4347+
4348+void MeteorShowerDialog::updateCompleteReceiver(void)
4349+{
4350+ ui->nextUpdateLabel->setText(QString(q_("Meteor showers is updated")));
4351+ // display the status for another full interval before refreshing status
4352+ updateTimer->start();
4353+ ui->lastUpdateDateTimeEdit->setDateTime(GETSTELMODULE(MeteorShowers)->getLastUpdate());
4354+ QTimer *timer = new QTimer(this);
4355+ connect(timer, SIGNAL(timeout()), this, SLOT(refreshUpdateValues()));
4356+}
4357+
4358+void MeteorShowerDialog::restoreDefaults(void)
4359+{
4360+ qDebug() << "MeteorShowers::restoreDefaults";
4361+ plugin->restoreDefaults();
4362+ plugin->readSettingsFromConfig();
4363+ updateGuiFromSettings();
4364+}
4365+
4366+void MeteorShowerDialog::updateGuiFromSettings(void)
4367+{
4368+ refreshUpdateValues();
4369+ refreshColorMarkers();
4370+}
4371+
4372+void MeteorShowerDialog::saveSettings(void)
4373+{
4374+ plugin->saveSettingsToConfig();
4375+}
4376+
4377+void MeteorShowerDialog::updateJSON(void)
4378+{
4379+ if(plugin->getUpdatesEnabled())
4380+ {
4381+ plugin->updateJSON();
4382+ }
4383+}
4384+
4385+void MeteorShowerDialog::refreshColorMarkers(void)
4386+{
4387+ setTextureColor(ui->textureARG, plugin->getColorARG());
4388+ setTextureColor(ui->textureARR, plugin->getColorARR());
4389+ setTextureColor(ui->textureIR, plugin->getColorIR());
4390+}
4391+
4392+void MeteorShowerDialog::setTextureColor(QLabel *texture, QColor color)
4393+{
4394+ QGraphicsColorizeEffect *e = new QGraphicsColorizeEffect(texture);
4395+ e->setColor(color);
4396+ texture->setGraphicsEffect(e);
4397+}
4398+
4399+void MeteorShowerDialog::setColorARG()
4400+{
4401+ QColor color = QColorDialog::getColor();
4402+ setTextureColor(ui->textureARG, color);
4403+ plugin->setColorARG(color);
4404+}
4405+
4406+void MeteorShowerDialog::setColorARR()
4407+{
4408+ QColor color = QColorDialog::getColor();
4409+ setTextureColor(ui->textureARR, color);
4410+ plugin->setColorARR(color);
4411+}
4412+
4413+void MeteorShowerDialog::setColorIR()
4414+{
4415+ QColor color = QColorDialog::getColor();
4416+ setTextureColor(ui->textureIR, color);
4417+ plugin->setColorIR(color);
4418+}
4419
4420=== added file 'plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp'
4421--- plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp 1970-01-01 00:00:00 +0000
4422+++ plugins/MeteorShowers/src/gui/MeteorShowerDialog.hpp 2014-03-10 17:28:07 +0000
4423@@ -0,0 +1,111 @@
4424+/*
4425+ * Stellarium Meteor Shower Plug-in GUI
4426+ *
4427+ * Copyright (C) 2013 Marcos Cardinot
4428+ * Copyright (C) 2011 Alexander Wolf
4429+ *
4430+ * This program is free software; you can redistribute it and/or
4431+ * modify it under the terms of the GNU General Public License
4432+ * as published by the Free Software Foundation; either version 2
4433+ * of the License, or (at your option) any later version.
4434+ *
4435+ * This program is distributed in the hope that it will be useful,
4436+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4437+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4438+ * GNU General Public License for more details.
4439+ *
4440+ * You should have received a copy of the GNU General Public License
4441+ * along with this program; if not, write to the Free Software
4442+ * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
4443+*/
4444+
4445+#ifndef _METEORSHOWERDIALOG_HPP_
4446+#define _METEORSHOWERDIALOG_HPP_
4447+
4448+#include <QColor>
4449+#include <QLabel>
4450+#include <QObject>
4451+#include <QTreeWidget>
4452+
4453+#include "MeteorShowers.hpp"
4454+#include "StelDialog.hpp"
4455+
4456+class MeteorShowers;
4457+class QTimer;
4458+class Ui_meteorShowerDialog;
4459+
4460+class MeteorShowerDialog : public StelDialog
4461+{
4462+ Q_OBJECT
4463+
4464+public:
4465+ MeteorShowerDialog();
4466+ ~MeteorShowerDialog();
4467+
4468+protected:
4469+ //! Initialize the dialog widgets and connect the signals/slots
4470+ void createDialogContent();
4471+
4472+public slots:
4473+ void retranslate();
4474+ void refreshUpdateValues(void); //! Refresh details about the last update
4475+ void refreshColorMarkers(void); //! Refresh the color of all markers
4476+ void refreshRangeDates(void); //! Refresh dates range when year in main app change
4477+
4478+private slots:
4479+ void setUpdateValues(int hours);
4480+ void setUpdatesEnabled(bool checkState);
4481+ void updateStateReceiver(MeteorShowers::UpdateState state);
4482+ void updateCompleteReceiver();
4483+ void restoreDefaults(void);
4484+ void saveSettings(void);
4485+ void updateJSON(void);
4486+ void setColorARR(void); //! Set color of active radiant based on real data.
4487+ void setColorARG(void); //! Set color of active radiant based on generic data.
4488+ void setColorIR(void); //! Set color of inactive radiant.
4489+ void checkDates(void); //! Checks if the inputed dates are valid for use.
4490+ void searchEvents(void); //! Search events and fill the list.
4491+ void selectEvent(const QModelIndex &modelIndex); //! If an event is selected by user, the current date change and the object is selected.
4492+
4493+private:
4494+ Ui_meteorShowerDialog* ui;
4495+ MeteorShowers* plugin;
4496+ void setAboutHtml(void);
4497+ void updateGuiFromSettings(void);
4498+ QTimer* updateTimer;
4499+ void setTextureColor(QLabel* texture, QColor color);
4500+
4501+ //! Defines the number and the order of the columns in the table that lists active meteor showers
4502+ //! @enum ModelColumns
4503+ enum ModelColumns {
4504+ ColumnName, //! name column
4505+ ColumnZHR, //! zhr column
4506+ ColumnDataType, //! data type column
4507+ ColumnPeak, //! peak date column
4508+ ColumnCount //! total number of columns
4509+ };
4510+ QTreeWidget* treeWidget; //! list of events
4511+ void initListEvents(void); //! Init header and list of events
4512+ void setHeaderNames(void); //! Update header names
4513+
4514+ // Reimplementation of QTreeWidgetItem class to fix the sorting bug
4515+ class TreeWidgetItem : public QTreeWidgetItem
4516+ {
4517+ public:
4518+ TreeWidgetItem(QTreeWidget* parent):QTreeWidgetItem(parent){}
4519+
4520+ private:
4521+ bool operator<(const QTreeWidgetItem &other)const {
4522+ int column = treeWidget()->sortColumn();
4523+
4524+ if (column == ColumnPeak)
4525+ return QDateTime::fromString(text(column),"dd/MMM/yyyy").operator <(QDateTime::fromString(other.text(column),"dd/MMM/yyyy"));
4526+ else if (column == ColumnZHR)
4527+ return text(column).toInt() < other.text(column).toInt();
4528+ else //ColumnName or ColumnDataType
4529+ return text(column).toLower() < other.text(column).toLower();
4530+ }
4531+ };
4532+};
4533+
4534+#endif // _METEORSHOWERDIALOG_HPP_
4535
4536=== added file 'plugins/MeteorShowers/src/gui/meteorShowerDialog.ui'
4537--- plugins/MeteorShowers/src/gui/meteorShowerDialog.ui 1970-01-01 00:00:00 +0000
4538+++ plugins/MeteorShowers/src/gui/meteorShowerDialog.ui 2014-03-10 17:28:07 +0000
4539@@ -0,0 +1,867 @@
4540+<?xml version="1.0" encoding="UTF-8"?>
4541+<ui version="4.0">
4542+ <class>meteorShowerDialog</class>
4543+ <widget class="QWidget" name="meteorShowerDialog">
4544+ <property name="geometry">
4545+ <rect>
4546+ <x>0</x>
4547+ <y>0</y>
4548+ <width>530</width>
4549+ <height>404</height>
4550+ </rect>
4551+ </property>
4552+ <property name="windowTitle">
4553+ <string>Meteor Showers Configuration</string>
4554+ </property>
4555+ <layout class="QVBoxLayout" name="verticalLayout_2">
4556+ <property name="spacing">
4557+ <number>0</number>
4558+ </property>
4559+ <property name="leftMargin">
4560+ <number>0</number>
4561+ </property>
4562+ <property name="topMargin">
4563+ <number>0</number>
4564+ </property>
4565+ <property name="rightMargin">
4566+ <number>0</number>
4567+ </property>
4568+ <property name="bottomMargin">
4569+ <number>0</number>
4570+ </property>
4571+ <item>
4572+ <widget class="BarFrame" name="TitleBar">
4573+ <property name="sizePolicy">
4574+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
4575+ <horstretch>0</horstretch>
4576+ <verstretch>0</verstretch>
4577+ </sizepolicy>
4578+ </property>
4579+ <property name="minimumSize">
4580+ <size>
4581+ <width>530</width>
4582+ <height>25</height>
4583+ </size>
4584+ </property>
4585+ <property name="maximumSize">
4586+ <size>
4587+ <width>16777215</width>
4588+ <height>25</height>
4589+ </size>
4590+ </property>
4591+ <property name="focusPolicy">
4592+ <enum>Qt::NoFocus</enum>
4593+ </property>
4594+ <property name="autoFillBackground">
4595+ <bool>false</bool>
4596+ </property>
4597+ <property name="frameShape">
4598+ <enum>QFrame::StyledPanel</enum>
4599+ </property>
4600+ <layout class="QHBoxLayout">
4601+ <property name="spacing">
4602+ <number>0</number>
4603+ </property>
4604+ <property name="leftMargin">
4605+ <number>0</number>
4606+ </property>
4607+ <property name="topMargin">
4608+ <number>0</number>
4609+ </property>
4610+ <property name="rightMargin">
4611+ <number>4</number>
4612+ </property>
4613+ <property name="bottomMargin">
4614+ <number>0</number>
4615+ </property>
4616+ <item>
4617+ <spacer>
4618+ <property name="orientation">
4619+ <enum>Qt::Horizontal</enum>
4620+ </property>
4621+ <property name="sizeHint" stdset="0">
4622+ <size>
4623+ <width>40</width>
4624+ <height>20</height>
4625+ </size>
4626+ </property>
4627+ </spacer>
4628+ </item>
4629+ <item>
4630+ <widget class="QLabel" name="stelWindowTitle">
4631+ <property name="text">
4632+ <string>Meteor Showers Plug-in Configuration</string>
4633+ </property>
4634+ </widget>
4635+ </item>
4636+ <item>
4637+ <spacer>
4638+ <property name="orientation">
4639+ <enum>Qt::Horizontal</enum>
4640+ </property>
4641+ <property name="sizeHint" stdset="0">
4642+ <size>
4643+ <width>40</width>
4644+ <height>20</height>
4645+ </size>
4646+ </property>
4647+ </spacer>
4648+ </item>
4649+ <item>
4650+ <widget class="QPushButton" name="closeStelWindow">
4651+ <property name="minimumSize">
4652+ <size>
4653+ <width>16</width>
4654+ <height>16</height>
4655+ </size>
4656+ </property>
4657+ <property name="maximumSize">
4658+ <size>
4659+ <width>16</width>
4660+ <height>16</height>
4661+ </size>
4662+ </property>
4663+ <property name="focusPolicy">
4664+ <enum>Qt::NoFocus</enum>
4665+ </property>
4666+ <property name="text">
4667+ <string/>
4668+ </property>
4669+ </widget>
4670+ </item>
4671+ </layout>
4672+ </widget>
4673+ </item>
4674+ <item>
4675+ <widget class="QTabWidget" name="tabs">
4676+ <property name="currentIndex">
4677+ <number>2</number>
4678+ </property>
4679+ <property name="documentMode">
4680+ <bool>false</bool>
4681+ </property>
4682+ <widget class="QWidget" name="settingsTab">
4683+ <attribute name="title">
4684+ <string>Settings</string>
4685+ </attribute>
4686+ <layout class="QVBoxLayout" name="verticalLayout_3">
4687+ <item>
4688+ <widget class="QGroupBox" name="internetUpdates">
4689+ <property name="title">
4690+ <string>Update data from Internet</string>
4691+ </property>
4692+ <property name="flat">
4693+ <bool>true</bool>
4694+ </property>
4695+ <property name="checkable">
4696+ <bool>true</bool>
4697+ </property>
4698+ <property name="checked">
4699+ <bool>true</bool>
4700+ </property>
4701+ <layout class="QVBoxLayout" name="verticalLayout_12">
4702+ <item>
4703+ <layout class="QGridLayout" name="gridLayout">
4704+ <item row="0" column="0">
4705+ <widget class="QLabel" name="lastUpdateLabel">
4706+ <property name="text">
4707+ <string>Last update:</string>
4708+ </property>
4709+ </widget>
4710+ </item>
4711+ <item row="0" column="2">
4712+ <widget class="QDateTimeEdit" name="lastUpdateDateTimeEdit">
4713+ <property name="enabled">
4714+ <bool>false</bool>
4715+ </property>
4716+ <property name="sizePolicy">
4717+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
4718+ <horstretch>0</horstretch>
4719+ <verstretch>0</verstretch>
4720+ </sizepolicy>
4721+ </property>
4722+ <property name="frame">
4723+ <bool>false</bool>
4724+ </property>
4725+ <property name="buttonSymbols">
4726+ <enum>QAbstractSpinBox::NoButtons</enum>
4727+ </property>
4728+ </widget>
4729+ </item>
4730+ <item row="1" column="0">
4731+ <widget class="QLabel" name="updateFrequencyLabel">
4732+ <property name="text">
4733+ <string>Update frequency (hours):</string>
4734+ </property>
4735+ </widget>
4736+ </item>
4737+ <item row="1" column="2">
4738+ <widget class="QSpinBox" name="updateFrequencySpinBox">
4739+ <property name="sizePolicy">
4740+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
4741+ <horstretch>0</horstretch>
4742+ <verstretch>0</verstretch>
4743+ </sizepolicy>
4744+ </property>
4745+ <property name="minimum">
4746+ <number>1</number>
4747+ </property>
4748+ <property name="maximum">
4749+ <number>9999</number>
4750+ </property>
4751+ <property name="value">
4752+ <number>1</number>
4753+ </property>
4754+ </widget>
4755+ </item>
4756+ <item row="2" column="0">
4757+ <widget class="QLabel" name="nextUpdateLabel">
4758+ <property name="text">
4759+ <string>[next update info]</string>
4760+ </property>
4761+ </widget>
4762+ </item>
4763+ <item row="2" column="1">
4764+ <spacer name="horizontalSpacer">
4765+ <property name="orientation">
4766+ <enum>Qt::Horizontal</enum>
4767+ </property>
4768+ <property name="sizeHint" stdset="0">
4769+ <size>
4770+ <width>17</width>
4771+ <height>20</height>
4772+ </size>
4773+ </property>
4774+ </spacer>
4775+ </item>
4776+ <item row="2" column="2">
4777+ <widget class="QPushButton" name="updateButton">
4778+ <property name="sizePolicy">
4779+ <sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
4780+ <horstretch>0</horstretch>
4781+ <verstretch>0</verstretch>
4782+ </sizepolicy>
4783+ </property>
4784+ <property name="text">
4785+ <string>Update now</string>
4786+ </property>
4787+ </widget>
4788+ </item>
4789+ </layout>
4790+ </item>
4791+ </layout>
4792+ </widget>
4793+ </item>
4794+ <item>
4795+ <widget class="QGroupBox" name="displayMeteorShowerBox">
4796+ <property name="toolTip">
4797+ <string/>
4798+ </property>
4799+ <property name="title">
4800+ <string>Meteor showers</string>
4801+ </property>
4802+ <property name="flat">
4803+ <bool>true</bool>
4804+ </property>
4805+ <property name="checkable">
4806+ <bool>false</bool>
4807+ </property>
4808+ <layout class="QGridLayout" name="gridLayout_8">
4809+ <item row="1" column="0">
4810+ <widget class="QCheckBox" name="displayShowMeteorShowerButton">
4811+ <property name="text">
4812+ <string>Show meteor showers button on toolbar</string>
4813+ </property>
4814+ </widget>
4815+ </item>
4816+ <item row="0" column="0">
4817+ <widget class="QCheckBox" name="displayMeteorShower">
4818+ <property name="text">
4819+ <string>Enable display of meteor showers at startup</string>
4820+ </property>
4821+ </widget>
4822+ </item>
4823+ </layout>
4824+ </widget>
4825+ </item>
4826+ <item>
4827+ <spacer name="verticalSpacer_3">
4828+ <property name="orientation">
4829+ <enum>Qt::Vertical</enum>
4830+ </property>
4831+ <property name="sizeHint" stdset="0">
4832+ <size>
4833+ <width>20</width>
4834+ <height>120</height>
4835+ </size>
4836+ </property>
4837+ </spacer>
4838+ </item>
4839+ <item>
4840+ <layout class="QHBoxLayout" name="horizontalLayout_7">
4841+ <item>
4842+ <widget class="QPushButton" name="restoreDefaultsButton">
4843+ <property name="sizePolicy">
4844+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
4845+ <horstretch>0</horstretch>
4846+ <verstretch>0</verstretch>
4847+ </sizepolicy>
4848+ </property>
4849+ <property name="text">
4850+ <string>Restore default settings</string>
4851+ </property>
4852+ </widget>
4853+ </item>
4854+ <item>
4855+ <widget class="QPushButton" name="saveSettingsButton">
4856+ <property name="sizePolicy">
4857+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
4858+ <horstretch>0</horstretch>
4859+ <verstretch>0</verstretch>
4860+ </sizepolicy>
4861+ </property>
4862+ <property name="text">
4863+ <string>Save settings as default</string>
4864+ </property>
4865+ </widget>
4866+ </item>
4867+ </layout>
4868+ </item>
4869+ </layout>
4870+ </widget>
4871+ <widget class="QWidget" name="radiantTab">
4872+ <property name="enabled">
4873+ <bool>true</bool>
4874+ </property>
4875+ <attribute name="title">
4876+ <string>Radiants</string>
4877+ </attribute>
4878+ <layout class="QVBoxLayout" name="verticalLayout_4">
4879+ <item>
4880+ <widget class="QGroupBox" name="groupBox">
4881+ <property name="title">
4882+ <string>Color of radiants markers</string>
4883+ </property>
4884+ <layout class="QGridLayout" name="gridLayout_5">
4885+ <property name="leftMargin">
4886+ <number>0</number>
4887+ </property>
4888+ <property name="topMargin">
4889+ <number>0</number>
4890+ </property>
4891+ <property name="rightMargin">
4892+ <number>0</number>
4893+ </property>
4894+ <property name="bottomMargin">
4895+ <number>0</number>
4896+ </property>
4897+ <property name="spacing">
4898+ <number>0</number>
4899+ </property>
4900+ <item row="0" column="1" alignment="Qt::AlignHCenter">
4901+ <widget class="QGroupBox" name="activeGenericData">
4902+ <property name="minimumSize">
4903+ <size>
4904+ <width>86</width>
4905+ <height>0</height>
4906+ </size>
4907+ </property>
4908+ <property name="toolTip">
4909+ <string>Active Radiant - Generic Data</string>
4910+ </property>
4911+ <property name="alignment">
4912+ <set>Qt::AlignCenter</set>
4913+ </property>
4914+ <layout class="QGridLayout" name="gridLayout_3">
4915+ <property name="leftMargin">
4916+ <number>0</number>
4917+ </property>
4918+ <property name="topMargin">
4919+ <number>0</number>
4920+ </property>
4921+ <property name="rightMargin">
4922+ <number>0</number>
4923+ </property>
4924+ <property name="bottomMargin">
4925+ <number>0</number>
4926+ </property>
4927+ <property name="spacing">
4928+ <number>0</number>
4929+ </property>
4930+ <item row="1" column="0">
4931+ <widget class="QPushButton" name="changeColorARG">
4932+ <property name="toolTip">
4933+ <string>Change Color</string>
4934+ </property>
4935+ <property name="text">
4936+ <string notr="true">...</string>
4937+ </property>
4938+ </widget>
4939+ </item>
4940+ <item row="0" column="0">
4941+ <widget class="QFrame" name="frame_4">
4942+ <property name="minimumSize">
4943+ <size>
4944+ <width>64</width>
4945+ <height>64</height>
4946+ </size>
4947+ </property>
4948+ <property name="maximumSize">
4949+ <size>
4950+ <width>64</width>
4951+ <height>64</height>
4952+ </size>
4953+ </property>
4954+ <property name="frameShape">
4955+ <enum>QFrame::StyledPanel</enum>
4956+ </property>
4957+ <property name="frameShadow">
4958+ <enum>QFrame::Raised</enum>
4959+ </property>
4960+ <widget class="QLabel" name="textureARG">
4961+ <property name="geometry">
4962+ <rect>
4963+ <x>0</x>
4964+ <y>0</y>
4965+ <width>64</width>
4966+ <height>64</height>
4967+ </rect>
4968+ </property>
4969+ <property name="minimumSize">
4970+ <size>
4971+ <width>64</width>
4972+ <height>64</height>
4973+ </size>
4974+ </property>
4975+ <property name="maximumSize">
4976+ <size>
4977+ <width>64</width>
4978+ <height>64</height>
4979+ </size>
4980+ </property>
4981+ <property name="styleSheet">
4982+ <string notr="true">background-image: url(:/MeteorShowers/radiantSetting.png);</string>
4983+ </property>
4984+ <property name="text">
4985+ <string/>
4986+ </property>
4987+ </widget>
4988+ </widget>
4989+ </item>
4990+ </layout>
4991+ </widget>
4992+ </item>
4993+ <item row="0" column="2" alignment="Qt::AlignHCenter">
4994+ <widget class="QGroupBox" name="inactive">
4995+ <property name="minimumSize">
4996+ <size>
4997+ <width>86</width>
4998+ <height>0</height>
4999+ </size>
5000+ </property>
The diff has been truncated for viewing.