diff options
author | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-29 22:03:57 +0000 |
---|---|---|
committer | xiyuan@chromium.org <xiyuan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-01-29 22:03:57 +0000 |
commit | 274e42bf367cc47931bdac85837cfc2c8259f8a1 (patch) | |
tree | 75dc09021e2b1e85d416928773b351de33b7fae3 | |
parent | a9aca52ac15959a2c71a4ee22539a2392d3ee06b (diff) | |
download | chromium_src-274e42bf367cc47931bdac85837cfc2c8259f8a1.zip chromium_src-274e42bf367cc47931bdac85837cfc2c8259f8a1.tar.gz chromium_src-274e42bf367cc47931bdac85837cfc2c8259f8a1.tar.bz2 |
Replace GtkFileChooser with file browser for ChromeOS
- Remove dialogs_gtk.cc and add select_file_dialog.cc for chrome os build;
- select_file_dialog.cc provides a SelectFileDialogImpl that serves file
browse html via HTMLDialogUI;
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/543137
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37547 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/dom_ui/downloads_dom_handler.cc | 110 | ||||
-rw-r--r-- | chrome/browser/dom_ui/downloads_dom_handler.h | 8 | ||||
-rw-r--r-- | chrome/browser/dom_ui/filebrowse_ui.cc | 135 | ||||
-rw-r--r-- | chrome/browser/dom_ui/filebrowse_ui.h | 4 | ||||
-rw-r--r-- | chrome/browser/download/download_util.cc | 105 | ||||
-rw-r--r-- | chrome/browser/download/download_util.h | 10 | ||||
-rw-r--r-- | chrome/browser/resources/filebrowse.html | 417 | ||||
-rw-r--r-- | chrome/browser/views/dialog_stubs_gtk.cc | 6 | ||||
-rw-r--r-- | chrome/browser/views/dom_view.cc | 2 | ||||
-rw-r--r-- | chrome/browser/views/select_file_dialog.cc | 390 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 8 |
11 files changed, 1050 insertions, 145 deletions
diff --git a/chrome/browser/dom_ui/downloads_dom_handler.cc b/chrome/browser/dom_ui/downloads_dom_handler.cc index 7e8d1a0..501faf0 100644 --- a/chrome/browser/dom_ui/downloads_dom_handler.cc +++ b/chrome/browser/dom_ui/downloads_dom_handler.cc @@ -6,7 +6,6 @@ #include "app/l10n_util.h" #include "base/basictypes.h" -#include "base/i18n/time_formatting.h" #include "base/singleton.h" #include "base/string_piece.h" #include "base/thread.h" @@ -20,7 +19,6 @@ #include "chrome/browser/profile.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/common/jstemplate_builder.h" -#include "chrome/common/time_format.h" #include "chrome/common/url_constants.h" #include "grit/browser_resources.h" #include "grit/generated_resources.h" @@ -106,7 +104,7 @@ void DownloadsDOMHandler::OnDownloadUpdated(DownloadItem* download) { const int id = static_cast<int>(it - download_items_.begin()); ListValue results_value; - results_value.Append(CreateDownloadItemValue(download, id)); + results_value.Append(download_util::CreateDownloadItemValue(download, id)); dom_ui_->CallJavascriptFunction(L"downloadUpdated", results_value); } @@ -221,63 +219,12 @@ void DownloadsDOMHandler::SendCurrentDownloads() { int index = static_cast<int>(it - download_items_.begin()); if (index > kMaxDownloads) break; - results_value.Append(CreateDownloadItemValue(*it, index)); + results_value.Append(download_util::CreateDownloadItemValue(*it, index)); } dom_ui_->CallJavascriptFunction(L"downloadsList", results_value); } -DictionaryValue* DownloadsDOMHandler::CreateDownloadItemValue( - DownloadItem* download, int id) { - DictionaryValue* file_value = new DictionaryValue(); - - file_value->SetInteger(L"started", - static_cast<int>(download->start_time().ToTimeT())); - file_value->SetString(L"since_string", - TimeFormat::RelativeDate(download->start_time(), NULL)); - file_value->SetString(L"date_string", - base::TimeFormatShortDate(download->start_time())); - file_value->SetInteger(L"id", id); - file_value->SetString(L"file_path", download->full_path().ToWStringHack()); - // Keep file names as LTR. - std::wstring file_name = download->GetFileName().ToWStringHack(); - if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) - l10n_util::WrapStringWithLTRFormatting(&file_name); - file_value->SetString(L"file_name", file_name); - file_value->SetString(L"url", download->url().spec()); - - if (download->state() == DownloadItem::IN_PROGRESS) { - if (download->safety_state() == DownloadItem::DANGEROUS) { - file_value->SetString(L"state", L"DANGEROUS"); - } else if (download->is_paused()) { - file_value->SetString(L"state", L"PAUSED"); - } else { - file_value->SetString(L"state", L"IN_PROGRESS"); - } - - file_value->SetString(L"progress_status_text", - GetProgressStatusText(download)); - - file_value->SetInteger(L"percent", - static_cast<int>(download->PercentComplete())); - file_value->SetInteger(L"received", - static_cast<int>(download->received_bytes())); - } else if (download->state() == DownloadItem::CANCELLED) { - file_value->SetString(L"state", L"CANCELLED"); - } else if (download->state() == DownloadItem::COMPLETE) { - if (download->safety_state() == DownloadItem::DANGEROUS) { - file_value->SetString(L"state", L"DANGEROUS"); - } else { - file_value->SetString(L"state", L"COMPLETE"); - } - } - - file_value->SetInteger(L"total", - static_cast<int>(download->total_bytes())); - - return file_value; -} - void DownloadsDOMHandler::ClearDownloadItems() { // Clear out old state and remove self as observer for each download. for (OrderedDownloads::iterator it = download_items_.begin(); @@ -305,56 +252,3 @@ DownloadItem* DownloadsDOMHandler::GetDownloadByValue(const Value* value) { } return NULL; } - -std::wstring DownloadsDOMHandler::GetProgressStatusText( - DownloadItem* download) { - int64 total = download->total_bytes(); - int64 size = download->received_bytes(); - DataUnits amount_units = GetByteDisplayUnits(size); - std::wstring received_size = FormatBytes(size, amount_units, true); - std::wstring amount = received_size; - - // Adjust both strings for the locale direction since we don't yet know which - // string we'll end up using for constructing the final progress string. - std::wstring amount_localized; - if (l10n_util::AdjustStringForLocaleDirection(amount, &amount_localized)) { - amount.assign(amount_localized); - received_size.assign(amount_localized); - } - - if (total) { - amount_units = GetByteDisplayUnits(total); - std::wstring total_text = FormatBytes(total, amount_units, true); - std::wstring total_text_localized; - if (l10n_util::AdjustStringForLocaleDirection(total_text, - &total_text_localized)) - total_text.assign(total_text_localized); - - amount = l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_SIZE, - received_size, - total_text); - } else { - amount.assign(received_size); - } - amount_units = GetByteDisplayUnits(download->CurrentSpeed()); - std::wstring speed_text = FormatSpeed(download->CurrentSpeed(), - amount_units, true); - std::wstring speed_text_localized; - if (l10n_util::AdjustStringForLocaleDirection(speed_text, - &speed_text_localized)) - speed_text.assign(speed_text_localized); - - base::TimeDelta remaining; - std::wstring time_remaining; - if (download->is_paused()) - time_remaining = l10n_util::GetString(IDS_DOWNLOAD_PROGRESS_PAUSED); - else if (download->TimeRemaining(&remaining)) - time_remaining = TimeFormat::TimeRemaining(remaining); - - if (time_remaining.empty()) { - return l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_STATUS_TIME_UNKNOWN, - speed_text, amount); - } - return l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_STATUS, speed_text, - amount, time_remaining); -} diff --git a/chrome/browser/dom_ui/downloads_dom_handler.h b/chrome/browser/dom_ui/downloads_dom_handler.h index ad7d459..e43882c 100644 --- a/chrome/browser/dom_ui/downloads_dom_handler.h +++ b/chrome/browser/dom_ui/downloads_dom_handler.h @@ -10,7 +10,6 @@ #include "chrome/browser/dom_ui/dom_ui.h" #include "chrome/browser/download/download_manager.h" -class DictionaryValue; class Value; // The handler for Javascript messages related to the "downloads" view, @@ -73,10 +72,6 @@ class DownloadsDOMHandler : public DOMMessageHandler, // Send the current list of downloads to the page. void SendCurrentDownloads(); - // Creates a representation of a download in a format that the downloads - // HTML page can understand. - DictionaryValue* CreateDownloadItemValue(DownloadItem* download, int id); - // Clear all download items and their observers. void ClearDownloadItems(); @@ -86,9 +81,6 @@ class DownloadsDOMHandler : public DOMMessageHandler, // Return the download that is referred to in a given value. DownloadItem* GetDownloadByValue(const Value* value); - // Get the localized status text for an in-progress download. - std::wstring GetProgressStatusText(DownloadItem* download); - // Current search text. std::wstring search_text_; diff --git a/chrome/browser/dom_ui/filebrowse_ui.cc b/chrome/browser/dom_ui/filebrowse_ui.cc index 68dbd21..dfc5ed5 100644 --- a/chrome/browser/dom_ui/filebrowse_ui.cc +++ b/chrome/browser/dom_ui/filebrowse_ui.cc @@ -21,6 +21,8 @@ #include "chrome/browser/browser_window.h" #include "chrome/browser/chrome_thread.h" #include "chrome/browser/dom_ui/dom_ui_favicon_source.h" +#include "chrome/browser/download/download_manager.h" +#include "chrome/browser/download/download_util.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/net/url_fetcher.h" #include "chrome/browser/history/history_types.h" @@ -80,11 +82,16 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, public chromeos::MountLibrary::Observer, #endif public base::SupportsWeakPtr<FilebrowseHandler>, - public URLFetcher::Delegate { + public URLFetcher::Delegate, + public DownloadManager::Observer, + public DownloadItem::Observer { public: FilebrowseHandler(); virtual ~FilebrowseHandler(); + // Init work after Attach. + void Init(); + // DirectoryLister::DirectoryListerDelegate methods: virtual void OnListFile(const file_util::FileEnumerator::FindInfo& data); virtual void OnListDone(int error); @@ -99,6 +106,15 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, const std::string& path); #endif + // DownloadItem::Observer interface + virtual void OnDownloadUpdated(DownloadItem* download); + virtual void OnDownloadFileCompleted(DownloadItem* download) { } + virtual void OnDownloadOpened(DownloadItem* download) { } + + // DownloadManager::Observer interface + virtual void ModelChanged(); + virtual void SetDownloads(std::vector<DownloadItem*>& downloads); + // Callback for the "getRoots" message. void HandleGetRoots(const Value* value); @@ -122,6 +138,11 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, // Callback for the "uploadToPicasaweb" message. void UploadToPicasaweb(const Value* value); + // Callback for the "getDownloads" message. + void HandleGetDownloads(const Value* value); + + void HandleCreateNewFolder(const Value* value); + void ReadInFile(); void FireUploadComplete(); @@ -129,6 +150,12 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, void OpenNewWindow(const Value* value, bool popup); + // Clear all download items and their observers. + void ClearDownloadItems(); + + // Send the current list of downloads to the page. + void SendCurrentDownloads(); + scoped_ptr<ListValue> filelist_value_; FilePath currentpath_; Profile* profile_; @@ -138,6 +165,10 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, TaskProxy* CurrentTask_; scoped_refptr<net::DirectoryLister> lister_; + DownloadManager* download_manager_; + typedef std::vector<DownloadItem*> DownloadList; + DownloadList download_items_; + DISALLOW_COPY_AND_ASSIGN(FilebrowseHandler); }; @@ -200,7 +231,8 @@ void FileBrowseUIHTMLSource::StartDataRequest(const std::string& path, // //////////////////////////////////////////////////////////////////////////////// FilebrowseHandler::FilebrowseHandler() - : profile_(NULL) { + : profile_(NULL), + download_manager_(NULL) { // TODO(dhg): Check to see if this is really necessary #if defined(OS_CHROMEOS) chromeos::MountLibrary* lib = chromeos::MountLibrary::Get(); @@ -218,6 +250,9 @@ FilebrowseHandler::~FilebrowseHandler() { lister_->Cancel(); lister_->set_delegate(NULL); } + + ClearDownloadItems(); + download_manager_->RemoveObserver(this); } DOMMessageHandler* FilebrowseHandler::Attach(DOMUI* dom_ui) { @@ -229,9 +264,15 @@ DOMMessageHandler* FilebrowseHandler::Attach(DOMUI* dom_ui) { &ChromeURLDataManager::AddDataSource, make_scoped_refptr(new DOMUIFavIconSource(dom_ui->GetProfile())))); profile_ = dom_ui->GetProfile(); + return DOMMessageHandler::Attach(dom_ui); } +void FilebrowseHandler::Init() { + download_manager_ = profile_->GetOriginalProfile()->GetDownloadManager(); + download_manager_->AddObserver(this); +} + void FilebrowseHandler::RegisterMessages() { dom_ui_->RegisterMessageCallback("getRoots", NewCallback(this, &FilebrowseHandler::HandleGetRoots)); @@ -245,6 +286,10 @@ void FilebrowseHandler::RegisterMessages() { NewCallback(this, &FilebrowseHandler::OpenNewFullWindow)); dom_ui_->RegisterMessageCallback("uploadToPicasaweb", NewCallback(this, &FilebrowseHandler::UploadToPicasaweb)); + dom_ui_->RegisterMessageCallback("getDownloads", + NewCallback(this, &FilebrowseHandler::HandleGetDownloads)); + dom_ui_->RegisterMessageCallback("createNewFolder", + NewCallback(this, &FilebrowseHandler::HandleCreateNewFolder)); } void FilebrowseHandler::FireUploadComplete() { @@ -345,6 +390,29 @@ void FilebrowseHandler::HandleGetRoots(const Value* value) { info_value, results_value); } +void FilebrowseHandler::HandleCreateNewFolder(const Value* value) { +#if defined(OS_CHROMEOS) + if (value && value->GetType() == Value::TYPE_LIST) { + const ListValue* list_value = static_cast<const ListValue*>(value); + std::string path; + + // Get path string. + if (list_value->GetString(0, &path)) { + + FilePath currentpath; + currentpath = FilePath(path); + + if (!file_util::CreateDirectory(currentpath)) { + LOG(ERROR) << "unable to create directory"; + } + } else { + LOG(ERROR) << "Unable to get string"; + return; + } + } +#endif +} + void FilebrowseHandler::OpenNewFullWindow(const Value* value) { OpenNewWindow(value, false); } @@ -548,15 +616,76 @@ void FilebrowseHandler::OnListDone(int error) { void FilebrowseHandler::HandleGetMetadata(const Value* value) { } +void FilebrowseHandler::HandleGetDownloads(const Value* value) { + ModelChanged(); +} + +void FilebrowseHandler::ModelChanged() { + ClearDownloadItems(); + download_manager_->GetDownloads(this, std::wstring()); +} + +void FilebrowseHandler::SetDownloads(std::vector<DownloadItem*>& downloads) { + ClearDownloadItems(); + + // Scan for any in progress downloads and add ourself to them as an observer. + for (DownloadList::iterator it = downloads.begin(); + it != downloads.end(); ++it) { + DownloadItem* download = *it; + // We want to know what happens as the download progresses and be notified + // when the user validates the dangerous download. + if (download->state() == DownloadItem::IN_PROGRESS || + download->safety_state() == DownloadItem::DANGEROUS) { + download->AddObserver(this); + download_items_.push_back(download); + } + } + + SendCurrentDownloads(); +} + +void FilebrowseHandler::OnDownloadUpdated(DownloadItem* download) { + DownloadList::iterator it = find(download_items_.begin(), + download_items_.end(), + download); + if (it == download_items_.end()) + return; + const int id = static_cast<int>(it - download_items_.begin()); + + ListValue results_value; + results_value.Append(download_util::CreateDownloadItemValue(download, id)); + dom_ui_->CallJavascriptFunction(L"downloadUpdated", results_value); +} + +void FilebrowseHandler::ClearDownloadItems() { + for (DownloadList::iterator it = download_items_.begin(); + it != download_items_.end(); ++it) { + (*it)->RemoveObserver(this); + } + download_items_.clear(); +} + +void FilebrowseHandler::SendCurrentDownloads() { + ListValue results_value; + for (DownloadList::iterator it = download_items_.begin(); + it != download_items_.end(); ++it) { + int index = static_cast<int>(it - download_items_.begin()); + results_value.Append(download_util::CreateDownloadItemValue(*it, index)); + } + + dom_ui_->CallJavascriptFunction(L"downloadsList", results_value); +} + //////////////////////////////////////////////////////////////////////////////// // // FileBrowseUIContents // //////////////////////////////////////////////////////////////////////////////// -FileBrowseUI::FileBrowseUI(TabContents* contents) : DOMUI(contents) { +FileBrowseUI::FileBrowseUI(TabContents* contents) : HtmlDialogUI(contents) { FilebrowseHandler* handler = new FilebrowseHandler(); AddMessageHandler((handler)->Attach(this)); + handler->Init(); FileBrowseUIHTMLSource* html_source = new FileBrowseUIHTMLSource(); // Set up the chrome://filebrowse/ source. diff --git a/chrome/browser/dom_ui/filebrowse_ui.h b/chrome/browser/dom_ui/filebrowse_ui.h index 6da8916..5f45fe4 100644 --- a/chrome/browser/dom_ui/filebrowse_ui.h +++ b/chrome/browser/dom_ui/filebrowse_ui.h @@ -9,14 +9,14 @@ #include "base/scoped_ptr.h" #include "base/values.h" #include "chrome/browser/dom_ui/chrome_url_data_manager.h" -#include "chrome/browser/dom_ui/dom_ui.h" +#include "chrome/browser/dom_ui/html_dialog_ui.h" #include "chrome/browser/history/history.h" #include "net/base/directory_lister.h" class GURL; -class FileBrowseUI : public DOMUI { +class FileBrowseUI : public HtmlDialogUI { public: explicit FileBrowseUI(TabContents* contents); diff --git a/chrome/browser/download/download_util.cc b/chrome/browser/download/download_util.cc index 7662bc7..711c24c 100644 --- a/chrome/browser/download/download_util.cc +++ b/chrome/browser/download/download_util.cc @@ -13,11 +13,14 @@ #include "app/resource_bundle.h" #include "base/file_util.h" #include "base/gfx/rect.h" +#include "base/i18n/time_formatting.h" #include "base/string_util.h" +#include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/download/download_item_model.h" #include "chrome/browser/download/download_manager.h" #include "chrome/common/extensions/extension.h" +#include "chrome/common/time_format.h" #include "grit/generated_resources.h" #include "grit/locale_settings.h" #include "grit/theme_resources.h" @@ -295,4 +298,106 @@ void DragDownload(const DownloadItem* download, } #endif // OS_LINUX +DictionaryValue* CreateDownloadItemValue(DownloadItem* download, int id) { + DictionaryValue* file_value = new DictionaryValue(); + + file_value->SetInteger(L"started", + static_cast<int>(download->start_time().ToTimeT())); + file_value->SetString(L"since_string", + TimeFormat::RelativeDate(download->start_time(), NULL)); + file_value->SetString(L"date_string", + base::TimeFormatShortDate(download->start_time())); + file_value->SetInteger(L"id", id); + file_value->SetString(L"file_path", download->full_path().ToWStringHack()); + // Keep file names as LTR. + std::wstring file_name = download->GetFileName().ToWStringHack(); + if (l10n_util::GetTextDirection() == l10n_util::RIGHT_TO_LEFT) + l10n_util::WrapStringWithLTRFormatting(&file_name); + file_value->SetString(L"file_name", file_name); + file_value->SetString(L"url", download->url().spec()); + + if (download->state() == DownloadItem::IN_PROGRESS) { + if (download->safety_state() == DownloadItem::DANGEROUS) { + file_value->SetString(L"state", L"DANGEROUS"); + } else if (download->is_paused()) { + file_value->SetString(L"state", L"PAUSED"); + } else { + file_value->SetString(L"state", L"IN_PROGRESS"); + } + + file_value->SetString(L"progress_status_text", + GetProgressStatusText(download)); + + file_value->SetInteger(L"percent", + static_cast<int>(download->PercentComplete())); + file_value->SetInteger(L"received", + static_cast<int>(download->received_bytes())); + } else if (download->state() == DownloadItem::CANCELLED) { + file_value->SetString(L"state", L"CANCELLED"); + } else if (download->state() == DownloadItem::COMPLETE) { + if (download->safety_state() == DownloadItem::DANGEROUS) { + file_value->SetString(L"state", L"DANGEROUS"); + } else { + file_value->SetString(L"state", L"COMPLETE"); + } + } + + file_value->SetInteger(L"total", + static_cast<int>(download->total_bytes())); + + return file_value; +} + +std::wstring GetProgressStatusText(DownloadItem* download) { + int64 total = download->total_bytes(); + int64 size = download->received_bytes(); + DataUnits amount_units = GetByteDisplayUnits(size); + std::wstring received_size = FormatBytes(size, amount_units, true); + std::wstring amount = received_size; + + // Adjust both strings for the locale direction since we don't yet know which + // string we'll end up using for constructing the final progress string. + std::wstring amount_localized; + if (l10n_util::AdjustStringForLocaleDirection(amount, &amount_localized)) { + amount.assign(amount_localized); + received_size.assign(amount_localized); + } + + if (total) { + amount_units = GetByteDisplayUnits(total); + std::wstring total_text = FormatBytes(total, amount_units, true); + std::wstring total_text_localized; + if (l10n_util::AdjustStringForLocaleDirection(total_text, + &total_text_localized)) + total_text.assign(total_text_localized); + + amount = l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_SIZE, + received_size, + total_text); + } else { + amount.assign(received_size); + } + amount_units = GetByteDisplayUnits(download->CurrentSpeed()); + std::wstring speed_text = FormatSpeed(download->CurrentSpeed(), + amount_units, true); + std::wstring speed_text_localized; + if (l10n_util::AdjustStringForLocaleDirection(speed_text, + &speed_text_localized)) + speed_text.assign(speed_text_localized); + + base::TimeDelta remaining; + std::wstring time_remaining; + if (download->is_paused()) + time_remaining = l10n_util::GetString(IDS_DOWNLOAD_PROGRESS_PAUSED); + else if (download->TimeRemaining(&remaining)) + time_remaining = TimeFormat::TimeRemaining(remaining); + + if (time_remaining.empty()) { + return l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_STATUS_TIME_UNKNOWN, + speed_text, amount); + } + return l10n_util::GetStringF(IDS_DOWNLOAD_TAB_PROGRESS_STATUS, speed_text, + amount, time_remaining); +} + } // namespace download_util diff --git a/chrome/browser/download/download_util.h b/chrome/browser/download/download_util.h index 7636b55..93114fe 100644 --- a/chrome/browser/download/download_util.h +++ b/chrome/browser/download/download_util.h @@ -23,6 +23,7 @@ class Canvas; } class BaseDownloadItemModel; +class DictionaryValue; class DownloadItem; class SkBitmap; @@ -134,6 +135,15 @@ void DragDownload(const DownloadItem* download, // Determine if the specified extension is an executable extension. bool IsExecutableExtension(const std::string& extension); +// Helpers --------------------------------------------------------------------- + +// Creates a representation of a download in a format that the downloads +// HTML page can understand. +DictionaryValue* CreateDownloadItemValue(DownloadItem* download, int id); + +// Get the localized status text for an in-progress download. +std::wstring GetProgressStatusText(DownloadItem* download); + } // namespace download_util #endif // CHROME_BROWSER_DOWNLOAD_DOWNLOAD_UTIL_H_ diff --git a/chrome/browser/resources/filebrowse.html b/chrome/browser/resources/filebrowse.html index 4189d68..ab1dcb3 100644 --- a/chrome/browser/resources/filebrowse.html +++ b/chrome/browser/resources/filebrowse.html @@ -34,11 +34,12 @@ div.header { .rowlink { height: 100%; width: 90%; + cursor: pointer; } a.iconlink { display: block; - font-family: helvetica; +/* font-family: helvetica; */ font-weight: bold; font-size: 11px; color: white; @@ -117,7 +118,7 @@ li.filebrowserow div.icon { width: 10px; } -.uploadicon { +.uploaicon { background: url('../../app/theme/filebrowse_upload.png'); position: absolute; right: 0; @@ -157,17 +158,36 @@ li.filebrowserow { padding: 8px 5px 5px 54px; /* overflow: hidden; */ font-size:.8em; - font-family: helvetica; +/* font-family: helvetica; */ position: relative; } +.downloadstatus { + width: 100%; + font-size:.6em; +} + +li.filebrowserow:hover { + background: #ebeff9; +} + li.filebrowserow span.name { margin-top: 10px; margin-left: -22px; position: relative; +} + +li.filebrowserow span.namelink { + margin-top: 10px; + margin-left: -22px; + position: relative; text-decoration:underline; } +.selected { + background-color: #b1c8f2; +} + div.title { text-align: right; position: relative; @@ -188,6 +208,7 @@ div.controlbutton { padding-bottom: 4px; padding-right: 7px; height: 15px; + cursor: pointer; } div.column { @@ -257,6 +278,78 @@ div.scanningcontainer { height: 100%; } +div.filebutton { + width: 70px; + height: 20px; + cursor: pointer; + padding-top:2px; + border:1px solid #abb6ce; + background-color: #f5f7fc; + -webkit-border-radius: 5px; + text-align: center; + font-size:.8em; +} + +.filenameprompt { + top: 10px; + left: 13px; + font-size:.8em; + position: absolute; +} + +.filename { + left: 80px; + top:5px; + right:10px; + font-size:.8em; + position: absolute; +} + +div.openbutton { + bottom: 5px; + left: 10px; + position: absolute; +} + +div.cancelbutton { + bottom: 5px; + left: 90px; + position: absolute; +} + +div.newfolderbutton { + bottom: 5px; + right: 10px; + position: absolute; +} + +div.opencontainer { + width: 100%; + bottom: 0; + left:0; + height: 30px; + position: absolute; + background-image: -webkit-gradient(linear, + 0% 0%, + 0% 90%, + from(rgb(239, 242, 249)), + to(rgba(201, 212, 245, 1))); +} + +div.savecontainer { + width: 100%; + bottom: 0; + left:0; + height: 60px; + position: absolute; + background-image: -webkit-gradient(linear, + 0% 0%, + 0% 90%, + from(rgb(239, 242, 249)), + to(rgba(201, 212, 245, 1))); +} + + div.container { top: 0; position: absolute; @@ -265,6 +358,22 @@ div.container { bottom: 0; } +div.containerwithopenbuttons { + top: 0; + position: absolute; + width: 100%; + left: 0; + bottom: 30px; +} + +div.containerwithsavebuttons { + top: 0; + position: absolute; + width: 100%; + left: 0; + bottom: 60px; +} + div.fullcontainer { top: 0px; position: absolute; @@ -337,7 +446,7 @@ a:hover { } </style> -<script src="local_strings.js"></script> +<script src='local_strings.js'></script> <script> @@ -351,11 +460,16 @@ var currentNode = -1; var foundImages = []; var currentImageMenu = ''; var inFullMode = false; +var inSelectMode = false; var videoPlaybackElement = null; var photoPreviewElement = null; var numColumns = 0; var divArray = []; var rootsDiv = null; +var currentlySelectedItems = new Array(); +var currentlySelectedPaths = new Array(); +var multiSelect = false; +var inSaveMode = false; function goBackInList() { if (currentNode > 0) { @@ -389,7 +503,7 @@ function animateScrollRight() { // it stops growing, so clear it out and no more timeouts. if (lastScrollLeft != main.scrollLeft) { lastScrollLeft = main.scrollLeft; - setTimeout("animateScrollRight()", 15); + setTimeout('animateScrollRight()', 15); } else { lastScrollLeft = 0; } @@ -516,14 +630,242 @@ function setUpForScanning() { main.textContent = 'Scanning Device...'; }; +function dialogOkClick() { + if (!multiSelect) { + chrome.send('DialogClose', [JSON.stringify({'path' : currentlySelectedPaths[0]})]); + } else { + chrome.send('DialogClose', [JSON.stringify({'path' : currentlySelectedPaths})]); + } +}; + +function dialogCancelClick() { + chrome.send('DialogClose', ['']); +}; + +function dialogSaveClick() { + var filenameInput = $('filename'); + var filename = filenameInput.value; + var currentPath = pathArray[pathArray.length - 1]; + currentPath += '/'; + currentPath += filename; + chrome.send('DialogClose', [JSON.stringify({'path' : currentPath})]); +}; + + +function createNewFormItem(initialName, isDirectory, id, blurcallback, keypresscallback) { + var element = document.createElement('li'); + element.className = 'filebrowserow'; + element.id = 'listItem' + elementIdCounter; + elementIdCounter++; + + var link; + link = document.createElement('div'); + link.className = 'rowlink'; + + var icon = document.createElement('div'); + icon.className = getClassForPath('', isDirectory); + link.appendChild(icon); + var input = document.createElement('input'); + input.className = 'name'; + input.id = 'newfoldername'; + input.onblur = blurcallback; + input.onkeypress = keypresscallback; + input.focus(); + + input.value = initialName; + link.appendChild(input); + + element.appendChild(link); + if (isDirectory) { + var rightarrow = document.createElement('div'); + rightarrow.align = 'right'; + rightarrow.innerHTML = '»'; + rightarrow.className = 'rightarrow'; + element.appendChild(rightarrow); + } + + return element; +}; + +function createFolder(elementId) { + var currentPath = pathArray[pathArray.length - 1]; + var element = $('newfoldername'); + if (element) { + element.id = ''; + var filename = element.value; + currentPath += '/'; + currentPath += filename; + var parent = element.parentNode; + parent.removeChild(element); + listitem = parent.parentNode; + + parent.onclick = new Function(getFunctionForItem(currentPath, listitem.id, true)); + + var span = document.createElement('span'); + if (inSelectMode) { + span.className = 'name'; + } else { + span.className = 'namelink'; + } + span.textContent = filename; + parent.appendChild(span); + + chrome.send('createNewFolder', [currentPath]); + } + return false; +}; + +function createFolderTyping(elementId) { + if (window.event.keyCode == 13) { + createFolder(elementId); + } +}; + +function getDirectoryForPath(path) { + var index = path.lastIndexOf('/'); + if (index == -1) { + return path; + } + return path.substr(path, index); +}; + +function downloadsList(results) { +// alert(JSON.stringify(results)); +// We might want to do something with this... For now assume that the update will get the necessary info +}; + +function downloadUpdated(results) { + for (var x = 0; x < results.length; x++) { + var element = $(results[x].file_path); + if (element) { + if (results[x].percent < 100) { + var progressDiv = null; + for (var y = 0; y < element.children.length; y++) { + if (element.children[y].className == 'downloadstatus') { + progressDiv = element.children[y]; + break; + } + } + if (progressDiv == null) { + element.className = 'filebrowserow downloading'; + var progressDiv = document.createElement('div'); + progressDiv.className = 'downloadstatus'; + element.appendChild(progressDiv); + } + progressDiv.textContent = results[x].progress_status_text; + + } else { + for (var x = 0; x < element.children.length; x++) { + if (element.children[x].className == 'downloadstatus') { + var child = element.children[x]; + element.removeChild(child); + } + } + element.className = 'filebrowserow'; + } + } else { + // TODO(dhg):Get the new file + } + } +}; + +function dialogNewFolderClick() { + + + var main = divArray[divArray.length - 1]; + var list; + for (var x = 0; x < main.childNodes.length; x++ ) { + if (main.childNodes[x].className == 'columnlist') { + list = main.childNodes[x].firstChild; + break; + } + } + var id = 'listItem' + elementIdCounter; + elementIdCounter++; + var element = createNewFormItem('', + true, + id, + new Function('createFolder("' + id + '")'), + new Function('createFolderTyping("' + id + '")')); + list.appendChild(element); + element.scrollIntoView(); +}; + /////////////////////////////////////////////////////////////////////////////// // Document Functions: /** * Window onload handler, sets up the page. */ function load() { - if(document.documentElement.clientWidth <= 400) { + if(document.documentElement.clientWidth <= 600) { inFullMode = false; + if (chrome.dialogArguments) { + var args = JSON.parse(chrome.dialogArguments); + if (args.type == 'open') { + multiSelect = false; + } else if (args.type == 'save') { + inSaveMode = true; + } else if (args.type == 'open_multiple') { + multiSelect = true; + } else { + alert ('got unknown type'); + } + inSelectMode = true; + if (inSaveMode) { + var main = $('main'); + main.className = 'containerwithsavebuttons'; + var savemenu = document.createElement('div'); + savemenu.className = 'savecontainer'; + + var savebutton = document.createElement('div'); + savebutton.className = 'filebutton openbutton'; + savebutton.onclick = dialogSaveClick; + savebutton.textContent = 'Save'; + savemenu.appendChild(savebutton); + + var cancelbutton = document.createElement('div'); + cancelbutton.className = 'filebutton cancelbutton'; + savemenu.appendChild(cancelbutton); + cancelbutton.textContent = 'Cancel'; + cancelbutton.onclick = dialogCancelClick; + + var filenameprompt = document.createElement('div'); + filenameprompt.className = 'filenameprompt'; + filenameprompt.textContent = 'File name:'; + savemenu.appendChild(filenameprompt); + + var filename = document.createElement('input'); + filename.className = 'filename'; + filename.id = 'filename'; + filename.value = args.current_file; + savemenu.appendChild(filename); + + var newfolderbutton = document.createElement('div'); + newfolderbutton.className = 'filebutton newfolderbutton'; + newfolderbutton.textContent = 'New Folder'; + newfolderbutton.onclick = dialogNewFolderClick; + savemenu.appendChild(newfolderbutton); + + document.body.appendChild(savemenu); + + } else { + var main = $('main'); + main.className = 'containerwithopenbuttons'; + var openmenu = document.createElement('div'); + openmenu.className = 'opencontainer'; + var openbutton = document.createElement('div'); + openbutton.className = 'filebutton openbutton'; + var cancelbutton = document.createElement('div'); + cancelbutton.className = 'filebutton cancelbutton'; + openmenu.appendChild(openbutton); + openbutton.onclick = dialogOkClick; + openmenu.appendChild(cancelbutton); + cancelbutton.onclick = dialogCancelClick; + openbutton.textContent = 'Open'; + cancelbutton.textContent = 'Cancel'; + document.body.appendChild(openmenu); + } + } } else { var main = $('main'); main.className = 'fullcontainer'; @@ -553,6 +895,7 @@ function load() { pathArray.push('roots'); getDataForPath('roots'); } + chrome.send("getDownloads", []); }; function jumpToNode(nodeNumber) { @@ -669,35 +1012,77 @@ function uploadComplete(result) { } }; +function findInArray(arr, element) { + for (var x = 0; x < arr.length; x++) { + if (arr[x] == element) { + return x; + } + } + return -1; +}; + +function selectItem(elementid, path) { + var element = $(elementid); + var index; + if ((index = findInArray(currentlySelectedItems, element)) != -1) { + // the user must want to toggle + currentlySelectedItems.splice(index, 1); + element.classname = 'filebrowserow'; + index = findInArray(currentlySelectedPaths, path); + currentlySelectedPaths.splice(index, 1); + } else { + if (!multiSelect) { + // clear out previous selected elements + for (var x = 0; x < currentlySelectedItems.length; x++) { + currentlySelectedItems[x].className = 'filebrowserow'; + } + } + element.className = 'selected filebrowserow'; + currentlySelectedItems.push(element); + currentlySelectedPaths.push(path); + } +}; + // TODO(dhg): Do not use javascript: href, use onclick instead -function createHrefForItem(path, isDirectory) { +function getFunctionForItem(path, id, isDirectory) { if (isDirectory) { - return 'javascript:descend("' + path + '", ' + currentNode + ');'; + return 'descend("' + path + '", ' + currentNode + ')'; + } if(inSelectMode) { + return 'selectItem("' + id + '", "' + path + '")'; } if (pathIsAudioFile(path)) { - return 'javascript:playMediaFile("' + path + '");'; + return 'playMediaFile("' + path + '")'; } if (pathIsVideoFile(path)) { - return 'javascript:playMediaFile("' + path + '");'; + return 'playMediaFile("' + path + '")'; } if (pathIsImageFile(path)) { - return 'javascript:showImage("' + path + '");'; + return 'showImage("' + path + '")'; } else { return ''; } }; +var elementIdCounter = 0; + function createNewItem(title, path, isDirectory) { var element = document.createElement('li'); element.className = 'filebrowserow'; - - var link = document.createElement('a'); + /*element.id = 'listItem' + elementIdCounter;*/ + element.id = path; + elementIdCounter++; + var link; + link = document.createElement('div'); + link.onclick = new Function(getFunctionForItem(path, element.id, isDirectory)); link.className = 'rowlink'; - link.href = createHrefForItem(path, isDirectory); var icon = document.createElement('div'); icon.className = getClassForPath(path, isDirectory); link.appendChild(icon); var span = document.createElement('span'); - span.className = 'name'; + if (inSelectMode) { + span.className = 'name'; + } else { + span.className = 'namelink'; + } span.textContent = title; link.appendChild(span); @@ -782,7 +1167,7 @@ function createNewList(title, results, main, path) { }; </script> -<body onload="load();" onclick='clearImageMenus()'> +<body onload='load();' onclick='clearImageMenus()' onselectstart='return false'> <div id='header' class=''> <div id='back' class='backbutton controlbutton' onclick='goBackInList();return false;'> <img src="../../app/theme/filebrowse_back.png" width='100%' height='100%'> diff --git a/chrome/browser/views/dialog_stubs_gtk.cc b/chrome/browser/views/dialog_stubs_gtk.cc index d9a0f0c..9d8c7d2 100644 --- a/chrome/browser/views/dialog_stubs_gtk.cc +++ b/chrome/browser/views/dialog_stubs_gtk.cc @@ -45,12 +45,6 @@ void ShowBookmarkManagerView(Profile* profile) { BookmarkManagerGtk::Show(profile); } -void ShowHtmlDialogView(gfx::NativeWindow parent, Browser* browser, - HtmlDialogUIDelegate* delegate) { - // Hasn't been implemented yet on linux. - NOTIMPLEMENTED(); -} - void ShowPasswordsExceptionsWindowView(Profile* profile) { ShowPasswordsExceptionsWindow(profile); } diff --git a/chrome/browser/views/dom_view.cc b/chrome/browser/views/dom_view.cc index cd3dc8f..29aaf19 100644 --- a/chrome/browser/views/dom_view.cc +++ b/chrome/browser/views/dom_view.cc @@ -7,7 +7,7 @@ #include "chrome/browser/tab_contents/tab_contents.h" #include "views/focus/focus_manager.h" -DOMView::DOMView() : initialized_(false), tab_contents_(NULL) { +DOMView::DOMView() : tab_contents_(NULL), initialized_(false) { SetFocusable(true); } diff --git a/chrome/browser/views/select_file_dialog.cc b/chrome/browser/views/select_file_dialog.cc new file mode 100644 index 0000000..375e224 --- /dev/null +++ b/chrome/browser/views/select_file_dialog.cc @@ -0,0 +1,390 @@ +// Copyright (c) 2010 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 "chrome/browser/shell_dialogs.h" + +#include "app/l10n_util.h" +#include "base/file_path.h" +#include "base/json/json_reader.h" +#include "base/scoped_ptr.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "base/values.h" +#include "chrome/browser/browser.h" +#include "chrome/browser/browser_list.h" +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/dom_ui/html_dialog_ui.h" +#include "chrome/browser/shell_dialogs.h" +#include "chrome/common/url_constants.h" +#include "grit/generated_resources.h" + +namespace { + +static const wchar_t* kKeyNamePath = L"path"; + +}; // namespace + +// Implementation of SelectFileDialog that shows an UI for choosing a file +// or folder using FileBrowseUI. +class SelectFileDialogImpl : public SelectFileDialog { + public: + explicit SelectFileDialogImpl(Listener* listener); + + // BaseShellDialog implementation. + virtual bool IsRunning(gfx::NativeWindow parent_window) const; + virtual void ListenerDestroyed(); + + // SelectFileDialog implementation. + // |params| is user data we pass back via the Listener interface. + virtual void SelectFile(Type type, + const string16& title, + const FilePath& default_path, + const FileTypeInfo* file_types, + int file_type_index, + const FilePath::StringType& default_extension, + gfx::NativeWindow owning_window, + void* params); + + private: + virtual ~SelectFileDialogImpl(); + + class FileBrowseDelegate : public HtmlDialogUIDelegate { + public: + FileBrowseDelegate(SelectFileDialogImpl* owner, + Type type, + const std::wstring& title, + const FilePath& default_path, + const FileTypeInfo* file_types, + int file_type_index, + const FilePath::StringType& default_extension, + gfx::NativeWindow parent, + void* params); + + // Owner of this FileBrowseDelegate. + SelectFileDialogImpl* owner_; + + // Parent window. + gfx::NativeWindow parent_; + + // The type of dialog we are showing the user. + Type type_; + + // The dialog title. + std::wstring title_; + + // Default path of the file dialog. + FilePath default_path_; + + // The file filters. + FileTypeInfo file_types_; + + // The index of the default selected file filter. + // Note: This starts from 1, not 0. + size_t file_type_index_; + + // Default extension to be added to file if user does not type one. + FilePath::StringType default_extension_; + + // Associated user data. + void* params_; + + private: + ~FileBrowseDelegate(); + + // Overridden from HtmlDialogUI::Delegate: + virtual bool IsDialogModal() const; + virtual std::wstring GetDialogTitle() const; + virtual GURL GetDialogContentURL() const; + virtual void GetDOMMessageHandlers( + std::vector<DOMMessageHandler*>* handlers) const; + virtual void GetDialogSize(gfx::Size* size) const; + virtual std::string GetDialogArgs() const; + virtual void OnDialogClosed(const std::string& json_retval); + + DISALLOW_COPY_AND_ASSIGN(FileBrowseDelegate); + }; + + // Notification from FileBrowseDelegate when file browse UI is dismissed. + void OnDialogClosed(FileBrowseDelegate* delegate, const std::string& json); + + // The set of all parent windows for which we are currently running dialogs. + std::set<gfx::NativeWindow> parents_; + + // The set of all FileBrowseDelegate that we are currently running. + std::set<FileBrowseDelegate*> delegates_; + + // The listener to be notified of selection completion. + Listener* listener_; + + DISALLOW_COPY_AND_ASSIGN(SelectFileDialogImpl); +}; + +// static +SelectFileDialog* SelectFileDialog::Create(Listener* listener) { + DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::IO)); + DCHECK(!ChromeThread::CurrentlyOn(ChromeThread::FILE)); + return new SelectFileDialogImpl(listener); +} + +SelectFileDialogImpl::SelectFileDialogImpl(Listener* listener) + : listener_(listener) { +} + +SelectFileDialogImpl::~SelectFileDialogImpl() { + // All dialogs should be dismissed by now. + DCHECK(parents_.empty() && delegates_.empty()); +} + +bool SelectFileDialogImpl::IsRunning(gfx::NativeWindow parent_window) const { + return parent_window && parents_.find(parent_window) != parents_.end(); +} + +void SelectFileDialogImpl::ListenerDestroyed() { + listener_ = NULL; +} + +void SelectFileDialogImpl::SelectFile( + Type type, + const string16& title, + const FilePath& default_path, + const FileTypeInfo* file_types, + int file_type_index, + const FilePath::StringType& default_extension, + gfx::NativeWindow owning_window, + void* params) { + std::wstring title_string; + if (title.empty()) { + int string_id; + switch (type) { + case SELECT_FOLDER: + string_id = IDS_SELECT_FOLDER_DIALOG_TITLE; + break; + case SELECT_OPEN_FILE: + case SELECT_OPEN_MULTI_FILE: + string_id = IDS_OPEN_FILE_DIALOG_TITLE; + break; + case SELECT_SAVEAS_FILE: + string_id = IDS_SAVE_AS_DIALOG_TITLE; + break; + default: + NOTREACHED(); + return; + } + title_string = l10n_util::GetString(string_id); + } else { + title_string = UTF16ToWide(title); + } + + if (owning_window) + parents_.insert(owning_window); + + FileBrowseDelegate* file_browse_delegate = new FileBrowseDelegate(this, + type, title_string, default_path, file_types, file_type_index, + default_extension, owning_window, params); + delegates_.insert(file_browse_delegate); + + Browser* browser = BrowserList::GetLastActive(); + DCHECK(browser); + browser->BrowserShowHtmlDialog(file_browse_delegate, owning_window); +} + +void SelectFileDialogImpl::OnDialogClosed(FileBrowseDelegate* delegate, + const std::string& json) { + // Nothing to do if listener_ is gone. + + if (!listener_) + return; + + bool notification_fired = false; + + if (!json.empty()) { + scoped_ptr<Value> value(base::JSONReader::Read(json, false)); + if (!value.get() || !value->IsType(Value::TYPE_DICTIONARY)) { + // Bad json value returned. + NOTREACHED(); + } else { + const DictionaryValue* dict = static_cast<DictionaryValue*>(value.get()); + if (delegate->type_ == SELECT_OPEN_FILE || + delegate->type_ == SELECT_SAVEAS_FILE || + delegate->type_ == SELECT_FOLDER) { + std::wstring path_string; + if (dict->HasKey(kKeyNamePath) && + dict->GetString(kKeyNamePath, &path_string)) { + FilePath path = FilePath::FromWStringHack(path_string); + + listener_->FileSelected(path, 0, delegate->params_); + notification_fired = true; + } + } else if (delegate->type_ == SELECT_OPEN_MULTI_FILE) { + ListValue* paths_value = NULL; + if (dict->HasKey(kKeyNamePath) && + dict->GetList(kKeyNamePath, &paths_value) && + paths_value) { + std::vector<FilePath> paths; + paths.reserve(paths_value->GetSize()); + for (size_t i = 0; i < paths_value->GetSize(); ++i) { + std::wstring path_string; + if (paths_value->GetString(i, &path_string) && + !path_string.empty()) { + paths.push_back(FilePath::FromWStringHack(path_string)); + } + } + + listener_->MultiFilesSelected(paths, delegate->params_); + notification_fired = true; + } + } else { + NOTREACHED(); + } + } + } + + // Always notify listener when dialog is dismissed. + if (!notification_fired) + listener_->FileSelectionCanceled(delegate->params_); + + parents_.erase(delegate->parent_); + delegates_.erase(delegate); +} + +SelectFileDialogImpl::FileBrowseDelegate::FileBrowseDelegate( + SelectFileDialogImpl* owner, + Type type, + const std::wstring& title, + const FilePath& default_path, + const FileTypeInfo* file_types, + int file_type_index, + const FilePath::StringType& default_extension, + gfx::NativeWindow parent, + void* params) + : owner_(owner), + parent_(parent), + type_(type), + title_(title), + default_path_(default_path), + file_type_index_(file_type_index), + default_extension_(default_extension), + params_(params) { + if (file_types) + file_types_ = *file_types; + else + file_types_.include_all_files = true; +} + +SelectFileDialogImpl::FileBrowseDelegate::~FileBrowseDelegate() { +} + +bool SelectFileDialogImpl::FileBrowseDelegate::IsDialogModal() const { + return true; +} + +std::wstring SelectFileDialogImpl::FileBrowseDelegate::GetDialogTitle() const { + return title_; +} + +GURL SelectFileDialogImpl::FileBrowseDelegate::GetDialogContentURL() const { + std::string url_string(chrome::kChromeUIFileBrowseURL); + + return GURL(url_string); +} + +void SelectFileDialogImpl::FileBrowseDelegate::GetDOMMessageHandlers( + std::vector<DOMMessageHandler*>* handlers) const { + return; +} + +void SelectFileDialogImpl::FileBrowseDelegate::GetDialogSize( + gfx::Size* size) const { + size->SetSize(320, 240); +} + +std::string SelectFileDialogImpl::FileBrowseDelegate::GetDialogArgs() const { + // SelectFile inputs as json. + // { + // "type" : "open", // (or "open_multiple", "save", "folder" + // "all_files" : true, + // "file_types" : { + // "exts" : [ ["htm", "html"], ["txt"] ], + // "desc" : [ "HTML files", "Text files" ], + // }, + // "file_type_index" : 1, // 1-based file type index. + // } + // See browser/shell_dialogs.h for more details. + + std::string type_string; + switch (type_) { + case SELECT_FOLDER: + type_string = "folder"; + break; + case SELECT_OPEN_FILE: + type_string = "open"; + break; + case SELECT_OPEN_MULTI_FILE: + type_string = "open_multiple"; + break; + case SELECT_SAVEAS_FILE: + type_string = "save"; + break; + default: + NOTREACHED(); + return std::string(); + } + + std::string exts_list; + std::string desc_list; + for (size_t i = 0; i < file_types_.extensions.size(); ++i) { + DCHECK(!file_types_.extensions[i].empty()); + + std::string exts; + for (size_t j = 0; j < file_types_.extensions[i].size(); ++j) { + if (!exts.empty()) + exts.append(","); + StringAppendF(&exts, "\"%s\"", file_types_.extensions[i][j].c_str()); + } + + if (!exts_list.empty()) + exts_list.append(","); + StringAppendF(&exts_list, "[%s]", exts.c_str()); + + std::string desc; + if (i < file_types_.extension_description_overrides.size()) { + desc = UTF16ToUTF8(file_types_.extension_description_overrides[i]); + } else { +#if defined(OS_WIN) + desc = WideToUTF8(file_types_.extensions[i][0]); +#elif defined(OS_POSIX) + desc = file_types_.extensions[i][0]; +#else + NOTIMPLEMENTED(); +#endif + } + + if (!desc_list.empty()) + desc_list.append(","); + StringAppendF(&desc_list, "\"%s\"", desc.c_str()); + } + + std::string filename = default_path_.BaseName().value(); + + return StringPrintf("{" + "\"type\":\"%s\"," + "\"all_files\":%s," + "\"current_file\":\"%s\"," + "\"file_types\":{\"exts\":[%s],\"desc\":[%s]}," + "\"file_type_index\":%d" + "}", + type_string.c_str(), + file_types_.include_all_files ? "true" : "false", + filename.c_str(), + exts_list.c_str(), + desc_list.c_str(), + file_type_index_); +} + +void SelectFileDialogImpl::FileBrowseDelegate::OnDialogClosed( + const std::string& json_retval) { + owner_->OnDialogClosed(this, json_retval); + delete this; + return; +} diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 951bce7..84d9336 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1876,6 +1876,7 @@ 'browser/views/restart_message_box.h', 'browser/views/sad_tab_view.cc', 'browser/views/sad_tab_view.h', + 'browser/views/select_file_dialog.cc', 'browser/views/select_profile_dialog.cc', 'browser/views/select_profile_dialog.h', 'browser/views/shell_dialogs_win.cc', @@ -2219,6 +2220,7 @@ 'browser/power_save_blocker_stub.cc', 'browser/views/new_browser_window_widget.cc', 'browser/views/new_browser_window_widget.h', + 'browser/views/select_file_dialog.cc', 'browser/views/tabs/grid.cc', 'browser/views/tabs/grid.h', 'browser/views/tabs/tab_overview_cell.cc', @@ -2293,6 +2295,8 @@ ['include', '^browser/views/detachable_toolbar_view.h'], ['include', '^browser/views/detachable_toolbar_view.cc'], ['include', '^browser/views/dialog_stubs_gtk.cc'], + ['include', '^browser/views/dom_view.cc'], + ['include', '^browser/views/dom_view.h'], ['include', '^browser/views/download_item_view.cc'], ['include', '^browser/views/download_item_view.h'], ['include', '^browser/views/download_shelf_view.cc'], @@ -2329,6 +2333,8 @@ ['include', '^browser/views/fullscreen_exit_bubble.h'], ['include', '^browser/views/go_button.cc'], ['include', '^browser/views/go_button.h'], + ['include', '^browser/views/html_dialog_view.cc'], + ['include', '^browser/views/html_dialog_view.h'], ['include', '^browser/views/theme_install_bubble_view.cc'], ['include', '^browser/views/theme_install_bubble_view.h'], ['include', '^browser/views/toolbar_star_toggle.h'], @@ -2365,6 +2371,7 @@ #['include', '^browser/views/panels/panel_scroller_header.h'], ['include', '^browser/views/sad_tab_view.cc'], ['include', '^browser/views/sad_tab_view.h'], + ['include', '^browser/views/select_file_dialog.cc'], ['include', '^browser/views/status_bubble_views.cc'], ['include', '^browser/views/status_bubble_views.h'], ['include', '^browser/views/tab_contents/native_tab_contents_container_gtk.cc'], @@ -2425,7 +2432,6 @@ ['include', '^browser/gtk/clear_browsing_data_dialog_gtk.h'], ['include', '^browser/gtk/constrained_window_gtk.cc'], ['include', '^browser/gtk/constrained_window_gtk.h'], - ['include', '^browser/gtk/dialogs_gtk.cc'], ['include', '^browser/gtk/download_started_animation_gtk.cc'], ['include', '^browser/gtk/edit_search_engine_dialog.cc'], ['include', '^browser/gtk/edit_search_engine_dialog.h'], |