| // Copyright (c) 2011 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/ui/webui/slideshow_ui.h" |
| |
| #include "base/callback.h" |
| #include "base/memory/singleton.h" |
| #include "base/memory/weak_ptr.h" |
| #include "base/message_loop.h" |
| #include "base/path_service.h" |
| #include "base/string_piece.h" |
| #include "base/string_util.h" |
| #include "base/threading/thread.h" |
| #include "base/time.h" |
| #include "base/utf_string_conversions.h" |
| #include "base/values.h" |
| #include "chrome/browser/history/history_types.h" |
| #include "chrome/browser/metrics/user_metrics.h" |
| #include "chrome/browser/profiles/profile.h" |
| #include "chrome/browser/ui/webui/favicon_source.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/jstemplate_builder.h" |
| #include "chrome/common/url_constants.h" |
| #include "content/browser/browser_thread.h" |
| #include "content/browser/tab_contents/tab_contents.h" |
| #include "grit/browser_resources.h" |
| #include "grit/chromium_strings.h" |
| #include "grit/generated_resources.h" |
| #include "grit/locale_settings.h" |
| #include "net/base/directory_lister.h" |
| #include "net/base/escape.h" |
| #include "ui/base/resource/resource_bundle.h" |
| |
| static const char kPropertyPath[] = "path"; |
| static const char kPropertyTitle[] = "title"; |
| static const char kPropertyOffset[] = "currentOffset"; |
| static const char kPropertyDirectory[] = "isDirectory"; |
| |
| class SlideshowUIHTMLSource : public ChromeURLDataManager::DataSource { |
| public: |
| SlideshowUIHTMLSource(); |
| |
| // Called when the network layer has requested a resource underneath |
| // the path we registered. |
| virtual void StartDataRequest(const std::string& path, |
| bool is_incognito, |
| int request_id); |
| virtual std::string GetMimeType(const std::string&) const { |
| return "text/html"; |
| } |
| |
| private: |
| ~SlideshowUIHTMLSource() {} |
| |
| DISALLOW_COPY_AND_ASSIGN(SlideshowUIHTMLSource); |
| }; |
| |
| // The handler for Javascript messages related to the "slideshow" view. |
| class SlideshowHandler : public net::DirectoryLister::DirectoryListerDelegate, |
| public WebUIMessageHandler, |
| public base::SupportsWeakPtr<SlideshowHandler> { |
| public: |
| SlideshowHandler(); |
| virtual ~SlideshowHandler(); |
| |
| // Init work after Attach. |
| void Init(); |
| |
| // DirectoryLister::DirectoryListerDelegate methods: |
| virtual void OnListFile( |
| const net::DirectoryLister::DirectoryListerData& data); |
| virtual void OnListDone(int error); |
| |
| // WebUIMessageHandler implementation. |
| virtual WebUIMessageHandler* Attach(WebUI* web_ui); |
| virtual void RegisterMessages(); |
| |
| void GetChildrenForPath(const FilePath& path, bool is_refresh); |
| |
| // Callback for the "getChildren" message. |
| void HandleGetChildren(const ListValue* args); |
| |
| void HandleRefreshDirectory(const ListValue* args); |
| |
| private: |
| bool PathIsImageFile(const char* filename); |
| |
| scoped_ptr<ListValue> filelist_value_; |
| FilePath currentpath_; |
| FilePath originalpath_; |
| Profile* profile_; |
| int counter_; |
| int currentOffset_; |
| scoped_refptr<net::DirectoryLister> lister_; |
| bool is_refresh_; |
| |
| DISALLOW_COPY_AND_ASSIGN(SlideshowHandler); |
| }; |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // SlideshowHTMLSource |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| SlideshowUIHTMLSource::SlideshowUIHTMLSource() |
| : DataSource(chrome::kChromeUISlideshowHost, MessageLoop::current()) { |
| } |
| |
| void SlideshowUIHTMLSource::StartDataRequest(const std::string& path, |
| bool is_incognito, |
| int request_id) { |
| DictionaryValue localized_strings; |
| // TODO(dhg): Add stirings to localized strings, also add more strings |
| // that are currently hardcoded. |
| SetFontAndTextDirection(&localized_strings); |
| |
| static const base::StringPiece slideshow_html( |
| ResourceBundle::GetSharedInstance().GetRawDataResource( |
| IDR_SLIDESHOW_HTML)); |
| const std::string full_html = jstemplate_builder::GetI18nTemplateHtml( |
| slideshow_html, &localized_strings); |
| |
| scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes); |
| html_bytes->data.resize(full_html.size()); |
| std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin()); |
| |
| SendResponse(request_id, html_bytes); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // SlideshowHandler |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| SlideshowHandler::SlideshowHandler() |
| : profile_(NULL), |
| is_refresh_(false) { |
| lister_ = NULL; |
| } |
| |
| SlideshowHandler::~SlideshowHandler() { |
| if (lister_.get()) { |
| lister_->Cancel(); |
| lister_->set_delegate(NULL); |
| } |
| } |
| |
| WebUIMessageHandler* SlideshowHandler::Attach(WebUI* web_ui) { |
| profile_ = web_ui->GetProfile(); |
| // Create our favicon data source. |
| profile_->GetChromeURLDataManager()->AddDataSource( |
| new FaviconSource(profile_)); |
| return WebUIMessageHandler::Attach(web_ui); |
| } |
| |
| void SlideshowHandler::Init() { |
| } |
| |
| void SlideshowHandler::RegisterMessages() { |
| web_ui_->RegisterMessageCallback("getChildren", |
| NewCallback(this, &SlideshowHandler::HandleGetChildren)); |
| web_ui_->RegisterMessageCallback("refreshDirectory", |
| NewCallback(this, &SlideshowHandler::HandleRefreshDirectory)); |
| } |
| |
| void SlideshowHandler::HandleRefreshDirectory(const ListValue* args) { |
| #if defined(OS_CHROMEOS) |
| std::string path = UTF16ToUTF8(ExtractStringValue(args)); |
| GetChildrenForPath(FilePath(path), true); |
| #endif |
| } |
| |
| void SlideshowHandler::GetChildrenForPath(const FilePath& path, |
| bool is_refresh) { |
| filelist_value_.reset(new ListValue()); |
| currentpath_ = path; |
| |
| if (lister_.get()) { |
| lister_->Cancel(); |
| lister_->set_delegate(NULL); |
| lister_ = NULL; |
| } |
| |
| is_refresh_ = is_refresh; |
| if (file_util::EnsureEndsWithSeparator(¤tpath_) && |
| currentpath_.IsAbsolute()) { |
| lister_ = new net::DirectoryLister(currentpath_, this); |
| } else { |
| originalpath_ = currentpath_; |
| currentpath_ = currentpath_.DirName(); |
| lister_ = new net::DirectoryLister(currentpath_, this); |
| } |
| counter_ = 0; |
| currentOffset_ = -1; |
| lister_->Start(); |
| } |
| |
| void SlideshowHandler::HandleGetChildren(const ListValue* args) { |
| #if defined(OS_CHROMEOS) |
| filelist_value_.reset(new ListValue()); |
| std::string path = UTF16ToUTF8(ExtractStringValue(args)); |
| GetChildrenForPath(FilePath(path), false); |
| #endif |
| } |
| |
| bool SlideshowHandler::PathIsImageFile(const char* filename) { |
| #if defined(OS_CHROMEOS) |
| FilePath file = FilePath(filename); |
| std::string ext = file.Extension(); |
| ext = StringToLowerASCII(ext); |
| if (ext == ".jpg" || |
| ext == ".jpeg" || |
| ext == ".png" || |
| ext == ".gif") { |
| return true; |
| } else { |
| return false; |
| } |
| #else |
| return false; |
| #endif |
| } |
| |
| void SlideshowHandler::OnListFile( |
| const net::DirectoryLister::DirectoryListerData& data) { |
| #if defined(OS_CHROMEOS) |
| if (data.info.filename[0] == '.') { |
| return; |
| } |
| if (!PathIsImageFile(data.info.filename.c_str())) { |
| return; |
| } |
| |
| DictionaryValue* file_value = new DictionaryValue(); |
| |
| file_value->SetString(kPropertyTitle, data.info.filename); |
| file_value->SetString(kPropertyPath, |
| currentpath_.Append(data.info.filename).value()); |
| file_value->SetBoolean(kPropertyDirectory, S_ISDIR(data.info.stat.st_mode)); |
| filelist_value_->Append(file_value); |
| std::string val; |
| file_value->GetString(kPropertyTitle, &val); |
| if (val == originalpath_.BaseName().value()) { |
| currentOffset_ = counter_; |
| } |
| counter_++; |
| #endif |
| } |
| |
| void SlideshowHandler::OnListDone(int error) { |
| DictionaryValue info_value; |
| counter_ = 0; |
| if (!(file_util::EnsureEndsWithSeparator(&originalpath_) && |
| originalpath_.IsAbsolute()) && |
| currentOffset_ != -1) { |
| info_value.SetInteger(kPropertyOffset, currentOffset_); |
| } |
| if (is_refresh_) { |
| info_value.SetString("functionCall", "refresh"); |
| } else { |
| info_value.SetString("functionCall", "getChildren"); |
| } |
| info_value.SetString(kPropertyPath, currentpath_.value()); |
| web_ui_->CallJavascriptFunction("browseFileResult", |
| info_value, *(filelist_value_.get())); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // SlideshowUI |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| SlideshowUI::SlideshowUI(TabContents* contents) : WebUI(contents) { |
| SlideshowHandler* handler = new SlideshowHandler(); |
| AddMessageHandler((handler)->Attach(this)); |
| handler->Init(); |
| SlideshowUIHTMLSource* html_source = new SlideshowUIHTMLSource(); |
| |
| // Set up the chrome://slideshow/ source. |
| contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source); |
| } |