File indexing completed on 2024-04-28 11:25:08
0001 /* 0002 SPDX-FileCopyrightText: 2011 Rafał Kułaga <rl.kulaga@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "printingwizard.h" 0008 0009 #include <QStackedWidget> 0010 #include <QPrinter> 0011 #include <QStandardPaths> 0012 0013 #include "finderchart.h" 0014 #include "loggingform.h" 0015 #include "detailstable.h" 0016 #include "pwizobjectselection.h" 0017 #include "pwizchartconfig.h" 0018 #include "pwizfovbrowse.h" 0019 #include "pwizfovconfig.h" 0020 #include "pwizfovtypeselection.h" 0021 #include "pwizfovmanual.h" 0022 #include "pwizfovsh.h" 0023 #include "pwizchartcontents.h" 0024 #include "pwizprint.h" 0025 #include "projections/projector.h" 0026 #include "kstars.h" 0027 #include "kstarsdata.h" 0028 #include "skymap.h" 0029 #include "legend.h" 0030 #include "shfovexporter.h" 0031 #include "Options.h" 0032 #include "kspaths.h" 0033 0034 PWizWelcomeUI::PWizWelcomeUI(QWidget *parent) : QFrame(parent) 0035 { 0036 setupUi(this); 0037 } 0038 0039 PrintingWizard::PrintingWizard(QWidget *parent) 0040 : QDialog(parent), m_KStars(KStars::Instance()), m_FinderChart(nullptr), m_SkyObject(nullptr), m_FovType(FT_UNDEFINED), 0041 m_FovImageSize(QSize(500, 500)), m_ShBeginObject(nullptr), m_PointingShBegin(false), m_SwitchColors(false), 0042 m_RecapturingFov(false), m_RecaptureIdx(-1) 0043 { 0044 m_Printer = new QPrinter(QPrinter::ScreenResolution); 0045 0046 setupWidgets(); 0047 } 0048 0049 PrintingWizard::~PrintingWizard() 0050 { 0051 // Clean up 0052 if (m_Printer) 0053 { 0054 delete m_Printer; 0055 } 0056 if (m_FinderChart) 0057 { 0058 delete m_FinderChart; 0059 } 0060 0061 qDeleteAll(m_FovSnapshots); 0062 } 0063 0064 void PrintingWizard::updateStepButtons() 0065 { 0066 switch (m_WizardStack->currentIndex()) 0067 { 0068 case PW_OBJECT_SELECTION: // object selection 0069 { 0070 nextB->setEnabled(m_SkyObject != nullptr); 0071 break; 0072 } 0073 } 0074 } 0075 0076 void PrintingWizard::beginPointing() 0077 { 0078 // If there is sky object already selected, center sky map around it 0079 if (m_SkyObject) 0080 { 0081 m_KStars->map()->setClickedObject(m_SkyObject); 0082 m_KStars->map()->slotCenter(); 0083 } 0084 0085 m_KStars->map()->setObjectPointingMode(true); 0086 hide(); 0087 } 0088 0089 void PrintingWizard::beginShBeginPointing() 0090 { 0091 m_PointingShBegin = true; 0092 0093 if (m_ShBeginObject) 0094 { 0095 m_KStars->map()->setClickedObject(m_SkyObject); 0096 m_KStars->map()->slotCenter(); 0097 } 0098 0099 m_KStars->map()->setObjectPointingMode(true); 0100 hide(); 0101 } 0102 0103 void PrintingWizard::pointingDone(SkyObject *obj) 0104 { 0105 if (m_PointingShBegin) 0106 { 0107 m_ShBeginObject = obj; 0108 m_WizFovShUI->setBeginObject(obj); 0109 m_PointingShBegin = false; 0110 } 0111 else 0112 { 0113 m_SkyObject = obj; 0114 m_WizObjectSelectionUI->setSkyObject(obj); 0115 } 0116 0117 show(); 0118 } 0119 0120 void PrintingWizard::beginFovCapture() 0121 { 0122 if (m_SkyObject) 0123 { 0124 slewAndBeginCapture(m_SkyObject); 0125 } 0126 } 0127 0128 void PrintingWizard::beginFovCapture(SkyPoint *center, FOV *fov) 0129 { 0130 slewAndBeginCapture(center, fov); 0131 } 0132 0133 void PrintingWizard::captureFov() 0134 { 0135 if (m_KStars->data()->getVisibleFOVs().isEmpty()) 0136 { 0137 return; 0138 } 0139 0140 QPixmap pixmap(m_FovImageSize); 0141 m_SimpleFovExporter.exportFov(m_KStars->data()->getVisibleFOVs().first(), &pixmap); 0142 if (m_WizFovConfigUI->isLegendEnabled()) 0143 { 0144 // Set legend position, orientation and type 0145 Legend legend(m_WizFovConfigUI->getLegendOrientation(), m_WizFovConfigUI->getLegendPosition()); 0146 legend.setType(m_WizFovConfigUI->getLegendType()); 0147 0148 // Check if alpha blending is enabled 0149 if (m_WizFovConfigUI->isAlphaBlendingEnabled()) 0150 { 0151 QColor bgColor = legend.getBgColor(); 0152 bgColor.setAlpha(200); 0153 legend.setBgColor(bgColor); 0154 } 0155 0156 // Paint legend 0157 legend.paintLegend(&pixmap); 0158 } 0159 FovSnapshot *snapshot = new FovSnapshot(pixmap, QString(), m_KStars->data()->getVisibleFOVs().first(), 0160 m_KStars->map()->getCenterPoint()); 0161 0162 if (m_RecapturingFov) 0163 { 0164 delete m_FovSnapshots.at(m_RecaptureIdx); 0165 m_FovSnapshots.replace(m_RecaptureIdx, snapshot); 0166 m_KStars->map()->setFovCaptureMode(false); 0167 m_RecapturingFov = false; 0168 m_RecaptureIdx = -1; 0169 fovCaptureDone(); 0170 } 0171 else 0172 { 0173 m_FovSnapshots.append(snapshot); 0174 } 0175 } 0176 0177 void PrintingWizard::fovCaptureDone() 0178 { 0179 //Restore old color scheme if necessary 0180 //(if printing was aborted, the ColorScheme is still restored) 0181 if (m_SwitchColors) 0182 { 0183 m_KStars->loadColorScheme(m_PrevSchemeName); 0184 m_KStars->map()->forceUpdate(); 0185 } 0186 0187 if (m_RecapturingFov) 0188 { 0189 m_RecapturingFov = false; 0190 m_RecaptureIdx = -1; 0191 } 0192 0193 show(); 0194 } 0195 0196 void PrintingWizard::beginShFovCapture() 0197 { 0198 if (!m_ShBeginObject) 0199 { 0200 return; 0201 } 0202 0203 ShFovExporter exporter(this, KStars::Instance()->map()); 0204 0205 // Get selected FOV symbol 0206 double fovArcmin(0); 0207 foreach (FOV *fov, KStarsData::Instance()->getAvailableFOVs()) 0208 { 0209 if (fov->name() == m_WizFovShUI->getFovName()) 0210 { 0211 fovArcmin = qMin(fov->sizeX(), fov->sizeY()); 0212 break; 0213 } 0214 } 0215 0216 // Calculate path and check if it's not empty 0217 if (!exporter.calculatePath(*m_SkyObject, *m_ShBeginObject, fovArcmin / 60, m_WizFovShUI->getMaglim())) 0218 { 0219 KMessageBox::information(this, 0220 i18n("Star hopper returned empty path. We advise you to change star hopping settings " 0221 "or use manual capture mode."), 0222 i18n("Star hopper failed to find path")); 0223 return; 0224 } 0225 0226 // If FOV shape should be overridden, do this now 0227 m_SimpleFovExporter.setFovShapeOverriden(m_WizFovConfigUI->isFovShapeOverriden()); 0228 m_SimpleFovExporter.setFovSymbolDrawn(m_WizFovConfigUI->isFovShapeOverriden()); 0229 0230 // If color scheme should be switched, save previous scheme name and switch to "sky chart" color scheme 0231 m_SwitchColors = m_WizFovConfigUI->isSwitchColorsEnabled(); 0232 m_PrevSchemeName = m_KStars->data()->colorScheme()->fileName(); 0233 if (m_SwitchColors) 0234 { 0235 m_KStars->loadColorScheme("chart.colors"); 0236 } 0237 0238 // Save previous FOV symbol names and switch to symbol selected by user 0239 QStringList prevFovNames = Options::fOVNames(); 0240 Options::setFOVNames(QStringList(m_WizFovShUI->getFovName())); 0241 KStarsData::Instance()->syncFOV(); 0242 if (KStarsData::Instance()->getVisibleFOVs().isEmpty()) 0243 { 0244 return; 0245 } 0246 0247 // Hide Printing Wizard 0248 hide(); 0249 0250 // Draw and export path 0251 exporter.exportPath(); 0252 0253 // Restore old color scheme if necessary 0254 if (m_SwitchColors) 0255 { 0256 m_KStars->loadColorScheme(m_PrevSchemeName); 0257 m_KStars->map()->forceUpdate(); 0258 } 0259 0260 // Update skymap 0261 m_KStars->map()->forceUpdate(true); 0262 0263 // Restore previous FOV symbol names 0264 Options::setFOVNames(prevFovNames); 0265 KStarsData::Instance()->syncFOV(); 0266 0267 //FIXME: this is _dirty_ workaround to get PrintingWizard displayed in its previous position. 0268 QTimer::singleShot(50, this, SLOT(show())); 0269 } 0270 0271 void PrintingWizard::recaptureFov(int idx) 0272 { 0273 // Set recapturing flag and index of the FOV snapshot to replace 0274 m_RecapturingFov = true; 0275 m_RecaptureIdx = idx; 0276 0277 // Begin FOV snapshot capture 0278 SkyPoint p = m_FovSnapshots.at(m_RecaptureIdx)->getCentralPoint(); 0279 slewAndBeginCapture(&p, m_FovSnapshots.at(m_RecaptureIdx)->getFov()); 0280 } 0281 0282 void PrintingWizard::slotPrevPage() 0283 { 0284 int currentIdx = m_WizardStack->currentIndex(); 0285 switch (currentIdx) 0286 { 0287 case PW_FOV_BROWSE: 0288 { 0289 switch (m_FovType) 0290 { 0291 case FT_MANUAL: 0292 { 0293 m_WizardStack->setCurrentIndex(PW_FOV_MANUAL); 0294 break; 0295 } 0296 0297 case FT_STARHOPPER: 0298 { 0299 m_WizardStack->setCurrentIndex(PW_FOV_SH); 0300 break; 0301 } 0302 0303 default: 0304 { 0305 return; 0306 } 0307 } 0308 0309 break; 0310 } 0311 0312 case PW_FOV_SH: 0313 { 0314 m_WizardStack->setCurrentIndex(PW_FOV_CONFIG); 0315 break; 0316 } 0317 0318 default: 0319 { 0320 m_WizardStack->setCurrentIndex(currentIdx - 1); 0321 break; 0322 } 0323 } 0324 0325 updateStepButtons(); 0326 updateButtons(); 0327 } 0328 0329 void PrintingWizard::slotNextPage() 0330 { 0331 int currentIdx = m_WizardStack->currentIndex(); 0332 switch (currentIdx) 0333 { 0334 case PW_FOV_TYPE: 0335 { 0336 m_FovType = m_WizFovTypeSelectionUI->getFovExportType(); 0337 m_WizardStack->setCurrentIndex(PW_FOV_CONFIG); 0338 break; 0339 } 0340 0341 case PW_FOV_CONFIG: 0342 { 0343 switch (m_FovType) 0344 { 0345 case FT_MANUAL: 0346 { 0347 m_WizardStack->setCurrentIndex(PW_FOV_MANUAL); 0348 break; 0349 } 0350 0351 case FT_STARHOPPER: 0352 { 0353 m_WizardStack->setCurrentIndex(PW_FOV_SH); 0354 break; 0355 } 0356 0357 default: // Undefined FOV type - do nothing 0358 { 0359 return; 0360 } 0361 } 0362 0363 break; 0364 } 0365 0366 case PW_FOV_MANUAL: 0367 { 0368 m_WizardStack->setCurrentIndex(PW_FOV_BROWSE); 0369 break; 0370 } 0371 0372 case PW_FOV_BROWSE: 0373 { 0374 m_WizChartContentsUI->entered(); 0375 m_WizardStack->setCurrentIndex(PW_CHART_CONTENTS); 0376 break; 0377 } 0378 0379 case PW_CHART_CONTENTS: 0380 { 0381 createFinderChart(); 0382 m_WizardStack->setCurrentIndex(PW_CHART_PRINT); 0383 break; 0384 } 0385 0386 default: 0387 { 0388 m_WizardStack->setCurrentIndex(currentIdx + 1); 0389 } 0390 } 0391 0392 updateButtons(); 0393 updateStepButtons(); 0394 } 0395 0396 void PrintingWizard::setupWidgets() 0397 { 0398 #ifdef Q_OS_OSX 0399 setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); 0400 #endif 0401 m_WizardStack = new QStackedWidget(this); 0402 0403 setWindowTitle(i18nc("@title:window", "Printing Wizard")); 0404 0405 QVBoxLayout *mainLayout = new QVBoxLayout; 0406 mainLayout->addWidget(m_WizardStack); 0407 setLayout(mainLayout); 0408 0409 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); 0410 mainLayout->addWidget(buttonBox); 0411 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 0412 0413 nextB = new QPushButton(i18n("&Next >")); 0414 nextB->setToolTip(i18n("Go to next Wizard page")); 0415 nextB->setDefault(true); 0416 backB = new QPushButton(i18n("< &Back")); 0417 backB->setToolTip(i18n("Go to previous Wizard page")); 0418 backB->setEnabled(false); 0419 0420 buttonBox->addButton(backB, QDialogButtonBox::ActionRole); 0421 buttonBox->addButton(nextB, QDialogButtonBox::ActionRole); 0422 0423 connect(nextB, SIGNAL(clicked()), this, SLOT(slotNextPage())); 0424 connect(backB, SIGNAL(clicked()), this, SLOT(slotPrevPage())); 0425 0426 // Create step widgets 0427 m_WizWelcomeUI = new PWizWelcomeUI(m_WizardStack); 0428 m_WizObjectSelectionUI = new PWizObjectSelectionUI(this, m_WizardStack); 0429 m_WizChartConfigUI = new PWizChartConfigUI(this); 0430 m_WizFovTypeSelectionUI = new PWizFovTypeSelectionUI(this, m_WizardStack); 0431 m_WizFovConfigUI = new PWizFovConfigUI(m_WizardStack); 0432 m_WizFovManualUI = new PWizFovManualUI(this, m_WizardStack); 0433 m_WizFovShUI = new PWizFovShUI(this, m_WizardStack); 0434 m_WizFovBrowseUI = new PWizFovBrowseUI(this, m_WizardStack); 0435 m_WizChartContentsUI = new PWizChartContentsUI(this, m_WizardStack); 0436 m_WizPrintUI = new PWizPrintUI(this, m_WizardStack); 0437 0438 // Add step widgets to m_WizardStack 0439 m_WizardStack->addWidget(m_WizWelcomeUI); 0440 m_WizardStack->addWidget(m_WizObjectSelectionUI); 0441 m_WizardStack->addWidget(m_WizChartConfigUI); 0442 m_WizardStack->addWidget(m_WizFovTypeSelectionUI); 0443 m_WizardStack->addWidget(m_WizFovConfigUI); 0444 m_WizardStack->addWidget(m_WizFovManualUI); 0445 m_WizardStack->addWidget(m_WizFovShUI); 0446 m_WizardStack->addWidget(m_WizFovBrowseUI); 0447 m_WizardStack->addWidget(m_WizChartContentsUI); 0448 m_WizardStack->addWidget(m_WizPrintUI); 0449 0450 // Set banner images for steps 0451 QPixmap bannerImg; 0452 if (bannerImg.load(KSPaths::locate(QStandardPaths::AppLocalDataLocation, "wzstars.png"))) 0453 { 0454 m_WizWelcomeUI->banner->setPixmap(bannerImg); 0455 m_WizObjectSelectionUI->banner->setPixmap(bannerImg); 0456 m_WizChartConfigUI->banner->setPixmap(bannerImg); 0457 m_WizFovTypeSelectionUI->banner->setPixmap(bannerImg); 0458 m_WizFovConfigUI->banner->setPixmap(bannerImg); 0459 m_WizFovManualUI->banner->setPixmap(bannerImg); 0460 m_WizFovShUI->banner->setPixmap(bannerImg); 0461 m_WizFovBrowseUI->banner->setPixmap(bannerImg); 0462 m_WizChartContentsUI->banner->setPixmap(bannerImg); 0463 m_WizPrintUI->banner->setPixmap(bannerImg); 0464 } 0465 0466 backB->setEnabled(false); 0467 } 0468 0469 void PrintingWizard::updateButtons() 0470 { 0471 nextB->setEnabled(m_WizardStack->currentIndex() < m_WizardStack->count() - 1); 0472 backB->setEnabled(m_WizardStack->currentIndex() > 0); 0473 } 0474 0475 void PrintingWizard::slewAndBeginCapture(SkyPoint *center, FOV *fov) 0476 { 0477 if (!center) 0478 { 0479 return; 0480 } 0481 0482 // If pointer to FOV is passed... 0483 if (fov) 0484 { 0485 // Switch to appropriate FOV symbol 0486 Options::setFOVNames(QStringList(fov->name())); 0487 m_KStars->data()->syncFOV(); 0488 0489 // Adjust map's zoom level 0490 double zoom = m_FovImageSize.width() > m_FovImageSize.height() ? 0491 SimpleFovExporter::calculateZoomLevel(m_FovImageSize.width(), fov->sizeX()) : 0492 SimpleFovExporter::calculateZoomLevel(m_FovImageSize.height(), fov->sizeY()); 0493 m_KStars->map()->setZoomFactor(zoom); 0494 } 0495 0496 m_SimpleFovExporter.setFovShapeOverriden(m_WizFovConfigUI->isFovShapeOverriden()); 0497 m_SimpleFovExporter.setFovSymbolDrawn(m_WizFovConfigUI->isFovShapeOverriden()); 0498 0499 m_SwitchColors = m_WizFovConfigUI->isSwitchColorsEnabled(); 0500 m_PrevSchemeName = m_KStars->data()->colorScheme()->fileName(); 0501 if (m_SwitchColors) 0502 { 0503 m_KStars->loadColorScheme("chart.colors"); 0504 } 0505 0506 m_KStars->hideAllFovExceptFirst(); 0507 m_KStars->map()->setClickedPoint(center); 0508 m_KStars->map()->slotCenter(); 0509 m_KStars->map()->setFovCaptureMode(true); 0510 hide(); 0511 } 0512 0513 void PrintingWizard::createFinderChart() 0514 { 0515 // Delete old (if needed) and create new FinderChart 0516 if (m_FinderChart) 0517 { 0518 delete m_FinderChart; 0519 } 0520 m_FinderChart = new FinderChart; 0521 0522 // Insert title and subtitle 0523 m_FinderChart->insertTitleSubtitle(m_WizChartConfigUI->titleEdit->text(), m_WizChartConfigUI->subtitleEdit->text()); 0524 0525 // Insert description 0526 if (!m_WizChartConfigUI->descriptionTextEdit->toPlainText().isEmpty()) 0527 { 0528 m_FinderChart->insertDescription(m_WizChartConfigUI->descriptionTextEdit->toPlainText()); 0529 } 0530 0531 // Insert simple finder chart logging form 0532 if (m_WizChartContentsUI->isLoggingFormChecked()) 0533 { 0534 LoggingForm chartLogger; 0535 chartLogger.createFinderChartLogger(); 0536 m_FinderChart->insertSectionTitle(i18n("Logging Form")); 0537 m_FinderChart->insertLoggingForm(&chartLogger); 0538 } 0539 0540 m_FinderChart->insertSectionTitle(i18n("Field of View Snapshots")); 0541 0542 // Insert FOV images and descriptions 0543 for (int i = 0; i < m_FovSnapshots.size(); i++) 0544 { 0545 FOV *fov = m_FovSnapshots.at(i)->getFov(); 0546 QString fovDescription = 0547 i18nc("%1 = FOV index, %2 = FOV count, %3 = FOV name, %4 = FOV X size, %5 = FOV Y size", 0548 "FOV (%1/%2): %3 (%4' x %5')", QString::number(i + 1), QString::number(m_FovSnapshots.size()), 0549 fov->name(), QString::number(fov->sizeX()), QString::number(fov->sizeY())) + 0550 "\n"; 0551 m_FinderChart->insertImage(m_FovSnapshots.at(i)->getPixmap().toImage(), 0552 fovDescription + m_FovSnapshots.at(i)->getDescription(), true); 0553 } 0554 0555 if (m_WizChartContentsUI->isGeneralTableChecked() || m_WizChartContentsUI->isPositionTableChecked() || 0556 m_WizChartContentsUI->isRSTTableChecked() || m_WizChartContentsUI->isAstComTableChecked()) 0557 { 0558 m_FinderChart->insertSectionTitle(i18n("Details About Object")); 0559 m_FinderChart->insertGeoTimeInfo(KStarsData::Instance()->ut(), KStarsData::Instance()->geo()); 0560 } 0561 0562 // Insert details table : general 0563 DetailsTable detTable; 0564 if (m_WizChartContentsUI->isGeneralTableChecked()) 0565 { 0566 detTable.createGeneralTable(m_SkyObject); 0567 m_FinderChart->insertDetailsTable(&detTable); 0568 } 0569 0570 // Insert details table : position 0571 if (m_WizChartContentsUI->isPositionTableChecked()) 0572 { 0573 detTable.createCoordinatesTable(m_SkyObject, m_KStars->data()->ut(), m_KStars->data()->geo()); 0574 m_FinderChart->insertDetailsTable(&detTable); 0575 } 0576 0577 // Insert details table : RST 0578 if (m_WizChartContentsUI->isRSTTableChecked()) 0579 { 0580 detTable.createRSTTAble(m_SkyObject, m_KStars->data()->ut(), m_KStars->data()->geo()); 0581 m_FinderChart->insertDetailsTable(&detTable); 0582 } 0583 0584 // Insert details table : Asteroid/Comet 0585 if (m_WizChartContentsUI->isAstComTableChecked()) 0586 { 0587 detTable.createAsteroidCometTable(m_SkyObject); 0588 m_FinderChart->insertDetailsTable(&detTable); 0589 } 0590 }