File indexing completed on 2024-04-28 07:32:43
0001 /* 0002 SPDX-FileCopyrightText: 2009 Khudyakov Alexey <alexey.skladnoy@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "infoboxwidget.h" 0008 0009 #include "colorscheme.h" 0010 #include "kstarsdata.h" 0011 #include "ksutils.h" 0012 0013 #include <KLocalizedString> 0014 0015 #include <QPainter> 0016 #include <QMouseEvent> 0017 #include <QFontMetrics> 0018 #include <QLocale> 0019 0020 const int InfoBoxWidget::padX = 6; 0021 const int InfoBoxWidget::padY = 2; 0022 0023 InfoBoxes::InfoBoxes(QWidget *parent) : QWidget(parent) 0024 { 0025 setMouseTracking(true); 0026 } 0027 0028 void InfoBoxes::addInfoBox(InfoBoxWidget *ibox) 0029 { 0030 ibox->setParent(this); 0031 m_boxes.append(ibox); 0032 } 0033 0034 void InfoBoxes::resizeEvent(QResizeEvent *) 0035 { 0036 foreach (InfoBoxWidget *w, m_boxes) 0037 w->adjust(); 0038 } 0039 0040 /* ================================================================ */ 0041 0042 InfoBoxWidget::InfoBoxWidget(bool shade, const QPoint &pos, int anchor, const QStringList &str, QWidget *parent) 0043 : QWidget(parent), m_strings(str), m_adjusted(false), m_grabbed(false), m_shaded(shade), m_anchor(anchor) 0044 { 0045 move(pos); 0046 updateSize(); 0047 } 0048 0049 void InfoBoxWidget::updateSize() 0050 { 0051 QFontMetrics fm(font()); 0052 int w = 0; 0053 foreach (const QString &str, m_strings) 0054 { 0055 w = qMax(w, fm.horizontalAdvance(str)); 0056 } 0057 0058 int h = fm.height() * (m_shaded ? 1 : m_strings.size()); 0059 // Add padding 0060 resize(w + 2 * padX, h + 2 * padY + 2); 0061 adjust(); 0062 } 0063 0064 void InfoBoxWidget::slotTimeChanged() 0065 { 0066 KStarsData *data = KStarsData::Instance(); 0067 0068 m_strings.clear(); 0069 m_strings 0070 << i18nc("Local Time", "LT: ") + data->lt().time().toString(QLocale().timeFormat().remove('t')) + 0071 " " + // Remove timezone, as timezone of geolocation in KStars might not be same as system locale timezone 0072 QLocale().toString(data->lt().date()); 0073 0074 m_strings << i18nc("Universal Time", "UT: ") + data->ut().time().toString("HH:mm:ss") + " " + 0075 QLocale().toString(data->ut().date()); // Do not format UTC according to locale 0076 0077 const QString STString = QString::asprintf("%02d:%02d:%02d ", data->lst()->hour(), data->lst()->minute(), 0078 data->lst()->second()); 0079 //Don't use KLocale::formatNumber() for Julian Day because we don't want 0080 //thousands-place separators 0081 QString JDString = QString::number(data->ut().djd(), 'f', 2); 0082 JDString.replace('.', QLocale().decimalPoint()); 0083 m_strings << i18nc("Sidereal Time", "ST: ") + STString + i18nc("Julian Day", "JD: ") + JDString; 0084 updateSize(); 0085 update(); 0086 } 0087 0088 void InfoBoxWidget::slotGeoChanged() 0089 { 0090 GeoLocation *geo = KStarsData::Instance()->geo(); 0091 0092 m_strings.clear(); 0093 m_strings << geo->fullName(); 0094 0095 //m_strings << i18nc("Longitude", "Long:") + ' ' + QLocale().toString(geo->lng()->Degrees(), 3) + " " + 0096 // i18nc("Latitude", "Lat:") + ' ' + QLocale().toString(geo->lat()->Degrees(), 3); 0097 0098 m_strings << i18nc("Longitude", "Long:") + ' ' + geo->lng()->toDMSString(true) + ' ' + 0099 i18nc("Latitude", "Lat:") + ' ' + geo->lat()->toDMSString(true); 0100 updateSize(); 0101 update(); 0102 } 0103 0104 void InfoBoxWidget::slotObjectChanged(SkyObject *obj) 0105 { 0106 setPoint(obj->translatedLongName(), obj); 0107 } 0108 0109 void InfoBoxWidget::slotPointChanged(SkyPoint *p) 0110 { 0111 setPoint(i18n("nothing"), p); 0112 } 0113 0114 void InfoBoxWidget::setPoint(QString name, SkyPoint *p) 0115 { 0116 m_strings.clear(); 0117 m_strings << name; 0118 m_strings << i18nc("Right Ascension", "RA") + ": " + p->ra().toHMSString() + " " + i18nc("Declination", "Dec") + 0119 ": " + p->dec().toDMSString(true); 0120 m_strings << i18nc("Azimuth", "Az") + ": " + p->az().toDMSString(true) + " " + i18nc("Altitude", "Alt") + ": " + 0121 p->alt().toDMSString(true); 0122 0123 dms lst = KStarsData::Instance()->geo()->GSTtoLST(KStarsData::Instance()->clock()->utc().gst()); 0124 dms ha(lst - p->ra()); 0125 QChar sign('+'); 0126 if (ha.Hours() > 12.0) 0127 { 0128 ha.setH(24.0 - ha.Hours()); 0129 sign = '-'; 0130 } 0131 m_strings << i18nc("Hour Angle", "HA") + ": " + sign + ha.toHMSString() + " " + i18nc("Zenith Angle", "ZA") + ": " + 0132 dms(90 - p->alt().Degrees()).toDMSString(true); 0133 updateSize(); 0134 update(); 0135 } 0136 0137 void InfoBoxWidget::adjust() 0138 { 0139 if (!isVisible()) 0140 return; 0141 // X axis 0142 int newX = x(); 0143 int maxX = parentWidget()->width() - width(); 0144 if (m_anchor & AnchorRight) 0145 { 0146 newX = maxX; 0147 } 0148 else 0149 { 0150 newX = KSUtils::clamp(newX, 0, maxX); 0151 if (newX == maxX) 0152 m_anchor |= AnchorRight; 0153 } 0154 // Y axis 0155 int newY = y(); 0156 int maxY = parentWidget()->height() - height(); 0157 if (m_anchor & AnchorBottom) 0158 { 0159 newY = maxY; 0160 } 0161 else 0162 { 0163 newY = KSUtils::clamp(newY, 0, maxY); 0164 if (newY == maxY) 0165 m_anchor |= AnchorBottom; 0166 } 0167 // Do move 0168 m_adjusted = true; 0169 move(newX, newY); 0170 } 0171 0172 void InfoBoxWidget::paintEvent(QPaintEvent *) 0173 { 0174 // If widget contain no strings return 0175 if (m_strings.empty()) 0176 return; 0177 // Start with painting 0178 ColorScheme *cs = KStarsData::Instance()->colorScheme(); 0179 QPainter p; 0180 p.begin(this); 0181 0182 // Draw background 0183 QColor colBG = cs->colorNamed("BoxBGColor"); 0184 colBG.setAlpha(127); 0185 p.fillRect(contentsRect(), colBG); 0186 // Draw border 0187 if (m_grabbed) 0188 { 0189 p.setPen(cs->colorNamed("BoxGrabColor")); 0190 p.drawRect(0, 0, width() - 1, height() - 1); 0191 } 0192 // Draw text 0193 int h = QFontMetrics(font()).height(); 0194 int y = 0; 0195 p.setPen(cs->colorNamed("BoxTextColor")); 0196 foreach (const QString &str, m_strings) 0197 { 0198 y += h; 0199 p.drawText(padX, padY + y, str); 0200 } 0201 // Done 0202 p.end(); 0203 } 0204 0205 void InfoBoxWidget::mouseMoveEvent(QMouseEvent *event) 0206 { 0207 m_grabbed = true; 0208 // X axis 0209 int newX = x() + event->x(); 0210 int maxX = parentWidget()->width() - width(); 0211 if (newX > maxX) 0212 { 0213 newX = maxX; 0214 m_anchor |= AnchorRight; 0215 } 0216 else 0217 { 0218 if (newX < 0) 0219 newX = 0; 0220 m_anchor &= ~AnchorRight; 0221 } 0222 // Y axis 0223 int newY = y() + event->y(); 0224 int maxY = parentWidget()->height() - height(); 0225 if (newY > maxY) 0226 { 0227 newY = maxY; 0228 m_anchor |= AnchorBottom; 0229 } 0230 else 0231 { 0232 if (newY < 0) 0233 newY = 0; 0234 m_anchor &= ~AnchorBottom; 0235 } 0236 // Do move 0237 m_adjusted = true; 0238 move(newX, newY); 0239 } 0240 0241 void InfoBoxWidget::mousePressEvent(QMouseEvent *) 0242 { 0243 emit clicked(); 0244 } 0245 0246 void InfoBoxWidget::showEvent(QShowEvent *) 0247 { 0248 if (!m_adjusted) 0249 adjust(); 0250 } 0251 0252 void InfoBoxWidget::mouseDoubleClickEvent(QMouseEvent *) 0253 { 0254 m_shaded = !m_shaded; 0255 updateSize(); 0256 update(); 0257 } 0258 0259 void InfoBoxWidget::mouseReleaseEvent(QMouseEvent *) 0260 { 0261 m_grabbed = false; 0262 }