00001
00018 #include <kapp.h>
00019 #include <klocale.h>
00020 #include <kpopupmenu.h>
00021 #include <kiconloader.h>
00022 #include <kdialog.h>
00023
00024 #include <qglobal.h>
00025 #include <qlabel.h>
00026 #include <qpainter.h>
00027 #include <qcursor.h>
00028 #include <qtooltip.h>
00029 #include <qsignalmapper.h>
00030 #include <qstringlist.h>
00031 #include <qarray.h>
00032 #include <qlayout.h>
00033
00034 #include "ksetiwatch.h"
00035 #include "skymap.h"
00036 #include "datainfo.h"
00037 #include "setiloc.h"
00038 #include "telescopepath.h"
00039
00041
00042 LocButton::LocButton(QWidget* parent, const char* name)
00043 : QButton(parent, name)
00044 {
00045 }
00046
00047 LocButton::~LocButton()
00048 {
00049 }
00050
00051
00052 void LocButton::setColor(const QColor& col)
00053 {
00054 m_color = col;
00055 update();
00056 }
00057
00058
00059 void LocButton::paintEvent(QPaintEvent*)
00060 {
00061 QPainter p;
00062 QBrush bru;
00063 QPen pen;
00064
00065 p.begin( this );
00066 pen.setColor(m_color);
00067 bru.setColor(m_color);
00068 if(globalopts->FillMarker)
00069 bru.setStyle(SolidPattern);
00070 else
00071 bru.setStyle(NoBrush);
00072 p.setPen(pen);
00073 p.setBrush(bru);
00074 p.drawEllipse(rect());
00075 p.end();
00076 }
00077
00079
00080 SkyMap* SkyMap::map = 0;
00081
00082 SkyMap::SkyMap(QWidget* parent, const char*)
00083 : QScrollView(parent), pathDlg(0), path(0)
00084 {
00085 SeLi.setAutoDelete(true);
00086
00087
00088 buttonSignals = new QSignalMapper(this);
00089 connect(buttonSignals, SIGNAL(mapped(const QString&)),
00090 this, SLOT(showTelescopePath(const QString&)));
00091
00092
00093 starmap = UserIcon("starmap");
00094 QSize s(starmap.size());
00095
00096 setCaption(i18n("Skymap (right click for menu)"));
00097 setMinimumSize(100, 100);
00098
00099 pic_options = new KPopupMenu(this, "Skymap");
00100 pic_options->setTitle(i18n("Skymap"));
00101 pic_options->setCheckable(true);
00102 pic_options->insertItem(i18n("Clear"), Clear);
00103 pic_options->insertItem(i18n("Show Text"), ShowText);
00104 pic_options->insertSeparator();
00105 pic_options->insertItem(i18n("Small Marker"), SmallMarker);
00106 pic_options->insertItem(i18n("Normal Marker"), NormalMarker);
00107 pic_options->insertItem(i18n("Large Marker"), LargeMarker);
00108 pic_options->insertSeparator();
00109 pic_options->insertItem(i18n("Fill Marker"), FillMarker);
00110 connect(pic_options, SIGNAL(activated(int)), SLOT(handlePopupCommand(int)));
00111 connect(pic_options, SIGNAL(aboutToShow()), SLOT(checkPopupStatus()));
00112
00113 pic = new QLabel(this);
00114 pic->installEventFilter(this);
00115 pic->setFixedSize(s);
00116 pic->setBackgroundPixmap(starmap);
00117 this->addChild(pic);
00118
00119 QWidget* d = QApplication::desktop();
00120 int w = d->width();
00121 int h = d->height();
00122 int w_sm(0), h_sm(0);
00123
00124 if(s.width() < w)
00125 w_sm = s.width()+4;
00126 else
00127 {
00128 w_sm = w - 8;
00129 h_sm = 16;
00130 }
00131 if(s.height() < h)
00132 h_sm += s.height()+4;
00133 else
00134 h_sm = h;
00135 resize(w_sm, h_sm);
00136 setMaximumSize(w_sm, h_sm);
00137 }
00138
00139
00140 SkyMap::~SkyMap()
00141 {
00142 clearMap();
00143 }
00144
00145
00146 bool SkyMap::event(QEvent* e)
00147 {
00148 switch(e->type())
00149 {
00150 case QEvent::MouseButtonPress:
00151 {
00152 QMouseEvent* me = dynamic_cast<QMouseEvent*>(e);
00153 if(me && me->button() == RightButton)
00154 pic_options->popup(QCursor::pos());
00155 break;
00156 }
00157 case QEvent::Close:
00158 {
00159 if(pathDlg != 0)
00160 pathDlg->close();
00161 break;
00162 }
00163 case QEvent::Hide:
00164 {
00165 if(pathDlg != 0)
00166 {
00167 isPathDlgHidden = pathDlg->isHidden();
00168 pathDlg->hide();
00169 }
00170 break;
00171 }
00172 case QEvent::Show:
00173 {
00174 if(pathDlg != 0 && isPathDlgHidden == false)
00175 {
00176 pathDlg->show();
00177 }
00178 break;
00179 }
00180 default:
00181 break;
00182 }
00183
00184 return(QScrollView::event(e));
00185 }
00186
00187
00188 bool SkyMap::eventFilter(QObject* o, QEvent* e)
00189 {
00190 if(e->type() == QEvent::Paint)
00191 {
00192 QLabel* pic = dynamic_cast<QLabel*>(o);
00193 QPaintEvent* pe = dynamic_cast<QPaintEvent*>(e);
00194 if(pic && pe)
00195 paintLocations(pe);
00196 return(true);
00197 }
00198 return(QScrollView::eventFilter(o, e));
00199 }
00200
00201
00202 void SkyMap::paintLocations(QPaintEvent*)
00203 {
00204 QPainter p;
00205 QBrush bru;
00206 QPen pen;
00207 QString id;
00208 int ms = globalopts->MarkerSize;
00209
00210 p.begin( pic );
00211 for(SkyPos* pos=SeLi.first(); pos != 0; pos=SeLi.next() )
00212 {
00213 QPoint lp = locationPosition(pos->ra, pos->dec);
00214 pen.setColor(pos->color);
00215 p.setPen(pen);
00216 if(pos->pathButton == 0)
00217 {
00218 bru.setColor(pos->color);
00219 if(globalopts->FillMarker)
00220 bru.setStyle(SolidPattern);
00221 else
00222 bru.setStyle(NoBrush);
00223 p.setBrush(bru);
00224 p.drawEllipse(lp.x()-ms*3, lp.y()-ms*3, ms*6, ms*6);
00225 }
00226 if(globalopts->ShowText)
00227 {
00228 id = pos->location + "\n" + pos->time_recorded;
00229 QRect r = p.boundingRect(0, 0, 10000, 10000, 0, (const char *)id);
00230 p.drawText(lp.x()-(r.width()/2), lp.y()-r.height()-ms*3-1,
00231 r.width(), r.height(), AlignCenter|DontClip, id);
00232 }
00233 }
00234 p.end();
00235 }
00236
00237
00238 SkyMap* SkyMap::instance()
00239 {
00240 if(map == 0)
00241 map = new SkyMap();
00242 return(map);
00243 }
00244
00245
00246 SkyMap* SkyMap::showMap()
00247 {
00248 SkyMap* m = instance();
00249 if(m)
00250 {
00251 m->show();
00252 if(m->isActiveWindow() == false)
00253 {
00254 if(m->isMinimized())
00255 {
00256 m->hide();
00257 m->showNormal();
00258 }
00259 m->raise();
00260 }
00261 }
00262 return(m);
00263 }
00264
00265
00266 void SkyMap::addLocation(SetiLoc* loc)
00267 {
00268 if(!loc->timeRecorded().isEmpty())
00269 {
00270 SkyPos *spos = new SkyPos;
00271
00272
00273 spos->location = loc->description();
00274 spos->time_recorded = loc->timeRecordedString();
00275 spos->color = loc->color();
00276 spos->ra = loc->startRA();
00277 spos->dec = loc->startDec();
00278
00279 setLocationButton(spos);
00280 buttonSignals->setMapping(spos->pathButton, spos->location);
00281 connect(spos->pathButton, SIGNAL(clicked()), buttonSignals, SLOT(map()));
00282
00283
00284 SeLi.append(spos);
00285 pic->update();
00286 }
00287
00288 connect(loc, SIGNAL(newWorkUnit(WorkUnitData, const QString&, const QColor&)),
00289 this, SLOT(updateLocation(WorkUnitData, const QString&, const QColor&)));
00290 }
00291
00292
00293 void SkyMap::addLocation(const QString& locName, const QString& time_rec,
00294 const QColor& col, double ra, double dec)
00295 {
00296 SkyPos *spos = new SkyPos;
00297
00298
00299 spos->location = locName;
00300 spos->time_recorded = time_rec;
00301 spos->color = col;
00302 spos->ra = ra;
00303 spos->dec = dec;
00304 spos->pathButton = 0;
00305
00306
00307 SeLi.append(spos);
00308 pic->update();
00309 }
00310
00311
00312 void SkyMap::clearMap()
00313 {
00314 for(SkyPos* pos=SeLi.first(); pos != 0; pos=SeLi.next() )
00315 {
00316 if(pos->pathButton)
00317 delete pos->pathButton;
00318 }
00319 SeLi.clear();
00320 pic->update();
00321 }
00322
00323
00324 void SkyMap::updateLocation(WorkUnitData wud, const QString& locname,
00325 const QColor& col)
00326 {
00327 for(SkyPos* pos=SeLi.first(); pos != 0; pos=SeLi.next() )
00328 {
00329 if(pos->location == locname)
00330 {
00331 pos->time_recorded = wud.time_recorded;
00332 pos->color = col;
00333 pos->ra = wud.start_ra;
00334 pos->dec = wud.start_dec;
00335 pic->update();
00336 break;
00337 }
00338 }
00339 }
00340
00341
00342 void SkyMap::setLocationButton(SkyPos* pos)
00343 {
00344 int ms = globalopts->MarkerSize;
00345 QPoint lp = locationPosition(pos->ra, pos->dec);
00346
00347 pos->pathButton = new LocButton(pic);
00348 pos->pathButton->setGeometry(lp.x()-ms*3, lp.y()-ms*3, ms*6, ms*6);
00349 pos->pathButton->setColor(pos->color);
00350 pos->pathButton->setBackgroundPixmap(starmap);
00351 pos->pathButton->setBackgroundOrigin(ParentOrigin);
00352 #if QT_VERSION < 0x030000
00353 pos->pathButton->setCursor(Qt::pointingHandCursor);
00354 #else
00355 pos->pathButton->setCursor(Qt::PointingHandCursor);
00356 #endif
00357 pos->pathButton->show();
00358 QToolTip::remove(pos->pathButton);
00359 QToolTip::add(pos->pathButton, pos->location + "\n" + pos->time_recorded);
00360 }
00361
00362
00363 void SkyMap::checkPopupStatus()
00364 {
00365 pic_options->setItemChecked(ShowText, globalopts->ShowText);
00366 pic_options->setItemChecked(FillMarker, globalopts->FillMarker);
00367 for(int i=SmallMarker;i<=LargeMarker;i++)
00368 {
00369 pic_options->setItemChecked(i, false);
00370 }
00371 pic_options->setItemChecked(globalopts->MarkerSize+SmallMarker-1, true);
00372 }
00373
00374
00375 void SkyMap::handlePopupCommand(int id)
00376 {
00377 switch(id)
00378 {
00379 case Clear:
00380 clearMap();
00381 break;
00382 case ShowText:
00383 globalopts->ShowText = !globalopts->ShowText;
00384 break;
00385 case FillMarker:
00386 globalopts->FillMarker = !globalopts->FillMarker;
00387 break;
00388 default:
00389 if(id >= SmallMarker && id <= LargeMarker)
00390 globalopts->MarkerSize = id - SmallMarker + 1;
00391 break;
00392 }
00393
00394 int ms = globalopts->MarkerSize;
00395 for(SkyPos* pos=SeLi.first(); pos != 0; pos=SeLi.next() )
00396 {
00397 if(pos->pathButton)
00398 {
00399 QPoint lp = locationPosition(pos->ra, pos->dec);
00400 pos->pathButton->setGeometry(lp.x()-ms*3, lp.y()-ms*3, ms*6, ms*6);
00401 pos->pathButton->update();
00402 }
00403 }
00404
00405 pic->update();
00406 }
00407
00408
00409 QPoint SkyMap::locationPosition(double ra, double dec)
00410 {
00411 int x = (int)(484.0 - (ra*965.0)/24.0);
00412 if(x < 0)
00413 x = 965 + x;
00414 int y = (int)(241.0 - (dec*482.0)/180.0);
00415
00416 return(QPoint(x, y));
00417 }
00418
00419
00420 void SkyMap::showTelescopePath(const QString& name)
00421 {
00422 SetiLoc* loc = Ksetiwatch::getLocation(name);
00423 if(loc)
00424 {
00425 if(pathDlg == 0)
00426 {
00427 pathDlg = new KDialog(this);
00428
00429 QBoxLayout *layout = new QVBoxLayout(pathDlg);
00430
00431 if(path == 0)
00432 path = new TelescopePath((SetiLoc*)0, pathDlg);
00433 layout->addWidget(path);
00434 }
00435
00436 path->setLocation(loc);
00437
00438 pathDlg->setCaption(i18n("Location %1: Telescope Path").arg(name));
00439 pathDlg->show();
00440 pathDlg->move(QCursor::pos());
00441 double aspect = 2.0*(path->xRange()/24.0)*(180.0/path->yRange());
00442
00443 if(aspect > 2.0)
00444 aspect = 2.0;
00445 if(aspect < 0.5)
00446 aspect = 0.5;
00447 if(aspect > 1.0)
00448 pathDlg->resize(static_cast<int>(150.0*aspect), 150);
00449 else
00450 pathDlg->resize(150, static_cast<int>(150.0/aspect));
00451 }
00452 }
00453
00454 #include "skymap.moc"
00455