File indexing completed on 2024-05-05 05:53:00
0001 // SPDX-FileCopyrightText: 1998 Matthias Hoelzer <hoelzer@kde.org> 0002 // SPDX-FileCopyrightText: 2002, 2016 David Faure <faure@kde.org> 0003 // SPDX-FileCopyrightText: 2005 Brad Hards <bradh@frogmouth.net> 0004 // SPDX-FileCopyrightText: 2008 Dmitry Suzdalev <dimsuz@gmail.com> 0005 // SPDX-FileCopyrightText: 2011 Kai Uwe Broulik <kde@privat.broulik.de> 0006 // SPDX-FileCopyrightText: 2020 Tristan Miller <psychonaut@nothingisreal.com> 0007 // 0008 // SPDX-License-Identifier: GPL-2.0-or-later 0009 0010 #include "config-kdialog.h" 0011 #include "widgets.h" 0012 #include "utils.h" 0013 #include "kdialog_version.h" 0014 0015 // KF 0016 #include <KMessageBox> 0017 #include <KRecentDocument> 0018 #include <KAboutData> 0019 #include <KConfig> 0020 #include <KIconDialog> 0021 #include <KColorMimeData> 0022 #include <KWindowSystem> 0023 #include <KIconLoader> 0024 #include <KLocalizedString> 0025 0026 0027 // Qt 0028 #include <QApplication> 0029 #include <QDate> 0030 #include <QDateTime> 0031 #include <QCheckBox> 0032 #include <QClipboard> 0033 #include <QColorDialog> 0034 #include <QDBusServiceWatcher> 0035 #include <QDebug> 0036 #include <QFileDialog> 0037 #include <QUrl> 0038 #include <QProcess> 0039 #include <QRegularExpression> 0040 #include <QTimer> 0041 0042 #include <iostream> 0043 #include <memory> 0044 0045 #if defined HAVE_X11 0046 #include <X11/Xlib.h> 0047 #include <X11/Xutil.h> 0048 #endif 0049 0050 #include <QDBusConnection> 0051 #include <QDBusConnectionInterface> 0052 0053 #include <unistd.h> 0054 #include <QCommandLineParser> 0055 #include <QCommandLineOption> 0056 0057 using namespace std; 0058 0059 // this class hooks into the eventloop and outputs the id 0060 // of shown dialogs or makes the dialog transient for other winids. 0061 // Will destroy itself on app exit. 0062 class ForeignWindowAttacher : public QObject 0063 { 0064 public: 0065 ForeignWindowAttacher(bool printID, const QString &parentHandle) 0066 : QObject(qApp) 0067 , print(printID) 0068 , parentHandle(parentHandle) 0069 { 0070 if (qApp) { 0071 qApp->installEventFilter(this); 0072 } 0073 } 0074 0075 protected: 0076 bool eventFilter(QObject *o, QEvent *e) override; 0077 private: 0078 bool print; 0079 QString parentHandle; 0080 }; 0081 0082 bool ForeignWindowAttacher::eventFilter(QObject *o, QEvent *e) 0083 { 0084 if (e->type() == QEvent::Show && o->isWidgetType() 0085 && o->inherits("QDialog")) { 0086 auto w = static_cast<QWidget *>(o); 0087 if (print) { 0088 cout << "winId: " << w->winId() << endl; 0089 } 0090 if (!parentHandle.isEmpty()) { 0091 w->setAttribute(Qt::WA_NativeWindow, true); 0092 KWindowSystem::setMainWindow(w->windowHandle(), parentHandle); 0093 } 0094 deleteLater(); // ForeignWindowAttacher is not needed anymore after the first dialog was shown 0095 return false; 0096 } 0097 return QObject::eventFilter(o, e); 0098 } 0099 0100 /** 0101 * Display a passive notification popup using the D-Bus interface, if possible. 0102 * @return true if the notification was successfully sent, false otherwise. 0103 */ 0104 static bool sendVisualNotification(const QString &text, const QString &title, const QString &icon, int timeout) 0105 { 0106 const QString dbusServiceName = QStringLiteral("org.freedesktop.Notifications"); 0107 const QString dbusInterfaceName = QStringLiteral("org.freedesktop.Notifications"); 0108 const QString dbusPath = QStringLiteral("/org/freedesktop/Notifications"); 0109 0110 // check if service already exists on plugin instantiation 0111 QDBusConnectionInterface *interface = QDBusConnection::sessionBus().interface(); 0112 0113 if (!interface || !interface->isServiceRegistered(dbusServiceName)) { 0114 //kDebug() << dbusServiceName << "D-Bus service not registered"; 0115 return false; 0116 } 0117 0118 if (timeout == 0) { 0119 timeout = 10 * 1000; 0120 } 0121 0122 QDBusMessage m = QDBusMessage::createMethodCall(dbusServiceName, dbusPath, dbusInterfaceName, QStringLiteral("Notify")); 0123 QList<QVariant> args; 0124 0125 args.append(QStringLiteral("kdialog")); // app_name 0126 args.append(0U); // replaces_id 0127 args.append(icon); // app_icon 0128 args.append(title); // summary 0129 args.append(text); // body 0130 args.append(QStringList()); // actions - unused for plain passive popups 0131 args.append(QVariantMap()); // hints - unused atm 0132 args.append(timeout); // expire timeout 0133 0134 m.setArguments(args); 0135 0136 QDBusMessage replyMsg = QDBusConnection::sessionBus().call(m); 0137 if (replyMsg.type() == QDBusMessage::ReplyMessage) { 0138 if (!replyMsg.arguments().isEmpty()) { 0139 return true; 0140 } 0141 // Not displaying any error messages as this is optional for kdialog 0142 // and KPassivePopup is a perfectly valid fallback. 0143 //else { 0144 // kDebug() << "Error: received reply with no arguments."; 0145 //} 0146 } else if (replyMsg.type() == QDBusMessage::ErrorMessage) { 0147 //kDebug() << "Error: failed to send D-Bus message"; 0148 //kDebug() << replyMsg; 0149 } else { 0150 //kDebug() << "Unexpected reply type"; 0151 } 0152 0153 return false; 0154 } 0155 0156 static void outputStringList(const QStringList &list, bool separateOutput) 0157 { 0158 if (separateOutput) { 0159 for (QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) { 0160 cout << (*it).toLocal8Bit().data() << endl; 0161 } 0162 } else { 0163 for (QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) { 0164 cout << (*it).toLocal8Bit().data() << " "; 0165 } 0166 cout << endl; 0167 } 0168 } 0169 0170 static void outputStringList(const QList<QUrl> &list, bool separateOutput) 0171 { 0172 if (separateOutput) { 0173 for (auto it = list.constBegin(); it != list.constEnd(); ++it) { 0174 cout << (*it).toDisplayString().toLocal8Bit().data() << endl; 0175 } 0176 } else { 0177 for (auto it = list.constBegin(); it != list.constEnd(); ++it) { 0178 cout << (*it).toDisplayString().toLocal8Bit().data() << " "; 0179 } 0180 cout << endl; 0181 } 0182 } 0183 0184 static KGuiItem configuredYes(const QString &text) 0185 { 0186 return KGuiItem(text, QStringLiteral("dialog-ok")); 0187 } 0188 0189 static KGuiItem configuredNo(const QString &text) 0190 { 0191 return KGuiItem(text, QStringLiteral("process-stop")); 0192 } 0193 0194 static KGuiItem configuredCancel(const QString &text) 0195 { 0196 return KGuiItem(text, QStringLiteral("dialog-cancel")); 0197 } 0198 0199 static KGuiItem configuredContinue(const QString &text) 0200 { 0201 return KGuiItem(text, QStringLiteral("arrow-right")); 0202 } 0203 0204 static void setFileDialogFilter(QFileDialog &dlg, const QString &filter) 0205 { 0206 if (filter.contains(QLatin1String("*"))) { 0207 QString qtFilter = filter; 0208 dlg.setNameFilter(qtFilter.replace(QLatin1Char('|'), QLatin1Char('\n'))); 0209 } else if (!filter.isEmpty()) { 0210 dlg.setMimeTypeFilters(filter.trimmed().split(QLatin1Char(' '))); 0211 } 0212 } 0213 0214 // taken from qfiledialog.cp 0215 static QString initialSelection(const QUrl &url) 0216 { 0217 if (url.isEmpty()) { 0218 return QString(); 0219 } 0220 if (url.isLocalFile()) { 0221 QFileInfo info(url.toLocalFile()); 0222 if (!info.isDir()) { 0223 return info.fileName(); 0224 } else { 0225 return QString(); 0226 } 0227 } 0228 // With remote URLs we can only assume. 0229 return url.fileName(); 0230 } 0231 0232 static QUrl initialDirectory(const QUrl &url) 0233 { 0234 if (url.isLocalFile() && QFileInfo(url.toLocalFile()).isDir()) { 0235 return url; 0236 } 0237 return url.adjusted(QUrl::RemoveFilename); 0238 } 0239 0240 int main(int argc, char *argv[]) 0241 { 0242 // Bug 373677: Qt removes various arguments it treats internally (such as title and icon) from args 0243 // and applies them to the first Qt::Window, while here we only show dialogs 0244 // so we need to store them before we even create our QApplication 0245 QStringList rawArgs; 0246 for (int i = 0; i < argc; ++i) { 0247 rawArgs << QString::fromLocal8Bit(argv[i]); 0248 } 0249 0250 QApplication app(argc, argv); 0251 KLocalizedString::setApplicationDomain(QByteArrayLiteral("kdialog")); 0252 0253 KAboutData aboutData(QStringLiteral("kdialog"), QString(), 0254 QStringLiteral(KDIALOG_VERSION_STRING), i18n("KDialog can be used to show nice dialog boxes from shell scripts"), 0255 KAboutLicense::GPL, 0256 i18n("(C) 2000, Nick Thompson")); 0257 aboutData.addAuthor(i18n("David Faure"), i18n("Current maintainer"), QStringLiteral("faure@kde.org")); 0258 aboutData.addAuthor(i18n("Brad Hards"), QString(), QStringLiteral("bradh@frogmouth.net")); 0259 aboutData.addAuthor(i18n("Nick Thompson"), QString(), QString() /*"nickthompson@lucent.com" bounces*/); 0260 aboutData.addAuthor(i18n("Matthias Hölzer"), QString(), QStringLiteral("hoelzer@kde.org")); 0261 aboutData.addAuthor(i18n("David Gümbel"), QString(), QStringLiteral("david.guembel@gmx.net")); 0262 aboutData.addAuthor(i18n("Richard Moore"), QString(), QStringLiteral("rich@kde.org")); 0263 aboutData.addAuthor(i18n("Dawit Alemayehu"), QString(), QStringLiteral("adawit@kde.org")); 0264 aboutData.addAuthor(i18n("Kai Uwe Broulik"), QString(), QStringLiteral("kde@privat.broulik.de")); 0265 KAboutData::setApplicationData(aboutData); 0266 QGuiApplication::setApplicationDisplayName(QString()); 0267 0268 QCommandLineParser parser; 0269 aboutData.setupCommandLine(&parser); 0270 0271 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("yesno"), i18n("Question message box with yes/no buttons"), QStringLiteral("text"))); 0272 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("yesnocancel"), i18n("Question message box with yes/no/cancel buttons"), QStringLiteral("text"))); 0273 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("warningyesno"), i18n("Warning message box with yes/no buttons"), QStringLiteral("text"))); 0274 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("warningcontinuecancel"), i18n("Warning message box with continue/cancel buttons"), QStringLiteral("text"))); 0275 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("warningyesnocancel"), i18n("Warning message box with yes/no/cancel buttons"), QStringLiteral("text"))); 0276 0277 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("ok-label"), i18n("Use text as OK button label"), QStringLiteral("text"))); 0278 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("yes-label"), i18n("Use text as Yes button label"), QStringLiteral("text"))); 0279 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("no-label"), i18n("Use text as No button label"), QStringLiteral("text"))); 0280 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("cancel-label"), i18n("Use text as Cancel button label"), QStringLiteral("text"))); 0281 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("continue-label"), i18n("Use text as Continue button label"), QStringLiteral("text"))); 0282 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("sorry"), i18n("'Sorry' message box"), QStringLiteral("text"))); 0283 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("detailedsorry"), i18n("'Sorry' message box with expandable Details field"), QStringLiteral("text> <details"))); 0284 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("error"), i18n("'Error' message box"), QStringLiteral("text"))); 0285 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("detailederror"), i18n("'Error' message box with expandable Details field"), QStringLiteral("text> <details"))); 0286 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("msgbox"), i18n("Message Box dialog"), QStringLiteral("text"))); 0287 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("inputbox"), i18n("Input Box dialog"), QStringLiteral("text> <init"))); 0288 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("imgbox"), i18n("Image Box dialog"), QStringLiteral("file"))); 0289 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("imginputbox"), i18n("Image Box Input dialog"), QStringLiteral("file> <text"))); 0290 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("password"), i18n("Password dialog"), QStringLiteral("text"))); 0291 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("newpassword"), i18n("New Password dialog"), QStringLiteral("text"))); 0292 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("textbox"), i18n("Text Box dialog"), QStringLiteral("file"))); 0293 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("textinputbox"), i18n("Text Input Box dialog"), QStringLiteral("text> <init"))); 0294 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("combobox"), i18n("ComboBox dialog"), QStringLiteral("text"))); 0295 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("menu"), i18n("Menu dialog"), QStringLiteral("text"))); 0296 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("checklist"), i18n("Check List dialog"), QStringLiteral("text"))); 0297 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("radiolist"), i18n("Radio List dialog"), QStringLiteral("text"))); 0298 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("passivepopup"), i18n("Passive Popup"), QStringLiteral("text> <timeout"))); 0299 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("icon"), i18n("Popup icon"), QStringLiteral("icon"))); 0300 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("getopenfilename"), i18n("File dialog to open an existing file (arguments [startDir] [filter])"))); 0301 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("getsavefilename"), i18n("File dialog to save a file (arguments [startDir] [filter])"))); 0302 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("getexistingdirectory"), i18n("File dialog to select an existing directory (arguments [startDir])"))); 0303 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("getopenurl"), i18n("File dialog to open an existing URL (arguments [startDir] [filter])"))); 0304 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("getsaveurl"), i18n("File dialog to save a URL (arguments [startDir] [filter])"))); 0305 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("geticon"), i18n("Icon chooser dialog (arguments [group] [context])"))); 0306 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("progressbar"), i18n("Progress bar dialog, returns a D-Bus reference for communication"), QStringLiteral("text"))); 0307 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("getcolor"), i18n("Color dialog to select a color"))); 0308 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("format"), i18n("Allow --getcolor to specify output format"), QStringLiteral("text"))); 0309 // TODO gauge stuff, reading values from stdin 0310 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("title"), i18n("Dialog title"), QStringLiteral("text"))); 0311 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("default"), i18n("Default entry to use for combobox, menu, color, and calendar"), QStringLiteral("text"))); 0312 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("multiple"), i18n("Allows the --getopenurl and --getopenfilename options to return multiple files"))); 0313 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("separate-output"), i18n("Return list items on separate lines (for checklist option and file open with --multiple)"))); 0314 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("print-winid"), i18n("Outputs the winId of each dialog"))); 0315 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("dontagain"), i18n("Config file and option name for saving the \"do-not-show/ask-again\" state"), 0316 QStringLiteral("file:entry"))); 0317 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("slider"), i18n("Slider dialog box, returns selected value (arguments [text] [min] [max] [step])"))); 0318 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("dateformat"), i18n("Date format for calendar result and/or default value (Qt-style); defaults to 'ddd MMM d yyyy'"), QStringLiteral("text"))); 0319 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("calendar"), i18n("Calendar dialog box, returns selected date"), QStringLiteral("text"))); 0320 /* kdialog originally used --embed for attaching the dialog box. However this is misleading and so we changed to --attach. 0321 * For backwards compatibility, we silently map --embed to --attach */ 0322 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("attach"), i18n("Makes the dialog transient for an X app specified by winid"), QStringLiteral("winid"))); 0323 QCommandLineOption embedOption(QStringList() << QStringLiteral("embed"), i18n("A synonym for --attach"), QStringLiteral("winid")); 0324 embedOption.setFlags(QCommandLineOption::HiddenFromHelp); 0325 parser.addOption(embedOption); 0326 parser.addOption(QCommandLineOption(QStringList() << QStringLiteral("geometry"), i18n("Dialog geometry: [=][<width>{xX}<height>][{+-}<xoffset>{+-}<yoffset>]"), QStringLiteral("geometry"))); 0327 0328 parser.addPositionalArgument(QStringLiteral("[arg]"), i18n("Arguments - depending on main option")); 0329 0330 parser.process(rawArgs); 0331 aboutData.processCommandLine(&parser); 0332 0333 // execute kdialog command 0334 0335 QApplication::setWindowIcon(QIcon::fromTheme(parser.value(QStringLiteral("icon")), QIcon::fromTheme(QStringLiteral("system-run")))); 0336 0337 const QStringList args = parser.positionalArguments(); 0338 QString title = parser.value(QStringLiteral("title")); 0339 if (title.isEmpty()) { 0340 title = i18n("KDialog"); 0341 } 0342 const bool separateOutput = parser.isSet(QStringLiteral("separate-output")); 0343 const bool printWId = parser.isSet(QStringLiteral("print-winid")); 0344 QString defaultEntry; 0345 const QString geometry = parser.value(QStringLiteral("geometry")); 0346 Utils::setGeometry(geometry); 0347 0348 QString parentHandle; 0349 bool attach = parser.isSet(QStringLiteral("attach")); 0350 if (attach) { 0351 parentHandle = parser.value(QStringLiteral("attach")); 0352 } else if (parser.isSet(QStringLiteral("embed"))) { 0353 /* KDialog originally used --embed for attaching the dialog box. However this is misleading and so we changed to --attach. 0354 * For consistency, we silently map --embed to --attach */ 0355 attach = true; 0356 parentHandle = parser.value(QStringLiteral("embed")); 0357 } 0358 0359 if (printWId || attach) { 0360 (void)new ForeignWindowAttacher(printWId, parentHandle); 0361 } 0362 0363 // button labels 0364 // Initialize with default labels 0365 KGuiItem okButton = KStandardGuiItem::ok(); 0366 KGuiItem yesButton = configuredYes(i18nc("@action:button", "&Yes")); 0367 KGuiItem noButton = configuredNo(i18nc("@action:button", "&No")); 0368 KGuiItem cancelButton = KStandardGuiItem::cancel(); 0369 KGuiItem continueButton = KStandardGuiItem::cont(); 0370 0371 // Customize the asked labels 0372 if (parser.isSet(QStringLiteral("ok-label"))) { 0373 okButton = configuredYes( parser.value(QStringLiteral("ok-label")) ); 0374 } 0375 if (parser.isSet(QStringLiteral("yes-label"))) { 0376 yesButton = configuredYes(parser.value(QStringLiteral("yes-label"))); 0377 } 0378 if (parser.isSet(QStringLiteral("no-label"))) { 0379 noButton = configuredNo(parser.value(QStringLiteral("no-label"))); 0380 } 0381 if (parser.isSet(QStringLiteral("cancel-label"))) { 0382 cancelButton = configuredCancel(parser.value(QStringLiteral("cancel-label"))); 0383 } 0384 if (parser.isSet(QStringLiteral("continue-label"))) { 0385 continueButton = configuredContinue(parser.value(QStringLiteral("continue-label"))); 0386 } 0387 0388 // --yesno and other message boxes 0389 auto type = static_cast<KMessageBox::DialogType>(0); 0390 QMessageBox::Icon icon = QMessageBox::Question; 0391 QByteArray option; 0392 if (parser.isSet(QStringLiteral("yesno"))) { 0393 option = "yesno"; 0394 type = KMessageBox::QuestionTwoActions; 0395 } else if (parser.isSet(QStringLiteral("yesnocancel"))) { 0396 option = "yesnocancel"; 0397 type = KMessageBox::QuestionTwoActionsCancel; 0398 } else if (parser.isSet(QStringLiteral("warningyesno"))) { 0399 option = "warningyesno"; 0400 type = KMessageBox::WarningTwoActions; 0401 icon = QMessageBox::Warning; 0402 } else if (parser.isSet(QStringLiteral("warningcontinuecancel"))) { 0403 option = "warningcontinuecancel"; 0404 type = KMessageBox::WarningContinueCancel; 0405 icon = QMessageBox::Warning; 0406 } else if (parser.isSet(QStringLiteral("warningyesnocancel"))) { 0407 option = "warningyesnocancel"; 0408 type = KMessageBox::WarningTwoActionsCancel; 0409 icon = QMessageBox::Warning; 0410 } else if (parser.isSet(QStringLiteral("sorry"))) { 0411 option = "sorry"; 0412 type = KMessageBox::Error; 0413 icon = QMessageBox::Warning; 0414 } else if (parser.isSet(QStringLiteral("detailedsorry"))) { 0415 option = "detailedsorry"; 0416 type = KMessageBox::Error; 0417 icon = QMessageBox::Warning; 0418 } else if (parser.isSet(QStringLiteral("error"))) { 0419 option = "error"; 0420 type = KMessageBox::Error; 0421 icon = QMessageBox::Critical; 0422 } else if (parser.isSet(QStringLiteral("detailederror"))) { 0423 option = "detailederror"; 0424 type = KMessageBox::Error; 0425 icon = QMessageBox::Critical; 0426 } else if (parser.isSet(QStringLiteral("msgbox"))) { 0427 option = "msgbox"; 0428 type = KMessageBox::Information; 0429 icon = QMessageBox::Information; 0430 } 0431 0432 if (!option.isEmpty()) { 0433 std::unique_ptr<KConfig> dontagaincfg; 0434 // --dontagain 0435 QString dontagain; // QString() 0436 if (parser.isSet(QStringLiteral("dontagain"))) { 0437 QString value = parser.value(QStringLiteral("dontagain")); 0438 const QStringList values = value.split(QLatin1Char(':'), Qt::SkipEmptyParts); 0439 if (values.count() == 2) { 0440 dontagaincfg.reset(new KConfig(values[0])); 0441 KMessageBox::setDontShowAgainConfig(dontagaincfg.get()); 0442 dontagain = values[ 1 ]; 0443 0444 if (type == KMessageBox::WarningContinueCancel) { 0445 if (!KMessageBox::shouldBeShownContinue(dontagain)) { 0446 return 0; 0447 } 0448 } else { 0449 KMessageBox::ButtonCode code; 0450 if (!KMessageBox::shouldBeShownTwoActions(dontagain, code)) { 0451 return code == KMessageBox::PrimaryAction ? 0 : 1; 0452 } 0453 } 0454 } else { 0455 qDebug("Incorrect --dontagain!"); 0456 } 0457 } 0458 0459 QString text = Utils::parseString(parser.value(QString::fromLatin1(option))); 0460 0461 QString details; 0462 if (args.count() == 1) { 0463 details = Utils::parseString(args.at(0)); 0464 } 0465 0466 QDialog dialog; 0467 dialog.setWindowTitle(title); 0468 auto buttonBox = new QDialogButtonBox(&dialog); 0469 KMessageBox::Options options = KMessageBox::NoExec | KMessageBox::Notify; 0470 0471 switch (type) { 0472 case KMessageBox::QuestionTwoActions: 0473 case KMessageBox::WarningTwoActions: 0474 buttonBox->setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No); 0475 KGuiItem::assign(buttonBox->button(QDialogButtonBox::Yes), yesButton); 0476 KGuiItem::assign(buttonBox->button(QDialogButtonBox::No), noButton); 0477 break; 0478 case KMessageBox::QuestionTwoActionsCancel: 0479 case KMessageBox::WarningTwoActionsCancel: 0480 buttonBox->setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No | QDialogButtonBox::Cancel); 0481 KGuiItem::assign(buttonBox->button(QDialogButtonBox::Yes), yesButton); 0482 KGuiItem::assign(buttonBox->button(QDialogButtonBox::No), noButton); 0483 KGuiItem::assign(buttonBox->button(QDialogButtonBox::Cancel), cancelButton); 0484 break; 0485 case KMessageBox::WarningContinueCancel: 0486 buttonBox->setStandardButtons(QDialogButtonBox::Yes | QDialogButtonBox::No); 0487 KGuiItem::assign(buttonBox->button(QDialogButtonBox::Yes), continueButton); 0488 KGuiItem::assign(buttonBox->button(QDialogButtonBox::No), cancelButton); 0489 break; 0490 case KMessageBox::Error: 0491 case KMessageBox::Information: 0492 buttonBox->addButton(QDialogButtonBox::Ok); 0493 KGuiItem::assign(buttonBox->button(QDialogButtonBox::Ok), okButton); 0494 buttonBox->button(QDialogButtonBox::Ok)->setFocus(); 0495 break; 0496 } 0497 (void)KMessageBox::createKMessageBox(&dialog, // dialog 0498 buttonBox, // buttons 0499 icon, // icon 0500 text, // text 0501 {}, // strlist 0502 dontagain.isEmpty() ? QString() : i18n("Do not ask again"), // ask 0503 nullptr, // checkboxReturn 0504 options, // options 0505 details); // details 0506 Utils::handleXGeometry(&dialog); 0507 const auto ret = QDialogButtonBox::StandardButton(dialog.exec()); 0508 if (!dontagain.isEmpty()) { 0509 // We use NoExec in order to call handleXGeometry before exec 0510 // But that means we need to query the state of the dontShowAgain checkbox ourselves too... 0511 auto cb = dialog.findChild<QCheckBox *>(); 0512 Q_ASSERT(cb); 0513 if (cb && cb->isChecked()) { 0514 if (type == KMessageBox::WarningContinueCancel) { 0515 if (ret == QDialogButtonBox::Yes) { 0516 KMessageBox::saveDontShowAgainContinue(dontagain); 0517 } 0518 } else if (ret != QDialogButtonBox::Cancel) { 0519 KMessageBox::saveDontShowAgainTwoActions(dontagain, ret == QDialogButtonBox::Yes ? KMessageBox::PrimaryAction : KMessageBox::SecondaryAction); 0520 } 0521 } 0522 } 0523 // We want to return 0 for ok, yes and continue, 1 for no and 2 for cancel 0524 return (ret == QDialogButtonBox::Ok || ret == QDialogButtonBox::Yes) ? 0 0525 : (ret == QDialogButtonBox::No ? 1 : 2); 0526 } 0527 0528 // --inputbox text [init] 0529 if (parser.isSet(QStringLiteral("inputbox"))) { 0530 QString result; 0531 QString init; 0532 0533 if (args.count() > 0) { 0534 init = args.at(0); 0535 } 0536 0537 const bool retcode = Widgets::inputBox(nullptr, title, Utils::parseString(parser.value(QStringLiteral("inputbox"))), init, result); 0538 cout << result.toLocal8Bit().data() << endl; 0539 return retcode ? 0 : 1; 0540 } 0541 0542 // --password text 0543 if (parser.isSet(QStringLiteral("password"))) { 0544 QString result; 0545 // Note that KPasswordDialog (as of 5.73.0) word-wraps the prompt, so newlines will be converted to spaces 0546 const bool retcode = Widgets::passwordBox(nullptr, title, Utils::parseString(parser.value(QStringLiteral("password"))), result); 0547 cout << qPrintable(result) << endl; 0548 return retcode ? 0 : 1; 0549 } 0550 0551 // --newpassword text 0552 if (parser.isSet(QStringLiteral("newpassword"))) { 0553 QString result; 0554 const bool retcode = Widgets::newPasswordBox(nullptr, title, Utils::parseString(parser.value(QStringLiteral("newpassword"))), result); 0555 cout << qPrintable(result) << endl; 0556 return retcode ? 0 : 1; 0557 } 0558 0559 // --passivepopup 0560 if (parser.isSet(QStringLiteral("passivepopup"))) { 0561 int timeout = 0; 0562 if (args.count() > 0) { 0563 timeout = 1000 * args.at(0).toInt(); 0564 } 0565 0566 if (timeout < 0) { 0567 timeout = -1; 0568 } 0569 0570 // Use --icon parameter for passivepopup as well 0571 QString iconArg; 0572 if (parser.isSet(QStringLiteral("icon"))) { 0573 iconArg = parser.value(QStringLiteral("icon")); 0574 } else { 0575 iconArg = QStringLiteral("dialog-information"); // Use generic (i)-icon if none specified 0576 } 0577 0578 // try to use more stylish notifications 0579 const bool result = sendVisualNotification(Utils::parseString(parser.value(QStringLiteral("passivepopup"))), title, iconArg, timeout); 0580 if (result) { 0581 return 0; 0582 } 0583 0584 qApp->exec(); 0585 return 0; 0586 } 0587 0588 // --textbox file [width] [height] 0589 if (parser.isSet(QStringLiteral("textbox"))) { 0590 int w = 0; 0591 int h = 0; 0592 0593 if (args.count() == 2) { 0594 w = args.at(0).toInt(); 0595 h = args.at(1).toInt(); 0596 } 0597 0598 return Widgets::textBox(nullptr, w, h, title, parser.value(QStringLiteral("textbox"))); 0599 } 0600 0601 // --imgbox <file> 0602 if (parser.isSet(QStringLiteral("imgbox"))) { 0603 return Widgets::imgBox(nullptr, title, parser.value(QStringLiteral("imgbox"))); 0604 } 0605 0606 // --imginputbox <file> [text] 0607 if (parser.isSet(QStringLiteral("imginputbox"))) { 0608 QString result; 0609 QString text; 0610 0611 if (args.count() > 0) { 0612 text = args.at(0); 0613 } 0614 0615 const bool retcode = Widgets::imgInputBox(nullptr, title, parser.value(QStringLiteral("imginputbox")), Utils::parseString(text), result); 0616 cout << result.toLocal8Bit().data() << endl; 0617 return retcode ? 0 : 1; 0618 } 0619 0620 // --textinputbox file [width] [height] 0621 if (parser.isSet(QStringLiteral("textinputbox"))) { 0622 int w = 400; 0623 int h = 200; 0624 0625 if (args.count() >= 3) { 0626 w = args.at(1).toInt(); 0627 h = args.at(2).toInt(); 0628 } 0629 0630 QString init; 0631 if (args.count() >= 1) { 0632 init = Utils::parseString(args.at(0)); 0633 } 0634 0635 QString result; 0636 int ret = Widgets::textInputBox(nullptr, w, h, title, Utils::parseString(parser.value(QStringLiteral("textinputbox"))), init, result); 0637 cout << qPrintable(result) << endl; 0638 return ret; 0639 } 0640 0641 // --combobox <text> item [item] ..." 0642 if (parser.isSet(QStringLiteral("combobox"))) { 0643 QStringList list; 0644 if (args.count() >= 1) { 0645 for (int i = 0; i < args.count(); i++) { 0646 list.append(args.at(i)); 0647 } 0648 const QString text = Utils::parseString(parser.value(QStringLiteral("combobox"))); 0649 if (parser.isSet(QStringLiteral("default"))) { 0650 defaultEntry = parser.value(QStringLiteral("default")); 0651 } 0652 QString result; 0653 const bool retcode = Widgets::comboBox(nullptr, title, text, list, defaultEntry, result); 0654 cout << result.toLocal8Bit().data() << endl; 0655 return retcode ? 0 : 1; 0656 } 0657 cerr << qPrintable(i18n("Syntax: --combobox <text> item [item] ...")) << endl; 0658 return -1; 0659 } 0660 0661 // --menu text tag item [tag item] ... 0662 if (parser.isSet(QStringLiteral("menu"))) { 0663 QStringList list; 0664 if (args.count() >= 2) { 0665 for (int i = 0; i < args.count(); i++) { 0666 list.append(args.at(i)); 0667 } 0668 const QString text = Utils::parseString(parser.value(QStringLiteral("menu"))); 0669 if (parser.isSet(QStringLiteral("default"))) { 0670 defaultEntry = parser.value(QStringLiteral("default")); 0671 } 0672 QString result; 0673 const bool retcode = Widgets::listBox(nullptr, title, text, list, defaultEntry, result); 0674 if (1 == retcode) { // OK was selected 0675 cout << result.toLocal8Bit().data() << endl; 0676 } 0677 return retcode ? 0 : 1; 0678 } 0679 cerr << qPrintable(i18n("Syntax: --menu text tag item [tag item] ...")) << endl; 0680 return -1; 0681 } 0682 0683 // --checklist text tag item status [tag item status] ... 0684 if (parser.isSet(QStringLiteral("checklist"))) { 0685 QStringList list; 0686 if (args.count() >= 3) { 0687 for (int i = 0; i < args.count(); i++) { 0688 list.append(args.at(i)); 0689 } 0690 0691 const QString text = Utils::parseString(parser.value(QStringLiteral("checklist"))); 0692 QStringList result; 0693 0694 const bool retcode = Widgets::checkList(nullptr, title, text, list, separateOutput, result); 0695 0696 for (int i = 0; i < result.count(); i++) { 0697 if (!result.at(i).isEmpty()) { 0698 cout << result.at(i).toLocal8Bit().data() << endl; 0699 } 0700 } 0701 return retcode ? 0 : 1; 0702 } 0703 cerr << qPrintable(i18n("Syntax: --checklist text tag item on/off [tag item on/off] ...")) << endl; 0704 return -1; 0705 } 0706 0707 // --radiolist text tag item status [tag item status] ... 0708 if (parser.isSet(QStringLiteral("radiolist"))) { 0709 QStringList list; 0710 if (args.count() >= 3) { 0711 for (int i = 0; i < args.count(); i++) { 0712 list.append(args.at(i)); 0713 } 0714 0715 const QString text = Utils::parseString(parser.value(QStringLiteral("radiolist"))); 0716 QString result; 0717 const bool retcode = Widgets::radioBox(nullptr, title, text, list, result); 0718 cout << result.toLocal8Bit().data() << endl; 0719 return retcode ? 0 : 1; 0720 } 0721 cerr << qPrintable(i18n("Syntax: --radiolist text tag item on/off [tag item on/off] ...")) << endl; 0722 return -1; 0723 } 0724 0725 // getopenfilename [startDir] [filter] 0726 // getopenurl [startDir] [filter] 0727 if (parser.isSet(QStringLiteral("getopenfilename")) || parser.isSet(QStringLiteral("getopenurl"))) { 0728 QString startDir = args.count() > 0 ? args.at(0) : QString(); 0729 const QUrl startUrl = QUrl::fromUserInput(startDir); 0730 QString filter; 0731 if (args.count() > 1) { 0732 filter = Utils::parseString(args.at(1)); 0733 } 0734 const bool multiple = parser.isSet(QStringLiteral("multiple")); 0735 0736 QFileDialog dlg; 0737 dlg.setAcceptMode(QFileDialog::AcceptOpen); 0738 dlg.setDirectoryUrl(initialDirectory(startUrl)); 0739 dlg.selectFile(initialSelection(startUrl)); 0740 0741 if (multiple) { 0742 dlg.setFileMode(QFileDialog::ExistingFiles); 0743 } else { 0744 dlg.setFileMode(QFileDialog::ExistingFile); 0745 } 0746 const bool openUrls = parser.isSet(QStringLiteral("getopenurl")); 0747 if (!openUrls) { 0748 dlg.setSupportedSchemes({QStringLiteral("file")}); 0749 } 0750 setFileDialogFilter(dlg, filter); 0751 Utils::handleXGeometry(&dlg); 0752 dlg.setWindowTitle(title.isEmpty() ? i18nc("@title:window", "Open") : title); 0753 if (!dlg.exec()) { 0754 return 1; // canceled 0755 } 0756 0757 if (openUrls) { 0758 const QList<QUrl> result = dlg.selectedUrls(); 0759 if (!result.isEmpty()) { 0760 if (multiple) { 0761 outputStringList(result, separateOutput); 0762 return 0; 0763 } else { 0764 cout << result.at(0).url().toLocal8Bit().data() << endl; 0765 return 0; 0766 } 0767 } 0768 } else { 0769 const QStringList result = dlg.selectedFiles(); 0770 if (!result.isEmpty()) { 0771 if (multiple) { 0772 outputStringList(result, separateOutput); 0773 return 0; 0774 } else { 0775 cout << result.at(0).toLocal8Bit().data() << endl; 0776 return 0; 0777 } 0778 } 0779 } 0780 return 1; 0781 } 0782 0783 // getsaveurl [startDir] [filter] 0784 // getsavefilename [startDir] [filter] 0785 if ((parser.isSet(QStringLiteral("getsavefilename"))) || (parser.isSet(QStringLiteral("getsaveurl")))) { 0786 QString startDir = args.count() > 0 ? args.at(0) : QString(); 0787 QString filter; 0788 const QUrl startUrl = QUrl::fromUserInput(startDir); 0789 0790 if (args.count() > 1) { 0791 filter = Utils::parseString(args.at(1)); 0792 } 0793 QFileDialog dlg; 0794 dlg.setAcceptMode(QFileDialog::AcceptSave); 0795 dlg.setFileMode(QFileDialog::AnyFile); 0796 dlg.setDirectoryUrl(initialDirectory(startUrl)); 0797 dlg.selectFile(initialSelection(startUrl)); 0798 setFileDialogFilter(dlg, filter); 0799 const bool saveUrls = parser.isSet(QStringLiteral("getsaveurl")); 0800 if (!saveUrls) { 0801 dlg.setSupportedSchemes({QStringLiteral("file")}); 0802 } 0803 Utils::handleXGeometry(&dlg); 0804 dlg.setWindowTitle(title.isEmpty() ? i18nc("@title:window", "Save As") : title); 0805 if (!dlg.exec()) { 0806 return 1; // canceled 0807 } 0808 0809 if (saveUrls) { 0810 const QList<QUrl> result = dlg.selectedUrls(); 0811 if (!result.isEmpty()) { 0812 cout << result.at(0).toString().toLocal8Bit().data() << endl; 0813 return 0; 0814 } 0815 } else { // getsavefilename 0816 const QStringList result = dlg.selectedFiles(); 0817 if (!result.isEmpty()) { 0818 const QString file = result.at(0); 0819 KRecentDocument::add(QUrl::fromLocalFile(file)); 0820 cout << file.toLocal8Bit().data() << endl; 0821 return 0; 0822 } 0823 } 0824 return 1; // canceled 0825 } 0826 0827 // getexistingdirectory [startDir] 0828 if (parser.isSet(QStringLiteral("getexistingdirectory"))) { 0829 QString startDir = args.count() > 0 ? args.at(0) : QString(); 0830 const QUrl startUrl = QUrl::fromUserInput(startDir); 0831 0832 QFileDialog dlg; 0833 dlg.setFileMode(QFileDialog::Directory); 0834 dlg.setOption(QFileDialog::ShowDirsOnly, true); 0835 dlg.setDirectoryUrl(initialDirectory(startUrl)); 0836 dlg.selectFile(initialSelection(startUrl)); 0837 Utils::handleXGeometry(&dlg); 0838 dlg.setWindowTitle(title.isEmpty() ? i18nc("@title:window", "Select Directory") : title); 0839 if (!dlg.exec()) { 0840 return 1; // canceled 0841 } 0842 const QList<QUrl> urls = dlg.selectedUrls(); 0843 if (!urls.isEmpty()) { 0844 cout << qPrintable(urls.at(0).toDisplayString(QUrl::PreferLocalFile)) << endl; 0845 return 0; 0846 } 0847 return 1; // canceled 0848 } 0849 0850 // geticon [group] [context] 0851 if (parser.isSet(QStringLiteral("geticon"))) { 0852 QString groupStr, contextStr; 0853 groupStr = parser.value(QStringLiteral("geticon")); 0854 if (args.count() >= 1) { 0855 contextStr = args.at(0); 0856 } 0857 const KIconLoader::Group group 0858 = (groupStr == QLatin1String("Desktop")) ? KIconLoader::Desktop 0859 : (groupStr == QLatin1String("Toolbar")) ? KIconLoader::Toolbar 0860 : (groupStr == QLatin1String("MainToolbar")) ? KIconLoader::MainToolbar 0861 : (groupStr == QLatin1String("Small")) ? KIconLoader::Small 0862 : (groupStr == QLatin1String("Dialog")) ? KIconLoader::Dialog 0863 : (groupStr == QLatin1String("User")) ? KIconLoader::User 0864 : /* else */ KIconLoader::NoGroup; 0865 0866 const KIconLoader::Context context 0867 = (contextStr == QLatin1String("Action")) ? KIconLoader::Action 0868 : (contextStr == QLatin1String("Application")) ? KIconLoader::Application 0869 : (contextStr == QLatin1String("Device")) ? KIconLoader::Device 0870 : (contextStr == QLatin1String("FileSystem")) ? KIconLoader::Place 0871 : (contextStr == QLatin1String("MimeType")) ? KIconLoader::MimeType 0872 : (contextStr == QLatin1String("Animation")) ? KIconLoader::Animation 0873 : (contextStr == QLatin1String("Category")) ? KIconLoader::Category 0874 : (contextStr == QLatin1String("Emblem")) ? KIconLoader::Emblem 0875 : (contextStr == QLatin1String("Emote")) ? KIconLoader::Emote 0876 : (contextStr == QLatin1String("International")) ? KIconLoader::International 0877 : (contextStr == QLatin1String("Place")) ? KIconLoader::Place 0878 : (contextStr == QLatin1String("StatusIcon")) ? KIconLoader::StatusIcon 0879 : // begin: KDE3 compatibility (useful?) 0880 (contextStr == QLatin1String("Devices")) ? KIconLoader::Device 0881 : (contextStr == QLatin1String("MimeTypes")) ? KIconLoader::MimeType 0882 : (contextStr == QLatin1String("FileSystems")) ? KIconLoader::Place 0883 : (contextStr == QLatin1String("Applications")) ? KIconLoader::Application 0884 : (contextStr == QLatin1String("Actions")) ? KIconLoader::Action 0885 : // end: KDE3 compatibility 0886 /* else */ KIconLoader::Any; 0887 0888 KIconDialog dlg; 0889 dlg.setup(group, context); 0890 dlg.setIconSize(KIconLoader::SizeHuge); 0891 0892 if (!title.isEmpty()) { 0893 dlg.setWindowTitle(title); 0894 } 0895 0896 Utils::handleXGeometry(&dlg); 0897 0898 const QString result = dlg.openDialog(); 0899 0900 if (!result.isEmpty()) { 0901 cout << result.toLocal8Bit().data() << endl; 0902 return 0; 0903 } 0904 return 1; // canceled 0905 } 0906 0907 // --progressbar text totalsteps 0908 if (parser.isSet(QStringLiteral("progressbar"))) { 0909 const QString text = Utils::parseString(parser.value(QStringLiteral("progressbar"))); 0910 0911 QProcess process; 0912 QStringList arguments; 0913 arguments << QStringLiteral("--progressbar"); 0914 arguments << text; 0915 arguments << QStringLiteral("--title"); 0916 arguments << title; 0917 if (args.count() == 1) { 0918 arguments << args.at(0); 0919 } 0920 qint64 pid = 0; 0921 if (process.startDetached(QStandardPaths::findExecutable(QStringLiteral("kdialog_progress_helper")), arguments, QString(), &pid)) { 0922 QDBusConnection dbus = QDBusConnection::sessionBus(); 0923 const QString serviceName = QStringLiteral("org.kde.kdialog-") + QString::number(pid); 0924 QDBusServiceWatcher watcher(serviceName, dbus, QDBusServiceWatcher::WatchForRegistration); 0925 QObject::connect(&watcher, &QDBusServiceWatcher::serviceRegistered, [serviceName](){ 0926 std::cout << serviceName.toLatin1().constData() << " /ProgressDialog" << std::endl << std::flush; 0927 qApp->quit(); 0928 }); 0929 qApp->exec(); 0930 return 0; 0931 } 0932 qWarning() << "Error starting kdialog_progress_helper"; 0933 return 1; 0934 } 0935 0936 // --getcolor 0937 if (parser.isSet(QStringLiteral("getcolor"))) { 0938 QColorDialog dlg; 0939 0940 if (parser.isSet(QStringLiteral("default"))) { 0941 defaultEntry = parser.value(QStringLiteral("default")); 0942 dlg.setCurrentColor(defaultEntry); 0943 } else { 0944 QColor color = KColorMimeData::fromMimeData(QApplication::clipboard()->mimeData(QClipboard::Clipboard)); 0945 if (color.isValid()) { 0946 dlg.setCurrentColor(color); 0947 } 0948 } 0949 0950 Utils::handleXGeometry(&dlg); 0951 dlg.setWindowTitle(title.isEmpty() ? i18nc("@title:window", "Choose Color") : title); 0952 0953 if (dlg.exec()) { 0954 QString result; 0955 const QColor color = dlg.selectedColor(); 0956 if (color.isValid() && parser.isSet(QStringLiteral("format"))) { 0957 bool found = false; 0958 QString format = parser.value(QStringLiteral("format")); 0959 format.remove(QLatin1Char('*')); // stripped out * for safety 0960 QList<QRegularExpression> pattern_pool; 0961 pattern_pool << QRegularExpression(QStringLiteral("(%#?[-+]?\\d*\\.?\\d*(?:ll|hh|l|h)?[diouxX])")) 0962 << QRegularExpression(QStringLiteral("(%#?[-+]?\\d*\\.?\\d*[l]?[efgEFG])")); 0963 0964 for (int i = 0; i < pattern_pool.size(); i++) { 0965 QRegularExpressionMatchIterator itor = pattern_pool.at(i).globalMatch(format); 0966 QRegularExpressionMatch match; 0967 int match_count = 0; 0968 while (itor.hasNext()) { 0969 match = itor.next(); 0970 if (match.hasMatch()) { 0971 match_count++; 0972 } 0973 } 0974 // currently only handle RGB, when alpha is ready, should hit 4 0975 if (3 == match_count) { 0976 found = true; 0977 if (match.captured(0).contains(QRegularExpression(QStringLiteral("[diouxX]")))) { 0978 result = QString::asprintf(format.toUtf8().constData(), color.red(), color.green(), color.blue()); 0979 } else { 0980 result = QString::asprintf(format.toUtf8().constData(), color.redF(), color.greenF(), color.blueF()); 0981 } 0982 break; 0983 } 0984 } 0985 if (false == found) { 0986 cout << "Invalid format pattern"; 0987 } 0988 } else { 0989 result = color.name(); 0990 } 0991 cout << result.toLocal8Bit().data() << endl; 0992 return 0; 0993 } 0994 return 1; // canceled 0995 } 0996 0997 if (parser.isSet(QStringLiteral("slider"))) { 0998 if (args.count() == 4) { 0999 QString text = Utils::parseString(args.at(0)); 1000 int miniValue = args.at(1).toInt(); 1001 int maxValue = args.at(2).toInt(); 1002 int step = args.at(3).toInt(); 1003 1004 int result = 0; 1005 1006 const bool returnCode = Widgets::slider(nullptr, title, text, miniValue, maxValue, step, result); 1007 if (returnCode) { 1008 cout << result << endl; 1009 } 1010 return returnCode; 1011 } else { 1012 cerr << qPrintable(i18n("Syntax: --slider <text> <min> <max> <step>")) << endl; 1013 return -1; 1014 } 1015 } 1016 1017 // --calendar text [--default default] [--dateformat format] 1018 if (parser.isSet(QStringLiteral("calendar"))) { 1019 // The default format is weird and non-standard. Sadly, it's too late to change this now. 1020 QString dateFormat = QStringLiteral("ddd MMM d yyyy"); 1021 if (parser.isSet(QStringLiteral("dateformat"))) { 1022 dateFormat = parser.value(QStringLiteral("dateformat")); 1023 } 1024 1025 QDate defaultDate = QDateTime::currentDateTime().date(); // today 1026 if (parser.isSet(QStringLiteral("default"))) { 1027 defaultEntry = parser.value(QStringLiteral("default")); 1028 defaultDate = QDate::fromString(defaultEntry, dateFormat); 1029 } 1030 1031 const QString text = Utils::parseString(parser.value(QStringLiteral("calendar"))); 1032 QDate result; 1033 1034 const bool returnCode = Widgets::calendar(nullptr, title, text, result, defaultDate); 1035 if (returnCode) { 1036 cout << result.toString(dateFormat).toLocal8Bit().data() << endl; 1037 } 1038 return returnCode; 1039 } 1040 1041 parser.showHelp(); 1042 return -2; // NOTREACHED 1043 }