| Index: chrome/browser/ui/libgtk2ui/select_file_dialog_impl_kde.cc
|
| diff --git a/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_kde.cc b/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_kde.cc
|
| deleted file mode 100644
|
| index 7b9882987edd31819756385a272ab66bbc7ddd0a..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/ui/libgtk2ui/select_file_dialog_impl_kde.cc
|
| +++ /dev/null
|
| @@ -1,527 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include <stddef.h>
|
| -#include <X11/Xlib.h>
|
| -
|
| -#include <memory>
|
| -#include <set>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/bind_helpers.h"
|
| -#include "base/command_line.h"
|
| -#include "base/logging.h"
|
| -#include "base/macros.h"
|
| -#include "base/nix/mime_util_xdg.h"
|
| -#include "base/nix/xdg_util.h"
|
| -#include "base/process/launch.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/string_split.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "base/threading/thread_restrictions.h"
|
| -#include "chrome/browser/ui/libgtk2ui/select_file_dialog_impl.h"
|
| -#include "chrome/grit/generated_resources.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "ui/aura/window_tree_host.h"
|
| -#include "ui/base/l10n/l10n_util.h"
|
| -#include "ui/strings/grit/ui_strings.h"
|
| -
|
| -// These conflict with base/tracked_objects.h, so need to come last.
|
| -#include <gdk/gdkx.h>
|
| -#include <gtk/gtk.h>
|
| -
|
| -using content::BrowserThread;
|
| -
|
| -namespace {
|
| -
|
| -std::string GetTitle(const std::string& title, int message_id) {
|
| - return title.empty() ? l10n_util::GetStringUTF8(message_id) : title;
|
| -}
|
| -
|
| -const char kKdialogBinary[] = "kdialog";
|
| -
|
| -} // namespace
|
| -
|
| -namespace libgtk2ui {
|
| -
|
| -// Implementation of SelectFileDialog that shows a KDE common dialog for
|
| -// choosing a file or folder. This acts as a modal dialog.
|
| -class SelectFileDialogImplKDE : public SelectFileDialogImpl {
|
| - public:
|
| - SelectFileDialogImplKDE(Listener* listener,
|
| - ui::SelectFilePolicy* policy,
|
| - base::nix::DesktopEnvironment desktop);
|
| -
|
| - protected:
|
| - ~SelectFileDialogImplKDE() override;
|
| -
|
| - // BaseShellDialog implementation:
|
| - bool IsRunning(gfx::NativeWindow parent_window) const override;
|
| -
|
| - // SelectFileDialog implementation.
|
| - // |params| is user data we pass back via the Listener interface.
|
| - void SelectFileImpl(Type type,
|
| - const base::string16& title,
|
| - const base::FilePath& default_path,
|
| - const FileTypeInfo* file_types,
|
| - int file_type_index,
|
| - const base::FilePath::StringType& default_extension,
|
| - gfx::NativeWindow owning_window,
|
| - void* params) override;
|
| -
|
| - private:
|
| - bool HasMultipleFileTypeChoicesImpl() override;
|
| -
|
| - struct KDialogParams {
|
| - KDialogParams(const std::string& type,
|
| - const std::string& title,
|
| - const base::FilePath& default_path,
|
| - XID parent,
|
| - bool file_operation,
|
| - bool multiple_selection)
|
| - : type(type),
|
| - title(title),
|
| - default_path(default_path),
|
| - parent(parent),
|
| - file_operation(file_operation),
|
| - multiple_selection(multiple_selection) {}
|
| -
|
| - std::string type;
|
| - std::string title;
|
| - base::FilePath default_path;
|
| - XID parent;
|
| - bool file_operation;
|
| - bool multiple_selection;
|
| - };
|
| -
|
| - struct KDialogOutputParams {
|
| - std::string output;
|
| - int exit_code;
|
| - };
|
| -
|
| - // Get the filters from |file_types_| and concatenate them into
|
| - // |filter_string|.
|
| - std::string GetMimeTypeFilterString();
|
| -
|
| - // Get KDialog command line representing the Argv array for KDialog.
|
| - void GetKDialogCommandLine(const std::string& type,
|
| - const std::string& title,
|
| - const base::FilePath& default_path,
|
| - XID parent,
|
| - bool file_operation,
|
| - bool multiple_selection,
|
| - base::CommandLine* command_line);
|
| -
|
| - // Call KDialog on the FILE thread and return the results.
|
| - std::unique_ptr<KDialogOutputParams> CallKDialogOutput(
|
| - const KDialogParams& params);
|
| -
|
| - // Notifies the listener that a single file was chosen.
|
| - void FileSelected(const base::FilePath& path, void* params);
|
| -
|
| - // Notifies the listener that multiple files were chosen.
|
| - void MultiFilesSelected(const std::vector<base::FilePath>& files,
|
| - void* params);
|
| -
|
| - // Notifies the listener that no file was chosen (the action was canceled).
|
| - // Dialog is passed so we can find that |params| pointer that was passed to
|
| - // us when we were told to show the dialog.
|
| - void FileNotSelected(void *params);
|
| -
|
| - void CreateSelectFolderDialog(Type type,
|
| - const std::string& title,
|
| - const base::FilePath& default_path,
|
| - XID parent, void* params);
|
| -
|
| - void CreateFileOpenDialog(const std::string& title,
|
| - const base::FilePath& default_path,
|
| - XID parent, void* params);
|
| -
|
| - void CreateMultiFileOpenDialog(const std::string& title,
|
| - const base::FilePath& default_path,
|
| - XID parent, void* params);
|
| -
|
| - void CreateSaveAsDialog(const std::string& title,
|
| - const base::FilePath& default_path,
|
| - XID parent, void* params);
|
| -
|
| - // Common function for OnSelectSingleFileDialogResponse and
|
| - // OnSelectSingleFolderDialogResponse.
|
| - void SelectSingleFileHelper(void* params,
|
| - bool allow_folder,
|
| - std::unique_ptr<KDialogOutputParams> results);
|
| -
|
| - void OnSelectSingleFileDialogResponse(
|
| - XID parent,
|
| - void* params,
|
| - std::unique_ptr<KDialogOutputParams> results);
|
| - void OnSelectMultiFileDialogResponse(
|
| - XID parent,
|
| - void* params,
|
| - std::unique_ptr<KDialogOutputParams> results);
|
| - void OnSelectSingleFolderDialogResponse(
|
| - XID parent,
|
| - void* params,
|
| - std::unique_ptr<KDialogOutputParams> results);
|
| -
|
| - // Should be either DESKTOP_ENVIRONMENT_KDE3, KDE4, or KDE5.
|
| - base::nix::DesktopEnvironment desktop_;
|
| -
|
| - // The set of all parent windows for which we are currently running
|
| - // dialogs. This should only be accessed on the UI thread.
|
| - std::set<XID> parents_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImplKDE);
|
| -};
|
| -
|
| -// static
|
| -bool SelectFileDialogImpl::CheckKDEDialogWorksOnUIThread() {
|
| - // No choice. UI thread can't continue without an answer here. Fortunately we
|
| - // only do this once, the first time a file dialog is displayed.
|
| - base::ThreadRestrictions::ScopedAllowIO allow_io;
|
| -
|
| - base::CommandLine::StringVector cmd_vector;
|
| - cmd_vector.push_back(kKdialogBinary);
|
| - cmd_vector.push_back("--version");
|
| - base::CommandLine command_line(cmd_vector);
|
| - std::string dummy;
|
| - return base::GetAppOutput(command_line, &dummy);
|
| -}
|
| -
|
| -// static
|
| -SelectFileDialogImpl* SelectFileDialogImpl::NewSelectFileDialogImplKDE(
|
| - Listener* listener,
|
| - ui::SelectFilePolicy* policy,
|
| - base::nix::DesktopEnvironment desktop) {
|
| - return new SelectFileDialogImplKDE(listener, policy, desktop);
|
| -}
|
| -
|
| -SelectFileDialogImplKDE::SelectFileDialogImplKDE(
|
| - Listener* listener,
|
| - ui::SelectFilePolicy* policy,
|
| - base::nix::DesktopEnvironment desktop)
|
| - : SelectFileDialogImpl(listener, policy),
|
| - desktop_(desktop) {
|
| - DCHECK(desktop_ == base::nix::DESKTOP_ENVIRONMENT_KDE3 ||
|
| - desktop_ == base::nix::DESKTOP_ENVIRONMENT_KDE4 ||
|
| - desktop_ == base::nix::DESKTOP_ENVIRONMENT_KDE5);
|
| -}
|
| -
|
| -SelectFileDialogImplKDE::~SelectFileDialogImplKDE() {
|
| -}
|
| -
|
| -bool SelectFileDialogImplKDE::IsRunning(gfx::NativeWindow parent_window) const {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - if (parent_window && parent_window->GetHost()) {
|
| - XID xid = parent_window->GetHost()->GetAcceleratedWidget();
|
| - return parents_.find(xid) != parents_.end();
|
| - }
|
| -
|
| - return false;
|
| -}
|
| -
|
| -// We ignore |default_extension|.
|
| -void SelectFileDialogImplKDE::SelectFileImpl(
|
| - Type type,
|
| - const base::string16& title,
|
| - const base::FilePath& default_path,
|
| - const FileTypeInfo* file_types,
|
| - int file_type_index,
|
| - const base::FilePath::StringType& default_extension,
|
| - gfx::NativeWindow owning_window,
|
| - void* params) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - type_ = type;
|
| -
|
| - XID window_xid = None;
|
| - if (owning_window && owning_window->GetHost()) {
|
| - // |owning_window| can be null when user right-clicks on a downloadable item
|
| - // and chooses 'Open Link in New Tab' when 'Ask where to save each file
|
| - // before downloading.' preference is turned on. (http://crbug.com/29213)
|
| - window_xid = owning_window->GetHost()->GetAcceleratedWidget();
|
| - parents_.insert(window_xid);
|
| - }
|
| -
|
| - std::string title_string = base::UTF16ToUTF8(title);
|
| -
|
| - file_type_index_ = file_type_index;
|
| - if (file_types)
|
| - file_types_ = *file_types;
|
| - else
|
| - file_types_.include_all_files = true;
|
| -
|
| - switch (type) {
|
| - case SELECT_FOLDER:
|
| - case SELECT_UPLOAD_FOLDER:
|
| - CreateSelectFolderDialog(type, title_string, default_path,
|
| - window_xid, params);
|
| - return;
|
| - case SELECT_OPEN_FILE:
|
| - CreateFileOpenDialog(title_string, default_path, window_xid, params);
|
| - return;
|
| - case SELECT_OPEN_MULTI_FILE:
|
| - CreateMultiFileOpenDialog(title_string, default_path, window_xid, params);
|
| - return;
|
| - case SELECT_SAVEAS_FILE:
|
| - CreateSaveAsDialog(title_string, default_path, window_xid, params);
|
| - return;
|
| - default:
|
| - NOTREACHED();
|
| - return;
|
| - }
|
| -}
|
| -
|
| -bool SelectFileDialogImplKDE::HasMultipleFileTypeChoicesImpl() {
|
| - return file_types_.extensions.size() > 1;
|
| -}
|
| -
|
| -std::string SelectFileDialogImplKDE::GetMimeTypeFilterString() {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::FILE);
|
| - std::string filter_string;
|
| - // We need a filter set because the same mime type can appear multiple times.
|
| - std::set<std::string> filter_set;
|
| - for (size_t i = 0; i < file_types_.extensions.size(); ++i) {
|
| - for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) {
|
| - if (!file_types_.extensions[i][j].empty()) {
|
| - std::string mime_type = base::nix::GetFileMimeType(base::FilePath(
|
| - "name").ReplaceExtension(file_types_.extensions[i][j]));
|
| - filter_set.insert(mime_type);
|
| - }
|
| - }
|
| - }
|
| - // Add the *.* filter, but only if we have added other filters (otherwise it
|
| - // is implied).
|
| - if (file_types_.include_all_files && !file_types_.extensions.empty())
|
| - filter_set.insert("application/octet-stream");
|
| - // Create the final output string.
|
| - filter_string.clear();
|
| - for (std::set<std::string>::iterator it = filter_set.begin();
|
| - it != filter_set.end(); ++it) {
|
| - filter_string.append(*it + " ");
|
| - }
|
| - return filter_string;
|
| -}
|
| -
|
| -std::unique_ptr<SelectFileDialogImplKDE::KDialogOutputParams>
|
| -SelectFileDialogImplKDE::CallKDialogOutput(const KDialogParams& params) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::FILE);
|
| - base::CommandLine::StringVector cmd_vector;
|
| - cmd_vector.push_back(kKdialogBinary);
|
| - base::CommandLine command_line(cmd_vector);
|
| - GetKDialogCommandLine(params.type, params.title, params.default_path,
|
| - params.parent, params.file_operation,
|
| - params.multiple_selection, &command_line);
|
| -
|
| - auto results = base::MakeUnique<KDialogOutputParams>();
|
| - // Get output from KDialog
|
| - base::GetAppOutputWithExitCode(command_line, &results->output,
|
| - &results->exit_code);
|
| - if (!results->output.empty())
|
| - results->output.erase(results->output.size() - 1);
|
| - return results;
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::GetKDialogCommandLine(
|
| - const std::string& type,
|
| - const std::string& title,
|
| - const base::FilePath& path,
|
| - XID parent,
|
| - bool file_operation,
|
| - bool multiple_selection,
|
| - base::CommandLine* command_line) {
|
| - CHECK(command_line);
|
| -
|
| - // Attach to the current Chrome window.
|
| - if (parent != None) {
|
| - command_line->AppendSwitchNative(
|
| - desktop_ == base::nix::DESKTOP_ENVIRONMENT_KDE3 ?
|
| - "--embed" : "--attach",
|
| - base::Uint64ToString(parent));
|
| - }
|
| -
|
| - // Set the correct title for the dialog.
|
| - if (!title.empty())
|
| - command_line->AppendSwitchNative("--title", title);
|
| - // Enable multiple file selection if we need to.
|
| - if (multiple_selection) {
|
| - command_line->AppendSwitch("--multiple");
|
| - command_line->AppendSwitch("--separate-output");
|
| - }
|
| - command_line->AppendSwitch(type);
|
| - // The path should never be empty. If it is, set it to PWD.
|
| - if (path.empty())
|
| - command_line->AppendArgPath(base::FilePath("."));
|
| - else
|
| - command_line->AppendArgPath(path);
|
| - // Depending on the type of the operation we need, get the path to the
|
| - // file/folder and set up mime type filters.
|
| - if (file_operation)
|
| - command_line->AppendArg(GetMimeTypeFilterString());
|
| - VLOG(1) << "KDialog command line: " << command_line->GetCommandLineString();
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::FileSelected(const base::FilePath& path,
|
| - void* params) {
|
| - if (type_ == SELECT_SAVEAS_FILE)
|
| - *last_saved_path_ = path.DirName();
|
| - else if (type_ == SELECT_OPEN_FILE)
|
| - *last_opened_path_ = path.DirName();
|
| - else if (type_ == SELECT_FOLDER || type_ == SELECT_UPLOAD_FOLDER)
|
| - *last_opened_path_ = path;
|
| - else
|
| - NOTREACHED();
|
| - if (listener_) { // What does the filter index actually do?
|
| - // TODO(dfilimon): Get a reasonable index value from somewhere.
|
| - listener_->FileSelected(path, 1, params);
|
| - }
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::MultiFilesSelected(
|
| - const std::vector<base::FilePath>& files, void* params) {
|
| - *last_opened_path_ = files[0].DirName();
|
| - if (listener_)
|
| - listener_->MultiFilesSelected(files, params);
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::FileNotSelected(void* params) {
|
| - if (listener_)
|
| - listener_->FileSelectionCanceled(params);
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::CreateSelectFolderDialog(
|
| - Type type, const std::string& title, const base::FilePath& default_path,
|
| - XID parent, void *params) {
|
| - int title_message_id = (type == SELECT_UPLOAD_FOLDER)
|
| - ? IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE
|
| - : IDS_SELECT_FOLDER_DIALOG_TITLE;
|
| - BrowserThread::PostTaskAndReplyWithResult(
|
| - BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(
|
| - &SelectFileDialogImplKDE::CallKDialogOutput, this,
|
| - KDialogParams(
|
| - "--getexistingdirectory", GetTitle(title, title_message_id),
|
| - default_path.empty() ? *last_opened_path_ : default_path, parent,
|
| - false, false)),
|
| - base::Bind(&SelectFileDialogImplKDE::OnSelectSingleFolderDialogResponse,
|
| - this, parent, params));
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::CreateFileOpenDialog(
|
| - const std::string& title, const base::FilePath& default_path,
|
| - XID parent, void* params) {
|
| - BrowserThread::PostTaskAndReplyWithResult(
|
| - BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(
|
| - &SelectFileDialogImplKDE::CallKDialogOutput, this,
|
| - KDialogParams(
|
| - "--getopenfilename", GetTitle(title, IDS_OPEN_FILE_DIALOG_TITLE),
|
| - default_path.empty() ? *last_opened_path_ : default_path, parent,
|
| - true, false)),
|
| - base::Bind(&SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse,
|
| - this, parent, params));
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::CreateMultiFileOpenDialog(
|
| - const std::string& title, const base::FilePath& default_path,
|
| - XID parent, void* params) {
|
| - BrowserThread::PostTaskAndReplyWithResult(
|
| - BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(
|
| - &SelectFileDialogImplKDE::CallKDialogOutput, this,
|
| - KDialogParams(
|
| - "--getopenfilename", GetTitle(title, IDS_OPEN_FILES_DIALOG_TITLE),
|
| - default_path.empty() ? *last_opened_path_ : default_path, parent,
|
| - true, true)),
|
| - base::Bind(&SelectFileDialogImplKDE::OnSelectMultiFileDialogResponse,
|
| - this, parent, params));
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::CreateSaveAsDialog(
|
| - const std::string& title, const base::FilePath& default_path,
|
| - XID parent, void* params) {
|
| - BrowserThread::PostTaskAndReplyWithResult(
|
| - BrowserThread::FILE, FROM_HERE,
|
| - base::Bind(
|
| - &SelectFileDialogImplKDE::CallKDialogOutput, this,
|
| - KDialogParams("--getsavefilename",
|
| - GetTitle(title, IDS_SAVE_AS_DIALOG_TITLE),
|
| - default_path.empty() ? *last_saved_path_ : default_path,
|
| - parent, true, false)),
|
| - base::Bind(&SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse,
|
| - this, parent, params));
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::SelectSingleFileHelper(
|
| - void* params,
|
| - bool allow_folder,
|
| - std::unique_ptr<KDialogOutputParams> results) {
|
| - VLOG(1) << "[kdialog] SingleFileResponse: " << results->output;
|
| - if (results->exit_code || results->output.empty()) {
|
| - FileNotSelected(params);
|
| - return;
|
| - }
|
| -
|
| - base::FilePath path(results->output);
|
| - if (allow_folder) {
|
| - FileSelected(path, params);
|
| - return;
|
| - }
|
| -
|
| - if (CallDirectoryExistsOnUIThread(path))
|
| - FileNotSelected(params);
|
| - else
|
| - FileSelected(path, params);
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::OnSelectSingleFileDialogResponse(
|
| - XID parent,
|
| - void* params,
|
| - std::unique_ptr<KDialogOutputParams> results) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - parents_.erase(parent);
|
| - SelectSingleFileHelper(params, false, std::move(results));
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::OnSelectSingleFolderDialogResponse(
|
| - XID parent,
|
| - void* params,
|
| - std::unique_ptr<KDialogOutputParams> results) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - parents_.erase(parent);
|
| - SelectSingleFileHelper(params, true, std::move(results));
|
| -}
|
| -
|
| -void SelectFileDialogImplKDE::OnSelectMultiFileDialogResponse(
|
| - XID parent,
|
| - void* params,
|
| - std::unique_ptr<KDialogOutputParams> results) {
|
| - DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
| - VLOG(1) << "[kdialog] MultiFileResponse: " << results->output;
|
| -
|
| - parents_.erase(parent);
|
| -
|
| - if (results->exit_code || results->output.empty()) {
|
| - FileNotSelected(params);
|
| - return;
|
| - }
|
| -
|
| - std::vector<base::FilePath> filenames_fp;
|
| - for (const base::StringPiece& line :
|
| - base::SplitStringPiece(results->output, "\n", base::KEEP_WHITESPACE,
|
| - base::SPLIT_WANT_NONEMPTY)) {
|
| - base::FilePath path(line);
|
| - if (CallDirectoryExistsOnUIThread(path))
|
| - continue;
|
| - filenames_fp.push_back(path);
|
| - }
|
| -
|
| - if (filenames_fp.empty()) {
|
| - FileNotSelected(params);
|
| - return;
|
| - }
|
| - MultiFilesSelected(filenames_fp, params);
|
| -}
|
| -
|
| -} // namespace libgtk2ui
|
|
|