1 /*
2 * Stellarium
3 * Copyright (C) 2008 Fabien Chereau
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 */
19
20
21 #include "StelDialog.hpp"
22 #include "StelDialog_p.hpp"
23 #include "StelMainView.hpp"
24 #include "StelGui.hpp"
25 #include "StelActionMgr.hpp"
26 #include "StelPropertyMgr.hpp"
27 #include "StelTranslator.hpp"
28 #include "StelModuleMgr.hpp"
29
30 #include <QDebug>
31 #include <QAbstractButton>
32 #include <QComboBox>
33 #include <QDialog>
34 #include <QGraphicsSceneWheelEvent>
35 #include <QMetaProperty>
36 #include <QStyleOptionGraphicsItem>
37 #include <QSlider>
38 #include <QSpinBox>
39 #include <QDoubleSpinBox>
40 #include <QLineEdit>
41 #include <QScroller>
42 #include <QToolButton>
43 #include <QColorDialog>
44 #include <QMessageBox>
45
StelDialog(QString dialogName,QObject * parent)46 StelDialog::StelDialog(QString dialogName, QObject* parent)
47 : QObject(parent)
48 , dialog(Q_NULLPTR)
49 , proxy(Q_NULLPTR)
50 , dialogName(dialogName)
51 {
52 if (parent == Q_NULLPTR)
53 setParent(StelMainView::getInstance().getGuiWidget());
54
55 connect(&StelApp::getInstance(), SIGNAL(fontChanged(QFont)), this, SLOT(handleFontChanged()));
56 connect(&StelApp::getInstance(), SIGNAL(guiFontSizeChanged(int)), this, SLOT(handleFontChanged()));
57 }
58
~StelDialog()59 StelDialog::~StelDialog()
60 {
61 }
62
close()63 void StelDialog::close()
64 {
65 setVisible(false);
66 }
67
styleChanged()68 void StelDialog::styleChanged()
69 {
70 // Nothing for now
71 }
72
visible() const73 bool StelDialog::visible() const
74 {
75 return dialog!=Q_NULLPTR && dialog->isVisible();
76 }
77
setVisible(bool v)78 void StelDialog::setVisible(bool v)
79 {
80 if (v)
81 {
82 StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
83 QSize screenSize = StelMainView::getInstance().size();
84 // If dialog size is very large and we move to a computer with much smaller screen, this should create the dialog with reasonable better size.
85 QSize maxSize = 0.95*screenSize;
86 if (dialog)
87 {
88 // reload stylesheet, in case size changed!
89 if (gui)
90 dialog->setStyleSheet(gui->getStelStyle().qtStyleSheet);
91 dialog->show();
92 StelMainView::getInstance().scene()->setActiveWindow(proxy);
93 // If the main window has been resized, it is possible the dialog
94 // will be off screen. Check for this and move it to a visible
95 // position if necessary
96 QPointF newPos = proxy->pos();
97 if (newPos.x()>=screenSize.width())
98 newPos.setX(screenSize.width() - dialog->size().width());
99 if (newPos.y()>=screenSize.height())
100 newPos.setY(screenSize.height() - dialog->size().height());
101 if (newPos != dialog->pos())
102 proxy->setPos(newPos);
103 }
104 else
105 {
106 QGraphicsWidget* parent = qobject_cast<QGraphicsWidget*>(this->parent());
107 dialog = new QDialog(Q_NULLPTR);
108 // dialog->setParent(parent);
109 //dialog->setAttribute(Qt::WA_OpaquePaintEvent, true);
110 connect(dialog, SIGNAL(rejected()), this, SLOT(close()));
111 createDialogContent();
112 if (gui)
113 dialog->setStyleSheet(gui->getStelStyle().qtStyleSheet);
114 // Ensure that tooltip get rendered in red in night mode.
115 connect(&StelApp::getInstance(), SIGNAL(visionNightModeChanged(bool)), this, SLOT(updateNightModeProperty(bool)));
116 updateNightModeProperty(StelApp::getInstance().getVisionModeNight());
117
118 proxy = new CustomProxy(parent, Qt::Tool);
119 proxy->setWidget(dialog);
120 QSizeF size = proxy->size();
121
122 connect(proxy, SIGNAL(sizeChanged(QSizeF)), this, SLOT(handleDialogSizeChanged(QSizeF)));
123
124 int newX, newY;
125 // Retrieve panel locations from config.ini, but shift if required to a visible position.
126 // else centre dialog according to current window size.
127 QSettings *conf=StelApp::getInstance().getSettings();
128 Q_ASSERT(conf);
129 QString confNamePt="DialogPositions/" + dialogName;
130 QString storedPosString=conf->value(confNamePt,
131 QString("%1,%2")
132 .arg(static_cast<int>((screenSize.width() - size.width() )/2))
133 .arg(static_cast<int>((screenSize.height() - size.height())/2)))
134 .toString();
135 QStringList posList=storedPosString.split(",");
136 if (posList.length()==2)
137 {
138 newX=posList.at(0).toInt();
139 newY=posList.at(1).toInt();
140 }
141 else // in case there is an invalid string?
142 {
143 newX=static_cast<int>((screenSize.width() - size.width() )/2);
144 newY=static_cast<int>((screenSize.height() - size.height())/2);
145 }
146
147 if (newX>=screenSize.width())
148 newX= (screenSize.width() - dialog->size().width());
149 if (newY>=screenSize.height())
150 newY= (screenSize.height() - dialog->size().height());
151
152 // Make sure that the window's title bar is accessible
153 if (newY <-0)
154 newY = 0;
155 proxy->setPos(newX, newY);
156 // Invisible frame around the window to make resizing easier
157 // (this also changes the bounding rectangle size)
158 proxy->setWindowFrameMargins(7,0,7,7);
159
160 // Retrieve stored panel sizes, scale panel up if it was stored larger than default.
161 QString confNameSize="DialogSizes/" + dialogName;
162 QString storedSizeString=conf->value(confNameSize, QString("0,0")).toString();
163 QStringList sizeList=storedSizeString.split(",");
164 if (sizeList.length()==2)
165 {
166 newX=sizeList.at(0).toInt();
167 newY=sizeList.at(1).toInt();
168 }
169 else // in case there is an invalid string?
170 {
171 newX=0;
172 newY=0;
173 }
174 // resize only if number was valid and larger than default loaded size.
175 if ( (newX>=proxy->size().width()) || (newY>=proxy->size().height()) )
176 {
177 //qDebug() << confNameSize << ": resize from" << proxy->size().width() << "x" << proxy->size().height() << "to " << storedSizeString;
178 proxy->resize(qMax(static_cast<qreal>(newX), proxy->size().width()), qMax(static_cast<qreal>(newY), proxy->size().height()));
179 }
180 if(proxy->size().width() > maxSize.width() || proxy->size().height() > maxSize.height())
181 {
182 proxy->resize(qMin(static_cast<qreal>(maxSize.width()), proxy->size().width()), qMin(static_cast<qreal>(maxSize.height()), proxy->size().height()));
183 }
184 handleDialogSizeChanged(proxy->size()); // This may trigger internal updates in subclasses. E.g. LocationPanel location arrow.
185
186 proxy->setZValue(100);
187 StelMainView::getInstance().scene()->setActiveWindow(proxy);
188 }
189 proxy->setFocus();
190 }
191 else
192 {
193 dialog->hide();
194 //proxy->clearFocus();
195 StelMainView::getInstance().focusSky();
196 }
197 emit visibleChanged(v);
198 }
199
handleFontChanged()200 void StelDialog::handleFontChanged()
201 {
202 if (dialog && dialog->isVisible())
203 {
204 // reload stylesheet, in case size or font changed!
205 StelGui* gui = dynamic_cast<StelGui*>(StelApp::getInstance().getGui());
206 if (gui)
207 dialog->setStyleSheet(gui->getStelStyle().qtStyleSheet);
208 }
209 }
210
connectCheckBox(QAbstractButton * checkBox,const QString & actionName)211 void StelDialog::connectCheckBox(QAbstractButton *checkBox, const QString &actionName)
212 {
213 StelAction* action = StelApp::getInstance().getStelActionManager()->findAction(actionName);
214 connectCheckBox(checkBox,action);
215 }
216
connectCheckBox(QAbstractButton * checkBox,StelAction * action)217 void StelDialog::connectCheckBox(QAbstractButton *checkBox, StelAction *action)
218 {
219 Q_ASSERT(action);
220 checkBox->setChecked(action->isChecked());
221 connect(action, SIGNAL(toggled(bool)), checkBox, SLOT(setChecked(bool)));
222 connect(checkBox, SIGNAL(toggled(bool)), action, SLOT(setChecked(bool)));
223 }
224
connectIntProperty(QLineEdit * lineEdit,const QString & propName)225 void StelDialog::connectIntProperty(QLineEdit* lineEdit, const QString& propName)
226 {
227 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
228 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
229
230 //use a proxy for the connection
231 new QLineEditStelPropertyConnectionHelper(prop,lineEdit);
232 }
233
connectIntProperty(QSpinBox * spinBox,const QString & propName)234 void StelDialog::connectIntProperty(QSpinBox *spinBox, const QString &propName)
235 {
236 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
237 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
238
239 //use a proxy for the connection
240 new QSpinBoxStelPropertyConnectionHelper(prop,spinBox);
241 }
242
connectIntProperty(QComboBox * comboBox,const QString & propName)243 void StelDialog::connectIntProperty(QComboBox *comboBox, const QString &propName)
244 {
245 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
246 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
247
248 //use a proxy for the connection
249 new QComboBoxStelPropertyConnectionHelper(prop,comboBox);
250 }
251
connectIntProperty(QSlider * slider,const QString & propName,int minValue,int maxValue)252 void StelDialog::connectIntProperty(QSlider *slider, const QString &propName,int minValue, int maxValue)
253 {
254 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
255 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
256
257 //The connection is handled by a helper class. It is automatically destroyed when the slider is destroyed.
258 new QSliderStelPropertyConnectionHelper(prop,minValue,maxValue,slider);
259 }
260
connectDoubleProperty(QDoubleSpinBox * spinBox,const QString & propName)261 void StelDialog::connectDoubleProperty(QDoubleSpinBox *spinBox, const QString &propName)
262 {
263 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
264 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
265
266 //use a proxy for the connection
267 new QDoubleSpinBoxStelPropertyConnectionHelper(prop,spinBox);
268 }
269
connectDoubleProperty(AngleSpinBox * spinBox,const QString & propName)270 void StelDialog::connectDoubleProperty(AngleSpinBox *spinBox, const QString &propName)
271 {
272 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
273 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
274
275 //use a proxy for the connection
276 new AngleSpinBoxStelPropertyConnectionHelper(prop,spinBox);
277 }
278
connectDoubleProperty(QSlider * slider,const QString & propName,double minValue,double maxValue)279 void StelDialog::connectDoubleProperty(QSlider *slider, const QString &propName,double minValue, double maxValue)
280 {
281 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
282 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
283
284 //The connection is handled by a helper class. It is automatically destroyed when the slider is destroyed.
285 new QSliderStelPropertyConnectionHelper(prop,minValue,maxValue,slider);
286 }
287
connectStringProperty(QComboBox * comboBox,const QString & propName)288 void StelDialog::connectStringProperty(QComboBox *comboBox, const QString &propName)
289 {
290 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
291 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
292
293 //use a proxy for the connection
294 new QComboBoxStelStringPropertyConnectionHelper(prop,comboBox);
295 }
296
connectStringProperty(QLineEdit * lineEdit,const QString & propName)297 void StelDialog::connectStringProperty(QLineEdit *lineEdit, const QString &propName)
298 {
299 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
300 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
301
302 //use a proxy for the connection
303 new QLineEditStelPropertyConnectionHelper(prop,lineEdit);
304 }
305
connectBoolProperty(QAbstractButton * checkBox,const QString & propName)306 void StelDialog::connectBoolProperty(QAbstractButton *checkBox, const QString &propName)
307 {
308 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
309 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
310
311 new QAbstractButtonStelPropertyConnectionHelper(prop,checkBox);
312 }
313
connectBoolProperty(QGroupBox * checkBox,const QString & propName)314 void StelDialog::connectBoolProperty(QGroupBox *checkBox, const QString &propName)
315 {
316 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propName);
317 Q_ASSERT_X(prop,"StelDialog", "StelProperty does not exist");
318
319 new QGroupBoxStelPropertyConnectionHelper(prop,checkBox);
320 }
321
askConfirmation()322 bool StelDialog::askConfirmation()
323 {
324 return (QMessageBox::warning(&StelMainView::getInstance(), q_("Attention!"), q_("Are you sure? This will delete your customized data."), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes);
325 }
326
connectColorButton(QToolButton * toolButton,QString propertyName,QString iniName,QString moduleName)327 void StelDialog::connectColorButton(QToolButton *toolButton, QString propertyName, QString iniName, QString moduleName)
328 {
329 toolButton->setProperty("propName", propertyName);
330 toolButton->setProperty("iniName", iniName);
331 toolButton->setProperty("moduleName", moduleName);
332 StelProperty* prop = StelApp::getInstance().getStelPropertyManager()->getProperty(propertyName);
333 QColor color=prop->getValue().value<Vec3f>().toQColor();
334 // Use style sheet to create a nice button :)
335 toolButton->setStyleSheet("QToolButton { background-color:" + color.name() + "; }");
336 toolButton->setFixedSize(QSize(18, 18));
337
338 connect(toolButton, SIGNAL(released()), this, SLOT(askColor()));
339 }
340
askColor()341 void StelDialog::askColor()
342 {
343 // Only work if connected from a QToolButton
344 if (!sender())
345 {
346 qWarning() << "askColor(): No sender? Ignoring.";
347 Q_ASSERT(0);
348 return;
349 }
350 if (QString(sender()->metaObject()->className()) != QString("QToolButton"))
351 {
352 qWarning() << "Sender not a QToolButton but a |" << sender()->metaObject()->className() << "|! ColorButton not set up properly! Ignoring.";
353 Q_ASSERT(0);
354 return;
355 }
356 QString propName=sender()->property("propName").toString();
357 QString iniName=sender()->property("iniName").toString();
358 QString moduleName=sender()->property("moduleName").toString(); // optional
359 if ((propName.isEmpty()) || (iniName.isEmpty()))
360 {
361 qWarning() << "ColorButton not set up properly! Ignoring.";
362 Q_ASSERT(0);
363 return;
364 }
365 Vec3d vColor = StelApp::getInstance().getStelPropertyManager()->getProperty(propName)->getValue().value<Vec3f>().toVec3d();
366 QColor color = vColor.toQColor();
367 QColor c = QColorDialog::getColor(color, &StelMainView::getInstance() , q_(static_cast<QToolButton*>(QObject::sender())->toolTip()));
368 if (c.isValid())
369 {
370 vColor = Vec3d(c.redF(), c.greenF(), c.blueF());
371 StelApp::getInstance().getStelPropertyManager()->setStelPropertyValue(propName, QVariant::fromValue(Vec3f(c.redF(), c.greenF(), c.blueF())));
372 if (moduleName.isEmpty())
373 StelApp::getInstance().getSettings()->setValue(iniName, vColor.toStr());
374 else
375 {
376 StelModule *module=StelApp::getInstance().getModuleMgr().getModule(moduleName);
377 QSettings *settings=module->getSettings();
378 Q_ASSERT(settings);
379 settings->setValue(iniName, vColor.toStr());
380 }
381 static_cast<QToolButton*>(QObject::sender())->setStyleSheet("QToolButton { background-color:" + c.name() + "; }");
382 }
383 }
384
enableKineticScrolling(bool b)385 void StelDialog::enableKineticScrolling(bool b)
386 {
387 if (kineticScrollingList.length()==0) return;
388 if (b)
389 {
390 for (auto* w : kineticScrollingList)
391 {
392 QScroller::grabGesture(w, QScroller::LeftMouseButtonGesture);
393 QScroller::scroller(w); // WHAT DOES THIS DO? We don't use the return value.
394 }
395 }
396 else
397 {
398 for (auto* w : kineticScrollingList)
399 {
400 QScroller::ungrabGesture(w);
401 // QScroller::scroller(w);
402 }
403 }
404 }
405
updateNightModeProperty(bool n)406 void StelDialog::updateNightModeProperty(bool n)
407 {
408 dialog->setProperty("nightMode", n);
409 }
410
handleMovedTo(QPoint newPos)411 void StelDialog::handleMovedTo(QPoint newPos)
412 {
413 QSettings *conf=StelApp::getInstance().getSettings();
414 Q_ASSERT(conf);
415 conf->setValue("DialogPositions/" + dialogName, QString("%1,%2").arg(newPos.x()).arg(newPos.y()));
416 }
417
handleDialogSizeChanged(QSizeF size)418 void StelDialog::handleDialogSizeChanged(QSizeF size)
419 {
420 QSettings *conf=StelApp::getInstance().getSettings();
421 Q_ASSERT(conf);
422 conf->setValue("DialogSizes/" + dialogName, QString("%1,%2").arg(static_cast<int>(size.width())).arg(static_cast<int>(size.height())));
423 }
424
425
426 //// --- Implementation of StelDialog_p.hpp classes follow ---
427
QAbstractButtonStelPropertyConnectionHelper(StelProperty * prop,QAbstractButton * button)428 QAbstractButtonStelPropertyConnectionHelper::QAbstractButtonStelPropertyConnectionHelper(StelProperty *prop, QAbstractButton *button)
429 :StelPropertyProxy(prop,button), button(button)
430 {
431 QVariant val = prop->getValue();
432 bool ok = val.canConvert<bool>();
433 Q_ASSERT_X(ok,"QAbstractButtonStelPropertyConnectionHelper","Can not convert to bool datatype");
434 Q_UNUSED(ok);
435 onPropertyChanged(val);
436
437 //in this direction, we can directly connect because Qt supports QVariant slots with the new syntax
438 connect(button, &QAbstractButton::toggled, prop, &StelProperty::setValue);
439 }
440
onPropertyChanged(const QVariant & value)441 void QAbstractButtonStelPropertyConnectionHelper::onPropertyChanged(const QVariant &value)
442 {
443 //block signals to prevent sending the valueChanged signal, changing the property again
444 bool b = button->blockSignals(true);
445 button->setChecked(value.toBool());
446 button->blockSignals(b);
447 }
448
QGroupBoxStelPropertyConnectionHelper(StelProperty * prop,QGroupBox * box)449 QGroupBoxStelPropertyConnectionHelper::QGroupBoxStelPropertyConnectionHelper(StelProperty *prop, QGroupBox *box)
450 :StelPropertyProxy(prop,box), box(box)
451 {
452 QVariant val = prop->getValue();
453 bool ok = val.canConvert<bool>();
454 Q_ASSERT_X(ok,"QGroupBoxStelPropertyConnectionHelper","Can not convert to bool datatype");
455 Q_UNUSED(ok);
456 onPropertyChanged(val);
457
458 //in this direction, we can directly connect because Qt supports QVariant slots with the new syntax
459 connect(box, &QGroupBox::toggled, prop, &StelProperty::setValue);
460 }
461
onPropertyChanged(const QVariant & value)462 void QGroupBoxStelPropertyConnectionHelper::onPropertyChanged(const QVariant &value)
463 {
464 //block signals to prevent sending the valueChanged signal, changing the property again
465 bool b = box->blockSignals(true);
466 box->setChecked(value.toBool());
467 box->blockSignals(b);
468 }
469
QComboBoxStelPropertyConnectionHelper(StelProperty * prop,QComboBox * combo)470 QComboBoxStelPropertyConnectionHelper::QComboBoxStelPropertyConnectionHelper(StelProperty *prop, QComboBox *combo)
471 :StelPropertyProxy(prop,combo), combo(combo)
472 {
473 QVariant val = prop->getValue();
474 bool ok = val.canConvert<int>();
475 Q_ASSERT_X(ok,"QComboBoxStelPropertyConnectionHelper","Can not convert to int datatype");
476 Q_UNUSED(ok);
477 onPropertyChanged(val);
478
479 //in this direction, we can directly connect because Qt supports QVariant slots with the new syntax
480 connect(combo, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),prop,&StelProperty::setValue);
481 }
482
onPropertyChanged(const QVariant & value)483 void QComboBoxStelPropertyConnectionHelper::onPropertyChanged(const QVariant &value)
484 {
485 //block signals to prevent sending the valueChanged signal, changing the property again
486 bool b = combo->blockSignals(true);
487 combo->setCurrentIndex(value.toInt());
488 combo->blockSignals(b);
489 }
QComboBoxStelStringPropertyConnectionHelper(StelProperty * prop,QComboBox * combo)490 QComboBoxStelStringPropertyConnectionHelper::QComboBoxStelStringPropertyConnectionHelper(StelProperty *prop, QComboBox *combo)
491 :StelPropertyProxy(prop,combo), combo(combo)
492 {
493 QVariant val = prop->getValue();
494 bool ok = val.canConvert<QString>();
495 Q_ASSERT_X(ok,"QComboBoxStelStringPropertyConnectionHelper","Can not convert to QString datatype");
496 Q_UNUSED(ok);
497 onPropertyChanged(val);
498
499 //in this direction, we can directly connect because Qt supports QVariant slots with the new syntax
500 connect(combo, static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::activated),prop,&StelProperty::setValue);
501 }
502
onPropertyChanged(const QVariant & value)503 void QComboBoxStelStringPropertyConnectionHelper::onPropertyChanged(const QVariant &value)
504 {
505 //block signals to prevent sending the valueChanged signal, changing the property again
506 bool b = combo->blockSignals(true);
507 combo->setCurrentText(value.toString());
508 combo->blockSignals(b);
509 }
510
QLineEditStelPropertyConnectionHelper(StelProperty * prop,QLineEdit * edit)511 QLineEditStelPropertyConnectionHelper::QLineEditStelPropertyConnectionHelper(StelProperty *prop, QLineEdit *edit)
512 :StelPropertyProxy(prop,edit), edit(edit)
513 {
514 QVariant val = prop->getValue();
515 bool ok = val.canConvert<int>();
516 Q_ASSERT_X(ok,"QLineEditStelPropertyConnectionHelper","Can not convert to int datatype");
517 Q_UNUSED(ok);
518 onPropertyChanged(val);
519
520 //in this direction, we can directly connect because Qt supports QVariant slots with the new syntax
521 connect(edit, static_cast<void (QLineEdit::*)(const QString&)>(&QLineEdit::textEdited),prop,&StelProperty::setValue);
522 }
523
onPropertyChanged(const QVariant & value)524 void QLineEditStelPropertyConnectionHelper::onPropertyChanged(const QVariant &value)
525 {
526 //block signals to prevent sending the valueChanged signal, changing the property again
527 bool b = edit->blockSignals(true);
528 edit->setText(value.toString());
529 edit->blockSignals(b);
530 }
531
QSpinBoxStelPropertyConnectionHelper(StelProperty * prop,QSpinBox * spin)532 QSpinBoxStelPropertyConnectionHelper::QSpinBoxStelPropertyConnectionHelper(StelProperty *prop, QSpinBox *spin)
533 :StelPropertyProxy(prop,spin), spin(spin)
534 {
535 QVariant val = prop->getValue();
536 bool ok = val.canConvert<int>();
537 Q_ASSERT_X(ok,"QSpinBoxStelPropertyConnectionHelper","Can not convert to int datatype");
538 Q_UNUSED(ok);
539 onPropertyChanged(val);
540
541 //in this direction, we can directly connect because Qt supports QVariant slots with the new syntax
542 connect(spin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),prop,&StelProperty::setValue);
543 }
544
onPropertyChanged(const QVariant & value)545 void QSpinBoxStelPropertyConnectionHelper::onPropertyChanged(const QVariant &value)
546 {
547 //block signals to prevent sending the valueChanged signal, changing the property again
548 bool b = spin->blockSignals(true);
549 spin->setValue(value.toInt());
550 spin->blockSignals(b);
551 }
552
QDoubleSpinBoxStelPropertyConnectionHelper(StelProperty * prop,QDoubleSpinBox * spin)553 QDoubleSpinBoxStelPropertyConnectionHelper::QDoubleSpinBoxStelPropertyConnectionHelper(StelProperty *prop, QDoubleSpinBox *spin)
554 :StelPropertyProxy(prop,spin), spin(spin)
555 {
556 QVariant val = prop->getValue();
557 bool ok = val.canConvert<double>();
558 Q_ASSERT_X(ok,"QDoubleSpinBoxStelPropertyConnectionHelper","Can not convert to double datatype");
559 Q_UNUSED(ok);
560 onPropertyChanged(val);
561
562 //in this direction, we can directly connect because Qt supports QVariant slots with the new syntax
563 connect(spin, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged),prop,&StelProperty::setValue);
564 }
565
onPropertyChanged(const QVariant & value)566 void QDoubleSpinBoxStelPropertyConnectionHelper::onPropertyChanged(const QVariant &value)
567 {
568 //block signals to prevent sending the valueChanged signal, changing the property again
569 bool b = spin->blockSignals(true);
570 spin->setValue(value.toDouble());
571 spin->blockSignals(b);
572 }
573
AngleSpinBoxStelPropertyConnectionHelper(StelProperty * prop,AngleSpinBox * spin)574 AngleSpinBoxStelPropertyConnectionHelper::AngleSpinBoxStelPropertyConnectionHelper(StelProperty *prop, AngleSpinBox *spin)
575 :StelPropertyProxy(prop,spin), spin(spin)
576 {
577 QVariant val = prop->getValue();
578 bool ok = val.canConvert<double>();
579 Q_ASSERT_X(ok,"AngleSpinBoxStelPropertyConnectionHelper","Can not convert to double datatype");
580 Q_UNUSED(ok);
581 onPropertyChanged(val);
582
583 //in this direction, we can directly connect because Qt supports QVariant slots with the new syntax
584 connect(spin, static_cast<void (AngleSpinBox::*)(double)>(&AngleSpinBox::valueChangedDeg),prop,&StelProperty::setValue);
585 }
586
onPropertyChanged(const QVariant & value)587 void AngleSpinBoxStelPropertyConnectionHelper::onPropertyChanged(const QVariant &value)
588 {
589 //block signals to prevent sending the valueChanged signal, changing the property again
590 bool b = spin->blockSignals(true);
591 spin->setDegrees(value.toDouble());
592 spin->blockSignals(b);
593 }
594
595
QSliderStelPropertyConnectionHelper(StelProperty * prop,double minValue,double maxValue,QSlider * slider)596 QSliderStelPropertyConnectionHelper::QSliderStelPropertyConnectionHelper(StelProperty *prop, double minValue, double maxValue, QSlider *slider)
597 : StelPropertyProxy(prop,slider),slider(slider),minValue(minValue),maxValue(maxValue)
598 {
599 QVariant val = prop->getValue();
600 bool ok = val.canConvert<double>();
601 Q_ASSERT_X(ok,"QSliderStelPropertyConnectionHelper","Can not convert to double datatype");
602 Q_UNUSED(ok);
603
604 dRange = maxValue - minValue;
605 onPropertyChanged(val);
606
607 connect(slider,SIGNAL(valueChanged(int)),this,SLOT(sliderIntValueChanged(int)));
608 }
609
QSliderStelPropertyConnectionHelper(StelProperty * prop,int minValue,int maxValue,QSlider * slider)610 QSliderStelPropertyConnectionHelper::QSliderStelPropertyConnectionHelper(StelProperty *prop, int minValue, int maxValue, QSlider *slider)
611 : StelPropertyProxy(prop,slider),slider(slider),minValue(minValue),maxValue(maxValue)
612 {
613 QVariant val = prop->getValue();
614 bool ok = val.canConvert<double>();
615 Q_ASSERT_X(ok,"QSliderStelPropertyConnectionHelper","Can not convert to double datatype");
616 Q_UNUSED(ok);
617
618 dRange = maxValue - minValue;
619 onPropertyChanged(val);
620
621 connect(slider,SIGNAL(valueChanged(int)),this,SLOT(sliderIntValueChanged(int)));
622 }
sliderIntValueChanged(int val)623 void QSliderStelPropertyConnectionHelper::sliderIntValueChanged(int val)
624 {
625 double dVal = ((val - slider->minimum()) / static_cast<double>(slider->maximum() - slider->minimum())) * dRange + minValue;
626 prop->setValue(dVal);
627 }
628
onPropertyChanged(const QVariant & val)629 void QSliderStelPropertyConnectionHelper::onPropertyChanged(const QVariant& val)
630 {
631 double dVal = val.toDouble();
632 int iRange = slider->maximum() - slider->minimum();
633 int iVal = qRound(((dVal - minValue)/dRange) * iRange + slider->minimum());
634 bool b = slider->blockSignals(true);
635 slider->setValue(iVal);
636 slider->blockSignals(b);
637 }
638