File indexing completed on 2024-04-14 14:11:44
0001 /* 0002 SPDX-FileCopyrightText: 2003 Jason Harris <kstars@30doradus.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "scriptbuilder.h" 0008 0009 #include "kspaths.h" 0010 #include "scriptfunction.h" 0011 #include "kstars.h" 0012 #include "kstarsdata.h" 0013 #include "skymap.h" 0014 #include "ksnotification.h" 0015 #include "kstarsdatetime.h" 0016 #include "dialogs/finddialog.h" 0017 #include "dialogs/locationdialog.h" 0018 #include "widgets/dmsbox.h" 0019 #include "widgets/timespinbox.h" 0020 #include "widgets/timestepbox.h" 0021 0022 #include <KLocalizedString> 0023 #include <KMessageBox> 0024 #include <KIO/StoredTransferJob> 0025 #include <KIO/CopyJob> 0026 #include <KJob> 0027 0028 #include <QApplication> 0029 #include <QFontMetrics> 0030 #include <QTreeWidget> 0031 #include <QTextStream> 0032 #include <QFileDialog> 0033 #include <QStandardPaths> 0034 #include <QTemporaryFile> 0035 #include <QProcess> 0036 #include <QDebug> 0037 0038 #include <sys/stat.h> 0039 0040 OptionsTreeViewWidget::OptionsTreeViewWidget(QWidget *p) : QFrame(p) 0041 { 0042 setupUi(this); 0043 } 0044 0045 OptionsTreeView::OptionsTreeView(QWidget *p) : QDialog(p) 0046 { 0047 otvw.reset(new OptionsTreeViewWidget(this)); 0048 0049 QVBoxLayout *mainLayout = new QVBoxLayout; 0050 0051 mainLayout->addWidget(otvw.get()); 0052 setLayout(mainLayout); 0053 0054 setWindowTitle(i18nc("@title:window", "Options")); 0055 0056 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); 0057 mainLayout->addWidget(buttonBox); 0058 connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); 0059 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 0060 0061 setModal(false); 0062 } 0063 0064 void OptionsTreeView::resizeColumns() 0065 { 0066 //Size each column to the maximum width of items in that column 0067 int maxwidth[3] = { 0, 0, 0 }; 0068 QFontMetrics qfm = optionsList()->fontMetrics(); 0069 0070 for (int i = 0; i < optionsList()->topLevelItemCount(); ++i) 0071 { 0072 QTreeWidgetItem *topitem = optionsList()->topLevelItem(i); 0073 topitem->setExpanded(true); 0074 0075 for (int j = 0; j < topitem->childCount(); ++j) 0076 { 0077 QTreeWidgetItem *child = topitem->child(j); 0078 0079 for (int icol = 0; icol < 3; ++icol) 0080 { 0081 child->setExpanded(true); 0082 0083 int w = qfm.horizontalAdvance(child->text(icol)) + 4; 0084 0085 if (icol == 0) 0086 { 0087 w += 2 * optionsList()->indentation(); 0088 } 0089 0090 if (w > maxwidth[icol]) 0091 { 0092 maxwidth[icol] = w; 0093 } 0094 } 0095 } 0096 } 0097 0098 for (int icol = 0; icol < 3; ++icol) 0099 { 0100 //DEBUG 0101 qDebug() << Q_FUNC_INFO << QString("max width of column %1: %2").arg(icol).arg(maxwidth[icol]); 0102 0103 optionsList()->setColumnWidth(icol, maxwidth[icol]); 0104 } 0105 } 0106 0107 ScriptNameWidget::ScriptNameWidget(QWidget *p) : QFrame(p) 0108 { 0109 setupUi(this); 0110 } 0111 0112 ScriptNameDialog::ScriptNameDialog(QWidget *p) : QDialog(p) 0113 { 0114 #ifdef Q_OS_OSX 0115 setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); 0116 #endif 0117 snw = new ScriptNameWidget(this); 0118 0119 QVBoxLayout *mainLayout = new QVBoxLayout; 0120 0121 mainLayout->addWidget(snw); 0122 setLayout(mainLayout); 0123 0124 setWindowTitle(i18nc("@title:window", "Script Data")); 0125 0126 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); 0127 mainLayout->addWidget(buttonBox); 0128 connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); 0129 connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); 0130 0131 okB = buttonBox->button(QDialogButtonBox::Ok); 0132 0133 connect(snw->ScriptName, SIGNAL(textChanged(QString)), this, SLOT(slotEnableOkButton())); 0134 } 0135 0136 ScriptNameDialog::~ScriptNameDialog() 0137 { 0138 delete snw; 0139 } 0140 0141 void ScriptNameDialog::slotEnableOkButton() 0142 { 0143 okB->setEnabled(!snw->ScriptName->text().isEmpty()); 0144 } 0145 0146 ScriptBuilderUI::ScriptBuilderUI(QWidget *p) : QFrame(p) 0147 { 0148 setupUi(this); 0149 } 0150 0151 ScriptBuilder::ScriptBuilder(QWidget *parent) 0152 : QDialog(parent), UnsavedChanges(false), checkForChanges(true), currentFileURL(), currentDir(QDir::homePath()), 0153 currentScriptName(), currentAuthor() 0154 { 0155 #ifdef Q_OS_OSX 0156 setWindowFlags(Qt::Tool | Qt::WindowStaysOnTopHint); 0157 #endif 0158 sb = new ScriptBuilderUI(this); 0159 0160 QVBoxLayout *mainLayout = new QVBoxLayout; 0161 0162 mainLayout->addWidget(sb); 0163 setLayout(mainLayout); 0164 0165 setWindowTitle(i18nc("@title:window", "Script Builder")); 0166 0167 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close); 0168 mainLayout->addWidget(buttonBox); 0169 connect(buttonBox, SIGNAL(rejected()), this, SLOT(slotClose())); 0170 0171 sb->FuncDoc->setTextInteractionFlags(Qt::NoTextInteraction); 0172 0173 //Initialize function templates and descriptions 0174 KStarsFunctionList.append(new ScriptFunction("lookTowards", 0175 i18n("Point the display at the specified location. %1 can be the name " 0176 "of an object, a cardinal point on the compass, or 'zenith'.", 0177 QString("dir")), 0178 false, "QString", "dir")); 0179 KStarsFunctionList.append(new ScriptFunction( 0180 "addLabel", i18n("Add a name label to the object named %1.", QString("name")), false, "QString", "name")); 0181 KStarsFunctionList.append( 0182 new ScriptFunction("removeLabel", i18n("Remove the name label from the object named %1.", QString("name")), 0183 false, "QString", "name")); 0184 KStarsFunctionList.append(new ScriptFunction( 0185 "addTrail", i18n("Add a trail to the solar system body named %1.", QString("name")), false, "QString", "name")); 0186 KStarsFunctionList.append(new ScriptFunction( 0187 "removeTrail", i18n("Remove the trail from the solar system body named %1.", QString("name")), false, "QString", 0188 "name")); 0189 KStarsFunctionList.append(new ScriptFunction("setRaDec", 0190 i18n("Point the display at the specified RA/Dec coordinates. RA is " 0191 "expressed in Hours; Dec is expressed in Degrees."), 0192 false, "double", "ra", "double", "dec")); 0193 KStarsFunctionList.append(new ScriptFunction( 0194 "setAltAz", 0195 i18n("Point the display at the specified Alt/Az coordinates. Alt and Az are expressed in Degrees."), false, 0196 "double", "alt", "double", "az")); 0197 KStarsFunctionList.append(new ScriptFunction("zoomIn", i18n("Increase the display Zoom Level."), false)); 0198 KStarsFunctionList.append(new ScriptFunction("zoomOut", i18n("Decrease the display Zoom Level."), false)); 0199 KStarsFunctionList.append( 0200 new ScriptFunction("defaultZoom", i18n("Set the display Zoom Level to its default value."), false)); 0201 KStarsFunctionList.append( 0202 new ScriptFunction("zoom", i18n("Set the display Zoom Level manually."), false, "double", "z")); 0203 KStarsFunctionList.append( 0204 new ScriptFunction("setLocalTime", i18n("Set the system clock to the specified Local Time."), false, "int", 0205 "year", "int", "month", "int", "day", "int", "hour", "int", "minute", "int", "second")); 0206 KStarsFunctionList.append(new ScriptFunction( 0207 "waitFor", i18n("Pause script execution for specified number of seconds."), false, "double", "sec")); 0208 KStarsFunctionList.append(new ScriptFunction("waitForKey", 0209 i18n("Halt script execution until the specified key is pressed. Only " 0210 "single-key strokes are possible; use 'space' for the spacebar."), 0211 false, "QString", "key")); 0212 KStarsFunctionList.append(new ScriptFunction( 0213 "setTracking", i18n("Set whether the display is tracking the current location."), false, "bool", "track")); 0214 KStarsFunctionList.append(new ScriptFunction( 0215 "changeViewOption", i18n("Change view option named %1 to value %2.", QString("opName"), QString("opValue")), 0216 false, "QString", "opName", "QString", "opValue")); 0217 KStarsFunctionList.append(new ScriptFunction( 0218 "setGeoLocation", i18n("Set the geographic location to the city specified by city, province and country."), 0219 false, "QString", "cityName", "QString", "provinceName", "QString", "countryName")); 0220 KStarsFunctionList.append(new ScriptFunction( 0221 "setColor", i18n("Set the color named %1 to the value %2.", QString("colorName"), QString("value")), false, 0222 "QString", "colorName", "QString", "value")); 0223 KStarsFunctionList.append(new ScriptFunction("loadColorScheme", i18n("Load the color scheme specified by name."), 0224 false, "QString", "name")); 0225 KStarsFunctionList.append( 0226 new ScriptFunction("exportImage", i18n("Export the sky image to the file, with specified width and height."), 0227 false, "QString", "fileName", "int", "width", "int", "height")); 0228 KStarsFunctionList.append( 0229 new ScriptFunction("printImage", 0230 i18n("Print the sky image to a printer or file. If %1 is true, it will show the print " 0231 "dialog. If %2 is true, it will use the Star Chart color scheme for printing.", 0232 QString("usePrintDialog"), QString("useChartColors")), 0233 false, "bool", "usePrintDialog", "bool", "useChartColors")); 0234 SimClockFunctionList.append(new ScriptFunction("stop", i18n("Halt the simulation clock."), true)); 0235 SimClockFunctionList.append(new ScriptFunction("start", i18n("Start the simulation clock."), true)); 0236 SimClockFunctionList.append(new ScriptFunction("setClockScale", 0237 i18n("Set the timescale of the simulation clock to specified scale. " 0238 " 1.0 means real-time; 2.0 means twice real-time; etc."), 0239 true, "double", "scale")); 0240 0241 // JM: We're using QTreeWdiget for Qt4 now 0242 QTreeWidgetItem *kstars_tree = new QTreeWidgetItem(sb->FunctionTree, QStringList("KStars")); 0243 QTreeWidgetItem *simclock_tree = new QTreeWidgetItem(sb->FunctionTree, QStringList("SimClock")); 0244 0245 for (auto &item : KStarsFunctionList) 0246 new QTreeWidgetItem(kstars_tree, QStringList(item->prototype())); 0247 0248 for (auto &item : SimClockFunctionList) 0249 new QTreeWidgetItem(simclock_tree, QStringList(item->prototype())); 0250 0251 kstars_tree->sortChildren(0, Qt::AscendingOrder); 0252 simclock_tree->sortChildren(0, Qt::AscendingOrder); 0253 0254 sb->FunctionTree->setColumnCount(1); 0255 sb->FunctionTree->setHeaderLabels(QStringList(i18n("Functions"))); 0256 sb->FunctionTree->setSortingEnabled(false); 0257 0258 //Add icons to Push Buttons 0259 sb->NewButton->setIcon(QIcon::fromTheme("document-new")); 0260 sb->OpenButton->setIcon(QIcon::fromTheme("document-open")); 0261 sb->SaveButton->setIcon(QIcon::fromTheme("document-save")); 0262 sb->SaveAsButton->setIcon( 0263 QIcon::fromTheme("document-save-as")); 0264 sb->RunButton->setIcon(QIcon::fromTheme("system-run")); 0265 sb->CopyButton->setIcon(QIcon::fromTheme("view-refresh")); 0266 sb->AddButton->setIcon(QIcon::fromTheme("go-previous")); 0267 sb->RemoveButton->setIcon(QIcon::fromTheme("go-next")); 0268 sb->UpButton->setIcon(QIcon::fromTheme("go-up")); 0269 sb->DownButton->setIcon(QIcon::fromTheme("go-down")); 0270 0271 sb->NewButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); 0272 sb->OpenButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); 0273 sb->SaveButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); 0274 sb->SaveAsButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); 0275 sb->RunButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); 0276 sb->CopyButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); 0277 sb->AddButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); 0278 sb->RemoveButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); 0279 sb->UpButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); 0280 sb->DownButton->setAttribute(Qt::WA_LayoutUsesWidgetRect); 0281 0282 //Prepare the widget stack 0283 argBlank = new QWidget(); 0284 argLookToward = new ArgLookToward(sb->ArgStack); 0285 argFindObject = new ArgFindObject(sb->ArgStack); //shared by Add/RemoveLabel and Add/RemoveTrail 0286 argSetRaDec = new ArgSetRaDec(sb->ArgStack); 0287 argSetAltAz = new ArgSetAltAz(sb->ArgStack); 0288 argSetLocalTime = new ArgSetLocalTime(sb->ArgStack); 0289 argWaitFor = new ArgWaitFor(sb->ArgStack); 0290 argWaitForKey = new ArgWaitForKey(sb->ArgStack); 0291 argSetTracking = new ArgSetTrack(sb->ArgStack); 0292 argChangeViewOption = new ArgChangeViewOption(sb->ArgStack); 0293 argSetGeoLocation = new ArgSetGeoLocation(sb->ArgStack); 0294 argTimeScale = new ArgTimeScale(sb->ArgStack); 0295 argZoom = new ArgZoom(sb->ArgStack); 0296 argExportImage = new ArgExportImage(sb->ArgStack); 0297 argPrintImage = new ArgPrintImage(sb->ArgStack); 0298 argSetColor = new ArgSetColor(sb->ArgStack); 0299 argLoadColorScheme = new ArgLoadColorScheme(sb->ArgStack); 0300 0301 sb->ArgStack->addWidget(argBlank); 0302 sb->ArgStack->addWidget(argLookToward); 0303 sb->ArgStack->addWidget(argFindObject); 0304 sb->ArgStack->addWidget(argSetRaDec); 0305 sb->ArgStack->addWidget(argSetAltAz); 0306 sb->ArgStack->addWidget(argSetLocalTime); 0307 sb->ArgStack->addWidget(argWaitFor); 0308 sb->ArgStack->addWidget(argWaitForKey); 0309 sb->ArgStack->addWidget(argSetTracking); 0310 sb->ArgStack->addWidget(argChangeViewOption); 0311 sb->ArgStack->addWidget(argSetGeoLocation); 0312 sb->ArgStack->addWidget(argTimeScale); 0313 sb->ArgStack->addWidget(argZoom); 0314 sb->ArgStack->addWidget(argExportImage); 0315 sb->ArgStack->addWidget(argPrintImage); 0316 sb->ArgStack->addWidget(argSetColor); 0317 sb->ArgStack->addWidget(argLoadColorScheme); 0318 0319 sb->ArgStack->setCurrentIndex(0); 0320 0321 snd = new ScriptNameDialog(KStars::Instance()); 0322 otv = new OptionsTreeView(KStars::Instance()); 0323 0324 otv->resize(sb->width(), 0.5 * sb->height()); 0325 0326 initViewOptions(); 0327 otv->resizeColumns(); 0328 0329 //connect widgets in ScriptBuilderUI 0330 connect(sb->FunctionTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(slotAddFunction())); 0331 connect(sb->FunctionTree, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(slotShowDoc())); 0332 connect(sb->UpButton, SIGNAL(clicked()), this, SLOT(slotMoveFunctionUp())); 0333 connect(sb->ScriptListBox, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(slotArgWidget())); 0334 connect(sb->DownButton, SIGNAL(clicked()), this, SLOT(slotMoveFunctionDown())); 0335 connect(sb->CopyButton, SIGNAL(clicked()), this, SLOT(slotCopyFunction())); 0336 connect(sb->RemoveButton, SIGNAL(clicked()), this, SLOT(slotRemoveFunction())); 0337 connect(sb->NewButton, SIGNAL(clicked()), this, SLOT(slotNew())); 0338 connect(sb->OpenButton, SIGNAL(clicked()), this, SLOT(slotOpen())); 0339 connect(sb->SaveButton, SIGNAL(clicked()), this, SLOT(slotSave())); 0340 connect(sb->SaveAsButton, SIGNAL(clicked()), this, SLOT(slotSaveAs())); 0341 connect(sb->AddButton, SIGNAL(clicked()), this, SLOT(slotAddFunction())); 0342 connect(sb->RunButton, SIGNAL(clicked()), this, SLOT(slotRunScript())); 0343 0344 //Connections for Arg Widgets 0345 connect(argSetGeoLocation->FindCityButton, SIGNAL(clicked()), this, SLOT(slotFindCity())); 0346 connect(argLookToward->FindButton, SIGNAL(clicked()), this, SLOT(slotFindObject())); 0347 connect(argChangeViewOption->TreeButton, SIGNAL(clicked()), this, SLOT(slotShowOptions())); 0348 connect(argFindObject->FindButton, SIGNAL(clicked()), this, SLOT(slotFindObject())); 0349 0350 connect(argLookToward->FocusEdit, SIGNAL(editTextChanged(QString)), this, SLOT(slotLookToward())); 0351 connect(argFindObject->NameEdit, SIGNAL(textChanged(QString)), this, SLOT(slotArgFindObject())); 0352 connect(argSetRaDec->RABox, SIGNAL(textChanged(QString)), this, SLOT(slotRa())); 0353 connect(argSetRaDec->DecBox, SIGNAL(textChanged(QString)), this, SLOT(slotDec())); 0354 connect(argSetAltAz->AltBox, SIGNAL(textChanged(QString)), this, SLOT(slotAlt())); 0355 connect(argSetAltAz->AzBox, SIGNAL(textChanged(QString)), this, SLOT(slotAz())); 0356 connect(argSetLocalTime->DateWidget, SIGNAL(dateChanged(QDate)), this, SLOT(slotChangeDate())); 0357 connect(argSetLocalTime->TimeBox, SIGNAL(timeChanged(QTime)), this, SLOT(slotChangeTime())); 0358 connect(argWaitFor->DelayBox, SIGNAL(valueChanged(int)), this, SLOT(slotWaitFor())); 0359 connect(argWaitForKey->WaitKeyEdit, SIGNAL(textChanged(QString)), this, SLOT(slotWaitForKey())); 0360 connect(argSetTracking->CheckTrack, SIGNAL(stateChanged(int)), this, SLOT(slotTracking())); 0361 connect(argChangeViewOption->OptionName, SIGNAL(activated(QString)), this, SLOT(slotViewOption())); 0362 connect(argChangeViewOption->OptionValue, SIGNAL(textChanged(QString)), this, SLOT(slotViewOption())); 0363 connect(argSetGeoLocation->CityName, SIGNAL(textChanged(QString)), this, SLOT(slotChangeCity())); 0364 connect(argSetGeoLocation->ProvinceName, SIGNAL(textChanged(QString)), this, SLOT(slotChangeProvince())); 0365 connect(argSetGeoLocation->CountryName, SIGNAL(textChanged(QString)), this, SLOT(slotChangeCountry())); 0366 connect(argTimeScale->TimeScale, SIGNAL(scaleChanged(float)), this, SLOT(slotTimeScale())); 0367 connect(argZoom->ZoomBox, SIGNAL(textChanged(QString)), this, SLOT(slotZoom())); 0368 connect(argExportImage->ExportFileName, SIGNAL(textChanged(QString)), this, SLOT(slotExportImage())); 0369 connect(argExportImage->ExportWidth, SIGNAL(valueChanged(int)), this, SLOT(slotExportImage())); 0370 connect(argExportImage->ExportHeight, SIGNAL(valueChanged(int)), this, SLOT(slotExportImage())); 0371 connect(argPrintImage->UsePrintDialog, SIGNAL(toggled(bool)), this, SLOT(slotPrintImage())); 0372 connect(argPrintImage->UseChartColors, SIGNAL(toggled(bool)), this, SLOT(slotPrintImage())); 0373 connect(argSetColor->ColorName, SIGNAL(activated(QString)), this, SLOT(slotChangeColorName())); 0374 connect(argSetColor->ColorValue, SIGNAL(changed(QColor)), this, SLOT(slotChangeColor())); 0375 connect(argLoadColorScheme->SchemeList, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(slotLoadColorScheme())); 0376 0377 //disable some buttons 0378 sb->CopyButton->setEnabled(false); 0379 sb->AddButton->setEnabled(false); 0380 sb->RemoveButton->setEnabled(false); 0381 sb->UpButton->setEnabled(false); 0382 sb->DownButton->setEnabled(false); 0383 sb->SaveButton->setEnabled(false); 0384 sb->SaveAsButton->setEnabled(false); 0385 sb->RunButton->setEnabled(false); 0386 } 0387 0388 ScriptBuilder::~ScriptBuilder() 0389 { 0390 while (!KStarsFunctionList.isEmpty()) 0391 delete KStarsFunctionList.takeFirst(); 0392 0393 while (!SimClockFunctionList.isEmpty()) 0394 delete SimClockFunctionList.takeFirst(); 0395 0396 while (!ScriptList.isEmpty()) 0397 delete ScriptList.takeFirst(); 0398 } 0399 0400 void ScriptBuilder::initViewOptions() 0401 { 0402 otv->optionsList()->setRootIsDecorated(true); 0403 QStringList fields; 0404 0405 //InfoBoxes 0406 opsGUI = new QTreeWidgetItem(otv->optionsList(), QStringList(i18n("InfoBoxes"))); 0407 fields << "ShowInfoBoxes" << i18n("Toggle display of all InfoBoxes") << i18n("bool"); 0408 new QTreeWidgetItem(opsGUI, fields); 0409 fields.clear(); 0410 fields << "ShowTimeBox" << i18n("Toggle display of Time InfoBox") << i18n("bool"); 0411 new QTreeWidgetItem(opsGUI, fields); 0412 fields.clear(); 0413 fields << "ShowGeoBox" << i18n("Toggle display of Geographic InfoBox") << i18n("bool"); 0414 new QTreeWidgetItem(opsGUI, fields); 0415 fields.clear(); 0416 fields << "ShowFocusBox" << i18n("Toggle display of Focus InfoBox") << i18n("bool"); 0417 new QTreeWidgetItem(opsGUI, fields); 0418 fields.clear(); 0419 fields << "ShadeTimeBox" << i18n("(un)Shade Time InfoBox") << i18n("bool"); 0420 new QTreeWidgetItem(opsGUI, fields); 0421 fields.clear(); 0422 fields << "ShadeGeoBox" << i18n("(un)Shade Geographic InfoBox") << i18n("bool"); 0423 new QTreeWidgetItem(opsGUI, fields); 0424 fields.clear(); 0425 fields << "ShadeFocusBox" << i18n("(un)Shade Focus InfoBox") << i18n("bool"); 0426 new QTreeWidgetItem(opsGUI, fields); 0427 fields.clear(); 0428 0429 argChangeViewOption->OptionName->addItem("ShowInfoBoxes"); 0430 argChangeViewOption->OptionName->addItem("ShowTimeBox"); 0431 argChangeViewOption->OptionName->addItem("ShowGeoBox"); 0432 argChangeViewOption->OptionName->addItem("ShowFocusBox"); 0433 argChangeViewOption->OptionName->addItem("ShadeTimeBox"); 0434 argChangeViewOption->OptionName->addItem("ShadeGeoBox"); 0435 argChangeViewOption->OptionName->addItem("ShadeFocusBox"); 0436 0437 //Toolbars 0438 opsToolbar = new QTreeWidgetItem(otv->optionsList(), QStringList(i18n("Toolbars"))); 0439 fields << "ShowMainToolBar" << i18n("Toggle display of main toolbar") << i18n("bool"); 0440 new QTreeWidgetItem(opsToolbar, fields); 0441 fields.clear(); 0442 fields << "ShowViewToolBar" << i18n("Toggle display of view toolbar") << i18n("bool"); 0443 new QTreeWidgetItem(opsToolbar, fields); 0444 fields.clear(); 0445 0446 argChangeViewOption->OptionName->addItem("ShowMainToolBar"); 0447 argChangeViewOption->OptionName->addItem("ShowViewToolBar"); 0448 0449 //Show Objects 0450 opsShowObj = new QTreeWidgetItem(otv->optionsList(), QStringList(i18n("Show Objects"))); 0451 fields << "ShowStars" << i18n("Toggle display of Stars") << i18n("bool"); 0452 new QTreeWidgetItem(opsShowObj, fields); 0453 fields.clear(); 0454 fields << "ShowDeepSky" << i18n("Toggle display of all deep-sky objects") << i18n("bool"); 0455 new QTreeWidgetItem(opsShowObj, fields); 0456 fields.clear(); 0457 new QTreeWidgetItem(opsShowObj, fields); 0458 fields.clear(); 0459 new QTreeWidgetItem(opsShowObj, fields); 0460 fields.clear(); 0461 fields << "ShowSolarSystem" << i18n("Toggle display of all solar system bodies") << i18n("bool"); 0462 new QTreeWidgetItem(opsShowObj, fields); 0463 fields.clear(); 0464 fields << "ShowSun" << i18n("Toggle display of Sun") << i18n("bool"); 0465 new QTreeWidgetItem(opsShowObj, fields); 0466 fields.clear(); 0467 fields << "ShowMoon" << i18n("Toggle display of Moon") << i18n("bool"); 0468 new QTreeWidgetItem(opsShowObj, fields); 0469 fields.clear(); 0470 fields << "ShowMercury" << i18n("Toggle display of Mercury") << i18n("bool"); 0471 new QTreeWidgetItem(opsShowObj, fields); 0472 fields.clear(); 0473 fields << "ShowVenus" << i18n("Toggle display of Venus") << i18n("bool"); 0474 new QTreeWidgetItem(opsShowObj, fields); 0475 fields.clear(); 0476 fields << "ShowMars" << i18n("Toggle display of Mars") << i18n("bool"); 0477 new QTreeWidgetItem(opsShowObj, fields); 0478 fields.clear(); 0479 fields << "ShowJupiter" << i18n("Toggle display of Jupiter") << i18n("bool"); 0480 new QTreeWidgetItem(opsShowObj, fields); 0481 fields.clear(); 0482 fields << "ShowSaturn" << i18n("Toggle display of Saturn") << i18n("bool"); 0483 new QTreeWidgetItem(opsShowObj, fields); 0484 fields.clear(); 0485 fields << "ShowUranus" << i18n("Toggle display of Uranus") << i18n("bool"); 0486 new QTreeWidgetItem(opsShowObj, fields); 0487 fields.clear(); 0488 fields << "ShowNeptune" << i18n("Toggle display of Neptune") << i18n("bool"); 0489 new QTreeWidgetItem(opsShowObj, fields); 0490 //fields.clear(); 0491 //fields << "ShowPluto" << i18n( "Toggle display of Pluto" ) << i18n( "bool" ); 0492 //new QTreeWidgetItem( opsShowObj, fields ); 0493 fields.clear(); 0494 fields << "ShowAsteroids" << i18n("Toggle display of Asteroids") << i18n("bool"); 0495 new QTreeWidgetItem(opsShowObj, fields); 0496 fields.clear(); 0497 fields << "ShowComets" << i18n("Toggle display of Comets") << i18n("bool"); 0498 new QTreeWidgetItem(opsShowObj, fields); 0499 fields.clear(); 0500 0501 argChangeViewOption->OptionName->addItem("ShowStars"); 0502 argChangeViewOption->OptionName->addItem("ShowDeepSky"); 0503 argChangeViewOption->OptionName->addItem("ShowSolarSystem"); 0504 argChangeViewOption->OptionName->addItem("ShowSun"); 0505 argChangeViewOption->OptionName->addItem("ShowMoon"); 0506 argChangeViewOption->OptionName->addItem("ShowMercury"); 0507 argChangeViewOption->OptionName->addItem("ShowVenus"); 0508 argChangeViewOption->OptionName->addItem("ShowMars"); 0509 argChangeViewOption->OptionName->addItem("ShowJupiter"); 0510 argChangeViewOption->OptionName->addItem("ShowSaturn"); 0511 argChangeViewOption->OptionName->addItem("ShowUranus"); 0512 argChangeViewOption->OptionName->addItem("ShowNeptune"); 0513 //argChangeViewOption->OptionName->addItem( "ShowPluto" ); 0514 argChangeViewOption->OptionName->addItem("ShowAsteroids"); 0515 argChangeViewOption->OptionName->addItem("ShowComets"); 0516 0517 opsShowOther = new QTreeWidgetItem(otv->optionsList(), QStringList(i18n("Show Other"))); 0518 fields << "ShowCLines" << i18n("Toggle display of constellation lines") << i18n("bool"); 0519 new QTreeWidgetItem(opsShowOther, fields); 0520 fields.clear(); 0521 fields << "ShowCBounds" << i18n("Toggle display of constellation boundaries") << i18n("bool"); 0522 new QTreeWidgetItem(opsShowOther, fields); 0523 fields.clear(); 0524 fields << "ShowCNames" << i18n("Toggle display of constellation names") << i18n("bool"); 0525 new QTreeWidgetItem(opsShowOther, fields); 0526 fields.clear(); 0527 fields << "ShowMilkyWay" << i18n("Toggle display of Milky Way") << i18n("bool"); 0528 new QTreeWidgetItem(opsShowOther, fields); 0529 fields.clear(); 0530 fields << "ShowGrid" << i18n("Toggle display of the coordinate grid") << i18n("bool"); 0531 new QTreeWidgetItem(opsShowOther, fields); 0532 fields.clear(); 0533 fields << "ShowEquator" << i18n("Toggle display of the celestial equator") << i18n("bool"); 0534 new QTreeWidgetItem(opsShowOther, fields); 0535 fields.clear(); 0536 fields << "ShowEcliptic" << i18n("Toggle display of the ecliptic") << i18n("bool"); 0537 new QTreeWidgetItem(opsShowOther, fields); 0538 fields.clear(); 0539 fields << "ShowHorizon" << i18n("Toggle display of the horizon line") << i18n("bool"); 0540 new QTreeWidgetItem(opsShowOther, fields); 0541 fields.clear(); 0542 fields << "ShowGround" << i18n("Toggle display of the opaque ground") << i18n("bool"); 0543 new QTreeWidgetItem(opsShowOther, fields); 0544 fields.clear(); 0545 fields << "ShowStarNames" << i18n("Toggle display of star name labels") << i18n("bool"); 0546 new QTreeWidgetItem(opsShowOther, fields); 0547 fields.clear(); 0548 fields << "ShowStarMagnitudes" << i18n("Toggle display of star magnitude labels") << i18n("bool"); 0549 new QTreeWidgetItem(opsShowOther, fields); 0550 fields.clear(); 0551 fields << "ShowAsteroidNames" << i18n("Toggle display of asteroid name labels") << i18n("bool"); 0552 new QTreeWidgetItem(opsShowOther, fields); 0553 fields.clear(); 0554 fields << "ShowCometNames" << i18n("Toggle display of comet name labels") << i18n("bool"); 0555 new QTreeWidgetItem(opsShowOther, fields); 0556 fields.clear(); 0557 fields << "ShowPlanetNames" << i18n("Toggle display of planet name labels") << i18n("bool"); 0558 new QTreeWidgetItem(opsShowOther, fields); 0559 fields.clear(); 0560 fields << "ShowPlanetImages" << i18n("Toggle display of planet images") << i18n("bool"); 0561 new QTreeWidgetItem(opsShowOther, fields); 0562 fields.clear(); 0563 0564 argChangeViewOption->OptionName->addItem("ShowCLines"); 0565 argChangeViewOption->OptionName->addItem("ShowCBounds"); 0566 argChangeViewOption->OptionName->addItem("ShowCNames"); 0567 argChangeViewOption->OptionName->addItem("ShowMilkyWay"); 0568 argChangeViewOption->OptionName->addItem("ShowGrid"); 0569 argChangeViewOption->OptionName->addItem("ShowEquator"); 0570 argChangeViewOption->OptionName->addItem("ShowEcliptic"); 0571 argChangeViewOption->OptionName->addItem("ShowHorizon"); 0572 argChangeViewOption->OptionName->addItem("ShowGround"); 0573 argChangeViewOption->OptionName->addItem("ShowStarNames"); 0574 argChangeViewOption->OptionName->addItem("ShowStarMagnitudes"); 0575 argChangeViewOption->OptionName->addItem("ShowAsteroidNames"); 0576 argChangeViewOption->OptionName->addItem("ShowCometNames"); 0577 argChangeViewOption->OptionName->addItem("ShowPlanetNames"); 0578 argChangeViewOption->OptionName->addItem("ShowPlanetImages"); 0579 0580 opsCName = new QTreeWidgetItem(otv->optionsList(), QStringList(i18n("Constellation Names"))); 0581 fields << "UseLatinConstellNames" << i18n("Show Latin constellation names") << i18n("bool"); 0582 new QTreeWidgetItem(opsCName, fields); 0583 fields.clear(); 0584 fields << "UseLocalConstellNames" << i18n("Show constellation names in local language") << i18n("bool"); 0585 new QTreeWidgetItem(opsCName, fields); 0586 fields.clear(); 0587 fields << "UseAbbrevConstellNames" << i18n("Show IAU-standard constellation abbreviations") << i18n("bool"); 0588 new QTreeWidgetItem(opsCName, fields); 0589 fields.clear(); 0590 0591 argChangeViewOption->OptionName->addItem("UseLatinConstellNames"); 0592 argChangeViewOption->OptionName->addItem("UseLocalConstellNames"); 0593 argChangeViewOption->OptionName->addItem("UseAbbrevConstellNames"); 0594 0595 opsHide = new QTreeWidgetItem(otv->optionsList(), QStringList(i18n("Hide Items"))); 0596 fields << "HideOnSlew" << i18n("Toggle whether objects hidden while slewing display") << i18n("bool"); 0597 new QTreeWidgetItem(opsHide, fields); 0598 fields.clear(); 0599 fields << "SlewTimeScale" << i18n("Timestep threshold (in seconds) for hiding objects") << i18n("double"); 0600 new QTreeWidgetItem(opsHide, fields); 0601 fields.clear(); 0602 fields << "HideStars" << i18n("Hide faint stars while slewing?") << i18n("bool"); 0603 new QTreeWidgetItem(opsHide, fields); 0604 fields.clear(); 0605 fields << "HidePlanets" << i18n("Hide solar system bodies while slewing?") << i18n("bool"); 0606 new QTreeWidgetItem(opsHide, fields); 0607 fields.clear(); 0608 fields << "HideMilkyWay" << i18n("Hide Milky Way while slewing?") << i18n("bool"); 0609 new QTreeWidgetItem(opsHide, fields); 0610 fields.clear(); 0611 fields << "HideCNames" << i18n("Hide constellation names while slewing?") << i18n("bool"); 0612 new QTreeWidgetItem(opsHide, fields); 0613 fields.clear(); 0614 fields << "HideCLines" << i18n("Hide constellation lines while slewing?") << i18n("bool"); 0615 new QTreeWidgetItem(opsHide, fields); 0616 fields.clear(); 0617 fields << "HideCBounds" << i18n("Hide constellation boundaries while slewing?") << i18n("bool"); 0618 new QTreeWidgetItem(opsHide, fields); 0619 fields.clear(); 0620 fields << "HideGrid" << i18n("Hide coordinate grid while slewing?") << i18n("bool"); 0621 new QTreeWidgetItem(opsHide, fields); 0622 fields.clear(); 0623 0624 argChangeViewOption->OptionName->addItem("HideOnSlew"); 0625 argChangeViewOption->OptionName->addItem("SlewTimeScale"); 0626 argChangeViewOption->OptionName->addItem("HideStars"); 0627 argChangeViewOption->OptionName->addItem("HidePlanets"); 0628 argChangeViewOption->OptionName->addItem("HideMilkyWay"); 0629 argChangeViewOption->OptionName->addItem("HideCNames"); 0630 argChangeViewOption->OptionName->addItem("HideCLines"); 0631 argChangeViewOption->OptionName->addItem("HideCBounds"); 0632 argChangeViewOption->OptionName->addItem("HideGrid"); 0633 0634 opsSkymap = new QTreeWidgetItem(otv->optionsList(), QStringList(i18n("Skymap Options"))); 0635 fields << "UseAltAz" << i18n("Use Horizontal coordinates? (otherwise, use Equatorial)") << i18n("bool"); 0636 new QTreeWidgetItem(opsSkymap, fields); 0637 fields.clear(); 0638 fields << "ZoomFactor" << i18n("Set the Zoom Factor") << i18n("double"); 0639 new QTreeWidgetItem(opsSkymap, fields); 0640 fields.clear(); 0641 fields << "FOVName" << i18n("Select angular size for the FOV symbol (in arcmin)") << i18n("double"); 0642 new QTreeWidgetItem(opsSkymap, fields); 0643 fields.clear(); 0644 fields << "FOVShape" << i18n("Select shape for the FOV symbol (0=Square, 1=Circle, 2=Crosshairs, 4=Bullseye)") 0645 << i18n("int"); 0646 new QTreeWidgetItem(opsSkymap, fields); 0647 fields.clear(); 0648 fields << "FOVColor" << i18n("Select color for the FOV symbol") << i18n("string"); 0649 new QTreeWidgetItem(opsSkymap, fields); 0650 fields.clear(); 0651 fields << "UseAnimatedSlewing" << i18n("Use animated slewing? (otherwise, \"snap\" to new focus)") << i18n("bool"); 0652 new QTreeWidgetItem(opsSkymap, fields); 0653 fields.clear(); 0654 fields << "UseRefraction" << i18n("Correct for atmospheric refraction?") << i18n("bool"); 0655 new QTreeWidgetItem(opsSkymap, fields); 0656 fields.clear(); 0657 fields << "UseAutoLabel" << i18n("Automatically attach name label to centered object?") << i18n("bool"); 0658 new QTreeWidgetItem(opsSkymap, fields); 0659 fields.clear(); 0660 fields << "UseHoverLabel" << i18n("Attach temporary name label when hovering mouse over an object?") 0661 << i18n("bool"); 0662 new QTreeWidgetItem(opsSkymap, fields); 0663 fields.clear(); 0664 fields << "UseAutoTrail" << i18n("Automatically add trail to centered solar system body?") << i18n("bool"); 0665 new QTreeWidgetItem(opsSkymap, fields); 0666 fields.clear(); 0667 fields << "FadePlanetTrails" << i18n("Planet trails fade to sky color? (otherwise color is constant)") 0668 << i18n("bool"); 0669 new QTreeWidgetItem(opsSkymap, fields); 0670 fields.clear(); 0671 0672 argChangeViewOption->OptionName->addItem("UseAltAz"); 0673 argChangeViewOption->OptionName->addItem("ZoomFactor"); 0674 argChangeViewOption->OptionName->addItem("FOVName"); 0675 argChangeViewOption->OptionName->addItem("FOVSize"); 0676 argChangeViewOption->OptionName->addItem("FOVShape"); 0677 argChangeViewOption->OptionName->addItem("FOVColor"); 0678 argChangeViewOption->OptionName->addItem("UseRefraction"); 0679 argChangeViewOption->OptionName->addItem("UseAutoLabel"); 0680 argChangeViewOption->OptionName->addItem("UseHoverLabel"); 0681 argChangeViewOption->OptionName->addItem("UseAutoTrail"); 0682 argChangeViewOption->OptionName->addItem("AnimateSlewing"); 0683 argChangeViewOption->OptionName->addItem("FadePlanetTrails"); 0684 0685 opsLimit = new QTreeWidgetItem(otv->optionsList(), QStringList(i18n("Limits"))); 0686 /* 0687 fields << "magLimitDrawStar" << i18n( "magnitude of faintest star drawn on map when zoomed in" ) << i18n( "double" ); 0688 new QTreeWidgetItem( opsLimit, fields ); 0689 fields.clear(); 0690 fields << "magLimitDrawStarZoomOut" << i18n( "magnitude of faintest star drawn on map when zoomed out" ) << i18n( "double" ); 0691 new QTreeWidgetItem( opsLimit, fields ); 0692 fields.clear(); 0693 */ 0694 0695 // TODO: We have disabled the following two features. Enable them when feasible... 0696 /* 0697 fields << "magLimitDrawDeepSky" << i18n( "magnitude of faintest nonstellar object drawn on map when zoomed in" ) << i18n( "double" ); 0698 new QTreeWidgetItem( opsLimit, fields ); 0699 fields.clear(); 0700 fields << "magLimitDrawDeepSkyZoomOut" << i18n( "magnitude of faintest nonstellar object drawn on map when zoomed out" ) << i18n( "double" ); 0701 new QTreeWidgetItem( opsLimit, fields ); 0702 fields.clear(); 0703 */ 0704 0705 //FIXME: This description is incorrect! Fix after strings freeze 0706 fields << "starLabelDensity" << i18n("magnitude of faintest star labeled on map") << i18n("double"); 0707 new QTreeWidgetItem(opsLimit, fields); 0708 fields.clear(); 0709 fields << "magLimitHideStar" << i18n("magnitude of brightest star hidden while slewing") << i18n("double"); 0710 new QTreeWidgetItem(opsLimit, fields); 0711 fields.clear(); 0712 fields << "magLimitAsteroid" << i18n("magnitude of faintest asteroid drawn on map") << i18n("double"); 0713 new QTreeWidgetItem(opsLimit, fields); 0714 fields.clear(); 0715 //FIXME: This description is incorrect! Fix after strings freeze 0716 fields << "asteroidLabelDensity" << i18n("magnitude of faintest asteroid labeled on map") << i18n("double"); 0717 new QTreeWidgetItem(opsLimit, fields); 0718 fields.clear(); 0719 fields << "maxRadCometName" << i18n("comets nearer to the Sun than this (in AU) are labeled on map") 0720 << i18n("double"); 0721 new QTreeWidgetItem(opsLimit, fields); 0722 fields.clear(); 0723 0724 // argChangeViewOption->OptionName->addItem( "magLimitDrawStar" ); 0725 // argChangeViewOption->OptionName->addItem( "magLimitDrawStarZoomOut" ); 0726 argChangeViewOption->OptionName->addItem("magLimitDrawDeepSky"); 0727 argChangeViewOption->OptionName->addItem("magLimitDrawDeepSkyZoomOut"); 0728 argChangeViewOption->OptionName->addItem("starLabelDensity"); 0729 argChangeViewOption->OptionName->addItem("magLimitHideStar"); 0730 argChangeViewOption->OptionName->addItem("magLimitAsteroid"); 0731 argChangeViewOption->OptionName->addItem("asteroidLabelDensity"); 0732 argChangeViewOption->OptionName->addItem("maxRadCometName"); 0733 0734 //init the list of color names and values 0735 for (unsigned int i = 0; i < KStarsData::Instance()->colorScheme()->numberOfColors(); ++i) 0736 { 0737 argSetColor->ColorName->addItem(KStarsData::Instance()->colorScheme()->nameAt(i)); 0738 } 0739 0740 //init list of color scheme names 0741 argLoadColorScheme->SchemeList->addItem(i18nc("use default color scheme", "Default Colors")); 0742 argLoadColorScheme->SchemeList->addItem(i18nc("use 'star chart' color scheme", "Star Chart")); 0743 argLoadColorScheme->SchemeList->addItem(i18nc("use 'night vision' color scheme", "Night Vision")); 0744 argLoadColorScheme->SchemeList->addItem(i18nc("use 'moonless night' color scheme", "Moonless Night")); 0745 0746 QFile file; 0747 QString line; 0748 //determine filename in local user KDE directory tree. 0749 file.setFileName(KSPaths::locate(QStandardPaths::AppLocalDataLocation, "colors.dat")); 0750 if (file.open(QIODevice::ReadOnly)) 0751 { 0752 QTextStream stream(&file); 0753 0754 while (!stream.atEnd()) 0755 { 0756 line = stream.readLine(); 0757 argLoadColorScheme->SchemeList->addItem(line.left(line.indexOf(':'))); 0758 } 0759 file.close(); 0760 } 0761 } 0762 0763 //Slots defined in ScriptBuilderUI 0764 void ScriptBuilder::slotNew() 0765 { 0766 saveWarning(); 0767 if (!UnsavedChanges) 0768 { 0769 ScriptList.clear(); 0770 sb->ScriptListBox->clear(); 0771 sb->ArgStack->setCurrentWidget(argBlank); 0772 0773 sb->CopyButton->setEnabled(false); 0774 sb->RemoveButton->setEnabled(false); 0775 sb->RunButton->setEnabled(false); 0776 sb->SaveAsButton->setEnabled(false); 0777 0778 currentFileURL.clear(); 0779 currentScriptName.clear(); 0780 } 0781 } 0782 0783 void ScriptBuilder::slotOpen() 0784 { 0785 saveWarning(); 0786 0787 QString fname; 0788 QTemporaryFile tmpfile; 0789 tmpfile.open(); 0790 0791 if (!UnsavedChanges) 0792 { 0793 currentFileURL = QFileDialog::getOpenFileUrl( 0794 KStars::Instance(), QString(), QUrl(currentDir), 0795 "*.kstars|" + i18nc("Filter by file type: KStars Scripts.", "KStars Scripts (*.kstars)")); 0796 0797 if (currentFileURL.isValid()) 0798 { 0799 currentDir = currentFileURL.toLocalFile(); 0800 0801 ScriptList.clear(); 0802 sb->ScriptListBox->clear(); 0803 sb->ArgStack->setCurrentWidget(argBlank); 0804 0805 if (currentFileURL.isLocalFile()) 0806 { 0807 fname = currentFileURL.toLocalFile(); 0808 } 0809 else 0810 { 0811 fname = tmpfile.fileName(); 0812 if (KIO::copy(currentFileURL, QUrl(fname))->exec() == false) 0813 //if ( ! KIO::NetAccess::download( currentFileURL, fname, (QWidget*) 0 ) ) 0814 KSNotification::sorry(i18n("Could not download remote file."), i18n("Download Error")); 0815 } 0816 0817 QFile f(fname); 0818 if (!f.open(QIODevice::ReadOnly)) 0819 { 0820 KSNotification::sorry(i18n("Could not open file %1.", f.fileName()), i18n("Could Not Open File")); 0821 currentFileURL.clear(); 0822 return; 0823 } 0824 0825 QTextStream istream(&f); 0826 readScript(istream); 0827 0828 f.close(); 0829 } 0830 else if (!currentFileURL.url().isEmpty()) 0831 { 0832 KSNotification::sorry(i18n("Invalid URL: %1", currentFileURL.url()), i18n("Invalid URL")); 0833 currentFileURL.clear(); 0834 } 0835 } 0836 } 0837 0838 void ScriptBuilder::slotSave() 0839 { 0840 QString fname; 0841 QTemporaryFile tmpfile; 0842 tmpfile.open(); 0843 0844 if (currentScriptName.isEmpty()) 0845 { 0846 //Get Script Name and Author info 0847 if (snd->exec() == QDialog::Accepted) 0848 { 0849 currentScriptName = snd->scriptName(); 0850 currentAuthor = snd->authorName(); 0851 } 0852 else 0853 { 0854 return; 0855 } 0856 } 0857 0858 bool newFilename = false; 0859 if (currentFileURL.isEmpty()) 0860 { 0861 currentFileURL = QFileDialog::getSaveFileUrl( 0862 KStars::Instance(), QString(), QUrl(currentDir), 0863 "*.kstars|" + i18nc("Filter by file type: KStars Scripts.", "KStars Scripts (*.kstars)")); 0864 newFilename = true; 0865 } 0866 0867 if (currentFileURL.isValid()) 0868 { 0869 currentDir = currentFileURL.toLocalFile(); 0870 0871 if (currentFileURL.isLocalFile()) 0872 { 0873 fname = currentFileURL.toLocalFile(); 0874 0875 //Warn user if file exists 0876 if (newFilename == true && QFile::exists(currentFileURL.toLocalFile())) 0877 { 0878 int r = KMessageBox::warningContinueCancel(static_cast<QWidget *>(parent()), 0879 i18n("A file named \"%1\" already exists. " 0880 "Overwrite it?", 0881 currentFileURL.fileName()), 0882 i18n("Overwrite File?"), KStandardGuiItem::overwrite()); 0883 0884 if (r == KMessageBox::Cancel) 0885 return; 0886 } 0887 } 0888 else 0889 { 0890 fname = tmpfile.fileName(); 0891 } 0892 0893 if (fname.right(7).toLower() != ".kstars") 0894 fname += ".kstars"; 0895 0896 QFile f(fname); 0897 if (!f.open(QIODevice::WriteOnly)) 0898 { 0899 QString message = i18n("Could not open file %1.", f.fileName()); 0900 KSNotification::sorry(message, i18n("Could Not Open File")); 0901 currentFileURL.clear(); 0902 return; 0903 } 0904 0905 QTextStream ostream(&f); 0906 writeScript(ostream); 0907 f.close(); 0908 0909 #ifndef _WIN32 0910 //set rwx for owner, rx for group, rx for other 0911 chmod(fname.toLatin1(), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 0912 #endif 0913 0914 if (tmpfile.fileName() == fname) 0915 { 0916 //need to upload to remote location 0917 //if ( ! KIO::NetAccess::upload( tmpfile.fileName(), currentFileURL, (QWidget*) 0 ) ) 0918 if (KIO::storedHttpPost(&tmpfile, currentFileURL)->exec() == false) 0919 { 0920 QString message = i18n("Could not upload image to remote location: %1", currentFileURL.url()); 0921 KSNotification::sorry(message, i18n("Could not upload file")); 0922 } 0923 } 0924 0925 setUnsavedChanges(false); 0926 } 0927 else 0928 { 0929 QString message = i18n("Invalid URL: %1", currentFileURL.url()); 0930 KSNotification::sorry(message, i18n("Invalid URL")); 0931 currentFileURL.clear(); 0932 } 0933 } 0934 0935 void ScriptBuilder::slotSaveAs() 0936 { 0937 currentFileURL.clear(); 0938 currentScriptName.clear(); 0939 slotSave(); 0940 } 0941 0942 void ScriptBuilder::saveWarning() 0943 { 0944 if (UnsavedChanges) 0945 { 0946 QString caption = i18n("Save Changes to Script?"); 0947 QString message = i18n("The current script has unsaved changes. Would you like to save before closing it?"); 0948 int ans = 0949 KMessageBox::warningYesNoCancel(nullptr, message, caption, KStandardGuiItem::save(), KStandardGuiItem::discard()); 0950 if (ans == KMessageBox::Yes) 0951 { 0952 slotSave(); 0953 setUnsavedChanges(false); 0954 } 0955 else if (ans == KMessageBox::No) 0956 { 0957 setUnsavedChanges(false); 0958 } 0959 0960 //Do nothing if 'cancel' selected 0961 } 0962 } 0963 0964 void ScriptBuilder::slotRunScript() 0965 { 0966 //hide window while script runs 0967 // If this is uncommented, the program hangs before the script is executed. Why? 0968 // hide(); 0969 0970 //Save current script to a temporary file, then execute that file. 0971 //For some reason, I can't use KTempFile here! If I do, then the temporary script 0972 //is not executable. Bizarre... 0973 //KTempFile tmpfile; 0974 //QString fname = tmpfile.name(); 0975 QString fname = QDir::tempPath() + QDir::separator() + "kstars-tempscript"; 0976 0977 QFile f(fname); 0978 if (f.exists()) 0979 f.remove(); 0980 if (!f.open(QIODevice::WriteOnly)) 0981 { 0982 QString message = i18n("Could not open file %1.", f.fileName()); 0983 KSNotification::sorry(message, i18n("Could Not Open File")); 0984 currentFileURL.clear(); 0985 return; 0986 } 0987 0988 QTextStream ostream(&f); 0989 writeScript(ostream); 0990 f.close(); 0991 0992 #ifndef _WIN32 0993 //set rwx for owner, rx for group, rx for other 0994 chmod(QFile::encodeName(f.fileName()), S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); 0995 #endif 0996 0997 QProcess p; 0998 #ifdef Q_OS_OSX 0999 QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); 1000 QString path = env.value("PATH", ""); 1001 env.insert("PATH", "/usr/local/bin:" + QCoreApplication::applicationDirPath() + ':' + path); 1002 p.setProcessEnvironment(env); 1003 #endif 1004 QStringList arguments; 1005 p.start(f.fileName(), arguments); 1006 1007 if (!p.waitForStarted()) 1008 qDebug() << Q_FUNC_INFO << "Process did not start."; 1009 1010 while (!p.waitForFinished(10)) 1011 { 1012 qApp->processEvents(); //otherwise tempfile may get deleted before script completes. 1013 if (p.state() != QProcess::Running) 1014 break; 1015 } 1016 //delete temp file 1017 if (f.exists()) 1018 f.remove(); 1019 1020 //uncomment if 'hide()' is uncommented... 1021 // show(); 1022 } 1023 1024 /* 1025 This can't work anymore and is also not portable in any way :( 1026 */ 1027 void ScriptBuilder::writeScript(QTextStream &ostream) 1028 { 1029 // FIXME Without --print-reply, the dbus-send doesn't do anything, why?? 1030 QString dbus_call = "dbus-send --dest=org.kde.kstars --print-reply "; 1031 QString main_method = "/KStars org.kde.kstars."; 1032 QString clock_method = "/KStars/SimClock org.kde.kstars.SimClock."; 1033 1034 //Write script header 1035 ostream << "#!/bin/bash\n"; 1036 ostream << "#KStars DBus script: " << currentScriptName << '\n'; 1037 ostream << "#by " << currentAuthor << '\n'; 1038 ostream << "#last modified: " << KStarsDateTime::currentDateTime().toString(Qt::ISODate) << '\n'; 1039 ostream << "#\n"; 1040 1041 foreach (ScriptFunction *sf, ScriptList) 1042 { 1043 if (!sf->valid()) 1044 continue; 1045 1046 if (sf->isClockFunction()) 1047 { 1048 ostream << dbus_call << clock_method << sf->scriptLine() << '\n'; 1049 } 1050 else 1051 { 1052 ostream << dbus_call << main_method << sf->scriptLine() << '\n'; 1053 } 1054 } 1055 1056 //Write script footer 1057 ostream << "##\n"; 1058 ostream.flush(); 1059 } 1060 1061 void ScriptBuilder::readScript(QTextStream &istream) 1062 { 1063 QString line; 1064 QString service_name = "org.kde.kstars."; 1065 QString fn_name; 1066 1067 while (!istream.atEnd()) 1068 { 1069 line = istream.readLine(); 1070 1071 //look for name of script 1072 if (line.contains("#KStars DBus script: ")) 1073 currentScriptName = line.mid(21).trimmed(); 1074 1075 //look for author of scriptbuilder 1076 if (line.contains("#by ")) 1077 currentAuthor = line.mid(4).trimmed(); 1078 1079 //Actual script functions 1080 if (line.left(4) == "dbus") 1081 { 1082 //is ClockFunction? 1083 if (line.contains("SimClock")) 1084 { 1085 service_name += "SimClock."; 1086 } 1087 1088 //remove leading dbus prefix 1089 line = line.mid(line.lastIndexOf(service_name) + service_name.count()); 1090 1091 fn_name = line.left(line.indexOf(' ')); 1092 1093 line = line.mid(line.indexOf(' ') + 1); 1094 1095 //construct a stringlist that is fcn name and its arg name/value pairs 1096 QStringList fn; 1097 1098 // If the function lacks any arguments, do not attempt to split 1099 // if (fn_name != line) 1100 // fn = line.split(' '); 1101 1102 if (parseFunction(fn_name, line)) 1103 { 1104 sb->ScriptListBox->addItem(ScriptList.last()->name()); 1105 // Initially, any read script is valid! 1106 ScriptList.last()->setValid(true); 1107 } 1108 else 1109 qWarning() << i18n("Could not parse script. Line was: %1", line); 1110 1111 } // end if left(4) == "dcop" 1112 } // end while !atEnd() 1113 1114 //Select first item in sb->ScriptListBox 1115 if (sb->ScriptListBox->count()) 1116 { 1117 sb->ScriptListBox->setCurrentItem(nullptr); 1118 slotArgWidget(); 1119 } 1120 } 1121 1122 bool ScriptBuilder::parseFunction(const QString &fn_name, const QString &fn_args) 1123 { 1124 // clean up the string list first if needed 1125 // We need to perform this in case we havea quoted string "NGC 3000" because this will counted 1126 // as two arguments, and it should be counted as one. 1127 // bool foundQuote(false), quoteProcessed(false); 1128 // QString cur, arg; 1129 // QStringList::iterator it; 1130 1131 // for (it = fn.begin(); it != fn.end(); ++it) 1132 // { 1133 // cur = (*it); 1134 1135 // cur = cur.mid(cur.indexOf(":") + 1).remove('\''); 1136 1137 // (*it) = cur; 1138 1139 // if (cur.startsWith('\"')) 1140 // { 1141 // arg += cur.rightRef(cur.length() - 1); 1142 // arg += ' '; 1143 // foundQuote = true; 1144 // quoteProcessed = true; 1145 // } 1146 // else if (cur.endsWith('\"')) 1147 // { 1148 // arg += cur.leftRef(cur.length() - 1); 1149 // arg += '\''; 1150 // foundQuote = false; 1151 // } 1152 // else if (foundQuote) 1153 // { 1154 // arg += cur; 1155 // arg += ' '; 1156 // } 1157 // else 1158 // { 1159 // arg += cur; 1160 // arg += '\''; 1161 // } 1162 // } 1163 1164 // if (quoteProcessed) 1165 // fn = arg.split(' ', QString::SkipEmptyParts); 1166 1167 QRegularExpression re("(?<=:)[^:\\s]*"); 1168 QRegularExpressionMatchIterator i = re.globalMatch(fn_args); 1169 QStringList fn; 1170 while (i.hasNext()) 1171 { 1172 QRegularExpressionMatch match = i.next(); 1173 fn << match.captured(0).remove("\""); 1174 }; 1175 1176 //loop over known functions to find a name match 1177 for (auto &sf : KStarsFunctionList) 1178 { 1179 if (fn_name == sf->name()) 1180 { 1181 // if (fn_name == "setGeoLocation") 1182 // { 1183 // ScriptList.append(new ScriptFunction(sf)); 1184 // ScriptList.last()->setArg(0, fn[0]); 1185 // ScriptList.last()->setArg(1, fn[1]); 1186 // ScriptList.last()->setArg(2, fn[2]); 1187 // } 1188 // else if (fn.count() != sf->numArgs()) 1189 // return false; 1190 1191 ScriptList.append(new ScriptFunction(sf)); 1192 1193 for (int i = 0; i < sf->numArgs(); ++i) 1194 ScriptList.last()->setArg(i, fn[i]); 1195 1196 return true; 1197 } 1198 1199 foreach (ScriptFunction *sf, SimClockFunctionList) 1200 { 1201 if (fn_name == sf->name()) 1202 { 1203 if (fn.count() != sf->numArgs()) 1204 return false; 1205 1206 ScriptList.append(new ScriptFunction(sf)); 1207 1208 for (int i = 0; i < sf->numArgs(); ++i) 1209 ScriptList.last()->setArg(i, fn[i]); 1210 1211 return true; 1212 } 1213 } 1214 } 1215 1216 //if we get here, no function-name match was found 1217 return false; 1218 } 1219 1220 void ScriptBuilder::setUnsavedChanges(bool b) 1221 { 1222 if (checkForChanges) 1223 { 1224 UnsavedChanges = b; 1225 sb->SaveButton->setEnabled(b); 1226 } 1227 } 1228 1229 void ScriptBuilder::slotCopyFunction() 1230 { 1231 if (!UnsavedChanges) 1232 setUnsavedChanges(true); 1233 1234 int Pos = sb->ScriptListBox->currentRow() + 1; 1235 ScriptList.insert(Pos, new ScriptFunction(ScriptList[Pos - 1])); 1236 //copy ArgVals 1237 for (int i = 0; i < ScriptList[Pos - 1]->numArgs(); ++i) 1238 ScriptList[Pos]->setArg(i, ScriptList[Pos - 1]->argVal(i)); 1239 1240 sb->ScriptListBox->insertItem(Pos, ScriptList[Pos]->name()); 1241 //sb->ScriptListBox->setSelected( Pos, true ); 1242 sb->ScriptListBox->setCurrentRow(Pos); 1243 slotArgWidget(); 1244 } 1245 1246 void ScriptBuilder::slotRemoveFunction() 1247 { 1248 setUnsavedChanges(true); 1249 1250 int Pos = sb->ScriptListBox->currentRow(); 1251 ScriptList.removeAt(Pos); 1252 sb->ScriptListBox->takeItem(Pos); 1253 if (sb->ScriptListBox->count() == 0) 1254 { 1255 sb->ArgStack->setCurrentWidget(argBlank); 1256 sb->CopyButton->setEnabled(false); 1257 sb->RemoveButton->setEnabled(false); 1258 sb->RunButton->setEnabled(false); 1259 sb->SaveAsButton->setEnabled(false); 1260 } 1261 else 1262 { 1263 //sb->ScriptListBox->setSelected( Pos, true ); 1264 if (Pos == sb->ScriptListBox->count()) 1265 { 1266 Pos = Pos - 1; 1267 } 1268 sb->ScriptListBox->setCurrentRow(Pos); 1269 } 1270 slotArgWidget(); 1271 } 1272 1273 void ScriptBuilder::slotAddFunction() 1274 { 1275 ScriptFunction *found = nullptr; 1276 QTreeWidgetItem *currentItem = sb->FunctionTree->currentItem(); 1277 1278 if (currentItem == nullptr || currentItem->parent() == nullptr) 1279 return; 1280 1281 for (auto &sc : KStarsFunctionList) 1282 { 1283 if (sc->prototype() == currentItem->text(0)) 1284 { 1285 found = sc; 1286 break; 1287 } 1288 } 1289 1290 for (auto &sc : SimClockFunctionList) 1291 { 1292 if (sc->prototype() == currentItem->text(0)) 1293 { 1294 found = sc; 1295 break; 1296 } 1297 } 1298 1299 if (found == nullptr) 1300 return; 1301 1302 setUnsavedChanges(true); 1303 1304 int Pos = sb->ScriptListBox->currentRow() + 1; 1305 1306 ScriptList.insert(Pos, new ScriptFunction(found)); 1307 sb->ScriptListBox->insertItem(Pos, ScriptList[Pos]->name()); 1308 sb->ScriptListBox->setCurrentRow(Pos); 1309 slotArgWidget(); 1310 } 1311 1312 void ScriptBuilder::slotMoveFunctionUp() 1313 { 1314 if (sb->ScriptListBox->currentRow() > 0) 1315 { 1316 setUnsavedChanges(true); 1317 1318 //QString t = sb->ScriptListBox->currentItem()->text(); 1319 QString t = sb->ScriptListBox->currentItem()->text(); 1320 unsigned int n = sb->ScriptListBox->currentRow(); 1321 1322 ScriptFunction *tmp = ScriptList.takeAt(n); 1323 ScriptList.insert(n - 1, tmp); 1324 1325 sb->ScriptListBox->takeItem(n); 1326 sb->ScriptListBox->insertItem(n - 1, t); 1327 sb->ScriptListBox->setCurrentRow(n - 1); 1328 slotArgWidget(); 1329 } 1330 } 1331 1332 void ScriptBuilder::slotMoveFunctionDown() 1333 { 1334 if (sb->ScriptListBox->currentRow() > -1 && sb->ScriptListBox->currentRow() < ((int)sb->ScriptListBox->count()) - 1) 1335 { 1336 setUnsavedChanges(true); 1337 1338 QString t = sb->ScriptListBox->currentItem()->text(); 1339 unsigned int n = sb->ScriptListBox->currentRow(); 1340 1341 ScriptFunction *tmp = ScriptList.takeAt(n); 1342 ScriptList.insert(n + 1, tmp); 1343 1344 sb->ScriptListBox->takeItem(n); 1345 sb->ScriptListBox->insertItem(n + 1, t); 1346 sb->ScriptListBox->setCurrentRow(n + 1); 1347 slotArgWidget(); 1348 } 1349 } 1350 1351 void ScriptBuilder::slotArgWidget() 1352 { 1353 //First, setEnabled on buttons that act on the selected script function 1354 if (sb->ScriptListBox->currentRow() == -1) //no selection 1355 { 1356 sb->CopyButton->setEnabled(false); 1357 sb->RemoveButton->setEnabled(false); 1358 sb->UpButton->setEnabled(false); 1359 sb->DownButton->setEnabled(false); 1360 } 1361 else if (sb->ScriptListBox->count() == 1) //only one item, so disable up/down buttons 1362 { 1363 sb->CopyButton->setEnabled(true); 1364 sb->RemoveButton->setEnabled(true); 1365 sb->UpButton->setEnabled(false); 1366 sb->DownButton->setEnabled(false); 1367 } 1368 else if (sb->ScriptListBox->currentRow() == 0) //first item selected 1369 { 1370 sb->CopyButton->setEnabled(true); 1371 sb->RemoveButton->setEnabled(true); 1372 sb->UpButton->setEnabled(false); 1373 sb->DownButton->setEnabled(true); 1374 } 1375 else if (sb->ScriptListBox->currentRow() == ((int)sb->ScriptListBox->count()) - 1) //last item selected 1376 { 1377 sb->CopyButton->setEnabled(true); 1378 sb->RemoveButton->setEnabled(true); 1379 sb->UpButton->setEnabled(true); 1380 sb->DownButton->setEnabled(false); 1381 } 1382 else //other item selected 1383 { 1384 sb->CopyButton->setEnabled(true); 1385 sb->RemoveButton->setEnabled(true); 1386 sb->UpButton->setEnabled(true); 1387 sb->DownButton->setEnabled(true); 1388 } 1389 1390 //RunButton and SaveAs button enabled when script not empty. 1391 if (sb->ScriptListBox->count()) 1392 { 1393 sb->RunButton->setEnabled(true); 1394 sb->SaveAsButton->setEnabled(true); 1395 } 1396 else 1397 { 1398 sb->RunButton->setEnabled(false); 1399 sb->SaveAsButton->setEnabled(false); 1400 setUnsavedChanges(false); 1401 } 1402 1403 //Display the function's arguments widget 1404 if (sb->ScriptListBox->currentRow() > -1 && sb->ScriptListBox->currentRow() < ((int)sb->ScriptListBox->count())) 1405 { 1406 unsigned int n = sb->ScriptListBox->currentRow(); 1407 ScriptFunction *sf = ScriptList.at(n); 1408 1409 checkForChanges = false; //Don't signal unsaved changes 1410 1411 if (sf->name() == "lookTowards") 1412 { 1413 sb->ArgStack->setCurrentWidget(argLookToward); 1414 QString s = sf->argVal(0); 1415 argLookToward->FocusEdit->setEditText(s); 1416 } 1417 else if (sf->name() == "addLabel" || sf->name() == "removeLabel" || sf->name() == "addTrail" || 1418 sf->name() == "removeTrail") 1419 { 1420 sb->ArgStack->setCurrentWidget(argFindObject); 1421 QString s = sf->argVal(0); 1422 argFindObject->NameEdit->setText(s); 1423 } 1424 else if (sf->name() == "setRaDec") 1425 { 1426 bool ok(false); 1427 double r(0.0), d(0.0); 1428 dms ra(0.0); 1429 1430 sb->ArgStack->setCurrentWidget(argSetRaDec); 1431 1432 ok = !sf->argVal(0).isEmpty(); 1433 if (ok) 1434 r = sf->argVal(0).toDouble(&ok); 1435 else 1436 argSetRaDec->RABox->clear(); 1437 if (ok) 1438 { 1439 ra.setH(r); 1440 argSetRaDec->RABox->show(ra); 1441 } 1442 1443 ok = !sf->argVal(1).isEmpty(); 1444 if (ok) 1445 d = sf->argVal(1).toDouble(&ok); 1446 else 1447 argSetRaDec->DecBox->clear(); 1448 if (ok) 1449 argSetRaDec->DecBox->show(dms(d)); 1450 } 1451 else if (sf->name() == "setAltAz") 1452 { 1453 bool ok(false); 1454 double x(0.0), y(0.0); 1455 1456 sb->ArgStack->setCurrentWidget(argSetAltAz); 1457 1458 ok = !sf->argVal(0).isEmpty(); 1459 if (ok) 1460 y = sf->argVal(0).toDouble(&ok); 1461 else 1462 argSetAltAz->AzBox->clear(); 1463 if (ok) 1464 argSetAltAz->AltBox->show(dms(y)); 1465 else 1466 argSetAltAz->AltBox->clear(); 1467 1468 ok = !sf->argVal(1).isEmpty(); 1469 x = sf->argVal(1).toDouble(&ok); 1470 if (ok) 1471 argSetAltAz->AzBox->show(dms(x)); 1472 } 1473 else if (sf->name() == "zoomIn") 1474 { 1475 sb->ArgStack->setCurrentWidget(argBlank); 1476 //no Args 1477 } 1478 else if (sf->name() == "zoomOut") 1479 { 1480 sb->ArgStack->setCurrentWidget(argBlank); 1481 //no Args 1482 } 1483 else if (sf->name() == "defaultZoom") 1484 { 1485 sb->ArgStack->setCurrentWidget(argBlank); 1486 //no Args 1487 } 1488 else if (sf->name() == "zoom") 1489 { 1490 sb->ArgStack->setCurrentWidget(argZoom); 1491 bool ok(false); 1492 /*double z = */ sf->argVal(0).toDouble(&ok); 1493 if (ok) 1494 argZoom->ZoomBox->setText(sf->argVal(0)); 1495 else 1496 argZoom->ZoomBox->setText("2000."); 1497 } 1498 else if (sf->name() == "exportImage") 1499 { 1500 sb->ArgStack->setCurrentWidget(argExportImage); 1501 argExportImage->ExportFileName->setUrl(QUrl::fromUserInput(sf->argVal(0))); 1502 bool ok(false); 1503 int w = 0, h = 0; 1504 w = sf->argVal(1).toInt(&ok); 1505 if (ok) 1506 h = sf->argVal(2).toInt(&ok); 1507 if (ok) 1508 { 1509 argExportImage->ExportWidth->setValue(w); 1510 argExportImage->ExportHeight->setValue(h); 1511 } 1512 else 1513 { 1514 argExportImage->ExportWidth->setValue(SkyMap::Instance()->width()); 1515 argExportImage->ExportHeight->setValue(SkyMap::Instance()->height()); 1516 } 1517 } 1518 else if (sf->name() == "printImage") 1519 { 1520 if (sf->argVal(0) == i18n("true")) 1521 argPrintImage->UsePrintDialog->setChecked(true); 1522 else 1523 argPrintImage->UsePrintDialog->setChecked(false); 1524 if (sf->argVal(1) == i18n("true")) 1525 argPrintImage->UseChartColors->setChecked(true); 1526 else 1527 argPrintImage->UseChartColors->setChecked(false); 1528 } 1529 else if (sf->name() == "setLocalTime") 1530 { 1531 sb->ArgStack->setCurrentWidget(argSetLocalTime); 1532 bool ok(false); 1533 int year = 0, month = 0, day = 0, hour = 0, min = 0, sec = 0; 1534 1535 year = sf->argVal(0).toInt(&ok); 1536 if (ok) 1537 month = sf->argVal(1).toInt(&ok); 1538 if (ok) 1539 day = sf->argVal(2).toInt(&ok); 1540 if (ok) 1541 argSetLocalTime->DateWidget->setDate(QDate(year, month, day)); 1542 else 1543 argSetLocalTime->DateWidget->setDate(QDate::currentDate()); 1544 1545 hour = sf->argVal(3).toInt(&ok); 1546 if (sf->argVal(3).isEmpty()) 1547 ok = false; 1548 if (ok) 1549 min = sf->argVal(4).toInt(&ok); 1550 if (ok) 1551 sec = sf->argVal(5).toInt(&ok); 1552 if (ok) 1553 argSetLocalTime->TimeBox->setTime(QTime(hour, min, sec)); 1554 else 1555 argSetLocalTime->TimeBox->setTime(QTime(QTime::currentTime())); 1556 } 1557 else if (sf->name() == "waitFor") 1558 { 1559 sb->ArgStack->setCurrentWidget(argWaitFor); 1560 bool ok(false); 1561 int sec = sf->argVal(0).toInt(&ok); 1562 if (ok) 1563 argWaitFor->DelayBox->setValue(sec); 1564 else 1565 argWaitFor->DelayBox->setValue(0); 1566 } 1567 else if (sf->name() == "waitForKey") 1568 { 1569 sb->ArgStack->setCurrentWidget(argWaitForKey); 1570 if (sf->argVal(0).length() == 1 || sf->argVal(0).toLower() == "space") 1571 argWaitForKey->WaitKeyEdit->setText(sf->argVal(0)); 1572 else 1573 argWaitForKey->WaitKeyEdit->setText(QString()); 1574 } 1575 else if (sf->name() == "setTracking") 1576 { 1577 sb->ArgStack->setCurrentWidget(argSetTracking); 1578 if (sf->argVal(0) == i18n("true")) 1579 argSetTracking->CheckTrack->setChecked(true); 1580 else 1581 argSetTracking->CheckTrack->setChecked(false); 1582 } 1583 else if (sf->name() == "changeViewOption") 1584 { 1585 sb->ArgStack->setCurrentWidget(argChangeViewOption); 1586 argChangeViewOption->OptionName->setCurrentIndex(argChangeViewOption->OptionName->findText(sf->argVal(0))); 1587 argChangeViewOption->OptionValue->setText(sf->argVal(1)); 1588 } 1589 else if (sf->name() == "setGeoLocation") 1590 { 1591 sb->ArgStack->setCurrentWidget(argSetGeoLocation); 1592 argSetGeoLocation->CityName->setText(sf->argVal(0)); 1593 argSetGeoLocation->ProvinceName->setText(sf->argVal(1)); 1594 argSetGeoLocation->CountryName->setText(sf->argVal(2)); 1595 } 1596 else if (sf->name() == "setColor") 1597 { 1598 sb->ArgStack->setCurrentWidget(argSetColor); 1599 if (sf->argVal(0).isEmpty()) 1600 sf->setArg(0, "SkyColor"); //initialize default value 1601 argSetColor->ColorName->setCurrentIndex( 1602 argSetColor->ColorName->findText(KStarsData::Instance()->colorScheme()->nameFromKey(sf->argVal(0)))); 1603 argSetColor->ColorValue->setColor(QColor(sf->argVal(1).remove('\\'))); 1604 } 1605 else if (sf->name() == "loadColorScheme") 1606 { 1607 sb->ArgStack->setCurrentWidget(argLoadColorScheme); 1608 argLoadColorScheme->SchemeList->setCurrentItem( 1609 argLoadColorScheme->SchemeList->findItems(sf->argVal(0).remove('\"'), Qt::MatchExactly).at(0)); 1610 } 1611 else if (sf->name() == "stop") 1612 { 1613 sb->ArgStack->setCurrentWidget(argBlank); 1614 //no Args 1615 } 1616 else if (sf->name() == "start") 1617 { 1618 sb->ArgStack->setCurrentWidget(argBlank); 1619 //no Args 1620 } 1621 else if (sf->name() == "setClockScale") 1622 { 1623 sb->ArgStack->setCurrentWidget(argTimeScale); 1624 bool ok(false); 1625 double ts = sf->argVal(0).toDouble(&ok); 1626 if (ok) 1627 argTimeScale->TimeScale->tsbox()->changeScale(float(ts)); 1628 else 1629 argTimeScale->TimeScale->tsbox()->changeScale(0.0); 1630 } 1631 1632 checkForChanges = true; //signal unsaved changes if the argument widgets are changed 1633 } 1634 } 1635 1636 void ScriptBuilder::slotShowDoc() 1637 { 1638 ScriptFunction *found = nullptr; 1639 QTreeWidgetItem *currentItem = sb->FunctionTree->currentItem(); 1640 1641 if (currentItem == nullptr || currentItem->parent() == nullptr) 1642 return; 1643 1644 for (auto &sc : KStarsFunctionList) 1645 { 1646 if (sc->prototype() == currentItem->text(0)) 1647 { 1648 found = sc; 1649 break; 1650 } 1651 } 1652 1653 for (auto &sc : SimClockFunctionList) 1654 { 1655 if (sc->prototype() == currentItem->text(0)) 1656 { 1657 found = sc; 1658 break; 1659 } 1660 } 1661 1662 if (found == nullptr) 1663 { 1664 sb->AddButton->setEnabled(false); 1665 qWarning() << i18n("Function index out of bounds."); 1666 return; 1667 } 1668 1669 sb->AddButton->setEnabled(true); 1670 sb->FuncDoc->setHtml(found->description()); 1671 } 1672 1673 //Slots for Arg Widgets 1674 void ScriptBuilder::slotFindCity() 1675 { 1676 QPointer<LocationDialog> ld = new LocationDialog(this); 1677 1678 if (ld->exec() == QDialog::Accepted) 1679 { 1680 if (ld->selectedCity()) 1681 { 1682 // set new location names 1683 argSetGeoLocation->CityName->setText(ld->selectedCityName()); 1684 if (!ld->selectedProvinceName().isEmpty()) 1685 { 1686 argSetGeoLocation->ProvinceName->setText(ld->selectedProvinceName()); 1687 } 1688 else 1689 { 1690 argSetGeoLocation->ProvinceName->clear(); 1691 } 1692 argSetGeoLocation->CountryName->setText(ld->selectedCountryName()); 1693 1694 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1695 if (sf->name() == "setGeoLocation") 1696 { 1697 setUnsavedChanges(true); 1698 1699 sf->setArg(0, ld->selectedCityName()); 1700 sf->setArg(1, ld->selectedProvinceName()); 1701 sf->setArg(2, ld->selectedCountryName()); 1702 } 1703 else 1704 { 1705 warningMismatch("setGeoLocation"); 1706 } 1707 } 1708 } 1709 delete ld; 1710 } 1711 1712 void ScriptBuilder::slotFindObject() 1713 { 1714 if (FindDialog::Instance()->exec() == QDialog::Accepted && FindDialog::Instance()->targetObject()) 1715 { 1716 setUnsavedChanges(true); 1717 1718 if (sender() == argLookToward->FindButton) 1719 argLookToward->FocusEdit->setEditText(FindDialog::Instance()->targetObject()->name()); 1720 else 1721 argFindObject->NameEdit->setText(FindDialog::Instance()->targetObject()->name()); 1722 } 1723 } 1724 1725 void ScriptBuilder::slotShowOptions() 1726 { 1727 //Show tree-view of view options 1728 if (otv->exec() == QDialog::Accepted) 1729 { 1730 argChangeViewOption->OptionName->setCurrentIndex( 1731 argChangeViewOption->OptionName->findText(otv->optionsList()->currentItem()->text(0))); 1732 } 1733 } 1734 1735 void ScriptBuilder::slotLookToward() 1736 { 1737 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1738 1739 if (sf->name() == "lookTowards") 1740 { 1741 setUnsavedChanges(true); 1742 1743 sf->setArg(0, argLookToward->FocusEdit->currentText()); 1744 sf->setValid(true); 1745 } 1746 else 1747 { 1748 warningMismatch("lookTowards"); 1749 } 1750 } 1751 1752 void ScriptBuilder::slotArgFindObject() 1753 { 1754 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1755 1756 if (sf->name() == "addLabel" || sf->name() == "removeLabel" || sf->name() == "addTrail" || 1757 sf->name() == "removeTrail") 1758 { 1759 setUnsavedChanges(true); 1760 1761 sf->setArg(0, argFindObject->NameEdit->text()); 1762 sf->setValid(true); 1763 } 1764 else 1765 { 1766 warningMismatch(sf->name()); 1767 } 1768 } 1769 1770 void ScriptBuilder::slotRa() 1771 { 1772 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1773 1774 if (sf->name() == "setRaDec") 1775 { 1776 //do nothing if box is blank (because we could be clearing boxes while switching argWidgets) 1777 if (argSetRaDec->RABox->text().isEmpty()) 1778 return; 1779 1780 bool ok(false); 1781 dms ra = argSetRaDec->RABox->createDms(&ok); 1782 if (ok) 1783 { 1784 setUnsavedChanges(true); 1785 1786 sf->setArg(0, QString("%1").arg(ra.Hours())); 1787 if (!sf->argVal(1).isEmpty()) 1788 sf->setValid(true); 1789 } 1790 else 1791 { 1792 sf->setArg(0, QString()); 1793 sf->setValid(false); 1794 } 1795 } 1796 else 1797 { 1798 warningMismatch("setRaDec"); 1799 } 1800 } 1801 1802 void ScriptBuilder::slotDec() 1803 { 1804 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1805 1806 if (sf->name() == "setRaDec") 1807 { 1808 //do nothing if box is blank (because we could be clearing boxes while switching argWidgets) 1809 if (argSetRaDec->DecBox->text().isEmpty()) 1810 return; 1811 1812 bool ok(false); 1813 dms dec = argSetRaDec->DecBox->createDms(&ok); 1814 if (ok) 1815 { 1816 setUnsavedChanges(true); 1817 1818 sf->setArg(1, QString("%1").arg(dec.Degrees())); 1819 if (!sf->argVal(0).isEmpty()) 1820 sf->setValid(true); 1821 } 1822 else 1823 { 1824 sf->setArg(1, QString()); 1825 sf->setValid(false); 1826 } 1827 } 1828 else 1829 { 1830 warningMismatch("setRaDec"); 1831 } 1832 } 1833 1834 void ScriptBuilder::slotAz() 1835 { 1836 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1837 1838 if (sf->name() == "setAltAz") 1839 { 1840 //do nothing if box is blank (because we could be clearing boxes while switching argWidgets) 1841 if (argSetAltAz->AzBox->text().isEmpty()) 1842 return; 1843 1844 bool ok(false); 1845 dms az = argSetAltAz->AzBox->createDms(&ok); 1846 if (ok) 1847 { 1848 setUnsavedChanges(true); 1849 sf->setArg(1, QString("%1").arg(az.Degrees())); 1850 if (!sf->argVal(0).isEmpty()) 1851 sf->setValid(true); 1852 } 1853 else 1854 { 1855 sf->setArg(1, QString()); 1856 sf->setValid(false); 1857 } 1858 } 1859 else 1860 { 1861 warningMismatch("setAltAz"); 1862 } 1863 } 1864 1865 void ScriptBuilder::slotAlt() 1866 { 1867 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1868 1869 if (sf->name() == "setAltAz") 1870 { 1871 //do nothing if box is blank (because we could be clearing boxes while switching argWidgets) 1872 if (argSetAltAz->AltBox->text().isEmpty()) 1873 return; 1874 1875 bool ok(false); 1876 dms alt = argSetAltAz->AltBox->createDms(&ok); 1877 if (ok) 1878 { 1879 setUnsavedChanges(true); 1880 1881 sf->setArg(0, QString("%1").arg(alt.Degrees())); 1882 if (!sf->argVal(1).isEmpty()) 1883 sf->setValid(true); 1884 } 1885 else 1886 { 1887 sf->setArg(0, QString()); 1888 sf->setValid(false); 1889 } 1890 } 1891 else 1892 { 1893 warningMismatch("setAltAz"); 1894 } 1895 } 1896 1897 void ScriptBuilder::slotChangeDate() 1898 { 1899 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1900 1901 if (sf->name() == "setLocalTime") 1902 { 1903 setUnsavedChanges(true); 1904 1905 QDate date = argSetLocalTime->DateWidget->date(); 1906 1907 sf->setArg(0, QString("%1").arg(date.year())); 1908 sf->setArg(1, QString("%1").arg(date.month())); 1909 sf->setArg(2, QString("%1").arg(date.day())); 1910 if (!sf->argVal(3).isEmpty()) 1911 sf->setValid(true); 1912 } 1913 else 1914 { 1915 warningMismatch("setLocalTime"); 1916 } 1917 } 1918 1919 void ScriptBuilder::slotChangeTime() 1920 { 1921 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1922 1923 if (sf->name() == "setLocalTime") 1924 { 1925 setUnsavedChanges(true); 1926 1927 QTime time = argSetLocalTime->TimeBox->time(); 1928 1929 sf->setArg(3, QString("%1").arg(time.hour())); 1930 sf->setArg(4, QString("%1").arg(time.minute())); 1931 sf->setArg(5, QString("%1").arg(time.second())); 1932 if (!sf->argVal(0).isEmpty()) 1933 sf->setValid(true); 1934 } 1935 else 1936 { 1937 warningMismatch("setLocalTime"); 1938 } 1939 } 1940 1941 void ScriptBuilder::slotWaitFor() 1942 { 1943 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1944 1945 if (sf->name() == "waitFor") 1946 { 1947 bool ok(false); 1948 int delay = argWaitFor->DelayBox->text().toInt(&ok); 1949 1950 if (ok) 1951 { 1952 setUnsavedChanges(true); 1953 1954 sf->setArg(0, QString("%1").arg(delay)); 1955 sf->setValid(true); 1956 } 1957 else 1958 { 1959 sf->setValid(false); 1960 } 1961 } 1962 else 1963 { 1964 warningMismatch("waitFor"); 1965 } 1966 } 1967 1968 void ScriptBuilder::slotWaitForKey() 1969 { 1970 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1971 1972 if (sf->name() == "waitForKey") 1973 { 1974 QString sKey = argWaitForKey->WaitKeyEdit->text().trimmed(); 1975 1976 //DCOP script can only use single keystrokes; make sure entry is either one character, 1977 //or the word 'space' 1978 if (sKey.length() == 1 || sKey == "space") 1979 { 1980 setUnsavedChanges(true); 1981 1982 sf->setArg(0, sKey); 1983 sf->setValid(true); 1984 } 1985 else 1986 { 1987 sf->setValid(false); 1988 } 1989 } 1990 else 1991 { 1992 warningMismatch("waitForKey"); 1993 } 1994 } 1995 1996 void ScriptBuilder::slotTracking() 1997 { 1998 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 1999 2000 if (sf->name() == "setTracking") 2001 { 2002 setUnsavedChanges(true); 2003 2004 sf->setArg(0, (argSetTracking->CheckTrack->isChecked() ? i18n("true") : i18n("false"))); 2005 sf->setValid(true); 2006 } 2007 else 2008 { 2009 warningMismatch("setTracking"); 2010 } 2011 } 2012 2013 void ScriptBuilder::slotViewOption() 2014 { 2015 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2016 2017 if (sf->name() == "changeViewOption") 2018 { 2019 if (argChangeViewOption->OptionName->currentIndex() >= 0 && argChangeViewOption->OptionValue->text().length()) 2020 { 2021 setUnsavedChanges(true); 2022 2023 sf->setArg(0, argChangeViewOption->OptionName->currentText()); 2024 sf->setArg(1, argChangeViewOption->OptionValue->text()); 2025 sf->setValid(true); 2026 } 2027 else 2028 { 2029 sf->setValid(false); 2030 } 2031 } 2032 else 2033 { 2034 warningMismatch("changeViewOption"); 2035 } 2036 } 2037 2038 void ScriptBuilder::slotChangeCity() 2039 { 2040 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2041 2042 if (sf->name() == "setGeoLocation") 2043 { 2044 QString city = argSetGeoLocation->CityName->text(); 2045 2046 if (city.length()) 2047 { 2048 setUnsavedChanges(true); 2049 2050 sf->setArg(0, city); 2051 if (sf->argVal(2).length()) 2052 sf->setValid(true); 2053 } 2054 else 2055 { 2056 sf->setArg(0, QString()); 2057 sf->setValid(false); 2058 } 2059 } 2060 else 2061 { 2062 warningMismatch("setGeoLocation"); 2063 } 2064 } 2065 2066 void ScriptBuilder::slotChangeProvince() 2067 { 2068 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2069 2070 if (sf->name() == "setGeoLocation") 2071 { 2072 QString province = argSetGeoLocation->ProvinceName->text(); 2073 2074 if (province.length()) 2075 { 2076 setUnsavedChanges(true); 2077 2078 sf->setArg(1, province); 2079 if (sf->argVal(0).length() && sf->argVal(2).length()) 2080 sf->setValid(true); 2081 } 2082 else 2083 { 2084 sf->setArg(1, QString()); 2085 //might not be invalid 2086 } 2087 } 2088 else 2089 { 2090 warningMismatch("setGeoLocation"); 2091 } 2092 } 2093 2094 void ScriptBuilder::slotChangeCountry() 2095 { 2096 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2097 2098 if (sf->name() == "setGeoLocation") 2099 { 2100 QString country = argSetGeoLocation->CountryName->text(); 2101 2102 if (country.length()) 2103 { 2104 setUnsavedChanges(true); 2105 2106 sf->setArg(2, country); 2107 if (sf->argVal(0).length()) 2108 sf->setValid(true); 2109 } 2110 else 2111 { 2112 sf->setArg(2, QString()); 2113 sf->setValid(false); 2114 } 2115 } 2116 else 2117 { 2118 warningMismatch("setGeoLocation"); 2119 } 2120 } 2121 2122 void ScriptBuilder::slotTimeScale() 2123 { 2124 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2125 2126 if (sf->name() == "setClockScale") 2127 { 2128 setUnsavedChanges(true); 2129 2130 sf->setArg(0, QString("%1").arg(argTimeScale->TimeScale->tsbox()->timeScale())); 2131 sf->setValid(true); 2132 } 2133 else 2134 { 2135 warningMismatch("setClockScale"); 2136 } 2137 } 2138 2139 void ScriptBuilder::slotZoom() 2140 { 2141 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2142 2143 if (sf->name() == "zoom") 2144 { 2145 setUnsavedChanges(true); 2146 2147 bool ok(false); 2148 argZoom->ZoomBox->text().toDouble(&ok); 2149 if (ok) 2150 { 2151 sf->setArg(0, argZoom->ZoomBox->text()); 2152 sf->setValid(true); 2153 } 2154 } 2155 else 2156 { 2157 warningMismatch("zoom"); 2158 } 2159 } 2160 2161 void ScriptBuilder::slotExportImage() 2162 { 2163 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2164 2165 if (sf->name() == "exportImage") 2166 { 2167 setUnsavedChanges(true); 2168 2169 sf->setArg(0, argExportImage->ExportFileName->url().url()); 2170 sf->setArg(1, QString("%1").arg(argExportImage->ExportWidth->value())); 2171 sf->setArg(2, QString("%1").arg(argExportImage->ExportHeight->value())); 2172 sf->setValid(true); 2173 } 2174 else 2175 { 2176 warningMismatch("exportImage"); 2177 } 2178 } 2179 2180 void ScriptBuilder::slotPrintImage() 2181 { 2182 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2183 2184 if (sf->name() == "printImage") 2185 { 2186 setUnsavedChanges(true); 2187 2188 sf->setArg(0, (argPrintImage->UsePrintDialog->isChecked() ? i18n("true") : i18n("false"))); 2189 sf->setArg(1, (argPrintImage->UseChartColors->isChecked() ? i18n("true") : i18n("false"))); 2190 sf->setValid(true); 2191 } 2192 else 2193 { 2194 warningMismatch("exportImage"); 2195 } 2196 } 2197 2198 void ScriptBuilder::slotChangeColorName() 2199 { 2200 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2201 2202 if (sf->name() == "setColor") 2203 { 2204 setUnsavedChanges(true); 2205 2206 argSetColor->ColorValue->setColor(KStarsData::Instance()->colorScheme()->colorAt(argSetColor->ColorName->currentIndex())); 2207 sf->setArg(0, KStarsData::Instance()->colorScheme()->keyAt(argSetColor->ColorName->currentIndex())); 2208 QString cname(argSetColor->ColorValue->color().name()); 2209 //if ( cname.at(0) == '#' ) cname = "\\" + cname; //prepend a "\" so bash doesn't think we have a comment 2210 sf->setArg(1, cname); 2211 sf->setValid(true); 2212 } 2213 else 2214 { 2215 warningMismatch("setColor"); 2216 } 2217 } 2218 2219 void ScriptBuilder::slotChangeColor() 2220 { 2221 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2222 2223 if (sf->name() == "setColor") 2224 { 2225 setUnsavedChanges(true); 2226 2227 sf->setArg(0, KStarsData::Instance()->colorScheme()->keyAt(argSetColor->ColorName->currentIndex())); 2228 QString cname(argSetColor->ColorValue->color().name()); 2229 //if ( cname.at(0) == '#' ) cname = "\\" + cname; //prepend a "\" so bash doesn't think we have a comment 2230 sf->setArg(1, cname); 2231 sf->setValid(true); 2232 } 2233 else 2234 { 2235 warningMismatch("setColor"); 2236 } 2237 } 2238 2239 void ScriptBuilder::slotLoadColorScheme() 2240 { 2241 ScriptFunction *sf = ScriptList[sb->ScriptListBox->currentRow()]; 2242 2243 if (sf->name() == "loadColorScheme") 2244 { 2245 setUnsavedChanges(true); 2246 2247 sf->setArg(0, '\"' + argLoadColorScheme->SchemeList->currentItem()->text() + '\"'); 2248 sf->setValid(true); 2249 } 2250 else 2251 { 2252 warningMismatch("loadColorScheme"); 2253 } 2254 } 2255 2256 void ScriptBuilder::slotClose() 2257 { 2258 saveWarning(); 2259 2260 if (!UnsavedChanges) 2261 { 2262 ScriptList.clear(); 2263 sb->ScriptListBox->clear(); 2264 sb->ArgStack->setCurrentWidget(argBlank); 2265 close(); 2266 } 2267 } 2268 2269 //TODO JM: INDI Scripting to be included in KDE 4.1 2270 2271 #if 0 2272 void ScriptBuilder::slotINDIStartDeviceName() 2273 { 2274 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2275 2276 if ( sf->name() == "startINDI" ) 2277 { 2278 setUnsavedChanges( true ); 2279 2280 sf->setArg(0, argStartINDI->deviceName->text()); 2281 sf->setArg(1, argStartINDI->LocalButton->isChecked() ? "true" : "false"); 2282 sf->setValid(true); 2283 } 2284 else 2285 { 2286 warningMismatch( "startINDI" ); 2287 } 2288 2289 } 2290 2291 void ScriptBuilder::slotINDIStartDeviceMode() 2292 { 2293 2294 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2295 2296 if ( sf->name() == "startINDI" ) 2297 { 2298 setUnsavedChanges( true ); 2299 2300 sf->setArg(1, argStartINDI->LocalButton->isChecked() ? "true" : "false"); 2301 sf->setValid(true); 2302 } 2303 else 2304 { 2305 warningMismatch( "startINDI" ); 2306 } 2307 2308 } 2309 2310 void ScriptBuilder::slotINDISetDevice() 2311 { 2312 2313 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2314 2315 if ( sf->name() == "setINDIDevice" ) 2316 { 2317 setUnsavedChanges( true ); 2318 2319 sf->setArg(0, argSetDeviceINDI->deviceName->text()); 2320 sf->setValid(true); 2321 } 2322 else 2323 { 2324 warningMismatch( "startINDI" ); 2325 } 2326 } 2327 2328 void ScriptBuilder::slotINDIShutdown() 2329 { 2330 2331 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2332 2333 if ( sf->name() == "shutdownINDI" ) 2334 { 2335 if (argShutdownINDI->deviceName->text().isEmpty()) 2336 { 2337 sf->setValid(false); 2338 return; 2339 } 2340 2341 if (sf->argVal(0) != argShutdownINDI->deviceName->text()) 2342 setUnsavedChanges( true ); 2343 2344 sf->setArg(0, argShutdownINDI->deviceName->text()); 2345 sf->setValid(true); 2346 } 2347 else 2348 { 2349 warningMismatch( "shutdownINDI" ); 2350 } 2351 2352 } 2353 2354 void ScriptBuilder::slotINDISwitchDeviceConnection() 2355 { 2356 2357 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2358 2359 if ( sf->name() == "switchINDI" ) 2360 { 2361 2362 if (sf->argVal(0) != (argSwitchINDI->OnButton->isChecked() ? "true" : "false")) 2363 setUnsavedChanges( true ); 2364 2365 sf->setArg(0, argSwitchINDI->OnButton->isChecked() ? "true" : "false"); 2366 sf->setValid(true); 2367 } 2368 else 2369 { 2370 warningMismatch( "switchINDI" ); 2371 } 2372 2373 } 2374 2375 void ScriptBuilder::slotINDISetPortDevicePort() 2376 { 2377 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2378 2379 if ( sf->name() == "setINDIPort" ) 2380 { 2381 2382 if (argSetPortINDI->devicePort->text().isEmpty()) 2383 { 2384 sf->setValid(false); 2385 return; 2386 } 2387 2388 if (sf->argVal(0) != argSetPortINDI->devicePort->text()) 2389 setUnsavedChanges( true ); 2390 2391 sf->setArg(0, argSetPortINDI->devicePort->text()); 2392 sf->setValid(true); 2393 } 2394 else 2395 { 2396 warningMismatch( "setINDIPort" ); 2397 } 2398 2399 } 2400 2401 void ScriptBuilder::slotINDISetTargetCoordDeviceRA() 2402 { 2403 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2404 2405 if ( sf->name() == "setINDITargetCoord" ) 2406 { 2407 //do nothing if box is blank (because we could be clearing boxes while switching argWidgets) 2408 if ( argSetTargetCoordINDI->RABox->text().isEmpty() ) 2409 { 2410 sf->setValid(false); 2411 return; 2412 } 2413 2414 bool ok(false); 2415 dms ra = argSetTargetCoordINDI->RABox->createDms(&ok); 2416 if ( ok ) 2417 { 2418 2419 if (sf->argVal(0) != QString( "%1" ).arg( ra.Hours() )) 2420 setUnsavedChanges( true ); 2421 2422 sf->setArg( 0, QString( "%1" ).arg( ra.Hours() ) ); 2423 if ( ( ! sf->argVal(1).isEmpty() )) 2424 sf->setValid( true ); 2425 else 2426 sf->setValid(false); 2427 2428 } 2429 else 2430 { 2431 sf->setArg( 0, QString() ); 2432 sf->setValid( false ); 2433 } 2434 } 2435 else 2436 { 2437 warningMismatch( "setINDITargetCoord" ); 2438 } 2439 2440 } 2441 2442 void ScriptBuilder::slotINDISetTargetCoordDeviceDEC() 2443 { 2444 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2445 2446 if ( sf->name() == "setINDITargetCoord" ) 2447 { 2448 //do nothing if box is blank (because we could be clearing boxes while switching argWidgets) 2449 if ( argSetTargetCoordINDI->DecBox->text().isEmpty() ) 2450 { 2451 sf->setValid(false); 2452 return; 2453 } 2454 2455 bool ok(false); 2456 dms dec = argSetTargetCoordINDI->DecBox->createDms(&ok); 2457 if ( ok ) 2458 { 2459 2460 if (sf->argVal(1) != QString( "%1" ).arg( dec.Degrees() )) 2461 setUnsavedChanges( true ); 2462 2463 sf->setArg( 1, QString( "%1" ).arg( dec.Degrees() ) ); 2464 if ( ( ! sf->argVal(0).isEmpty() )) 2465 sf->setValid( true ); 2466 else 2467 sf->setValid(false); 2468 2469 } 2470 else 2471 { 2472 sf->setArg( 1, QString() ); 2473 sf->setValid( false ); 2474 } 2475 } 2476 else 2477 { 2478 warningMismatch( "setINDITargetCoord" ); 2479 } 2480 2481 } 2482 2483 void ScriptBuilder::slotINDIsetCoreProperty(SequenceJob::SJ_TargetName,TargetName() 2484 { 2485 2486 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2487 2488 if ( sf->name() == "setINDITargetName" ) 2489 { 2490 if (argsetCoreProperty(SequenceJob::SJ_TargetName,INDI->targetName->text().isEmpty()) 2491 { 2492 sf->setValid(false); 2493 return; 2494 } 2495 2496 if (sf->argVal(0) != argsetCoreProperty(SequenceJob::SJ_TargetName,INDI->targetName->text()) 2497 setUnsavedChanges( true ); 2498 2499 sf->setArg(0, argsetCoreProperty(SequenceJob::SJ_TargetName,INDI->targetName->text()); 2500 sf->setValid(true); 2501 } 2502 else 2503 { 2504 warningMismatch( "setINDITargetName" ); 2505 } 2506 2507 } 2508 2509 void ScriptBuilder::slotINDISetActionName() 2510 { 2511 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2512 2513 if ( sf->name() == "setINDIAction" ) 2514 { 2515 if (argSetActionINDI->actionName->text().isEmpty()) 2516 { 2517 sf->setValid(false); 2518 return; 2519 } 2520 2521 if (sf->argVal(0) != argSetActionINDI->actionName->text()) 2522 setUnsavedChanges( true ); 2523 2524 sf->setArg(0, argSetActionINDI->actionName->text()); 2525 sf->setValid(true); 2526 } 2527 else 2528 { 2529 warningMismatch( "setINDIAction" ); 2530 } 2531 2532 } 2533 2534 void ScriptBuilder::slotINDIWaitForActionName() 2535 { 2536 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2537 2538 if ( sf->name() == "waitForINDIAction" ) 2539 { 2540 if (argWaitForActionINDI->actionName->text().isEmpty()) 2541 { 2542 sf->setValid(false); 2543 return; 2544 } 2545 2546 if (sf->argVal(0) != argWaitForActionINDI->actionName->text()) 2547 setUnsavedChanges( true ); 2548 2549 sf->setArg(0, argWaitForActionINDI->actionName->text()); 2550 sf->setValid(true); 2551 } 2552 else 2553 { 2554 warningMismatch( "waitForINDIAction" ); 2555 } 2556 2557 } 2558 2559 void ScriptBuilder::slotINDISetFocusSpeed() 2560 { 2561 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2562 2563 if ( sf->name() == "setINDIFocusSpeed" ) 2564 { 2565 2566 if (sf->argVal(0).toInt() != argSetFocusSpeedINDI->speedIN->value()) 2567 setUnsavedChanges( true ); 2568 2569 sf->setArg(0, QString("%1").arg(argSetFocusSpeedINDI->speedIN->value())); 2570 sf->setValid(true); 2571 } 2572 else 2573 { 2574 warningMismatch( "setINDIFocusSpeed" ); 2575 } 2576 2577 } 2578 2579 void ScriptBuilder::slotINDIStartFocusDirection() 2580 { 2581 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2582 2583 if ( sf->name() == "startINDIFocus" ) 2584 { 2585 if (sf->argVal(0) != argStartFocusINDI->directionCombo->currentText()) 2586 setUnsavedChanges( true ); 2587 2588 sf->setArg(0, argStartFocusINDI->directionCombo->currentText()); 2589 sf->setValid(true); 2590 } 2591 else 2592 { 2593 warningMismatch( "startINDIFocus" ); 2594 } 2595 2596 } 2597 2598 void ScriptBuilder::slotINDISetFocusTimeout() 2599 { 2600 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2601 2602 if ( sf->name() == "setINDIFocusTimeout" ) 2603 { 2604 if (sf->argVal(0).toInt() != argSetFocusTimeoutINDI->timeOut->value()) 2605 setUnsavedChanges( true ); 2606 2607 sf->setArg(0, QString("%1").arg(argSetFocusTimeoutINDI->timeOut->value())); 2608 sf->setValid(true); 2609 } 2610 else 2611 { 2612 warningMismatch( "setINDIFocusTimeout" ); 2613 } 2614 2615 } 2616 2617 void ScriptBuilder::slotINDISetGeoLocationDeviceLong() 2618 { 2619 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2620 2621 if ( sf->name() == "setINDIGeoLocation" ) 2622 { 2623 //do nothing if box is blank (because we could be clearing boxes while switching argWidgets) 2624 if ( argSetGeoLocationINDI->longBox->text().isEmpty()) 2625 { 2626 sf->setValid(false); 2627 return; 2628 } 2629 2630 bool ok(false); 2631 dms longitude = argSetGeoLocationINDI->longBox->createDms(&ok); 2632 if ( ok ) 2633 { 2634 2635 if (sf->argVal(0) != QString( "%1" ).arg( longitude.Degrees())) 2636 setUnsavedChanges( true ); 2637 2638 sf->setArg( 0, QString( "%1" ).arg( longitude.Degrees() ) ); 2639 if ( ! sf->argVal(1).isEmpty() ) 2640 sf->setValid( true ); 2641 else 2642 sf->setValid(false); 2643 2644 } 2645 else 2646 { 2647 sf->setArg( 0, QString() ); 2648 sf->setValid( false ); 2649 } 2650 } 2651 else 2652 { 2653 warningMismatch( "setINDIGeoLocation" ); 2654 } 2655 2656 } 2657 2658 void ScriptBuilder::slotINDISetGeoLocationDeviceLat() 2659 { 2660 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2661 2662 if ( sf->name() == "setINDIGeoLocation" ) 2663 { 2664 //do nothing if box is blank (because we could be clearing boxes while switching argWidgets) 2665 if ( argSetGeoLocationINDI->latBox->text().isEmpty() ) 2666 { 2667 sf->setValid(false); 2668 return; 2669 } 2670 2671 bool ok(false); 2672 dms latitude = argSetGeoLocationINDI->latBox->createDms(&ok); 2673 if ( ok ) 2674 { 2675 2676 if (sf->argVal(1) != QString( "%1" ).arg( latitude.Degrees())) 2677 setUnsavedChanges( true ); 2678 2679 sf->setArg( 1, QString( "%1" ).arg( latitude.Degrees() ) ); 2680 if ( ! sf->argVal(0).isEmpty() ) 2681 sf->setValid( true ); 2682 else 2683 sf->setValid(false); 2684 2685 } 2686 else 2687 { 2688 sf->setArg( 1, QString() ); 2689 sf->setValid( false ); 2690 } 2691 } 2692 else 2693 { 2694 warningMismatch( "setINDIGeoLocation" ); 2695 } 2696 2697 } 2698 2699 void ScriptBuilder::slotINDIStartExposureTimeout() 2700 { 2701 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2702 2703 if ( sf->name() == "startINDIExposure" ) 2704 { 2705 2706 if (sf->argVal(0).toInt() != argStartExposureINDI->timeOut->value()) 2707 setUnsavedChanges( true ); 2708 2709 sf->setArg(0, QString("%1").arg(argStartExposureINDI->timeOut->value())); 2710 sf->setValid(true); 2711 } 2712 else 2713 { 2714 warningMismatch( "startINDIExposure" ); 2715 } 2716 2717 } 2718 2719 void ScriptBuilder::slotINDISetUTC() 2720 { 2721 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2722 2723 if ( sf->name() == "setINDIUTC" ) 2724 { 2725 2726 if (argSetUTCINDI->UTC->text().isEmpty()) 2727 { 2728 sf->setValid(false); 2729 return; 2730 } 2731 2732 if (sf->argVal(0) != argSetUTCINDI->UTC->text()) 2733 setUnsavedChanges( true ); 2734 2735 sf->setArg(0, argSetUTCINDI->UTC->text()); 2736 sf->setValid(true); 2737 } 2738 else 2739 { 2740 warningMismatch( "setINDIUTC" ); 2741 } 2742 2743 } 2744 2745 void ScriptBuilder::slotINDISetScopeAction() 2746 { 2747 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2748 2749 if ( sf->name() == "setINDIScopeAction" ) 2750 { 2751 2752 if (sf->argVal(0) != argSetScopeActionINDI->actionCombo->currentText()) 2753 setUnsavedChanges( true ); 2754 2755 sf->setArg(0, argSetScopeActionINDI->actionCombo->currentText()); 2756 sf->setINDIProperty("CHECK"); 2757 sf->setValid(true); 2758 } 2759 else 2760 { 2761 warningMismatch( "setINDIScopeAction" ); 2762 } 2763 2764 } 2765 2766 void ScriptBuilder::slotINDISetFrameType() 2767 { 2768 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2769 2770 if ( sf->name() == "setINDIFrameType" ) 2771 { 2772 2773 if (sf->argVal(0) != argSetFrameTypeINDI->typeCombo->currentText()) 2774 setUnsavedChanges( true ); 2775 2776 sf->setArg(0, argSetFrameTypeINDI->typeCombo->currentText()); 2777 sf->setValid(true); 2778 } 2779 else 2780 { 2781 warningMismatch( "setINDIFrameType" ); 2782 } 2783 2784 } 2785 2786 void ScriptBuilder::slotINDISetCCDTemp() 2787 { 2788 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2789 2790 if ( sf->name() == "setINDICCDTemp" ) 2791 { 2792 2793 if (sf->argVal(0).toInt() != argSetCCDTempINDI->temp->value()) 2794 setUnsavedChanges( true ); 2795 2796 sf->setArg(0, QString("%1").arg(argSetCCDTempINDI->temp->value())); 2797 sf->setValid(true); 2798 } 2799 else 2800 { 2801 warningMismatch( "setINDICCDTemp" ); 2802 } 2803 2804 } 2805 2806 void ScriptBuilder::slotINDISetFilterNum() 2807 { 2808 2809 ScriptFunction * sf = ScriptList[ sb->ScriptListBox->currentRow() ]; 2810 2811 if ( sf->name() == "setINDIFilterNum" ) 2812 { 2813 2814 if (sf->argVal(0).toInt() != argSetFilterNumINDI->filter_num->value()) 2815 setUnsavedChanges( true ); 2816 2817 sf->setArg(0, QString("%1").arg(argSetFilterNumINDI->filter_num->value())); 2818 sf->setValid(true); 2819 } 2820 else 2821 { 2822 warningMismatch( "setINDIFilterNum" ); 2823 } 2824 2825 2826 } 2827 #endif 2828 2829 void ScriptBuilder::warningMismatch(const QString &expected) const 2830 { 2831 qWarning() << i18n("Mismatch between function and Arg widget (expected %1.)", QString(expected)); 2832 }