Kstars

detaildialoglite.cpp
1/*
2 SPDX-FileCopyrightText: 2016 Artem Fedoskin <afedoskin3@gmail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "detaildialoglite.h"
8
9#include "constellationboundarylines.h"
10#include "deepskyobject.h"
11#include "kspaths.h"
12#include "ksutils.h"
13#include "Options.h"
14#include "skymapcomposite.h"
15#include "skymaplite.h"
16#include "starobject.h"
17#include "kstarslite/skyobjectlite.h"
18#include "skyobjects/ksasteroid.h"
19#include "skyobjects/kscomet.h"
20#include "skyobjects/ksmoon.h"
21#include "skyobjects/ksplanetbase.h"
22#include "skyobjects/supernova.h"
23
24#include <QDesktopServices>
25#include <QTemporaryFile>
26
27DetailDialogLite::DetailDialogLite()
28{
29 setProperty("isLinksOn", true);
30 setProperty("isLogOn", true);
31}
32
33void DetailDialogLite::initialize()
34{
35 connect(SkyMapLite::Instance(), SIGNAL(objectLiteChanged()), this, SLOT(createGeneralTab()));
36 connect(SkyMapLite::Instance(), SIGNAL(objectLiteChanged()), this, SLOT(createPositionTab()));
37 connect(SkyMapLite::Instance(), SIGNAL(objectLiteChanged()), this, SLOT(createLogTab()));
38 connect(SkyMapLite::Instance(), SIGNAL(objectLiteChanged()), this, SLOT(createLinksTab()));
39}
40
41void DetailDialogLite::createGeneralTab()
42{
43 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
44
45 // Stuff that should be visible only for specific types of objects
46 setProperty("illumination", ""); // Only shown for the moon
47 setProperty("BVindex", ""); // Only shown for stars
48 setupThumbnail();
49
50 //Fill in the data fields
51 //Contents depend on type of object
52 QString objecttyp, str;
53
54 switch (selectedObject->type())
55 {
56 case SkyObject::STAR:
57 {
58 StarObject *s = (StarObject *)selectedObject;
59
60 if (s->getHDIndex())
61 {
62 setProperty("name", (QString("%1, HD %2").arg(s->longname()).arg(s->getHDIndex())));
63 }
64 else
65 {
66 setProperty("name", s->longname());
67 }
68
69 objecttyp = s->sptype() + ' ' + i18n("star");
70 setProperty("magnitude", i18nc("number in magnitudes", "%1 mag",
71 QLocale().toString(s->mag(), 'f', 2))); //show to hundredth place
72
73 if (s->getBVIndex() < 30.)
74 {
75 setProperty("BVindex", QString::number(s->getBVIndex(), 'f', 2));
76 }
77
78 //distance
79 if (s->distance() > 2000. || s->distance() < 0.) // parallax < 0.5 mas
80 {
81 setProperty("distance", (QString(i18nc("larger than 2000 parsecs", "> 2000 pc"))));
82 }
83 else if (s->distance() > 50.) //show to nearest integer
84 {
85 setProperty("distance",
86 (i18nc("number in parsecs", "%1 pc", QLocale().toString(s->distance(), 'f', 0))));
87 }
88 else if (s->distance() > 10.0) //show to tenths place
89 {
90 setProperty("distance",
91 (i18nc("number in parsecs", "%1 pc", QLocale().toString(s->distance(), 'f', 1))));
92 }
93 else //show to hundredths place
94 {
95 setProperty("distance",
96 (i18nc("number in parsecs", "%1 pc", QLocale().toString(s->distance(), 'f', 2))));
97 }
98
99 //Note multiplicity/variability in angular size label
100 setProperty("angSize", QString());
101 if (s->isMultiple() && s->isVariable())
102 {
103 QString multiple = QString(i18nc("the star is a multiple star", "multiple") + ',');
104 setProperty("angSize", QString(multiple + '\n' + (i18nc("the star is a variable star", "variable"))));
105 }
106 else if (s->isMultiple())
107 {
108 setProperty("angSize", i18nc("the star is a multiple star", "multiple"));
109 }
110 else if (s->isVariable())
111 {
112 setProperty("angSize", (i18nc("the star is a variable star", "variable")));
113 }
114
115 break; //end of stars case
116 }
117 case SkyObject::ASTEROID: //[fall through to planets]
118 case SkyObject::COMET: //[fall through to planets]
119 case SkyObject::MOON: //[fall through to planets]
120 case SkyObject::PLANET:
121 {
122 KSPlanetBase *ps = (KSPlanetBase *)selectedObject;
123
124 setProperty("name", ps->longname());
125
126 //Type is "G5 star" for Sun
127 if (ps->name() == "Sun")
128 {
129 objecttyp = i18n("G5 star");
130 }
131 else if (ps->name() == "Moon")
132 {
133 objecttyp = ps->translatedName();
134 }
135 else if (ps->name() == i18n("Pluto") || ps->name() == "Ceres" ||
136 ps->name() == "Eris") // TODO: Check if Ceres / Eris have translations and i18n() them
137 {
138 objecttyp = i18n("Dwarf planet");
139 }
140 else
141 {
142 objecttyp = ps->typeName();
143 }
144
145 //The moon displays illumination fraction and updateMag is called to calculate moon's current magnitude
146 if (selectedObject->name() == "Moon")
147 {
149 "illumination",
150 (QString("%1 %").arg(QLocale().toString(((KSMoon *)selectedObject)->illum() * 100., 'f', 0))));
151 ((KSMoon *)selectedObject)->updateMag();
152 }
153
154 // JM: Shouldn't we use the calculated magnitude? Disabling the following
155 /*
156 if(selectedObject->type() == SkyObject::COMET){
157 Data->Magnitude->setText(i18nc("number in magnitudes", "%1 mag",
158 QLocale().toString( ((KSComet *)selectedObject)->getTotalMagnitudeParameter(), 'f', 2))); //show to hundredth place
159
160 }
161 else{*/
162 setProperty("magnitude", (i18nc("number in magnitudes", "%1 mag",
163 QLocale().toString(ps->mag(), 'f', 2)))); //show to hundredth place
164 //}
165
166 //Distance from Earth. The moon requires a unit conversion
167 if (ps->name() == "Moon")
168 {
169 setProperty("distance", (i18nc("distance in kilometers", "%1 km",
170 QLocale().toString(ps->rearth() * AU_KM, 'f', 2))));
171 }
172 else
173 {
174 setProperty("distance", (i18nc("distance in Astronomical Units", "%1 AU",
175 QLocale().toString(ps->rearth(), 'f', 3))));
176 }
177
178 //Angular size; moon and sun in arcmin, others in arcsec
179 if (ps->angSize())
180 {
181 if (ps->name() == "Sun" || ps->name() == "Moon")
182 {
184 "angSize",
185 (i18nc(
186 "angular size in arcminutes", "%1 arcmin",
188 ps->angSize(), 'f',
189 1)))); // Needn't be a plural form because sun / moon will never contract to 1 arcminute
190 }
191 else
192 {
193 setProperty("angSize", i18nc("angular size in arcseconds", "%1 arcsec",
194 QLocale().toString(ps->angSize() * 60.0, 'f', 1)));
195 }
196 }
197 else
198 {
199 setProperty("angSize", "--");
200 }
201
202 break; //end of planets/comets/asteroids case
203 }
204 case SkyObject::SUPERNOVA:
205 {
206 Supernova *sup = (Supernova *)selectedObject;
207
208 objecttyp = i18n("Supernova");
209 setProperty("name", sup->name());
210 setProperty("magnitude", (i18nc("number in magnitudes", "%1 mag", QLocale().toString(sup->mag(), 'f', 2))));
211 setProperty("distance", "---");
212 break;
213 }
214 default: //deep-sky objects
215 {
216 DeepSkyObject *dso = (DeepSkyObject *)selectedObject;
217
218 //Show all names recorded for the object
219 QStringList nameList;
220 if (!dso->longname().isEmpty() && dso->longname() != dso->name())
221 {
222 nameList.append(dso->translatedLongName());
223 nameList.append(dso->translatedName());
224 }
225 else
226 {
227 nameList.append(dso->translatedName());
228 }
229
230 if (!dso->translatedName2().isEmpty())
231 {
232 nameList.append(dso->translatedName2());
233 }
234
235 if (dso->ugc() != 0)
236 {
237 nameList.append(QString("UGC %1").arg(dso->ugc()));
238 }
239
240 if (dso->pgc() != 0)
241 {
242 nameList.append(QString("PGC %1").arg(dso->pgc()));
243 }
244
245 setProperty("name", nameList.join(","));
246
247 objecttyp = dso->typeName();
248
249 if (dso->type() == SkyObject::RADIO_SOURCE)
250 {
251 //ta->MagLabel->setText(i18nc("integrated flux at a frequency", "Flux(%1):", dso->customCatalog()->fluxFrequency()));
252 //Data->Magnitude->setText(i18nc("integrated flux value", "%1 %2",
253 // QLocale().toString(dso->flux(), 'f', 1), dso->customCatalog()->fluxUnit())); //show to tenths place
254 }
255 else if (dso->mag() > 90.0)
256 {
257 setProperty("magnitude", "--");
258 }
259 else
260 {
261 setProperty("magnitude", i18nc("number in magnitudes", "%1 mag",
262 QLocale().toString(dso->mag(), 'f', 1))); //show to tenths place
263 }
264
265 //No distances at this point...
266 setProperty("distance", "--");
267
268 //Only show decimal place for small angular sizes
269 if (dso->a() > 10.0)
270 {
271 setProperty("angSize",
272 i18nc("angular size in arcminutes", "%1 arcmin", QLocale().toString(dso->a(), 'f', 0)));
273 }
274 else if (dso->a())
275 {
276 setProperty("angSize",
277 i18nc("angular size in arcminutes", "%1 arcmin", QLocale().toString(dso->a(), 'f', 1)));
278 }
279 else
280 {
281 setProperty("angSize", "--");
282 }
283
284 break;
285 }
286 }
287
288 //Reset advanced properties
289 setProperty("perihilion", "");
290 setProperty("orbitID", "");
291 setProperty("NEO", "");
292 setProperty("diameter", "");
293 setProperty("rotation", "");
294 setProperty("earthMOID", "");
295 setProperty("orbitClass", "");
296 setProperty("albedo", "");
297 setProperty("dimensions", "");
298 setProperty("period", "");
299
300 // Add specifics data
301 switch (selectedObject->type())
302 {
303 case SkyObject::ASTEROID:
304 {
305 KSAsteroid *ast = (KSAsteroid *)selectedObject;
306
307 // Perihelion
308 str.setNum(ast->getPerihelion());
309 setProperty("perihelion", QString(str + " AU"));
310 // Earth MOID
311 if (ast->getEarthMOID() == 0)
312 str = "";
313 else
314 str.setNum(ast->getEarthMOID()).append(" AU");
315 setProperty("earthMOID", str);
316 // Orbit ID
317 setProperty("orbitID", ast->getOrbitID());
318 // Orbit Class
319 setProperty("orbitClass", ast->getOrbitClass());
320 // NEO
321 if (ast->isNEO())
322 setProperty("NEO", "Yes");
323 else
324 setProperty("NEO", "No");
325 // Albedo
326 if (ast->getAlbedo() == 0.0)
327 str = "";
328 else
329 str.setNum(ast->getAlbedo());
330 setProperty("albedo", str);
331 // Diameter
332 if (ast->getDiameter() == 0.0)
333 str = "";
334 else
335 str.setNum(ast->getDiameter()).append(" km");
336 setProperty("diameter", str);
337 // Dimensions
338 if (ast->getDimensions().isEmpty())
339 setProperty("dimensions", "");
340 else
341 setProperty("dimensions", QString(ast->getDimensions() + " km"));
342 // Rotation period
343 if (ast->getRotationPeriod() == 0.0)
344 str = "";
345 else
346 str.setNum(ast->getRotationPeriod()).append(" h");
347 setProperty("rotation", str);
348 // Period
349 if (ast->getPeriod() == 0.0)
350 str = "";
351 else
352 str.setNum(ast->getPeriod()).append(" y");
353 setProperty("period", str);
354
355 break;
356 }
357 case SkyObject::COMET:
358 {
359 KSComet *com = (KSComet *)selectedObject;
360
361 // Perihelion
362 str.setNum(com->getPerihelion());
363 setProperty("perihelion", QString(str + " AU"));
364 // Earth MOID
365 if (com->getEarthMOID() == 0)
366 str = "";
367 else
368 str.setNum(com->getEarthMOID()).append(" AU");
369 setProperty("earthMOID", str);
370 // Orbit ID
371 setProperty("orbitID", com->getOrbitID());
372 // Orbit Class
373 setProperty("orbitClass", com->getOrbitClass());
374 // NEO
375 if (com->isNEO())
376 setProperty("NEO", "Yes");
377 else
378 setProperty("NEO", "No");
379 // Albedo
380 if (com->getAlbedo() == 0.0)
381 str = "";
382 else
383 str.setNum(com->getAlbedo());
384 setProperty("albedo", str);
385 // Diameter
386 if (com->getDiameter() == 0.0)
387 str = "";
388 else
389 str.setNum(com->getDiameter()).append(" km");
390 setProperty("diameter", str);
391 // Dimensions
392 if (com->getDimensions().isEmpty())
393 setProperty("dimensions", "");
394 else
395 setProperty("dimensions", QString(com->getDimensions() + " km"));
396 // Rotation period
397 if (com->getRotationPeriod() == 0.0)
398 str = "";
399 else
400 str.setNum(com->getRotationPeriod()).append(" h");
401 setProperty("rotation", str);
402 // Period
403 if (com->getPeriod() == 0.0)
404 str = "";
405 else
406 str.setNum(com->getPeriod()).append(" y");
407 setProperty("period", str);
408
409 break;
410 }
411 }
412
413 //Common to all types:
414 QString cname = KStarsData::Instance()->skyComposite()->constellationBoundary()->constellationName(selectedObject);
415 if (selectedObject->type() != SkyObject::CONSTELLATION)
416 {
417 cname = i18nc("%1 type of sky object (planet, asteroid etc), %2 name of a constellation", "%1 in %2", objecttyp,
418 cname);
419 }
420 setProperty("typeInConstellation", cname);
421}
422
423void DetailDialogLite::createPositionTab()
424{
425 KStarsData *data = KStarsData::Instance();
426 KStarsDateTime ut = data->ut();
427 GeoLocation *geo = data->geo();
428
429 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
430
431 //Coordinates Section:
432 //Don't use KLocale::formatNumber() for the epoch string,
433 //because we don't want a thousands-place separator!
434 QString sEpoch = QString::number(ut.epoch(), 'f', 1);
435 //Replace the decimal point with localized decimal symbol
436 sEpoch.replace('.', QLocale().decimalPoint());
437
438 qDebug() << (selectedObject->deprecess(data->updateNum(), 2451545.0l)).ra0().toHMSString()
439 << (selectedObject->deprecess(data->updateNum(), 2451545.0l)).dec0().toDMSString() << endl;
440 //qDebug() << selectedObject->ra().toHMSString() << selectedObject->dec().toDMSString() << endl;
441 setProperty("RALabel", i18n("RA (%1):", sEpoch));
442 setProperty("decLabel", i18n("Dec (%1):", sEpoch));
443 setProperty("RA", selectedObject->ra().toHMSString());
444 setProperty("dec", selectedObject->dec().toDMSString());
445
446 selectedObject->EquatorialToHorizontal(data->lst(), data->geo()->lat());
447
448 setProperty("az", selectedObject->az().toDMSString());
449 dms a;
450
451 if (Options::useAltAz())
452 a = selectedObject->alt();
453 else
454 a = selectedObject->altRefracted();
455 setProperty("alt", a.toDMSString());
456
457 // Display the RA0 and Dec0 for objects that are outside the solar system
458 if (!selectedObject->isSolarSystem())
459 {
460 setProperty("RA0", selectedObject->ra0().toHMSString());
461 setProperty("dec0", selectedObject->dec0().toDMSString());
462 }
463 else
464 {
465 setProperty("RA0", "--");
466 setProperty("dec0", "--");
467 }
468
469 //Hour Angle can be negative, but dms HMS expressions cannot.
470 //Here's a kludgy workaround:
471 dms lst = geo->GSTtoLST(ut.gst());
472 dms ha(lst.Degrees() - selectedObject->ra().Degrees());
473 QChar sgn('+');
474 if (ha.Hours() > 12.0)
475 {
476 ha.setH(24.0 - ha.Hours());
477 sgn = '-';
478 }
479 setProperty("HA", QString("%1%2").arg(sgn).arg(ha.toHMSString()));
480
481 //Airmass is approximated as the secant of the zenith distance,
482 //equivalent to 1./sin(Alt). Beware of Inf at Alt=0!
483 if (selectedObject->alt().Degrees() > 0.0)
484 setProperty("airmass", QLocale().toString(selectedObject->airmass(), 'f', 2));
485 else
486 setProperty("airmass", "--");
487
488 //Rise/Set/Transit Section:
489
490 //Prepare time/position variables
491 QTime rt = selectedObject->riseSetTime(ut, geo, true); //true = use rise time
492 dms raz = selectedObject->riseSetTimeAz(ut, geo, true); //true = use rise time
493
494 //If transit time is before rise time, use transit time for tomorrow
495 QTime tt = selectedObject->transitTime(ut, geo);
496 dms talt = selectedObject->transitAltitude(ut, geo);
497 if (tt < rt)
498 {
499 tt = selectedObject->transitTime(ut.addDays(1), geo);
500 talt = selectedObject->transitAltitude(ut.addDays(1), geo);
501 }
502
503 //If set time is before rise time, use set time for tomorrow
504 QTime st = selectedObject->riseSetTime(ut, geo, false); //false = use set time
505 dms saz = selectedObject->riseSetTimeAz(ut, geo, false); //false = use set time
506 if (st < rt)
507 {
508 st = selectedObject->riseSetTime(ut.addDays(1), geo, false); //false = use set time
509 saz = selectedObject->riseSetTimeAz(ut.addDays(1), geo, false); //false = use set time
510 }
511
512 if (rt.isValid())
513 {
514 setProperty("timeRise", QString().sprintf("%02d:%02d", rt.hour(), rt.minute()));
515 setProperty("timeSet", QString().sprintf("%02d:%02d", st.hour(), st.minute()));
516 setProperty("azRise", raz.toDMSString());
517 setProperty("azSet", saz.toDMSString());
518 }
519 else
520 {
521 if (selectedObject->alt().Degrees() > 0.0)
522 {
523 setProperty("timeRise", i18n("Circumpolar"));
524 setProperty("timeSet", i18n("Circumpolar"));
525 }
526 else
527 {
528 setProperty("timeRise", i18n("Never rises"));
529 setProperty("timeSet", i18n("Never rises"));
530 }
531
532 setProperty("azRise", i18nc("Not Applicable", "N/A"));
533 setProperty("azSet", i18nc("Not Applicable", "N/A"));
534 }
535
536 setProperty("timeTransit", QString().sprintf("%02d:%02d", tt.hour(), tt.minute()));
537 setProperty("altTransit", talt.toDMSString());
538
539 // Restore the position and other time-dependent parameters
540 selectedObject->recomputeCoords(ut, geo);
541}
542
543void DetailDialogLite::createLogTab()
544{
545 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
546 //Don't create a log tab for an unnamed star
547 if (selectedObject->name() == QString("star"))
548 {
549 setProperty("isLogOn", false);
550 return;
551 }
552 setProperty("isLogOn", true);
553
554 if (selectedObject->userLog().isEmpty())
555 {
556 setProperty("userLog",
557 i18n("Record here observation logs and/or data on %1.", selectedObject->translatedName()));
558 }
559 else
560 {
561 setProperty("userLog", selectedObject->userLog());
562 }
563
564 /*//Automatically save the log contents when the widget loses focus
565 connect( Log->UserLog, SIGNAL(focusOut()), this, SLOT(saveLogData()) );*/
566}
567
568void DetailDialogLite::createLinksTab()
569{
570 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
571
572 //No links for unnamed stars
573 if (selectedObject->name() == QString("star"))
574 {
575 setProperty("isLinksOn", false);
576 return;
577 }
578
579 setProperty("isLinksOn", true);
580
581 QStringList newInfoList;
582 foreach (const QString &s, selectedObject->InfoTitle())
583 newInfoList.append(i18nc("Image/info menu item (should be translated)", s.toLocal8Bit()));
584 setProperty("infoTitleList", newInfoList);
585
586 QStringList newImageList;
587 foreach (const QString &s, selectedObject->ImageTitle())
588 newImageList.append(i18nc("Image/info menu item (should be translated)", s.toLocal8Bit()));
589
590 setProperty("imageTitleList", newImageList);
591}
592
593void DetailDialogLite::updateLocalDatabase(int type, const QString &search_line, const QString &replace_line)
594{
595 QString TempFileName, file_line;
596 QFile URLFile;
597 QTemporaryFile TempFile;
598 QTextStream *temp_stream = nullptr;
599 QTextStream *out_stream = nullptr;
600 bool replace = !replace_line.isEmpty();
601
602 if (search_line.isEmpty())
603 return;
604
605 TempFile.setAutoRemove(false);
606 TempFile.open();
607 TempFileName = TempFile.fileName();
608
609 switch (type)
610 {
611 // Info Links
612 case 0:
613 // Get name for our local info_url file
614 URLFile.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("info_url.dat"));
615 break;
616
617 // Image Links
618 case 1:
619 // Get name for our local info_url file
620 URLFile.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("image_url.dat"));
621 break;
622 }
623
624 if (!URLFile.open(QIODevice::ReadWrite))
625 {
626 qDebug() << "DetailDialog: Failed to open " << URLFile.fileName();
627 qDebug() << "KStars cannot save to user database";
628 return;
629 }
630
631 // Copy URL file to temp file
632 TempFile.write(URLFile.readAll());
633 //Return pointers to initial positions
634 TempFile.seek(0);
635 //Clear URLFile
636 URLFile.resize(0);
637
638 // Get streams;
639 temp_stream = new QTextStream(&TempFile);
640 out_stream = new QTextStream(&URLFile);
641
642 while (!temp_stream->atEnd())
643 {
644 file_line = temp_stream->readLine();
645 // If we find a match, either replace, or remove (by skipping).
646 if (file_line == search_line)
647 {
648 if (replace)
649 (*out_stream) << replace_line << endl;
650 else
651 continue;
652 }
653 else
654 (*out_stream) << file_line << endl;
655 }
656
657 URLFile.close();
658 delete temp_stream;
659 delete out_stream;
660}
661
662void DetailDialogLite::addLink(const QString &url, const QString &desc, bool isImageLink)
663{
664 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
665
666 if (url.isEmpty() || desc.isEmpty())
667 return; //Do nothing if empty url or desc were provided
668
669 QString entry;
670 QFile file;
671
672 if (isImageLink)
673 {
674 //Add link to object's ImageList, and descriptive text to its ImageTitle list
675 selectedObject->ImageList().append(url);
676 selectedObject->ImageTitle().append(desc);
677
678 //Also, update the user's custom image links database
679 //check for user's image-links database. If it doesn't exist, create it.
680 //determine filename in local user KDE directory tree.
681 file.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("image_url.dat"));
682
684 {
685 QString message =
686 i18n("Custom image-links file could not be opened.\nLink cannot be recorded for future sessions.");
687 qDebug() << message;
688 return;
689 }
690 else
691 {
692 entry = selectedObject->name() + ':' + desc + ':' + url;
693 QTextStream stream(&file);
694 stream << entry << endl;
695 file.close();
696 setProperty("imageTitleList", selectedObject->ImageTitle());
697 }
698 }
699 else
700 {
701 selectedObject->InfoList().append(url);
702 selectedObject->InfoTitle().append(desc);
703
704 //check for user's image-links database. If it doesn't exist, create it.
705 //determine filename in local user KDE directory tree.
706 file.setFileName(QDir(KSPaths::writableLocation(QStandardPaths::AppDataLocation)).filePath("info_url.dat"));
707
709 {
710 QString message = i18n(
711 "Custom information-links file could not be opened.\nLink cannot be recorded for future sessions.");
712 qDebug() << message;
713 return;
714 }
715 else
716 {
717 entry = selectedObject->name() + ':' + desc + ':' + url;
718 QTextStream stream(&file);
719 stream << entry << endl;
720 file.close();
721 setProperty("infoTitleList", selectedObject->InfoTitle());
722 }
723 }
724}
725
726void DetailDialogLite::removeLink(int itemIndex, bool isImage)
727{
728 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
729
730 QString currentItemURL, currentItemTitle, LineEntry, TempFileName, FileLine;
731 QFile URLFile;
732 QTemporaryFile TempFile;
733 TempFile.setAutoRemove(false);
734 TempFile.open();
735 TempFileName = TempFile.fileName();
736
737 //Check if it is a valid index
738 if (itemIndex < 0)
739 {
740 return;
741 }
742 else if (isImage && itemIndex >= selectedObject->ImageTitle().length())
743 {
744 return;
745 }
746 else if (!isImage && itemIndex >= selectedObject->InfoTitle().length())
747 {
748 return;
749 }
750 //if (title.isEmpty() || url.isEmpty()) return;
751
752 if (!isImage) //Information
753 {
754 currentItemTitle = selectedObject->InfoTitle()[itemIndex];
755 currentItemURL = selectedObject->InfoList()[itemIndex];
756 LineEntry = selectedObject->name();
757 LineEntry += ':';
758 LineEntry += currentItemTitle;
759 LineEntry += ':';
760 LineEntry += currentItemURL;
761 }
762 else //Image
763 {
764 currentItemTitle = selectedObject->ImageTitle()[itemIndex];
765 currentItemURL = selectedObject->ImageList()[itemIndex];
766 LineEntry = selectedObject->name();
767 LineEntry += ':';
768 LineEntry += currentItemTitle;
769 LineEntry += ':';
770 LineEntry += currentItemURL;
771 }
772
773 /*if (KMessageBox::warningContinueCancel( 0, i18n("Are you sure you want to remove the %1 link?", currentItemTitle), i18n("Delete Confirmation"),KStandardGuiItem::del())!=KMessageBox::Continue)
774 return;*/
775
776 if (isImage)
777 {
778 selectedObject->ImageTitle().removeAt(itemIndex);
779 selectedObject->ImageList().removeAt(itemIndex);
780 }
781 else
782 {
783 selectedObject->InfoTitle().removeAt(itemIndex);
784 selectedObject->InfoList().removeAt(itemIndex);
785 }
786
787 // Remove link from file
788 updateLocalDatabase(isImage ? 1 : 0, LineEntry);
789
790 setProperty("infoTitleList", selectedObject->InfoTitle());
791 setProperty("imageTitleList", selectedObject->ImageTitle());
792}
793
794void DetailDialogLite::editLink(int itemIndex, bool isImage, const QString &desc, const QString &url)
795{
796 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
797
798 if (url.isEmpty() || desc.isEmpty())
799 return; //Do nothing if empty url or desc were provided
800
801 QString search_line, replace_line, currentItemTitle, currentItemURL;
802
803 //Check if it is a valid index
804 if (itemIndex < 0)
805 {
806 return;
807 }
808 else if (isImage && itemIndex >= selectedObject->ImageTitle().length())
809 {
810 return;
811 }
812 else if (!isImage && itemIndex >= selectedObject->InfoTitle().length())
813 {
814 return;
815 }
816
817 if (!isImage) //Information
818 {
819 currentItemTitle = selectedObject->InfoTitle()[itemIndex];
820 currentItemURL = selectedObject->InfoList()[itemIndex];
821 search_line = selectedObject->name();
822 search_line += ':';
823 search_line += currentItemTitle;
824 search_line += ':';
825 search_line += currentItemURL;
826 }
827 else //Image
828 {
829 currentItemTitle = selectedObject->ImageTitle()[itemIndex];
830 currentItemURL = selectedObject->ImageList()[itemIndex];
831 search_line = selectedObject->name();
832 search_line += ':';
833 search_line += currentItemTitle;
834 search_line += ':';
835 search_line += currentItemURL;
836 }
837
838 bool go(true);
839
840 // If nothing changed, skip th action
841 if (url == currentItemURL && desc == currentItemTitle)
842 go = false;
843
844 if (go)
845 {
846 replace_line = selectedObject->name() + ':' + desc + ':' + url;
847
848 // Info Link
849 if (!isImage)
850 {
851 selectedObject->InfoTitle().replace(itemIndex, desc);
852 selectedObject->InfoList().replace(itemIndex, url);
853
854 // Image Links
855 }
856 else
857 {
858 selectedObject->ImageTitle().replace(itemIndex, desc);
859 selectedObject->ImageList().replace(itemIndex, url);
860 }
861
862 // Update local files
863 updateLocalDatabase(isImage ? 1 : 0, search_line, replace_line);
864
865 setProperty("infoTitleList", selectedObject->InfoTitle());
866 setProperty("imageTitleList", selectedObject->ImageTitle());
867 }
868}
869
870QString DetailDialogLite::getInfoURL(int index)
871{
872 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
873 QStringList urls = selectedObject->InfoList();
874 if (index >= 0 && index < urls.size())
875 {
876 return urls[index];
877 }
878 else
879 {
880 return "";
881 }
882}
883
884QString DetailDialogLite::getImageURL(int index)
885{
886 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
887 QStringList urls = selectedObject->ImageList();
888 if (index >= 0 && index < urls.size())
889 {
890 return urls[index];
891 }
892 else
893 {
894 return "";
895 }
896}
897
898void DetailDialogLite::setupThumbnail()
899{
900 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
901 //No image if object is a star
902 if (selectedObject->type() == SkyObject::STAR || selectedObject->type() == SkyObject::CATALOG_STAR)
903 {
904 /*Thumbnail->scaled( Data->Image->width(), Data->Image->height() );
905 Thumbnail->fill( Data->DataFrame->palette().color( QPalette::Window ) );
906 Data->Image->setPixmap( *Thumbnail );*/
907 setProperty("thumbnail", "");
908 return;
909 }
910
911 //Try to load the object's image from disk
912 //If no image found, load "no image" image
913 QFile file;
914 QString fname = "thumb-" + selectedObject->name().toLower().remove(' ') + ".png";
915 if (KSUtils::openDataFile(file, fname))
916 {
917 file.close();
918 setProperty("thumbnail", file.fileName());
919 }
920 else
921 {
922 setProperty("thumbnail", "");
923 }
924}
925
926/*void DetailDialogLite::viewResource(int itemIndex, bool isImage) {
927 QString url;
928 if(isImage) {
929 url = getImageURL(itemIndex);
930 } else {
931 url = getInfoURL(itemIndex);
932 }
933 QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
934}*/
935
936void DetailDialogLite::saveLogData(const QString &userLog)
937{
938 SkyObject *selectedObject = SkyMapLite::Instance()->getClickedObjectLite()->getObject();
939
940 selectedObject->saveUserLog(userLog);
941}
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
Definition geolocation.h:28
const CachingDms * lat() const
Definition geolocation.h:70
A subclass of KSPlanetBase that implements asteroids.
Definition ksasteroid.h:42
QString getOrbitClass() const
Definition ksasteroid.h:118
bool isNEO() const
Definition ksasteroid.h:128
QString getOrbitID() const
Definition ksasteroid.h:108
double getEarthMOID() const
Definition ksasteroid.h:98
float getRotationPeriod() const
Definition ksasteroid.h:168
double getPerihelion() const
Definition ksasteroid.h:88
float getDiameter() const
Definition ksasteroid.h:148
QString getDimensions() const
Definition ksasteroid.h:158
float getPeriod() const
Definition ksasteroid.h:178
float getAlbedo() const
Definition ksasteroid.h:138
A subclass of KSPlanetBase that implements comets.
Definition kscomet.h:44
double getEarthMOID()
Definition kscomet.h:118
float getAlbedo()
Definition kscomet.h:142
float getRotationPeriod()
Definition kscomet.h:160
bool isNEO()
Definition kscomet.h:136
double getPerihelion()
Returns Perihelion distance.
Definition kscomet.h:85
QString getOrbitClass()
Definition kscomet.h:130
QString getDimensions()
Definition kscomet.h:154
float getDiameter()
Definition kscomet.h:148
float getPeriod()
Definition kscomet.h:166
QString getOrbitID()
Definition kscomet.h:124
Provides necessary information about the Moon.
Definition ksmoon.h:26
A subclass of TrailObject that provides additional information needed for most solar system objects.
double angSize() const
double rearth() const
KStarsData is the backbone of KStars.
Definition kstarsdata.h:74
CachingDms * lst()
Definition kstarsdata.h:226
const KStarsDateTime & ut() const
Definition kstarsdata.h:159
GeoLocation * geo()
Definition kstarsdata.h:232
SkyMapComposite * skyComposite()
Definition kstarsdata.h:168
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
KStarsDateTime addDays(int nd) const
Modify the Date/Time by adding a number of days.
double epoch() const
This is (approximately) the year expressed as a floating-point value.
SkyObjectLite * getClickedObjectLite()
getter for clickedObjectLite
Definition skymaplite.h:401
SkyObject * getObject() const
Provides all necessary information about an object in the sky: its coordinates, name(s),...
Definition skyobject.h:42
QString translatedName() const
Definition skyobject.h:149
dms riseSetTimeAz(const KStarsDateTime &dt, const GeoLocation *geo, bool rst) const
virtual QString name(void) const
Definition skyobject.h:146
dms transitAltitude(const KStarsDateTime &dt, const GeoLocation *geo) const
bool isSolarSystem() const
Definition skyobject.h:218
virtual QString longname(void) const
Definition skyobject.h:165
QTime transitTime(const KStarsDateTime &dt, const GeoLocation *geo) const
The same iteration technique described in riseSetTime() is used here.
QTime riseSetTime(const KStarsDateTime &dt, const GeoLocation *geo, bool rst, bool exact=true) const
Determine the time at which the point will rise or set.
Definition skyobject.cpp:93
static QString typeName(const int t)
int type(void) const
Definition skyobject.h:189
float mag() const
Definition skyobject.h:207
SkyPoint recomputeCoords(const KStarsDateTime &dt, const GeoLocation *geo=nullptr) const
The equatorial coordinates for the object on date dt are computed and returned, but the object's inte...
double airmass() const
Definition skypoint.h:303
const CachingDms & dec() const
Definition skypoint.h:269
const CachingDms & ra0() const
Definition skypoint.h:251
const CachingDms & ra() const
Definition skypoint.h:263
dms altRefracted() const
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
Definition skypoint.cpp:77
const dms & az() const
Definition skypoint.h:275
const dms & alt() const
Definition skypoint.h:281
const CachingDms & dec0() const
Definition skypoint.h:257
SkyPoint deprecess(const KSNumbers *num, long double epoch=J2000)
Obtain a Skypoint with RA0 and Dec0 set from the RA, Dec of this skypoint.
Definition skypoint.cpp:257
This is a subclass of SkyObject.
Definition starobject.h:33
QString longname(void) const override
If star is unnamed return "star" otherwise return the longname.
Definition starobject.h:133
double distance() const
Definition starobject.h:242
float getBVIndex() const
Definition starobject.h:287
int getHDIndex() const
Definition starobject.h:254
bool isMultiple() const
Definition starobject.h:251
bool isVariable() const
Definition starobject.h:264
QString sptype(void) const
Returns entire spectral type string.
Represents the supernova object.
Definition supernova.h:34
An angle, stored as degrees, but expressible in many ways.
Definition dms.h:38
const QString toDMSString(const bool forceSign=false, const bool machineReadable=false, const bool highPrecision=false) const
Definition dms.cpp:287
const QString toHMSString(const bool machineReadable=false, const bool highPrecision=false) const
Definition dms.cpp:378
const double & Degrees() const
Definition dms.h:141
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
char * toString(const EngineQuery &query)
GeoCoordinates geo(const QVariant &location)
const QList< QKeySequence > & replace()
virtual QString fileName() const const override
bool open(FILE *fh, OpenMode mode, FileHandleFlags handleFlags)
bool resize(const QString &fileName, qint64 sz)
void setFileName(const QString &name)
virtual void close() override
virtual bool seek(qint64 pos) override
QByteArray readAll()
qint64 write(const QByteArray &data)
void append(QList< T > &&value)
qsizetype size() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool setProperty(const char *name, QVariant &&value)
QString & append(QChar ch)
QString arg(Args &&... args) const const
bool isEmpty() const const
QString number(double n, char format, int precision)
QString & remove(QChar ch, Qt::CaseSensitivity cs)
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
QString & setNum(double n, char format, int precision)
QByteArray toLocal8Bit() const const
QString toLower() const const
QString join(QChar separator) const const
QTextStream & endl(QTextStream &stream)
virtual QString fileName() const const override
void setAutoRemove(bool b)
bool atEnd() const const
QString readLine(qint64 maxlen)
int hour() const const
bool isValid(int h, int m, int s, int ms)
int minute() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:04:46 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.