/* * Copyright (C) 2009 Timothy Reaves * * 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. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "Oculars.hpp" #include "GridLinesMgr.hpp" #include "LabelMgr.hpp" #include "StelApp.hpp" #include "StelCore.hpp" #include "StelFileMgr.hpp" #include "StelModuleMgr.hpp" #include "StelMovementMgr.hpp" #include "StelObjectMgr.hpp" #include "StelPainter.hpp" #include "StelProjector.hpp" #include "StelGui.hpp" #include "StelGuiItems.hpp" #include "StelMainWindow.hpp" #include "StelTranslator.hpp" #include #include #include #include #include #include #include #include #include #include #include #include #if defined(__APPLE__) && defined(__MACH__) #include /* Header File For The GLU Library */ #else #include /* Header File For The GLU Library */ #endif /* ********************************************************************* */ #if 0 #pragma mark - #pragma mark StelModuleMgr Methods #endif /* ********************************************************************* */ //! This method is the one called automatically by the StelModuleMgr just //! after loading the dynamic library StelModule* OcularsStelPluginInterface::getStelModule() const { return new Oculars(); } StelPluginInfo OcularsStelPluginInterface::getPluginInfo() const { // Allow to load the resources when used as a static plugin Q_INIT_RESOURCE(Oculars); StelPluginInfo info; info.id = "Oculars"; info.displayedName = "Ocular"; info.authors = "Timothy Reaves"; info.contact = "treaves@silverfieldstech.com"; info.description = "Shows the sky as if looking through a telescope eyepiece"; return info; } Q_EXPORT_PLUGIN2(Oculars, OcularsStelPluginInterface) /* ********************************************************************* */ #if 0 #pragma mark - #pragma mark Instance Methods #endif /* ********************************************************************* */ Oculars::Oculars() : selectedOcularIndex(-1), flagShowOculars(false), usageMessageLabelID(-1), pxmapGlow(NULL), pxmapOnIcon(NULL), pxmapOffIcon(NULL), toolbarButton(NULL) { flagShowOculars = false; flagShowCrosshairs = false; flagShowTelrad = false; font.setPixelSize(14); maxImageCircle = 0.0; CCDs = QList(); oculars = QList(); ready = false; selectedCCDIndex = 0; selectedOcularIndex = 0; selectedTelescopeIndex = 0; setObjectName("Oculars"); telescopes = QList(); useMaxImageCircle = true; visible = false; ocularsTableModel = NULL; telescopesTableModel = NULL; ocularDialog = NULL; } Oculars::~Oculars() { delete CCDsTableModel; CCDsTableModel = NULL; delete ocularsTableModel; ocularsTableModel = NULL; delete telescopesTableModel; telescopesTableModel = NULL; delete ocularDialog; ocularDialog = NULL; } /* ********************************************************************* */ #if 0 #pragma mark - #pragma mark StelModule Methods #endif /* ********************************************************************* */ bool Oculars::configureGui(bool show) { if (show) { StelGui* gui = dynamic_cast(StelApp::getInstance().getGui()); Q_ASSERT(gui); gui->getGuiActions("actionShow_Ocular_Window")->setChecked(true); } return ready; } //! Draw any parts on the screen which are for our module void Oculars::draw(StelCore* core) { if (flagShowTelrad) { drawTelrad(); } if (flagShowOculars){ // Insure there is a selected ocular & telescope if (selectedCCDIndex > CCDs.count()) { qWarning() << "Oculars: the selected sensor index of " << selectedCCDIndex << " is greater than the sensor count of " << CCDs.count() << ". Module disabled!"; ready = false; } if (selectedOcularIndex > oculars.count()) { qWarning() << "Oculars: the selected ocular index of " << selectedOcularIndex << " is greater than the ocular count of " << oculars.count() << ". Module disabled!"; ready = false; } else if (selectedTelescopeIndex > telescopes.count()) { qWarning() << "Oculars: the selected telescope index of " << selectedTelescopeIndex << " is greater than the telescope count of " << telescopes.count() << ". Module disabled!"; ready = false; } if (ready) { paintMask(); if (flagShowCrosshairs) { drawCrosshairs(); } // Paint the information in the upper-right hand corner paintText(core); } newInstrument = false; // Now that it's been drawn once } } //! Determine which "layer" the plagin's drawing will happen on. double Oculars::getCallOrder(StelModuleActionName actionName) const { // TODO; this really doesn't seem to have any effect. I've tried everything from -100 to +100, // and a calculated value. It all seems to work the same regardless. double order = 1000.0; if (actionName==StelModule::ActionHandleKeys || actionName==StelModule::ActionHandleMouseMoves) { order = StelApp::getInstance().getModuleMgr().getModule("StelMovementMgr")->getCallOrder(actionName) - 1.0; } else if (actionName==StelModule::ActionDraw) { order = GETSTELMODULE(LabelMgr)->getCallOrder(actionName) + 100.0; } return order; } void Oculars::handleMouseClicks(class QMouseEvent* event) { StelCore *core = StelApp::getInstance().getCore(); StelMovementMgr *movementManager = core->getMovementMgr(); if (StelApp::getInstance().getStelObjectMgr().getWasSelected()){ LabelMgr *labelManager = GETSTELMODULE(LabelMgr); if (flagShowOculars) { // center the selected object in the ocular, and track. movementManager->setFlagTracking(true); } else { // remove the usage label if it is being displayed. if (usageMessageLabelID > -1) { labelManager->setLabelShow(usageMessageLabelID, false); labelManager->deleteLabel(usageMessageLabelID); usageMessageLabelID = -1; } } } else if(flagShowOculars) { // The ocular is displayed, but no object is selected. So don't track the stars. movementManager->setFlagLockEquPos(false); } event->setAccepted(false); } void Oculars::init() { qDebug() << "Ocular plugin - press Command-o to toggle eyepiece view mode. Press ALT-o for configuration."; // Load settings from ocular.ini validateIniFile(); if (initializeDB()) { // assume all is well ready = true; ocularDialog = new OcularDialog(CCDsTableModel, ocularsTableModel, telescopesTableModel); initializeActivationActions(); } try { StelFileMgr::Flags flags = (StelFileMgr::Flags)(StelFileMgr::Directory|StelFileMgr::Writable); QString ocularIniPath = StelFileMgr::findFile("modules/Oculars/", flags) + "ocular.ini"; QSettings settings(ocularIniPath, QSettings::IniFormat); useMaxImageCircle = settings.value("use_max_exit_circle", 0.0).toBool(); } catch (std::runtime_error& e) { qWarning() << "WARNING: unable to locate ocular.ini file or create a default one for Ocular plugin: " << e.what(); } //Load the module's custom style sheets QFile styleSheetFile; styleSheetFile.setFileName(":/ocular/normalStyle.css"); if(styleSheetFile.open(QFile::ReadOnly|QFile::Text)) { normalStyleSheet = styleSheetFile.readAll(); } styleSheetFile.close(); styleSheetFile.setFileName(":/ocular/nightStyle.css"); if(styleSheetFile.open(QFile::ReadOnly|QFile::Text)) { nightStyleSheet = styleSheetFile.readAll(); } styleSheetFile.close(); } void Oculars::deinit() { QSqlDatabase db = QSqlDatabase::database("oculars"); db.close(); QSqlDatabase::removeDatabase(QSqlDatabase::defaultConnection); } void Oculars::setStelStyle(const QString&) { ocularDialog->updateStyle(); } const StelStyle Oculars::getModuleStyleSheet(const StelStyle& style) { StelStyle pluginStyle(style); if (style.confSectionName == "color") { pluginStyle.qtStyleSheet.append(normalStyleSheet); } else { pluginStyle.qtStyleSheet.append(nightStyleSheet); } return pluginStyle; } /* ********************************************************************* */ #if 0 #pragma mark - #pragma mark Private slots Methods #endif /* ********************************************************************* */ void Oculars::determineMaxImageCircle() { if (ready) { QListIterator ocularIterator(oculars); while (ocularIterator.hasNext()) { Ocular *ocular = ocularIterator.next(); QListIterator telescopeIterator(telescopes); while (telescopeIterator.hasNext()) { Telescope *telescope = telescopeIterator.next(); if (ocular->getExitCircle(telescope) > maxImageCircle) { maxImageCircle = ocular->getExitCircle(telescope); } } } } // insure it is not zero if (maxImageCircle == 0.0) { maxImageCircle = 1.0; } } void Oculars::instrumentChanged() { newInstrument = true; zoom(true); } void Oculars::loadCCDs() { CCDs.clear(); int rowCount = CCDsTableModel->rowCount(); for (int row = 0; row < rowCount; row++) { CCDs.append(new CCD(CCDsTableModel->record(row))); } } void Oculars::loadOculars() { oculars.clear(); int rowCount = ocularsTableModel->rowCount(); for (int row = 0; row < rowCount; row++) { oculars.append(new Ocular(ocularsTableModel->record(row))); } } void Oculars::loadTelescopes() { telescopes.clear(); int rowCount = telescopesTableModel->rowCount(); for (int row = 0; row < rowCount; row++) { telescopes.append(new Telescope(telescopesTableModel->record(row))); } } void Oculars::setScaleImageCircle(bool state) { if (state) { determineMaxImageCircle(); } useMaxImageCircle = state; } /* ********************************************************************* */ #if 0 #pragma mark - #pragma mark Slots Methods #endif /* ********************************************************************* */ void Oculars::enableOcular(bool b) { if (!ready) { qDebug() << "The Oculars module has been disabled."; return; } if (b) { // load data and determine if we're ready (if we have all required data) loadDatabaseObjects(); } if (!ready) { // no, some data was missing. We already warned, done. return; } StelCore *core = StelApp::getInstance().getCore(); LabelMgr* labelManager = GETSTELMODULE(LabelMgr); // Toggle the plugin on & off. To toggle on, we want to ensure there is a selected object. if (!flagShowOculars && !StelApp::getInstance().getStelObjectMgr().getWasSelected()) { if (usageMessageLabelID == -1) { QFontMetrics metrics(font); QString labelText = "Please select an object before enabling Ocular."; StelProjector::StelProjectorParams projectorParams = core->getCurrentStelProjectorParams(); int xPosition = projectorParams.viewportCenter[0]; xPosition = xPosition - 0.5 * (metrics.width(labelText)); int yPosition = projectorParams.viewportCenter[1]; yPosition = yPosition - 0.5 * (metrics.height()); usageMessageLabelID = labelManager->labelScreen(labelText, xPosition, yPosition, true, font.pixelSize(), "#99FF99"); } // we didn't accept the new status - make sure the toolbar button reflects this StelGui* gui = dynamic_cast(StelApp::getInstance().getGui()); Q_ASSERT(gui); gui->getGuiActions("actionShow_Ocular")->setChecked(false); } else { if (selectedOcularIndex != -1) { // remove the usage label if it is being displayed. if (usageMessageLabelID > -1) { labelManager->setLabelShow(usageMessageLabelID, false); labelManager->deleteLabel(usageMessageLabelID); usageMessageLabelID = -1; } flagShowOculars = b; zoom(false); } } if (flagShowOculars) { initializeActions(); } } void Oculars::decrementCCDIndex() { selectedCCDIndex--; if (selectedCCDIndex == -1) { selectedCCDIndex = CCDs.count() - 1; } emit(selectedCCDChanged()); } void Oculars::decrementOcularIndex() { selectedOcularIndex--; if (selectedOcularIndex == -1) { selectedOcularIndex = oculars.count() - 1; } emit(selectedOcularChanged()); } void Oculars::decrementTelescopeIndex() { selectedTelescopeIndex--; if (selectedTelescopeIndex == -1) { selectedTelescopeIndex = telescopes.count() - 1; } emit(selectedTelescopeChanged()); } void Oculars::incrementCCDIndex() { selectedCCDIndex++; if (selectedCCDIndex == CCDs.count()) { selectedCCDIndex = 0; } emit(selectedCCDChanged()); } void Oculars::incrementOcularIndex() { selectedOcularIndex++; if (selectedOcularIndex == oculars.count()) { selectedOcularIndex = 0; } emit(selectedOcularChanged()); } void Oculars::incrementTelescopeIndex() { selectedTelescopeIndex++; if (selectedTelescopeIndex == telescopes.count()) { selectedTelescopeIndex = 0; } emit(selectedTelescopeChanged()); } void Oculars::toggleCrosshair() { flagShowCrosshairs = !flagShowCrosshairs; } void Oculars::toggleTelrad() { flagShowTelrad = !flagShowTelrad; } /* ********************************************************************* */ #if 0 #pragma mark - #pragma mark Private Methods #endif /* ********************************************************************* */ void Oculars::drawCrosshairs() { const StelProjectorP projector = StelApp::getInstance().getCore()->getProjection(StelCore::FrameEquinoxEqu); StelCore *core = StelApp::getInstance().getCore(); StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams(); // Center of screen Vec2i centerScreen(projector->getViewportPosX()+projector->getViewportWidth()/2, projector->getViewportPosY()+projector->getViewportHeight()/2); GLdouble length = 0.5 * params.viewportFovDiameter; // See if we need to scale the length if (useMaxImageCircle && oculars[selectedOcularIndex]->getExitCircle(telescopes[selectedTelescopeIndex]) > 0.0) { length = oculars[selectedOcularIndex]->getExitCircle(telescopes[selectedTelescopeIndex]) * length / maxImageCircle; } // Draw the lines StelPainter painter(projector); painter.setColor(0.77, 0.14, 0.16, 1); painter.drawLine2d(centerScreen[0], centerScreen[1], centerScreen[0], centerScreen[1] + length); painter.drawLine2d(centerScreen[0], centerScreen[1], centerScreen[0], centerScreen[1] - length); painter.drawLine2d(centerScreen[0], centerScreen[1], centerScreen[0] + length, centerScreen[1]); painter.drawLine2d(centerScreen[0], centerScreen[1], centerScreen[0] - length, centerScreen[1]); } void Oculars::drawTelrad() { if (!flagShowOculars) { const StelProjectorP projector = StelApp::getInstance().getCore()->getProjection(StelCore::FrameEquinoxEqu); StelCore *core = StelApp::getInstance().getCore(); StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams(); // StelPainter drawing StelPainter painter(projector); painter.setColor(0.77, 0.14, 0.16, 1.0); Vec2i centerScreen(projector->getViewportPosX()+projector->getViewportWidth()/2, projector->getViewportPosY()+projector->getViewportHeight()/2); painter.drawCircle(centerScreen[0], centerScreen[1], 0.5 * projector->getPixelPerRadAtCenter() * (M_PI/180) * (0.5)); painter.drawCircle(centerScreen[0], centerScreen[1], 0.5 * projector->getPixelPerRadAtCenter() * (M_PI/180) * (2.0)); painter.drawCircle(centerScreen[0], centerScreen[1], 0.5 * projector->getPixelPerRadAtCenter() * (M_PI/180) * (4.0)); // // Direct drawing // glDisable(GL_BLEND); // glColor3f(0.f,0.f,0.f); // glPushMatrix(); // glTranslated(params.viewportCenter[0], params.viewportCenter[1], 0.0); // GLUquadricObj *quadric = gluNewQuadric(); // // the gray circle // glColor4f(0.77, 0.14, 0.16, 0.5); // float radius = 0.5 * projector->getPixelPerRadAtCenter() * (M_PI/180) * (0.5); // gluDisk(quadric, radius - 1.0, radius, 256, 1); // radius = 0.5 * projector->getPixelPerRadAtCenter() * (M_PI/180) * (2.0); // gluDisk(quadric, radius - 1.0, radius, 256, 1); // radius = 0.5 * projector->getPixelPerRadAtCenter() * (M_PI/180) * (4.0); // gluDisk(quadric, radius - 1.0, radius, 256, 1); // gluDeleteQuadric(quadric); // glPopMatrix(); } } void Oculars::initializeActivationActions() { QString group = "Oculars Plugin"; StelGui* gui = dynamic_cast(StelApp::getInstance().getGui()); Q_ASSERT(gui); gui->addGuiActions("actionShow_Ocular", N_("Enable ocular"), "Ctrl+O", "Plugin Key Bindings", true); gui->getGuiActions("actionShow_Ocular")->setChecked(flagShowOculars); connect(gui->getGuiActions("actionShow_Ocular"), SIGNAL(toggled(bool)), this, SLOT(enableOcular(bool))); gui->addGuiActions("actionShow_Ocular_Window", N_("Configuration Window"), "ALT+O", group, true); connect(gui->getGuiActions("actionShow_Ocular_Window"), SIGNAL(toggled(bool)), ocularDialog, SLOT(setVisible(bool))); connect(ocularDialog, SIGNAL(visibleChanged(bool)), gui->getGuiActions("actionShow_Ocular_Window"), SLOT(setChecked(bool))); gui->addGuiActions("actionShow_Ocular_Telrad", N_("Display Telrad"), "Ctrl+B", group, true); gui->getGuiActions("actionShow_Ocular_Telrad")->setChecked(flagShowTelrad); connect(gui->getGuiActions("actionShow_Ocular_Telrad"), SIGNAL(toggled(bool)), this, SLOT(toggleTelrad())); // Make a toolbar button try { pxmapGlow = new QPixmap(":/graphicGui/glow32x32.png"); pxmapOnIcon = new QPixmap(":/ocular/bt_ocular_on.png"); pxmapOffIcon = new QPixmap(":/ocular/bt_ocular_off.png"); toolbarButton = new StelButton(NULL, *pxmapOnIcon, *pxmapOffIcon, *pxmapGlow, gui->getGuiActions("actionShow_Ocular")); gui->getButtonBar()->addButton(toolbarButton, "065-pluginsGroup"); } catch (std::runtime_error& e) { qWarning() << "WARNING: unable create toolbar button for Oculars plugin: " << e.what(); } } void Oculars::initializeActions() { static bool actions_initialized; if (actions_initialized) return; actions_initialized = true; QString group = "Oculars Plugin"; StelGui* gui = dynamic_cast(StelApp::getInstance().getGui()); Q_ASSERT(gui); gui->addGuiActions("actionShow_Ocular_Crosshair", N_("Toggle Crosshair"), "ALT+C", group, true); gui->addGuiActions("actionShow_CCD_increment", N_("Select next sensor"), "Shift+Ctrl+]", group, false); gui->addGuiActions("actionShow_CCD_decrement", N_("Select previous sensor"), "Shift+Ctrl+[", group, false); gui->addGuiActions("actionShow_Ocular_increment", N_("Select next ocular"), "Ctrl+]", group, false); gui->addGuiActions("actionShow_Ocular_decrement", N_("Select previous ocular"), "Ctrl+[", group, false); gui->addGuiActions("actionShow_Telescope_increment", N_("Select next telescope"), "Shift+]", group, false); gui->addGuiActions("actionShow_Telescope_decrement", N_("Select previous telescope"), "Shift+[", group, false); connect(gui->getGuiActions("actionShow_Ocular_Crosshair"), SIGNAL(toggled(bool)), this, SLOT(toggleCrosshair())); connect(gui->getGuiActions("actionShow_CCD_increment"), SIGNAL(triggered()), this, SLOT(incrementCCDIndex())); connect(gui->getGuiActions("actionShow_CCD_decrement"), SIGNAL(triggered()), this, SLOT(decrementCCDIndex())); connect(gui->getGuiActions("actionShow_Ocular_increment"), SIGNAL(triggered()), this, SLOT(incrementOcularIndex())); connect(gui->getGuiActions("actionShow_Ocular_decrement"), SIGNAL(triggered()), this, SLOT(decrementOcularIndex())); connect(gui->getGuiActions("actionShow_Telescope_increment"), SIGNAL(triggered()), this, SLOT(incrementTelescopeIndex())); connect(gui->getGuiActions("actionShow_Telescope_decrement"), SIGNAL(triggered()), this, SLOT(decrementTelescopeIndex())); /* connect(telescopesTableModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(dataChanged())); connect(telescopesTableModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(rowsInserted())); connect(telescopesTableModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(rowsRemoved())); */ connect(this, SIGNAL(selectedCCDChanged()), this, SLOT(instrumentChanged())); connect(this, SIGNAL(selectedOcularChanged()), this, SLOT(instrumentChanged())); connect(this, SIGNAL(selectedTelescopeChanged()), this, SLOT(instrumentChanged())); connect(ocularDialog, SIGNAL(scaleImageCircleChanged(bool)), this, SLOT(setScaleImageCircle(bool))); } // Return true if we're ready (could read all required data), false otherwise bool Oculars::initializeDB() { StelFileMgr::Flags flags = (StelFileMgr::Flags)(StelFileMgr::Directory|StelFileMgr::Writable); QString dbPath = StelFileMgr::findFile("modules/Oculars/", flags); QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "oculars"); db.setDatabaseName(dbPath + "oculars.sqlite"); if (db.open()) { #define EXEC(sql) if (!query.exec(sql)) { qDebug() << query.lastError(); return false;} qDebug() << "Oculars opened the DB successfully."; // See if the tables alreadt exist. QStringList tableList = db.tables(); if (!tableList.contains("oculars")) { QSqlQuery query = QSqlQuery(db); EXEC("create table oculars (id INTEGER PRIMARY KEY, name VARCHAR, afov FLOAT, efl FLOAT, fieldStop FLOAT)"); EXEC("INSERT INTO oculars (name, afov, efl, fieldStop) VALUES ('one', 43, 40, 0)"); EXEC("INSERT INTO oculars (name, afov, efl, fieldStop) VALUES ('two', 82, 31, 0)"); EXEC("INSERT INTO oculars (name, afov, efl, fieldStop) VALUES ('three', 52, 10.5, 0)"); EXEC("INSERT INTO oculars (name, afov, efl, fieldStop) VALUES ('four', 52, 26, 0)"); EXEC("INSERT INTO oculars (name, afov, efl, fieldStop) VALUES ('five', 82, 20, 0)"); } if (!tableList.contains("telescopes")) { QSqlQuery query = QSqlQuery(db); EXEC("create table telescopes (id INTEGER PRIMARY KEY, name VARCHAR, focalLength FLOAT, diameter FLOAT, vFlip VARCHAR, hFlip VARCHAR)"); EXEC("INSERT INTO telescopes (name, focalLength, diameter, vFlip, hFlip) VALUES ('C1400', 3190, 355.6, 'false', 'true')"); EXEC("INSERT INTO telescopes (name, focalLength, diameter, vFlip, hFlip) VALUES ('80EDF', 500, 80, 'false', 'false')"); } if (!tableList.contains("ccd")) { QSqlQuery query = QSqlQuery(db); EXEC("create table ccd (id INTEGER PRIMARY KEY, name VARCHAR, resolution_x INTEGER, resolution_y INTEGER, chip_width FLOAT, chip_height FLOAT, pixel_width FLOAT, pixel_height FLOAT)"); EXEC("INSERT INTO ccd (name, resolution_x, resolution_y, chip_width, chip_height, pixel_width, pixel_height) VALUES ('None', 0, 0, 0, 0, 0, 0)"); EXEC("INSERT INTO ccd (name, resolution_x, resolution_y, chip_width, chip_height, pixel_width, pixel_height) VALUES ('EOS 450D', 4272, 2848, 22.2, 14.8, 5.2, 5.2)"); } // Set the table models CCDsTableModel = new QSqlTableModel(0, db); CCDsTableModel->setTable("ccd"); CCDsTableModel->select(); ocularsTableModel = new QSqlTableModel(0, db); ocularsTableModel->setTable("oculars"); if (!ocularsTableModel->select()) return false; telescopesTableModel = new QSqlTableModel(0, db); telescopesTableModel->setTable("telescopes"); if (!telescopesTableModel->select()) return false; #undef EXEC return true; } else { qDebug() << "Oculars could not open its database; disabling module."; } return false; } void Oculars::interceptMovementKey(QKeyEvent* event) { // We onle care about the arrow keys. This flag tracks that. bool consumeEvent = false; StelCore *core = StelApp::getInstance().getCore(); StelMovementMgr *movementManager = core->getMovementMgr(); if (event->type() == QEvent::KeyPress) { // Direction and zoom replacements switch (event->key()) { case Qt::Key_Left: movementManager->turnLeft(true); consumeEvent = true; break; case Qt::Key_Right: movementManager->turnRight(true); consumeEvent = true; break; case Qt::Key_Up: if (!event->modifiers().testFlag(Qt::ControlModifier)) { movementManager->turnUp(true); } consumeEvent = true; break; case Qt::Key_Down: if (!event->modifiers().testFlag(Qt::ControlModifier)) { movementManager->turnDown(true); } consumeEvent = true; break; case Qt::Key_PageUp: movementManager->zoomIn(true); consumeEvent = true; break; case Qt::Key_PageDown: movementManager->zoomOut(true); consumeEvent = true; break; case Qt::Key_Shift: movementManager->moveSlow(true); consumeEvent = true; break; } } else { // When a deplacement key is released stop mooving switch (event->key()) { case Qt::Key_Left: movementManager->turnLeft(false); consumeEvent = true; break; case Qt::Key_Right: movementManager->turnRight(false); consumeEvent = true; break; case Qt::Key_Up: movementManager->turnUp(false); consumeEvent = true; break; case Qt::Key_Down: movementManager->turnDown(false); consumeEvent = true; break; case Qt::Key_PageUp: movementManager->zoomIn(false); consumeEvent = true; break; case Qt::Key_PageDown: movementManager->zoomOut(false); consumeEvent = true; break; case Qt::Key_Shift: movementManager->moveSlow(false); consumeEvent = true; break; } if (consumeEvent) { // We don't want to re-center the object; just hold the current position. movementManager->setFlagLockEquPos(true); } } if (consumeEvent) { event->accept(); } else { event->setAccepted(false); } } void Oculars::loadDatabaseObjects() { loadCCDs(); loadOculars(); loadTelescopes(); if (useMaxImageCircle) { determineMaxImageCircle(); } // A telescope and one of [CCD|Ocular] must be defined for the plugin to be usable. if (telescopes.size() == 0) { ready = false; qWarning() << "WARNING: no telescopes found. Ocular will be disabled."; } else if (oculars.size() == 0 && CCDs.size() == 0) { ready = false; qWarning() << "WARNING: no oculars or CCDs found. Ocular will be disabled."; } else { ready = true; } } void Oculars::paintMask() { StelCore *core = StelApp::getInstance().getCore(); StelProjector::StelProjectorParams params = core->getCurrentStelProjectorParams(); glDisable(GL_BLEND); glColor3f(0.f,0.f,0.f); glPushMatrix(); glTranslated(params.viewportCenter[0], params.viewportCenter[1], 0.0); GLUquadricObj *quadric = gluNewQuadric(); GLdouble inner = 0.5 * params.viewportFovDiameter; // See if we need to scale the mask if (useMaxImageCircle && oculars[selectedOcularIndex]->getExitCircle(telescopes[selectedTelescopeIndex]) > 0.0) { inner = oculars[selectedOcularIndex]->getExitCircle(telescopes[selectedTelescopeIndex]) * inner / maxImageCircle; } GLdouble outer = params.viewportXywh[2] + params.viewportXywh[3]; // Draw the mask gluDisk(quadric, inner, outer, 256, 1); // the gray circle glColor3f(0.15f,0.15f,0.15f); gluDisk(quadric, inner - 1.0, inner, 256, 1); gluDeleteQuadric(quadric); // draw sensor rectangle CCD *ccd = CCDs[selectedCCDIndex]; if (ccd) { Ocular *ocular = oculars[selectedOcularIndex]; float CCDx = ccd->getActualFOVx(ocular); float CCDy = ccd->getActualFOVy(ocular); if (CCDx > 0.0 && CCDy > 0.0) { glBegin(GL_LINE_LOOP); glVertex2f(-CCDx, CCDy); glVertex2f(CCDx, CCDy); glVertex2f(CCDx, -CCDy); glVertex2f(-CCDx, -CCDy); glEnd(); } } glPopMatrix(); } void Oculars::paintText(const StelCore* core) { const StelProjectorP prj = core->getProjection(StelCore::FrameAltAz); StelPainter painter(prj); // Get the current instruments CCD *ccd = CCDs[selectedCCDIndex]; Ocular *ocular = oculars[selectedOcularIndex]; Telescope *telescope = telescopes[selectedTelescopeIndex]; // set up the color and the GL state painter.setColor(0.8, 0.48, 0.0, 1); glDisable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); // Get the X & Y positions, and the line height painter.setFont(font); QString widthString = "MMMMMMMMMMMMMMMMMMM"; float insetFromRHS = painter.getFontMetrics().width(widthString); StelProjector::StelProjectorParams projectorParams = core->getCurrentStelProjectorParams(); int xPosition = projectorParams.viewportXywh[2]; xPosition -= insetFromRHS; int yPosition = projectorParams.viewportXywh[3]; yPosition -= 40; const int lineHeight = painter.getFontMetrics().height(); // The CCD QString ccdSensorLabel, ccdInfoLabel; if (ccd && ccd->getChipWidth() > .0 && ccd->getChipHeight() > .0) { ccdInfoLabel = "Dimension : " + QVariant(ccd->getChipWidth()).toString() + "x" + QVariant(ccd->getChipHeight()).toString() + " mm"; if (ccd->getName() != QString("")) { ccdSensorLabel = "Sensor #" + QVariant(selectedCCDIndex).toString(); ccdSensorLabel.append(" : ").append(ccd->getName()); } } if (ccdSensorLabel != QString("")) { painter.drawText(xPosition, yPosition, ccdSensorLabel); yPosition-=lineHeight; painter.drawText(xPosition, yPosition, ccdInfoLabel); yPosition-=lineHeight; } // The Ocular QString ocularNumberLabel = "Ocular #" + QVariant(selectedOcularIndex).toString(); if (ocular->getName() != QString("")) { ocularNumberLabel.append(" : ").append(ocular->getName()); } painter.drawText(xPosition, yPosition, ocularNumberLabel); yPosition-=lineHeight; QString ocularFLLabel = "Ocular FL: " + QVariant(ocular->getEffectiveFocalLength()).toString() + QChar(0x00B0); painter.drawText(xPosition, yPosition, ocularFLLabel); yPosition-=lineHeight; QString ocularFOVLabel = "Ocular aFOV: " + QVariant(ocular->getAppearentFOV()).toString() + QChar(0x00B0); painter.drawText(xPosition, yPosition, ocularFOVLabel); yPosition-=lineHeight; // The telescope QString telescopeNumberLabel = "Telescope #" + QVariant(selectedTelescopeIndex).toString(); if (telescope->getName() != QString("")) { telescopeNumberLabel.append(" : ").append(telescope->getName()); } painter.drawText(xPosition, yPosition, telescopeNumberLabel); yPosition-=lineHeight; // General info QString magnificationLabel = "Magnification: " + QVariant(((int)(ocular->getMagnification(telescope) * 10.0)) / 10.0).toString() + "x"; painter.drawText(xPosition, yPosition, magnificationLabel); yPosition-=lineHeight; QString imageCircleLabel = "Image Circle: " + QVariant(((int)(ocular->getExitCircle(telescope) * 10.0)) / 10.0).toString() + "mm"; painter.drawText(xPosition, yPosition, imageCircleLabel); yPosition-=lineHeight; QString fovLabel = "FOV: " + QVariant(((int)(ocular->getActualFOV(telescope) * 10000.00)) / 10000.0).toString() + QChar(0x00B0); painter.drawText(xPosition, yPosition, fovLabel); } void Oculars::validateIniFile() { // Insure the module directory exists StelFileMgr::makeSureDirExistsAndIsWritable(StelFileMgr::getUserDir()+"/modules/Oculars"); StelFileMgr::Flags flags = (StelFileMgr::Flags)(StelFileMgr::Directory|StelFileMgr::Writable); QString ocularIniPath = StelFileMgr::findFile("modules/Oculars/", flags) + "ocular.ini"; // If the ini file does not already exist, create it from the resource in the QT resource if(!QFileInfo(ocularIniPath).exists()) { QFile src(":/ocular/default_ocular.ini"); if (!src.copy(ocularIniPath)) { qWarning() << "Oculars::validateIniFile cannot copy default_ocular.ini resource to [non-existing] " + ocularIniPath; } else { qDebug() << "Oculars::validateIniFile copied default_ocular.ini to " << ocularIniPath; // The resource is read only, and the new file inherits this, so set write-able. QFile dest(ocularIniPath); dest.setPermissions(dest.permissions() | QFile::WriteOwner); } } else { qDebug() << "Oculars::validateIniFile ocular.ini exists at: " << ocularIniPath << ". Checking version..."; QSettings settings(ocularIniPath, QSettings::IniFormat); double ocularsVersion = settings.value("oculars_version", "0.0").toDouble(); qWarning() << "Oculars::validateIniFile found existing ini file version " << ocularsVersion; if (ocularsVersion < MIN_OCULARS_INI_VERSION) { qWarning() << "Oculars::validateIniFile existing ini file version " << ocularsVersion << " too old to use; required version is " << MIN_OCULARS_INI_VERSION << ". Copying over new one."; // delete last "old" file, if it exists QFile deleteFile(ocularIniPath + ".old"); deleteFile.remove(); // Rename the old one, and copy over a new one QFile oldFile(ocularIniPath); if (!oldFile.rename(ocularIniPath + ".old")) { qWarning() << "Oculars::validateIniFile cannot move ocular.ini resource to ocular.ini.old at path " + ocularIniPath; } else { qWarning() << "Oculars::validateIniFile ocular.ini resource renamed to ocular.ini.old at path " + ocularIniPath; QFile src(":/ocular/default_ocular.ini"); if (!src.copy(ocularIniPath)) { qWarning() << "Oculars::validateIniFile cannot copy default_ocular.ini resource to [non-existing] " + ocularIniPath; } else { qDebug() << "Oculars::validateIniFile copied default_ocular.ini to " << ocularIniPath; // The resource is read only, and the new file inherits this... make sure the new file // is writable by the Stellarium process so that updates can be done. QFile dest(ocularIniPath); dest.setPermissions(dest.permissions() | QFile::WriteOwner); } } } } } void Oculars::unzoomOcular() { StelCore *core = StelApp::getInstance().getCore(); StelMovementMgr *movementManager = core->getMovementMgr(); GridLinesMgr *gridManager = (GridLinesMgr *)StelApp::getInstance().getModuleMgr().getModule("GridLinesMgr"); gridManager->setFlagAzimuthalGrid(flagAzimuthalGrid); gridManager->setFlagEquatorGrid(flagEquatorGrid); gridManager->setFlagEquatorJ2000Grid(flagEquatorJ2000Grid); gridManager->setFlagEquatorLine(flagEquatorLine); gridManager->setFlagEclipticLine(flagEclipticLine); gridManager->setFlagMeridianLine(flagMeridianLine); movementManager->setFlagTracking(false); movementManager->setFlagEnableZoomKeys(true); movementManager->setFlagEnableMouseNavigation(true); // Set the screen display // core->setMaskType(StelProjector::MaskNone); core->setFlipHorz(false); core->setFlipVert(false); movementManager->zoomTo(movementManager->getInitFov()); } void Oculars::zoom(bool rezoom) { if (flagShowOculars) { if (!rezoom) { GridLinesMgr *gridManager = (GridLinesMgr *)StelApp::getInstance().getModuleMgr().getModule("GridLinesMgr"); // Current state flagAzimuthalGrid = gridManager->getFlagAzimuthalGrid(); flagEquatorGrid = gridManager->getFlagEquatorGrid(); flagEquatorJ2000Grid = gridManager->getFlagEquatorJ2000Grid(); flagEquatorLine = gridManager->getFlagEquatorLine(); flagEclipticLine = gridManager->getFlagEclipticLine(); flagMeridianLine = gridManager->getFlagMeridianLine(); } // set new state zoomOcular(); } else { //reset to original state unzoomOcular(); } } void Oculars::zoomOcular() { StelCore *core = StelApp::getInstance().getCore(); StelMovementMgr *movementManager = core->getMovementMgr(); GridLinesMgr *gridManager = (GridLinesMgr *)StelApp::getInstance().getModuleMgr().getModule("GridLinesMgr"); gridManager->setFlagAzimuthalGrid(false); gridManager->setFlagEquatorGrid(false); gridManager->setFlagEquatorJ2000Grid(false); gridManager->setFlagEquatorLine(false); gridManager->setFlagEclipticLine(false); gridManager->setFlagMeridianLine(false); movementManager->setFlagTracking(true); movementManager->setFlagEnableZoomKeys(false); movementManager->setFlagEnableMouseNavigation(false); // We won't always have a selected object if (StelApp::getInstance().getStelObjectMgr().getWasSelected()) { movementManager-> moveToJ2000(StelApp::getInstance().getStelObjectMgr().getSelectedObject()[0]->getEquinoxEquatorialPos(core->getNavigator()), 0.0, 1); } // Set the screen display // core->setMaskType(StelProjector::MaskDisk); Ocular *ocular = oculars[selectedOcularIndex]; Telescope *telescope = telescopes[selectedTelescopeIndex]; core->setFlipHorz(telescope->isHFlipped()); core->setFlipVert(telescope->isVFlipped()); double actualFOV = ocular->getActualFOV(telescope); // See if the mask was scaled; if so, correct the actualFOV. if (useMaxImageCircle && ocular->getExitCircle(telescope) > 0.0) { actualFOV = maxImageCircle * actualFOV / ocular->getExitCircle(telescope); } movementManager->zoomTo(actualFOV, 0.0); }