diff options
Diffstat (limited to 'src/PortalService.cpp')
-rw-r--r-- | src/PortalService.cpp | 239 |
1 files changed, 222 insertions, 17 deletions
diff --git a/src/PortalService.cpp b/src/PortalService.cpp index 47acb67..c100720 100644 --- a/src/PortalService.cpp +++ b/src/PortalService.cpp @@ -23,9 +23,21 @@ #include <tqdbusmessage.h> #include <tqdbusvariant.h> +//FileChooser +#include <kmimetype.h> +#include <twin.h> +#include <tqregexp.h> + // TDE #include <tdemessagebox.h> +#include <tdefiledialog.h> #include <kdebug.h> +#include <kpushbutton.h> + +// FileChooser +#include "util.h" +#define OPTION_VALID(opt, sig) \ + options.keys().contains(opt) && check_variant(options[opt], sig) // Portal #include "PortalService.h" @@ -289,30 +301,223 @@ TQString FileChooserService::objectPath() const { return TQString(); } -bool FileChooserService::OpenFile(const TQT_DBusObjectPath& handle, const TQString& app_id, - const TQString& parent_window, const TQString& title, - const TQMap<TQString, TQT_DBusVariant>& options, TQ_UINT32& response, - TQMap<TQString, TQT_DBusVariant>& results, TQT_DBusError& error) { - // do something - return true; +bool FileChooserService::OpenFile(const TQT_DBusObjectPath& handle, + const TQString& app_id, + const TQString& parent_window, + const TQString& title, + const TQMap<TQString, TQT_DBusVariant> &options, + TQ_UINT32& response, + TQMap<TQString, TQT_DBusVariant> &results, + TQT_DBusError& error) +{ + FileDialogOpts opts; + + opts.caption = title; + + if (OPTION_VALID("accept_label", "s")) + opts.okButtonText = options["accept_label"].value.toString(); + + if (OPTION_VALID("directory", "b")) + opts.directory = options["directory"].value.toBool(); + + if (OPTION_VALID("multiple", "b")) + opts.multiple = options["multiple"].value.toBool(); + + if (OPTION_VALID("modal", "b")) + opts.modal = options["modal"].value.toBool(); + + if (OPTION_VALID("filters", "a(sa(us))")) + opts.filters = parseFilterList(options["filters"], options["current_filter"]); + + opts.windowId = parseWindowId(parent_window); + + return execFileDialog(opts, handle, response, results, error); } -bool FileChooserService::SaveFile(const TQT_DBusObjectPath& handle, const TQString& app_id, - const TQString& parent_window, const TQString& title, - const TQMap<TQString, TQT_DBusVariant>& options, TQ_UINT32& response, - TQMap<TQString, TQT_DBusVariant>& results, TQT_DBusError& error) { - // do something - return true; +bool FileChooserService::SaveFile(const TQT_DBusObjectPath& handle, + const TQString& app_id, + const TQString& parent_window, + const TQString& title, + const TQMap<TQString, TQT_DBusVariant> &options, + TQ_UINT32& response, + TQMap<TQString, TQT_DBusVariant> &results, + TQT_DBusError& error) +{ + FileDialogOpts opts; + + opts.caption = title; + + if (OPTION_VALID("accept_label", "s")) + opts.okButtonText = options["accept_label"].value.toString(); + + if (OPTION_VALID("directory", "b")) + opts.directory = options["directory"].value.toBool(); + + if (OPTION_VALID("multiple", "b")) + opts.multiple = options["multiple"].value.toBool(); + + if (OPTION_VALID("modal", "b")) + opts.modal = options["modal"].value.toBool(); + + if (OPTION_VALID("filters", "a(sa(us))")) + opts.filters = parseFilterList(options["filters"], options["current_filter"]); + + if (OPTION_VALID("current_folder", "ay")) + opts.startDir = bytelist_to_string(options["current_folder"].value.toList().toByteList()); + + if (OPTION_VALID("current_name", "s")) + opts.startName = options["current_name"].value.toString(); + + opts.windowId = parseWindowId(parent_window); + + return execFileDialog(opts, handle, response, results, error); } -bool FileChooserService::SaveFiles(const TQT_DBusObjectPath& handle, const TQString& app_id, - const TQString& parent_window, const TQString& title, - const TQMap<TQString, TQT_DBusVariant>& options, TQ_UINT32& response, - TQMap<TQString, TQT_DBusVariant>& results, TQT_DBusError& error) { - // do something +bool FileChooserService::SaveFiles(const TQT_DBusObjectPath& handle, + const TQString& app_id, + const TQString& parent_window, + const TQString& title, + const TQMap<TQString, TQT_DBusVariant> &options, + TQ_UINT32& response, + TQMap<TQString, TQT_DBusVariant> &results, + TQT_DBusError& error) +{ + return false; +} + +bool FileChooserService::execFileDialog(FileDialogOpts options, + const TQT_DBusObjectPath& handle, + TQ_UINT32& response, + TQMap<TQString, TQT_DBusVariant> &results, + TQT_DBusError& error) +{ + KFileDialog *dialog = new KFileDialog (options.startDir, TQString::null, + nullptr, "xdg-tde-file-chooser", + options.modal); + uint mode = KFile::LocalOnly; + if (options.savingMode) + { + dialog->setOperationMode(KFileDialog::Saving); + } + else { + mode |= KFile::ExistingOnly; + } + dialog->setMode(mode | options.mode()); + + if (!options.caption.isNull()) + dialog->setPlainCaption(options.caption); + + if (!options.okButtonText.isNull()) + dialog->okButton()->setText(options.okButtonText); + + if (!options.filters.isNull()) + dialog->setFilter(options.filters); + + dialog->setSelection(options.startName); + + if (options.windowId > 0) KWin::setMainWindow(dialog, options.windowId); + + if (dialog->exec() == TQDialog::Accepted) + { + response = 0; + TQT_DBusDataList urls = kurl_list_to_datalist(dialog->selectedURLs()); + TQT_DBusVariant var = TQT_DBusData::fromList(urls).getAsVariantData().toVariant(); + results.insert("uris", var); + } + else response = 1; return true; } +WId FileChooserService::parseWindowId(const TQString data) +{ + if (!data.startsWith("x11:")) + { + kdWarning() << "[FileChooser] Window Identifiers are currently only " + << "supported for X11. Created dialog will be parentless." + << endl; + return 0; + } + + bool ok; + WId wid = data.mid(4).toInt(&ok, 16); + return ok ? wid : 0; +} + +TQString FileChooserService::parseFilter(const TQT_DBusData data) +{ + TQStringList patternList; + + TQValueList<TQT_DBusData> filterData = data.toStruct(); + + TQString label = filterData[0].toString(); + TQValueList<TQT_DBusData> patterns = filterData[1].toTQValueList(); + + TQValueList<TQT_DBusData>::iterator fp; + for (fp = patterns.begin(); fp != patterns.end(); ++fp) + { + TQValueList<TQT_DBusData> patternData = (*fp).toStruct(); + bool isMime = (patternData[0].toUInt32() == 1); + if (isMime) { + // KFileDialog cannot handle both a mime and a simple + // extension filter, so in case we get a mimetype, + // we just get the associated extensions from the + // MIME system + TQString mime = patternData[1].toString(); + patternList += KMimeType::mimeType(mime)->patterns(); + } + else { + TQString patternString = patternData[1].toString(); + + // Regex patterns like *.[hH][tT][mM][lL] are unnecessary for us + // and causes a problem with the save dialog's extension autoselection + TQString finalPattern = patternString; + if (TQRegExp("[*.](?:[[](?:[A-Za-z]{2})[]])+").search(patternString) != -1) + { + finalPattern = "*."; + int pos = patternString.find('['); + while (pos != -1) + { + finalPattern += patternString[pos + 1]; + pos = patternString.find('[', patternString.find(']', pos)); + } + } + patternList += finalPattern; + } + } + + TQString patternString = patternList.join(" "); + + return TQString("%1|%2 (%3)").arg(patternString, label, patternString); +} + +TQString FileChooserService::parseFilterList(const TQT_DBusVariant filterData, + const TQT_DBusVariant currentFilterData) +{ + TQStringList filterList; + TQValueList<TQT_DBusData> filters = filterData.value.toTQValueList(); + if (filters.count() > 0) { + TQValueList<TQT_DBusData>::iterator f; + for (f = filters.begin(); f != filters.end(); ++f) + filterList += parseFilter((*f)); + } + + if (check_variant(currentFilterData, "(sa(us))")) + { + TQString currentFilter = parseFilter(currentFilterData.value); + if (filterList.contains(currentFilter)) + { + // We have no way to affect the filter selection of the dialog, + // so we just move the current filter to the top of the list + // to get it selected automatically + filterList.remove(currentFilter); + filterList.prepend(currentFilter); + } + } + + return filterList.join("\n"); +} + + void FileChooserService::handleMethodReply(const TQT_DBusMessage& reply) { m_connection->send(reply); } |