File indexing completed on 2024-04-21 14:47:03
0001 /* 0002 SPDX-FileCopyrightText: 2002 Jason Harris <kstars@30doradus.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "timespinbox.h" 0008 0009 #include "kstars_debug.h" 0010 0011 #include <KLocalizedString> 0012 0013 #include <QDebug> 0014 #include <QLineEdit> 0015 0016 #include <cmath> 0017 0018 #define SECS_PER_DAY 86400. 0019 #define SIDEREAL_YEAR 31558149.77 0020 0021 //Time steps: 0022 //0-9: 0 sec, 0.1, 0.25, 0.5, 1, 2, 5, 10, 20, 30 sec 0023 //10-14: 1 minute, 2, 5, 10, 15, 30 min 0024 //15-19: 1 hour, 2, 4, 6, 12 hours 0025 //20-23: 1 day, 2, 3, 5 days 0026 //24-26: 1 week, 2, 3 weeks 0027 //27-32: 1 month, 2, 3, 4, 6, 9 months 0028 //33-41: 1 year, 2, 3, 4, 5, 10, 25, 50, 100 years 0029 0030 TimeSpinBox::TimeSpinBox(QWidget *parent, bool _daysonly) : QSpinBox(parent) 0031 { 0032 setDaysOnly(_daysonly); 0033 0034 setMinimum(-41); 0035 setMaximum(41); 0036 setSingleStep(1); 0037 0038 setButtonSymbols(QSpinBox::PlusMinus); 0039 lineEdit()->setReadOnly(true); 0040 setValue(4); //1 second (real time) 0041 0042 //Set width: 0043 QFontMetrics fm(font()); 0044 int extra = width() - lineEdit()->width(); 0045 uint wmax = 0; 0046 for (int i = 0; i < maximum(); ++i) 0047 { 0048 uint w = fm.horizontalAdvance('-' + TimeString[i]); 0049 0050 if (w > wmax) 0051 wmax = w; 0052 } 0053 setFixedWidth(wmax + extra); 0054 0055 connect(this, SIGNAL(valueChanged(int)), this, SLOT(reportChange())); 0056 // updateDisplay(); 0057 } 0058 0059 void TimeSpinBox::setDaysOnly(bool daysonly) 0060 { 0061 DaysOnly = daysonly; 0062 0063 int i = 0; //index for TimeScale values 0064 TimeScale[0] = 0.0; // 0.0 sec 0065 if (!daysOnly()) 0066 { 0067 TimeScale[1] = 0.1; // 0.1 sec 0068 TimeScale[2] = 0.25; // 0.25 sec 0069 TimeScale[3] = 0.5; // 0.5 sec 0070 TimeScale[4] = 1.0; // 1 sec (real-time) 0071 TimeScale[5] = 2.0; // 2 sec 0072 TimeScale[6] = 5.0; // 5 sec 0073 TimeScale[7] = 10.0; // 10 sec 0074 TimeScale[8] = 20.0; // 20 sec 0075 TimeScale[9] = 30.0; // 30 sec 0076 TimeScale[10] = 60.0; // 1 min 0077 TimeScale[11] = 120.0; // 2 min 0078 TimeScale[12] = 300.0; // 5 min 0079 TimeScale[13] = 600.0; // 10 min 0080 TimeScale[14] = 900.0; // 15 min 0081 TimeScale[15] = 1800.0; // 30 min 0082 TimeScale[16] = 3600.0; // 1 hr 0083 TimeScale[17] = 7200.0; // 2 hr 0084 TimeScale[18] = 10800.0; // 3 hr 0085 TimeScale[19] = 21600.0; // 6 hr 0086 TimeScale[20] = 43200.0; // 12 hr 0087 i = 20; 0088 } 0089 TimeScale[i + 1] = 86164.1; // 23 hr 56 min 0090 TimeScale[i + 2] = SECS_PER_DAY; // 1 day 0091 TimeScale[i + 3] = 2. * SECS_PER_DAY; // 2 days 0092 TimeScale[i + 4] = 3. * SECS_PER_DAY; // 3 days 0093 TimeScale[i + 5] = 5. * SECS_PER_DAY; // 5 days 0094 TimeScale[i + 6] = 7. * SECS_PER_DAY; // 1 week 0095 TimeScale[i + 7] = 14. * SECS_PER_DAY; //2 weeks 0096 TimeScale[i + 8] = 21. * SECS_PER_DAY; //3 weeks 0097 //Months aren't a simple measurement of time; I'll just use fractions of a year 0098 TimeScale[i + 9] = SIDEREAL_YEAR / 12.0; // 1 month 0099 TimeScale[i + 10] = SIDEREAL_YEAR / 6.0; // 2 months 0100 TimeScale[i + 11] = 0.25 * SIDEREAL_YEAR; // 3 months 0101 TimeScale[i + 12] = SIDEREAL_YEAR / 3.0; // 4 months 0102 TimeScale[i + 13] = 0.5 * SIDEREAL_YEAR; // 6 months 0103 TimeScale[i + 14] = 0.75 * SIDEREAL_YEAR; // 9 months 0104 TimeScale[i + 15] = SIDEREAL_YEAR; // 1 year 0105 TimeScale[i + 16] = 2.0 * SIDEREAL_YEAR; // 2 years 0106 TimeScale[i + 17] = 3.0 * SIDEREAL_YEAR; // 3 years 0107 TimeScale[i + 18] = 5.0 * SIDEREAL_YEAR; // 5 years 0108 TimeScale[i + 19] = 10.0 * SIDEREAL_YEAR; // 10 years 0109 TimeScale[i + 20] = 25.0 * SIDEREAL_YEAR; // 25 years 0110 TimeScale[i + 21] = 50.0 * SIDEREAL_YEAR; // 50 years 0111 TimeScale[i + 22] = 100.0 * SIDEREAL_YEAR; // 100 years 0112 0113 TimeString.clear(); 0114 if (!daysOnly()) 0115 { 0116 TimeString.append("0 " + i18nc("seconds", "secs")); 0117 TimeString.append("0.1 " + i18nc("seconds", "secs")); 0118 TimeString.append("0.25 " + i18nc("seconds", "secs")); 0119 TimeString.append("0.5 " + i18nc("seconds", "secs")); 0120 TimeString.append("1 " + i18nc("second", "sec")); 0121 TimeString.append("2 " + i18nc("seconds", "secs")); 0122 TimeString.append("5 " + i18nc("seconds", "secs")); 0123 TimeString.append("10 " + i18nc("seconds", "secs")); 0124 TimeString.append("20 " + i18nc("seconds", "secs")); 0125 TimeString.append("30 " + i18nc("seconds", "secs")); 0126 TimeString.append("1 " + i18nc("minute", "min")); 0127 TimeString.append("2 " + i18nc("minutes", "mins")); 0128 TimeString.append("5 " + i18nc("minutes", "mins")); 0129 TimeString.append("10 " + i18nc("minutes", "mins")); 0130 TimeString.append("15 " + i18nc("minutes", "mins")); 0131 TimeString.append("30 " + i18nc("minutes", "mins")); 0132 TimeString.append("1 " + i18n("hour")); 0133 TimeString.append("2 " + i18nc("hours", "hrs")); 0134 TimeString.append("3 " + i18nc("hours", "hrs")); 0135 TimeString.append("6 " + i18nc("hours", "hrs")); 0136 TimeString.append("12 " + i18nc("hours", "hrs")); 0137 } 0138 else 0139 { 0140 TimeString.append("0 " + i18n("days")); 0141 } 0142 TimeString.append("1 " + i18nc("sidereal day", "sid day")); 0143 TimeString.append("1 " + i18n("day")); 0144 TimeString.append("2 " + i18n("days")); 0145 TimeString.append("3 " + i18n("days")); 0146 TimeString.append("5 " + i18n("days")); 0147 TimeString.append("1 " + i18n("week")); 0148 TimeString.append("2 " + i18nc("weeks", "wks")); 0149 TimeString.append("3 " + i18nc("weeks", "wks")); 0150 TimeString.append("1 " + i18n("month")); 0151 TimeString.append("2 " + i18nc("months", "mths")); 0152 TimeString.append("3 " + i18nc("months", "mths")); 0153 TimeString.append("4 " + i18nc("months", "mths")); 0154 TimeString.append("6 " + i18nc("months", "mths")); 0155 TimeString.append("9 " + i18nc("months", "mths")); 0156 TimeString.append("1 " + i18n("year")); 0157 TimeString.append("2 " + i18nc("years", "yrs")); 0158 TimeString.append("3 " + i18nc("years", "yrs")); 0159 TimeString.append("5 " + i18nc("years", "yrs")); 0160 TimeString.append("10 " + i18nc("years", "yrs")); 0161 TimeString.append("25 " + i18nc("years", "yrs")); 0162 TimeString.append("50 " + i18nc("years", "yrs")); 0163 TimeString.append("100 " + i18nc("years", "yrs")); 0164 0165 if (!daysOnly()) 0166 { 0167 setMinimum(-41); 0168 setMaximum(41); 0169 } 0170 else 0171 { 0172 setMinimum(-21); 0173 setMaximum(21); 0174 } 0175 } 0176 0177 int TimeSpinBox::valueFromText(const QString &text) const 0178 { 0179 for (int i = 0; i < TimeString.size(); i++) 0180 { 0181 if (text == TimeString[i]) 0182 { 0183 return i; 0184 } 0185 if (text.mid(1, text.length()) == TimeString[i]) 0186 { 0187 return -1 * i; 0188 } 0189 } 0190 0191 return 0; 0192 } 0193 0194 QString TimeSpinBox::textFromValue(int value) const 0195 { 0196 QString result; 0197 int posval(abs(value)); 0198 0199 if (posval > TimeString.size() - 1) 0200 posval = 4; 0201 0202 result = TimeString[posval]; 0203 0204 if (value < 0) 0205 { 0206 result = '-' + result; 0207 } 0208 return result; 0209 } 0210 0211 void TimeSpinBox::changeScale(float x) 0212 { 0213 //Pick the closest value 0214 int imin = 0; 0215 float dxlast(10000000000.0), dxmin(10000000000.0); 0216 0217 for (unsigned int i = 0; i < 42; ++i) 0218 { 0219 float dx = fabs(TimeScale[i] - fabs(x)); 0220 0221 if (dx < dxmin) 0222 { 0223 imin = i; 0224 dxmin = dx; 0225 } 0226 if (dx > dxlast) 0227 break; //we have passed the minimum dx 0228 0229 dxlast = dx; 0230 } 0231 0232 if (x < 0.0) 0233 imin *= -1; 0234 setValue(imin); 0235 } 0236 0237 float TimeSpinBox::timeScale(void) const 0238 { 0239 return value() > 0 ? TimeScale[value()] : -1. * TimeScale[abs(value())]; 0240 } 0241 0242 void TimeSpinBox::reportChange() 0243 { 0244 qCDebug(KSTARS) << "Reporting new timestep value: " << timeScale(); 0245 emit scaleChanged(timeScale()); 0246 }