00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <kapplication.h>
00019 #include <kconfig.h>
00020 #include <kiconloader.h>
00021 #include <kstatusbar.h>
00022 #include <kmessagebox.h>
00023 #include <kaction.h>
00024 #include <kstandarddirs.h>
00025
00026 #include <qmemarray.h>
00027 #include <qpointarray.h>
00028 #include <qcursor.h>
00029 #include <qbitmap.h>
00030 #include <qpainter.h>
00031
00032 #include <math.h>
00033 #include <stdlib.h>
00034 #include <unistd.h>
00035
00036 #include "skymap.h"
00037 #include "Options.h"
00038 #include "kstars.h"
00039 #include "kstarsdata.h"
00040 #include "imageviewer.h"
00041 #include "infoboxes.h"
00042 #include "detaildialog.h"
00043 #include "addlinkdialog.h"
00044 #include "kspopupmenu.h"
00045 #include "simclock.h"
00046 #include "skyobject.h"
00047 #include "deepskyobject.h"
00048 #include "ksmoon.h"
00049 #include "ksasteroid.h"
00050 #include "kscomet.h"
00051 #include "starobject.h"
00052 #include "customcatalog.h"
00053
00054 SkyMap::SkyMap(KStarsData *d, QWidget *parent, const char *name )
00055 : QWidget (parent,name), computeSkymap(true), angularDistanceMode(false),
00056 ksw(0), data(d), pmenu(0), sky(0), sky2(0), IBoxes(0),
00057 ClickedObject(0), FocusObject(0), TransientObject(0),
00058 starpix(0), pts(0), sp(0)
00059 {
00060 if ( parent ) ksw = (KStars*) parent->parent();
00061 else ksw = 0;
00062
00063 pts = new QPointArray( 2000 );
00064 sp = new SkyPoint();
00065
00066 ZoomRect = QRect();
00067
00068 setDefaultMouseCursor();
00069
00070
00071 starpix = new StarPixmap( data->colorScheme()->starColorMode(), data->colorScheme()->starColorIntensity() );
00072
00073 setBackgroundColor( QColor( data->colorScheme()->colorNamed( "SkyColor" ) ) );
00074 setBackgroundMode( QWidget::NoBackground );
00075 setFocusPolicy( QWidget::StrongFocus );
00076 setMinimumSize( 380, 250 );
00077 setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding ) );
00078
00079 setMouseTracking (true);
00080 midMouseButtonDown = false;
00081 mouseButtonDown = false;
00082 slewing = false;
00083 clockSlewing = false;
00084
00085 ClickedObject = NULL;
00086 FocusObject = NULL;
00087
00088 sky = new QPixmap();
00089 sky2 = new QPixmap();
00090 pmenu = new KSPopupMenu( ksw );
00091
00092
00093 TransientTimeout = 100;
00094 connect( &HoverTimer, SIGNAL( timeout() ), this, SLOT( slotTransientLabel() ) );
00095 connect( &TransientTimer, SIGNAL( timeout() ), this, SLOT( slotTransientTimeout() ) );
00096
00097 IBoxes = new InfoBoxes( Options::windowWidth(), Options::windowHeight(),
00098 Options::positionTimeBox(), Options::shadeTimeBox(),
00099 Options::positionGeoBox(), Options::shadeGeoBox(),
00100 Options::positionFocusBox(), Options::shadeFocusBox(),
00101 data->colorScheme()->colorNamed( "BoxTextColor" ),
00102 data->colorScheme()->colorNamed( "BoxGrabColor" ),
00103 data->colorScheme()->colorNamed( "BoxBGColor" ) );
00104
00105 IBoxes->showTimeBox( Options::showTimeBox() );
00106 IBoxes->showFocusBox( Options::showFocusBox() );
00107 IBoxes->showGeoBox( Options::showGeoBox() );
00108 IBoxes->timeBox()->setAnchorFlag( Options::stickyTimeBox() );
00109 IBoxes->geoBox()->setAnchorFlag( Options::stickyGeoBox() );
00110 IBoxes->focusBox()->setAnchorFlag( Options::stickyFocusBox() );
00111
00112 IBoxes->geoChanged( data->geo() );
00113
00114 connect( IBoxes->timeBox(), SIGNAL( shaded(bool) ), data, SLOT( saveTimeBoxShaded(bool) ) );
00115 connect( IBoxes->geoBox(), SIGNAL( shaded(bool) ), data, SLOT( saveGeoBoxShaded(bool) ) );
00116 connect( IBoxes->focusBox(), SIGNAL( shaded(bool) ), data, SLOT( saveFocusBoxShaded(bool) ) );
00117 connect( IBoxes->timeBox(), SIGNAL( moved(QPoint) ), data, SLOT( saveTimeBoxPos(QPoint) ) );
00118 connect( IBoxes->geoBox(), SIGNAL( moved(QPoint) ), data, SLOT( saveGeoBoxPos(QPoint) ) );
00119 connect( IBoxes->focusBox(), SIGNAL( moved(QPoint) ), data, SLOT( saveFocusBoxPos(QPoint) ) );
00120
00121 connect( this, SIGNAL( destinationChanged() ), this, SLOT( slewFocus() ) );
00122
00123
00124
00125 for ( unsigned int index = 0; index <184; ++index ) {
00126 double alt = -1.75 + index*0.5;
00127
00128 RefractCorr1[index] = 1.02 / tan( dms::PI*( alt + 10.3/(alt + 5.11) )/180.0 ) / 60.0;
00129 RefractCorr2[index] = -1.0 / tan( dms::PI*( alt + 7.31/(alt + 4.4) )/180.0 ) / 60.0;
00130 }
00131 }
00132
00133 SkyMap::~SkyMap() {
00134 delete starpix;
00135 delete pts;
00136 delete sp;
00137 delete sky;
00138 delete sky2;
00139 delete pmenu;
00140 delete IBoxes;
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156 }
00157
00158 void SkyMap::setGeometry( int x, int y, int w, int h ) {
00159 QWidget::setGeometry( x, y, w, h );
00160 sky->resize( w, h );
00161 sky2->resize( w, h );
00162 }
00163
00164 void SkyMap::setGeometry( const QRect &r ) {
00165 QWidget::setGeometry( r );
00166 sky->resize( r.width(), r.height() );
00167 sky2->resize( r.width(), r.height() );
00168 }
00169
00170
00171 void SkyMap::showFocusCoords( bool coordsOnly ) {
00172 if ( ! coordsOnly ) {
00173
00174 QString oname;
00175 oname = i18n( "nothing" );
00176 if ( focusObject() != NULL && Options::isTracking() )
00177 oname = focusObject()->translatedLongName();
00178
00179 infoBoxes()->focusObjChanged(oname);
00180 }
00181
00182 if ( Options::useAltAz() && Options::useRefraction() ) {
00183 SkyPoint corrFocus( *(focus()) );
00184 corrFocus.setAlt( refract( focus()->alt(), false ) );
00185 corrFocus.HorizontalToEquatorial( data->LST, data->geo()->lat() );
00186 corrFocus.setAlt( refract( focus()->alt(), true ) );
00187 infoBoxes()->focusCoordChanged( &corrFocus );
00188 } else {
00189 infoBoxes()->focusCoordChanged( focus() );
00190 }
00191 }
00192
00193 SkyObject* SkyMap::objectNearest( SkyPoint *p ) {
00194 double r0 = 200.0/Options::zoomFactor();
00195 double rmin = r0;
00196
00197
00198 double rstar_min = r0;
00199 double starmag_min = 20.0;
00200 int istar_min = -1;
00201
00202 if ( Options::showStars() ) {
00203
00204
00205
00206 for ( register unsigned int i=0; i<data->starList.count(); ++i ) {
00207 SkyObject *test = (SkyObject *)data->starList.at(i);
00208
00209 double dRA = test->ra()->Hours() - p->ra()->Hours();
00210 double dDec = test->dec()->Degrees() - p->dec()->Degrees();
00211
00212 double f = 15.0*cos( test->dec()->radians() );
00213 double r = f*f*dRA*dRA + dDec*dDec;
00214 if (r < r0 && test->mag() < starmag_min ) {
00215 istar_min = i;
00216 rstar_min = r;
00217 starmag_min = test->mag();
00218 }
00219 }
00220 }
00221
00222
00223 double r = 0.0;
00224 double rsolar_min = r0;
00225 SkyObject *solarminobj = NULL;
00226
00227 if ( Options::showPlanets() )
00228 solarminobj = data->PCat->findClosest( p, r );
00229
00230 if ( r < r0 ) {
00231 rsolar_min = r;
00232 } else {
00233 solarminobj = NULL;
00234 }
00235
00236
00237 if ( Options::showMoon() ) {
00238 double dRA = data->Moon->ra()->Hours() - p->ra()->Hours();
00239 double dDec = data->Moon->dec()->Degrees() - p->dec()->Degrees();
00240 double f = 15.0*cos( data->Moon->dec()->radians() );
00241 r = f*f*dRA*dRA + dDec*dDec;
00242 if (r < rsolar_min) {
00243 solarminobj= data->Moon;
00244 rsolar_min = r;
00245 }
00246 }
00247
00248
00249 if ( Options::showAsteroids() ) {
00250 for ( KSAsteroid *ast = data->asteroidList.first(); ast; ast = data->asteroidList.next() ) {
00251
00252 double dRA = ast->ra()->Hours() - p->ra()->Hours();
00253 double dDec = ast->dec()->Degrees() - p->dec()->Degrees();
00254 double f = 15.0*cos( ast->dec()->radians() );
00255 double r = f*f*dRA*dRA + dDec*dDec;
00256 if ( r < rsolar_min && ast->mag() < Options::magLimitAsteroid() ) {
00257 solarminobj = ast;
00258 rsolar_min = r;
00259 }
00260 }
00261 }
00262
00263
00264 if ( Options::showComets() ) {
00265 for ( KSComet *com = data->cometList.first(); com; com = data->cometList.next() ) {
00266
00267 double dRA = com->ra()->Hours() - p->ra()->Hours();
00268 double dDec = com->dec()->Degrees() - p->dec()->Degrees();
00269 double f = 15.0*cos( com->dec()->radians() );
00270 double r = f*f*dRA*dRA + dDec*dDec;
00271 if ( r < rsolar_min ) {
00272 solarminobj = com;
00273 rsolar_min = r;
00274 }
00275 }
00276 }
00277
00278
00279 double rmess_min = r0;
00280 double rngc_min = r0;
00281 double ric_min = r0;
00282 double rother_min = r0;
00283 int imess_min = -1;
00284 int ingc_min = -1;
00285 int iic_min = -1;
00286 int iother_min = -1;
00287
00288 for ( DeepSkyObject *o = data->deepSkyList.first(); o; o = data->deepSkyList.next() ) {
00289 bool checkObject = false;
00290 if ( o->isCatalogM() &&
00291 ( Options::showMessier() || Options::showMessierImages() ) ) checkObject = true;
00292 if ( o->isCatalogNGC() && Options::showNGC() ) checkObject = true;
00293 if ( o->isCatalogIC() && Options::showIC() ) checkObject = true;
00294 if ( o->catalog().isEmpty() && Options::showOther() ) checkObject = true;
00295
00296 if ( checkObject ) {
00297
00298 double dRA = o->ra()->Hours() - p->ra()->Hours();
00299 double dDec = o->dec()->Degrees() - p->dec()->Degrees();
00300 double f = 15.0*cos( o->dec()->radians() );
00301 double r = f*f*dRA*dRA + dDec*dDec;
00302 if ( o->isCatalogM() && r < rmess_min) {
00303 imess_min = data->deepSkyList.at();
00304 rmess_min = r;
00305 }
00306 if ( o->isCatalogNGC() && r < rngc_min) {
00307 ingc_min = data->deepSkyList.at();
00308 rngc_min = r;
00309 }
00310 if ( o->isCatalogIC() && r < ric_min) {
00311 iic_min = data->deepSkyList.at();
00312 ric_min = r;
00313 }
00314 if ( o->catalog().isEmpty() && r < rother_min) {
00315 iother_min = data->deepSkyList.at();
00316 rother_min = r;
00317 }
00318 }
00319 }
00320
00321
00322 double rcust_min = r0;
00323 int icust_min = -1;
00324 int icust_cat = -1;
00325
00326 for ( register unsigned int j=0; j< data->CustomCatalogs.count(); ++j ) {
00327 if ( Options::showCatalog()[j] ) {
00328 QPtrList<SkyObject> catList = data->CustomCatalogs.at(j)->objList();
00329
00330 for ( register unsigned int i=0; i<catList.count(); ++i ) {
00331
00332 SkyObject *test = (SkyObject *)catList.at(i);
00333 double dRA = test->ra()->Hours()-p->ra()->Hours();
00334 double dDec = test->dec()->Degrees()-p->dec()->Degrees();
00335 double f = 15.0*cos( test->dec()->radians() );
00336 double r = f*f*dRA*dRA + dDec*dDec;
00337 if (r < rcust_min) {
00338 icust_cat = j;
00339 icust_min = i;
00340 rcust_min = r;
00341 }
00342 }
00343 }
00344 }
00345
00346 int jmin(-1);
00347 int icat(-1);
00348
00349
00350
00351 if ( istar_min >= 0 && rstar_min < r0 ) {
00352 rmin = rstar_min;
00353 icat = 0;
00354 }
00355
00356
00357 if ( iic_min >= 0 && ric_min < r0 && rmin > 0.5*ric_min ) {
00358 rmin = ric_min;
00359 icat = 1;
00360 jmin = iic_min;
00361 }
00362
00363
00364 if ( ingc_min >= 0 && rngc_min < r0 && rmin > 0.5*rngc_min ) {
00365 rmin = rngc_min;
00366 icat = 1;
00367 jmin = ingc_min;
00368 }
00369
00370
00371 if ( iother_min >= 0 && rother_min < r0 && rmin > 0.5*rother_min ) {
00372 rmin = rother_min;
00373 icat = 1;
00374 jmin = iother_min;
00375 }
00376
00377
00378 if ( imess_min >= 0 && rmess_min < r0 && rmin > 0.5*rmess_min ) {
00379 rmin = rmess_min;
00380 icat = 1;
00381 jmin = imess_min;
00382 }
00383
00384
00385 if ( icust_min >= 0 && rcust_min < r0 && rmin > 0.5*rcust_min ) {
00386 rmin = rcust_min;
00387 icat = 2;
00388 }
00389
00390
00391 if ( solarminobj != NULL && rmin > 0.5*rsolar_min ) {
00392 rmin = rsolar_min;
00393 icat = 3;
00394 }
00395
00396 QPtrList<SkyObject> cat;
00397
00398 switch (icat) {
00399 case 0:
00400 return data->starList.at(istar_min);
00401 break;
00402
00403 case 1:
00404 return data->deepSkyList.at(jmin);
00405 break;
00406
00407 case 2:
00408 cat = data->CustomCatalogs.at(icust_cat)->objList();
00409 return cat.at(icust_min);
00410 break;
00411
00412 case 3:
00413 return solarminobj;
00414 break;
00415
00416 default:
00417 return NULL;
00418 break;
00419 }
00420 }
00421
00422 void SkyMap::slotTransientLabel( void ) {
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 if ( ! slewing && ! ( Options::useAltAz() && Options::showGround() &&
00436 mousePoint()->alt()->Degrees() < 0.0 ) ) {
00437 SkyObject *so = objectNearest( mousePoint() );
00438
00439 if ( so && ! isObjectLabeled( so ) ) {
00440 setTransientObject( so );
00441
00442 TransientColor = data->colorScheme()->colorNamed( "UserLabelColor" );
00443 if ( TransientTimer.isActive() ) TransientTimer.stop();
00444 update();
00445 }
00446 }
00447 }
00448
00449
00450
00451
00452 void SkyMap::slotTransientTimeout( void ) {
00453
00454 if ( transientObject() == focusObject() && Options::useAutoLabel() ) {
00455 setTransientObject( NULL );
00456 TransientTimer.stop();
00457 return;
00458 }
00459
00460
00461 QColor c1 = data->colorScheme()->colorNamed( "UserLabelColor" );
00462 QColor c2 = data->colorScheme()->colorNamed( "SkyColor" );
00463
00464 int dRed = ( c2.red() - c1.red() )/20;
00465 int dGreen = ( c2.green() - c1.green() )/20;
00466 int dBlue = ( c2.blue() - c1.blue() )/20;
00467 int newRed = TransientColor.red() + dRed;
00468 int newGreen = TransientColor.green() + dGreen;
00469 int newBlue = TransientColor.blue() + dBlue;
00470
00471
00472
00473 if ( abs(newRed-c2.red()) < abs(dRed) || abs(newGreen-c2.green()) < abs(dGreen) || abs(newBlue-c2.blue()) < abs(dBlue) ) {
00474 setTransientObject( NULL );
00475 TransientTimer.stop();
00476 } else {
00477 TransientColor.setRgb( newRed, newGreen, newBlue );
00478 }
00479
00480 update();
00481 }
00482
00483 void SkyMap::setFocusObject( SkyObject *o ) {
00484 FocusObject = o;
00485
00486 if ( FocusObject )
00487 Options::setFocusObject( FocusObject->name() );
00488 else
00489 Options::setFocusObject( i18n( "nothing" ) );
00490 }
00491
00492 void SkyMap::slotCenter( void ) {
00493 setFocusPoint( clickedPoint() );
00494 if ( Options::useAltAz() )
00495 focusPoint()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00496
00497
00498 if ( focusObject() && focusObject()->isSolarSystem() && data->temporaryTrail ) {
00499 ((KSPlanetBase*)focusObject())->clearTrail();
00500 data->temporaryTrail = false;
00501 }
00502
00503
00504
00505 if ( Options::useAltAz() && Options::showGround() &&
00506 focus()->alt()->Degrees() > -1.0 && focusPoint()->alt()->Degrees() < -1.0 ) {
00507
00508 QString caption = i18n( "Requested Position Below Horizon" );
00509 QString message = i18n( "The requested position is below the horizon.\nWould you like to go there anyway?" );
00510 if ( KMessageBox::warningYesNo( this, message, caption,
00511 i18n("Go Anyway"), i18n("Keep Position"), "dag_focus_below_horiz" )==KMessageBox::No ) {
00512 setClickedObject( NULL );
00513 setFocusObject( NULL );
00514 Options::setIsTracking( false );
00515
00516 return;
00517 }
00518 }
00519
00520
00521
00522 setFocusObject( ClickedObject );
00523 Options::setIsTracking( true );
00524 if ( ksw ) {
00525 ksw->actionCollection()->action("track_object")->setIconSet( BarIcon( "encrypted" ) );
00526 ksw->toolBar( "mainToolBar" )->setButtonIconSet( 4, BarIcon( "encrypted" ) );
00527 ksw->actionCollection()->action("track_object")->setText( i18n( "Stop &Tracking" ) );
00528 }
00529
00530
00531 if ( focusObject() && focusObject()->isSolarSystem()
00532 && Options::useAutoTrail()
00533 && ! ((KSPlanetBase*)focusObject())->hasTrail() ) {
00534 ((KSPlanetBase*)focusObject())->addToTrail();
00535 data->temporaryTrail = true;
00536 }
00537
00538
00539 if ( Options::useAltAz() ) {
00540 if ( Options::useRefraction() )
00541 setDestinationAltAz( refract( focusPoint()->alt(), true ).Degrees(), focusPoint()->az()->Degrees() );
00542 else
00543 setDestinationAltAz( focusPoint()->alt()->Degrees(), focusPoint()->az()->Degrees() );
00544 } else {
00545 setDestination( focusPoint() );
00546 }
00547
00548 focusPoint()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00549
00550
00551 if ( ksw ) {
00552 QString sX = focusPoint()->az()->toDMSString();
00553 QString sY = focusPoint()->alt()->toDMSString(true);
00554 if ( Options::useAltAz() && Options::useRefraction() )
00555 sY = refract( focusPoint()->alt(), true ).toDMSString(true);
00556 QString s = sX + ", " + sY;
00557 ksw->statusBar()->changeItem( s, 1 );
00558 s = focusPoint()->ra()->toHMSString() + ", " + focusPoint()->dec()->toDMSString(true);
00559 ksw->statusBar()->changeItem( s, 2 );
00560 }
00561
00562 showFocusCoords();
00563 }
00564
00565 void SkyMap::slotDSS( void ) {
00566 QString URLprefix( "http://archive.stsci.edu/cgi-bin/dss_search?v=1" );
00567 QString URLsuffix( "&e=J2000&h=15.0&w=15.0&f=gif&c=none&fov=NONE" );
00568 dms ra(0.0), dec(0.0);
00569 QString RAString, DecString;
00570 char decsgn;
00571
00572
00573
00574 if ( clickedObject() ) {
00575 ra.setH( clickedObject()->ra0()->Hours() );
00576 dec.setD( clickedObject()->dec0()->Degrees() );
00577 } else {
00578
00579 clickedPoint()->setRA0( clickedPoint()->ra()->Hours() );
00580 clickedPoint()->setDec0( clickedPoint()->dec()->Degrees() );
00581 clickedPoint()->precessFromAnyEpoch( data->ut().djd(), J2000 );
00582 ra.setH( clickedPoint()->ra()->Hours() );
00583 dec.setD( clickedPoint()->dec()->Degrees() );
00584
00585
00586 clickedPoint()->setRA( clickedPoint()->ra0()->Hours() );
00587 clickedPoint()->setDec( clickedPoint()->dec0()->Degrees() );
00588 }
00589
00590 RAString = RAString.sprintf( "&r=%02d+%02d+%02d", ra.hour(), ra.minute(), ra.second() );
00591
00592 decsgn = '+';
00593 if ( dec.Degrees() < 0.0 ) decsgn = '-';
00594 int dd = abs( dec.degree() );
00595 int dm = abs( dec.arcmin() );
00596 int ds = abs( dec.arcsec() );
00597 DecString = DecString.sprintf( "&d=%c%02d+%02d+%02d", decsgn, dd, dm, ds );
00598
00599
00600 KURL url (URLprefix + RAString + DecString + URLsuffix);
00601
00602 QString message = i18n( "Digitized Sky Survey image provided by the Space Telescope Science Institute." );
00603 new ImageViewer (&url, message, this);
00604 }
00605
00606 void SkyMap::slotDSS2( void ) {
00607 QString URLprefix( "http://archive.stsci.edu/cgi-bin/dss_search?v=2r" );
00608 QString URLsuffix( "&e=J2000&h=15.0&w=15.0&f=gif&c=none&fov=NONE" );
00609 dms ra(0.0), dec(0.0);
00610 QString RAString, DecString;
00611 char decsgn;
00612
00613
00614
00615 if ( clickedObject() ) {
00616 ra.setH( clickedObject()->ra0()->Hours() );
00617 dec.setD( clickedObject()->dec0()->Degrees() );
00618 } else {
00619
00620 clickedPoint()->setRA0( clickedPoint()->ra()->Hours() );
00621 clickedPoint()->setDec0( clickedPoint()->dec()->Degrees() );
00622 clickedPoint()->precessFromAnyEpoch( data->ut().djd(), J2000 );
00623 ra.setH( clickedPoint()->ra()->Hours() );
00624 dec.setD( clickedPoint()->dec()->Degrees() );
00625
00626
00627 clickedPoint()->setRA( clickedPoint()->ra0()->Hours() );
00628 clickedPoint()->setDec( clickedPoint()->dec0()->Degrees() );
00629 }
00630
00631 RAString = RAString.sprintf( "&r=%02d+%02d+%02d", ra.hour(), ra.minute(), ra.second() );
00632
00633 decsgn = '+';
00634 if ( dec.Degrees() < 0.0 ) decsgn = '-';
00635 int dd = abs( dec.degree() );
00636 int dm = abs( dec.arcmin() );
00637 int ds = abs( dec.arcsec() );
00638
00639 DecString = DecString.sprintf( "&d=%c%02d+%02d+%02d", decsgn, dd, dm, ds );
00640
00641
00642 KURL url (URLprefix + RAString + DecString + URLsuffix);
00643
00644 QString message = i18n( "Digitized Sky Survey image provided by the Space Telescope Science Institute." );
00645 new ImageViewer (&url, message, this);
00646 }
00647
00648 void SkyMap::slotInfo( int id ) {
00649 QStringList::Iterator it = clickedObject()->InfoList.at(id-200);
00650 QString sURL = (*it);
00651 KURL url ( sURL );
00652 if (!url.isEmpty())
00653 kapp->invokeBrowser(sURL);
00654 }
00655
00656 void SkyMap::slotBeginAngularDistance(void) {
00657 setPreviousClickedPoint( mousePoint() );
00658 angularDistanceMode = true;
00659 beginRulerPoint = getXY( previousClickedPoint(), Options::useAltAz(), Options::useRefraction() );
00660 endRulerPoint = QPoint( beginRulerPoint.x(),beginRulerPoint.y() );
00661 }
00662
00663 void SkyMap::slotEndAngularDistance(void) {
00664 dms angularDistance;
00665 if(angularDistanceMode) {
00666 if ( SkyObject *so = objectNearest( mousePoint() ) ) {
00667 angularDistance = so->angularDistanceTo( previousClickedPoint() );
00668 ksw->statusBar()->changeItem( so->translatedLongName() +
00669 " " +
00670 i18n("Angular distance: " ) +
00671 angularDistance.toDMSString(), 0 );
00672 } else {
00673 angularDistance = mousePoint()->angularDistanceTo( previousClickedPoint() );
00674 ksw->statusBar()->changeItem( i18n("Angular distance: " ) +
00675 angularDistance.toDMSString(), 0 );
00676 }
00677 angularDistanceMode=false;
00678 }
00679 }
00680
00681 void SkyMap::slotCancelAngularDistance(void) {
00682 angularDistanceMode=false;
00683 }
00684
00685 void SkyMap::slotImage( int id ) {
00686 QStringList::Iterator it = clickedObject()->ImageList.at(id-100);
00687 QStringList::Iterator it2 = clickedObject()->ImageTitle.at(id-100);
00688 QString sURL = (*it);
00689 QString message = (*it2);
00690 KURL url ( sURL );
00691 if (!url.isEmpty())
00692 new ImageViewer (&url, clickedObject()->messageFromTitle(message), this);
00693 }
00694
00695 bool SkyMap::isObjectLabeled( SkyObject *object ) {
00696 for ( SkyObject *o = data->ObjLabelList.first(); o; o = data->ObjLabelList.next() ) {
00697 if ( o == object ) return true;
00698 }
00699
00700 return false;
00701 }
00702
00703 void SkyMap::slotRemoveObjectLabel( void ) {
00704 for ( SkyObject *o = data->ObjLabelList.first(); o; o = data->ObjLabelList.next() ) {
00705 if ( o == clickedObject() ) {
00706
00707 data->ObjLabelList.remove();
00708 break;
00709 }
00710 }
00711
00712 forceUpdate();
00713 }
00714
00715 void SkyMap::slotAddObjectLabel( void ) {
00716 data->ObjLabelList.append( clickedObject() );
00717
00718 if ( transientObject() == clickedObject() ) setTransientObject( NULL );
00719 forceUpdate();
00720 }
00721
00722 void SkyMap::slotRemovePlanetTrail( void ) {
00723
00724 if ( clickedObject() && clickedObject()->isSolarSystem() ) {
00725 ((KSPlanetBase*)clickedObject())->clearTrail();
00726 forceUpdate();
00727 }
00728 }
00729
00730 void SkyMap::slotAddPlanetTrail( void ) {
00731
00732 if ( clickedObject() && clickedObject()->isSolarSystem() ) {
00733 ((KSPlanetBase*)clickedObject())->addToTrail();
00734 forceUpdate();
00735 }
00736 }
00737
00738 void SkyMap::slotDetail( void ) {
00739
00740 if ( !clickedObject() ) {
00741 KMessageBox::sorry( this, i18n("No object selected."), i18n("Object Details") );
00742 return;
00743 }
00744 DetailDialog detail( clickedObject(), data->ut(), data->geo(), ksw );
00745 detail.exec();
00746 }
00747
00748 void SkyMap::slotClockSlewing() {
00749
00750 if ( fabs( data->clock()->scale() ) > Options::slewTimeScale() ) {
00751 if ( ! clockSlewing ) {
00752 clockSlewing = true;
00753 data->clock()->setManualMode( true );
00754
00755
00756 if ( ksw ) ksw->updateTime( false );
00757 }
00758 } else {
00759 if ( clockSlewing ) {
00760 clockSlewing = false;
00761 data->clock()->setManualMode( false );
00762
00763
00764 if ( ksw ) ksw->updateTime( false );
00765 }
00766 }
00767 }
00768
00769 void SkyMap::setFocus( SkyPoint *p ) {
00770 setFocus( p->ra()->Hours(), p->dec()->Degrees() );
00771 }
00772
00773 void SkyMap::setFocus( const dms &ra, const dms &dec ) {
00774 setFocus( ra.Hours(), dec.Degrees() );
00775 }
00776
00777 void SkyMap::setFocus( double ra, double dec ) {
00778 Focus.set( ra, dec );
00779 focus()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00780 }
00781
00782 void SkyMap::setFocusAltAz( const dms &alt, const dms &az) {
00783 setFocusAltAz( alt.Degrees(), az.Degrees() );
00784 }
00785
00786 void SkyMap::setFocusAltAz(double alt, double az) {
00787 focus()->setAlt(alt);
00788 focus()->setAz(az);
00789 focus()->HorizontalToEquatorial( data->LST, data->geo()->lat() );
00790 slewing = false;
00791
00792 oldfocus()->set( focus()->ra(), focus()->dec() );
00793 oldfocus()->setAz( focus()->az()->Degrees() );
00794 oldfocus()->setAlt( focus()->alt()->Degrees() );
00795
00796 double dHA = data->LST->Hours() - focus()->ra()->Hours();
00797 while ( dHA < 0.0 ) dHA += 24.0;
00798 data->HourAngle->setH( dHA );
00799
00800 forceUpdate();
00801 }
00802
00803 void SkyMap::setDestination( SkyPoint *p ) {
00804 Destination.set( p->ra(), p->dec() );
00805 destination()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00806 emit destinationChanged();
00807 }
00808
00809 void SkyMap::setDestination( const dms &ra, const dms &dec ) {
00810 Destination.set( ra, dec );
00811 destination()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00812 emit destinationChanged();
00813 }
00814
00815 void SkyMap::setDestination( double ra, double dec ) {
00816 Destination.set( ra, dec );
00817 destination()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00818 emit destinationChanged();
00819 }
00820
00821 void SkyMap::setDestinationAltAz( const dms &alt, const dms &az) {
00822 destination()->setAlt(alt);
00823 destination()->setAz(az);
00824 destination()->HorizontalToEquatorial( data->LST, data->geo()->lat() );
00825 emit destinationChanged();
00826 }
00827
00828 void SkyMap::setDestinationAltAz(double alt, double az) {
00829 destination()->setAlt(alt);
00830 destination()->setAz(az);
00831 destination()->HorizontalToEquatorial( data->LST, data->geo()->lat() );
00832 emit destinationChanged();
00833 }
00834
00835 void SkyMap::updateFocus() {
00836 if ( Options::isTracking() && focusObject() != NULL ) {
00837 if ( Options::useAltAz() ) {
00838
00839 double dAlt = focusObject()->alt()->Degrees();
00840 if ( Options::useRefraction() )
00841 dAlt = refract( focusObject()->alt(), true ).Degrees();
00842 setFocusAltAz( dAlt, focusObject()->az()->Degrees() );
00843 focus()->HorizontalToEquatorial( data->LST, data->geo()->lat() );
00844 setDestination( focus() );
00845 } else {
00846
00847 setFocus( focusObject() );
00848 focus()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00849 setDestination( focus() );
00850 }
00851 } else if ( Options::isTracking() && focusPoint() != NULL ) {
00852 if ( Options::useAltAz() ) {
00853
00854 setFocus( focusPoint() );
00855 focus()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00856 setDestination( focus() );
00857 }
00858 } else if ( ! slewing ) {
00859
00860 if ( Options::useAltAz() ) {
00861 focus()->setAlt( destination()->alt()->Degrees() );
00862 focus()->setAz( destination()->az()->Degrees() );
00863 focus()->HorizontalToEquatorial( data->LST, data->geo()->lat() );
00864
00865 } else {
00866 focus()->setRA( data->LST->Hours() - data->HourAngle->Hours() );
00867 setDestination( focus() );
00868 focus()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00869 destination()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00870 }
00871 }
00872
00873
00874 data->setHourAngle( data->LST->Hours() - focus()->ra()->Hours() );
00875
00876 setOldFocus( focus() );
00877 oldfocus()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00878 }
00879
00880 void SkyMap::slewFocus( void ) {
00881 double dX, dY, fX, fY, r;
00882 double step = 1.0;
00883 SkyPoint newFocus;
00884
00885
00886
00887
00888 if ( !mouseButtonDown ) {
00889 bool goSlew = ( Options::useAnimatedSlewing() &&
00890 ! data->snapNextFocus() ) &&
00891 !( data->clock()->isManualMode() && data->clock()->isActive() );
00892 if ( goSlew ) {
00893 if ( Options::useAltAz() ) {
00894 dX = destination()->az()->Degrees() - focus()->az()->Degrees();
00895 dY = destination()->alt()->Degrees() - focus()->alt()->Degrees();
00896 } else {
00897 dX = destination()->ra()->Degrees() - focus()->ra()->Degrees();
00898 dY = destination()->dec()->Degrees() - focus()->dec()->Degrees();
00899 }
00900
00901
00902 if ( dX < -180.0 ) dX = 360.0 + dX;
00903 else if ( dX > 180.0 ) dX = -360.0 + dX;
00904
00905 r = sqrt( dX*dX + dY*dY );
00906
00907 while ( r > step ) {
00908 fX = dX / r;
00909 fY = dY / r;
00910
00911 if ( Options::useAltAz() ) {
00912 focus()->setAlt( focus()->alt()->Degrees() + fY*step );
00913 focus()->setAz( dms( focus()->az()->Degrees() + fX*step ).reduce() );
00914 focus()->HorizontalToEquatorial( data->LST, data->geo()->lat() );
00915 } else {
00916 fX = fX/15.;
00917 newFocus.set( focus()->ra()->Hours() + fX*step, focus()->dec()->Degrees() + fY*step );
00918 setFocus( &newFocus );
00919 focus()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00920 }
00921
00922 slewing = true;
00923
00924 if ( transientObject() && ! TransientTimer.isActive() )
00925 fadeTransientLabel();
00926
00927 forceUpdate();
00928 kapp->processEvents(10);
00929
00930 if ( Options::useAltAz() ) {
00931 dX = destination()->az()->Degrees() - focus()->az()->Degrees();
00932 dY = destination()->alt()->Degrees() - focus()->alt()->Degrees();
00933 } else {
00934 dX = destination()->ra()->Degrees() - focus()->ra()->Degrees();
00935 dY = destination()->dec()->Degrees() - focus()->dec()->Degrees();
00936 }
00937
00938
00939 if ( dX < -180.0 ) dX = 360.0 + dX;
00940 else if ( dX > 180.0 ) dX = -360.0 + dX;
00941
00942 r = sqrt( dX*dX + dY*dY );
00943 }
00944 }
00945
00946
00947
00948 if ( Options::useAltAz() ) {
00949 setFocusAltAz( destination()->alt()->Degrees(), destination()->az()->Degrees() );
00950 focus()->HorizontalToEquatorial( data->LST, data->geo()->lat() );
00951 } else {
00952 setFocus( destination() );
00953 focus()->EquatorialToHorizontal( data->LST, data->geo()->lat() );
00954 }
00955
00956 data->HourAngle->setH( data->LST->Hours() - focus()->ra()->Hours() );
00957 slewing = false;
00958
00959
00960 if ( data->snapNextFocus() ) {
00961 data->setSnapNextFocus(false);
00962 }
00963
00964
00965
00966 if ( Options::useHoverLabel() )
00967 HoverTimer.start( HOVER_INTERVAL, true );
00968
00969 forceUpdate();
00970 }
00971 }
00972
00973 void SkyMap::invokeKey( int key ) {
00974 QKeyEvent *e = new QKeyEvent( QEvent::KeyPress, key, 0, 0 );
00975 keyPressEvent( e );
00976 delete e;
00977 }
00978
00979 double SkyMap::findPA( SkyObject *o, int x, int y, double scale ) {
00980
00981
00982
00983 double newDec = o->dec()->Degrees() + 5730.0/Options::zoomFactor();
00984 if ( newDec > 90.0 ) newDec = 90.0;
00985 SkyPoint test( o->ra()->Hours(), newDec );
00986 if ( Options::useAltAz() ) test.EquatorialToHorizontal( data->LST, data->geo()->lat() );
00987 QPoint t = getXY( &test, Options::useAltAz(), Options::useRefraction(), scale );
00988 double dx = double( t.x() - x );
00989 double dy = double( y - t.y() );
00990 double north;
00991 if ( dy ) {
00992 north = atan( dx/dy )*180.0/dms::PI;
00993
00994 if ( dy < 0.0 ) north += 180.0;
00995 if ( north >= 360.0 ) north -= 360.;
00996 } else {
00997 north = 90.0;
00998 if ( dx > 0 ) north = -90.0;
00999 }
01000
01001 return ( north + o->pa() );
01002 }
01003
01004 QPoint SkyMap::getXY( SkyPoint *o, bool Horiz, bool doRefraction, double scale ) {
01005 QPoint p;
01006
01007 double Y, dX;
01008 double sindX, cosdX, sinY, cosY, sinY0, cosY0;
01009
01010 int Width = int( width() * scale );
01011 int Height = int( height() * scale );
01012
01013 double pscale = Options::zoomFactor() * scale;
01014
01015 if ( Horiz ) {
01016 if ( doRefraction ) Y = refract( o->alt(), true ).radians();
01017 else Y = o->alt()->radians();
01018
01019 if ( focus()->az()->Degrees() > 270.0 && o->az()->Degrees() < 90.0 ) {
01020 dX = 2*dms::PI + focus()->az()->radians() - o->az()->radians();
01021 } else {
01022 dX = focus()->az()->radians() - o->az()->radians();
01023 }
01024
01025 focus()->alt()->SinCos( sinY0, cosY0 );
01026
01027 } else {
01028 if (focus()->ra()->Hours() > 18.0 && o->ra()->Hours() < 6.0) {
01029 dX = 2*dms::PI + o->ra()->radians() - focus()->ra()->radians();
01030 } else {
01031 dX = o->ra()->radians() - focus()->ra()->radians();
01032 }
01033 Y = o->dec()->radians();
01034 focus()->dec()->SinCos( sinY0, cosY0 );
01035 }
01036
01037
01038 #if ( __GLIBC__ >= 2 && __GLIBC_MINOR__ >=1 ) && !defined(__UCLIBC__)
01039
01040 sincos( dX, &sindX, &cosdX );
01041 sincos( Y, &sinY, &cosY );
01042 #else
01043
01044 sindX = sin(dX);
01045 cosdX = cos(dX);
01046 sinY = sin(Y);
01047 cosY = cos(Y);
01048 #endif
01049
01050 double c = sinY0*sinY + cosY0*cosY*cosdX;
01051
01052 if ( c < 0.0 ) {
01053 p.setX( -10000000 );
01054 p.setY( -10000000 );
01055 return p;
01056 }
01057
01058 double k = sqrt( 2.0/( 1 + c ) );
01059
01060 p.setX( int( 0.5*Width - pscale*k*cosY*sindX ) );
01061 p.setY( int( 0.5*Height - pscale*k*( cosY0*sinY - sinY0*cosY*cosdX ) ) );
01062
01063 return p;
01064 }
01065
01066 SkyPoint SkyMap::dXdYToRaDec( double dx, double dy, bool useAltAz, dms *LST, const dms *lat, bool doRefract ) {
01067
01068
01069
01070 SkyPoint result;
01071 double sinDec, cosDec, sinDec0, cosDec0, sinc, cosc, sinlat, coslat;
01072 double xx, yy;
01073
01074 double r = sqrt( dx*dx + dy*dy );
01075 dms centerAngle;
01076 centerAngle.setRadians( 2.0*asin(0.5*r) );
01077
01078 focus()->dec()->SinCos( sinDec0, cosDec0 );
01079 centerAngle.SinCos( sinc, cosc );
01080
01081 if ( useAltAz ) {
01082 dms HA;
01083 dms Dec, alt, az, alt0, az0;
01084 double A;
01085 double sinAlt, cosAlt, sinAlt0, cosAlt0, sinAz, cosAz;
01086
01087 az0 = focus()->az()->Degrees();
01088 alt0 = focus()->alt()->Degrees();
01089 alt0.SinCos( sinAlt0, cosAlt0 );
01090
01091 dx = -dx;
01092 yy = dx*sinc;
01093 xx = r*cosAlt0*cosc - dy*sinAlt0*sinc;
01094
01095 A = atan( yy/xx );
01096
01097 if ( xx<0 ) A = A + dms::PI;
01098
01099
01100 dms deltaAz;
01101 deltaAz.setRadians( A );
01102 az = focus()->az()->Degrees() + deltaAz.Degrees();
01103 alt.setRadians( asin( cosc*sinAlt0 + ( dy*sinc*cosAlt0 )/r ) );
01104
01105 if ( doRefract ) alt.setD( refract( &alt, false ).Degrees() );
01106
01107 az.SinCos( sinAz, cosAz );
01108 alt.SinCos( sinAlt, cosAlt );
01109 lat->SinCos( sinlat, coslat );
01110
01111 Dec.setRadians( asin( sinAlt*sinlat + cosAlt*coslat*cosAz ) );
01112 Dec.SinCos( sinDec, cosDec );
01113
01114 HA.setRadians( acos( ( sinAlt - sinlat*sinDec )/( coslat*cosDec ) ) );
01115 if ( sinAz > 0.0 ) HA.setH( 24.0 - HA.Hours() );
01116
01117 result.setRA( LST->Hours() - HA.Hours() );
01118 result.setRA( result.ra()->reduce() );
01119 result.setDec( Dec.Degrees() );
01120
01121 return result;
01122
01123 } else {
01124 yy = dx*sinc;
01125 xx = r*cosDec0*cosc - dy*sinDec0*sinc;
01126
01127 double RARad = ( atan( yy / xx ) );
01128
01129 if ( xx<0 ) RARad = RARad + dms::PI;
01130
01131
01132 dms deltaRA, Dec;
01133 deltaRA.setRadians( RARad );
01134 Dec.setRadians( asin( cosc*sinDec0 + (dy*sinc*cosDec0)/r ) );
01135
01136 result.setRA( focus()->ra()->Hours() + deltaRA.Hours() );
01137 result.setRA( result.ra()->reduce() );
01138 result.setDec( Dec.Degrees() );
01139
01140 return result;
01141 }
01142 }
01143
01144 dms SkyMap::refract( const dms *alt, bool findApparent ) {
01145 if ( alt->Degrees() <= -2.000 ) return dms( alt->Degrees() );
01146
01147 int index = int( ( alt->Degrees() + 2.0 )*2. );
01148 dms result;
01149
01150
01151 if ( index < 0 || index > 183 ) {
01152 return dms( alt->Degrees() );
01153 }
01154
01155 if ( findApparent ) {
01156 result.setD( alt->Degrees() + RefractCorr1[index] );
01157 } else {
01158 result.setD( alt->Degrees() + RefractCorr2[index] );
01159 }
01160
01161 return result;
01162 }
01163
01164
01165
01166
01167
01168
01169
01170 void SkyMap::forceUpdate( bool now )
01171 {
01172 QPoint mp( mapFromGlobal( QCursor::pos() ) );
01173 double dx = ( 0.5*width() - mp.x() )/Options::zoomFactor();
01174 double dy = ( 0.5*height() - mp.y() )/Options::zoomFactor();
01175
01176 if (! unusablePoint (dx, dy)) {
01177
01178 setMousePoint( dXdYToRaDec( dx, dy, Options::useAltAz(), data->LST, data->geo()->lat(), Options::useRefraction() ) );
01179 }
01180
01181 computeSkymap = true;
01182 if ( now ) repaint();
01183 else update();
01184 }
01185
01186 float SkyMap::fov() {
01187 if ( width() >= height() )
01188 return 28.65*width()/Options::zoomFactor();
01189 else
01190 return 28.65*height()/Options::zoomFactor();
01191 }
01192
01193 bool SkyMap::checkVisibility( SkyPoint *p, float FOV, double XMax ) {
01194 double dX, dY;
01195 bool useAltAz = Options::useAltAz();
01196
01197
01198
01199
01200
01201
01202
01203 if ( useAltAz && Options::showGround() && p->alt()->Degrees() < -2.0
01204 && ( focus()->alt()->Degrees() > 0. || FOV > 50. ) ) return false;
01205
01206 if ( useAltAz ) {
01207 dY = fabs( p->alt()->Degrees() - focus()->alt()->Degrees() );
01208 } else {
01209 dY = fabs( p->dec()->Degrees() - focus()->dec()->Degrees() );
01210 }
01211 if ( isPoleVisible ) dY *= 0.75;
01212 if ( dY > FOV ) return false;
01213 if ( isPoleVisible ) return true;
01214
01215 if ( useAltAz ) {
01216 dX = fabs( p->az()->Degrees() - focus()->az()->Degrees() );
01217 } else {
01218 dX = fabs( p->ra()->Degrees() - focus()->ra()->Degrees() );
01219 }
01220 if ( dX > 180.0 ) dX = 360.0 - dX;
01221
01222 if ( dX < XMax ) {
01223 return true;
01224 } else {
01225 return false;
01226 }
01227 }
01228
01229 bool SkyMap::unusablePoint (double dx, double dy)
01230 {
01231 if (dx >= 1.41 || dx <= -1.41 || dy >= 1.41 || dy <= -1.41)
01232 return true;
01233 else
01234 return false;
01235 }
01236
01237 void SkyMap::setZoomMouseCursor()
01238 {
01239 mouseMoveCursor = false;
01240
01241 QPainter p;
01242 QPixmap cursorPix (32, 32);
01243
01244 int mx = cursorPix. width() / 2;
01245 int my = cursorPix. height() / 2;
01246
01247 cursorPix.fill (white);
01248 p.begin (&cursorPix);
01249 p.setPen (QPen (black, 2));
01250
01251 p.drawEllipse( mx - 7, my - 7, 14, 14 );
01252 p.drawLine( mx + 5, my + 5, mx + 11, my + 11 );
01253 p.end();
01254
01255
01256 QBitmap mask (32, 32);
01257 mask.fill (color0);
01258
01259 p.begin (&mask);
01260
01261 p.setPen (QPen (color1, 3));
01262 p.drawEllipse( mx - 7, my - 7, 14, 14 );
01263 p.drawLine( mx + 5, my + 5, mx + 12, my + 12 );
01264 p.end();
01265
01266 cursorPix.setMask (mask);
01267 QCursor cursor (cursorPix);
01268 setCursor (cursor);
01269 }
01270
01271 void SkyMap::setDefaultMouseCursor()
01272 {
01273 mouseMoveCursor = false;
01274
01275 QPainter p;
01276 QPixmap cursorPix (32, 32);
01277
01278 int mx = cursorPix. width() / 2;
01279 int my = cursorPix. height() / 2;
01280
01281 cursorPix.fill (white);
01282 p.begin (&cursorPix);
01283 p.setPen (QPen (black, 2));
01284
01285 p.drawLine (mx - 2, my - 2, mx - 8, mx - 8);
01286 p.drawLine (mx + 2, my + 2, mx + 8, mx + 8);
01287
01288 p.drawLine (mx - 2, my + 2, mx - 8, mx + 8);
01289 p.drawLine (mx + 2, my - 2, mx + 8, mx - 8);
01290 p.end();
01291
01292
01293 QBitmap mask (32, 32);
01294 mask.fill (color0);
01295
01296 p.begin (&mask);
01297
01298 p.setPen (QPen (color1, 3));
01299
01300 p.drawLine (mx - 2, my - 2, mx - 8, mx - 8);
01301 p.drawLine (mx + 2, my + 2, mx + 8, mx + 8);
01302
01303 p.drawLine (mx - 2, my + 2, mx - 8, mx + 8);
01304 p.drawLine (mx + 2, my - 2, mx + 8, mx - 8);
01305 p.end();
01306
01307 cursorPix.setMask (mask);
01308 QCursor cursor (cursorPix);
01309 setCursor (cursor);
01310 }
01311
01312 void SkyMap::setMouseMoveCursor()
01313 {
01314 if (mouseButtonDown)
01315 {
01316 setCursor (9);
01317 mouseMoveCursor = true;
01318 }
01319 }
01320
01321 void SkyMap::addLink( void ) {
01322 AddLinkDialog adialog( this, clickedObject()->name() );
01323 QString entry;
01324 QFile file;
01325
01326 if ( adialog.exec()==QDialog::Accepted ) {
01327 if ( adialog.isImageLink() ) {
01328
01329 clickedObject()->ImageList.append( adialog.url() );
01330 clickedObject()->ImageTitle.append( adialog.desc() );
01331
01332
01333
01334 file.setName( locateLocal( "appdata", "image_url.dat" ) );
01335
01336 if ( !file.open( IO_ReadWrite | IO_Append ) ) {
01337 QString message = i18n( "Custom image-links file could not be opened.\nLink cannot be recorded for future sessions." );
01338 KMessageBox::sorry( 0, message, i18n( "Could Not Open File" ) );
01339 return;
01340 } else {
01341 entry = clickedObject()->name() + ":" + adialog.desc() + ":" + adialog.url();
01342 QTextStream stream( &file );
01343 stream << entry << endl;
01344 file.close();
01345 emit linkAdded();
01346 }
01347 } else {
01348 clickedObject()->InfoList.append( adialog.url() );
01349 clickedObject()->InfoTitle.append( adialog.desc() );
01350
01351
01352 file.setName( locateLocal( "appdata", "info_url.dat" ) );
01353
01354 if ( !file.open( IO_ReadWrite | IO_Append ) ) {
01355 QString message = i18n( "Custom information-links file could not be opened.\nLink cannot be recorded for future sessions." ); KMessageBox::sorry( 0, message, i18n( "Could not Open File" ) );
01356 return;
01357 } else {
01358 entry = clickedObject()->name() + ":" + adialog.desc() + ":" + adialog.url();
01359 QTextStream stream( &file );
01360 stream << entry << endl;
01361 file.close();
01362 emit linkAdded();
01363 }
01364 }
01365 }
01366 }
01367
01368 void SkyMap::updateAngleRuler() {
01369 if ( Options::useAltAz() ) PreviousClickedPoint.EquatorialToHorizontal( data->LST, data->geo()->lat() );
01370 beginRulerPoint = getXY( previousClickedPoint(), Options::useAltAz(), Options::useRefraction() );
01371
01372
01373 endRulerPoint = mapFromGlobal( QCursor::pos() );
01374 }
01375
01376 #include "skymap.moc"