Warning, file /education/kstars/kstars/skymapevents.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2001 Jason Harris <jharris@30doradus.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 //This file contains Event handlers for the SkyMap class. 0008 0009 #include "skymap.h" 0010 0011 #include "ksplanetbase.h" 0012 #include "kspopupmenu.h" 0013 #include "kstars.h" 0014 #include "observinglist.h" 0015 #include "Options.h" 0016 #include "skyglpainter.h" 0017 #include "skyqpainter.h" 0018 #include "printing/simplefovexporter.h" 0019 #include "skycomponents/skylabeler.h" 0020 #include "skycomponents/skymapcomposite.h" 0021 #include "skycomponents/starcomponent.h" 0022 #include "skycomponents/mosaiccomponent.h" 0023 #ifdef HAVE_INDI 0024 #include "skyobjects/mosaictiles.h" 0025 #endif 0026 #include "widgets/infoboxwidget.h" 0027 0028 #include <QGestureEvent> 0029 #include <QStatusBar> 0030 #include <QToolTip> 0031 0032 void SkyMap::resizeEvent(QResizeEvent *) 0033 { 0034 computeSkymap = true; // skymap must be new computed 0035 0036 //FIXME: No equivalent for this line in Qt4 ?? 0037 // if ( testWState( Qt::WState_AutoMask ) ) updateMask(); 0038 0039 // Resize the widget that draws the sky map. 0040 // FIXME: The resize event doesn't pass to children. Any better way of doing this? 0041 m_SkyMapDraw->resize(size()); 0042 0043 // Resize infoboxes container. 0044 // FIXME: this is not really pretty. Maybe there are some better way to this??? 0045 m_iboxes->resize(size()); 0046 } 0047 0048 void SkyMap::keyPressEvent(QKeyEvent *e) 0049 { 0050 bool arrowKeyPressed(false); 0051 bool shiftPressed(false); 0052 float step = 1.0; 0053 if (e->modifiers() & Qt::ShiftModifier) 0054 { 0055 step = 10.0; 0056 shiftPressed = true; 0057 } 0058 0059 //If the DBus resume key is not empty, then DBus processing is 0060 //paused while we wait for a keypress 0061 if (!data->resumeKey.isEmpty() && QKeySequence(e->key()) == data->resumeKey) 0062 { 0063 //The resumeKey was pressed. Signal that it was pressed by 0064 //resetting it to empty; this will break the loop in 0065 //KStars::waitForKey() 0066 data->resumeKey = QKeySequence(); 0067 return; 0068 } 0069 0070 if (m_previewLegend) 0071 { 0072 slotCancelLegendPreviewMode(); 0073 } 0074 0075 switch (e->key()) 0076 { 0077 case Qt::Key_Left: 0078 if (Options::useAltAz()) 0079 { 0080 focus()->setAz(dms(focus()->az().Degrees() - step * MINZOOM / Options::zoomFactor()).reduce()); 0081 focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat()); 0082 } 0083 else 0084 { 0085 focus()->setRA(focus()->ra().Hours() + 0.05 * step * MINZOOM / Options::zoomFactor()); 0086 focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat()); 0087 } 0088 0089 arrowKeyPressed = true; 0090 slewing = true; 0091 break; 0092 0093 case Qt::Key_Right: 0094 if (Options::useAltAz()) 0095 { 0096 focus()->setAz(dms(focus()->az().Degrees() + step * MINZOOM / Options::zoomFactor()).reduce()); 0097 focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat()); 0098 } 0099 else 0100 { 0101 focus()->setRA(focus()->ra().Hours() - 0.05 * step * MINZOOM / Options::zoomFactor()); 0102 focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat()); 0103 } 0104 0105 arrowKeyPressed = true; 0106 slewing = true; 0107 break; 0108 0109 case Qt::Key_Up: 0110 if (Options::useAltAz()) 0111 { 0112 focus()->setAltRefracted(focus()->altRefracted().Degrees() + step * MINZOOM / Options::zoomFactor()); 0113 if (focus()->alt().Degrees() > 90.0) 0114 focus()->setAlt(90.0); 0115 focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat()); 0116 } 0117 else 0118 { 0119 focus()->setDec(focus()->dec().Degrees() + step * MINZOOM / Options::zoomFactor()); 0120 if (focus()->dec().Degrees() > 90.0) 0121 focus()->setDec(90.0); 0122 focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat()); 0123 } 0124 0125 arrowKeyPressed = true; 0126 slewing = true; 0127 break; 0128 0129 case Qt::Key_Down: 0130 if (Options::useAltAz()) 0131 { 0132 focus()->setAltRefracted(focus()->altRefracted().Degrees() - step * MINZOOM / Options::zoomFactor()); 0133 if (focus()->alt().Degrees() < -90.0) 0134 focus()->setAlt(-90.0); 0135 focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat()); 0136 } 0137 else 0138 { 0139 focus()->setDec(focus()->dec().Degrees() - step * MINZOOM / Options::zoomFactor()); 0140 if (focus()->dec().Degrees() < -90.0) 0141 focus()->setDec(-90.0); 0142 focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat()); 0143 } 0144 0145 arrowKeyPressed = true; 0146 slewing = true; 0147 break; 0148 0149 case Qt::Key_Plus: //Zoom in 0150 case Qt::Key_Equal: 0151 zoomInOrMagStep(e->modifiers()); 0152 break; 0153 0154 case Qt::Key_Minus: //Zoom out 0155 case Qt::Key_Underscore: 0156 zoomOutOrMagStep(e->modifiers()); 0157 break; 0158 0159 case Qt::Key_0: //center on Sun 0160 setClickedObject(data->skyComposite()->planet(KSPlanetBase::SUN)); 0161 setClickedPoint(clickedObject()); 0162 slotCenter(); 0163 break; 0164 0165 case Qt::Key_1: //center on Mercury 0166 setClickedObject(data->skyComposite()->planet(KSPlanetBase::MERCURY)); 0167 setClickedPoint(clickedObject()); 0168 slotCenter(); 0169 break; 0170 0171 case Qt::Key_2: //center on Venus 0172 setClickedObject(data->skyComposite()->planet(KSPlanetBase::VENUS)); 0173 setClickedPoint(clickedObject()); 0174 slotCenter(); 0175 break; 0176 0177 case Qt::Key_3: //center on Moon 0178 setClickedObject(data->skyComposite()->planet(KSPlanetBase::MOON)); 0179 setClickedPoint(clickedObject()); 0180 slotCenter(); 0181 break; 0182 0183 case Qt::Key_4: //center on Mars 0184 setClickedObject(data->skyComposite()->planet(KSPlanetBase::MARS)); 0185 setClickedPoint(clickedObject()); 0186 slotCenter(); 0187 break; 0188 0189 case Qt::Key_5: //center on Jupiter 0190 setClickedObject(data->skyComposite()->planet(KSPlanetBase::JUPITER)); 0191 setClickedPoint(clickedObject()); 0192 slotCenter(); 0193 break; 0194 0195 case Qt::Key_6: //center on Saturn 0196 setClickedObject(data->skyComposite()->planet(KSPlanetBase::SATURN)); 0197 setClickedPoint(clickedObject()); 0198 slotCenter(); 0199 break; 0200 0201 case Qt::Key_7: //center on Uranus 0202 setClickedObject(data->skyComposite()->planet(KSPlanetBase::URANUS)); 0203 setClickedPoint(clickedObject()); 0204 slotCenter(); 0205 break; 0206 0207 case Qt::Key_8: //center on Neptune 0208 setClickedObject(data->skyComposite()->planet(KSPlanetBase::NEPTUNE)); 0209 setClickedPoint(clickedObject()); 0210 slotCenter(); 0211 break; 0212 0213 /*case Qt::Key_9: //center on Pluto 0214 setClickedObject( data->skyComposite()->planet( KSPlanetBase::PLUTO ) ); 0215 setClickedPoint( clickedObject() ); 0216 slotCenter(); 0217 break;*/ 0218 0219 case Qt::Key_BracketLeft: // Begin measuring angular distance 0220 if (!rulerMode) 0221 slotBeginAngularDistance(); 0222 break; 0223 case Qt::Key_Escape: // Cancel angular distance measurement 0224 { 0225 if (rulerMode) 0226 slotCancelRulerMode(); 0227 0228 if (m_fovCaptureMode) 0229 slotFinishFovCaptureMode(); 0230 break; 0231 } 0232 0233 case Qt::Key_C: //Center clicked object 0234 if (clickedObject()) 0235 slotCenter(); 0236 break; 0237 0238 case Qt::Key_D: //Details window for Clicked/Centered object 0239 { 0240 SkyObject *orig = nullptr; 0241 if (shiftPressed) 0242 { 0243 orig = clickedObject(); 0244 setClickedObject(focusObject()); 0245 } 0246 0247 if (clickedObject()) 0248 { 0249 slotDetail(); 0250 } 0251 0252 if (orig) 0253 { 0254 setClickedObject(orig); 0255 } 0256 break; 0257 } 0258 0259 case Qt::Key_P: //Show Popup menu for Clicked/Centered object 0260 if (shiftPressed) 0261 { 0262 if (focusObject()) 0263 focusObject()->showPopupMenu(pmenu, QCursor::pos()); 0264 } 0265 else 0266 { 0267 if (clickedObject()) 0268 clickedObject()->showPopupMenu(pmenu, QCursor::pos()); 0269 } 0270 break; 0271 0272 case Qt::Key_O: //Add object to Observing List 0273 { 0274 SkyObject *orig = nullptr; 0275 if (shiftPressed) 0276 { 0277 orig = clickedObject(); 0278 setClickedObject(focusObject()); 0279 } 0280 0281 if (clickedObject()) 0282 { 0283 data->observingList()->slotAddObject(); 0284 } 0285 0286 if (orig) 0287 { 0288 setClickedObject(orig); 0289 } 0290 break; 0291 } 0292 0293 case Qt::Key_L: //Toggle User label on Clicked/Centered object 0294 { 0295 SkyObject *orig = nullptr; 0296 if (shiftPressed) 0297 { 0298 orig = clickedObject(); 0299 setClickedObject(focusObject()); 0300 } 0301 0302 if (clickedObject()) 0303 { 0304 if (isObjectLabeled(clickedObject())) 0305 slotRemoveObjectLabel(); 0306 else 0307 slotAddObjectLabel(); 0308 } 0309 0310 if (orig) 0311 { 0312 setClickedObject(orig); 0313 } 0314 break; 0315 } 0316 0317 case Qt::Key_T: //Toggle planet trail on Clicked/Centered object (if solsys) 0318 { 0319 SkyObject *orig = nullptr; 0320 if (shiftPressed) 0321 { 0322 orig = clickedObject(); 0323 setClickedObject(focusObject()); 0324 } 0325 0326 KSPlanetBase *planet = dynamic_cast<KSPlanetBase *>(clickedObject()); 0327 if (planet) 0328 { 0329 if (planet->hasTrail()) 0330 slotRemovePlanetTrail(); 0331 else 0332 slotAddPlanetTrail(); 0333 } 0334 0335 if (orig) 0336 { 0337 setClickedObject(orig); 0338 } 0339 break; 0340 } 0341 0342 case Qt::Key_R: 0343 { 0344 // Toggle relativistic corrections 0345 Options::setUseRelativistic(!Options::useRelativistic()); 0346 qDebug() << Q_FUNC_INFO << "Relativistic corrections: " << Options::useRelativistic(); 0347 forceUpdate(); 0348 break; 0349 } 0350 0351 case Qt::Key_A: 0352 Options::setUseAntialias(!Options::useAntialias()); 0353 qDebug() << Q_FUNC_INFO << "Use Antialiasing: " << Options::useAntialias(); 0354 forceUpdate(); 0355 break; 0356 0357 case Qt::Key_K: 0358 { 0359 if (m_fovCaptureMode) 0360 slotCaptureFov(); 0361 break; 0362 } 0363 0364 case Qt::Key_PageUp: 0365 { 0366 KStars::Instance()->selectPreviousFov(); 0367 break; 0368 } 0369 0370 case Qt::Key_PageDown: 0371 { 0372 KStars::Instance()->selectNextFov(); 0373 break; 0374 } 0375 0376 default: 0377 // We don't want to do anything in this case. Key is unknown 0378 return; 0379 } 0380 0381 if (arrowKeyPressed) 0382 { 0383 stopTracking(); 0384 setDestination(*focus()); 0385 } 0386 0387 forceUpdate(); //need a total update, or slewing with the arrow keys doesn't work. 0388 } 0389 0390 void SkyMap::stopTracking() 0391 { 0392 KStars *kstars = KStars::Instance(); 0393 0394 emit positionChanged(focus()); 0395 if (kstars && Options::isTracking()) 0396 kstars->slotTrack(); 0397 } 0398 0399 bool SkyMap::event(QEvent *event) 0400 { 0401 #if !defined(KSTARS_LITE) 0402 if (event->type() == QEvent::TouchBegin) 0403 { 0404 m_touchMode = true; 0405 m_pinchScale = -1; 0406 } 0407 0408 if (event->type() == QEvent::Gesture && m_touchMode) 0409 { 0410 QGestureEvent* gestureEvent = static_cast<QGestureEvent*>(event); 0411 0412 if (QPinchGesture *pinch = static_cast<QPinchGesture*>(gestureEvent->gesture(Qt::PinchGesture))) 0413 { 0414 QPinchGesture::ChangeFlags changeFlags = pinch->changeFlags(); 0415 0416 m_pinchMode = true; 0417 if (changeFlags & QPinchGesture::ScaleFactorChanged) 0418 { 0419 if (m_pinchScale == -1) 0420 { 0421 m_pinchScale = pinch->totalScaleFactor(); 0422 return true; 0423 } 0424 if (pinch->totalScaleFactor() - m_pinchScale > 0.1) 0425 { 0426 m_pinchScale = pinch->totalScaleFactor(); 0427 zoomInOrMagStep(0); 0428 return true; 0429 } 0430 if (pinch->totalScaleFactor() - m_pinchScale < -0.1) 0431 { 0432 m_pinchScale = pinch->totalScaleFactor(); 0433 zoomOutOrMagStep(0); 0434 return true; 0435 } 0436 } 0437 } 0438 if (QTapAndHoldGesture *tapAndHold = static_cast<QTapAndHoldGesture*>(gestureEvent->gesture(Qt::TapAndHoldGesture))) 0439 { 0440 m_tapAndHoldMode = true; 0441 if (tapAndHold->state() == Qt::GestureFinished) 0442 { 0443 if (clickedObject()) 0444 { 0445 clickedObject()->showPopupMenu(pmenu, tapAndHold->position().toPoint()); 0446 } 0447 else 0448 { 0449 pmenu->createEmptyMenu(clickedPoint()); 0450 pmenu->popup(tapAndHold->position().toPoint()); 0451 } 0452 m_touchMode = false; 0453 m_pinchMode = false; 0454 m_tapAndHoldMode = false; 0455 } 0456 } 0457 return true; 0458 } 0459 #endif 0460 return QGraphicsView::event(event); 0461 } 0462 0463 void SkyMap::keyReleaseEvent(QKeyEvent *e) 0464 { 0465 switch (e->key()) 0466 { 0467 case Qt::Key_Plus: //Zoom in 0468 case Qt::Key_Equal: 0469 case Qt::Key_Minus: //Zoom out 0470 case Qt::Key_Underscore: 0471 0472 case Qt::Key_Left: //no break; continue to Qt::Key_Down 0473 case Qt::Key_Right: //no break; continue to Qt::Key_Down 0474 case Qt::Key_Up: //no break; continue to Qt::Key_Down 0475 case Qt::Key_Down: 0476 slewing = false; 0477 0478 if (Options::useAltAz()) 0479 setDestinationAltAz(focus()->alt(), focus()->az(), false); 0480 else 0481 setDestination(*focus()); 0482 0483 showFocusCoords(); 0484 forceUpdate(); // Need a full update to draw faint objects that are not drawn while slewing. 0485 break; 0486 } 0487 } 0488 0489 void SkyMap::mouseMoveEvent(QMouseEvent *e) 0490 { 0491 #if !defined(KSTARS_LITE) 0492 // Skip touch points 0493 if (m_pinchMode || m_tapAndHoldMode || (m_touchMode && e->globalX() == 0 && e->globalY() == 0)) 0494 return; 0495 #endif 0496 0497 if (Options::useHoverLabel()) 0498 { 0499 //Start a single-shot timer to monitor whether we are currently hovering. 0500 //The idea is that whenever a moveEvent occurs, the timer is reset. It 0501 //will only timeout if there are no move events for HOVER_INTERVAL ms 0502 m_HoverTimer.start(HOVER_INTERVAL); 0503 QToolTip::hideText(); 0504 } 0505 0506 //Are we defining a ZoomRect? 0507 if (ZoomRect.center().x() > 0 && ZoomRect.center().y() > 0) 0508 { 0509 //cancel operation if the user let go of CTRL 0510 if (!(e->modifiers() & Qt::ControlModifier)) 0511 { 0512 ZoomRect = QRect(); //invalidate ZoomRect 0513 update(); 0514 } 0515 else 0516 { 0517 //Resize the rectangle so that it passes through the cursor position 0518 QPoint pcenter = ZoomRect.center(); 0519 int dx = abs(e->x() - pcenter.x()); 0520 int dy = abs(e->y() - pcenter.y()); 0521 if (dx == 0 || float(dy) / float(dx) > float(height()) / float(width())) 0522 { 0523 //Size rect by height 0524 ZoomRect.setHeight(2 * dy); 0525 ZoomRect.setWidth(2 * dy * width() / height()); 0526 } 0527 else 0528 { 0529 //Size rect by height 0530 ZoomRect.setWidth(2 * dx); 0531 ZoomRect.setHeight(2 * dx * height() / width()); 0532 } 0533 ZoomRect.moveCenter(pcenter); //reset center 0534 0535 update(); 0536 return; 0537 } 0538 } 0539 0540 if (projector()->unusablePoint(e->pos())) 0541 return; // break if point is unusable 0542 0543 //determine RA, Dec of mouse pointer 0544 m_MousePoint = projector()->fromScreen(e->pos(), data->lst(), data->geo()->lat()); 0545 0546 double dyPix = 0.5 * height() - e->y(); 0547 if (midMouseButtonDown) //zoom according to y-offset 0548 { 0549 float yoff = dyPix - y0; 0550 if (yoff > 10) 0551 { 0552 y0 = dyPix; 0553 slotZoomIn(); 0554 } 0555 if (yoff < -10) 0556 { 0557 y0 = dyPix; 0558 slotZoomOut(); 0559 } 0560 } 0561 0562 if (mouseButtonDown) 0563 { 0564 #ifdef HAVE_INDI 0565 if (Options::showMosaicPanel()) 0566 { 0567 auto tiles = KStarsData::Instance()->skyComposite()->mosaicComponent()->tiles(); 0568 0569 if (tiles->operationMode() == MosaicTiles::MODE_PLANNING) 0570 { 0571 // Check if mouse point within Mosaic FOV bounds. 0572 auto mosaicFOV = tiles->mosaicFOV(); 0573 auto upperRA = tiles->ra0().Degrees() + mosaicFOV.width() / 60; 0574 auto lowerRA = tiles->ra0().Degrees() - mosaicFOV.width() / 60; 0575 auto upperDE = tiles->dec0().Degrees() + mosaicFOV.height() / 60; 0576 auto lowerDE = tiles->dec0().Degrees() - mosaicFOV.height() / 60; 0577 0578 auto mouseRA = m_MousePoint.ra().Degrees(); 0579 auto mouseDE = m_MousePoint.dec().Degrees(); 0580 0581 // If mouse point is within, then behave like drag and drop 0582 if (mouseRA > lowerRA && mouseRA < upperRA && mouseDE > lowerDE && mouseDE < upperDE) 0583 { 0584 if (!mouseDragCursor) 0585 setMouseDragCursor(); 0586 0587 dms dRA = m_MousePoint.ra() - clickedPoint()->ra(); 0588 dms dDec = m_MousePoint.dec() - clickedPoint()->dec(); 0589 0590 // Emit difference between mouse point and clicked point. 0591 emit mosaicCenterChanged(dRA, dDec); 0592 0593 // Update mouse and clicked points. 0594 m_MousePoint = projector()->fromScreen(e->pos(), data->lst(), data->geo()->lat()); 0595 setClickedPoint(&m_MousePoint); 0596 update(); 0597 return; 0598 } 0599 } 0600 } 0601 #endif 0602 0603 // set the mouseMoveCursor and set slewing=true, if they are not set yet 0604 if (!mouseMoveCursor) 0605 setMouseMoveCursor(); 0606 if (!slewing) 0607 { 0608 slewing = true; 0609 stopTracking(); //toggle tracking off 0610 } 0611 0612 //Update focus such that the sky coords at mouse cursor remain approximately constant 0613 if (Options::useAltAz()) 0614 { 0615 m_MousePoint.EquatorialToHorizontal(data->lst(), data->geo()->lat()); 0616 clickedPoint()->EquatorialToHorizontal(data->lst(), data->geo()->lat()); 0617 dms dAz = m_MousePoint.az() - clickedPoint()->az(); 0618 dms dAlt = m_MousePoint.altRefracted() - clickedPoint()->altRefracted(); 0619 focus()->setAz(focus()->az().Degrees() - dAz.Degrees()); //move focus in opposite direction 0620 focus()->setAz(focus()->az().reduce()); 0621 focus()->setAltRefracted(KSUtils::clamp(focus()->altRefracted().Degrees() - dAlt.Degrees(), -90.0, 90.0)); 0622 focus()->HorizontalToEquatorial(data->lst(), data->geo()->lat()); 0623 } 0624 else 0625 { 0626 dms dRA = m_MousePoint.ra() - clickedPoint()->ra(); 0627 dms dDec = m_MousePoint.dec() - clickedPoint()->dec(); 0628 focus()->setRA(focus()->ra().Hours() - dRA.Hours()); //move focus in opposite direction 0629 focus()->setRA(focus()->ra().reduce()); 0630 focus()->setDec(KSUtils::clamp(focus()->dec().Degrees() - dDec.Degrees(), -90.0, 90.0)); 0631 focus()->EquatorialToHorizontal(data->lst(), data->geo()->lat()); 0632 } 0633 showFocusCoords(); 0634 0635 //redetermine RA, Dec of mouse pointer, using new focus 0636 m_MousePoint = projector()->fromScreen(e->pos(), data->lst(), data->geo()->lat()); 0637 setClickedPoint(&m_MousePoint); 0638 forceUpdate(); // must be new computed 0639 } 0640 else //mouse button not down 0641 { 0642 if (Options::useAltAz()) 0643 m_MousePoint.EquatorialToHorizontal(data->lst(), data->geo()->lat()); 0644 emit mousePointChanged(&m_MousePoint); 0645 } 0646 } 0647 0648 void SkyMap::wheelEvent(QWheelEvent *e) 0649 { 0650 if (e->angleDelta().y() > 0) 0651 zoomInOrMagStep(e->modifiers()); 0652 else if (e->angleDelta().y() < 0) 0653 zoomOutOrMagStep(e->modifiers()); 0654 } 0655 0656 void SkyMap::mouseReleaseEvent(QMouseEvent *e) 0657 { 0658 #if !defined(KSTARS_LITE) 0659 if (m_touchMode) 0660 { 0661 m_touchMode = false; 0662 m_pinchMode = false; 0663 m_tapAndHoldMode = false; 0664 } 0665 #endif 0666 0667 if (ZoomRect.isValid()) 0668 { 0669 stopTracking(); 0670 SkyPoint newcenter = projector()->fromScreen(ZoomRect.center(), data->lst(), data->geo()->lat()); 0671 setFocus(&newcenter); 0672 setDestination(newcenter); 0673 0674 //Zoom in on center of Zoom Circle, by a factor equal to the ratio 0675 //of the sky pixmap's width to the Zoom Circle's diameter 0676 float factor = float(width()) / float(ZoomRect.width()); 0677 setZoomFactor(Options::zoomFactor() * factor); 0678 } 0679 0680 setMouseCursorShape(static_cast<Cursor>(Options::defaultCursor())); 0681 0682 ZoomRect = QRect(); //invalidate ZoomRect 0683 0684 if (m_previewLegend) 0685 { 0686 slotCancelLegendPreviewMode(); 0687 } 0688 0689 //false if double-clicked, because it's unset there. 0690 if (mouseButtonDown) 0691 { 0692 mouseButtonDown = false; 0693 if (slewing) 0694 { 0695 slewing = false; 0696 if (Options::useAltAz()) 0697 setDestinationAltAz(focus()->alt(), focus()->az(), false); 0698 else 0699 setDestination(*focus()); 0700 } 0701 else if (Options::leftClickSelectsObject()) 0702 mouseDoubleClickEvent(e); 0703 forceUpdate(); // is needed because after moving the sky not all stars are shown 0704 } 0705 // if middle button was pressed unset here 0706 midMouseButtonDown = false; 0707 } 0708 0709 void SkyMap::mousePressEvent(QMouseEvent *e) 0710 { 0711 KStars *kstars = KStars::Instance(); 0712 0713 if ((e->modifiers() & Qt::ControlModifier) && (e->button() == Qt::LeftButton)) 0714 { 0715 ZoomRect.moveCenter(e->pos()); 0716 setZoomMouseCursor(); 0717 update(); //refresh without redrawing skymap 0718 return; 0719 } 0720 0721 // if button is down and cursor is not moved set the move cursor after 500 ms 0722 //QTimer::singleShot(500, this, SLOT(setMouseMoveCursor())); 0723 0724 // break if point is unusable 0725 if (projector()->unusablePoint(e->pos())) 0726 return; 0727 0728 if (!midMouseButtonDown && e->button() == Qt::MidButton) 0729 { 0730 y0 = 0.5 * height() - e->y(); //record y pixel coordinate for middle-button zooming 0731 midMouseButtonDown = true; 0732 } 0733 0734 if (!mouseButtonDown) 0735 { 0736 if (e->button() == Qt::LeftButton) 0737 { 0738 mouseButtonDown = true; 0739 } 0740 0741 //determine RA, Dec of mouse pointer 0742 m_MousePoint = projector()->fromScreen(e->pos(), data->lst(), data->geo()->lat()); 0743 setClickedPoint(&m_MousePoint); 0744 0745 //Find object nearest to clickedPoint() 0746 double maxrad = 5000.0 / Options::zoomFactor(); 0747 SkyObject *obj = data->skyComposite()->objectNearest(clickedPoint(), maxrad); 0748 setClickedObject(obj); 0749 if (obj) 0750 setClickedPoint(obj); 0751 0752 switch (e->button()) 0753 { 0754 case Qt::LeftButton: 0755 { 0756 QString name; 0757 if (clickedObject()) 0758 { 0759 name = clickedObject()->translatedLongName(); 0760 emit objectClicked(clickedObject()); 0761 } 0762 else 0763 name = i18n("Empty sky"); 0764 //kstars->statusBar()->changeItem(name, 0 ); 0765 kstars->statusBar()->showMessage(name, 0); 0766 0767 emit positionClicked(&m_MousePoint); 0768 } 0769 0770 break; 0771 case Qt::RightButton: 0772 if (rulerMode) 0773 { 0774 // Compute angular distance. 0775 slotEndRulerMode(); 0776 } 0777 else 0778 { 0779 // Show popup menu 0780 if (clickedObject()) 0781 { 0782 clickedObject()->showPopupMenu(pmenu, QCursor::pos()); 0783 } 0784 else 0785 { 0786 pmenu->createEmptyMenu(clickedPoint()); 0787 pmenu->popup(QCursor::pos()); 0788 } 0789 } 0790 break; 0791 default: 0792 ; 0793 } 0794 } 0795 } 0796 0797 void SkyMap::mouseDoubleClickEvent(QMouseEvent *e) 0798 { 0799 if (e->button() == Qt::LeftButton && !projector()->unusablePoint(e->pos())) 0800 { 0801 mouseButtonDown = false; 0802 if (e->x() != width() / 2 || e->y() != height() / 2) 0803 slotCenter(); 0804 } 0805 } 0806 0807 double SkyMap::zoomFactor(const int modifier) 0808 { 0809 double factor = (modifier & Qt::ControlModifier) ? DZOOM : (Options::zoomScrollFactor() + 1); 0810 if (modifier & Qt::ShiftModifier) 0811 factor = sqrt(factor); 0812 return factor; 0813 } 0814 0815 void SkyMap::zoomInOrMagStep(const int modifier) 0816 { 0817 if (modifier & Qt::AltModifier) 0818 incMagLimit(modifier); 0819 else 0820 setZoomFactor(Options::zoomFactor() * zoomFactor(modifier)); 0821 } 0822 0823 void SkyMap::zoomOutOrMagStep(const int modifier) 0824 { 0825 if (modifier & Qt::AltModifier) 0826 decMagLimit(modifier); 0827 else 0828 setZoomFactor(Options::zoomFactor() / zoomFactor(modifier)); 0829 } 0830 0831 double SkyMap::magFactor(const int modifier) 0832 { 0833 double factor = (modifier & Qt::ControlModifier) ? 0.1 : 0.5; 0834 if (modifier & Qt::ShiftModifier) 0835 factor *= 2.0; 0836 return factor; 0837 } 0838 0839 void SkyMap::incMagLimit(const int modifier) 0840 { 0841 double limit = 2.222 * log10(static_cast<double>(Options::starDensity())) + 0.35; 0842 limit += magFactor(modifier); 0843 if (limit > 5.75954) 0844 limit = 5.75954; 0845 Options::setStarDensity(pow(10, (limit - 0.35) / 2.222)); 0846 //printf("maglim set to %3.1f\n", limit); 0847 forceUpdate(); 0848 } 0849 0850 void SkyMap::decMagLimit(const int modifier) 0851 { 0852 double limit = 2.222 * log10(static_cast<double>(Options::starDensity())) + 0.35; 0853 limit -= magFactor(modifier); 0854 if (limit < 1.18778) 0855 limit = 1.18778; 0856 Options::setStarDensity(pow(10, (limit - 0.35) / 2.222)); 0857 //printf("maglim set to %3.1f\n", limit); 0858 forceUpdate(); 0859 }