diff --git a/kstars/auxiliary/xplanetimageviewer.cpp b/kstars/auxiliary/xplanetimageviewer.cpp index d5b4fffd1..53454b0d2 100644 --- a/kstars/auxiliary/xplanetimageviewer.cpp +++ b/kstars/auxiliary/xplanetimageviewer.cpp @@ -1,1120 +1,1161 @@ /*************************************************************************** XPlanetImageviewer.cpp - Based on: KStars Image Viwer by Thomas Kabelmann ------------------- begin : Sun Aug 12, 2018 copyright : (C) 2018 by Robert Lancaster email : rlancaste@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "xplanetimageviewer.h" #include "Options.h" #include "dialogs/timedialog.h" #include #ifndef KSTARS_LITE #include "kstars.h" #endif #ifndef KSTARS_LITE #include #endif #include #include #include #include #include #include #include #include #include #include #include "skymap.h" #include "kspaths.h" #include #include +typedef enum { +SUN,MERCURY,VENUS, +EARTH,MOON, +MARS,PHOBOS,DEIMOS, +JUPITER,GANYMEDE,IO,CALLISTO,EUROPA, +SATURN,TITAN,MIMAS,ENCELADUS,TETHYS,DIONE,RHEA,HYPERION,IAPETUS,PHOEBE, +URANUS,UMBRIEL,ARIEL,MIRANDA,TITANIA,OBERON, +NEPTUNE,TRITON } objects; + XPlanetImageLabel::XPlanetImageLabel(QWidget *parent) : QFrame(parent) { #ifndef KSTARS_LITE grabGesture(Qt::PinchGesture); setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); setFrameStyle(QFrame::StyledPanel | QFrame::Plain); setLineWidth(2); #endif } void XPlanetImageLabel::setImage(const QImage &img) { #ifndef KSTARS_LITE m_Image = img; - pix = QPixmap::fromImage(m_Image); + m_Pix = QPixmap::fromImage(m_Image); #endif } void XPlanetImageLabel::invertPixels() { #ifndef KSTARS_LITE m_Image.invertPixels(); - pix = QPixmap::fromImage(m_Image.scaled(width(), height(), Qt::KeepAspectRatio)); + m_Pix = QPixmap::fromImage(m_Image.scaled(width(), height(), Qt::KeepAspectRatio)); #endif } void XPlanetImageLabel::paintEvent(QPaintEvent *) { #ifndef KSTARS_LITE QPainter p; p.begin(this); int x = 0; - if (pix.width() < width()) - x = (width() - pix.width()) / 2; - p.drawPixmap(x, 0, pix); + if (m_Pix.width() < width()) + x = (width() - m_Pix.width()) / 2; + p.drawPixmap(x, 0, m_Pix); p.end(); #endif } void XPlanetImageLabel::resizeEvent(QResizeEvent *event) { - if (event->size() == pix.size()) + if (event->size() == m_Pix.size()) return; - pix = QPixmap::fromImage(m_Image.scaled(event->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + m_Pix = QPixmap::fromImage(m_Image.scaled(event->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); } void XPlanetImageLabel::refreshImage() { - pix = QPixmap::fromImage(m_Image.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); + m_Pix = QPixmap::fromImage(m_Image.scaled(size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); update(); } void XPlanetImageLabel::wheelEvent(QWheelEvent *e) { //This attempts to send the wheel event back to the Scroll Area if it was taken from a trackpad //It should still do the zoom if it is a mouse wheel if (e->source() == Qt::MouseEventSynthesizedBySystem) { QFrame::wheelEvent(e); } else { if (e->delta() > 0) emit zoomIn(); else if (e->delta() < 0) emit zoomOut(); e->accept(); } } bool XPlanetImageLabel::event(QEvent *event) { if (event->type() == QEvent::Gesture) return gestureEvent(dynamic_cast(event)); return QFrame::event(event); } bool XPlanetImageLabel::gestureEvent(QGestureEvent *event) { if (QGesture *pinch = event->gesture(Qt::PinchGesture)) pinchTriggered(dynamic_cast(pinch)); return true; } void XPlanetImageLabel::pinchTriggered(QPinchGesture *gesture) { if (gesture->totalScaleFactor() > 1) emit zoomIn(); else emit zoomOut(); } void XPlanetImageLabel::mousePressEvent(QMouseEvent *e) { - mouseButtonDown = true; - lastMousePoint = e->globalPos(); + m_MouseButtonDown = true; + m_LastMousePoint = e->globalPos(); e->accept(); } void XPlanetImageLabel::mouseReleaseEvent(QMouseEvent *e) { - mouseButtonDown = false; + m_MouseButtonDown = false; e->accept(); } void XPlanetImageLabel::mouseMoveEvent(QMouseEvent *e) { - if(mouseButtonDown) + if(m_MouseButtonDown) { QPoint newPoint = e->globalPos(); - int dx = newPoint.x() - lastMousePoint.x(); - int dy = newPoint.y() - lastMousePoint.y(); + int dx = newPoint.x() - m_LastMousePoint.x(); + int dy = newPoint.y() - m_LastMousePoint.y(); emit changePosition(QPoint(dx, dy)); - lastMousePoint = newPoint; + m_LastMousePoint = newPoint; } e->accept(); } XPlanetImageViewer::XPlanetImageViewer(const QString &obj, QWidget *parent): QDialog(parent) { #ifndef KSTARS_LITE - lastURL = QUrl::fromLocalFile(QDir::homePath()); + m_LastFile = QDir::homePath(); - object=obj; #ifdef Q_OS_OSX setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); #endif setAttribute(Qt::WA_DeleteOnClose, true); setModal(false); - setWindowTitle(i18n("XPlanet Solar System Simulator: %1", object)); + setWindowTitle(i18n("XPlanet Solar System Simulator: %1", obj)); setXPlanetDate(KStarsData::Instance()->ut()); if (Options::xplanetFOV()) - FOV = KStars::Instance()->map()->fov(); - else - FOV = 0; + m_FOV = KStars::Instance()->map()->fov(); // Create widget QFrame *page = new QFrame(this); //setMainWidget( page ); QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(page); setLayout(mainLayout); QWidget *selectorsWidget= new QWidget(this); QHBoxLayout *selectorsLayout = new QHBoxLayout(selectorsWidget); selectorsLayout->setMargin(0); mainLayout->addWidget(selectorsWidget); - QStringList objects; - objects << i18n("Sun") << i18n("Mercury") << i18n("Venus"); - objects << i18n("Earth") << i18n("Moon"); - objects << i18n("Mars") << i18n("Phobos") << i18n("Deimos"); - objects << i18n("Jupiter") << i18n("Ganymede") << i18n("Io") << i18n("Callisto") << i18n("Europa"); - objects << i18n("Saturn") << i18n("Titan") << i18n("Mimas") << i18n("Enceladus") << i18n("Tethys") << i18n("Dione") << i18n("Rhea") << i18n("Hyperion") << i18n("Iapetus") << i18n("Phoebe"); - objects << i18n("Uranus") << i18n("Umbriel") << i18n("Ariel") << i18n("Miranda") << i18n("Titania") << i18n("Oberon"); - objects << i18n("Neptune") << i18n("Triton"); + m_ObjectNames << i18n("Sun") << i18n("Mercury") << i18n("Venus"); + m_ObjectNames << i18n("Earth") << i18n("Moon"); + m_ObjectNames << i18n("Mars") << i18n("Phobos") << i18n("Deimos"); + m_ObjectNames << i18n("Jupiter") << i18n("Ganymede") << i18n("Io") << i18n("Callisto") << i18n("Europa"); + m_ObjectNames << i18n("Saturn") << i18n("Titan") << i18n("Mimas") << i18n("Enceladus") << i18n("Tethys") << i18n("Dione") << i18n("Rhea") << i18n("Hyperion") << i18n("Iapetus") << i18n("Phoebe"); + m_ObjectNames << i18n("Uranus") << i18n("Umbriel") << i18n("Ariel") << i18n("Miranda") << i18n("Titania") << i18n("Oberon"); + m_ObjectNames << i18n("Neptune") << i18n("Triton"); + + m_CurrentObjectIndex = m_ObjectNames.indexOf(obj); + m_ObjectName = m_ObjectNames.at(m_CurrentObjectIndex); QComboBox *objectSelector = new QComboBox(this); - objectSelector->addItems(objects); + objectSelector->addItems(m_ObjectNames); objectSelector->setToolTip(i18n("This allows you to select a new object/target for XPlanet to view")); selectorsLayout->addWidget(objectSelector); - objectSelector->setCurrentIndex(objectSelector->findText(object)); - connect(objectSelector, SIGNAL(currentTextChanged(QString)), this, SLOT(updateXPlanetObject(QString))); + objectSelector->setCurrentIndex(m_CurrentObjectIndex); + connect(objectSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(updateXPlanetObject(int))); - origin = i18n("Earth"); + m_CurrentOriginIndex = EARTH; + m_OriginName = m_ObjectNames.at(EARTH); selectorsLayout->addWidget(new QLabel(i18n("from"),this)); - originSelector = new QComboBox(this); - originSelector->addItems(objects); - originSelector->setToolTip(i18n("This allows you to select a viewing location")); - selectorsLayout->addWidget(originSelector); - originSelector->setCurrentIndex(originSelector->findText(origin)); - connect(originSelector, SIGNAL(currentTextChanged(QString)), this, SLOT(updateXPlanetOrigin(QString))); + m_OriginSelector = new QComboBox(this); + m_OriginSelector->addItems(m_ObjectNames); + m_OriginSelector->setToolTip(i18n("This allows you to select a viewing location")); + selectorsLayout->addWidget(m_OriginSelector); + m_OriginSelector->setCurrentIndex(EARTH); + connect(m_OriginSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(updateXPlanetOrigin(int))); - lat = Options::xplanetLatitude().toDouble(); - lon = Options::xplanetLongitude().toDouble(); - radius = 45; + m_lat = Options::xplanetLatitude().toDouble(); + m_lon = Options::xplanetLongitude().toDouble(); + m_Radius = 45; selectorsLayout->addWidget(new QLabel(i18n("Location:"), this)); - latDisplay = new QLabel(this); - latDisplay->setToolTip(i18n("XPlanet Latitude, only valid when viewing the object from the same object")); - latDisplay->setText(QString::number(lat)); - latDisplay->setDisabled(true); - selectorsLayout->addWidget(latDisplay); - - selectorsLayout->addWidget(new QLabel(",", this)); - lonDisplay = new QLabel(this); - lonDisplay->setToolTip(i18n("XPlanet Longitude, only valid when viewing the object from the same object")); - lonDisplay->setText(QString::number(lon)); - lonDisplay->setDisabled(true); - selectorsLayout->addWidget(lonDisplay); - - selectorsLayout->addWidget(new QLabel(",", this)); - radDisplay = new QLabel(this); - radDisplay->setToolTip(i18n("XPlanet object radius in %, only valid when viewing the object from the same object")); - radDisplay->setText(QString::number(radius)); - radDisplay->setDisabled(true); - selectorsLayout->addWidget(radDisplay); - - freeRotate = new QPushButton(this); - freeRotate->setIcon(QIcon::fromTheme("object-rotate-left")); - freeRotate->setAttribute(Qt::WA_LayoutUsesWidgetRect); - freeRotate->setMaximumSize(QSize(32,32)); - freeRotate->setMinimumSize(QSize(32,32)); - freeRotate->setCheckable(true); - freeRotate->setToolTip(i18n("Hover over target and freely rotate view with mouse in XPlanet Viewer")); - selectorsLayout->addWidget(freeRotate); - connect(freeRotate, SIGNAL(clicked()), this, SLOT(slotFreeRotate())); + m_PositionDisplay = new QLabel(this); + m_PositionDisplay->setToolTip(i18n("XPlanet Latitude, Longitude, and object radius in %. This is only valid when viewing the object from the same object")); + updatePositionDisplay(); + m_PositionDisplay->setDisabled(true); + selectorsLayout->addWidget(m_PositionDisplay); + + m_FreeRotate = new QPushButton(this); + m_FreeRotate->setIcon(QIcon::fromTheme("object-rotate-left")); + m_FreeRotate->setAttribute(Qt::WA_LayoutUsesWidgetRect); + m_FreeRotate->setMaximumSize(QSize(32,32)); + m_FreeRotate->setMinimumSize(QSize(32,32)); + m_FreeRotate->setCheckable(true); + m_FreeRotate->setToolTip(i18n("Hover over target and freely rotate view with mouse in XPlanet Viewer")); + selectorsLayout->addWidget(m_FreeRotate); + connect(m_FreeRotate, SIGNAL(clicked()), this, SLOT(slotFreeRotate())); QPushButton *saveB = new QPushButton(this); saveB->setIcon(QIcon::fromTheme("document-save")); saveB->setAttribute(Qt::WA_LayoutUsesWidgetRect); saveB->setMaximumSize(QSize(32,32)); saveB->setMinimumSize(QSize(32,32)); saveB->setToolTip(i18n("Save the image to disk")); selectorsLayout->addWidget(saveB); connect(saveB, SIGNAL(clicked()), this, SLOT(saveFileToDisk())); QWidget *viewControlsWidget= new QWidget(this); QHBoxLayout *viewControlsLayout = new QHBoxLayout(viewControlsWidget); viewControlsLayout->setMargin(0); mainLayout->addWidget(viewControlsWidget); viewControlsLayout->addWidget(new QLabel(i18n("FOV:"), this)); - FOVEdit = new NonLinearDoubleSpinBox(); - FOVEdit->setDecimals(4); + m_FOVEdit = new NonLinearDoubleSpinBox(); + m_FOVEdit->setDecimals(4); QList possibleValues; possibleValues << 0; for(double i=.001;i<100;i*=1.5) possibleValues << i; - FOVEdit->setRecommendedValues(possibleValues); - FOVEdit->setValue(0); - FOVEdit->setToolTip(i18n("Sets the FOV to the Specified value. Note: has no effect if hovering over object.")); - viewControlsLayout->addWidget(FOVEdit); - connect(FOVEdit, SIGNAL(valueChanged(double)), this, SLOT(updateXPlanetFOVEdit())); - - kstarsFOV = new QPushButton(this); - kstarsFOV->setIcon(QIcon::fromTheme("zoom-fit-width")); - kstarsFOV->setAttribute(Qt::WA_LayoutUsesWidgetRect); - kstarsFOV->setMaximumSize(QSize(32,32)); - kstarsFOV->setMinimumSize(QSize(32,32)); - kstarsFOV->setToolTip(i18n("Zoom to the current KStars FOV. Note: has no effect if hovering over object.")); - viewControlsLayout->addWidget(kstarsFOV); - connect(kstarsFOV, SIGNAL(clicked()), this, SLOT(setKStarsXPlanetFOV())); - - noFOV = new QPushButton(this); - noFOV->setIcon(QIcon::fromTheme("system-reboot")); - noFOV->setAttribute(Qt::WA_LayoutUsesWidgetRect); - noFOV->setMaximumSize(QSize(32,32)); - noFOV->setMinimumSize(QSize(32,32)); - noFOV->setToolTip(i18n("Optimum FOV for the target, FOV parameter not specified. Note: has no effect if hovering over object.")); - viewControlsLayout->addWidget(noFOV); - connect(noFOV, SIGNAL(clicked()), this, SLOT(clearXPlanetFOV())); - - rotation = 0; + m_FOVEdit->setRecommendedValues(possibleValues); + m_FOVEdit->setValue(0); + m_FOVEdit->setToolTip(i18n("Sets the FOV to the Specified value. Note: has no effect if hovering over object.")); + viewControlsLayout->addWidget(m_FOVEdit); + connect(m_FOVEdit, SIGNAL(valueChanged(double)), this, SLOT(updateXPlanetFOVEdit())); + + m_KStarsFOV = new QPushButton(this); + m_KStarsFOV->setIcon(QIcon::fromTheme("zoom-fit-width")); + m_KStarsFOV->setAttribute(Qt::WA_LayoutUsesWidgetRect); + m_KStarsFOV->setMaximumSize(QSize(32,32)); + m_KStarsFOV->setMinimumSize(QSize(32,32)); + m_KStarsFOV->setToolTip(i18n("Zoom to the current KStars FOV. Note: has no effect if hovering over object.")); + viewControlsLayout->addWidget(m_KStarsFOV); + connect(m_KStarsFOV, SIGNAL(clicked()), this, SLOT(setKStarsXPlanetFOV())); + + m_NoFOV = new QPushButton(this); + m_NoFOV->setIcon(QIcon::fromTheme("system-reboot")); + m_NoFOV->setAttribute(Qt::WA_LayoutUsesWidgetRect); + m_NoFOV->setMaximumSize(QSize(32,32)); + m_NoFOV->setMinimumSize(QSize(32,32)); + m_NoFOV->setToolTip(i18n("Optimum FOV for the target, FOV parameter not specified. Note: has no effect if hovering over object.")); + viewControlsLayout->addWidget(m_NoFOV); + connect(m_NoFOV, SIGNAL(clicked()), this, SLOT(clearXPlanetFOV())); + + m_Rotation = 0; viewControlsLayout->addWidget(new QLabel(i18n("Rotation:"), this)); - rotateEdit = new QSpinBox(); + m_RotateEdit = new QSpinBox(); - rotateEdit->setRange(-180, 180); - rotateEdit->setValue(0); - rotateEdit->setSingleStep(10); - rotateEdit->setToolTip(i18n("Set the view rotation to the desired angle")); - viewControlsLayout->addWidget(rotateEdit); - connect(rotateEdit, SIGNAL(valueChanged(int)), this, SLOT(updateXPlanetRotationEdit())); + m_RotateEdit->setRange(-180, 180); + m_RotateEdit->setValue(0); + m_RotateEdit->setSingleStep(10); + m_RotateEdit->setToolTip(i18n("Set the view rotation to the desired angle")); + viewControlsLayout->addWidget(m_RotateEdit); + connect(m_RotateEdit, SIGNAL(valueChanged(int)), this, SLOT(updateXPlanetRotationEdit())); QPushButton *invertRotation = new QPushButton(this); invertRotation->setIcon(QIcon::fromTheme("object-flip-vertical")); invertRotation->setAttribute(Qt::WA_LayoutUsesWidgetRect); invertRotation->setMaximumSize(QSize(32,32)); invertRotation->setMinimumSize(QSize(32,32)); invertRotation->setToolTip(i18n("Rotate the view 180 degrees")); viewControlsLayout->addWidget(invertRotation); connect(invertRotation, SIGNAL(clicked()), this, SLOT(invertXPlanetRotation())); QPushButton *resetRotation = new QPushButton(this); resetRotation->setIcon(QIcon::fromTheme("system-reboot")); resetRotation->setAttribute(Qt::WA_LayoutUsesWidgetRect); resetRotation->setMaximumSize(QSize(32,32)); resetRotation->setMinimumSize(QSize(32,32)); resetRotation->setToolTip(i18n("Reset view rotation to 0")); viewControlsLayout->addWidget(resetRotation); connect(resetRotation, SIGNAL(clicked()), this, SLOT(resetXPlanetRotation())); QPushButton *optionsB = new QPushButton(this); optionsB->setIcon(QIcon::fromTheme("configure")); optionsB->setAttribute(Qt::WA_LayoutUsesWidgetRect); optionsB->setMaximumSize(QSize(32,32)); optionsB->setMinimumSize(QSize(32,32)); optionsB->setToolTip(i18n("Bring up XPlanet Options")); viewControlsLayout->addWidget(optionsB); connect(optionsB, SIGNAL(clicked()), KStars::Instance(), SLOT(slotViewOps())); QPushButton *invertB = new QPushButton(this); invertB->setIcon(QIcon::fromTheme("edit-select-invert")); invertB->setAttribute(Qt::WA_LayoutUsesWidgetRect); invertB->setMaximumSize(QSize(32,32)); invertB->setMinimumSize(QSize(32,32)); invertB->setToolTip(i18n("Reverse colors of the image. This is useful to enhance contrast at times. This affects " "only the display and not the saving.")); viewControlsLayout->addWidget(invertB); connect(invertB, SIGNAL(clicked()), this, SLOT(invertColors())); QWidget *timeWidget= new QWidget(this); QHBoxLayout *timeLayout = new QHBoxLayout(timeWidget); mainLayout->addWidget(timeWidget); timeLayout->setMargin(0); - xplanetTime = KStarsData::Instance()->lt(); + m_XPlanetTime = KStarsData::Instance()->lt(); QPushButton *setTime = new QPushButton(this); setTime->setIcon(QIcon::fromTheme("clock")); setTime->setAttribute(Qt::WA_LayoutUsesWidgetRect); setTime->setMaximumSize(QSize(32,32)); setTime->setMinimumSize(QSize(32,32)); setTime->setToolTip(i18n("Allows you to set the XPlanet time to a different date/time from KStars")); timeLayout->addWidget(setTime); connect(setTime, SIGNAL(clicked()), this, SLOT(setXPlanetTime())); QPushButton *kstarsTime = new QPushButton(this); kstarsTime->setIcon(QIcon::fromTheme("system-reboot")); kstarsTime->setAttribute(Qt::WA_LayoutUsesWidgetRect); kstarsTime->setMaximumSize(QSize(32,32)); kstarsTime->setMinimumSize(QSize(32,32)); kstarsTime->setToolTip(i18n("Sets the XPlanet time to the current KStars time")); timeLayout->addWidget(kstarsTime); connect(kstarsTime, SIGNAL(clicked()), this, SLOT(setXPlanetTimetoKStarsTime())); - XPlanetTimeDisplay = new QLabel(this); - XPlanetTimeDisplay->setToolTip(i18n("Current XPlanet Time")); - timeLayout->addWidget(XPlanetTimeDisplay); - - XPlanetTimeDisplay->setText(xplanetTime.date().toString() + ", " + xplanetTime.time().toString()); - - timeSlider = new QSlider(Qt::Horizontal, this); - timeLayout->addWidget(timeSlider); - timeSlider->setRange(-100, 100); - timeSlider->setToolTip(i18n("This sets the time step from the current XPlanet time, good for viewing events")); - connect(timeSlider, SIGNAL(valueChanged(int)), this, SLOT(updateXPlanetTime(int))); - - timeEdit = new QSpinBox(this); - timeEdit->setRange(-100, 100); - timeEdit->setMaximumWidth(50); - timeEdit->setToolTip(i18n("This sets the time step from the current XPlanet time")); - timeLayout->addWidget(timeEdit); - connect(timeEdit, SIGNAL(valueChanged(int)), this, SLOT(updateXPlanetTimeEdit())); - - timeUnit = MINS; - timeUnitsSelect = new QComboBox(this); - timeLayout->addWidget(timeUnitsSelect); - timeUnitsSelect->addItem(i18n("years")); - timeUnitsSelect->addItem(i18n("months")); - timeUnitsSelect->addItem(i18n("days")); - timeUnitsSelect->addItem(i18n("hours")); - timeUnitsSelect->addItem(i18n("mins")); - timeUnitsSelect->addItem(i18n("secs")); - timeUnitsSelect->setCurrentIndex(MINS); - timeUnitsSelect->setToolTip(i18n("Lets you change the units for the timestep in the animation")); - connect(timeUnitsSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(updateXPlanetTimeUnits(int))); - - XPlanetTimer = new QTimer(this); - XPlanetTimer->setInterval(Options::xplanetAnimationDelay().toInt()); - connect(XPlanetTimer, SIGNAL(timeout()), this, SLOT(incrementXPlanetTime())); - - runTime = new QPushButton(this); - runTime->setIcon(QIcon::fromTheme("media-playback-start")); - runTime->setAttribute(Qt::WA_LayoutUsesWidgetRect); - runTime->setCheckable(true); - runTime->setMaximumSize(QSize(32,32)); - runTime->setMinimumSize(QSize(32,32)); - runTime->setToolTip(i18n("Lets you run the animation")); - timeLayout->addWidget(runTime); - connect(runTime, SIGNAL(clicked()), this, SLOT(toggleXPlanetRun())); + m_XPlanetTimeDisplay = new QLabel(this); + m_XPlanetTimeDisplay->setToolTip(i18n("Current XPlanet Time")); + timeLayout->addWidget(m_XPlanetTimeDisplay); + + m_XPlanetTimeDisplay->setText(i18n("%1, %2", m_XPlanetTime.date().toString() , m_XPlanetTime.time().toString())); + + m_TimeSlider = new QSlider(Qt::Horizontal, this); + m_TimeSlider->setTracking(false); + connect(m_TimeSlider,SIGNAL(sliderMoved(int)),this,SLOT(timeSliderDisplay(int))); + timeLayout->addWidget(m_TimeSlider); + m_TimeSlider->setRange(-100, 100); + m_TimeSlider->setToolTip(i18n("This sets the time step from the current XPlanet time, good for viewing events")); + connect(m_TimeSlider, SIGNAL(valueChanged(int)), this, SLOT(updateXPlanetTime(int))); + + m_TimeEdit = new QSpinBox(this); + m_TimeEdit->setRange(-10000, 10000); + m_TimeEdit->setMaximumWidth(50); + m_TimeEdit->setToolTip(i18n("This sets the time step from the current XPlanet time")); + timeLayout->addWidget(m_TimeEdit); + connect(m_TimeEdit, SIGNAL(valueChanged(int)), this, SLOT(updateXPlanetTimeEdit())); + + m_CurrentTimeUnitIndex = MINS; + m_TimeUnitsSelect = new QComboBox(this); + timeLayout->addWidget(m_TimeUnitsSelect); + m_TimeUnitsSelect->addItem(i18n("years")); + m_TimeUnitsSelect->addItem(i18n("months")); + m_TimeUnitsSelect->addItem(i18n("days")); + m_TimeUnitsSelect->addItem(i18n("hours")); + m_TimeUnitsSelect->addItem(i18n("minutes")); + m_TimeUnitsSelect->addItem(i18n("seconds")); + m_TimeUnitsSelect->setCurrentIndex(MINS); + m_TimeUnitsSelect->setToolTip(i18n("Lets you change the units for the timestep in the animation")); + connect(m_TimeUnitsSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(updateXPlanetTimeUnits(int))); + + m_XPlanetTimer = new QTimer(this); + m_XPlanetTimer->setInterval(Options::xplanetAnimationDelay()); + connect(m_XPlanetTimer, SIGNAL(timeout()), this, SLOT(incrementXPlanetTime())); + + m_RunTime = new QPushButton(this); + m_RunTime->setIcon(QIcon::fromTheme("media-playback-start")); + m_RunTime->setAttribute(Qt::WA_LayoutUsesWidgetRect); + m_RunTime->setCheckable(true); + m_RunTime->setMaximumSize(QSize(32,32)); + m_RunTime->setMinimumSize(QSize(32,32)); + m_RunTime->setToolTip(i18n("Lets you run the animation")); + timeLayout->addWidget(m_RunTime); + connect(m_RunTime, SIGNAL(clicked()), this, SLOT(toggleXPlanetRun())); QPushButton *resetTime = new QPushButton(this); resetTime->setIcon(QIcon::fromTheme("system-reboot")); resetTime->setAttribute(Qt::WA_LayoutUsesWidgetRect); resetTime->setMaximumSize(QSize(32,32)); resetTime->setMinimumSize(QSize(32,32)); resetTime->setToolTip(i18n("Resets the animation to 0 timesteps from the current XPlanet Time")); timeLayout->addWidget(resetTime); connect(resetTime, SIGNAL(clicked()), this, SLOT(resetXPlanetTime())); m_View = new XPlanetImageLabel(page); m_View->setAutoFillBackground(false); m_Caption = new QLabel(page); m_Caption->setAutoFillBackground(true); m_Caption->setFrameShape(QFrame::StyledPanel); - m_Caption->setText(object); + m_Caption->setText(m_ObjectName); // Add layout QVBoxLayout *vlay = new QVBoxLayout(page); vlay->setSpacing(0); vlay->setMargin(0); vlay->addWidget(m_View); vlay->addWidget(m_Caption); connect(m_View, SIGNAL(zoomIn()), this, SLOT(zoomInXPlanetFOV())); connect(m_View, SIGNAL(zoomOut()), this, SLOT(zoomOutXPlanetFOV())); connect(m_View, SIGNAL(changePosition(QPoint)), this, SLOT(changeXPlanetPosition(QPoint))); //Reverse colors QPalette p = palette(); p.setColor(QPalette::Window, palette().color(QPalette::WindowText)); p.setColor(QPalette::WindowText, palette().color(QPalette::Window)); m_Caption->setPalette(p); m_View->setPalette(p); +#ifndef Q_OS_WIN + if(Options::xplanetUseFIFO()) + { + connect(&watcherTimeout,SIGNAL(timeout()),&fifoImageLoadWatcher,SLOT(cancel())); + connect(&fifoImageLoadWatcher,SIGNAL(finished()),this,SLOT(showImage())); + } +#endif + + #ifdef Q_OS_OSX QList qButtons = findChildren(); for (auto &button : qButtons) button->setAutoDefault(false); #endif updateXPlanetTime(0); - startXplanet(); #endif } XPlanetImageViewer::~XPlanetImageViewer() { QApplication::restoreOverrideCursor(); } void XPlanetImageViewer::startXplanet() { - if(xplanetRunning) + if(m_XPlanetRunning) return; //This means something failed in the file output if(!setupOutputFile()) return; QString xPlanetLocation = Options::xplanetPath(); #ifdef Q_OS_OSX if (Options::xplanetIsInternal()) xPlanetLocation = QCoreApplication::applicationDirPath() + "/xplanet/bin/xplanet"; #endif // If Options::xplanetPath() is empty, return if (xPlanetLocation.isEmpty()) { KMessageBox::error(nullptr, i18n("Xplanet binary path is empty in config panel.")); return; } // If Options::xplanetPath() does not exist, return const QFileInfo xPlanetLocationInfo(xPlanetLocation); if (!xPlanetLocationInfo.exists() || !xPlanetLocationInfo.isExecutable()) { KMessageBox::error(nullptr, i18n("The configured Xplanet binary does not exist or is not executable.")); return; } // Create xplanet process QProcess *xplanetProc = new QProcess(this); // Add some options QStringList args; //This specifies the object to be viewed - args << "-body" << object.toLower(); + args << "-body" << m_ObjectName.toLower(); //This is the date and time requested - args << "-date" << date; + args << "-date" << m_Date; //This is the glare from the sun args << "-glare" << Options::xplanetGlare(); args << "-base_magnitude" << Options::xplanetMagnitude(); //This is the correction for light's travel time. args << "-light_time"; - args << "-geometry" << Options::xplanetWidth() + 'x' + Options::xplanetHeight(); + args << "-geometry" << QString::number(Options::xplanetWidth()) + 'x' + QString::number(Options::xplanetHeight()); - if(FOV != 0) - args << "-fov" << QString::number(FOV); + if(m_FOV != 0) + args << "-fov" << QString::number(m_FOV); //Need to convert to locale for places that don't use decimals?? //args << "-fov" << fov.setNum(fov());//.replace('.', ','); //This rotates the view for different object angles - args << "-rotate" << QString::number(rotation); + args << "-rotate" << QString::number(m_Rotation); if (Options::xplanetConfigFile()) args << "-config" << Options::xplanetConfigFilePath(); if (Options::xplanetStarmap()) args << "-starmap" << Options::xplanetStarmapPath(); if (Options::xplanetArcFile()) args << "-arc_file" << Options::xplanetArcFilePath(); - if (!file.fileName().isEmpty()) - args << "-output" << file.fileName() << "-quality" << Options::xplanetQuality(); + if (!m_File.fileName().isEmpty()) + args << "-output" << m_File.fileName() << "-quality" << Options::xplanetQuality(); // Labels if (Options::xplanetLabel()) { args << "-fontsize" << Options::xplanetFontSize() << "-color" << "0x" + Options::xplanetColor().mid(1) << "-date_format" << Options::xplanetDateFormat(); if (Options::xplanetLabelGMT()) args << "-gmtlabel"; else args << "-label"; if (!Options::xplanetLabelString().isEmpty()) args << "-label_string" << "\"" + Options::xplanetLabelString() + "\""; if (Options::xplanetLabelTL()) args << "-labelpos" << "+15+15"; else if (Options::xplanetLabelTR()) args << "-labelpos" << "-15+15"; else if (Options::xplanetLabelBR()) args << "-labelpos" << "-15-15"; else if (Options::xplanetLabelBL()) args << "-labelpos" << "+15-15"; } // Markers if (Options::xplanetMarkerFile()) args << "-marker_file" << Options::xplanetMarkerFilePath(); if (Options::xplanetMarkerBounds()) args << "-markerbounds" << Options::xplanetMarkerBoundsPath(); // Position // This sets the position from which the planet is viewed. // Note that setting Latitude and Longitude means that position above the SAME object - if(object == origin) + if(m_CurrentObjectIndex == m_CurrentOriginIndex) { if (Options::xplanetRandom()) args << "-random"; else - args << "-latitude" << QString::number(lat) << "-longitude" << QString::number(lon) << "-radius" << QString::number(radius); + args << "-latitude" << QString::number(m_lat) << "-longitude" << QString::number(m_lon) << "-radius" << QString::number(m_Radius); } else - args << "-origin" << origin; + args << "-origin" << m_OriginName; // Projection if (Options::xplanetProjection()) { switch (Options::xplanetProjection()) { case 1: args << "-projection" << "ancient"; break; case 2: args << "-projection" << "azimuthal"; break; case 3: args << "-projection" << "bonne"; break; case 4: args << "-projection" << "gnomonic"; break; case 5: args << "-projection" << "hemisphere"; break; case 6: args << "-projection" << "lambert"; break; case 7: args << "-projection" << "mercator"; break; case 8: args << "-projection" << "mollweide"; break; case 9: args << "-projection" << "orthographic"; break; case 10: args << "-projection" << "peters"; break; case 11: args << "-projection" << "polyconic"; break; case 12: args << "-projection" << "rectangular"; break; case 13: args << "-projection" << "tsc"; break; default: break; } if (Options::xplanetBackground()) { if (Options::xplanetBackgroundImage()) args << "-background" << Options::xplanetBackgroundImagePath(); else args << "-background" << "0x" + Options::xplanetBackgroundColorValue().mid(1); } } #ifdef Q_OS_OSX if (Options::xplanetIsInternal()) { QString searchDir = QCoreApplication::applicationDirPath() + "/xplanet/share/xplanet/"; args << "-searchdir" << searchDir; } #endif //This prevents it from running forever. args << "-num_times" << "1"; - // Run xplanet - if(Options::xplanetUseFIFO()) - QtConcurrent::run(this, &XPlanetImageViewer::loadImage); + m_XPlanetRunning = true; + m_ImageLoadSucceeded = false; //This will be set to true if it works. + uint32_t timeout = Options::xplanetTimeout(); + + //FIFO files don't work on windows + #ifndef Q_OS_WIN + if(Options::xplanetUseFIFO()) + { + fifoImageLoadWatcher.setFuture(QtConcurrent::run(this, &XPlanetImageViewer::loadImage)); + watcherTimeout.setSingleShot(true); + watcherTimeout.start(timeout); + } + #endif + xplanetProc->start(xPlanetLocation, args); + //Uncomment to print the XPlanet commands to the console // qDebug() << "Run:" << xplanetProc->program() << args.join(" "); - xplanetRunning = true; - bool succeeded = xplanetProc->waitForFinished(Options::xplanetTimeout().toInt()); - xplanetRunning = false; + + bool XPlanetSucceeded = xplanetProc->waitForFinished(timeout); + m_XPlanetRunning = false; + xplanetProc->kill(); //In case it timed out xplanetProc->deleteLater(); - if(succeeded) + if(XPlanetSucceeded) { - if(FOV == 0) - m_Caption->setText(i18n("XPlanet View: ") + object + i18n(" from ") + origin + ", " + dateText); + if(m_FOV == 0) + m_Caption->setText(i18n("XPlanet View: %1 from %2 on %3", m_ObjectName, m_OriginName, m_DateText)); else - m_Caption->setText(i18n("XPlanet View: ") + object + i18n(" from ") + origin + ", " + dateText + i18n(", FOV: ") + QString::number(FOV)); - if(!Options::xplanetUseFIFO()) - loadImage(); - showImage(); - } -} + m_Caption->setText(i18n("XPlanet View: %1 from %2 on %3 at FOV: %4 deg", m_ObjectName, m_OriginName, m_DateText, m_FOV)); + #ifdef Q_OS_WIN + loadImage(); //This will also set imageLoadSucceeded based on whether it worked. + #else + if(Options::xplanetUseFIFO()) + return; //The loading of the image is handled with the watcher + else + loadImage(); //This will also set imageLoadSucceeded based on whether it worked. + #endif -bool XPlanetImageViewer::setupOutputFile() -{ - if(Options::xplanetUseFIFO()) - { - if(file.fileName().contains("/tmp/xplanetfifo") && file.exists()) - return true; - file.setFileName(QString("/tmp/xplanetfifo%1.png").arg(QUuid::createUuid().toString().mid(1, 8))); - int fd =0; - if ((fd = mkfifo(file.fileName().toLatin1(), S_IRUSR | S_IWUSR) < 0)) + if(m_ImageLoadSucceeded) + showImage(); + else { - KMessageBox::error(nullptr, i18n("Error making FIFO file %1: %2.", file.fileName(), strerror(errno))); - return false; + QString text = i18n("Loading of the image of object %1 failed.", m_ObjectName); + KMessageBox::error(this, text); } } else { - QDir writableDir; - QString xPlanetDirPath = KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "xplanet"; - writableDir.mkpath(xPlanetDirPath); - file.setFileName(xPlanetDirPath + QDir::separator() + object + ".png"); + KStars::Instance()->statusBar()->showMessage(i18n("XPlanet failed to generate the image for object %1 before the timeout expired.", m_ObjectName)); + #ifndef Q_OS_WIN + if(Options::xplanetUseFIFO()) + fifoImageLoadWatcher.cancel(); + #endif } +} + +bool XPlanetImageViewer::setupOutputFile() +{ + #ifndef Q_OS_WIN + if(Options::xplanetUseFIFO()) + { + if(m_File.fileName().contains("xplanetfifo") && m_File.exists()) + return true; + QDir kstarsTempDir(KSPaths::writableLocation(QStandardPaths::TempLocation)); + kstarsTempDir.mkdir(kstarsTempDir.absolutePath()); + m_File.setFileName(kstarsTempDir.absolutePath() + QDir::separator() + QString("xplanetfifo%1.png").arg(QUuid::createUuid().toString().mid(1, 8)).toLatin1()); + int mkFifoSuccess = 0; //Note if the return value of the command is 0 it succeeded, -1 means it failed. + if ((mkFifoSuccess = mkfifo(m_File.fileName().toLatin1(), S_IRUSR | S_IWUSR) < 0)) + { + KMessageBox::error(nullptr, i18n("Error making FIFO file %1: %2.", m_File.fileName(), strerror(errno))); + return false; + } + return true; + } + #endif + //If the user is using windows or has not selected to use FIFO, it uses files in the KStars data directory. + QDir writableDir; + QString xPlanetDirPath = KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "xplanet"; + writableDir.mkpath(xPlanetDirPath); + m_File.setFileName(xPlanetDirPath + QDir::separator() + m_ObjectName + ".png"); return true; } void XPlanetImageViewer::zoomInXPlanetFOV() { - if(origin == object) + if(m_CurrentObjectIndex == m_CurrentOriginIndex) { - radius += 5; - radDisplay->setText(QString::number(radius)); + m_Radius += 5; + updatePositionDisplay(); startXplanet(); } else { - FOVEdit->stepDown(); + m_FOVEdit->stepDown(); startXplanet(); } } void XPlanetImageViewer::zoomOutXPlanetFOV() { - if(origin == object) + if(m_CurrentObjectIndex == m_CurrentOriginIndex) { - if(radius > 0) + if(m_Radius > 0) { - radius -= 5; - radDisplay->setText(QString::number(radius)); + m_Radius -= 5; + updatePositionDisplay(); startXplanet(); } } else { - FOVEdit->stepUp(); + m_FOVEdit->stepUp(); startXplanet(); } } +void XPlanetImageViewer::updatePositionDisplay() +{ + m_PositionDisplay->setText(i18n("%1, %2, %3", QString::number(m_lat), QString::number(m_lon), QString::number(m_Radius))); +} + void XPlanetImageViewer::updateXPlanetTime(int timeShift){ KStarsDateTime shiftedXPlanetTime; - switch(timeUnit) + switch(m_CurrentTimeUnitIndex) { case YEARS: - shiftedXPlanetTime = xplanetTime.addDays(timeShift * 365); + shiftedXPlanetTime = m_XPlanetTime.addDays(timeShift * 365); break; case MONTHS: - shiftedXPlanetTime = xplanetTime.addDays(timeShift * 30); + shiftedXPlanetTime = m_XPlanetTime.addDays(timeShift * 30); break; case DAYS: - shiftedXPlanetTime = xplanetTime.addDays(timeShift); + shiftedXPlanetTime = m_XPlanetTime.addDays(timeShift); break; case HOURS: - shiftedXPlanetTime = xplanetTime.addSecs(timeShift * 3600); + shiftedXPlanetTime = m_XPlanetTime.addSecs(timeShift * 3600); break; case MINS: - shiftedXPlanetTime = xplanetTime.addSecs(timeShift * 60); + shiftedXPlanetTime = m_XPlanetTime.addSecs(timeShift * 60); break; case SECS: - shiftedXPlanetTime = xplanetTime.addSecs(timeShift); + shiftedXPlanetTime = m_XPlanetTime.addSecs(timeShift); break; } setXPlanetDate(shiftedXPlanetTime); - dateText = shiftedXPlanetTime.date().toString() + ", " + shiftedXPlanetTime.time().toString(); - timeEdit->setValue(timeShift); - startXplanet(); + m_DateText = i18n("%1, %2", shiftedXPlanetTime.date().toString(), shiftedXPlanetTime.time().toString()); + if(m_TimeEdit->value() != timeShift) + m_TimeEdit->setValue(timeShift); + else + startXplanet(); } -void XPlanetImageViewer::updateXPlanetObject(const QString &obj){ - object = obj; +void XPlanetImageViewer::updateXPlanetObject(int objectIndex){ + m_CurrentObjectIndex = objectIndex; + m_ObjectName = m_ObjectNames.at(objectIndex); - setWindowTitle(i18n("XPlanet Solar System Simulator: %1", object)); - if(freeRotate->isChecked()) - originSelector->setCurrentIndex(originSelector->findText(object)); + setWindowTitle(i18n("XPlanet Solar System Simulator: %1", m_ObjectName)); + if(m_FreeRotate->isChecked()) + m_OriginSelector->setCurrentIndex(m_CurrentObjectIndex); startXplanet(); } -void XPlanetImageViewer::updateXPlanetOrigin(const QString &obj) +void XPlanetImageViewer::updateXPlanetOrigin(int originIndex) { - origin = obj; - if(object == origin) - freeRotate->setChecked(true); + m_CurrentOriginIndex = originIndex; + m_OriginName = m_ObjectNames.at(originIndex); + if(m_CurrentObjectIndex == m_CurrentOriginIndex) + m_FreeRotate->setChecked(true); else - freeRotate->setChecked(false); + m_FreeRotate->setChecked(false); updateStates();//This will update the disabled/enabled states startXplanet(); } void XPlanetImageViewer::changeXPlanetPosition(QPoint delta) { - if(origin == object) + if(m_CurrentObjectIndex == m_CurrentOriginIndex) { - double newLon = lon + delta.x(); - double newLat = lat + delta.y(); + double newLon = m_lon + delta.x(); + double newLat = m_lat + delta.y(); - if(newLat > 90) - newLat = 90; - if(newLat < -90) - newLat = -90; + newLat = qBound(-90.0, newLat, 90.0); - lon = newLon; - lat = newLat; + m_lon = newLon; + m_lat = newLat; - latDisplay->setText(QString::number(lat)); - lonDisplay->setText(QString::number(lon)); + updatePositionDisplay(); startXplanet(); } } void XPlanetImageViewer::slotFreeRotate() { - if(freeRotate->isChecked()) - originSelector->setCurrentIndex(originSelector->findText(object)); + if(m_FreeRotate->isChecked()) + m_OriginSelector->setCurrentIndex(m_CurrentObjectIndex); else - originSelector->setCurrentIndex(originSelector->findText(i18n("Earth"))); + m_OriginSelector->setCurrentIndex(EARTH); } void XPlanetImageViewer::updateStates() { - if(freeRotate->isChecked()) + if(m_FreeRotate->isChecked()) { - FOVEdit->setDisabled(true); - kstarsFOV->setDisabled(true); - noFOV->setDisabled(true); + m_FOVEdit->setDisabled(true); + m_KStarsFOV->setDisabled(true); + m_NoFOV->setDisabled(true); - latDisplay->setDisabled(false); - lonDisplay->setDisabled(false); - radDisplay->setDisabled(false); + m_PositionDisplay->setDisabled(false); } else { - FOVEdit->setDisabled(false); - kstarsFOV->setDisabled(false); - noFOV->setDisabled(false); + m_FOVEdit->setDisabled(false); + m_KStarsFOV->setDisabled(false); + m_NoFOV->setDisabled(false); - latDisplay->setDisabled(true); - lonDisplay->setDisabled(true); - radDisplay->setDisabled(true); + m_PositionDisplay->setDisabled(true); } } void XPlanetImageViewer::setXPlanetDate(KStarsDateTime time){ //Note Xplanet uses UT time for everything but we want the labels to all be LT KStarsDateTime utTime = KStarsData::Instance()->geo()->LTtoUT(time); - QString year, month, day, hour, minute, second; - - if (year.setNum(utTime.date().year()).size() == 1) - year.push_front('0'); - if (month.setNum(utTime.date().month()).size() == 1) - month.push_front('0'); - if (day.setNum(utTime.date().day()).size() == 1) - day.push_front('0'); - if (hour.setNum(utTime.time().hour()).size() == 1) - hour.push_front('0'); - if (minute.setNum(utTime.time().minute()).size() == 1) - minute.push_front('0'); - if (second.setNum(utTime.time().second()).size() == 1) - second.push_front('0'); - - date = year + month + day + '.' + hour + minute + second; - + m_Date = utTime.toString(Qt::ISODate) + .replace("-",QString("")) + .replace("T",".") + .replace(":",QString("")) + .replace("Z",QString("")); } void XPlanetImageViewer::updateXPlanetTimeUnits(int units) { - timeUnit = units; + m_CurrentTimeUnitIndex = units; updateXPlanetTimeEdit(); } void XPlanetImageViewer::updateXPlanetTimeEdit() { - int timeShift = timeEdit->text().toInt(); - if(timeSlider->value() != timeShift) - timeSlider->setValue(timeShift); + if(m_TimeSlider->isSliderDown()) + return; + int timeShift = m_TimeEdit->value(); + if(m_TimeSlider->value() != timeShift) + { + + if(timeShift > m_TimeSlider->maximum() + 100) + m_TimeSlider->setMaximum(timeShift); + if(timeShift < m_TimeSlider->minimum() - 100) + m_TimeSlider->setMinimum(timeShift); + m_TimeSlider->setValue(timeShift); + } else updateXPlanetTime(timeShift); } +void XPlanetImageViewer::timeSliderDisplay(int timeShift) +{ + m_TimeEdit->setValue(timeShift); +} + void XPlanetImageViewer::incrementXPlanetTime() { - if(!xplanetRunning) + if(!m_XPlanetRunning) { - int timeShift = timeEdit->text().toInt(); - if(timeSlider->maximum() == timeShift) - timeSlider->setMaximum(timeSlider->maximum() + 1); - if(timeEdit->maximum() == timeShift) - timeEdit->setMaximum(timeSlider->maximum() + 1); - timeSlider->setValue(timeShift + 1); + int timeShift = m_TimeEdit->value(); + if(m_TimeSlider->maximum() <= timeShift) + m_TimeSlider->setMaximum(timeShift + 100); + if(m_TimeEdit->maximum() <= timeShift) + m_TimeEdit->setMaximum(timeShift + 100); + m_TimeSlider->setValue(timeShift + 1); } } void XPlanetImageViewer::setXPlanetTime() { - QPointer timedialog = new TimeDialog(xplanetTime, KStarsData::Instance()->geo(), this); + QPointer timedialog = new TimeDialog(m_XPlanetTime, KStarsData::Instance()->geo(), this); if (timedialog->exec() == QDialog::Accepted) { - xplanetTime = timedialog->selectedDateTime(); - XPlanetTimeDisplay->setText(xplanetTime.date().toString() + ", " + xplanetTime.time().toString()); + m_XPlanetTime = timedialog->selectedDateTime(); + m_XPlanetTimeDisplay->setText(i18n("%1, %2", m_XPlanetTime.date().toString(), m_XPlanetTime.time().toString())); int timeShift = 0; - timeSlider->setMaximum(100); - if(timeSlider->value() != timeShift) - timeSlider->setValue(timeShift); + m_TimeSlider->setRange(-100,100); + if(m_TimeSlider->value() != timeShift) + m_TimeSlider->setValue(timeShift); else updateXPlanetTime(timeShift); - startXplanet(); } } void XPlanetImageViewer::setXPlanetTimetoKStarsTime() { - xplanetTime = KStarsData::Instance()->lt(); - XPlanetTimeDisplay->setText(xplanetTime.date().toString() + ", " + xplanetTime.time().toString()); + m_XPlanetTime = KStarsData::Instance()->lt(); + m_XPlanetTimeDisplay->setText(i18n("%1, %2", m_XPlanetTime.date().toString(), m_XPlanetTime.time().toString())); int timeShift = 0; - timeSlider->setMaximum(100); - if(timeSlider->value() != timeShift) - timeSlider->setValue(timeShift); + m_TimeSlider->setRange(-100,100); + if(m_TimeSlider->value() != timeShift) + m_TimeSlider->setValue(timeShift); else updateXPlanetTime(timeShift); - startXplanet(); } void XPlanetImageViewer::resetXPlanetTime() { int timeShift = 0; - timeSlider->setMaximum(100); - timeEdit->setMaximum(100); - if(timeSlider->value() != timeShift) - timeSlider->setValue(timeShift); + m_TimeSlider->setRange(-100, 100); + if(m_TimeSlider->value() != timeShift) + m_TimeSlider->setValue(timeShift); else updateXPlanetTime(timeShift); } void XPlanetImageViewer::toggleXPlanetRun() { - if(XPlanetTimer->isActive()) + if(m_XPlanetTimer->isActive()) { - XPlanetTimer->stop(); + m_XPlanetTimer->stop(); + #ifndef Q_OS_WIN + if(Options::xplanetUseFIFO()) + fifoImageLoadWatcher.cancel(); + #endif } else { - XPlanetTimer->setInterval(Options::xplanetAnimationDelay().toInt()); - XPlanetTimer->start(); + m_XPlanetTimer->setInterval(Options::xplanetAnimationDelay()); + m_XPlanetTimer->start(); } } void XPlanetImageViewer::updateXPlanetFOVEdit() { - FOV = FOVEdit->value(); + m_FOV = m_FOVEdit->value(); startXplanet(); } void XPlanetImageViewer::clearXPlanetFOV() { - FOV = 0; - FOVEdit->setValue(0); + m_FOV = 0; + m_FOVEdit->setValue(0); startXplanet(); } void XPlanetImageViewer::setKStarsXPlanetFOV() { - FOV = KStars::Instance()->map()->fov(); - FOVEdit->setValue(FOV); + m_FOV = KStars::Instance()->map()->fov(); + m_FOVEdit->setValue(m_FOV); startXplanet(); } void XPlanetImageViewer::updateXPlanetRotationEdit() { - rotation = rotateEdit->value(); + m_Rotation = m_RotateEdit->value(); startXplanet(); } void XPlanetImageViewer::resetXPlanetRotation(){ - rotateEdit->setValue(0); + m_RotateEdit->setValue(0); } void XPlanetImageViewer::invertXPlanetRotation(){ - rotateEdit->setValue(180); + m_RotateEdit->setValue(180); } bool XPlanetImageViewer::loadImage() { #ifndef KSTARS_LITE - if (!image.load(file.fileName())) + + if (!m_Image.load(m_File.fileName())) { - QString text = i18n("Loading of the image of object %1 failed.", object); - KMessageBox::error(this, text); + m_ImageLoadSucceeded = false; return false; } + m_ImageLoadSucceeded = true; return true; #else + imageLoadSucceeded = false; return false; #endif } bool XPlanetImageViewer::showImage() { #ifndef KSTARS_LITE //If the image is larger than screen width and/or screen height, //shrink it to fit the screen QRect deskRect = QApplication::desktop()->availableGeometry(); int w = deskRect.width(); // screen width int h = deskRect.height(); // screen height - if (image.width() <= w && image.height() > h) //Window is taller than desktop - image = image.scaled(int(image.width() * h / image.height()), h); - else if (image.height() <= h && image.width() > w) //window is wider than desktop - image = image.scaled(w, int(image.height() * w / image.width())); - else if (image.width() > w && image.height() > h) //window is too tall and too wide + if (m_Image.width() <= w && m_Image.height() > h) //Window is taller than desktop + m_Image = m_Image.scaled(int(m_Image.width() * h / m_Image.height()), h); + else if (m_Image.height() <= h && m_Image.width() > w) //window is wider than desktop + m_Image = m_Image.scaled(w, int(m_Image.height() * w / m_Image.width())); + else if (m_Image.width() > w && m_Image.height() > h) //window is too tall and too wide { //which needs to be shrunk least, width or height? - float fx = float(w) / float(image.width()); - float fy = float(h) / float(image.height()); + float fx = float(w) / float(m_Image.width()); + float fy = float(h) / float(m_Image.height()); if (fx > fy) //width needs to be shrunk less, so shrink to fit in height - image = image.scaled(int(image.width() * fy), h); + m_Image = m_Image.scaled(int(m_Image.width() * fy), h); else //vice versa - image = image.scaled(w, int(image.height() * fx)); + m_Image = m_Image.scaled(w, int(m_Image.height() * fx)); } const bool initialLoad = !isVisible(); show(); // hide is default - m_View->setImage(image); - w = image.width(); + m_View->setImage(m_Image); + w = m_Image.width(); //If the caption is wider than the image, set the window size //to fit the caption if (m_Caption->width() > w) w = m_Caption->width(); if(initialLoad) - resize(w, image.height()); + resize(w, m_Image.height()); else { m_View->refreshImage(); } update(); show(); return true; #else return false; #endif } void XPlanetImageViewer::saveFileToDisk() { #ifndef KSTARS_LITE + QFileDialog saveDialog(KStars::Instance(), i18n("Save Image"), m_LastFile); + saveDialog.setDefaultSuffix("png"); + saveDialog.setAcceptMode(QFileDialog::AcceptSave); + saveDialog.exec(); - QUrl newURL = QFileDialog::getSaveFileUrl(KStars::Instance(), i18n("Save Image"), lastURL); // save-dialog with default filename - if (!newURL.isEmpty()) - { - if (newURL.toLocalFile().endsWith(QLatin1String(".png")) == false) - newURL.setPath(newURL.toLocalFile() + ".png"); + if(saveDialog.result() == QFileDialog::Rejected) + return; + if(saveDialog.selectedFiles().isEmpty()) + return; + QString newFileName = saveDialog.selectedFiles().first(); + if(newFileName.isEmpty()) + return; - QFile f(newURL.toLocalFile()); - if (f.exists()) - { - int r = KMessageBox::warningContinueCancel(parentWidget(), - i18n("A file named \"%1\" already exists. " - "Overwrite it?", - newURL.fileName()), - i18n("Overwrite File?"), KStandardGuiItem::overwrite()); - if (r == KMessageBox::Cancel) - return; - - f.remove(); - } + m_LastFile = newFileName; - lastURL = QUrl(newURL.toString(QUrl::RemoveFilename)); + saveFile(newFileName); - saveFile(newURL); - } #endif } -void XPlanetImageViewer::saveFile(QUrl &url) +void XPlanetImageViewer::saveFile(const QString &fileName) { #ifndef KSTARS_LITE - if (file.copy(url.toLocalFile()) == false) + + if (! m_Image.save(fileName, "png")) { - QString text = i18n("Saving of the image %1 failed.", url.toString()); + QString text = i18n("Saving of the image to %1 failed.", fileName); KMessageBox::error(this, text); } else - KStars::Instance()->statusBar()->showMessage(i18n("Saved image to %1", url.toString())); + KStars::Instance()->statusBar()->showMessage(i18n("Saved image to %1", fileName)); #endif } void XPlanetImageViewer::invertColors() { #ifndef KSTARS_LITE // Invert colors m_View->invertPixels(); m_View->update(); #endif } diff --git a/kstars/auxiliary/xplanetimageviewer.h b/kstars/auxiliary/xplanetimageviewer.h index ffb1dbf97..e0cece6e8 100644 --- a/kstars/auxiliary/xplanetimageviewer.h +++ b/kstars/auxiliary/xplanetimageviewer.h @@ -1,237 +1,244 @@ /*************************************************************************** XPlanetImageviewer.cpp - Based on: KStars Image Viwer by Thomas Kabelmann ------------------- begin : Sun Aug 12, 2018 copyright : (C) 2018 by Robert Lancaster email : rlancaste@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #pragma once #include "auxiliary/filedownloader.h" #include #include #include #include "nonlineardoublespinbox.h" #include #include #include #include #include -#include #include "kstarsdata.h" #include #include #include class QLabel; /** * @class XPlanetImageLabel * @short XPlanet Image viewer QFrame for the KPlanetImageViewer for KStars * @author Thomas Kabelmann * @author Jasem Mutlaq * @author Robert Lancaster * @version 1.1 * * This image-viewer QFrame automatically resizes the picture. It also receives input from the mouse to * zoom and pan the XPlanet Image. */ class XPlanetImageLabel : public QFrame { Q_OBJECT public: explicit XPlanetImageLabel(QWidget *parent); ~XPlanetImageLabel() override = default; void setImage(const QImage &img); void invertPixels(); void refreshImage(); public slots: void wheelEvent(QWheelEvent *e) override; void mousePressEvent(QMouseEvent *e) override; void mouseReleaseEvent(QMouseEvent *e) override; void mouseMoveEvent(QMouseEvent *e) override; signals: void zoomIn(); void zoomOut(); void changePosition(QPoint); protected: void paintEvent(QPaintEvent *e) override; void resizeEvent(QResizeEvent *) override; private: //Image related - QPixmap pix; + QPixmap m_Pix; QImage m_Image; //Mouse related - bool mouseButtonDown = false; - QPoint lastMousePoint; + bool m_MouseButtonDown = false; + QPoint m_LastMousePoint; bool event(QEvent *event) override; bool gestureEvent(QGestureEvent *event); void pinchTriggered(QPinchGesture *gesture); }; /** * @class XPlanetImageViewer * @short XPlanet Image viewer window for KStars * @author Thomas Kabelmann * @author Jasem Mutlaq * @author Robert Lancaster * @version 1.1 * * This class is meant to interact with XPlanet and display the results. It has interfaces to control many of the XPlanet Options. * It can change a number of properties using controls. It works with the XPlanetImageLabel to display the results. It also can work * with the XPlanetImageLabel to respond to mouse inputs on the ImageLabel and act on them in the Image Viewer. It has a hover mode where * it hovers over the same planetary body or a remote mode where it views one body from another. It has interfaces for changing the field of * view, the time, the rotation, and other settings. In hover mode, it can change latitude, longitude, and radius with the mouse inputs. * It also can animate events so that you can watch xplanet frames like a movie to see solar system events in action. */ class XPlanetImageViewer : public QDialog { Q_OBJECT public: /** Create xplanet image viewer from Object */ explicit XPlanetImageViewer(const QString &obj, QWidget *parent = nullptr); /** Destructor. If there is a partially downloaded image file, delete it.*/ ~XPlanetImageViewer() override; /** * @brief loadImage Load image from local file and display it * @param filename path to local image * @return True if opened and displayed, false otherwise */ bool loadImage(); void startXplanet(); private: - /** - * Display the downloaded image. Resize the window to fit the image, If the image is - * larger than the screen, make the image as large as possible while preserving the - * original aspect ratio - */ - bool showImage(); + /** prepares the output file**/ bool setupOutputFile(); - QImage image; + QImage m_Image; /** Save the downloaded image to a local file. */ - void saveFile(QUrl &url); - - QFile file; + void saveFile(const QString & fileName); - QString filename; - - FileDownloader downloadJob; + QFile m_File; XPlanetImageLabel *m_View { nullptr }; QLabel *m_Caption { nullptr }; - QUrl lastURL; + QString m_LastFile; + + QStringList m_ObjectNames; typedef enum { YEARS, MONTHS, DAYS, HOURS, MINS, SECS } timeUnits; void setXPlanetDate(KStarsDateTime time); //XPlanet strings - QString object; - QString origin; - QString date; - QString dateText; + QString m_ObjectName; + QString m_OriginName; + QString m_Date; + QString m_DateText; //XPlanet numbers - int rotation; - int timeUnit; - int radius; - double FOV; - double lat; - double lon; + int m_CurrentObjectIndex { 0 }; + int m_CurrentOriginIndex { 0 }; + int m_Rotation { 0 }; + int m_CurrentTimeUnitIndex { 0 }; + uint32_t m_Radius { 0 }; + double m_FOV { 0 }; + double m_lat { 0 }; + double m_lon { 0 }; + +#ifndef Q_OS_WIN + QFutureWatcher fifoImageLoadWatcher; + QTimer watcherTimeout; +#endif // Time - KStarsDateTime xplanetTime; - bool xplanetRunning = false; + KStarsDateTime m_XPlanetTime {}; + bool m_XPlanetRunning = false; - QComboBox *originSelector {nullptr}; + QComboBox *m_OriginSelector {nullptr}; // Field of view controls - QPushButton *kstarsFOV {nullptr}; - QPushButton *noFOV {nullptr}; - NonLinearDoubleSpinBox *FOVEdit {nullptr}; + QPushButton *m_KStarsFOV {nullptr}; + QPushButton *m_NoFOV {nullptr}; + NonLinearDoubleSpinBox *m_FOVEdit {nullptr}; // Rotation controls - QSpinBox *rotateEdit {nullptr}; + QSpinBox *m_RotateEdit {nullptr}; // Free rotation controls - QLabel *latDisplay {nullptr}; - QLabel *lonDisplay {nullptr}; - QLabel *radDisplay {nullptr}; - QPushButton *freeRotate {nullptr}; + QLabel *m_PositionDisplay {nullptr}; + QPushButton *m_FreeRotate {nullptr}; + bool m_ImageLoadSucceeded = false; // Time controls - QLabel *XPlanetTimeDisplay {nullptr}; - QSlider *timeSlider {nullptr}; - QSpinBox *timeEdit {nullptr}; - QComboBox *timeUnitsSelect {nullptr}; + QLabel *m_XPlanetTimeDisplay {nullptr}; + QSlider *m_TimeSlider {nullptr}; + QSpinBox *m_TimeEdit {nullptr}; + QComboBox *m_TimeUnitsSelect {nullptr}; //Animation controls - QPushButton *runTime {nullptr}; - QTimer *XPlanetTimer {nullptr}; + QPushButton *m_RunTime {nullptr}; + QTimer *m_XPlanetTimer {nullptr}; private slots: + /** + * Display the downloaded image. Resize the window to fit the image, If the image is + * larger than the screen, make the image as large as possible while preserving the + * original aspect ratio + */ + bool showImage(); + // Saves file to disk. void saveFileToDisk(); // Inverts colors void invertColors(); // Rotation slots void updateXPlanetRotationEdit(); void resetXPlanetRotation(); void invertXPlanetRotation(); // Free Rotation slots void changeXPlanetPosition(QPoint delta); void slotFreeRotate(); void updateStates(); + void updatePositionDisplay(); // Field of View slots void zoomInXPlanetFOV(); void zoomOutXPlanetFOV(); void updateXPlanetFOVEdit(); void clearXPlanetFOV(); void setKStarsXPlanetFOV(); // Time slots void updateXPlanetTime(int timeShift); - void updateXPlanetObject(const QString & obj); - void updateXPlanetOrigin(const QString & obj); + void updateXPlanetObject(int objectIndex); + void updateXPlanetOrigin(int originIndex); void updateXPlanetTimeUnits(int units); void updateXPlanetTimeEdit(); void setXPlanetTime(); void setXPlanetTimetoKStarsTime(); void resetXPlanetTime(); // Animation slots void incrementXPlanetTime(); void toggleXPlanetRun(); + void timeSliderDisplay(int timeShift); }; diff --git a/kstars/kstars.kcfg b/kstars/kstars.kcfg index c1e958302..9f062d5da 100644 --- a/kstars/kstars.kcfg +++ b/kstars/kstars.kcfg @@ -1,2230 +1,2230 @@ ksutils.h The screen coordinates of the Time InfoBox. QPoint(0,0) The screen coordinates of the Focus InfoBox. QPoint(600,0) The screen coordinates of the Geographic Location InfoBox. QPoint(0,600) If true, the Time InfoBox will show only its top line of data. true If true, the Focus InfoBox will show only its top line of data. true If true, the Geographic Location InfoBox will show only its top line of data. true Toggles display of all three InfoBoxes. true Toggles display of the Time InfoBox. true Toggles display of the Focus InfoBox. true Toggles display of the Geographic Location InfoBox. true Is the Time InfoBox anchored to a window edge? 0 = not anchored; 1 = anchored to right edge; 2 = anchored to bottom edge; 3 = anchored to bottom and right edges. 0 0 3 Is the Focus InfoBox anchored to a window edge? 0 = not anchored; 1 = anchored to right edge; 2 = anchored to bottom edge; 3 = anchored to bottom and right edges. 1 0 3 Is the Geographic Location InfoBox anchored to a window edge? 0 = not anchored; 1 = anchored to right edge; 2 = anchored to bottom edge; 3 = anchored to bottom and right edges. 2 0 3 Toggle display of the status bar. true Toggle display of the Horizontal coordinates of the mouse cursor in the status bar. true Toggle display of the Equatorial coordinates of the mouse cursor at the current epoch in the status bar. true Toggle display of the Equatorial coordinates of the mouse cursor at the standard epoch in the status bar. false true 1024 768 true Black Body List of the filenames of custom object catalogs. List of integers toggling display of each custom object catalog (any nonzero value indicates the objects in that catalog will be displayed). List of names for which custom catalogs are to be displayed. Names of objects entered into the find dialog are resolved using online services and stored in the database. This option also toggles the display of such resolved objects on the sky map. true 800 600 true true false Toggle display of crosshairs centered at telescope's pointed position in the KStars sky map. true Toggle display of INDI messages in the KStars statusbar. true Show INDI messages as desktop notifications instead of dialogs. false true false false The default location of saved FITS files KSUtils::getDefaultPath("fitsDir") INDI server will attempt to bind with ports starting from this port 7624 INDI server will attempt to bind with ports ending with this port 9000 List of the aliases for filter wheel slots. PATH to indiserver binary KSUtils::getDefaultPath("indiServer") false PATH to indi drivers directory KSUtils::getDefaultPath("indiDriversDir") false 320 240 false false false false false false false false false false false The City name of the current geographic location. Greenwich The Province name of the current geographic location. This is the name of the state for locations in the U. S. The Country name of the current geographic location. United Kingdom The longitude of the current geographic location, in decimal degrees. 0.0 The latitude of the current geographic location, in decimal degrees. 51.468 -10.0 0.0 Two-letter code that determines the dates on which daylight savings time begins and ends (you can view the rules by pressing the "Explain DST Rules" button in the Geographic Location window). -- If true, focus changes will cause the sky to visibly spin to the new position. Otherwise, the display will "snap" instantly to the new position. true The names of the currently selected field-of-view indicators. The list of defined FOV indicator names is listed in the "Settings|FOV Symbols" menu. Telrad If true, trails attached to solar system bodies will fade into the background sky color. true The right ascension of the initial focus position of the sky map, in decimal hours. This value is volatile; it is reset whenever the program shuts down. 180.0 The declination of the initial focus position of the sky map, in decimal degrees. This value is volatile; it is reset whenever the program shuts down. 45.0 The name of the object that should be centered and tracked on startup. If no object should be centered, set to "nothing". This value is volatile; it is reset whenever the program shuts down. nothing True if the skymap should track on its initial position on startup. This value is volatile; it is reset whenever the program shuts down. false Toggle whether KStars should hide some objects while the display is moving, for smoother motion. true Toggle whether constellation boundaries are hidden while the display is in motion. true Toggle whether constellation lines are hidden while the display is in motion. false Choose sky culture. 11 Toggle whether constellation names are hidden while the display is in motion. false Toggle whether the coordinate grids are hidden while the display is in motion. true Toggle whether the Milky Way contour is hidden while the display is in motion. true Toggle whether IC objects are hidden while the display is in motion. true Toggle whether Messier objects are hidden while the display is in motion. true Toggle whether NGC objects are hidden while the display is in motion. true Toggle whether extra objects are hidden while the display is in motion. true Toggle whether solar system objects are hidden while the display is in motion. false Toggle whether faint stars are hidden while the display is in motion. true Toggle whether name labels are hidden while the display is in motion. true Toggle whether asteroids are drawn in the sky map. true Toggle whether asteroid name labels are drawn in the sky map. false Toggle whether comets are drawn in the sky map. true Toggle whether comet comas are drawn in the sky map. true Toggle whether comet name labels are drawn in the sky map. false Toggle whether supernovae are drawn in the sky map. false Toggle whether supernova name labels are drawn in the sky map. false Set magnitude limit for supernovae to be shown on the skymap. 16 Toggle supernova alerts. true Set magnitude limit for supernovae to be alerted. 13 Toggle whether constellation boundaries are drawn in the sky map. false Toggle whether constellation boundary containing the central focus point is highlighted in the sky map. false Toggle whether constellation lines are drawn in the sky map. false Toggle whether constellation art drawn in the sky map. false Toggle whether constellation name labels are drawn in the sky map. false Toggle whether deep-sky objects are drawn in the sky map. true Toggle whether the ecliptic line is drawn in the sky map. false Toggle whether the equator line is drawn in the sky map. false Coordinate grids will automatically change according to active coordinate system. true Toggle whether the equatorial coordinate grid is drawn in the sky map. false Toggle whether the horizontal coordinate grid is drawn in the sky map. false Toggle whether the local meridian line is drawn in the sky map. false Toggle whether the region below the horizon is opaque. true Toggle whether the horizon line is drawn in the sky map. true Toggle whether flags are drawn in the sky map. true Toggle whether IC objects are drawn in the sky map. false Toggle whether NGC objects are drawn in the sky map. true Toggle whether Messier objects are drawn in the sky map. true Toggle whether Messier objects are rendered as images in the sky map. true Toggle whether extra objects are drawn in the sky map. true Toggle whether the Milky Way contour is drawn in the sky map. true Toggle whether the Milky Way contour is filled. When this option is false, the Milky Way is shown as an outline. true Meta-option to control whether all major planets (and the Sun and Moon) are drawn in the sky map. true Toggle whether major planets (and the Sun and Moon) are rendered as images in the sky map. true Toggle whether major planets (and the Sun and Moon) are labeled in the sky map. true Toggle whether the Sun is drawn in the sky map. true Toggle whether the Moon is drawn in the sky map. true Toggle whether Mercury is drawn in the sky map. true Toggle whether Venus is drawn in the sky map. true Toggle whether Mars is drawn in the sky map. true Toggle whether Jupiter is drawn in the sky map. true Toggle whether Saturn is drawn in the sky map. true Toggle whether Uranus is drawn in the sky map. true Toggle whether Neptune is drawn in the sky map. true Toggle whether Pluto is drawn in the sky map. true Toggle whether stars are drawn in the sky map. true Toggle whether star magnitude (brightness) labels are shown in the sky map. false Toggle whether star name labels are shown in the sky map. true Toggle whether deep-sky object magnitude (brightness) labels are shown in the sky map. false Toggle whether deep-sky object name labels are shown in the sky map. false The timescale above which slewing mode is forced on at all times. 60 The background fill mode for the on-screen information boxes: 0="no BG"; 1="semi-transparent BG"; 2="opaque BG" 1 Algorithm for the mapping projection. 0 Use official IAU abbreviations for constellation names. false Use Latin constellation names. false Use localized constellation names (if localized names are not available, default to Latin names). true Display the sky with horizontal coordinates (when false, equatorial coordinates will be used). true Toggle whether a centered object automatically gets a name label attached. true Toggle whether a centered solar system object automatically gets a trail attached, as long as it remains centered. true Toggle whether the object under the mouse cursor gets a transient name label. true Toggle whether object positions are corrected for the effects of atmospheric refraction (only applies when horizontal coordinates are used). true Toggle whether corrections due to bending of light around the sun are taken into account false Toggle whether the sky is rendered using antialiasing. Lines and shapes are smoother with antialiasing, but rendering the screen will take more time. true The zoom level, measured in pixels per radian. 250. 250. 5000000. When zooming in or out, change zoom speed factor by this multiplier. 0.2 0.01 1.0 The faint magnitude limit for drawing asteroids. 15.0 The maximum magnitude (visibility) to filter the asteroid data download from JPL. 12.000 Controls the relative number of asteroid name labels drawn in the map. 4.0 The faint magnitude limit for drawing deep-sky objects, when fully zoomed in. 16.0 The faint magnitude limit for drawing deep-sky objects, when fully zoomed out. 5.0 When enabled, objects whose magnitudes are unknown, or not available to KStars, are drawn irrespective of the faint limits set. true Sets the density of stars in the field of view 5 The faint magnitude limit for drawing stars, when the map is in motion (only applicable if faint stars are set to be hidden while the map is in motion). 5.0 The relative density for drawing star name and magnitude labels. 2.0 The relative density for drawing deep-sky object name and magnitude labels. 5.0 If true, long names (common names) for deep-sky objects are shown in the labels. false The maximum solar distance for drawing comets. 3.0 Use experimental OpenGL backend (deprecated). false The state of the clock (running or not) true Objects in the observing list will be highlighted with a symbol in the map. true Objects in the observing list will be highlighted with a colored name label in the map. false The observing list will prefer DSS imagery while downloading imagery. true The observing list will prefer SDSS imagery while downloading imagery. false Check this if you use a large Dobsonian telescope. Sorting by percentage current altitude is an easy way of determining what objects are well-placed for observation. However, when using a large Dobsonian telescope, objects close to the zenith are hard to observe. Since tracking there corresponds to a rotation in azimuth, it is both counterintuitive and requires the observer to frequently move the ladder. The region around the zenith where this is particularly frustrating is called the Dobsonian hole. This checkbox makes the observing list consider objects present in the hole as unfit for observation. false This specifies the angular radius of the Dobsonian hole, i.e. the region where a large Dobsonian telescope cannot be pointed easily. 15.00 The name of the color scheme moonless-night.colors The method for rendering stars: 0="realistic colors"; 1="solid red"; 2="solid black"; 3="solid white"; 4="solid real colors" 0 4 The color saturation level of stars (only applicable when using "realistic colors" mode). 6 10 The color for the angular-distance measurement ruler. #FFF The background color of the on-screen information boxes. #000 The text color for the on-screen information boxes, when activated by a mouse click. #F00 The normal text color of the on-screen information boxes. #FFF The color for the constellation boundary lines. #222 The color for the constellation boundary lines. #222 The color for the constellation figure lines. #555 The color for the constellation names. #AA7 The color for the cardinal compass point labels. #002 The color for the ecliptic line. #663 The color for the equator line. #FFF The color for the equatorial coordinate grid lines. #456 The color for the horizontal coordinate grid lines. #5A3 The color for objects which have extra URL links available. #A00 The color for the horizon line and opaque ground. #5A3 The color for the local meridian line. #0059b3 The color for Messier object symbols. #0F0 The color for NGC object symbols. #066 The color for IC object symbols. #439 The color for the Milky Way contour. #123 The color for star name labels. #7AA The color for deep-sky object name labels. #7AA The color for solar system object labels. #439 The color for solar system object trails. #963 The color for the sky background. #002 The color for the artificial horizon region. #C82828 The color for telescope target symbols. #8B8 Color of visible satellites. #00FF00 Color of invisible satellites. #FF0000 Color of satellites labels. #640000 Color of supernova #FFA500 The color for user-added object labels. #439 The color for RA Guide Error bar in Ekos guide module. #00FF00 The color for DEC Guide Error bar in Ekos guide module. #00A5FF The color for solver FOV box in Ekos alignment module. #FFFF00 false Xplanet binary path KSUtils::getDefaultPath("XplanetPath") Option to use a FIFO file instead of saving to the hard disk true - + How long to wait for XPlanet before giving up in milliseconds 1000 - + How long to pause between frames in the XPlanet Animation 100 - + Width of xplanet window 640 - + Height of xplanet window 480 If true, display a label in the upper right corner. false Show local time. true Show GMT instead of local time. false Specify the text of the first line of the label. By default, it says something like "Looking at Earth". Any instances of %t will be replaced by the target name, and any instances of %o will be replaced by the origin name. Specify the point size. 12 Set the color for the label. #F00 Specify the format for the date/time label. This format string is passed to strftime(3). The default is "%c %Z", which shows the date, time, and time zone in the locale’s appropriate date and time representation. %c %Z false true false false Draw a glare around the sun with a radius of the specified value larger than the Sun. The default value is 28. 28 Place the observer above a random latitude and longitude false Place the observer above the specified longitude and latitude true Render the target body as seen from above the specified latitude (in degrees). The default value is 0. 0 Place the observer above the specified longitude (in degrees). Longitude is positive going east, negative going west (for the earth and moon), so for example Los Angeles is at -118 or 242. The default value is 0. 0 The default is no projection. Multiple bodies will not be shown if this option is specified, although shadows will still be drawn. 0 Use a file as the background image, with the planet to be superimposed upon it. This option is only meaningful with the -projection option. A color may also be supplied. false Use a file as the background image. false The path of the background image. Use a color as the background. true The color of the background. #000 A star of the specified magnitude will have a pixel brightness of 1. The default value is 10. Stars will be drawn more brightly if this number is larger. 10 If checked, use an arc file to be plotted against the background stars. false Specify an arc file to be plotted against the background stars. If checked, use a config file. false Use the specified configuration file. If checked, use kstars's FOV. false If checked, use the specified marker file. false Specify a file containing user-defined marker data to display against the background stars. If checked, write coordinates of the bounding box for each marker in a file. false Write coordinates of the bounding box for each marker to this file. If checked, use star map file to draw the background stars. false Star map file path This option is only used when creating JPEG images. The quality can range from 0 to 100. The default value is 80. 80 Toggle whether satellite tracks are drawn in the sky map. false Toggle whether satellite tracks are drawn in the sky map. false If selected, satellites will be draw like stars, otherwise, draw satellites as small colored square. false Toggle whether satellite labels are drawn in the sky map. false List of selected satellites. Checking this option causes recomputation of current equatorial coordinates from catalog coordinates (i.e. application of precession, nutation and aberration corrections) for every redraw of the map. This makes processing slower when there are many stars to handle, but is more likely to be bug free. There are known bugs in the rendering of stars when this recomputation is avoided. false The default size for DSS images downloaded from the Internet. 15.0 To include parts of the star field, we add some extra padding around DSS images of deep-sky objects. This option configures the total (both sides) padding added to either dimension of the field. 10.0 Checking this option causes KStars to generate verbose debug information for diagnostic purposes. This may cause slowdown of KStars. false Checking this option causes KStars to generate regular debug information. true Checking this option causes KStars to stop generating ANY debug information. false Checking this option causes KStars log debug messages to the default output used by the platform (e.g. Standard Error). true Checking this option causes KStars log debug messages to a log file as specified. false Log FITS Data activity. false Log INDI devices activity. false Log Ekos Capture Module activity. false Log Ekos Focus Module activity. false Log Ekos Guide Module activity. false Log Ekos Alignment Module activity. false Log Ekos Mount Module activity. false true Display all captured FITS images in a single tab instead of multiple tabs per image. true Display all captured FITS images in a single FITS Viewer window. By default each camera create its own FITS Viewer instance false Display all opened FITS images in a single FITS Viewer window. true false true true true false 4 false false 40.0 0 600 600 true false true false Simulators false true false 1 Minimum telescope altitude limit. If the telescope is below this limit, it will be commanded to stop. 0 Maximum telescope altitude limit. If the telescope is above this limit, it will be commanded to stop. 90.0 false false 1 0 If guide deviation exceeds this limit, the exposure will be automatically aborted and only resumed when the deviation is within this limit. 2 If HFR deviation exceeds this limit, the autofocus routine will be automatically started. 0.5 false false false Sets the time interval before forced autofocus attempts during a capture sequence. 60 If the target hour angle exceeds this value, Ekos will command a meridian flip and if successful it will resume guiding and capture operations. false false If set, Ekos will capture a few flat images to determine the optimal exposure time to achieve the desired ADU value. 0 Maximum difference between measured and target ADU values to deem the value as acceptable. 1000 0 0 0 0 0.1 0 true false 2.5 false 1 30 true true 0 KSUtils::getDefaultPath("fitsDir") Step size of the absolute focuser. The step size TICKS should be adjusted so that when the focuser moves TICKS steps, the difference in HFR is more than 0.1 pixels. Lower the value when you are close to optimal focus. 100 Wait for this many seconds after moving the focuser before capturing the next image during AutoFocus. 0 The tolerance specifies the percentage difference between the current focusing position and the minimum obtained during the focusing run. Adjustment of this value is necessary to prevent the focusing algorithm from oscillating back and forth. 1 Set the maximum travel distance of an absolute focuser. 10000 Specifies exposure value of CCD when performing focusing. Lower this value to avoid saturation of bright stars which adversely affects HFR measurement. Increase the value if no stars are detected. 0.5 Set box size to select a focus star. 64 Set horizontal binning of CCD camera while in focus mode. 1 Set vertical binning of CCD camera while in focus mode. 1 true false false true false 0 150 0 0 1 Specifies exposure value of CCD in seconds when performing plate solving. 1 Set binning index of CCD camera while in alignment mode. Default values 0-3 corresponding to 1x1 to 4x4 binning. 4 is max binning. 4 Display detailed verbose messages of the astrometry solver process while in progress. false Use rotator when performing load and slew. false Threshold between measured and FITS position angles in arcminutes to consider the load and slew operation successful. 30 0 0 0 true false false 30 0 false 1500 true true true true true 1 true 2 true true 30 false Path to astrometry.net solver location. KSUtils::getDefaultPath("AstrometrySolverBinary") false Path to astrometry.net wcsinfo location. KSUtils::getDefaultPath("AstrometryWCSInfo") false Path to astrometry.net file location. KSUtils::getDefaultPath("AstrometryConfFile") false Key to access astrometry.net online web services. You must register with astrometry.net to obtain a key. iczikaqstszeptgs http://nova.astrometry.net true 180 1.0 0 0 localhost 4400 localhost 5656 0 1000 2 false 1 false false false 5 60 10 true false false false 2 1 0 1 45 10 500 false false false 2 true true true true true true 133.33 133.33 0 0 0 0 5000 5000 100 100 0.5 2 true true false false Log Ekos Scheduler Module activity. false Sort scheduler jobs by priority and altitude. true true false false false false true false 2 5 30 0 0 0 0 0 0 7624 8624 300 1000 None false false Toggle whether the HIPS sources are drawn in the sky map. false diff --git a/kstars/xplanet/opsxplanet.cpp b/kstars/xplanet/opsxplanet.cpp index 0d5d7773a..525469dc5 100644 --- a/kstars/xplanet/opsxplanet.cpp +++ b/kstars/xplanet/opsxplanet.cpp @@ -1,191 +1,198 @@ /*************************************************************************** opsxplanet.cpp - K Desktop Planetarium ------------------- begin : Wed 26 Nov 2008 copyright : (C) 2008 by Jerome SONRIER email : jsid@emor3j.fr.eu.org ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "opsxplanet.h" #include "kstars.h" #include "kstarsdata.h" #include "Options.h" #include OpsXplanet::OpsXplanet(KStars *_ks) : QFrame(_ks), ksw(_ks) { setupUi(this); #ifdef Q_OS_OSX connect(kcfg_xplanetIsInternal, SIGNAL(clicked()), this, SLOT(toggleXPlanetInternal())); kcfg_xplanetIsInternal->setToolTip(i18n("Internal or External XPlanet?")); if (Options::xplanetIsInternal()) kcfg_XplanetPath->setEnabled(false); #else kcfg_xplanetIsInternal->setVisible(false); #endif // Init projections combobox kcfg_XplanetProjection->addItem(i18nc("Map projection method", "No projection"), "no projection"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Ancient"), "ancient"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Azimuthal"), "azimuthal"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Bonne"), "bonne"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Gnomonic"), "gnomonic"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Hemisphere"), "hemisphere"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Lambert"), "lambert"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Mercator"), "mercator"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Mollweide"), "mollweide"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Orthographic"), "orthographic"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Peters"), "peters"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Polyconic"), "polyconic"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "Rectangular"), "rectangular"); kcfg_XplanetProjection->addItem(i18nc("Map projection method", "TSC"), "tsc"); // Enable/Disable somme widgets connect(kcfg_XplanetConfigFile, SIGNAL(toggled(bool)), SLOT(slotConfigFileWidgets(bool))); connect(kcfg_XplanetStarmap, SIGNAL(toggled(bool)), SLOT(slotStarmapFileWidgets(bool))); connect(kcfg_XplanetArcFile, SIGNAL(toggled(bool)), SLOT(slotArcFileWidgets(bool))); connect(kcfg_XplanetLabel, SIGNAL(toggled(bool)), SLOT(slotLabelWidgets(bool))); connect(kcfg_XplanetMarkerFile, SIGNAL(toggled(bool)), SLOT(slotMarkerFileWidgets(bool))); connect(kcfg_XplanetMarkerBounds, SIGNAL(toggled(bool)), SLOT(slotMarkerBoundsWidgets(bool))); connect(kcfg_XplanetProjection, SIGNAL(currentIndexChanged(int)), SLOT(slotProjectionWidgets(int))); connect(kcfg_XplanetBackground, SIGNAL(toggled(bool)), SLOT(slotBackgroundWidgets(bool))); kcfg_XplanetConfigFilePath->setEnabled(Options::xplanetConfigFile()); kcfg_XplanetStarmapPath->setEnabled(Options::xplanetStarmap()); kcfg_XplanetArcFilePath->setEnabled(Options::xplanetArcFile()); kcfg_XplanetLabelLocalTime->setEnabled(Options::xplanetLabel()); kcfg_XplanetLabelGMT->setEnabled(Options::xplanetLabel()); textLabelXplanetLabelString->setEnabled(Options::xplanetLabel()); kcfg_XplanetLabelString->setEnabled(Options::xplanetLabel()); textLabelXplanetDateFormat->setEnabled(Options::xplanetLabel()); kcfg_XplanetDateFormat->setEnabled(Options::xplanetLabel()); textLabelXplanetFontSize->setEnabled(Options::xplanetLabel()); kcfg_XplanetFontSize->setEnabled(Options::xplanetLabel()); textLabelXplanetColor->setEnabled(Options::xplanetLabel()); kcfg_XplanetColor->setEnabled(Options::xplanetLabel()); textLabelLabelPos->setEnabled(Options::xplanetLabel()); kcfg_XplanetLabelTL->setEnabled(Options::xplanetLabel()); kcfg_XplanetLabelTR->setEnabled(Options::xplanetLabel()); kcfg_XplanetLabelBR->setEnabled(Options::xplanetLabel()); kcfg_XplanetLabelBL->setEnabled(Options::xplanetLabel()); kcfg_XplanetMarkerFilePath->setEnabled(Options::xplanetMarkerFile()); kcfg_XplanetMarkerBounds->setEnabled(Options::xplanetMarkerFile()); if (Options::xplanetMarkerFile() && Options::xplanetMarkerBounds()) kcfg_XplanetMarkerBoundsPath->setEnabled(true); else kcfg_XplanetMarkerBoundsPath->setEnabled(false); if (Options::xplanetProjection() == 0) groupBoxBackground->setEnabled(false); kcfg_XplanetBackgroundImage->setEnabled(Options::xplanetBackgroundImage()); kcfg_XplanetBackgroundImagePath->setEnabled(Options::xplanetBackgroundImage()); kcfg_XplanetBackgroundColor->setEnabled(Options::xplanetBackgroundImage()); kcfg_XplanetBackgroundColorValue->setEnabled(Options::xplanetBackgroundImage()); if (Options::xplanetProjection() == 0) groupBoxBackground->setEnabled(false); + #ifdef Q_OS_WIN + kcfg_XplanetUseFIFO->setChecked(false); + kcfg_XplanetUseFIFO->setDisabled(true); + kcfg_XplanetUseFIFO->setToolTip(i18n("FIFO files are not supported on Windows")); + #endif + + connect(openXPlanetMaps, SIGNAL(clicked()),this,SLOT(showXPlanetMapsDirectory())); } void OpsXplanet::showXPlanetMapsDirectory() { QString xplanetMapsDir; if (Options::xplanetIsInternal()) xplanetMapsDir = QCoreApplication::applicationDirPath() + "/xplanet/share/xplanet/images"; else xplanetMapsDir = Options::xplanetPath() + "../share/xplanet/images"; QUrl path = QUrl::fromLocalFile(xplanetMapsDir); QDesktopServices::openUrl(path); } void OpsXplanet::toggleXPlanetInternal() { kcfg_XplanetPath->setEnabled(!kcfg_xplanetIsInternal->isChecked()); if (kcfg_xplanetIsInternal->isChecked()) kcfg_XplanetPath->setText("*Internal XPlanet*"); else kcfg_XplanetPath->setText(KSUtils::getDefaultPath("XplanetPath")); } void OpsXplanet::slotConfigFileWidgets(bool on) { kcfg_XplanetConfigFilePath->setEnabled(on); } void OpsXplanet::slotStarmapFileWidgets(bool on) { kcfg_XplanetStarmapPath->setEnabled(on); } void OpsXplanet::slotArcFileWidgets(bool on) { kcfg_XplanetArcFilePath->setEnabled(on); } void OpsXplanet::slotLabelWidgets(bool on) { kcfg_XplanetLabelLocalTime->setEnabled(on); kcfg_XplanetLabelGMT->setEnabled(on); textLabelXplanetLabelString->setEnabled(on); kcfg_XplanetLabelString->setEnabled(on); textLabelXplanetDateFormat->setEnabled(on); kcfg_XplanetDateFormat->setEnabled(on); textLabelXplanetFontSize->setEnabled(on); kcfg_XplanetFontSize->setEnabled(on); textLabelXplanetColor->setEnabled(on); kcfg_XplanetColor->setEnabled(on); textLabelLabelPos->setEnabled(on); kcfg_XplanetLabelTL->setEnabled(on); kcfg_XplanetLabelTR->setEnabled(on); kcfg_XplanetLabelBR->setEnabled(on); kcfg_XplanetLabelBL->setEnabled(on); } void OpsXplanet::slotMarkerFileWidgets(bool on) { kcfg_XplanetMarkerFilePath->setEnabled(on); kcfg_XplanetMarkerBounds->setEnabled(on); if (kcfg_XplanetMarkerBounds->isChecked()) kcfg_XplanetMarkerBoundsPath->setEnabled(on); } void OpsXplanet::slotMarkerBoundsWidgets(bool on) { kcfg_XplanetMarkerBoundsPath->setEnabled(on); } void OpsXplanet::slotProjectionWidgets(int index) { if (index == 0) groupBoxBackground->setEnabled(false); else groupBoxBackground->setEnabled(true); if (!kcfg_XplanetBackground->isChecked()) { kcfg_XplanetBackgroundImage->setEnabled(false); kcfg_XplanetBackgroundImagePath->setEnabled(false); kcfg_XplanetBackgroundColor->setEnabled(false); kcfg_XplanetBackgroundColorValue->setEnabled(false); } } void OpsXplanet::slotBackgroundWidgets(bool on) { kcfg_XplanetBackgroundImage->setEnabled(on); kcfg_XplanetBackgroundImagePath->setEnabled(on); kcfg_XplanetBackgroundColor->setEnabled(on); kcfg_XplanetBackgroundColorValue->setEnabled(on); } diff --git a/kstars/xplanet/opsxplanet.ui b/kstars/xplanet/opsxplanet.ui index ceef1cf1c..49e769fb9 100644 --- a/kstars/xplanet/opsxplanet.ui +++ b/kstars/xplanet/opsxplanet.ui @@ -1,1066 +1,1066 @@ OpsXplanet 0 0 622 647 0 General QFormLayout::ExpandingFieldsGrow Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 0 0 Xplanet path: 0 0 Xplanet binary path Enter here the path of xplanet binary. Window size: QLayout::SetMaximumSize 0 0 50 16777215 Set the width of window Set the width of the xplanet image x true 50 16777215 Set the height of window Set the height of the xplanet image pixels Qt::Horizontal 40 20 The time KStars will wait for XPlanet to complete before giving up. XPlanet Timeout Animation Delay The delay between frames for the animation Qt::Vertical QSizePolicy::Fixed 506 13 QFormLayout::ExpandingFieldsGrow Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter Use kstars's FOV? If checked, use kstars's FOV. Use kstars's FOV Glare of Sun: 0 0 Radius of the glare around the Sun. Draw a glare around the sun with a radius of the specified value larger than the Sun. The default value is 28. Base magnitude: 0 0 A star of the specified magnitude will have a pixel brightness of 1 A star of the specified magnitude will have a pixel brightness of 1. The default value is 10. Stars will be drawn more brightly if this number is larger. Use custom star map? If checked, use star map file to draw the background stars. Star map: 0 0 Star map file path Star map file path 0 0 Arc file path Specify an arc file to be plotted against the background stars. 0 0 Config file path Use the specified configuration file Config file: Arc file: Use kstars's FOV? <html><head/><body><p>If checked, XPlanet will use a FIFO file in the /tmp directory to temporarily save the XPlanet image for KStars to load them and update the view. If not checked, XPlanet will actually save the files to the XPlanet folder in the KStars data directory. Using a FIFO file should save the hard disk from excessive reads/writes and may offer a performance enhancement.</p></body></html> Use FIFO File (saves to memory instead of a hard disk) Qt::Vertical QSizePolicy::Fixed 506 13 Output file quality: 0 0 JPEG Quality This option is only used when creating JPEG images. The quality can range from 0 to 100. The default value is 80. 100 Qt::Horizontal 40 20 - XPlanet Requires Maps in order to function properly. It does not ship with a lot of planetary maps. You need to download some in order to get the full benefits of XPlanet. This is a good place to start: <a href =http://xplanet.sourceforge.net/maps.php>http://xplanet.sourceforge.net/maps.php</a> + XPlanet requires maps in order to function properly. It does not ship with a lot of planetary maps. You need to download some in order to get the full benefits of XPlanet. This is a good place to start: <a href="http://xplanet.sourceforge.net/maps.php">http://xplanet.sourceforge.net/maps.php</a> true true XPlanet Planet Maps Qt::Vertical 20 40 Labels and markers Labels QFormLayout::ExpandingFieldsGrow Qt::AlignBottom|Qt::AlignRight|Qt::AlignTrailing Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter local time true GMT Label string: Specify the text of the first line of the label. Specify the text of the first line of the label. By default, it says something like "Looking at Earth". Any instances of %t will be replaced by the target name, and any instances of %o will be replaced by the origin name. Date format: Specify the format for the date/time label. Specify the format for the date/time label. This format string is passed to strftime(3). The default is "%c %Z", which shows the date, time, and time zone in the locale’s appropriate date and time representation. true Font size: Label font size Specify the point size. Color: Label color Set the color for the label. Top left false Bottom left false Top right true Bottom right false Qt::Vertical 20 40 Label position: Qt::Vertical 20 40 Show label? If checked, display a label in the upper right corner. Show label Markers Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter Use marker file? If checked, use the specified marker file. Use marker file: Marker file path Specify a file containing user defined marker data to display against the background stars. Write marker bounds in a file Write coordinates of the bounding box for each marker in a file. Write marker bounds to: Marker bounds file path Write coordinates of the bounding box for each marker to this file. Qt::Vertical 20 40 Position Place the observer above latitude true Latitude in degrees Render the target body as seen from above the specified latitude (in degrees). The default value is 0. -360 360 and longitude Longitude in degrees Place the observer above the specified longitude (in degrees). Longitude is positive going east, negative going west (for the earth and moon), so for example Los Angeles is at -118 or 242. The default value is 0. -360 360 in degrees Place the observer above a random latitude and longitude Qt::Vertical 20 40 Projection Projection: The projection type The default is no projection. Multiple bodies will not be shown if this option is specified, although shadows will still be drawn. Qt::Horizontal 40 20 true Background Use background? If checked, use a file or a color as background. Use background Background image: false Use this file as the background image Enter here the path of background image file. Background color: true Background color Set the color for the background. Qt::Horizontal 40 20 Qt::Vertical 20 40 KColorButton QPushButton
kcolorbutton.h
tab kcfg_XplanetPath kcfg_XplanetWidth kcfg_XplanetHeight kcfg_XplanetFOV kcfg_XplanetGlare kcfg_XplanetMagnitude kcfg_XplanetConfigFile kcfg_XplanetConfigFilePath kcfg_XplanetStarmap kcfg_XplanetStarmapPath kcfg_XplanetArcFile kcfg_XplanetArcFilePath kcfg_XplanetQuality kcfg_XplanetLabel kcfg_XplanetLabelLocalTime kcfg_XplanetLabelGMT kcfg_XplanetLabelString kcfg_XplanetDateFormat kcfg_XplanetFontSize kcfg_XplanetColor kcfg_XplanetLabelTL kcfg_XplanetLabelTR kcfg_XplanetLabelBL kcfg_XplanetLabelBR kcfg_XplanetMarkerFile kcfg_XplanetMarkerFilePath kcfg_XplanetMarkerBounds kcfg_XplanetMarkerBoundsPath kcfg_XplanetLatLong kcfg_XplanetLatitude kcfg_XplanetLongitude kcfg_XplanetRandom kcfg_XplanetProjection kcfg_XplanetBackground kcfg_XplanetBackgroundImage kcfg_XplanetBackgroundImagePath kcfg_XplanetBackgroundColor kcfg_XplanetBackgroundColorValue