Kstars

xplanetimageviewer.cpp
1/*
2 SPDX-FileCopyrightText: Thomas Kabelmann
3 SPDX-FileCopyrightText: 2018 Robert Lancaster <rlancaste@gmail.com>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6*/
7
8#include "xplanetimageviewer.h"
9#include "Options.h"
10#include "dialogs/timedialog.h"
11#include "ksnotification.h"
12
13#include <QtConcurrent>
14
15#ifndef KSTARS_LITE
16#include "kstars.h"
17#endif
18
19#ifndef KSTARS_LITE
20#include <KMessageBox>
21#endif
22
23#include <QFileDialog>
24#include <QPainter>
25#include <QResizeEvent>
26#include <QStatusBar>
27#include <QTemporaryFile>
28#include <QVBoxLayout>
29#include <QPushButton>
30#include <QApplication>
31#include <QScreen>
32#include <QSlider>
33#include "skymap.h"
34#include "kspaths.h"
35#include "fov.h"
36
37#include <QUuid>
38#include <sys/stat.h>
39#include <QInputDialog>
40
41typedef enum
42{
43 SUN, MERCURY, VENUS,
44 EARTH, MOON,
45 MARS, PHOBOS, DEIMOS,
46 JUPITER, GANYMEDE, IO, CALLISTO, EUROPA,
47 SATURN, TITAN, MIMAS, ENCELADUS, TETHYS, DIONE, RHEA, HYPERION, IAPETUS, PHOEBE,
48 URANUS, UMBRIEL, ARIEL, MIRANDA, TITANIA, OBERON,
49 NEPTUNE, TRITON
50} objects;
51
52XPlanetImageLabel::XPlanetImageLabel(QWidget *parent) : QFrame(parent)
53{
54#ifndef KSTARS_LITE
55 grabGesture(Qt::PinchGesture);
57 setFrameStyle(QFrame::StyledPanel | QFrame::Plain);
58 setLineWidth(2);
59#endif
60}
61
62void XPlanetImageLabel::setImage(const QImage &img)
63{
64#ifndef KSTARS_LITE
65 m_Image = img;
66 m_Pix = QPixmap::fromImage(m_Image);
67#endif
68}
69
70void XPlanetImageLabel::invertPixels()
71{
72#ifndef KSTARS_LITE
73 m_Image.invertPixels();
75#endif
76}
77
78void XPlanetImageLabel::paintEvent(QPaintEvent *)
79{
80#ifndef KSTARS_LITE
81 QPainter p;
82 p.begin(this);
83 int x = 0;
84 if (m_Pix.width() < width())
85 x = (width() - m_Pix.width()) / 2;
86 p.drawPixmap(x, 0, m_Pix);
87 p.end();
88#endif
89}
90
91void XPlanetImageLabel::resizeEvent(QResizeEvent *event)
92{
93 if (event->size() == m_Pix.size())
94 return;
95
97}
98
99void XPlanetImageLabel::refreshImage()
100{
102 update();
103}
104
105void XPlanetImageLabel::wheelEvent(QWheelEvent *e)
106{
107 //This attempts to send the wheel event back to the Scroll Area if it was taken from a trackpad
108 //It should still do the zoom if it is a mouse wheel
110 {
112 }
113 else
114 {
115 if (e->angleDelta().y() > 0)
116 emit zoomIn();
117 else if (e->angleDelta().y() < 0)
118 emit zoomOut();
119 e->accept();
120 }
121}
122
123bool XPlanetImageLabel::event(QEvent *event)
124{
125 if (event->type() == QEvent::Gesture)
126 return gestureEvent(dynamic_cast<QGestureEvent *>(event));
127 return QFrame::event(event);
128}
129
130bool XPlanetImageLabel::gestureEvent(QGestureEvent *event)
131{
132 if (QGesture *pinch = event->gesture(Qt::PinchGesture))
133 pinchTriggered(dynamic_cast<QPinchGesture *>(pinch));
134 return true;
135}
136
137
138void XPlanetImageLabel::pinchTriggered(QPinchGesture *gesture)
139{
140 if (gesture->totalScaleFactor() > 1)
141 emit zoomIn();
142 else
143 emit zoomOut();
144}
145
146
147void XPlanetImageLabel::mousePressEvent(QMouseEvent *e)
148{
149 m_MouseButtonDown = true;
150 m_LastMousePoint = e->globalPos();
151 e->accept();
152}
153
154void XPlanetImageLabel::mouseReleaseEvent(QMouseEvent *e)
155{
156 m_MouseButtonDown = false;
157 e->accept();
158}
159
160void XPlanetImageLabel::mouseMoveEvent(QMouseEvent *e)
161{
162 if(m_MouseButtonDown)
163 {
165 int dx = newPoint.x() - m_LastMousePoint.x();
166 int dy = newPoint.y() - m_LastMousePoint.y();
167 if(e->buttons() & Qt::RightButton)
168 emit changeLocation(QPoint(dx, dy));
169 if(e->buttons() & Qt::LeftButton)
170 emit changePosition(QPoint(dx, dy));
171 m_LastMousePoint = newPoint;
172 }
173 e->accept();
174}
175
177{
178#ifndef KSTARS_LITE
179 m_LastFile = QDir::homePath();
180
181#ifdef Q_OS_OSX
183#endif
185 setModal(false);
186 setWindowTitle(i18nc("@title:window", "XPlanet Solar System Simulator: %1", obj));
187
188 setXPlanetDate(KStarsData::Instance()->ut());
189
190 // Create widget
191 QFrame *page = new QFrame(this);
192
193 //setMainWidget( page );
194 QVBoxLayout *mainLayout = new QVBoxLayout(this);
195 mainLayout->addWidget(page);
196 setLayout(mainLayout);
197
198 QWidget *selectorsWidget = new QWidget(this);
200 selectorsLayout->setContentsMargins(0, 0, 0, 0);
201 mainLayout->addWidget(selectorsWidget);
202
203 m_ObjectNames << i18n("Sun") << i18n("Mercury") << i18n("Venus");
204 m_objectDefaultFOVs << 0.74818 << 0.004 << 0.02;
205 m_ObjectNames << i18n("Earth") << i18n("Moon");
206 m_objectDefaultFOVs << 1.0 << 0.74818;
207 m_ObjectNames << i18n("Mars") << i18n("Phobos") << i18n("Deimos");
208 m_objectDefaultFOVs << 0.00865 << 0.00002 << 0.00002;
209 m_ObjectNames << i18n("Jupiter") << i18n("Ganymede") << i18n("Io") << i18n("Callisto") << i18n("Europa");
210 m_objectDefaultFOVs << 0.02 << 0.0005 << 0.0004 << 0.0005 << 0.0003;
211 m_ObjectNames << i18n("Saturn") << i18n("Titan") << i18n("Mimas") << i18n("Enceladus") << i18n("Tethys") << i18n("Dione") << i18n("Rhea") << i18n("Hyperion") << i18n("Iapetus") << i18n("Phoebe");
212 m_objectDefaultFOVs << 0.02 << 0.0003 << 0.00002 << 0.00003 << 0.00007 << 0.00007 << 0.0001 << 0.00002 << 0.0001 << 0.00002;
213 m_ObjectNames << i18n("Uranus") << i18n("Umbriel") << i18n("Ariel") << i18n("Miranda") << i18n("Titania") << i18n("Oberon");
214 m_objectDefaultFOVs << 0.00256 << 0.00004 << 0.00004 << 0.00002 << 0.00005 << 0.00005;
215 m_ObjectNames << i18n("Neptune") << i18n("Triton");
216 m_objectDefaultFOVs << 0.00114 << 0.0001;
217
218 m_CurrentObjectIndex = m_ObjectNames.indexOf(obj);
219 if (m_CurrentObjectIndex < 0)
220 // Set to Saturn if current object is not in the list.
221 m_CurrentObjectIndex = 13;
222 m_ObjectName = m_ObjectNames.at(m_CurrentObjectIndex);
223
225 objectSelector->addItems(m_ObjectNames);
226 objectSelector->setToolTip(i18n("This allows you to select a new object/target for XPlanet to view"));
228 objectSelector->setCurrentIndex(m_CurrentObjectIndex);
229 connect(objectSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(updateXPlanetObject(int)));
230
231 m_CurrentOriginIndex = EARTH;
232 m_OriginName = m_ObjectNames.at(EARTH);
233
234 selectorsLayout->addWidget(new QLabel(i18n("from"), this));
235 m_OriginSelector = new QComboBox(this);
236 m_OriginSelector->addItems(m_ObjectNames);
237 m_OriginSelector->setToolTip(i18n("This allows you to select a viewing location"));
238 selectorsLayout->addWidget(m_OriginSelector);
239 m_OriginSelector->setCurrentIndex(EARTH);
240 connect(m_OriginSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(updateXPlanetOrigin(int)));
241
242 m_lat = Options::xplanetLatitude().toDouble();
243 m_lon = Options::xplanetLongitude().toDouble();
244 m_Radius = 45;
245
246 selectorsLayout->addWidget(new QLabel(i18n("Location:"), this));
247
248 m_PositionDisplay = new QLabel(this);
249 m_PositionDisplay->setToolTip(i18n("XPlanet Latitude, Longitude, and object radius in %. This is only valid when viewing the object from the same object"));
250 updatePositionDisplay();
251 m_PositionDisplay->setDisabled(true);
252 selectorsLayout->addWidget(m_PositionDisplay);
253
255 resetXPlanetLocation->setIcon(QIcon::fromTheme("system-reboot"));
257 resetXPlanetLocation->setMaximumSize(QSize(32, 32));
258 resetXPlanetLocation->setMinimumSize(QSize(32, 32));
259 resetXPlanetLocation->setToolTip(i18n("Reset XPlanet Location to the location specified in the XPlanet Options"));
261 connect(resetXPlanetLocation, SIGNAL(clicked()), this, SLOT(resetLocation()));
262
263 m_FreeRotate = new QPushButton(this);
264 m_FreeRotate->setIcon(QIcon::fromTheme("object-rotate-left"));
266 m_FreeRotate->setMaximumSize(QSize(32, 32));
267 m_FreeRotate->setMinimumSize(QSize(32, 32));
268 m_FreeRotate->setCheckable(true);
269 m_FreeRotate->setToolTip(i18n("Hover over target and freely rotate view with mouse in XPlanet Viewer"));
270 selectorsLayout->addWidget(m_FreeRotate);
271 connect(m_FreeRotate, SIGNAL(clicked()), this, SLOT(slotFreeRotate()));
272
273 QPushButton *reCenterB = new QPushButton(this);
274 reCenterB->setIcon(QIcon::fromTheme("snap-bounding-box-center"));
276 reCenterB->setMaximumSize(QSize(32, 32));
277 reCenterB->setMinimumSize(QSize(32, 32));
278 reCenterB->setToolTip(i18n("Recenters the XPlanet image once it has been moved"));
279 selectorsLayout->addWidget(reCenterB);
280 connect(reCenterB, SIGNAL(clicked()), this, SLOT(reCenterXPlanet()));
281
282 QPushButton *saveB = new QPushButton(this);
283 saveB->setIcon(QIcon::fromTheme("document-save"));
284 saveB->setAttribute(Qt::WA_LayoutUsesWidgetRect);
285 saveB->setMaximumSize(QSize(32, 32));
286 saveB->setMinimumSize(QSize(32, 32));
287 saveB->setToolTip(i18n("Save the image to disk"));
288 selectorsLayout->addWidget(saveB);
289 connect(saveB, SIGNAL(clicked()), this, SLOT(saveFileToDisk()));
290
293 viewControlsLayout->setContentsMargins(0, 0, 0, 0);
294 mainLayout->addWidget(viewControlsWidget);
295
296 viewControlsLayout->addWidget(new QLabel(i18n("FOV:"), this));
297
298 m_FOVEdit = new NonLinearDoubleSpinBox();
299 m_FOVEdit->setDecimals(5);
300 QList<double> possibleValues;
301 possibleValues << 0;
302 for(double i = .0001; i < 100; i *= 1.5)
303 possibleValues << i;
304 m_FOVEdit->setRecommendedValues(possibleValues);
305 m_FOVEdit->setToolTip(i18n("Sets the FOV to the Specified value. Note: has no effect if hovering over object."));
306 viewControlsLayout->addWidget(m_FOVEdit);
307
308 if (Options::xplanetFOV())
309 m_FOV = KStars::Instance()->map()->fov();
310 else
311 m_FOV = m_objectDefaultFOVs.at( m_CurrentObjectIndex);
312 m_FOVEdit->setValue(m_FOV);
313
314 connect(m_FOVEdit, SIGNAL(valueChanged(double)), this, SLOT(updateXPlanetFOVEdit()));
315
316 m_KStarsFOV = new QPushButton(this);
317 m_KStarsFOV->setIcon(QIcon::fromTheme("zoom-fit-width"));
319 m_KStarsFOV->setMaximumSize(QSize(32, 32));
320 m_KStarsFOV->setMinimumSize(QSize(32, 32));
321 m_KStarsFOV->setToolTip(i18n("Zoom to the current KStars FOV. Note: has no effect if hovering over object."));
322 viewControlsLayout->addWidget(m_KStarsFOV);
323 connect(m_KStarsFOV, SIGNAL(clicked()), this, SLOT(setKStarsXPlanetFOV()));
324
325 m_setFOV = new QPushButton(this);
326 m_setFOV->setIcon(QIcon::fromTheme("view-list-details"));
328 m_setFOV->setMaximumSize(QSize(32, 32));
329 m_setFOV->setMinimumSize(QSize(32, 32));
330 m_setFOV->setToolTip(i18n("Zoom to a specific FOV. This has no effect when hovering over an object"));
331 viewControlsLayout->addWidget(m_setFOV);
332 connect(m_setFOV, SIGNAL(clicked()), this, SLOT(setFOVfromList()));
333
334 m_NoFOV = new QPushButton(this);
335 m_NoFOV->setIcon(QIcon::fromTheme("system-reboot"));
337 m_NoFOV->setMaximumSize(QSize(32, 32));
338 m_NoFOV->setMinimumSize(QSize(32, 32));
339 m_NoFOV->setToolTip(i18n("Optimum FOV for the target, FOV parameter not specified. Note: has no effect if hovering over object."));
340 viewControlsLayout->addWidget(m_NoFOV);
341 connect(m_NoFOV, SIGNAL(clicked()), this, SLOT(resetXPlanetFOV()));
342
343 m_Rotation = 0;
344
345 viewControlsLayout->addWidget(new QLabel(i18n("Rotation:"), this));
346
347 m_RotateEdit = new QSpinBox();
348
349 m_RotateEdit->setRange(-180, 180);
350 m_RotateEdit->setValue(0);
351 m_RotateEdit->setSingleStep(10);
352 m_RotateEdit->setToolTip(i18n("Set the view rotation to the desired angle"));
353 viewControlsLayout->addWidget(m_RotateEdit);
354 connect(m_RotateEdit, SIGNAL(valueChanged(int)), this, SLOT(updateXPlanetRotationEdit()));
355
357 invertRotation->setIcon(QIcon::fromTheme("object-flip-vertical"));
359 invertRotation->setMaximumSize(QSize(32, 32));
360 invertRotation->setMinimumSize(QSize(32, 32));
361 invertRotation->setToolTip(i18n("Rotate the view 180 degrees"));
363 connect(invertRotation, SIGNAL(clicked()), this, SLOT(invertXPlanetRotation()));
364
365 QPushButton *resetRotation = new QPushButton(this);
366 resetRotation->setIcon(QIcon::fromTheme("system-reboot"));
368 resetRotation->setMaximumSize(QSize(32, 32));
369 resetRotation->setMinimumSize(QSize(32, 32));
370 resetRotation->setToolTip(i18n("Reset view rotation to 0"));
371 viewControlsLayout->addWidget(resetRotation);
372 connect(resetRotation, SIGNAL(clicked()), this, SLOT(resetXPlanetRotation()));
373
374 QPushButton *optionsB = new QPushButton(this);
375 optionsB->setIcon(QIcon::fromTheme("configure"));
377 optionsB->setMaximumSize(QSize(32, 32));
378 optionsB->setMinimumSize(QSize(32, 32));
379 optionsB->setToolTip(i18n("Bring up XPlanet Options"));
380 viewControlsLayout->addWidget(optionsB);
381 connect(optionsB, SIGNAL(clicked()), KStars::Instance(), SLOT(slotViewOps()));
382
383 QPushButton *invertB = new QPushButton(this);
384 invertB->setIcon(QIcon::fromTheme("edit-select-invert"));
386 invertB->setMaximumSize(QSize(32, 32));
387 invertB->setMinimumSize(QSize(32, 32));
388 invertB->setToolTip(i18n("Reverse colors of the image. This is useful to enhance contrast at times. This affects "
389 "only the display and not the saving."));
390 viewControlsLayout->addWidget(invertB);
391 connect(invertB, SIGNAL(clicked()), this, SLOT(invertColors()));
392
393 QWidget *timeWidget = new QWidget(this);
395 mainLayout->addWidget(timeWidget);
396 timeLayout->setContentsMargins(0, 0, 0, 0);
397
398 m_XPlanetTime = KStarsData::Instance()->lt();
399
400 QPushButton *setTime = new QPushButton(this);
401 setTime->setIcon(QIcon::fromTheme("clock"));
403 setTime->setMaximumSize(QSize(32, 32));
404 setTime->setMinimumSize(QSize(32, 32));
405 setTime->setToolTip(i18n("Allows you to set the XPlanet time to a different date/time from KStars"));
406 timeLayout->addWidget(setTime);
407 connect(setTime, SIGNAL(clicked()), this, SLOT(setXPlanetTime()));
408
410 kstarsTime->setIcon(QIcon::fromTheme("system-reboot"));
412 kstarsTime->setMaximumSize(QSize(32, 32));
413 kstarsTime->setMinimumSize(QSize(32, 32));
414 kstarsTime->setToolTip(i18n("Sets the XPlanet time to the current KStars time"));
415 timeLayout->addWidget(kstarsTime);
416 connect(kstarsTime, SIGNAL(clicked()), this, SLOT(setXPlanetTimetoKStarsTime()));
417
418 m_XPlanetTimeDisplay = new QLabel(this);
419 m_XPlanetTimeDisplay->setToolTip(i18n("Current XPlanet Time"));
420 timeLayout->addWidget(m_XPlanetTimeDisplay);
421
422 m_XPlanetTimeDisplay->setText(i18n("%1, %2", m_XPlanetTime.date().toString(), m_XPlanetTime.time().toString()));
423
424 m_TimeSlider = new QSlider(Qt::Horizontal, this);
425 m_TimeSlider->setTracking(false);
426 connect(m_TimeSlider, SIGNAL(sliderMoved(int)), this, SLOT(timeSliderDisplay(int)));
427 timeLayout->addWidget(m_TimeSlider);
428 m_TimeSlider->setRange(-100, 100);
429 m_TimeSlider->setToolTip(i18n("This sets the time step from the current XPlanet time, good for viewing events"));
430 connect(m_TimeSlider, SIGNAL(valueChanged(int)), this, SLOT(updateXPlanetTime(int)));
431
432 m_TimeEdit = new QSpinBox(this);
433 m_TimeEdit->setRange(-10000, 10000);
434 m_TimeEdit->setMaximumWidth(50);
435 m_TimeEdit->setToolTip(i18n("This sets the time step from the current XPlanet time"));
436 timeLayout->addWidget(m_TimeEdit);
437 connect(m_TimeEdit, SIGNAL(valueChanged(int)), this, SLOT(updateXPlanetTimeEdit()));
438
439 m_CurrentTimeUnitIndex = MINS;
440 m_TimeUnitsSelect = new QComboBox(this);
441 timeLayout->addWidget(m_TimeUnitsSelect);
442 m_TimeUnitsSelect->addItem(i18n("years"));
443 m_TimeUnitsSelect->addItem(i18n("months"));
444 m_TimeUnitsSelect->addItem(i18n("days"));
445 m_TimeUnitsSelect->addItem(i18n("hours"));
446 m_TimeUnitsSelect->addItem(i18n("minutes"));
447 m_TimeUnitsSelect->addItem(i18n("seconds"));
448 m_TimeUnitsSelect->setCurrentIndex(MINS);
449 m_TimeUnitsSelect->setToolTip(i18n("Lets you change the units for the timestep in the animation"));
450 connect(m_TimeUnitsSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(updateXPlanetTimeUnits(int)));
451
452 m_XPlanetTimer = new QTimer(this);
453 m_XPlanetTimer->setInterval(Options::xplanetAnimationDelay());
454 connect(m_XPlanetTimer, SIGNAL(timeout()), this, SLOT(incrementXPlanetTime()));
455
456 m_RunTime = new QPushButton(this);
457 m_RunTime->setIcon(QIcon::fromTheme("media-playback-start"));
459 m_RunTime->setCheckable(true);
460 m_RunTime->setMaximumSize(QSize(32, 32));
461 m_RunTime->setMinimumSize(QSize(32, 32));
462 m_RunTime->setToolTip(i18n("Lets you run the animation"));
463 timeLayout->addWidget(m_RunTime);
464 connect(m_RunTime, SIGNAL(clicked()), this, SLOT(toggleXPlanetRun()));
465
466 QPushButton *resetTime = new QPushButton(this);
467 resetTime->setIcon(QIcon::fromTheme("system-reboot"));
469 resetTime->setMaximumSize(QSize(32, 32));
470 resetTime->setMinimumSize(QSize(32, 32));
471 resetTime->setToolTip(i18n("Resets the animation to 0 timesteps from the current XPlanet Time"));
472 timeLayout->addWidget(resetTime);
473 connect(resetTime, SIGNAL(clicked()), this, SLOT(resetXPlanetTime()));
474
475 m_View = new XPlanetImageLabel(page);
476 m_View->setAutoFillBackground(false);
477 m_Caption = new QLabel(page);
478 m_Caption->setAutoFillBackground(true);
480 m_Caption->setText(m_ObjectName);
481 // Add layout
482 QVBoxLayout *vlay = new QVBoxLayout(page);
483 vlay->setSpacing(0);
484 vlay->setContentsMargins(0, 0, 0, 0);
485 vlay->addWidget(m_View);
486 vlay->addWidget(m_Caption);
487
488
489 connect(m_View, SIGNAL(zoomIn()), this, SLOT(zoomInXPlanetFOV()));
490 connect(m_View, SIGNAL(zoomOut()), this, SLOT(zoomOutXPlanetFOV()));
491 connect(m_View, SIGNAL(changePosition(QPoint)), this, SLOT(changeXPlanetPosition(QPoint)));
492 connect(m_View, SIGNAL(changeLocation(QPoint)), this, SLOT(changeXPlanetLocation(QPoint)));
493
494 //Reverse colors
495 QPalette p = palette();
498 m_Caption->setPalette(p);
499 m_View->setPalette(p);
500
501#ifndef Q_OS_WIN
502 if(Options::xplanetUseFIFO())
503 {
504 connect(&watcherTimeout, SIGNAL(timeout()), &fifoImageLoadWatcher, SLOT(cancel()));
505 connect(&fifoImageLoadWatcher, SIGNAL(finished()), this, SLOT(showImage()));
506 }
507#endif
508
509
510#ifdef Q_OS_OSX
512 for (auto &button : qButtons)
513 button->setAutoDefault(false);
514#endif
515 updateXPlanetTime(0);
516#endif
517}
518
523
524void XPlanetImageViewer::startXplanet()
525{
526 if(m_XPlanetRunning)
527 return;
528
529 //This means something failed in the file output
530 if(!setupOutputFile())
531 return;
532
533 QString xPlanetLocation = Options::xplanetPath();
534#ifdef Q_OS_OSX
535 if (Options::xplanetIsInternal())
537#endif
538
539 // If Options::xplanetPath() is empty, return
540 if (xPlanetLocation.isEmpty())
541 {
542 KSNotification::error(i18n("Xplanet binary path is empty in config panel."));
543 return;
544 }
545
546 // If Options::xplanetPath() does not exist, return
548 if (!xPlanetLocationInfo.exists() || !xPlanetLocationInfo.isExecutable())
549 {
550 KSNotification::error(i18n("The configured Xplanet binary does not exist or is not executable."));
551 return;
552 }
553
554 // Create xplanet process
555 QProcess *xplanetProc = new QProcess(this);
556
557 // Add some options
559
560 //This specifies the object to be viewed
561 args << "-body" << m_ObjectName.toLower();
562 //This is the date and time requested
563 args << "-date" << m_Date;
564 //This is the glare from the sun
565 args << "-glare" << Options::xplanetGlare();
566 args << "-base_magnitude" << Options::xplanetMagnitude();
567 //This is the correction for light's travel time.
568 args << "-light_time";
569
570 args << "-geometry" << QString::number(Options::xplanetWidth()) + 'x' + QString::number(Options::xplanetHeight());
571
572 if(m_FOV != 0)
573 args << "-fov" << QString::number(m_FOV);
574 //Need to convert to locale for places that don't use decimals??
575 //args << "-fov" << fov.setNum(fov());//.replace('.', ',');
576
577 //This rotates the view for different object angles
578 args << "-rotate" << QString::number(m_Rotation);
579
580 if (Options::xplanetConfigFile())
581 args << "-config" << Options::xplanetConfigFilePath();
582 if (Options::xplanetStarmap())
583 args << "-starmap" << Options::xplanetStarmapPath();
584 if (Options::xplanetArcFile())
585 args << "-arc_file" << Options::xplanetArcFilePath();
586 if (!m_File.fileName().isEmpty())
587 args << "-output" << m_File.fileName() << "-quality" << Options::xplanetQuality();
588
589 // Labels
590 if (Options::xplanetLabel())
591 {
592 args << "-fontsize" << Options::xplanetFontSize() << "-color"
593 << "0x" + Options::xplanetColor().mid(1) << "-date_format" << Options::xplanetDateFormat();
594
595 if (Options::xplanetLabelGMT())
596 args << "-gmtlabel";
597 else
598 args << "-label";
599 if (!Options::xplanetLabelString().isEmpty())
600 args << "-label_string"
601 << "\"" + Options::xplanetLabelString() + "\"";
602 if (Options::xplanetLabelTL())
603 args << "-labelpos"
604 << "+15+15";
605 else if (Options::xplanetLabelTR())
606 args << "-labelpos"
607 << "-15+15";
608 else if (Options::xplanetLabelBR())
609 args << "-labelpos"
610 << "-15-15";
611 else if (Options::xplanetLabelBL())
612 args << "-labelpos"
613 << "+15-15";
614 }
615
616 // Markers
617 if (Options::xplanetMarkerFile())
618 args << "-marker_file" << Options::xplanetMarkerFilePath();
619 if (Options::xplanetMarkerBounds())
620 args << "-markerbounds" << Options::xplanetMarkerBoundsPath();
621
622 // Position
623 // This sets the position from which the planet is viewed.
624 // Note that setting Latitude and Longitude means that position above the SAME object
625
626 if(m_CurrentObjectIndex == m_CurrentOriginIndex)
627 {
628 if (Options::xplanetRandom())
629 args << "-random";
630 else
631 args << "-latitude" << QString::number(m_lat) << "-longitude" << QString::number(m_lon) << "-radius" << QString::number(m_Radius);
632 }
633 else
634 args << "-origin" << m_OriginName;
635
636 //Centering
637 //This allows you to recenter the xplanet view
638
639 args << "-center" << "+" + QString::number(Options::xplanetWidth() / 2 + center.x()) + "+" + QString::number(Options::xplanetHeight() / 2 + center.y());
640
641 // Projection
642 if (Options::xplanetProjection())
643 {
644 switch (Options::xplanetProjection())
645 {
646 case 1:
647 args << "-projection"
648 << "ancient";
649 break;
650 case 2:
651 args << "-projection"
652 << "azimuthal";
653 break;
654 case 3:
655 args << "-projection"
656 << "bonne";
657 break;
658 case 4:
659 args << "-projection"
660 << "gnomonic";
661 break;
662 case 5:
663 args << "-projection"
664 << "hemisphere";
665 break;
666 case 6:
667 args << "-projection"
668 << "lambert";
669 break;
670 case 7:
671 args << "-projection"
672 << "mercator";
673 break;
674 case 8:
675 args << "-projection"
676 << "mollweide";
677 break;
678 case 9:
679 args << "-projection"
680 << "orthographic";
681 break;
682 case 10:
683 args << "-projection"
684 << "peters";
685 break;
686 case 11:
687 args << "-projection"
688 << "polyconic";
689 break;
690 case 12:
691 args << "-projection"
692 << "rectangular";
693 break;
694 case 13:
695 args << "-projection"
696 << "tsc";
697 break;
698 default:
699 break;
700 }
701 if (Options::xplanetBackground())
702 {
703 if (Options::xplanetBackgroundImage())
704 args << "-background" << Options::xplanetBackgroundImagePath();
705 else
706 args << "-background"
707 << "0x" + Options::xplanetBackgroundColorValue().mid(1);
708 }
709 }
710
711#ifdef Q_OS_OSX
713 args << "-searchdir" << searchDir;
714#endif
715
716#ifdef Q_OS_WIN
717 QString searchDir = xPlanetLocationInfo.dir().absolutePath() + QDir::separator() + "xplanet";
718 args << "-searchdir" << searchDir;
719#endif
720
721 //This prevents it from running forever.
722 args << "-num_times" << "1";
723
724 m_XPlanetRunning = true;
725 m_ImageLoadSucceeded = false; //This will be set to true if it works.
726 uint32_t timeout = Options::xplanetTimeout();
727
728 //FIFO files don't work on windows
729#ifndef Q_OS_WIN
730 if(Options::xplanetUseFIFO())
731 {
732 fifoImageLoadWatcher.setFuture(QtConcurrent::run(this, &XPlanetImageViewer::loadImage));
733 watcherTimeout.setSingleShot(true);
734 watcherTimeout.start(timeout);
735 }
736#endif
737
739
740 //Uncomment to print the XPlanet commands to the console
741 // qDebug() << Q_FUNC_INFO << "Run:" << xplanetProc->program() << args.join(" ");
742
743 bool XPlanetSucceeded = xplanetProc->waitForFinished(timeout);
744 m_XPlanetRunning = false;
745 xplanetProc->kill(); //In case it timed out
746 xplanetProc->deleteLater();
748 {
749 if(m_FOV == 0)
750 m_Caption->setText(i18n("XPlanet View: %1 from %2 on %3", m_ObjectName, m_OriginName, m_DateText));
751 else
752 m_Caption->setText(i18n("XPlanet View: %1 from %2 on %3 at FOV: %4 deg", m_ObjectName, m_OriginName, m_DateText, m_FOV));
753#ifdef Q_OS_WIN
754 loadImage(); //This will also set imageLoadSucceeded based on whether it worked.
755#else
756 if(Options::xplanetUseFIFO())
757 return; //The loading of the image is handled with the watcher
758 else
759 loadImage(); //This will also set imageLoadSucceeded based on whether it worked.
760#endif
761
762 if(m_ImageLoadSucceeded)
763 showImage();
764 else
765 {
766 KSNotification::error(i18n("Loading of the image of object %1 failed.", m_ObjectName));
767 }
768 }
769 else
770 {
771 KStars::Instance()->statusBar()->showMessage(i18n("XPlanet failed to generate the image for object %1 before the timeout expired.", m_ObjectName));
772#ifndef Q_OS_WIN
773 if(Options::xplanetUseFIFO())
774 fifoImageLoadWatcher.cancel();
775#endif
776 }
777}
778
779bool XPlanetImageViewer::setupOutputFile()
780{
781#ifndef Q_OS_WIN
782 if(Options::xplanetUseFIFO())
783 {
784 if(m_File.fileName().contains("xplanetfifo") && m_File.exists())
785 return true;
786 QDir kstarsTempDir(KSPaths::writableLocation(QStandardPaths::TempLocation) + QDir::separator() + qAppName());
787 kstarsTempDir.mkpath(".");
788 m_File.setFileName(kstarsTempDir.filePath(QString("xplanetfifo%1.png").arg(QUuid::createUuid().toString().mid(1, 8)).toLatin1()));
789 if (mkfifo(m_File.fileName().toLatin1(), S_IRUSR | S_IWUSR) < 0)
790 {
791 KSNotification::error(i18n("Error making FIFO file %1: %2.", m_File.fileName(), strerror(errno)));
792 return false;
793 }
794 return true;
795 }
796#endif
797
798 //If the user is using windows or has not selected to use FIFO, it uses files in the KStars data directory.
799 QDir xPlanetDirPath(KSPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QDir::separator() + "xplanet");
800 xPlanetDirPath.mkpath(".");
801 m_File.setFileName(xPlanetDirPath.filePath(m_ObjectName + ".png"));
802 return true;
803}
804
805void XPlanetImageViewer::zoomInXPlanetFOV()
806{
807 if(m_CurrentObjectIndex == m_CurrentOriginIndex)
808 {
809 m_Radius += 5;
810 updatePositionDisplay();
811 startXplanet();
812 }
813 else
814 {
815 m_FOVEdit->stepDown();
816 startXplanet();
817 }
818
819}
820
821void XPlanetImageViewer::zoomOutXPlanetFOV()
822{
823 if(m_CurrentObjectIndex == m_CurrentOriginIndex)
824 {
825 if(m_Radius > 0)
826 {
827 m_Radius -= 5;
828 updatePositionDisplay();
829 startXplanet();
830 }
831 }
832 else
833 {
834 m_FOVEdit->stepUp();
835 startXplanet();
836 }
837
838}
839
840void XPlanetImageViewer::updatePositionDisplay()
841{
842 m_PositionDisplay->setText(i18n("%1, %2, %3", QString::number(m_lat), QString::number(m_lon), QString::number(m_Radius)));
843}
844
845void XPlanetImageViewer::updateXPlanetTime(int timeShift)
846{
847
849 switch(m_CurrentTimeUnitIndex)
850 {
851 case YEARS:
852 shiftedXPlanetTime = m_XPlanetTime.addDays(timeShift * 365);
853 break;
854
855 case MONTHS:
856 shiftedXPlanetTime = m_XPlanetTime.addDays(timeShift * 30);
857 break;
858
859 case DAYS:
860 shiftedXPlanetTime = m_XPlanetTime.addDays(timeShift);
861 break;
862
863 case HOURS:
864 shiftedXPlanetTime = m_XPlanetTime.addSecs(timeShift * 3600);
865 break;
866
867 case MINS:
868 shiftedXPlanetTime = m_XPlanetTime.addSecs(timeShift * 60);
869 break;
870
871 case SECS:
872 shiftedXPlanetTime = m_XPlanetTime.addSecs(timeShift);
873 break;
874 }
875
876 setXPlanetDate(shiftedXPlanetTime);
877 m_DateText = i18n("%1, %2", shiftedXPlanetTime.date().toString(), shiftedXPlanetTime.time().toString());
878 if(m_TimeEdit->value() != timeShift)
879 m_TimeEdit->setValue(timeShift);
880 else
881 startXplanet();
882}
883
884void XPlanetImageViewer::updateXPlanetObject(int objectIndex)
885{
886 center = QPoint(0, 0);
887 m_CurrentObjectIndex = objectIndex;
888 m_ObjectName = m_ObjectNames.at(objectIndex);
889
890 setWindowTitle(i18nc("@title:window", "XPlanet Solar System Simulator: %1", m_ObjectName));
891 if(m_FreeRotate->isChecked())
892 m_OriginSelector->setCurrentIndex(m_CurrentObjectIndex);
893 if(m_CurrentObjectIndex == m_CurrentOriginIndex)
894 startXplanet();
895 else
896 resetXPlanetFOV();
897}
898
899void XPlanetImageViewer::updateXPlanetOrigin(int originIndex)
900{
901 center = QPoint(0, 0);
902 m_CurrentOriginIndex = originIndex;
903 m_OriginName = m_ObjectNames.at(originIndex);
904 if(m_CurrentObjectIndex == m_CurrentOriginIndex)
905 m_FreeRotate->setChecked(true);
906 else
907 m_FreeRotate->setChecked(false);
908 updateStates();//This will update the disabled/enabled states
909 startXplanet();
910}
911
912void XPlanetImageViewer::changeXPlanetLocation(QPoint delta)
913{
914 if(m_CurrentObjectIndex == m_CurrentOriginIndex)
915 {
916 double newLon = m_lon + delta.x();
917 double newLat = m_lat + delta.y();
918
919 newLat = qBound(-90.0, newLat, 90.0);
920
921 m_lon = newLon;
922 m_lat = newLat;
923
924 updatePositionDisplay();
925 startXplanet();
926 }
927}
928
929void XPlanetImageViewer::changeXPlanetPosition(QPoint delta)
930{
931 center.setX(center.x() + delta.x());
932 center.setY(center.y() + delta.y());
933 startXplanet();
934}
935
936void XPlanetImageViewer::reCenterXPlanet()
937{
938 center = QPoint(0, 0);
939 startXplanet();
940}
941
942void XPlanetImageViewer::resetLocation()
943{
944 m_lat = Options::xplanetLatitude().toDouble();
945 m_lon = Options::xplanetLongitude().toDouble();
946 m_Radius = 45;
947 updatePositionDisplay();
948 startXplanet();
949}
950
951void XPlanetImageViewer::slotFreeRotate()
952{
953 if(m_FreeRotate->isChecked())
954 m_OriginSelector->setCurrentIndex(m_CurrentObjectIndex);
955 else
956 m_OriginSelector->setCurrentIndex(EARTH);
957}
958
959void XPlanetImageViewer::updateStates()
960{
961 if(m_FreeRotate->isChecked())
962 {
963 m_FOVEdit->setDisabled(true);
964 m_KStarsFOV->setDisabled(true);
965 m_NoFOV->setDisabled(true);
966
967 m_PositionDisplay->setDisabled(false);
968 }
969 else
970 {
971 m_FOVEdit->setDisabled(false);
972 m_KStarsFOV->setDisabled(false);
973 m_NoFOV->setDisabled(false);
974
975 m_PositionDisplay->setDisabled(true);
976 }
977}
978
979void XPlanetImageViewer::setXPlanetDate(KStarsDateTime time)
980{
981 //Note Xplanet uses UT time for everything but we want the labels to all be LT
982 KStarsDateTime utTime = KStarsData::Instance()->geo()->LTtoUT(time);
983 m_Date = utTime.toString(Qt::ISODate)
984 .replace("-", QString(""))
985 .replace("T", ".")
986 .replace(":", QString(""))
987 .replace("Z", QString(""));
988}
989
990void XPlanetImageViewer::updateXPlanetTimeUnits(int units)
991{
992 m_CurrentTimeUnitIndex = units;
993 updateXPlanetTimeEdit();
994}
995
996void XPlanetImageViewer::updateXPlanetTimeEdit()
997{
998 if(m_TimeSlider->isSliderDown())
999 return;
1000 int timeShift = m_TimeEdit->value();
1001 if(m_TimeSlider->value() != timeShift)
1002 {
1003
1004 if(timeShift > m_TimeSlider->maximum() + 100)
1005 m_TimeSlider->setMaximum(timeShift);
1006 if(timeShift < m_TimeSlider->minimum() - 100)
1007 m_TimeSlider->setMinimum(timeShift);
1008 m_TimeSlider->setValue(timeShift);
1009 }
1010 else
1011 updateXPlanetTime(timeShift);
1012}
1013
1014void XPlanetImageViewer::timeSliderDisplay(int timeShift)
1015{
1016 m_TimeEdit->setValue(timeShift);
1017}
1018
1019void XPlanetImageViewer::incrementXPlanetTime()
1020{
1021 if(!m_XPlanetRunning)
1022 {
1023 int timeShift = m_TimeEdit->value();
1024 if(m_TimeSlider->maximum() <= timeShift)
1025 m_TimeSlider->setMaximum(timeShift + 100);
1026 if(m_TimeEdit->maximum() <= timeShift)
1027 m_TimeEdit->setMaximum(timeShift + 100);
1028 m_TimeSlider->setValue(timeShift + 1);
1029 }
1030}
1031
1032void XPlanetImageViewer::setXPlanetTime()
1033{
1034 QPointer<TimeDialog> timedialog = new TimeDialog(m_XPlanetTime, KStarsData::Instance()->geo(), this);
1035 if (timedialog->exec() == QDialog::Accepted)
1036 {
1037 m_XPlanetTime = timedialog->selectedDateTime();
1038 m_XPlanetTimeDisplay->setText(i18n("%1, %2", m_XPlanetTime.date().toString(), m_XPlanetTime.time().toString()));
1039 int timeShift = 0;
1040 m_TimeSlider->setRange(-100, 100);
1041 if(m_TimeSlider->value() != timeShift)
1042 m_TimeSlider->setValue(timeShift);
1043 else
1044 updateXPlanetTime(timeShift);
1045 }
1046}
1047
1048void XPlanetImageViewer::setXPlanetTimetoKStarsTime()
1049{
1050 m_XPlanetTime = KStarsData::Instance()->lt();
1051 m_XPlanetTimeDisplay->setText(i18n("%1, %2", m_XPlanetTime.date().toString(), m_XPlanetTime.time().toString()));
1052 int timeShift = 0;
1053 m_TimeSlider->setRange(-100, 100);
1054 if(m_TimeSlider->value() != timeShift)
1055 m_TimeSlider->setValue(timeShift);
1056 else
1057 updateXPlanetTime(timeShift);
1058}
1059
1060void XPlanetImageViewer::resetXPlanetTime()
1061{
1062 int timeShift = 0;
1063 m_TimeSlider->setRange(-100, 100);
1064 if(m_TimeSlider->value() != timeShift)
1065 m_TimeSlider->setValue(timeShift);
1066 else
1067 updateXPlanetTime(timeShift);
1068}
1069
1070void XPlanetImageViewer::toggleXPlanetRun()
1071{
1072 if(m_XPlanetTimer->isActive())
1073 {
1074 m_XPlanetTimer->stop();
1075#ifndef Q_OS_WIN
1076 if(Options::xplanetUseFIFO())
1077 fifoImageLoadWatcher.cancel();
1078#endif
1079 }
1080 else
1081 {
1082 m_XPlanetTimer->setInterval(Options::xplanetAnimationDelay());
1083 m_XPlanetTimer->start();
1084 }
1085}
1086
1087void XPlanetImageViewer::updateXPlanetFOVEdit()
1088{
1089 m_FOV = m_FOVEdit->value();
1090 startXplanet();
1091}
1092
1093void XPlanetImageViewer::resetXPlanetFOV()
1094{
1095 m_FOV = m_objectDefaultFOVs.at(m_CurrentObjectIndex);
1096 m_FOVEdit->setValue(m_FOV);
1097 startXplanet();
1098}
1099
1100void XPlanetImageViewer::setKStarsXPlanetFOV()
1101{
1102 m_FOV = KStars::Instance()->map()->fov();
1103 m_FOVEdit->setValue(m_FOV);
1104 startXplanet();
1105}
1106void XPlanetImageViewer::setFOVfromList()
1107{
1108 if (!KStarsData::Instance()->getAvailableFOVs().isEmpty())
1109 {
1110 // Ask the user to choose from a list of available FOVs.
1112 for (const FOV *f : KStarsData::Instance()->getAvailableFOVs())
1113 {
1114 nameToFovMap.insert(f->name(), f);
1115 }
1116 bool ok = false;
1117 const FOV *fov = nullptr;
1118 fov = nameToFovMap[QInputDialog::getItem(this, i18n("Choose a field-of-view"),
1119 i18n("FOV to render in XPlanet:"), nameToFovMap.keys(), 0,
1120 false, &ok)];
1121 if (ok)
1122 {
1123 m_FOV = fov->sizeX() / 60 ; //Converting from arcmin to degrees
1124 m_FOVEdit->setValue(m_FOV);
1125 startXplanet();
1126 }
1127 }
1128}
1129
1130void XPlanetImageViewer::updateXPlanetRotationEdit()
1131{
1132 m_Rotation = m_RotateEdit->value();
1133 startXplanet();
1134}
1135
1136void XPlanetImageViewer::resetXPlanetRotation()
1137{
1138 m_RotateEdit->setValue(0);
1139}
1140
1141void XPlanetImageViewer::invertXPlanetRotation()
1142{
1143 m_RotateEdit->setValue(180);
1144}
1145
1147{
1148#ifndef KSTARS_LITE
1149
1150 if (!m_Image.load(m_File.fileName()))
1151 {
1152 m_ImageLoadSucceeded = false;
1153 return false;
1154 }
1155 m_ImageLoadSucceeded = true;
1156 return true;
1157#else
1158 imageLoadSucceeded = false;
1159 return false;
1160#endif
1161}
1162
1163bool XPlanetImageViewer::showImage()
1164{
1165#ifndef KSTARS_LITE
1166
1167 //If the image is larger than screen width and/or screen height,
1168 //shrink it to fit the screen
1170 int w = deskRect.width(); // screen width
1171 int h = deskRect.height(); // screen height
1172
1173 if (m_Image.width() <= w && m_Image.height() > h) //Window is taller than desktop
1174 m_Image = m_Image.scaled(int(m_Image.width() * h / m_Image.height()), h);
1175 else if (m_Image.height() <= h && m_Image.width() > w) //window is wider than desktop
1176 m_Image = m_Image.scaled(w, int(m_Image.height() * w / m_Image.width()));
1177 else if (m_Image.width() > w && m_Image.height() > h) //window is too tall and too wide
1178 {
1179 //which needs to be shrunk least, width or height?
1180 float fx = float(w) / float(m_Image.width());
1181 float fy = float(h) / float(m_Image.height());
1182 if (fx > fy) //width needs to be shrunk less, so shrink to fit in height
1183 m_Image = m_Image.scaled(int(m_Image.width() * fy), h);
1184 else //vice versa
1185 m_Image = m_Image.scaled(w, int(m_Image.height() * fx));
1186 }
1187 const bool initialLoad = !isVisible();
1188
1189 show(); // hide is default
1190
1191 m_View->setImage(m_Image);
1192 w = m_Image.width();
1193
1194 //If the caption is wider than the image, set the window size
1195 //to fit the caption
1196 if (m_Caption->width() > w)
1197 w = m_Caption->width();
1198 if(initialLoad)
1199 resize(w, m_Image.height());
1200 else
1201 {
1202 m_View->refreshImage();
1203 }
1204
1205 update();
1206 show();
1207
1208 return true;
1209#else
1210 return false;
1211#endif
1212}
1213
1214void XPlanetImageViewer::saveFileToDisk()
1215{
1216#ifndef KSTARS_LITE
1217 QFileDialog saveDialog(KStars::Instance(), i18nc("@title:window", "Save Image"), m_LastFile);
1218 saveDialog.setDefaultSuffix("png");
1219 saveDialog.setAcceptMode(QFileDialog::AcceptSave);
1220 saveDialog.exec();
1221
1222 if(saveDialog.result() == QFileDialog::Rejected)
1223 return;
1224 if(saveDialog.selectedFiles().isEmpty())
1225 return;
1226 QString newFileName = saveDialog.selectedFiles().first();
1227 if(newFileName.isEmpty())
1228 return;
1229
1230 m_LastFile = newFileName;
1231
1232 saveFile(newFileName);
1233
1234#endif
1235}
1236
1237void XPlanetImageViewer::saveFile(const QString &fileName)
1238{
1239#ifndef KSTARS_LITE
1240
1241 if (! m_Image.save(fileName, "png"))
1242 {
1243 KSNotification::error(i18n("Saving of the image to %1 failed.", fileName));
1244 }
1245 else
1246 KStars::Instance()->statusBar()->showMessage(i18n("Saved image to %1", fileName));
1247#endif
1248}
1249
1250void XPlanetImageViewer::invertColors()
1251{
1252#ifndef KSTARS_LITE
1253 // Invert colors
1254 m_View->invertPixels();
1255 m_View->update();
1256#endif
1257}
1258
A simple class encapsulating a Field-of-View symbol.
Definition fov.h:28
KStarsData is the backbone of KStars.
Definition kstarsdata.h:72
Extension of QDateTime for KStars KStarsDateTime can represent the date/time as a Julian Day,...
KStarsDateTime addDays(int nd) const
Modify the Date/Time by adding a number of days.
KStarsDateTime addSecs(double s) const
static KStars * Instance()
Definition kstars.h:123
A class for adjusting the Time and Date.
Definition timedialog.h:38
XPlanet Image viewer QFrame for the KPlanetImageViewer for KStars.
XPlanetImageViewer(const QString &obj, QWidget *parent=nullptr)
Create xplanet image viewer from Object.
~XPlanetImageViewer() override
Destructor.
bool loadImage()
loadImage Load image and display it
QString i18nc(const char *context, const char *text, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
AKONADI_CALENDAR_EXPORT KCalendarCore::Event::Ptr event(const Akonadi::Item &item)
char * toString(const EngineQuery &query)
GeoCoordinates geo(const QVariant &location)
void setCheckable(bool)
bool isChecked() const const
void setIcon(const QIcon &icon)
void setMinimum(int)
void setRange(int min, int max)
bool isSliderDown() const const
void setTracking(bool enable)
void addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
virtual void setSpacing(int spacing) override
void addItem(const QIcon &icon, const QString &text, const QVariant &userData)
void addItems(const QStringList &texts)
void setCurrentIndex(int index)
QString applicationDirPath()
QString toString(QStringView format, QCalendar cal) const const
QDate date() const const
QTime time() const const
void finished(int result)
void setModal(bool modal)
QString homePath()
QChar separator()
void setDecimals(int prec)
void setValue(double val)
void accept()
bool exists(const QString &fileName)
virtual QString fileName() const const override
void setFileName(const QString &name)
virtual bool event(QEvent *e) override
void setFrameShape(Shape)
void setFuture(const QFuture< T > &future)
void restoreOverrideCursor()
QIcon fromTheme(const QString &name)
int height() const const
void invertPixels(InvertMode mode)
bool load(QIODevice *device, const char *format)
bool save(QIODevice *device, const char *format, int quality) const const
QImage scaled(const QSize &size, Qt::AspectRatioMode aspectRatioMode, Qt::TransformationMode transformMode) const const
int width() const const
QString getItem(QWidget *parent, const QString &title, const QString &label, const QStringList &items, int current, bool editable, bool *ok, Qt::WindowFlags flags, Qt::InputMethodHints inputMethodHints)
void setText(const QString &)
void setContentsMargins(const QMargins &margins)
const_reference at(qsizetype i) const const
QPoint globalPos() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool begin(QPaintDevice *device)
void drawPixmap(const QPoint &point, const QPixmap &pixmap)
bool end()
void setColor(ColorGroup group, ColorRole role, const QColor &color)
QPixmap fromImage(QImage &&image, Qt::ImageConversionFlags flags)
QSize size() const const
int width() const const
void setX(int x)
void setY(int y)
int x() const const
int y() const const
Qt::MouseButtons buttons() const const
void setRange(int minimum, int maximum)
void setSingleStep(int val)
void setValue(int val)
QString locate(StandardLocation type, const QString &fileName, LocateOptions options)
QString number(double n, char format, int precision)
QString toLower() const const
qsizetype indexOf(const QRegularExpression &re, qsizetype from) const const
KeepAspectRatio
PinchGesture
RightButton
MouseEventSynthesizedBySystem
Horizontal
SmoothTransformation
WA_DeleteOnClose
QFuture< T > run(Function function,...)
QString toString(QStringView format) const const
void setInterval(int msec)
bool isActive() const const
void setSingleShot(bool singleShot)
void start()
void stop()
QUuid createUuid()
Qt::MouseEventSource source() const const
QPoint angleDelta() const const
QWidget(QWidget *parent, Qt::WindowFlags f)
void setAutoFillBackground(bool enabled)
void setMaximumSize(const QSize &)
void setMaximumWidth(int maxw)
void setMinimumSize(const QSize &)
void setAttribute(Qt::WidgetAttribute attribute, bool on)
void setDisabled(bool disable)
void setLayout(QLayout *layout)
void show()
void setToolTip(const QString &)
void update()
bool isVisible() const const
virtual void wheelEvent(QWheelEvent *event)
void setWindowFlags(Qt::WindowFlags type)
void setWindowTitle(const QString &)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:19:02 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.