7#include "detaildialog.h"
9#include "config-kstars.h"
11#include "addlinkdialog.h"
13#include "ksnotification.h"
14#include "kstarsdata.h"
15#include "observinglist.h"
17#include "skyobjectuserdata.h"
18#include "thumbnailpicker.h"
19#include "skycomponents/constellationboundarylines.h"
20#include "skycomponents/skymapcomposite.h"
21#include "catalogobject.h"
22#include "skyobjects/ksasteroid.h"
23#include "skyobjects/kscomet.h"
24#include "skyobjects/ksmoon.h"
25#include "skyobjects/starobject.h"
26#include "skyobjects/supernova.h"
27#include "catalogsdb.h"
31#include "indi/indilistener.h"
32#include "indi/indimount.h"
35#include <QDesktopServices>
37#include <QDirIterator>
56 Thumbnail.reset(
new QPixmap(200, 200));
65 createPositionTab(ut, geo);
71void DetailDialog::createGeneralTab()
73 Data =
new DataWidget(
this);
104 switch (selectedObject->
type())
106 case SkyObject::STAR:
112 Data->Names->setText(
117 Data->Names->setText(s->
longname());
121 Data->Magnitude->setText(
122 i18nc(
"number in magnitudes",
"%1 mag",
140 Data->Distance->setText(
141 QString(
i18nc(
"larger than 2000 parsecs",
"> 2000 pc")));
145 Data->Distance->setText(
i18nc(
"number in parsecs",
"%1 pc",
150 Data->Distance->setText(
i18nc(
"number in parsecs",
"%1 pc",
155 Data->Distance->setText(
i18nc(
"number in parsecs",
"%1 pc",
160 Data->AngSizeLabel->setText(
QString());
161 Data->AngSize->setText(
QString());
162 Data->AngSizeLabel->
setFont(Data->AngSize->
font());
165 Data->AngSizeLabel->setText(
166 i18nc(
"the star is a multiple star",
"multiple") +
',');
167 Data->AngSize->setText(
i18nc(
"the star is a variable star",
"variable"));
171 Data->AngSizeLabel->setText(
172 i18nc(
"the star is a multiple star",
"multiple"));
176 Data->AngSizeLabel->setText(
177 i18nc(
"the star is a variable star",
"variable"));
181 double pmRA = s->
pmRA(), pmDec = s->
pmDec();
182 if (std::isfinite(pmRA) && std::isfinite(pmDec) && (pmRA != 0.0 || pmDec != 0.0))
185 Data->IllumLabel->setText(
i18nc(
"Proper motion of a star",
"Proper Motion:"));
186 Data->Illumination->setText(
188 "The first arg is proper motion in right ascension and the second in the declination. The unit stands for milliarcsecond per year",
199 case SkyObject::ASTEROID:
200 case SkyObject::COMET:
201 case SkyObject::MOON:
202 case SkyObject::PLANET:
209 Data->Names->setText(
ps->longname());
212 if (
ps->name() ==
i18n(
"Sun"))
216 else if (
ps->name() ==
i18n(
"Moon"))
220 else if (
ps->name() ==
i18nc(
"Asteroid name (optional)",
"Pluto") ||
221 ps->name() ==
i18nc(
"Asteroid name (optional)",
"Ceres") ||
222 ps->name() ==
i18nc(
"Asteroid name (optional)",
"Eris"))
232 if (selectedObject->
name() ==
i18n(
"Moon"))
237 ((
KSMoon *)selectedObject)->illum() * 100.,
'f', 0)));
238 ((
KSMoon *)selectedObject)->updateMag();
249 Data->Magnitude->setText(
250 i18nc(
"number in magnitudes",
"%1 mag",
255 if (
ps->name() ==
i18n(
"Moon"))
257 Data->Distance->setText(
258 i18nc(
"distance in kilometers",
"%1 km",
263 Data->Distance->setText(
i18nc(
"distance in Astronomical Units",
"%1 AU",
270 if (
ps->name() ==
i18n(
"Sun") ||
ps->name() ==
i18n(
"Moon"))
272 Data->AngSize->setText(
i18nc(
273 "angular size in arcminutes",
"%1 arcmin",
280 Data->AngSize->setText(
281 i18nc(
"angular size in arcseconds",
"%1 arcsec",
287 Data->AngSize->setText(
"--");
292 case SkyObject::SUPERNOVA:
297 Data->Names->setText(
sup->name());
299 Data->Magnitude->setText(
i18nc(
"number in magnitudes",
"%1 mag",
302 Data->Magnitude->setText(
"--");
313 Data->dataGridLayout->addWidget(discoveryDate, 1, 1);
317 Data->dataGridLayout->addWidget(typeLabel, 2, 0);
318 Data->dataGridLayout->addWidget(type, 2, 1);
322 sup->getHostGalaxy().isEmpty() ?
"--" :
sup->getHostGalaxy(),
this);
324 Data->dataGridLayout->addWidget(hostGalaxy, 3, 1);
332 Data->dataGridLayout->addWidget(redShift, 4, 1);
339 Data->dataGridLayout->addWidget(urlLabel, 5, 0);
340 Data->dataGridLayout->addWidget(url, 5, 1);
353 if (!
dso->longname().isEmpty() &&
dso->longname() !=
dso->name())
360 if (!
dso->translatedName2().isEmpty())
365 Data->Names->setText(
nameList.join(
","));
369 if (
dso->type() == SkyObject::RADIO_SOURCE)
371 Data->MagLabel->setText(
372 i18nc(
"integrated flux at a frequency",
"Flux(%1):", 1));
373 Data->Magnitude->setText(
i18nc(
"integrated flux value",
"%1 %2",
377 else if (std::isnan(
dso->mag()))
379 Data->Magnitude->setText(
"--");
383 Data->Magnitude->setText(
384 i18nc(
"number in magnitudes",
"%1 mag",
389 Data->Distance->setText(
"--");
392 Data->Catalog->setText(
dso->getCatalog().name);
397 Data->AngSize->setText(
i18nc(
"angular size in arcminutes",
"%1 arcmin",
402 Data->AngSize->setText(
i18nc(
"angular size in arcminutes",
"%1 arcmin",
407 Data->AngSize->setText(
"--");
415 switch (selectedObject->
type())
417 case SkyObject::ASTEROID:
421 DataComet =
new DataCometWidget(
this);
425 DataComet->Perihelion->setText(
i18nc(
"Distance in astronomical units",
429 if (
ast->getEarthMOID() == 0)
430 DataComet->EarthMOID->setText(
"--");
432 DataComet->EarthMOID->setText(
433 i18nc(
"Distance in astronomical units",
"%1 AU",
436 DataComet->OrbitID->setText(
ast->getOrbitID());
438 DataComet->OrbitClass->setText(
ast->getOrbitClass());
441 DataComet->NEO->setText(
i18n(
"Yes"));
443 DataComet->NEO->setText(
i18n(
"No"));
445 if (
ast->getAlbedo() == 0.0)
446 DataComet->Albedo->setText(
"--");
450 if (
ast->getDiameter() == 0.0)
451 DataComet->Diameter->setText(
"--");
453 DataComet->Diameter->setText(
i18nc(
"Diameter in kilometers",
"%1 km",
456 if (
ast->getDimensions().isEmpty())
457 DataComet->Dimensions->setText(
"--");
459 DataComet->Dimensions->setText(
460 i18nc(
"Dimension in kilometers",
"%1 km",
ast->getDimensions()));
462 if (
ast->getRotationPeriod() == 0.0)
463 DataComet->Rotation->setText(
"--");
465 DataComet->Rotation->setText(
466 i18nc(
"Rotation period in hours",
"%1 h",
469 if (
ast->getPeriod() == 0.0)
470 DataComet->Period->setText(
"--");
472 DataComet->Period->setText(
i18nc(
"Orbit period in years",
"%1 y",
476 case SkyObject::COMET:
479 DataComet =
new DataCometWidget(
this);
483 DataComet->Perihelion->setText(
i18nc(
"Distance in astronomical units",
487 if (
com->getEarthMOID() == 0)
488 DataComet->EarthMOID->setText(
"--");
490 DataComet->EarthMOID->setText(
491 i18nc(
"Distance in astronomical units",
"%1 AU",
494 DataComet->OrbitID->setText(
com->getOrbitID());
496 DataComet->OrbitClass->setText(
com->getOrbitClass());
499 DataComet->NEO->setText(
i18n(
"Yes"));
501 DataComet->NEO->setText(
i18n(
"No"));
503 if (
com->getAlbedo() == 0.0)
504 DataComet->Albedo->setText(
"--");
508 if (
com->getDiameter() == 0.0)
509 DataComet->Diameter->setText(
"--");
511 DataComet->Diameter->setText(
i18nc(
"Diameter in kilometers",
"%1 km",
514 if (
com->getDimensions().isEmpty())
515 DataComet->Dimensions->setText(
"--");
517 DataComet->Dimensions->setText(
518 i18nc(
"Dimension in kilometers",
"%1 km",
com->getDimensions()));
520 if (
com->getRotationPeriod() == 0.0)
521 DataComet->Rotation->setText(
"--");
523 DataComet->Rotation->setText(
524 i18nc(
"Rotation period in hours",
"%1 h",
527 if (
com->getPeriod() == 0.0)
528 DataComet->Period->setText(
"--");
530 DataComet->Period->setText(
i18nc(
"Orbit period in years",
"%1 y",
539 ->constellationBoundary()
540 ->constellationName(selectedObject);
541 if (selectedObject->
type() != SkyObject::CONSTELLATION)
544 "%1 type of sky object (planet, asteroid etc), %2 name of a constellation",
547 Data->ObjectTypeInConstellation->setText(
cname);
552 Pos =
new PositionWidget(
this);
570 Pos->RALabel->setText(
i18n(
"RA (%1):",
sEpoch));
571 Pos->DecLabel->setText(
i18n(
"DE (%1):",
sEpoch));
572 Pos->RA->setText(selectedObject->
ra().toHMSString(
false,
true));
573 Pos->Dec->setText(selectedObject->
dec().toDMSString(
false,
false,
true));
577 Pos->Az->setText(selectedObject->
az().toDMSString());
580 if (Options::useAltAz())
581 a = selectedObject->
alt();
589 Pos->RA0->setText(selectedObject->
ra0().toHMSString(
false,
true));
590 Pos->Dec0->setText(selectedObject->
dec0().toDMSString(
false,
false,
true));
592 if (!selectedObject->
isSolarSystem() || selectedObject->
type() == SkyObject::COMET
593 || selectedObject->
type() == SkyObject::ASTEROID)
595 Pos->RA0->setText(selectedObject->
ra0().toHMSString());
596 Pos->Dec0->setText(selectedObject->
dec0().toDMSString());
600 Pos->RA0->setText(
"--");
601 Pos->Dec0->setText(
"--");
610 if (ha.Hours() > 12.0)
612 ha.setH(24.0 - ha.Hours());
615 Pos->HA->setText(
QString(
"%1%2").arg(sgn).arg(ha.toHMSString()));
619 if (selectedObject->
alt().Degrees() > 0.0)
622 Pos->Airmass->setText(
"--");
652 Pos->AzRise->setText(
raz.toDMSString());
653 Pos->AzSet->setText(
saz.toDMSString());
657 if (selectedObject->
alt().Degrees() > 0.0)
659 Pos->TimeRise->setText(
i18n(
"Circumpolar"));
660 Pos->TimeSet->setText(
i18n(
"Circumpolar"));
664 Pos->TimeRise->setText(
i18n(
"Never rises"));
665 Pos->TimeSet->setText(
i18n(
"Never rises"));
668 Pos->AzRise->setText(
i18nc(
"Not Applicable",
"N/A"));
669 Pos->AzSet->setText(
i18nc(
"Not Applicable",
"N/A"));
673 Pos->AltTransit->setText(
talt.toDMSString());
679void DetailDialog::createLinksTab()
685 Links =
new LinksWidget(
this);
691 for (
const auto &link : m_user_data.websites())
693 link.title.toLocal8Bit()));
697 for (
const auto &link : m_user_data.images())
699 "Image/info menu item (should be translated)",
link.title.toLocal8Bit()));
711 Links->ImageTitleList,
SLOT(clearSelection()));
717 Links->InfoTitleList,
SLOT(clearSelection()));
738 const auto &success = KStarsData::Instance()->addToUserData(
739 selectedObject->
name(),
742 adialog->desc(), QUrl(adialog->url()),
743 (adialog->isImageLink()) ? SkyObjectUserdata::LinkData::Type::image :
744 SkyObjectUserdata::LinkData::Type::website });
748 KSNotification::sorry(success.second,
i18n(
"Could not add the link."));
756void DetailDialog::createAdvancedTab()
760 if (selectedObject->
name() ==
QString(
"star") || KStarsData::Instance()->avdTree().isEmpty() ||
761 selectedObject->
type() == SkyObject::PLANET || selectedObject->
type() == SkyObject::COMET ||
762 selectedObject->
type() == SkyObject::ASTEROID)
765 Adv =
new DatabaseWidget(
this);
773void DetailDialog::createLogTab()
780 Log =
new LogWidget(
this);
783 Log->LogTitle->setPalette(titlePalette);
785 const auto &log = m_user_data.userLog;
788 Log->UserLog->setText(
i18n(
"Record here observation logs and/or data on %1.",
791 Log->UserLog->setText(log);
806 if (m_CurrentLink ==
nullptr)
809 if (m_CurrentLink->
listWidget() == Links->InfoTitleList)
811 URL = m_user_data.websites()
812 .at(Links->InfoTitleList->row(m_CurrentLink))
815 else if (m_CurrentLink->
listWidget() == Links->ImageTitleList)
817 URL = m_user_data.images()
818 .at(Links->ImageTitleList->row(m_CurrentLink))
828 Links->InfoTitleList->clear();
829 Links->ImageTitleList->clear();
831 for (
const auto &element : m_user_data.websites())
832 Links->InfoTitleList->addItem(element.title);
834 for (
const auto &element : m_user_data.images())
835 Links->ImageTitleList->addItem(element.title);
843 if (!Links->InfoTitleList->selectedItems().isEmpty() || !Links->ImageTitleList->selectedItems().isEmpty())
855 SkyObjectUserdata::Type type = SkyObjectUserdata::Type::image;
858 if (m_CurrentLink ==
nullptr)
877 if (m_CurrentLink->
listWidget() == Links->InfoTitleList)
879 row = Links->InfoTitleList->row(m_CurrentLink);
880 type = SkyObjectUserdata::Type::website;
882 else if (m_CurrentLink->
listWidget() == Links->ImageTitleList)
884 row = Links->ImageTitleList->row(m_CurrentLink);
885 type = SkyObjectUserdata::Type::image;
890 const auto ¤tItem = m_user_data.links.at(type).at(row);
922 const auto &success = KStarsData::Instance()->editUserData(
923 selectedObject->
name(), row,
924 { editNameField.text(), QUrl{ editLinkField.text() }, type });
927 KSNotification::sorry(success.second,
i18n(
"Could not edit the entry."));
930 if (type == SkyObjectUserdata::Type::website)
931 Links->InfoTitleList->setCurrentRow(row);
933 Links->ImageTitleList->setCurrentRow(row);
942 if (m_CurrentLink ==
nullptr)
945 SkyObjectUserdata::Type type;
947 if (m_CurrentLink->
listWidget() == Links->InfoTitleList)
949 row = Links->InfoTitleList->row(m_CurrentLink);
950 type = SkyObjectUserdata::Type::website;
952 else if (m_CurrentLink->
listWidget() == Links->ImageTitleList)
954 row = Links->ImageTitleList->row(m_CurrentLink);
955 type = SkyObjectUserdata::Type::image;
962 i18n(
"Are you sure you want to remove the %1 link?", m_CurrentLink->
text()),
963 i18n(
"Delete Confirmation"),
967 const auto &success =
968 KStarsData::Instance()->deleteUserData(selectedObject->
name(), row, type);
971 KSNotification::sorry(success.second,
i18n(
"Could not delete the entry."));
976void DetailDialog::populateADVTree()
983 foreach (ADVTreeData *item, KStarsData::Instance()->avdTree())
992 Adv->ADVTree->addTopLevelItem(temp);
1020 foreach (ADVTreeData *item, KStarsData::Instance()->avdTree())
1022 if (item->Name == current->
text(0))
1025 link = parseADVData(link);
1038 if ((index = link.indexOf(
"KSOBJ")) != -1)
1040 link.remove(index, 5);
1041 link = link.insert(index, selectedObject->
name());
1044 if ((index =
link.indexOf(
"KSRA")) != -1)
1046 link.remove(index, 4);
1048 selectedObject->
ra0().second());
1054 if ((index =
link.indexOf(
"KSDEC")) != -1)
1056 link.remove(index, 5);
1057 if (selectedObject->
dec().degree() < 0)
1060 selectedObject->
dec0().arcsec());
1067 selectedObject->
dec0().arcsec());
1080 const auto &success = KStarsData::Instance()->updateUserLog(
1081 selectedObject->
name(), Log->UserLog->toPlainText());
1084 KSNotification::sorry(success.second,
i18n(
"Could not update the user log."));
1089 KStarsData::Instance()->observingList()->slotAddObject(selectedObject);
1094 SkyMap::Instance()->setClickedObject(selectedObject);
1095 SkyMap::Instance()->slotCenter();
1102 if (INDIListener::Instance()->
size() == 0)
1104 KSNotification::sorry(
i18n(
"No connected mounts found."));
1108 for (
auto &
oneDevice : INDIListener::devices())
1110 if (!(
oneDevice->getDriverInterface() & INDI::BaseDevice::TELESCOPE_INTERFACE))
1115 KSNotification::error(
i18n(
"Mount %1 is offline. Please connect and retry again.",
oneDevice->getDeviceName()));
1124 if (selectedObject && selectedObject->
name() ==
i18n(
"Sun"))
1127 i18n(
"Danger! Viewing the Sun without adequate solar filters is dangerous and will result in permanent eye damage!"))
1132 mount->Slew(selectedObject);
1136 KSNotification::sorry(
i18n(
"No connected mounts found."));
1144 if (selectedObject->
type() == SkyObject::STAR ||
1145 selectedObject->
type() == SkyObject::CATALOG_STAR)
1147 Thumbnail->scaled(Data->Image->
width(), Data->Image->
height());
1149 Data->Image->setPixmap(*Thumbnail);
1165 "thumb-" + selectedObject->
name().toLower().remove(
' ').remove(
'/') +
1168 const QFile file{ path };
1171 Thumbnail->load(path,
"PNG");
1177 Thumbnail->load(
":/images/noimage.png");
1179 *Thumbnail = Thumbnail->scaled(Data->Image->
width(), Data->Image->
height(),
1182 Data->Image->setPixmap(*Thumbnail);
1195 .
filePath(
"thumb-" + selectedObject->
name().toLower().remove(
' ').remove(
'/') +
".png");
1197 Data->Image->setPixmap(*(tp->image()));
1201 if (tp->imageFound())
1203#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
1204 bool rc = Data->Image->pixmap()->save(
fname,
"PNG");
1207 KSNotification::error(
i18n(
"Unable to save image to %1",
fname),
1208 i18n(
"Save Thumbnail"));
1211 *Thumbnail = *(Data->Image->pixmap());
1216 KSNotification::error(
i18n(
"Unable to save image to %1",
fname),
1217 i18n(
"Save Thumbnail"));
1226 f.setFileName(
fname);
AddLinkDialog is a simple dialog for adding a custom URL to a popup menu.
A simple container object to hold the minimum information for a Deep Sky Object to be drawn on the sk...
void centerMap()
Slot to center this object in the display.
void removeLinkDialog()
remove a URL entry from either the Images or Info lists, and update the user's *url....
void showThumbnail()
Slot to display the thumbnail image for the object.
void setCurrentLink(QListWidgetItem *it)
Set the currently-selected URL resource.
void centerTelescope()
Slot to center this object in the telescope.
void updateLists()
Rebuild the Image and Info URL lists for this object.
void saveLogData()
Save the User's text in the Log Tab to the userlog.dat file.
void viewADVData()
Open the web browser to the selected online astronomy database, with a query to the object of this De...
void editLinkDialog()
Open a dialog to edit a URL in either the Images or Info lists, and update the user's *url....
void updateThumbnail()
Slot to update thumbnail image for the object, using the Thumbnail Picker tool.
void updateButtons()
Update View/Edit/Remove buttons.
void addToObservingList()
Slot to add this object to the observing list.
void viewLink()
Slot for viewing the selected image or info URL in the web browser.
DetailDialog(SkyObject *o, const KStarsDateTime &ut, GeoLocation *geo, QWidget *parent=nullptr)
Constructor.
void addLink()
Popup menu function: Add a custom Image or Information URL.
Contains all relevant information for specifying a location on Earth: City Name, State/Province name,...
const CachingDms * lat() const
QDialogButtonBox * buttonBox()
void setStandardButtons(QDialogButtonBox::StandardButtons buttons)
void setFaceType(FaceType faceType)
void addPage(KPageWidgetItem *item)
A subclass of KSPlanetBase that implements asteroids.
A subclass of KSPlanetBase that implements comets.
Provides necessary information about the Moon.
A subclass of TrailObject that provides additional information needed for most solar system objects.
void updateCoords(const KSNumbers *num, bool includePlanets=true, const CachingDms *lat=nullptr, const CachingDms *LST=nullptr, bool forceRecompute=false) override
Update position of the planet (reimplemented from SkyPoint)
KStarsData is the backbone of KStars.
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
static double jdToEpoch(long double jd, EpochType type=JULIAN)
Takes in a Julian Date and returns the corresponding epoch year in the given system.
KStarsDateTime addDays(int nd) const
Modify the Date/Time by adding a number of days.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
QString translatedName() const
dms riseSetTimeAz(const KStarsDateTime &dt, const GeoLocation *geo, bool rst) const
virtual QString name(void) const
dms transitAltitude(const KStarsDateTime &dt, const GeoLocation *geo) const
bool isSolarSystem() const
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.
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 getLastPrecessJD() const
const CachingDms & dec() const
const CachingDms & ra0() const
const CachingDms & ra() const
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
const CachingDms & dec0() const
This is a subclass of SkyObject.
QString longname(void) const override
If star is unnamed return "star" otherwise return the longname.
QString sptype(void) const
Returns entire spectral type string.
Represents the supernova object.
Dialog for modifying an object's thumbnail image.
An angle, stored as degrees, but expressible in many ways.
const QString toDMSString(const bool forceSign=false, const bool machineReadable=false, const bool highPrecision=false) const
const double & Degrees() const
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
char * toString(const EngineQuery &query)
KIOCORE_EXPORT CopyJob * link(const QList< QUrl > &src, const QUrl &destDir, JobFlags flags=DefaultFlags)
GeoCoordinates geo(const QVariant &location)
ButtonCode warningContinueCancel(QWidget *parent, const QString &text, const QString &title=QString(), const KGuiItem &buttonContinue=KStandardGuiItem::cont(), const KGuiItem &buttonCancel=KStandardGuiItem::cancel(), const QString &dontAskAgainName=QString(), Options options=Notify)
void addLayout(QLayout *layout, int stretch)
bool openUrl(const QUrl &url)
QString absoluteFilePath(const QString &fileName) const const
QString filePath(const QString &fileName) const const
bool mkpath(const QString &dirPath) const const
bool hasNext() const const
void setFrameStyle(int style)
void setOpenExternalLinks(bool open)
void setTextFormat(Qt::TextFormat)
void setTextInteractionFlags(Qt::TextInteractionFlags flags)
QString text() const const
QString toString(QDate date, FormatType format) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QObject * parent() const const
void setObjectName(QAnyStringView name)
void setColor(ColorGroup group, ColorRole role, const QColor &color)
QString arg(Args &&... args) const const
QString asprintf(const char *cformat,...)
QString number(double n, char format, int precision)
QByteArray toLocal8Bit() const const
QString text(int column) const const
Stores the tite and URL of a webpage.