diff options
author | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-11 17:39:18 +0000 |
---|---|---|
committer | davemoore@chromium.org <davemoore@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-11 17:39:18 +0000 |
commit | 9d6b9affe59b28dba4061cec771a65d28d8635a9 (patch) | |
tree | 2eed6d0f6c2a7136b129dd0d9296f42e5e7b2bea /chrome | |
parent | b5db700c4f0b93867f6aaf6c4c4ddbd2f1a3392d (diff) | |
download | chromium_src-9d6b9affe59b28dba4061cec771a65d28d8635a9.zip chromium_src-9d6b9affe59b28dba4061cec771a65d28d8635a9.tar.gz chromium_src-9d6b9affe59b28dba4061cec771a65d28d8635a9.tar.bz2 |
Creating new CL for uploading a picture from ChromiumOS
TEST=none
BUG=none
Review URL: http://codereview.chromium.org/452016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34351 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/app/theme/theme_resources.grd | 1 | ||||
-rw-r--r-- | chrome/browser/browser_resources.grd | 2 | ||||
-rw-r--r-- | chrome/browser/dom_ui/filebrowse_ui.cc | 186 | ||||
-rw-r--r-- | chrome/browser/resources/filebrowse.html | 189 |
4 files changed, 342 insertions, 36 deletions
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 74dee3f..a92cf0e 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -417,6 +417,7 @@ <include name="IDR_ICON_MEDIA" file="icon_media.png" type="BINDATA" /> <include name="IDR_ICON_PHOTO" file="icon_photo.png" type="BINDATA" /> <include name="IDR_ICON_WEBPAGE" file="icon_webpage.png" type="BINDATA" /> + <include name="IDR_FILEBROWSER_UPLOAD" file="filebrowse_upload.png" type="BINDATA" /> </if> <if expr="(pp_ifdef('chromeos') or pp_ifdef('toolkit_views')) and pp_ifdef('_google_chrome')"> diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd index 4e0b4bc..0b65a12 100644 --- a/chrome/browser/browser_resources.grd +++ b/chrome/browser/browser_resources.grd @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- This comment is only here because changes to resources are not picked up -without changes to the corresponding grd file. sky --> +without changes to the corresponding grd file. dhg sdggg --> <grit latest_public_release="0" current_release="1"> <outputs> <output filename="grit/browser_resources.h" type="rc_header"> diff --git a/chrome/browser/dom_ui/filebrowse_ui.cc b/chrome/browser/dom_ui/filebrowse_ui.cc index 13b6539..6e67a6f 100644 --- a/chrome/browser/dom_ui/filebrowse_ui.cc +++ b/chrome/browser/dom_ui/filebrowse_ui.cc @@ -14,12 +14,14 @@ #include "base/thread.h" #include "base/time.h" #include "base/values.h" +#include "base/weak_ptr.h" #include "chrome/browser/bookmarks/bookmark_model.h" #include "chrome/browser/browser.h" #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/metrics/user_metrics.h" +#include "chrome/browser/net/url_fetcher.h" #include "chrome/browser/history/history_types.h" #include "chrome/browser/profile.h" #include "chrome/common/jstemplate_builder.h" @@ -38,7 +40,11 @@ static const int kMaxSearchResults = 100; static const std::wstring kPropertyPath = L"path"; static const std::wstring kPropertyTitle = L"title"; static const std::wstring kPropertyDirectory = L"isDirectory"; - +static const std::string kPicasawebUserPrefix = + "http://picasaweb.google.com/data/feed/api/user/"; +static const std::string kPicasawebDefault = "/albumid/default"; +static const std::string kPicasawebDropBox = "/DropBox"; +static const std::string kPicasawebBaseUrl = "http://picasaweb.google.com/"; class FileBrowseUIHTMLSource : public ChromeURLDataManager::DataSource { public: @@ -59,9 +65,13 @@ class FileBrowseUIHTMLSource : public ChromeURLDataManager::DataSource { DISALLOW_COPY_AND_ASSIGN(FileBrowseUIHTMLSource); }; +class TaskProxy; + // The handler for Javascript messages related to the "filebrowse" view. class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, - public DOMMessageHandler { + public DOMMessageHandler, + public base::SupportsWeakPtr<FilebrowseHandler>, + public URLFetcher::Delegate { public: FilebrowseHandler(); virtual ~FilebrowseHandler(); @@ -77,16 +87,29 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, // Callback for the "getRoots" message. void HandleGetRoots(const Value* value); + void OnURLFetchComplete(const URLFetcher* source, + const GURL& url, + const URLRequestStatus& status, + int response_code, + const ResponseCookies& cookies, + const std::string& data); + // Callback for the "getChildren" message. void HandleGetChildren(const Value* value); // Callback for the "getMetadata" message. void HandleGetMetadata(const Value* value); - // Callback for the "openNewWindow" message. + // Callback for the "openNewWindow" message. void OpenNewFullWindow(const Value* value); void OpenNewPopupWindow(const Value* value); + // Callback for the "uploadToPicasaweb" message. + void UploadToPicasaweb(const Value* value); + + void ReadInFile(); + void FireUploadComplete(); + private: void OpenNewWindow(const Value* value, bool popup); @@ -94,11 +117,36 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, scoped_ptr<ListValue> filelist_value_; FilePath currentpath_; Profile* profile_; + std::string current_file_contents_; + std::string current_file_uploaded_; + int upload_response_code_; + TaskProxy* CurrentTask_; scoped_refptr<net::DirectoryLister> lister_; DISALLOW_COPY_AND_ASSIGN(FilebrowseHandler); }; +class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> { + public: + TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler) + : handler_(handler) {} + void ReadInFileProxy() { + if (handler_) { + handler_->ReadInFile(); + } + } + + void FireUploadCompleteProxy() { + if (handler_) { + handler_->FireUploadComplete(); + } + } + private: + base::WeakPtr<FilebrowseHandler> handler_; + friend class base::RefCountedThreadSafe<TaskProxy>; +}; + + //////////////////////////////////////////////////////////////////////////////// // // FileBrowseHTMLSource @@ -173,12 +221,52 @@ void FilebrowseHandler::RegisterMessages() { NewCallback(this, &FilebrowseHandler::OpenNewPopupWindow)); dom_ui_->RegisterMessageCallback("openNewFullWindow", NewCallback(this, &FilebrowseHandler::OpenNewFullWindow)); + dom_ui_->RegisterMessageCallback("uploadToPicasaweb", + NewCallback(this, &FilebrowseHandler::UploadToPicasaweb)); +} + +void FilebrowseHandler::FireUploadComplete() { + DictionaryValue info_value; + info_value.SetString(L"path", current_file_uploaded_); + + std::string username; + username = getenv("CHROMEOS_USER"); + + if (username.empty()) { + LOG(ERROR) << "Unable to get username"; + return; + } + int location = username.find_first_of('@',0); + if (location <= 0) { + LOG(ERROR) << "Username not formatted correctly"; + return; + } + username = username.erase(username.find_first_of('@',0)); + std::string picture_url; + picture_url = kPicasawebBaseUrl; + picture_url += username; + picture_url += kPicasawebDropBox; + info_value.SetString(L"url", picture_url); + info_value.SetInteger(L"status_code", upload_response_code_); + dom_ui_->CallJavascriptFunction(L"uploadComplete", info_value); +} + +void FilebrowseHandler::OnURLFetchComplete(const URLFetcher* source, + const GURL& url, + const URLRequestStatus& status, + int response_code, + const ResponseCookies& cookies, + const std::string& data) { + upload_response_code_ = response_code; + + ChromeThread::PostTask( + ChromeThread::UI, FROM_HERE, + NewRunnableMethod(CurrentTask_, &TaskProxy::FireUploadCompleteProxy)); } void FilebrowseHandler::HandleGetRoots(const Value* value) { ListValue results_value; DictionaryValue info_value; - DictionaryValue* page_value = new DictionaryValue(); // TODO(dhg): add other entries, make this more general page_value->SetString(kPropertyPath, "/home/chronos"); @@ -187,9 +275,9 @@ void FilebrowseHandler::HandleGetRoots(const Value* value) { results_value.Append(page_value); - info_value.SetString(L"call", "getRoots"); + info_value.SetString(L"functionCall", "getRoots"); - dom_ui_->CallJavascriptFunction(L"fileBrowseResult", + dom_ui_->CallJavascriptFunction(L"browseFileResult", info_value, results_value); } @@ -240,6 +328,85 @@ void FilebrowseHandler::OpenNewWindow(const Value* value, bool popup) { } } +void FilebrowseHandler::ReadInFile() { +#if defined(OS_CHROMEOS) + // Get the users username + std::string username; + username = getenv("CHROMEOS_USER"); + + if (username.empty()) { + LOG(ERROR) << "Unable to get username"; + return; + } + int location = username.find_first_of('@',0); + if (location <= 0) { + LOG(ERROR) << "Username not formatted correctly"; + return; + } + username = username.erase(username.find_first_of('@',0)); + std::string url = kPicasawebUserPrefix; + url += username; + url += kPicasawebDefault; + + FilePath currentpath; + currentpath = FilePath(current_file_uploaded_); + // Get the filename + std::string filename; + filename = currentpath.BaseName().value(); + std::string filecontents; + if (!file_util::ReadFileToString(currentpath, &filecontents)) { + LOG(ERROR) << "Unable to read this file:" << currentpath.value(); + return; + } + + URLFetcher* fetcher = URLFetcher::Create(0, + GURL(url), + URLFetcher::POST, + this); + fetcher->set_upload_data("image/jpeg", filecontents); + + // Set the filename on the server + std::string slug = "Slug: "; + slug += filename; + fetcher->set_extra_request_headers(slug); + fetcher->set_request_context(Profile::GetDefaultRequestContext()); + fetcher->Start(); +#endif +} + +// This is just a prototype for allowing generic uploads to various sites +// TODO(dhg): Remove this and implement general upload. +void FilebrowseHandler::UploadToPicasaweb(const Value* value) { + std::string path; +#if defined(OS_CHROMEOS) + if (value && value->GetType() == Value::TYPE_LIST) { + const ListValue* list_value = static_cast<const ListValue*>(value); + Value* list_member; + + // Get search string. + if (list_value->Get(0, &list_member) && + list_member->GetType() == Value::TYPE_STRING) { + const StringValue* string_value = + static_cast<const StringValue*>(list_member); + string_value->GetAsString(&path); + } + + } else { + LOG(ERROR) << "Wasn't able to get the List if requested files."; + return; + } + current_file_uploaded_ = path; + // ReadInFile(); + TaskProxy* task = new TaskProxy(AsWeakPtr()); + task->AddRef(); + CurrentTask_ = task; + ChromeThread::PostTask( + ChromeThread::FILE, FROM_HERE, + NewRunnableMethod( + task, &TaskProxy::ReadInFileProxy)); +#endif +} + void FilebrowseHandler::HandleGetChildren(const Value* value) { std::string path; if (value && value->GetType() == Value::TYPE_LIST) { @@ -298,9 +465,9 @@ void FilebrowseHandler::OnListFile( void FilebrowseHandler::OnListDone(int error) { DictionaryValue info_value; - info_value.SetString(L"call", "getChildren"); + info_value.SetString(L"functionCall", "getChildren"); info_value.SetString(kPropertyPath, currentpath_.value()); - dom_ui_->CallJavascriptFunction(L"fileBrowseResult", + dom_ui_->CallJavascriptFunction(L"browseFileResult", info_value, *(filelist_value_.get())); } @@ -314,7 +481,8 @@ void FilebrowseHandler::HandleGetMetadata(const Value* value) { //////////////////////////////////////////////////////////////////////////////// FileBrowseUI::FileBrowseUI(TabContents* contents) : DOMUI(contents) { - AddMessageHandler((new FilebrowseHandler())->Attach(this)); + FilebrowseHandler* handler = new FilebrowseHandler(); + AddMessageHandler((handler)->Attach(this)); FileBrowseUIHTMLSource* html_source = new FileBrowseUIHTMLSource(); // Set up the chrome://filebrowse/ source. diff --git a/chrome/browser/resources/filebrowse.html b/chrome/browser/resources/filebrowse.html index c517476..bd9a31b 100644 --- a/chrome/browser/resources/filebrowse.html +++ b/chrome/browser/resources/filebrowse.html @@ -15,7 +15,11 @@ div.header { position: absolute; -webkit-box-sizing: border-box; box-sizing: border-box; - background-image: -webkit-gradient(linear, 0% 0%, 0% 90%, from(rgb(239, 242, 249)), to(rgba(201, 212, 245, 1))); + background-image: -webkit-gradient(linear, + 0% 0%, + 0% 90%, + from(rgb(239, 242, 249)), + to(rgba(201, 212, 245, 1))); border-bottom-color: #999; border-bottom-width: 1px; color: black; @@ -61,10 +65,45 @@ li.filebrowserow div.icon { width: 10px; } +.uploadicon { + background: url('../../app/theme/filebrowse_upload.png'); + position: absolute; + right: 0; + top: 5px; + height: 100%; + width: 12px; + margin-left: 5px; + margin-top: 5px; + background-repeat: no-repeat; + cursor:pointer; +} + +.uploadcomplete { + height: 100%; + position: absolute; + right: 0; + top: 5px; + height: 100%; + width: 70px; + margin-left: 5px; + margin-top: 5px; +} + +.uploadprogress { + position: absolute; + right: 0; + top: 5px; + height: 100%; + width: 12px; + margin-left: 5px; + margin-top: 5px; + background-repeat: no-repeat; +} + li.filebrowserow { border-bottom: 1px solid #f7f7f7; padding: 8px 5px 5px 54px; - overflow: hidden; +/* overflow: hidden; */ font-size:.8em; font-family: helvetica; position: relative; @@ -79,7 +118,8 @@ li.filebrowserow span.name { div.title { text-align: center; position: relative; - font-size: 18px; + font-size: .8em; + font-weight: bold; padding-top: 10px; } @@ -154,6 +194,37 @@ div.container { height: 100%; } +.uploadmenu { + top: 0; + right: 0; + width: 100px; + height: 70px; + position: absolute; + display: none; + z-index: 999; + background: white; + border: 1px solid black; + padding: 5px; +} + +.uploadmenuitem { + width: 100%; + height: 20px; + text-align: left; + cursor: pointer; + left: 0; + color: blue; + text-decoration: underline; +} + +.uploadmenuitemdisabled { + width: 100%; + height: 20px; + text-align: left; + color: gray; + left: 0; +} + a:hover { color: #3874be; text-decoration: underline; @@ -172,43 +243,46 @@ function $(o) { var pathArray = []; var currentNode = -1; +var foundImages = []; +var currentImageMenu = ''; -var goBackInList = function() { +function goBackInList() { if (currentNode > 0) { currentNode--; getDataForPath(pathArray[currentNode]); } }; -var goForwardInList = function() { +function goForwardInList() { if (currentNode < (pathArray.length - 1)) { currentNode++; getDataForPath(pathArray[currentNode]); } }; -function fileBrowseResult(info, results) { - if (info.call == 'getRoots' || info.call == 'getChildren') { +function browseFileResult(info, results) { + if (info.functionCall == 'getRoots' || + info.functionCall == 'getChildren') { currentNode++; - createNewList(' ', results); + createNewList('Removeable Media', results); } } -var pathIsVideoFile = function(path) { +function pathIsVideoFile(path) { return /\.(mp4|ogg|mpg|avi)$/i.test(path); }; -var pathIsAudioFile = function(path) { +function pathIsAudioFile(path) { return /\.(mp3|m4a)$/i.test(path); }; -var pathIsImageFile = function(path) { - return /\.(jpg|png)$/i.test(path); +function pathIsImageFile(path) { + return /\.(jpg|png|gif)$/i.test(path); }; -var setUpForPlayback = function(path) { - mediapath = 'file://' + path; +function setUpForPlayback(path) { + var mediapath = 'file://' + path; var header = $('header'); document.body.removeChild(header); var main = $('main'); @@ -230,7 +304,7 @@ var setUpForPlayback = function(path) { main.appendChild(element); }; -var getClassForPath = function(path, isDirectory) { +function getClassForPath(path, isDirectory) { if (isDirectory) { return 'icon iconfolder'; } else if (pathIsImageFile(path)) { @@ -243,7 +317,7 @@ var getClassForPath = function(path, isDirectory) { return 'icon iconfile'; }; -var getDataForPath = function(path) { +function getDataForPath(path) { if (path == 'roots' ) { chrome.send('getRoots', []); } else { @@ -272,7 +346,7 @@ function load() { } }; -var decend = function(path) { +function descend(path) { if (pathArray.length <currentNode) { pathArray = pathArray.slice(0, currentNode); } @@ -289,22 +363,61 @@ function showImage(path) { chrome.send('openNewFullWindow', ['file://' + path]); }; +function clearImageMenus() { + if (foundImages[currentImageMenu]) { + var element = foundImages[currentImageMenu]; + element.firstChild.style.display = 'none'; + currentImageMenu = ''; + } +}; + +function uploadImage(path) { + if (foundImages[path]) { + var element = foundImages[path]; + element.onclick = undefined; + element.className = 'uploadprogress'; + } + chrome.send('uploadToPicasaweb', [path]); +}; + +function showMenu(path) { + if (foundImages[path]) { + clearImageMenus(); + var element = foundImages[path]; + element.firstChild.style.display = 'block'; + currentImageMenu = path; + } + window.event.stopPropagation(); +} + +function uploadComplete(result) { + if (foundImages[result.path]) { + var element = foundImages[result.path]; + element.className = 'uploadcomplete'; + if (result.status_code == 201) { + element.innerHTML = '<a href=' + result.url + '>Uploaded</a>'; + } else { + element.textContent = 'Error'; + } + } +}; + // TODO(dhg): Do not use javascript: href, use onclick instead -var createHrefForItem = function(path, isDirectory) { +function createHrefForItem(path, isDirectory) { if (isDirectory) { - return 'javascript:decend("'+path+'");'; + return 'javascript:descend("' + path + '");'; } if (pathIsAudioFile(path)) { - return 'javascript:playMediaFile("'+path+'");'; + return 'javascript:playMediaFile("' + path + '");'; } if (pathIsVideoFile(path)) { - return 'javascript:playMediaFile("'+path+'");'; + return 'javascript:playMediaFile("' + path + '");'; } if (pathIsImageFile(path)) { - return 'javascript:showImage("'+path+'");'; + return 'javascript:showImage("' + path + '");'; } else { return ''; } }; -var createNewItem = function(title, path, isDirectory) { +function createNewItem(title, path, isDirectory) { var element = document.createElement('li'); element.className = 'filebrowserow'; @@ -328,16 +441,40 @@ var createNewItem = function(title, path, isDirectory) { rightarrow.innerHTML = '»'; rightarrow.className = 'rightarrow'; element.appendChild(rightarrow); + } else if (pathIsImageFile(path)) { + var uploadicon = document.createElement('div'); + var uploadmenu = document.createElement('div'); + uploadmenu.className = 'uploadmenu'; + var picasaitem = document.createElement('div'); + var flikritem = document.createElement('div'); + var emailitem = document.createElement('div'); + picasaitem.textContent = 'Picasa Web'; + flikritem.textContent = 'Flikr'; + emailitem.textContent = 'Email'; + picasaitem.className = 'uploadmenuitem'; + flikritem.className = 'uploadmenuitemdisabled'; + emailitem.className = 'uploadmenuitemdisabled'; + picasaitem.onclick = new Function('uploadImage("' + path + '")'); + uploadmenu.appendChild(picasaitem); + uploadmenu.appendChild(flikritem); + uploadmenu.appendChild(emailitem); + uploadicon.align = 'right'; + uploadicon.className = 'uploadicon'; + uploadicon.onclick = new Function('showMenu("' + path + '")'); + uploadicon.appendChild(uploadmenu); + element.appendChild(uploadicon); + // Doing this so that we can change it when we get events + foundImages[path] = uploadicon; } return element; }; -var clearChildren = function(element) { +function clearChildren(element) { element.innerHTML = ''; }; -var createNewList = function(title, results) { +function createNewList(title, results) { var list = document.createElement('ul'); list.className = 'filebrowselist'; var header = $('currenttitle'); @@ -354,7 +491,7 @@ var createNewList = function(title, results) { }; </script> -<body onload="load();"> +<body onload="load();" onclick='clearImageMenus()'> <div id='header' class='header'> <div id='back' class='backbutton controlbutton' onclick='goBackInList();return false;'> <img src="../../app/theme/filebrowse_back.png" width='100%' height='100%'> |