00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include <qstring.h>
00019 #include <qlayout.h>
00020 #include <qlineedit.h>
00021 #include <qimage.h>
00022 #include <qregexp.h>
00023
00024 #include <kapplication.h>
00025 #include <kstandarddirs.h>
00026 #include <kmessagebox.h>
00027 #include <kactivelabel.h>
00028 #include <kpushbutton.h>
00029 #include <klistview.h>
00030 #include <klineedit.h>
00031
00032 #include "detaildialog.h"
00033
00034 #include "details_data.h"
00035 #include "details_position.h"
00036 #include "details_links.h"
00037 #include "details_database.h"
00038 #include "details_log.h"
00039
00040 #include "kstars.h"
00041 #include "kstarsdata.h"
00042 #include "kstarsdatetime.h"
00043 #include "geolocation.h"
00044 #include "ksutils.h"
00045 #include "skymap.h"
00046 #include "skyobject.h"
00047 #include "starobject.h"
00048 #include "deepskyobject.h"
00049 #include "ksplanetbase.h"
00050 #include "ksmoon.h"
00051 #include "thumbnailpicker.h"
00052
00053 #include "indielement.h"
00054 #include "indiproperty.h"
00055 #include "indidevice.h"
00056 #include "indimenu.h"
00057 #include "devicemanager.h"
00058 #include "indistd.h"
00059
00060 LogEdit::LogEdit( QWidget *parent, const char *name ) : KTextEdit( parent, name )
00061 {
00062 setFrameStyle( QFrame::StyledPanel );
00063 setFrameShadow( QFrame::Plain );
00064 setLineWidth( 4 );
00065 }
00066
00067 void LogEdit::focusOutEvent( QFocusEvent *e ) {
00068 emit focusOut();
00069 QWidget::focusOutEvent(e);
00070 }
00071
00072 ClickLabel::ClickLabel( QWidget *parent, const char *name ) : QLabel( parent, name )
00073 {}
00074
00075 DetailDialog::DetailDialog(SkyObject *o, const KStarsDateTime &ut, GeoLocation *geo,
00076 QWidget *parent, const char *name ) :
00077 KDialogBase( KDialogBase::Tabbed, i18n( "Object Details" ), Close, Close, parent, name ) ,
00078 selectedObject(o), ksw((KStars*)parent), Data(0), Pos(0), Links(0), Adv(0), Log(0)
00079 {
00080
00081 setPaletteBackgroundColor( palette().color( QPalette::Active, QColorGroup::Base ) );
00082 setPaletteForegroundColor( palette().color( QPalette::Active, QColorGroup::Text ) );
00083
00084
00085 Thumbnail = new QPixmap( 200, 200 );
00086
00087 createGeneralTab();
00088 createPositionTab( ut, geo );
00089 createLinksTab();
00090 createAdvancedTab();
00091 createLogTab();
00092
00093
00094 connect( Data->ObsListButton, SIGNAL( clicked() ), this, SLOT( addToObservingList() ) );
00095 connect( Data->CenterButton, SIGNAL( clicked() ), this, SLOT( centerMap() ) );
00096 connect( Data->ScopeButton, SIGNAL( clicked() ), this, SLOT( centerTelescope() ) );
00097 connect( Data->Image, SIGNAL( clicked() ), this, SLOT( updateThumbnail() ) );
00098 }
00099
00100 void DetailDialog::createGeneralTab()
00101 {
00102 QFrame *DataTab = addPage(i18n("General"));
00103 Data = new DetailsDataUI( DataTab, "general_data_tab" );
00104
00105
00106 Data->Names->setPaletteBackgroundColor( palette().color( QPalette::Active, QColorGroup::Highlight ) );
00107 Data->Names->setPaletteForegroundColor( palette().color( QPalette::Active, QColorGroup::HighlightedText ) );
00108 Data->DataFrame->setPaletteForegroundColor( palette().color( QPalette::Active, QColorGroup::Highlight ) );
00109 Data->Type->setPalette( palette() );
00110 Data->Constellation->setPalette( palette() );
00111 Data->Mag->setPalette( palette() );
00112 Data->Distance->setPalette( palette() );
00113 Data->AngSize->setPalette( palette() );
00114 Data->InLabel->setPalette( palette() );
00115 Data->MagLabel->setPalette( palette() );
00116 Data->DistanceLabel->setPalette( palette() );
00117 Data->AngSizeLabel->setPalette( palette() );
00118
00119
00120 showThumbnail();
00121
00122 QVBoxLayout *vlay = new QVBoxLayout( DataTab, 0, 0 );
00123 vlay->addWidget( Data );
00124
00125
00126
00127 StarObject *s = 0L;
00128 DeepSkyObject *dso = 0L;
00129 KSPlanetBase *ps = 0L;
00130 QString pname(""), oname("");
00131
00132 switch ( selectedObject->type() ) {
00133 case 0:
00134 s = (StarObject *)selectedObject;
00135
00136 Data->Names->setText( s->longname() );
00137 Data->Type->setText( s->sptype() + " " + i18n("star") );
00138 Data->Mag->setText( i18n( "number in magnitudes", "%1 mag" ).arg(
00139 KGlobal::locale()->formatNumber( s->mag(), 1 ) ) );
00140
00141
00142 if ( s->distance() > 2000. || s->distance() < 0. )
00143 Data->Distance->setText( QString(i18n("larger than 2000 parsecs", "> 2000 pc") ) );
00144 else if ( s->distance() > 50.0 )
00145 Data->Distance->setText( i18n( "number in parsecs", "%1 pc" ).arg(
00146 QString::number( int( s->distance() + 0.5 ) ) ) );
00147 else if ( s->distance() > 10.0 )
00148 Data->Distance->setText( i18n( "number in parsecs", "%1 pc" ).arg(
00149 KGlobal::locale()->formatNumber( s->distance(), 1 ) ) );
00150 else
00151 Data->Distance->setText( i18n( "number in parsecs", "%1 pc" ).arg(
00152 KGlobal::locale()->formatNumber( s->distance(), 2 ) ) );
00153
00154
00155 Data->AngSizeLabel->setText( "" );
00156 Data->AngSize->setText( "" );
00157 Data->AngSizeLabel->setFont( Data->AngSize->font() );
00158 if ( s->isMultiple() && s->isVariable() ) {
00159 Data->AngSizeLabel->setText( i18n( "the star is a multiple star", "multiple" ) + "," );
00160 Data->AngSize->setText( i18n( "the star is a variable star", "variable" ) );
00161 } else if ( s->isMultiple() )
00162 Data->AngSizeLabel->setText( i18n( "the star is a multiple star", "multiple" ) );
00163 else if ( s->isVariable() )
00164 Data->AngSizeLabel->setText( i18n( "the star is a variable star", "variable" ) );
00165
00166 break;
00167
00168 case 9:
00169 case 10:
00170 case 2:
00171 ps = (KSPlanetBase *)selectedObject;
00172
00173 Data->Names->setText( ps->longname() );
00174
00175 if ( ps->name() == "Sun" )
00176 Data->Type->setText( i18n("G5 star") );
00177 else
00178 Data->Type->setText( ps->typeName() );
00179
00180 Data->Constellation->setText( ps->constellation( ksw->data()->csegmentList,
00181 ksw->data()->cnameList ) );
00182
00183
00184 if ( selectedObject->name() == "Moon" ) {
00185 Data->MagLabel->setText( i18n("Illumination:") );
00186 Data->Mag->setText( QString("%1 %").arg( int( ((KSMoon *)selectedObject)->illum()*100. ) ) );
00187 } else {
00188 Data->Mag->setText( i18n( "number in magnitudes", "%1 mag" ).arg(
00189 KGlobal::locale()->formatNumber( ps->mag(), 1 ) ) );
00190 }
00191
00192
00193 if ( ps->name() == "Moon" ) {
00194 Data->Distance->setText( i18n("distance in kilometers", "%1 km").arg(
00195 KGlobal::locale()->formatNumber( ps->rearth()*AU_KM ) ) );
00196 } else {
00197 Data->Distance->setText( i18n("distance in Astronomical Units", "%1 AU").arg(
00198 KGlobal::locale()->formatNumber( ps->rearth() ) ) );
00199 }
00200
00201
00202 if ( ps->angSize() ) {
00203 if ( ps->name() == "Sun" || ps->name() == "Moon" )
00204 Data->AngSize->setText( i18n("angular size in arcminutes", "%1 arcmin").arg(
00205 KGlobal::locale()->formatNumber( ps->angSize() ) ) );
00206 else
00207 Data->AngSize->setText( i18n("angular size in arcseconds", "%1 arcsec").arg(
00208 KGlobal::locale()->formatNumber( ps->angSize()*60.0 ) ) );
00209 } else {
00210 Data->AngSize->setText( "--" );
00211 }
00212
00213 break;
00214
00215 default:
00216 dso = (DeepSkyObject *)selectedObject;
00217
00218
00219 if ( ! dso->longname().isEmpty() && dso->longname() != dso->name() ) {
00220 pname = dso->translatedLongName();
00221 oname = dso->translatedName();
00222 } else {
00223 pname = dso->translatedName();
00224 }
00225
00226 if ( ! dso->translatedName2().isEmpty() ) {
00227 if ( oname.isEmpty() ) oname = dso->translatedName2();
00228 else oname += ", " + dso->translatedName2();
00229 }
00230
00231 if ( dso->ugc() != 0 ) {
00232 if ( ! oname.isEmpty() ) oname += ", ";
00233 oname += "UGC " + QString("%1").arg( dso->ugc() );
00234 }
00235 if ( dso->pgc() != 0 ) {
00236 if ( ! oname.isEmpty() ) oname += ", ";
00237 oname += "PGC " + QString("%1").arg( dso->pgc() );
00238 }
00239
00240 if ( ! oname.isEmpty() ) pname += ", " + oname;
00241 Data->Names->setText( pname );
00242
00243 Data->Type->setText( dso->typeName() );
00244
00245 if ( dso->mag() > 90.0 )
00246 Data->Mag->setText( "--" );
00247 else
00248 Data->Mag->setText( i18n( "number in magnitudes", "%1 mag" ).arg(
00249 KGlobal::locale()->formatNumber( dso->mag(), 1 ) ) );
00250
00251
00252 Data->Distance->setText( "--" );
00253
00254
00255 if ( dso->a() > 10.0 )
00256 Data->AngSize->setText( i18n("angular size in arcminutes", "%1 arcmin").arg(
00257 int( dso->a() ) ) );
00258 else if ( dso->a() )
00259 Data->AngSize->setText( i18n("angular size in arcminutes", "%1 arcmin").arg(
00260 KGlobal::locale()->formatNumber( dso->a(), 1 ) ) );
00261 else
00262 Data->AngSize->setText( "--" );
00263
00264 break;
00265 }
00266
00267
00268 Data->Constellation->setText( selectedObject->constellation( ksw->data()->csegmentList,
00269 ksw->data()->cnameList ) );
00270 }
00271
00272 void DetailDialog::createPositionTab( const KStarsDateTime &ut, GeoLocation *geo ) {
00273 QFrame *PosTab = addPage( i18n("Position") );
00274 Pos = new DetailsPositionUI( PosTab, "position_tab" );
00275
00276
00277 Pos->CoordTitle->setPaletteBackgroundColor( palette().color( QPalette::Active, QColorGroup::Highlight ) );
00278 Pos->CoordTitle->setPaletteForegroundColor( palette().color( QPalette::Active, QColorGroup::HighlightedText ) );
00279 Pos->CoordFrame->setPaletteForegroundColor( palette().color( QPalette::Active, QColorGroup::Highlight ) );
00280 Pos->RSTTitle->setPaletteBackgroundColor( palette().color( QPalette::Active, QColorGroup::Highlight ) );
00281 Pos->RSTTitle->setPaletteForegroundColor( palette().color( QPalette::Active, QColorGroup::HighlightedText ) );
00282 Pos->RSTFrame->setPaletteForegroundColor( palette().color( QPalette::Active, QColorGroup::Highlight ) );
00283 Pos->RA->setPalette( palette() );
00284 Pos->Dec->setPalette( palette() );
00285 Pos->Az->setPalette( palette() );
00286 Pos->Alt->setPalette( palette() );
00287 Pos->HA->setPalette( palette() );
00288 Pos->Airmass->setPalette( palette() );
00289 Pos->TimeRise->setPalette( palette() );
00290 Pos->TimeTransit->setPalette( palette() );
00291 Pos->TimeSet->setPalette( palette() );
00292 Pos->AzRise->setPalette( palette() );
00293 Pos->AltTransit->setPalette( palette() );
00294 Pos->AzSet->setPalette( palette() );
00295 Pos->RALabel->setPalette( palette() );
00296 Pos->DecLabel->setPalette( palette() );
00297 Pos->AzLabel->setPalette( palette() );
00298 Pos->AltLabel->setPalette( palette() );
00299 Pos->HALabel->setPalette( palette() );
00300 Pos->AirmassLabel->setPalette( palette() );
00301 Pos->TimeRiseLabel->setPalette( palette() );
00302 Pos->TimeTransitLabel->setPalette( palette() );
00303 Pos->TimeSetLabel->setPalette( palette() );
00304 Pos->AzRiseLabel->setPalette( palette() );
00305 Pos->AltTransitLabel->setPalette( palette() );
00306 Pos->AzSetLabel->setPalette( palette() );
00307
00308 QVBoxLayout *vlay = new QVBoxLayout( PosTab, 0, 0 );
00309 vlay->addWidget( Pos );
00310
00311
00312
00313
00314 QString sEpoch = QString::number( ut.epoch(), 'f', 1 );
00315
00316 sEpoch.replace( ".", KGlobal::locale()->decimalSymbol() );
00317
00318 Pos->RALabel->setText( i18n( "RA (%1):" ).arg( sEpoch ) );
00319 Pos->DecLabel->setText( i18n( "Dec (%1):" ).arg( sEpoch ) );
00320 Pos->RA->setText( selectedObject->ra()->toHMSString() );
00321 Pos->Dec->setText( selectedObject->dec()->toDMSString() );
00322 Pos->Az->setText( selectedObject->az()->toDMSString() );
00323 Pos->Alt->setText( selectedObject->alt()->toDMSString() );
00324
00325
00326
00327 dms lst = geo->GSTtoLST( ut.gst() );
00328 dms ha( lst.Degrees() - selectedObject->ra()->Degrees() );
00329 QChar sgn('+');
00330 if ( ha.Hours() > 12.0 ) {
00331 ha.setH( 24.0 - ha.Hours() );
00332 sgn = '-';
00333 }
00334 Pos->HA->setText( QString("%1%2").arg(sgn).arg( ha.toHMSString() ) );
00335
00336
00337
00338 if ( selectedObject->alt()->Degrees() > 0.0 )
00339 Pos->Airmass->setText( KGlobal::locale()->formatNumber(
00340 1./sin( selectedObject->alt()->radians() ), 2 ) );
00341 else
00342 Pos->Airmass->setText( "--" );
00343
00344
00345
00346
00347 QTime rt = selectedObject->riseSetTime( ut, geo, true );
00348 dms raz = selectedObject->riseSetTimeAz( ut, geo, true );
00349
00350
00351 QTime tt = selectedObject->transitTime( ut, geo );
00352 dms talt = selectedObject->transitAltitude( ut, geo );
00353 if ( tt < rt ) {
00354 tt = selectedObject->transitTime( ut.addDays( 1 ), geo );
00355 talt = selectedObject->transitAltitude( ut.addDays( 1 ), geo );
00356 }
00357
00358
00359 QTime st = selectedObject->riseSetTime( ut, geo, false );
00360 dms saz = selectedObject->riseSetTimeAz( ut, geo, false );
00361 if ( st < rt ) {
00362 st = selectedObject->riseSetTime( ut.addDays( 1 ), geo, false );
00363 saz = selectedObject->riseSetTimeAz( ut.addDays( 1 ), geo, false );
00364 }
00365
00366 if ( rt.isValid() ) {
00367 Pos->TimeRise->setText( QString().sprintf( "%02d:%02d", rt.hour(), rt.minute() ) );
00368 Pos->TimeSet->setText( QString().sprintf( "%02d:%02d", st.hour(), st.minute() ) );
00369 Pos->AzRise->setText( raz.toDMSString() );
00370 Pos->AzSet->setText( saz.toDMSString() );
00371 } else {
00372 if ( selectedObject->alt()->Degrees() > 0.0 ) {
00373 Pos->TimeRise->setText( i18n( "Circumpolar" ) );
00374 Pos->TimeSet->setText( i18n( "Circumpolar" ) );
00375 } else {
00376 Pos->TimeRise->setText( i18n( "Never rises" ) );
00377 Pos->TimeSet->setText( i18n( "Never rises" ) );
00378 }
00379
00380 Pos->AzRise->setText( i18n( "Not Applicable", "N/A" ) );
00381 Pos->AzSet->setText( i18n( "Not Applicable", "N/A" ) );
00382 }
00383
00384 Pos->TimeTransit->setText( QString().sprintf( "%02d:%02d", tt.hour(), tt.minute() ) );
00385 Pos->AltTransit->setText( talt.toDMSString() );
00386 }
00387
00388 void DetailDialog::createLinksTab()
00389 {
00390
00391 if (selectedObject->name() == QString("star"))
00392 return;
00393
00394 QFrame *LinksTab = addPage( i18n( "Links" ) );
00395 Links = new DetailsLinksUI( LinksTab, "links_tab" );
00396
00397
00398 Links->InfoTitle->setPaletteBackgroundColor( palette().color( QPalette::Active, QColorGroup::Text ) );
00399 Links->InfoTitle->setPaletteForegroundColor( palette().color( QPalette::Active, QColorGroup::Base ) );
00400 Links->ImagesTitle->setPaletteBackgroundColor( palette().color( QPalette::Active, QColorGroup::Text ) );
00401 Links->ImagesTitle->setPaletteForegroundColor( palette().color( QPalette::Active, QColorGroup::Base ) );
00402
00403 QPalette p = palette();
00404 p.setColor( QPalette::Active, QColorGroup::Dark, palette().color( QPalette::Active, QColorGroup::Highlight ) );
00405 Links->InfoList->setPalette( p );
00406 Links->ImagesList->setPalette( p );
00407
00408 QVBoxLayout *vlay = new QVBoxLayout( LinksTab, 0, 0 );
00409 vlay->addWidget( Links );
00410
00411 QStringList::Iterator itList = selectedObject->InfoList.begin();
00412 QStringList::Iterator itTitle = selectedObject->InfoTitle.begin();
00413 QStringList::Iterator itListEnd = selectedObject->InfoList.end();
00414
00415 for ( ; itList != itListEnd; ++itList ) {
00416 Links->InfoList->insertItem(QString(*itTitle));
00417 itTitle++;
00418 }
00419
00420 Links->InfoList->setSelected(0, true);
00421
00422 itList = selectedObject->ImageList.begin();
00423 itTitle = selectedObject->ImageTitle.begin();
00424 itListEnd = selectedObject->ImageList.end();
00425
00426 for ( ; itList != itListEnd; ++itList ) {
00427 Links->ImagesList->insertItem(QString(*itTitle));
00428 itTitle++;
00429 }
00430
00431 if (! Links->InfoList->count() && ! Links->ImagesList->count()) {
00432 Links->EditLinkButton->setDisabled(true);
00433 Links->RemoveLinkButton->setDisabled(true);
00434 }
00435
00436
00437 connect( Links->ViewButton, SIGNAL(clicked()), this, SLOT( viewLink() ) );
00438 connect( Links->AddLinkButton, SIGNAL(clicked()), ksw->map(), SLOT( addLink() ) );
00439 connect( Links->EditLinkButton, SIGNAL(clicked()), this, SLOT( editLinkDialog() ) );
00440 connect( Links->RemoveLinkButton, SIGNAL(clicked()), this, SLOT( removeLinkDialog() ) );
00441 connect( Links->InfoList, SIGNAL(highlighted(int)), this, SLOT( unselectImagesList() ) );
00442 connect( Links->ImagesList, SIGNAL(highlighted(int)), this, SLOT( unselectInfoList() ) );
00443 connect( ksw->map(), SIGNAL(linkAdded()), this, SLOT( updateLists() ) );
00444 }
00445
00446 void DetailDialog::createAdvancedTab()
00447 {
00448
00449
00450 if (selectedObject->name() == QString("star") ||
00451 ksw->data()->ADVtreeList.isEmpty() ||
00452 selectedObject->type() == SkyObject::PLANET ||
00453 selectedObject->type() == SkyObject::COMET ||
00454 selectedObject->type() == SkyObject::ASTEROID )
00455 return;
00456
00457 QFrame *AdvancedTab = addPage(i18n("Advanced"));
00458 Adv = new DetailsDatabaseUI( AdvancedTab, "database_tab" );
00459
00460 QVBoxLayout *vlay = new QVBoxLayout( AdvancedTab, 0, 0 );
00461 vlay->addWidget( Adv );
00462
00463 treeIt = new QPtrListIterator<ADVTreeData> (ksw->data()->ADVtreeList);
00464 connect( Adv->ADVTree, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(viewADVData()));
00465
00466 populateADVTree(NULL);
00467 }
00468
00469 void DetailDialog::createLogTab()
00470 {
00471
00472 if (selectedObject->name() == QString("star"))
00473 return;
00474
00475
00476 QFrame *LogTab = addPage(i18n("Log"));
00477 Log = new DetailsLogUI( LogTab, "log_tab" );
00478
00479
00480 Log->LogTitle->setPaletteBackgroundColor( palette().color( QPalette::Active, QColorGroup::Text ) );
00481 Log->LogTitle->setPaletteForegroundColor( palette().color( QPalette::Active, QColorGroup::Base ) );
00482
00483 QVBoxLayout *vlay = new QVBoxLayout( LogTab, 0, 0 );
00484 vlay->addWidget( Log );
00485
00486 if ( selectedObject->userLog.isEmpty() )
00487 Log->UserLog->setText(i18n("Record here observation logs and/or data on %1.").arg(selectedObject->translatedName()));
00488 else
00489 Log->UserLog->setText(selectedObject->userLog);
00490
00491
00492 connect( Log->UserLog, SIGNAL( focusOut() ), this, SLOT( saveLogData() ) );
00493 }
00494
00495
00496 void DetailDialog::unselectInfoList()
00497 {
00498 Links->InfoList->setSelected( Links->InfoList->currentItem(), false );
00499 }
00500
00501 void DetailDialog::unselectImagesList()
00502 {
00503 Links->ImagesList->setSelected( Links->ImagesList->currentItem(), false );
00504 }
00505
00506 void DetailDialog::viewLink()
00507 {
00508 QString URL;
00509
00510 if ( Links->InfoList->currentItem() != -1 &&
00511 Links->InfoList->isSelected( Links->InfoList->currentItem() ) )
00512 URL = QString( *selectedObject->InfoList.at( Links->InfoList->currentItem() ) );
00513 else if ( Links->ImagesList->currentItem() != -1 )
00514 URL = QString( *selectedObject->ImageList.at( Links->ImagesList->currentItem() ) );
00515
00516 if (!URL.isEmpty())
00517 kapp->invokeBrowser(URL);
00518 }
00519
00520 void DetailDialog::updateLists()
00521 {
00522 Links->InfoList->clear();
00523 Links->ImagesList->clear();
00524
00525 QStringList::Iterator itList = selectedObject->InfoList.begin();
00526 QStringList::Iterator itTitle = selectedObject->InfoTitle.begin();
00527 QStringList::Iterator itListEnd = selectedObject->InfoList.end();
00528
00529 for ( ; itList != itListEnd; ++itList ) {
00530 Links->InfoList->insertItem(QString(*itTitle));
00531 itTitle++;
00532 }
00533
00534 Links->InfoList->setSelected(0, true);
00535 itList = selectedObject->ImageList.begin();
00536 itTitle = selectedObject->ImageTitle.begin();
00537 itListEnd = selectedObject->ImageList.end();
00538
00539 for ( ; itList != itListEnd; ++itList ) {
00540 Links->ImagesList->insertItem(QString(*itTitle));
00541 itTitle++;
00542 }
00543 }
00544
00545 void DetailDialog::editLinkDialog()
00546 {
00547 int type;
00548 uint i;
00549 QString defaultURL , entry;
00550 QFile newFile;
00551
00552 KDialogBase editDialog(KDialogBase::Plain, i18n("Edit Link"), Ok|Cancel, Ok , this, "editlink", false);
00553 QFrame *editFrame = editDialog.plainPage();
00554
00555 editLinkURL = new QLabel(i18n("URL:"), editFrame);
00556 editLinkField = new QLineEdit(editFrame, "lineedit");
00557 editLinkField->setMinimumWidth(300);
00558 editLinkField->home(false);
00559 editLinkLayout = new QHBoxLayout(editFrame, 6, 6, "editlinklayout");
00560 editLinkLayout->addWidget(editLinkURL);
00561 editLinkLayout->addWidget(editLinkField);
00562
00563 currentItemIndex = Links->InfoList->currentItem();
00564
00565 if (currentItemIndex != -1 && Links->InfoList->isSelected(currentItemIndex))
00566 {
00567 defaultURL = *selectedObject->InfoList.at(currentItemIndex);
00568 editLinkField->setText(defaultURL);
00569 type = 1;
00570 currentItemTitle = Links->InfoList->currentText();
00571 }
00572 else if ( (currentItemIndex = Links->ImagesList->currentItem()) != -1)
00573 {
00574 defaultURL = *selectedObject->ImageList.at(currentItemIndex);
00575 editLinkField->setText(defaultURL);
00576 type = 0;
00577 currentItemTitle = Links->ImagesList->currentText();
00578 }
00579 else return;
00580
00581
00582 if (!editDialog.exec() == QDialog::Accepted)
00583 return;
00584
00585 if (!editLinkField->edited())
00586 return;
00587
00588
00589 currentItemURL = editLinkField->text();
00590 entry = selectedObject->name() + ":" + currentItemTitle + ":" + currentItemURL;
00591
00592
00593
00594
00595
00596 switch (type)
00597 {
00598 case 0:
00599 if (!verifyUserData(type))
00600 return;
00601 break;
00602 case 1:
00603 if (!verifyUserData(type))
00604 return;
00605 break;
00606 }
00607
00608
00609 newFile.setName(file.name());
00610 newFile.open(IO_WriteOnly);
00611
00612 QTextStream newStream(&newFile);
00613
00614 for (i=0; i<dataList.count(); i++)
00615 {
00616 newStream << dataList[i] << endl;
00617 continue;
00618 }
00619
00620 if (type==0)
00621 {
00622 *selectedObject->ImageTitle.at(currentItemIndex) = currentItemTitle;
00623 *selectedObject->ImageList.at(currentItemIndex) = currentItemURL;
00624 }
00625 else
00626 {
00627 *selectedObject->InfoTitle.at(currentItemIndex) = currentItemTitle;
00628 *selectedObject->InfoList.at(currentItemIndex) = currentItemURL;
00629 }
00630
00631 newStream << entry << endl;
00632
00633 newFile.close();
00634 file.close();
00635 updateLists();
00636 }
00637
00638 void DetailDialog::removeLinkDialog()
00639 {
00640 int type;
00641 uint i;
00642 QString defaultURL, entry;
00643 QFile newFile;
00644
00645 currentItemIndex = Links->InfoList->currentItem();
00646
00647 if (currentItemIndex != -1 && Links->InfoList->isSelected(currentItemIndex))
00648 {
00649 defaultURL = *selectedObject->InfoList.at(currentItemIndex);
00650 type = 1;
00651 currentItemTitle = Links->InfoList->currentText();
00652 }
00653 else
00654 {
00655 currentItemIndex = Links->ImagesList->currentItem();
00656 defaultURL = *selectedObject->ImageList.at(currentItemIndex);
00657 type = 0;
00658 currentItemTitle = Links->ImagesList->currentText();
00659 }
00660
00661 if (KMessageBox::warningContinueCancel( 0, i18n("Are you sure you want to remove the %1 link?").arg(currentItemTitle), i18n("Delete Confirmation"),KStdGuiItem::del())!=KMessageBox::Continue)
00662 return;
00663
00664 switch (type)
00665 {
00666 case 0:
00667 if (!verifyUserData(type))
00668 return;
00669 selectedObject->ImageTitle.remove( selectedObject->ImageTitle.at(currentItemIndex));
00670 selectedObject->ImageList.remove( selectedObject->ImageList.at(currentItemIndex));
00671 break;
00672
00673 case 1:
00674 if (!verifyUserData(type))
00675 return;
00676 selectedObject->InfoTitle.remove(selectedObject->InfoTitle.at(currentItemIndex));
00677 selectedObject->InfoList.remove(selectedObject->InfoList.at(currentItemIndex));
00678 break;
00679 }
00680
00681
00682 newFile.setName(file.name());
00683 newFile.open(IO_WriteOnly);
00684
00685 QTextStream newStream(&newFile);
00686
00687 for (i=0; i<dataList.count(); i++)
00688 newStream << dataList[i] << endl;
00689
00690 newFile.close();
00691 file.close();
00692 updateLists();
00693 }
00694
00695 bool DetailDialog::verifyUserData(int type)
00696 {
00697 QString line, name, sub, title;
00698 bool ObjectFound = false;
00699 uint i;
00700
00701 switch (type)
00702 {
00703 case 0:
00704 if (!readUserFile(type))
00705 return false;
00706 for (i=0; i<dataList.count(); i++)
00707 {
00708 line = dataList[i];
00709 name = line.mid( 0, line.find(':') );
00710 sub = line.mid( line.find(':')+1 );
00711 title = sub.mid( 0, sub.find(':') );
00712 if (name == selectedObject->name() && title == currentItemTitle)
00713 {
00714 ObjectFound = true;
00715 dataList.remove(dataList.at(i));
00716 break;
00717 }
00718 }
00719 break;
00720 case 1:
00721 if (!readUserFile(type))
00722 return false;
00723 for (i=0; i<dataList.count(); i++)
00724 {
00725 line = dataList[i];
00726 name = line.mid( 0, line.find(':') );
00727 sub = line.mid( line.find(':')+1 );
00728 title = sub.mid( 0, sub.find(':') );
00729 if (name == selectedObject->name() && title == currentItemTitle)
00730 {
00731 ObjectFound = true;
00732 dataList.remove(dataList.at(i));
00733 break;
00734 }
00735 }
00736 break;
00737 }
00738 return ObjectFound;
00739 }
00740
00741 bool DetailDialog::readUserFile(int type)
00742 {
00743 switch (type)
00744 {
00745 case 0:
00746 file.setName( locateLocal( "appdata", "image_url.dat" ) );
00747 if ( !file.open( IO_ReadOnly) )
00748 {
00749 ksw->data()->initError("image_url.dat", false);
00750 return false;
00751 }
00752 break;
00753
00754 case 1:
00755 file.setName( locateLocal( "appdata", "info_url.dat" ) );
00756 if ( !file.open( IO_ReadOnly) )
00757 {
00758 ksw->data()->initError("info_url.dat", false);
00759 return false;
00760 }
00761 break;
00762 }
00763
00764
00765 file.reset();
00766 QTextStream stream(&file);
00767
00768 dataList.clear();
00769
00770
00771 while (!stream.eof())
00772 dataList.append(stream.readLine());
00773
00774 return true;
00775 }
00776
00777 void DetailDialog::populateADVTree(QListViewItem *parent)
00778 {
00779
00780 if (!treeIt->current())
00781 return;
00782
00783
00784 if (treeIt->current()->Type == 0)
00785 forkTree(parent);
00786
00787 while (treeIt->current())
00788 {
00789 if (treeIt->current()->Type == 0)
00790 {
00791 forkTree(parent);
00792 continue;
00793 }
00794 else if (treeIt->current()->Type == 1)
00795 break;
00796
00797 if (parent)
00798 new QListViewItem( parent, treeIt->current()->Name);
00799 else
00800 new QListViewItem( Adv->ADVTree, treeIt->current()->Name);
00801
00802 ++(*treeIt);
00803 }
00804 }
00805
00806 void DetailDialog::forkTree(QListViewItem *parent)
00807 {
00808 QListViewItem *current = 0;
00809 if (parent)
00810 current = new QListViewItem(parent, treeIt->current()->Name);
00811 else
00812 current = new QListViewItem(Adv->ADVTree, treeIt->current()->Name);
00813
00814
00815 ++(*treeIt);
00816 populateADVTree(current);
00817 ++(*treeIt);
00818 }
00819
00820 void DetailDialog::viewADVData()
00821 {
00822 QString link;
00823 QListViewItem * current = Adv->ADVTree->currentItem();
00824
00825 if (!current) return;
00826
00827 treeIt->toFirst();
00828 while (treeIt->current())
00829 {
00830 if (treeIt->current()->Name == current->text(0))
00831 {
00832 if (treeIt->current()->Type == 2) break;
00833 else return;
00834 }
00835 ++(*treeIt);
00836 }
00837
00838 link = treeIt->current()->Link;
00839 link = parseADVData(link);
00840 kapp->invokeBrowser(link);
00841 }
00842
00843 QString DetailDialog::parseADVData(QString link)
00844 {
00845 QString subLink;
00846 int index;
00847
00848 if ( (index = link.find("KSOBJ")) != -1)
00849 {
00850 link.remove(index, 5);
00851 link = link.insert(index, selectedObject->name());
00852 }
00853
00854 if ( (index = link.find("KSRA")) != -1)
00855 {
00856 link.remove(index, 4);
00857 subLink = QString().sprintf("%02d%02d%02d", selectedObject->ra0()->hour(), selectedObject->ra0()->minute(), selectedObject->ra0()->second());
00858 subLink = subLink.insert(2, "%20");
00859 subLink = subLink.insert(7, "%20");
00860
00861 link = link.insert(index, subLink);
00862 }
00863 if ( (index = link.find("KSDEC")) != -1)
00864 {
00865 link.remove(index, 5);
00866 if (selectedObject->dec()->degree() < 0)
00867 {
00868 subLink = QString().sprintf("%03d%02d%02d", selectedObject->dec0()->degree(), selectedObject->dec0()->arcmin(), selectedObject->dec0()->arcsec());
00869 subLink = subLink.insert(3, "%20");
00870 subLink = subLink.insert(8, "%20");
00871 }
00872 else
00873 {
00874 subLink = QString().sprintf("%02d%02d%02d", selectedObject->dec0()->degree(), selectedObject->dec0()->arcmin(), selectedObject->dec0()->arcsec());
00875 subLink = subLink.insert(0, "%2B");
00876 subLink = subLink.insert(5, "%20");
00877 subLink = subLink.insert(10, "%20");
00878 }
00879 link = link.insert(index, subLink);
00880 }
00881
00882 return link;
00883 }
00884
00885 void DetailDialog::saveLogData() {
00886 selectedObject->saveUserLog( Log->UserLog->text() );
00887 }
00888
00889 void DetailDialog::addToObservingList() {
00890 ksw->observingList()->slotAddObject( selectedObject );
00891 }
00892
00893 void DetailDialog::centerMap() {
00894 ksw->map()->setClickedObject( selectedObject );
00895 ksw->map()->slotCenter();
00896 }
00897
00898 void DetailDialog::centerTelescope()
00899 {
00900
00901 INDI_D *indidev(NULL);
00902 INDI_P *prop(NULL), *onset(NULL);
00903 INDI_E *RAEle(NULL), *DecEle(NULL), *AzEle(NULL), *AltEle(NULL), *ConnectEle(NULL), *nameEle(NULL);
00904 bool useJ2000( false);
00905 int selectedCoord(0);
00906 SkyPoint sp;
00907
00908
00909
00910
00911 INDIMenu *imenu = ksw->getINDIMenu();
00912
00913
00914 for (unsigned int i=0; i < imenu->mgr.count() ; i++)
00915 {
00916 for (unsigned int j=0; j < imenu->mgr.at(i)->indi_dev.count(); j++)
00917 {
00918 indidev = imenu->mgr.at(i)->indi_dev.at(j);
00919 indidev->stdDev->currentObject = NULL;
00920 prop = indidev->findProp("EQUATORIAL_EOD_COORD");
00921 if (prop == NULL)
00922 {
00923 prop = indidev->findProp("EQUATORIAL_COORD");
00924 if (prop == NULL)
00925 {
00926 prop = indidev->findProp("HORIZONTAL_COORD");
00927 if (prop == NULL)
00928 continue;
00929 else
00930 selectedCoord = 1;
00931 }
00932 else
00933 useJ2000 = true;
00934 }
00935
00936 ConnectEle = indidev->findElem("CONNECT");
00937 if (!ConnectEle) continue;
00938
00939 if (ConnectEle->state == PS_OFF)
00940 {
00941 KMessageBox::error(0, i18n("Telescope %1 is offline. Please connect and retry again.").arg(indidev->label));
00942 return;
00943 }
00944
00945 switch (selectedCoord)
00946 {
00947
00948 case 0:
00949 if (prop->perm == PP_RO) continue;
00950 RAEle = prop->findElement("RA");
00951 if (!RAEle) continue;
00952 DecEle = prop->findElement("DEC");
00953 if (!DecEle) continue;
00954 break;
00955
00956
00957 case 1:
00958 if (prop->perm == PP_RO) continue;
00959 AzEle = prop->findElement("AZ");
00960 if (!AzEle) continue;
00961 AltEle = prop->findElement("ALT");
00962 if (!AltEle) continue;
00963 break;
00964 }
00965
00966 onset = indidev->findProp("ON_COORD_SET");
00967 if (!onset) continue;
00968
00969 onset->activateSwitch("SLEW");
00970
00971 indidev->stdDev->currentObject = selectedObject;
00972
00973
00974 if (indidev->stdDev->currentObject)
00975 {
00976 nameEle = indidev->findElem("OBJECT_NAME");
00977 if (nameEle && nameEle->pp->perm != PP_RO)
00978 {
00979 nameEle->write_w->setText(indidev->stdDev->currentObject->name());
00980 nameEle->pp->newText();
00981 }
00982 }
00983
00984 switch (selectedCoord)
00985 {
00986 case 0:
00987 if (indidev->stdDev->currentObject)
00988 sp.set (indidev->stdDev->currentObject->ra(), indidev->stdDev->currentObject->dec());
00989 else
00990 sp.set (ksw->map()->clickedPoint()->ra(), ksw->map()->clickedPoint()->dec());
00991
00992 if (useJ2000)
00993 sp.apparentCoord(ksw->data()->ut().djd(), (long double) J2000);
00994
00995 RAEle->write_w->setText(QString("%1:%2:%3").arg(sp.ra()->hour()).arg(sp.ra()->minute()).arg(sp.ra()->second()));
00996 DecEle->write_w->setText(QString("%1:%2:%3").arg(sp.dec()->degree()).arg(sp.dec()->arcmin()).arg(sp.dec()->arcsec()));
00997
00998 break;
00999
01000 case 1:
01001 if (indidev->stdDev->currentObject)
01002 {
01003 sp.setAz(*indidev->stdDev->currentObject->az());
01004 sp.setAlt(*indidev->stdDev->currentObject->alt());
01005 }
01006 else
01007 {
01008 sp.setAz(*ksw->map()->clickedPoint()->az());
01009 sp.setAlt(*ksw->map()->clickedPoint()->alt());
01010 }
01011
01012 AzEle->write_w->setText(QString("%1:%2:%3").arg(sp.az()->degree()).arg(sp.az()->arcmin()).arg(sp.az()->arcsec()));
01013 AltEle->write_w->setText(QString("%1:%2:%3").arg(sp.alt()->degree()).arg(sp.alt()->arcmin()).arg(sp.alt()->arcsec()));
01014
01015 break;
01016 }
01017
01018 prop->newText();
01019
01020 return;
01021 }
01022 }
01023
01024
01025 KMessageBox::sorry(0, i18n("KStars did not find any active telescopes."));
01026
01027 }
01028
01029 void DetailDialog::showThumbnail() {
01030
01031 if ( selectedObject->type() == SkyObject::STAR ||
01032 selectedObject->type() == SkyObject::CATALOG_STAR ) {
01033 Thumbnail->resize( Data->Image->width(), Data->Image->height() );
01034 Thumbnail->fill( Data->paletteBackgroundColor() );
01035 Data->Image->setPixmap( *Thumbnail );
01036 return;
01037 }
01038
01039
01040
01041
01042 QFile file;
01043 QString fname = "thumb-" + selectedObject->name().lower().replace( QRegExp(" "), "" ) + ".png";
01044 if ( KSUtils::openDataFile( file, fname ) ) {
01045 file.close();
01046 Thumbnail->load( file.name(), "PNG" );
01047 } else if ( KSUtils::openDataFile( file, "noimage.png" ) ) {
01048 file.close();
01049 Thumbnail->load( file.name(), "PNG" );
01050 } else {
01051 Thumbnail->resize( Data->Image->width(), Data->Image->height() );
01052 Thumbnail->fill( Data->paletteBackgroundColor() );
01053 }
01054
01055 Data->Image->setPixmap( *Thumbnail );
01056 }
01057
01058 void DetailDialog::updateThumbnail() {
01059 ThumbnailPicker tp( selectedObject, *Thumbnail, this, "thumbnaileditor" );
01060
01061 if ( tp.exec() == QDialog::Accepted ) {
01062 QString fname = locateLocal( "appdata", "thumb-"
01063 + selectedObject->name().lower().replace( QRegExp(" "), "" ) + ".png" );
01064
01065 Data->Image->setPixmap( *(tp.image()) );
01066
01067
01068
01069 if ( tp.imageFound() ) {
01070 Data->Image->pixmap()->save( fname, "PNG" );
01071 *Thumbnail = *(Data->Image->pixmap());
01072 } else {
01073 QFile f;
01074 f.setName( fname );
01075 f.remove();
01076 }
01077 }
01078 }
01079
01080 #include "detaildialog.moc"