File indexing completed on 2024-04-28 07:32:11
0001 /* 0002 SPDX-FileCopyrightText: 2011 Rafał Kułaga <rl.kulaga@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "detailstable.h" 0008 0009 #include <QTextDocument> 0010 #include <QTextTable> 0011 0012 #include "kstars.h" 0013 #include "kstarsdata.h" 0014 #include "ksplanetbase.h" 0015 #include "starobject.h" 0016 #include "skymapcomposite.h" 0017 #include "constellationboundarylines.h" 0018 #include "catalogobject.h" 0019 #include "ksmoon.h" 0020 #include "ksasteroid.h" 0021 #include "kscomet.h" 0022 #include "Options.h" 0023 #include "catalogsdb.h" 0024 0025 DetailsTable::DetailsTable() 0026 { 0027 m_Document = new QTextDocument(KStars::Instance()); 0028 0029 setDefaultFormatting(); 0030 } 0031 0032 DetailsTable::~DetailsTable() 0033 { 0034 if (m_Document) 0035 { 0036 delete m_Document; 0037 } 0038 } 0039 0040 void DetailsTable::createGeneralTable(SkyObject *obj) 0041 { 0042 clearContents(); 0043 0044 QTextCursor cursor = m_Document->rootFrame()->firstCursorPosition(); 0045 0046 //Fill in the data fields 0047 //Contents depend on type of object 0048 StarObject *s = nullptr; 0049 CatalogObject *dso = nullptr; 0050 KSPlanetBase *ps = nullptr; 0051 QString pname, oname; 0052 0053 QString objNamesVal, objTypeVal, objDistVal, objSizeVal, objMagVal, objBvVal, objIllumVal; 0054 QString objSizeLabel, objMagLabel; 0055 0056 switch (obj->type()) 0057 { 0058 case SkyObject::STAR: 0059 { 0060 s = (StarObject *)obj; 0061 0062 objNamesVal = s->longname(); 0063 0064 if (s->getHDIndex() != 0) 0065 { 0066 if (!s->longname().isEmpty()) 0067 { 0068 objNamesVal = s->longname() + QString(", HD%1").arg(QString::number(s->getHDIndex())); 0069 } 0070 0071 else 0072 { 0073 objNamesVal = QString(", HD%1").arg(QString::number(s->getHDIndex())); 0074 } 0075 } 0076 0077 objTypeVal = s->sptype() + ' ' + i18n("star"); 0078 objMagVal = i18nc("number in magnitudes", "%1 mag", QLocale().toString(s->mag(), 1)); //show to tenths place 0079 0080 if (s->getBVIndex() < 30.0) 0081 { 0082 objBvVal = QString::number(s->getBVIndex(), 'g', 2); 0083 } 0084 0085 //distance 0086 if (s->distance() > 2000. || s->distance() < 0.) // parallax < 0.5 mas 0087 { 0088 objDistVal = i18nc("larger than 2000 parsecs", "> 2000 pc"); 0089 } 0090 0091 else if (s->distance() > 50.0) //show to nearest integer 0092 { 0093 objDistVal = i18nc("number in parsecs", "%1 pc", QLocale().toString(s->distance(), 0)); 0094 } 0095 0096 else if (s->distance() > 10.0) //show to tenths place 0097 { 0098 objDistVal = i18nc("number in parsecs", "%1 pc", QLocale().toString(s->distance(), 1)); 0099 } 0100 0101 else //show to hundredths place 0102 { 0103 objDistVal = i18nc("number in parsecs", "%1 pc", QLocale().toString(s->distance(), 2)); 0104 } 0105 0106 //Note multiplicity/variability in angular size label 0107 if (s->isMultiple() && s->isVariable()) 0108 { 0109 objSizeLabel = i18nc("the star is a multiple star", "multiple") + ','; 0110 objSizeVal = i18nc("the star is a variable star", "variable"); 0111 } 0112 0113 else if (s->isMultiple()) 0114 { 0115 objSizeLabel = i18nc("the star is a multiple star", "multiple"); 0116 } 0117 0118 else if (s->isVariable()) 0119 { 0120 objSizeLabel = i18nc("the star is a variable star", "variable"); 0121 } 0122 0123 objIllumVal = "--"; 0124 0125 break; //End of stars case 0126 } 0127 0128 case SkyObject::ASTEROID: //[fall through to planets] 0129 0130 case SkyObject::COMET: //[fall through to planets] 0131 0132 case SkyObject::MOON: //[fall through to planets] 0133 0134 case SkyObject::PLANET: 0135 { 0136 ps = dynamic_cast<KSPlanetBase *>(obj); 0137 0138 objNamesVal = ps->longname(); 0139 //Type is "G5 star" for Sun 0140 if (ps->name() == i18n("Sun")) 0141 { 0142 objTypeVal = i18n("G5 star"); 0143 } 0144 0145 else if (ps->name() == i18n("Moon")) 0146 { 0147 objTypeVal = ps->translatedName(); 0148 } 0149 0150 else if (ps->name() == i18nc("Asteroid name (optional)", "Pluto") || ps->name() == i18nc("Asteroid name (optional)", "Ceres") || 0151 ps->name() == i18nc("Asteroid name (optional)", "Eris")) // TODO: Check if Ceres / Eris have translations and i18n() them 0152 { 0153 objTypeVal = i18n("Dwarf planet"); 0154 } 0155 0156 else 0157 { 0158 objTypeVal = ps->typeName(); 0159 } 0160 0161 //Magnitude: The moon displays illumination fraction instead 0162 if (obj->name() == i18n("Moon")) 0163 { 0164 KSMoon * const m = dynamic_cast<KSMoon *>(obj); 0165 if (m) 0166 objIllumVal = QString("%1 %").arg(QLocale().toString(m->illum() * 100., 0)); 0167 } 0168 0169 objMagVal = 0170 i18nc("number in magnitudes", "%1 mag", QLocale().toString(ps->mag(), 1)); //show to tenths place 0171 0172 //Distance from Earth. The moon requires a unit conversion 0173 if (ps->name() == i18n("Moon")) 0174 { 0175 objDistVal = i18nc("distance in kilometers", "%1 km", QLocale().toString(ps->rearth() * AU_KM)); 0176 } 0177 0178 else 0179 { 0180 objDistVal = i18nc("distance in Astronomical Units", "%1 AU", QLocale().toString(ps->rearth())); 0181 } 0182 0183 //Angular size; moon and sun in arcmin, others in arcsec 0184 if (ps->angSize()) 0185 { 0186 if (ps->name() == i18n("Sun") || ps->name() == i18n("Moon")) 0187 { 0188 // Needn't be a plural form because sun / moon will never contract to 1 arcminute 0189 objSizeVal = i18nc("angular size in arcminutes", "%1 arcmin", QLocale().toString(ps->angSize())); 0190 } 0191 0192 else 0193 { 0194 objSizeVal = 0195 i18nc("angular size in arcseconds", "%1 arcsec", QLocale().toString(ps->angSize() * 60.0)); 0196 } 0197 } 0198 0199 else 0200 { 0201 objSizeVal = "--"; 0202 } 0203 0204 break; //End of planets/comets/asteroids case 0205 } 0206 0207 default: //Deep-sky objects 0208 { 0209 dso = (CatalogObject *)obj; 0210 0211 //Show all names recorded for the object 0212 if (!dso->longname().isEmpty() && dso->longname() != dso->name()) 0213 { 0214 pname = dso->translatedLongName(); 0215 oname = dso->translatedName(); 0216 } 0217 0218 else 0219 { 0220 pname = dso->translatedName(); 0221 } 0222 0223 if (!dso->translatedName2().isEmpty()) 0224 { 0225 if (oname.isEmpty()) 0226 { 0227 oname = dso->translatedName2(); 0228 } 0229 0230 else 0231 { 0232 oname += ", " + dso->translatedName2(); 0233 } 0234 } 0235 0236 0237 if (!oname.isEmpty()) 0238 { 0239 pname += ", " + oname; 0240 } 0241 0242 objNamesVal = pname; 0243 0244 objTypeVal = dso->typeName(); 0245 0246 if (dso->type() == SkyObject::RADIO_SOURCE) 0247 { 0248 objMagLabel = 0249 i18nc("integrated flux at a frequency", "Flux(%1):", CatalogsDB::flux_frequency); 0250 objMagVal = i18nc("integrated flux value", "%1 %2", QLocale().toString(dso->flux(), 1), 0251 CatalogsDB::flux_unit); //show to tenths place 0252 } 0253 0254 if (dso->mag() > 90.0) 0255 { 0256 objMagVal = "--"; 0257 } 0258 0259 else 0260 { 0261 objMagVal = 0262 i18nc("number in magnitudes", "%1 mag", QLocale().toString(dso->mag(), 1)); //show to tenths place 0263 } 0264 0265 //No distances at this point... 0266 objDistVal = "--"; 0267 0268 //Only show decimal place for small angular sizes 0269 if (dso->a() > 10.0) 0270 { 0271 objSizeVal = i18nc("angular size in arcminutes", "%1 arcmin", QLocale().toString(dso->a(), 0)); 0272 } 0273 0274 else if (dso->a()) 0275 { 0276 objSizeVal = i18nc("angular size in arcminutes", "%1 arcmin", QLocale().toString(dso->a(), 1)); 0277 } 0278 0279 else 0280 { 0281 objSizeVal = "--"; 0282 } 0283 0284 break; //End of deep-space objects case 0285 } 0286 } 0287 0288 //Common to all types: 0289 if (obj->type() == SkyObject::CONSTELLATION) 0290 { 0291 objTypeVal = KStarsData::Instance()->skyComposite()->constellationBoundary()->constellationName(obj); 0292 } 0293 0294 else 0295 { 0296 objTypeVal = 0297 i18nc("%1 type of sky object (planet, asteroid etc), %2 name of a constellation", "%1 in %2", objTypeVal, 0298 KStarsData::Instance()->skyComposite()->constellationBoundary()->constellationName(obj)); 0299 } 0300 0301 QVector<QTextLength> constraints; 0302 constraints << QTextLength(QTextLength::PercentageLength, 25) << QTextLength(QTextLength::PercentageLength, 25) 0303 << QTextLength(QTextLength::PercentageLength, 25) << QTextLength(QTextLength::PercentageLength, 25); 0304 m_TableFormat.setColumnWidthConstraints(constraints); 0305 0306 QTextTable *table = cursor.insertTable(5, 4, m_TableFormat); 0307 table->mergeCells(0, 0, 1, 4); 0308 QTextBlockFormat centered; 0309 centered.setAlignment(Qt::AlignCenter); 0310 table->cellAt(0, 0).firstCursorPosition().setBlockFormat(centered); 0311 table->cellAt(0, 0).firstCursorPosition().insertText(i18n("General"), m_TableTitleCharFormat); 0312 0313 table->mergeCells(1, 1, 1, 3); 0314 table->cellAt(1, 0).firstCursorPosition().insertText(i18n("Names:"), m_ItemNameCharFormat); 0315 table->cellAt(1, 0).firstCursorPosition().setBlockFormat(centered); 0316 table->cellAt(1, 1).firstCursorPosition().insertText(objNamesVal, m_ItemValueCharFormat); 0317 0318 table->cellAt(2, 0).firstCursorPosition().insertText(i18n("Type:"), m_ItemNameCharFormat); 0319 table->cellAt(2, 0).firstCursorPosition().setBlockFormat(centered); 0320 table->cellAt(2, 1).firstCursorPosition().insertText(objTypeVal, m_ItemValueCharFormat); 0321 0322 table->cellAt(3, 0).firstCursorPosition().insertText(i18n("Distance:"), m_ItemNameCharFormat); 0323 table->cellAt(3, 0).firstCursorPosition().setBlockFormat(centered); 0324 table->cellAt(3, 1).firstCursorPosition().insertText(objDistVal, m_ItemValueCharFormat); 0325 0326 table->cellAt(4, 0).firstCursorPosition().insertText(i18n("Size:"), m_ItemNameCharFormat); 0327 table->cellAt(4, 0).firstCursorPosition().setBlockFormat(centered); 0328 table->cellAt(4, 1).firstCursorPosition().insertText(objSizeVal, m_ItemValueCharFormat); 0329 0330 table->cellAt(2, 2).firstCursorPosition().insertText(i18n("Magnitude:"), m_ItemNameCharFormat); 0331 table->cellAt(2, 2).firstCursorPosition().setBlockFormat(centered); 0332 table->cellAt(2, 3).firstCursorPosition().insertText(objMagVal, m_ItemValueCharFormat); 0333 0334 table->cellAt(3, 2).firstCursorPosition().insertText(i18n("B-V index:"), m_ItemNameCharFormat); 0335 table->cellAt(3, 2).firstCursorPosition().setBlockFormat(centered); 0336 table->cellAt(3, 3).firstCursorPosition().insertText(objBvVal, m_ItemValueCharFormat); 0337 0338 table->cellAt(4, 2).firstCursorPosition().insertText(i18n("Illumination:"), m_ItemNameCharFormat); 0339 table->cellAt(4, 2).firstCursorPosition().setBlockFormat(centered); 0340 table->cellAt(4, 3).firstCursorPosition().insertText(objIllumVal, m_ItemValueCharFormat); 0341 } 0342 0343 void DetailsTable::createAsteroidCometTable(SkyObject *obj) 0344 { 0345 clearContents(); 0346 0347 QTextCursor cursor = m_Document->rootFrame()->firstCursorPosition(); 0348 0349 QString perihelionVal, orbitIdVal, neoVal, diamVal, rotPeriodVal, moidVal; 0350 QString orbitClassVal, albedoVal, dimVal, periodVal; 0351 0352 // Add specifics data 0353 switch (obj->type()) 0354 { 0355 case SkyObject::ASTEROID: 0356 { 0357 KSAsteroid *ast = (KSAsteroid *)obj; 0358 0359 // Perihelion 0360 perihelionVal = QString::number(ast->getPerihelion()) + " AU"; 0361 0362 // Earth MOID 0363 moidVal = ast->getEarthMOID() == 0 ? QString("--") : QString::number(ast->getEarthMOID()) + QString(" AU"); 0364 0365 // Orbit ID 0366 orbitIdVal = ast->getOrbitID(); 0367 0368 // Orbit Class 0369 orbitClassVal = ast->getOrbitClass(); 0370 0371 // NEO 0372 neoVal = ast->isNEO() ? i18n("Yes") : i18n("No"); 0373 0374 // Albedo 0375 albedoVal = ast->getAlbedo() == 0 ? QString("--") : QString::number(ast->getAlbedo()); 0376 0377 // Diameter 0378 diamVal = ast->getDiameter() == 0 ? QString("--") : QString::number(ast->getDiameter()) + QString(" km"); 0379 0380 // Dimensions 0381 dimVal = ast->getDimensions().isEmpty() ? QString("--") : ast->getDimensions() + QString(" km"); 0382 0383 // Rotation period 0384 rotPeriodVal = ast->getRotationPeriod() == 0 ? QString("--") : 0385 QString::number(ast->getRotationPeriod()) + QString(" h"); 0386 0387 // Period 0388 periodVal = ast->getPeriod() == 0 ? QString("--") : QString::number(ast->getPeriod()) + QString(" y"); 0389 0390 break; 0391 } 0392 0393 case SkyObject::COMET: 0394 { 0395 KSComet *com = (KSComet *)obj; 0396 0397 // Perihelion 0398 perihelionVal = QString::number(com->getPerihelion()) + " AU"; 0399 0400 // Earth MOID 0401 moidVal = com->getEarthMOID() == 0 ? QString("--") : QString::number(com->getEarthMOID()) + QString(" AU"); 0402 0403 // Orbit ID 0404 orbitIdVal = com->getOrbitID(); 0405 0406 // Orbit Class 0407 orbitClassVal = com->getOrbitClass(); 0408 0409 // NEO 0410 neoVal = com->isNEO() ? i18n("Yes") : i18n("No"); 0411 0412 // Albedo 0413 albedoVal = com->getAlbedo() == 0 ? QString("--") : QString::number(com->getAlbedo()); 0414 0415 // Diameter 0416 diamVal = com->getDiameter() == 0 ? QString("--") : QString::number(com->getDiameter()) + QString(" km"); 0417 0418 // Dimensions 0419 dimVal = com->getDimensions().isEmpty() ? QString("--") : com->getDimensions() + QString(" km"); 0420 0421 // Rotation period 0422 rotPeriodVal = com->getRotationPeriod() == 0 ? QString("--") : 0423 QString::number(com->getRotationPeriod()) + QString(" h"); 0424 0425 // Period 0426 periodVal = com->getPeriod() == 0 ? QString("--") : QString::number(com->getPeriod()) + QString(" y"); 0427 0428 break; 0429 } 0430 0431 default: 0432 { 0433 return; 0434 } 0435 } 0436 0437 // Set column width constraints 0438 QVector<QTextLength> constraints; 0439 constraints << QTextLength(QTextLength::PercentageLength, 25) << QTextLength(QTextLength::PercentageLength, 25) 0440 << QTextLength(QTextLength::PercentageLength, 25) << QTextLength(QTextLength::PercentageLength, 25); 0441 m_TableFormat.setColumnWidthConstraints(constraints); 0442 0443 QTextTable *table = cursor.insertTable(6, 4, m_TableFormat); 0444 table->mergeCells(0, 0, 1, 4); 0445 QTextBlockFormat centered; 0446 centered.setAlignment(Qt::AlignCenter); 0447 table->cellAt(0, 0).firstCursorPosition().setBlockFormat(centered); 0448 table->cellAt(0, 0).firstCursorPosition().insertText(i18n("Asteroid/Comet details"), m_TableTitleCharFormat); 0449 0450 table->cellAt(1, 0).firstCursorPosition().insertText(i18n("Perihelion:"), m_ItemNameCharFormat); 0451 table->cellAt(1, 0).firstCursorPosition().setBlockFormat(centered); 0452 table->cellAt(1, 1).firstCursorPosition().insertText(perihelionVal, m_ItemValueCharFormat); 0453 0454 table->cellAt(2, 0).firstCursorPosition().insertText(i18n("Orbit ID:"), m_ItemNameCharFormat); 0455 table->cellAt(2, 0).firstCursorPosition().setBlockFormat(centered); 0456 table->cellAt(2, 1).firstCursorPosition().insertText(orbitIdVal, m_ItemValueCharFormat); 0457 0458 table->cellAt(3, 0).firstCursorPosition().insertText(i18n("NEO:"), m_ItemNameCharFormat); 0459 table->cellAt(3, 0).firstCursorPosition().setBlockFormat(centered); 0460 table->cellAt(3, 1).firstCursorPosition().insertText(neoVal, m_ItemValueCharFormat); 0461 0462 table->cellAt(4, 0).firstCursorPosition().insertText(i18n("Diameter:"), m_ItemNameCharFormat); 0463 table->cellAt(4, 0).firstCursorPosition().setBlockFormat(centered); 0464 table->cellAt(4, 1).firstCursorPosition().insertText(diamVal, m_ItemValueCharFormat); 0465 0466 table->cellAt(5, 0).firstCursorPosition().insertText(i18n("Rotation period:"), m_ItemNameCharFormat); 0467 table->cellAt(5, 0).firstCursorPosition().setBlockFormat(centered); 0468 table->cellAt(5, 1).firstCursorPosition().insertText(rotPeriodVal, m_ItemValueCharFormat); 0469 0470 table->cellAt(1, 2).firstCursorPosition().insertText(i18n("Earth MOID:"), m_ItemNameCharFormat); 0471 table->cellAt(1, 2).firstCursorPosition().setBlockFormat(centered); 0472 table->cellAt(1, 3).firstCursorPosition().insertText(moidVal, m_ItemValueCharFormat); 0473 0474 table->cellAt(2, 2).firstCursorPosition().insertText(i18n("Orbit class:"), m_ItemNameCharFormat); 0475 table->cellAt(2, 2).firstCursorPosition().setBlockFormat(centered); 0476 table->cellAt(2, 3).firstCursorPosition().insertText(orbitClassVal, m_ItemValueCharFormat); 0477 0478 table->cellAt(3, 2).firstCursorPosition().insertText(i18n("Albedo:"), m_ItemNameCharFormat); 0479 table->cellAt(3, 2).firstCursorPosition().setBlockFormat(centered); 0480 table->cellAt(3, 3).firstCursorPosition().insertText(albedoVal, m_ItemValueCharFormat); 0481 0482 table->cellAt(4, 2).firstCursorPosition().insertText(i18n("Dimensions:"), m_ItemNameCharFormat); 0483 table->cellAt(4, 2).firstCursorPosition().setBlockFormat(centered); 0484 table->cellAt(4, 3).firstCursorPosition().insertText(dimVal, m_ItemValueCharFormat); 0485 0486 table->cellAt(5, 2).firstCursorPosition().insertText(i18n("Period:"), m_ItemNameCharFormat); 0487 table->cellAt(5, 2).firstCursorPosition().setBlockFormat(centered); 0488 table->cellAt(5, 3).firstCursorPosition().insertText(periodVal, m_ItemValueCharFormat); 0489 } 0490 0491 void DetailsTable::createCoordinatesTable(SkyObject *obj, const KStarsDateTime &ut, GeoLocation *geo) 0492 { 0493 clearContents(); 0494 0495 QTextCursor cursor = m_Document->rootFrame()->firstCursorPosition(); 0496 0497 // Set column width constraints 0498 QVector<QTextLength> constraints; 0499 constraints << QTextLength(QTextLength::PercentageLength, 25) << QTextLength(QTextLength::PercentageLength, 25) 0500 << QTextLength(QTextLength::PercentageLength, 25) << QTextLength(QTextLength::PercentageLength, 25); 0501 m_TableFormat.setColumnWidthConstraints(constraints); 0502 0503 // Insert table & row containing table name 0504 QTextTable *table = cursor.insertTable(4, 4, m_TableFormat); 0505 table->mergeCells(0, 0, 1, 4); 0506 QTextBlockFormat centered; 0507 centered.setAlignment(Qt::AlignCenter); 0508 table->cellAt(0, 0).firstCursorPosition().setBlockFormat(centered); 0509 table->cellAt(0, 0).firstCursorPosition().insertText(i18n("Coordinates"), m_TableTitleCharFormat); 0510 0511 //Coordinates Section: 0512 //Don't use KLocale::formatNumber() for the epoch string, 0513 //because we don't want a thousands-place separator! 0514 QString sEpoch = QString::number(ut.epoch(), 'f', 1); 0515 //Replace the decimal point with localized decimal symbol 0516 sEpoch.replace('.', QLocale().decimalPoint()); 0517 0518 table->cellAt(1, 0).firstCursorPosition().insertText(i18n("RA (%1):", sEpoch), m_ItemNameCharFormat); 0519 table->cellAt(1, 0).firstCursorPosition().setBlockFormat(centered); 0520 table->cellAt(1, 1).firstCursorPosition().insertText(obj->ra().toHMSString(), m_ItemValueCharFormat); 0521 0522 table->cellAt(2, 0).firstCursorPosition().insertText(i18n("Dec (%1):", sEpoch), m_ItemNameCharFormat); 0523 table->cellAt(2, 0).firstCursorPosition().setBlockFormat(centered); 0524 table->cellAt(2, 1).firstCursorPosition().insertText(obj->dec().toDMSString(), m_ItemValueCharFormat); 0525 0526 table->cellAt(3, 0).firstCursorPosition().insertText(i18n("Hour angle:"), m_ItemNameCharFormat); 0527 table->cellAt(3, 0).firstCursorPosition().setBlockFormat(centered); 0528 //Hour Angle can be negative, but dms HMS expressions cannot. 0529 //Here's a kludgy workaround: 0530 dms lst = geo->GSTtoLST(ut.gst()); 0531 dms ha(lst.Degrees() - obj->ra().Degrees()); 0532 QChar sgn('+'); 0533 if (ha.Hours() > 12.0) 0534 { 0535 ha.setH(24.0 - ha.Hours()); 0536 sgn = '-'; 0537 } 0538 table->cellAt(3, 1).firstCursorPosition().insertText(QString("%1%2").arg(sgn).arg(ha.toHMSString()), 0539 m_ItemValueCharFormat); 0540 0541 table->cellAt(1, 2).firstCursorPosition().insertText(i18n("Azimuth:"), m_ItemNameCharFormat); 0542 table->cellAt(1, 2).firstCursorPosition().setBlockFormat(centered); 0543 table->cellAt(1, 3).firstCursorPosition().insertText(obj->az().toDMSString(), m_ItemValueCharFormat); 0544 0545 table->cellAt(2, 2).firstCursorPosition().insertText(i18n("Altitude:"), m_ItemNameCharFormat); 0546 table->cellAt(2, 2).firstCursorPosition().setBlockFormat(centered); 0547 dms a; 0548 if (Options::useAltAz()) 0549 { 0550 a = obj->alt(); 0551 } 0552 0553 else 0554 { 0555 a = obj->altRefracted(); 0556 } 0557 table->cellAt(2, 3).firstCursorPosition().insertText(a.toDMSString(), m_ItemValueCharFormat); 0558 0559 table->cellAt(3, 2).firstCursorPosition().insertText(i18n("Airmass:"), m_ItemNameCharFormat); 0560 table->cellAt(3, 2).firstCursorPosition().setBlockFormat(centered); 0561 //Airmass is approximated as the secant of the zenith distance, 0562 //equivalent to 1./sin(Alt). Beware of Inf at Alt=0! 0563 QString aMassStr; 0564 if (obj->alt().Degrees() > 0.0) 0565 { 0566 aMassStr = QLocale().toString(1. / sin(obj->alt().radians()), 2); 0567 } 0568 0569 else 0570 { 0571 aMassStr = "--"; 0572 } 0573 table->cellAt(3, 3).firstCursorPosition().insertText(aMassStr, m_ItemValueCharFormat); 0574 0575 // Restore the position and other time-dependent parameters 0576 obj->recomputeCoords(ut, geo); 0577 } 0578 0579 void DetailsTable::createRSTTAble(SkyObject *obj, const KStarsDateTime &ut, GeoLocation *geo) 0580 { 0581 clearContents(); 0582 0583 QTextCursor cursor = m_Document->rootFrame()->firstCursorPosition(); 0584 0585 QString rtValue, stValue; // Rise/Set time values 0586 QString azRValue, azSValue; // Rise/Set azimuth values 0587 0588 //Prepare time/position variables 0589 QTime rt = obj->riseSetTime(ut, geo, true); //true = use rise time 0590 dms raz = obj->riseSetTimeAz(ut, geo, true); //true = use rise time 0591 0592 //If transit time is before rise time, use transit time for tomorrow 0593 QTime tt = obj->transitTime(ut, geo); 0594 dms talt = obj->transitAltitude(ut, geo); 0595 if (tt < rt) 0596 { 0597 tt = obj->transitTime(ut.addDays(1), geo); 0598 talt = obj->transitAltitude(ut.addDays(1), geo); 0599 } 0600 0601 //If set time is before rise time, use set time for tomorrow 0602 QTime st = obj->riseSetTime(ut, geo, false); //false = use set time 0603 dms saz = obj->riseSetTimeAz(ut, geo, false); //false = use set time 0604 if (st < rt) 0605 { 0606 st = obj->riseSetTime(ut.addDays(1), geo, false); //false = use set time 0607 saz = obj->riseSetTimeAz(ut.addDays(1), geo, false); //false = use set time 0608 } 0609 0610 if (rt.isValid()) 0611 { 0612 rtValue = QString::asprintf("%02d:%02d", rt.hour(), rt.minute()); 0613 stValue = QString::asprintf("%02d:%02d", st.hour(), st.minute()); 0614 azRValue = raz.toDMSString(); 0615 azSValue = saz.toDMSString(); 0616 } 0617 0618 else 0619 { 0620 if (obj->alt().Degrees() > 0.0) 0621 { 0622 rtValue = i18n("Circumpolar"); 0623 stValue = i18n("Circumpolar"); 0624 } 0625 0626 else 0627 { 0628 rtValue = i18n("Never rises"); 0629 stValue = i18n("Never rises"); 0630 } 0631 0632 azRValue = i18nc("Not Applicable", "N/A"); 0633 azSValue = i18nc("Not Applicable", "N/A"); 0634 } 0635 0636 // Set column width constraints 0637 QVector<QTextLength> constraints; 0638 constraints << QTextLength(QTextLength::PercentageLength, 25) << QTextLength(QTextLength::PercentageLength, 25) 0639 << QTextLength(QTextLength::PercentageLength, 25) << QTextLength(QTextLength::PercentageLength, 25); 0640 m_TableFormat.setColumnWidthConstraints(constraints); 0641 0642 // Insert table & row containing table name 0643 QTextTable *table = cursor.insertTable(4, 4, m_TableFormat); 0644 table->mergeCells(0, 0, 1, 4); 0645 QTextBlockFormat centered; 0646 centered.setAlignment(Qt::AlignCenter); 0647 table->cellAt(0, 0).firstCursorPosition().setBlockFormat(centered); 0648 table->cellAt(0, 0).firstCursorPosition().insertText(i18n("Rise/Set/Transit"), m_TableTitleCharFormat); 0649 0650 // Insert cell names & values 0651 table->cellAt(1, 0).firstCursorPosition().insertText(i18n("Rise time:"), m_ItemNameCharFormat); 0652 table->cellAt(1, 0).firstCursorPosition().setBlockFormat(centered); 0653 table->cellAt(1, 1).firstCursorPosition().insertText(rtValue, m_ItemValueCharFormat); 0654 0655 table->cellAt(2, 0).firstCursorPosition().insertText(i18n("Transit time:"), m_ItemNameCharFormat); 0656 table->cellAt(2, 0).firstCursorPosition().setBlockFormat(centered); 0657 table->cellAt(2, 1).firstCursorPosition().insertText(QString::asprintf("%02d:%02d", tt.hour(), tt.minute()), 0658 m_ItemValueCharFormat); 0659 0660 table->cellAt(3, 0).firstCursorPosition().insertText(i18n("Set time:"), m_ItemNameCharFormat); 0661 table->cellAt(3, 0).firstCursorPosition().setBlockFormat(centered); 0662 table->cellAt(3, 1).firstCursorPosition().insertText(stValue, m_ItemValueCharFormat); 0663 0664 table->cellAt(1, 2).firstCursorPosition().insertText(i18n("Azimuth at rise:"), m_ItemNameCharFormat); 0665 table->cellAt(1, 2).firstCursorPosition().setBlockFormat(centered); 0666 table->cellAt(1, 3).firstCursorPosition().insertText(azRValue, m_ItemValueCharFormat); 0667 0668 table->cellAt(2, 2).firstCursorPosition().insertText(i18n("Altitude at transit:"), m_ItemNameCharFormat); 0669 table->cellAt(2, 2).firstCursorPosition().setBlockFormat(centered); 0670 table->cellAt(2, 3).firstCursorPosition().insertText(talt.toDMSString(), m_ItemValueCharFormat); 0671 0672 table->cellAt(3, 2).firstCursorPosition().insertText(i18n("Azimuth at set:"), m_ItemNameCharFormat); 0673 table->cellAt(3, 2).firstCursorPosition().setBlockFormat(centered); 0674 table->cellAt(3, 3).firstCursorPosition().insertText(azSValue, m_ItemValueCharFormat); 0675 0676 // Restore the position and other time-dependent parameters 0677 obj->recomputeCoords(ut, geo); 0678 } 0679 0680 void DetailsTable::clearContents() 0681 { 0682 m_Document->clear(); 0683 } 0684 0685 void DetailsTable::setDefaultFormatting() 0686 { 0687 // Set default table format 0688 m_TableFormat.setAlignment(Qt::AlignCenter); 0689 m_TableFormat.setBorder(4); 0690 m_TableFormat.setCellPadding(2); 0691 m_TableFormat.setCellSpacing(2); 0692 0693 // Set default table title character format 0694 m_TableTitleCharFormat.setFont(QFont("Times", 12, QFont::Bold)); 0695 m_TableTitleCharFormat.setFontCapitalization(QFont::Capitalize); 0696 0697 // Set default table item name character format 0698 m_ItemNameCharFormat.setFont(QFont("Times", 10, QFont::Bold)); 0699 0700 // Set default table item value character format 0701 m_ItemValueCharFormat.setFont(QFont("Times", 10)); 0702 }