diff options
-rw-r--r-- | chrome/app/theme/filebrowse_menu.png | bin | 0 -> 2936 bytes | |||
-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 | 135 | ||||
-rw-r--r-- | chrome/browser/resources/filebrowse.html | 241 |
5 files changed, 282 insertions, 97 deletions
diff --git a/chrome/app/theme/filebrowse_menu.png b/chrome/app/theme/filebrowse_menu.png Binary files differnew file mode 100644 index 0000000..2b737c4 --- /dev/null +++ b/chrome/app/theme/filebrowse_menu.png diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index 5d0d8e4..d755473c 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd @@ -427,6 +427,7 @@ <include name="IDR_ICON_WEBPAGE" file="icon_webpage.png" type="BINDATA" /> <include name="IDR_FILEBROWSER_UPLOAD" file="filebrowse_upload.png" type="BINDATA" /> <include name="IDR_FILEBROWSER_FULLSCREEN" file="filebrowse_fullscreen.png" type="BINDATA" /> + <include name="IDR_FILEBROWSER_MENU" file="filebrowse_menu.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 dfb9438..7da7632 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. dhg --> +without changes to the corresponding grd file. dopeeqd --> <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 e8e2c99..4d8e941 100644 --- a/chrome/browser/dom_ui/filebrowse_ui.cc +++ b/chrome/browser/dom_ui/filebrowse_ui.cc @@ -126,6 +126,8 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, // Callback for the "getRoots" message. void HandleGetRoots(const Value* value); + void GetChildrenForPath(FilePath& path, bool is_refresh); + void OnURLFetchComplete(const URLFetcher* source, const GURL& url, const URLRequestStatus& status, @@ -151,6 +153,12 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, void HandleCreateNewFolder(const Value* value); + void HandleDeleteFile(const Value* value); + void DeleteFile(const FilePath& path); + void FireDeleteComplete(const FilePath& path); + + void HandlePauseToggleDownload(const Value* value); + void ReadInFile(); void FireUploadComplete(); @@ -172,6 +180,7 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, int upload_response_code_; TaskProxy* CurrentTask_; scoped_refptr<net::DirectoryLister> lister_; + bool is_refresh_; DownloadManager* download_manager_; typedef std::vector<DownloadItem*> DownloadList; @@ -182,8 +191,9 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate, class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> { public: - explicit TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler) - : handler_(handler) {} + explicit TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler, FilePath& path) + : handler_(handler), + path_(path) {} void ReadInFileProxy() { if (handler_) { handler_->ReadInFile(); @@ -195,8 +205,21 @@ class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> { handler_->FireUploadComplete(); } } + + void DeleteFileProxy() { + if (handler_) { + handler_->DeleteFile(path_); + } + } + + void FireDeleteCompleteProxy() { + if (handler_) { + handler_->FireDeleteComplete(path_); + } + } private: base::WeakPtr<FilebrowseHandler> handler_; + FilePath path_; friend class base::RefCountedThreadSafe<TaskProxy>; }; @@ -240,13 +263,13 @@ void FileBrowseUIHTMLSource::StartDataRequest(const std::string& path, //////////////////////////////////////////////////////////////////////////////// FilebrowseHandler::FilebrowseHandler() : profile_(NULL), + is_refresh_(false), download_manager_(NULL) { - // TODO(dhg): Check to see if this is really necessary + lister_ = NULL; #if defined(OS_CHROMEOS) chromeos::MountLibrary* lib = chromeos::MountLibrary::Get(); lib->AddObserver(this); #endif - lister_ = NULL; } FilebrowseHandler::~FilebrowseHandler() { @@ -298,8 +321,19 @@ void FilebrowseHandler::RegisterMessages() { NewCallback(this, &FilebrowseHandler::HandleGetDownloads)); dom_ui_->RegisterMessageCallback("createNewFolder", NewCallback(this, &FilebrowseHandler::HandleCreateNewFolder)); + dom_ui_->RegisterMessageCallback("pauseToggleDownload", + NewCallback(this, &FilebrowseHandler::HandlePauseToggleDownload)); + dom_ui_->RegisterMessageCallback("deleteFile", + NewCallback(this, &FilebrowseHandler::HandleDeleteFile)); } + +void FilebrowseHandler::FireDeleteComplete(const FilePath& path) { + // We notify the UI by telling it to refresh its contents. + FilePath dir_path = path.DirName(); + GetChildrenForPath(dir_path, true); +}; + void FilebrowseHandler::FireUploadComplete() { DictionaryValue info_value; info_value.SetString(L"path", current_file_uploaded_); @@ -421,6 +455,25 @@ void FilebrowseHandler::HandleCreateNewFolder(const Value* value) { #endif } +void FilebrowseHandler::HandlePauseToggleDownload(const Value* value) { +#if defined(OS_CHROMEOS) + if (value && value->GetType() == Value::TYPE_LIST) { + const ListValue* list_value = static_cast<const ListValue*>(value); + int id; + std::string str_id; + + if (list_value->GetString(0, &str_id)) { + id = atoi(str_id.c_str()); + DownloadItem* item = download_items_[id]; + item->TogglePause(); + } else { + LOG(ERROR) << "Unable to get id for download to pause"; + return; + } + } +#endif +} + void FilebrowseHandler::OpenNewFullWindow(const Value* value) { OpenNewWindow(value, false); } @@ -537,7 +590,8 @@ void FilebrowseHandler::UploadToPicasaweb(const Value* value) { } current_file_uploaded_ = path; // ReadInFile(); - TaskProxy* task = new TaskProxy(AsWeakPtr()); + FilePath current_path(path); + TaskProxy* task = new TaskProxy(AsWeakPtr(), current_path); task->AddRef(); CurrentTask_ = task; ChromeThread::PostTask( @@ -547,6 +601,21 @@ void FilebrowseHandler::UploadToPicasaweb(const Value* value) { #endif } +void FilebrowseHandler::GetChildrenForPath(FilePath& path, bool is_refresh) { + filelist_value_.reset(new ListValue()); + currentpath_ = FilePath(path); + + if (lister_.get()) { + lister_->Cancel(); + lister_->set_delegate(NULL); + lister_ = NULL; + } + + is_refresh_ = is_refresh; + lister_ = new net::DirectoryLister(currentpath_, this); + lister_->Start(); +} + void FilebrowseHandler::HandleGetChildren(const Value* value) { std::string path; if (value && value->GetType() == Value::TYPE_LIST) { @@ -566,19 +635,14 @@ void FilebrowseHandler::HandleGetChildren(const Value* value) { return; } filelist_value_.reset(new ListValue()); + FilePath currentpath; #if defined(OS_WIN) - currentpath_ = FilePath(ASCIIToWide(path)); + currentpath = FilePath(ASCIIToWide(path)); #else - currentpath_ = FilePath(path); + currentpath = FilePath(path); #endif - if (lister_.get()) { - lister_->Cancel(); - lister_->set_delegate(NULL); - lister_ = NULL; - } - lister_ = new net::DirectoryLister(currentpath_, this); - lister_->Start(); + GetChildrenForPath(currentpath, false); } void FilebrowseHandler::OnListFile( @@ -615,10 +679,15 @@ void FilebrowseHandler::OnListFile( void FilebrowseHandler::OnListDone(int error) { DictionaryValue info_value; - info_value.SetString(L"functionCall", "getChildren"); + if (is_refresh_) { + info_value.SetString(L"functionCall", "refresh"); + } else { + info_value.SetString(L"functionCall", "getChildren"); + } info_value.SetString(kPropertyPath, currentpath_.value()); dom_ui_->CallJavascriptFunction(L"browseFileResult", info_value, *(filelist_value_.get())); + SendCurrentDownloads(); } void FilebrowseHandler::HandleGetMetadata(const Value* value) { @@ -652,6 +721,42 @@ void FilebrowseHandler::SetDownloads(std::vector<DownloadItem*>& downloads) { SendCurrentDownloads(); } +void FilebrowseHandler::DeleteFile(const FilePath& path) { + if (!file_util::Delete(path, true)) { + LOG(ERROR) << "unable to delete directory"; + } + ChromeThread::PostTask( + ChromeThread::UI, FROM_HERE, + NewRunnableMethod(CurrentTask_, &TaskProxy::FireDeleteCompleteProxy)); +} + +void FilebrowseHandler::HandleDeleteFile(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); + + TaskProxy* task = new TaskProxy(AsWeakPtr(), currentpath); + task->AddRef(); + CurrentTask_ = task; + ChromeThread::PostTask( + ChromeThread::FILE, FROM_HERE, + NewRunnableMethod( + task, &TaskProxy::DeleteFileProxy)); + } else { + LOG(ERROR) << "Unable to get string"; + return; + } + } +#endif +} + void FilebrowseHandler::OnDownloadUpdated(DownloadItem* download) { DownloadList::iterator it = find(download_items_.begin(), download_items_.end(), diff --git a/chrome/browser/resources/filebrowse.html b/chrome/browser/resources/filebrowse.html index ca2a651..d6595a2 100644 --- a/chrome/browser/resources/filebrowse.html +++ b/chrome/browser/resources/filebrowse.html @@ -29,27 +29,6 @@ div.header { color: black; } -li.filebrowserow .actionmenu { - display:inline-block; - float:right; - width:15px; - height:16px; - opacity:0.3; - -webkit-transition: opacity 0.2s ease-out ; - -} - -li.filebrowserow:hover .actionmenu { -opacity:0.75;; --webkit-transition: opacity 0.0s ease-out ; - -} - -li.filebrowserow:hover .actionmenu:hover { -opacity:1.0; --webkit-transition: opacity 0.0s ease-out ; -} - .rowlink { height: 100%; width: 90%; @@ -132,17 +111,29 @@ li.filebrowserow div.icon { opacity:0.5; } -.uploaicon { - background: url('../../app/theme/filebrowse_upload.png'); +.menuicon { + background: url('../../app/theme/filebrowse_menu.png'); position: absolute; - right: 0; + right: 4px; top: 5px; height: 100%; - width: 12px; - margin-left: 5px; + width: 15px; + margin-left: 0; margin-top: 5px; background-repeat: no-repeat; cursor:pointer; + opacity:0.3; + -webkit-transition: opacity 0.2s ease-out ; +} + +li.filebrowserow:hover .menuicon { + opacity:0.75;; + -webkit-transition: opacity 0.0s ease-out ; +} + +li.filebrowserow:hover .menuicon:hover { + opacity:1.0; + -webkit-transition: opacity 0.0s ease-out ; } .uploadcomplete { @@ -182,6 +173,17 @@ li.filebrowserow { font-size:.6em; } +.downloadpause { + right:0; + bottom:0; + height: 15px; + cursor: pointer; + color:blue; + text-align: center; + position: absolute; + text-decoration:underline; +} + li.filebrowserow:hover { background: #ebeff9; cursor: pointer; @@ -446,30 +448,42 @@ div.fullcontainer { height: 100%; } -.uploadmenu { - top: 0; - right: 0; +.menu { + top: 14px; + right: 2px; width: 100px; - height: 70px; + -webkit-box-shadow: rgba(0, 0, 0, 0.3) 0px 3px 3px; + border-bottom-left-radius: 4px 4px; + border-bottom-right-radius: 4px 4px; + border-top-left-radius: 4px 4px; + border-top-right-radius: 0px 0px; position: absolute; display: none; z-index: 999; background: white; - border: 1px solid black; + -webkit-border-top-left-radius: 4px; + border: 1px solid rgba(0, 0, 0, 0.6); padding: 5px; } -.uploadmenuitem { +.menuitem { width: 100%; height: 20px; text-align: left; cursor: pointer; left: 0; - color: blue; - text-decoration: underline; + color:#0D0052; + -webkit-transition: color 1.0s ease-out ; } -.uploadmenuitemdisabled { +.menuitem:hover { + text-decoration:underline; + color:#20c; + background: #ebeff9; + -webkit-transition: color 0.0s ease-out ; +} + +.menuitemdisabled { width: 100%; height: 20px; text-align: left; @@ -489,7 +503,7 @@ function $(o) { var pathArray = []; var currentNode = -1; -var foundImages = []; +var menus = []; var currentImageMenu = ''; var inFullMode = false; var inSelectMode = false; @@ -502,6 +516,12 @@ var currentlySelectedItems = new Array(); var currentlySelectedPaths = new Array(); var multiSelect = false; var inSaveMode = false; +var currentMenu = null; +var mainColumn = null; + +// strings +var kPauseDownload = 'pause'; +var kResumeDownload = 'resume'; function goBackInList() { if (currentNode > 0) { @@ -529,7 +549,7 @@ function goForwardInList() { var lastScrollLeft = 0; function animateScrollRight() { - var main = $('main'); + var main = mainColumn; main.scrollLeft += 20; // since if its larger than a size, we know we reached the leftmost part when // it stops growing, so clear it out and no more timeouts. @@ -553,7 +573,7 @@ function getCurrentContainer() { animateScrollRight(); return newContainer; } else { - return $('main'); + return mainColumn; } }; @@ -587,9 +607,20 @@ function browseFileResult(info, results) { } } else if (info.functionCall == 'getChildren') { var main = getCurrentContainer(); + main.id = 'dir/' + info.path; divArray.push(main); createNewList(lastDir, results, main, info.path); + } else if (info.functionCall == 'refresh') { + var main = $('dir/' + info.path); + if (main) { + clearList(main); + createNewList(lastDir, results, main, info.path); + } else { + alert('hmm, got a refresh on an unknown directory: '+ 'dir/' + info.path); + // not currently displayed, so just return. + return; + } } }; @@ -606,7 +637,7 @@ function pathIsImageFile(path) { }; function moveScrollLeft() { - var main = $('main'); + var main = mainColumn; main.scrollLeft += 10; } @@ -614,7 +645,7 @@ function setUpForPlayback(path) { var mediapath = 'file://' + path; var header = $('header'); document.body.removeChild(header); - var main = $('main'); + var main = mainColumn; main.className = 'playbackcontainer'; var elementType; if (pathIsVideoFile(path)) { @@ -669,7 +700,7 @@ function getDataForPath(path) { function setUpForScanning() { var header = $('header'); document.body.removeChild(header); - var main = $('main'); + var main = mainColumn; main.className = 'scanningcontainer'; main.textContent = 'Scanning Device...'; }; @@ -765,6 +796,10 @@ function createFolder(elementId) { return false; }; +function deleteFile(path) { + chrome.send('deleteFile', [path]); +}; + function createFolderTyping(elementId) { if (window.event.keyCode == 13) { createFolder(elementId); @@ -779,9 +814,21 @@ function getDirectoryForPath(path) { return path.substr(path, index); }; +function pauseToggleDownload(id) { + var element = $('downloaditem' + id); + if (element.textContent == kPauseDownload) { + element.textContent = kResumeDownload; + } else { + element.textContent = kPauseDownload; + } + // Have to convert to a string, the system wasn't accepting ints + chrome.send('pauseToggleDownload', ['' + id]); +}; + 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 + downloadUpdated(results); }; function downloadUpdated(results) { @@ -801,6 +848,18 @@ function downloadUpdated(results) { var progressDiv = document.createElement('div'); progressDiv.className = 'downloadstatus'; element.appendChild(progressDiv); + var pauseDiv = document.createElement('div'); + pauseDiv.onclick = new Function('pauseToggleDownload(' + results[x].id + ')'); + pauseDiv.className = 'downloadpause'; + if (results[x].state == "DANGEROUS") { + pauseDiv.textContent = "danger"; + } else if (results[x].state == "PAUSED") { + pauseDiv.textContent = kResumeDownload; + } else if (results[x].state == "IN_PROGRESS") { + pauseDiv.textContent = kPauseDownload; + } + pauseDiv.id = 'downloaditem' + results[x].id; + element.appendChild(pauseDiv); } progressDiv.textContent = results[x].progress_status_text; @@ -809,6 +868,9 @@ function downloadUpdated(results) { if (element.children[x].className == 'downloadstatus') { var child = element.children[x]; element.removeChild(child); + } else if (element.children[x].className == 'downloadpause') { + var child = element.children[x]; + element.removeChild(child); } } element.className = 'filebrowserow'; @@ -850,6 +912,7 @@ function dialogNewFolderClick() { * Window onload handler, sets up the page. */ function load() { + mainColumn = $('main'); if(document.documentElement.clientWidth <= 600) { inFullMode = false; @@ -866,7 +929,7 @@ function load() { } inSelectMode = true; if (inSaveMode) { - var main = $('main'); + var main = mainColumn; main.className = 'containerwithsavebuttons'; var savemenu = document.createElement('div'); savemenu.className = 'savecontainer'; @@ -905,7 +968,7 @@ function load() { document.body.appendChild(savemenu); } else { - var main = $('main'); + var main = mainColumn; main.className = 'containerwithopenbuttons'; var openmenu = document.createElement('div'); openmenu.className = 'opencontainer'; @@ -923,7 +986,7 @@ function load() { } } } else { - var main = $('main'); + var main = mainColumn; main.className = 'fullcontainer'; var innerContainer = document.createElement('div'); innerContainer.className = 'container'; @@ -1029,34 +1092,41 @@ function showImage(path) { } }; -function clearImageMenus() { - if (foundImages[currentImageMenu]) { - var element = foundImages[currentImageMenu]; - element.firstChild.style.display = 'none'; - currentImageMenu = ''; +function clearMenus() { + + if (currentMenu) { + currentMenu.firstChild.style.display = 'none'; + currentMenu.style.opacity = ''; + currentMenu = null; } }; function uploadImage(path) { + /* if (foundImages[path]) { var element = foundImages[path]; element.onclick = undefined; element.className = 'uploadprogress'; } - chrome.send('uploadToPicasaweb', [path]); + chrome.send('uploadToPicasaweb', [path]);*/ }; function showMenu(path) { - if (foundImages[path]) { - clearImageMenus(); - var element = foundImages[path]; + var element = menus[path]; + if (element.firstChild.style.display == 'block') { + // Second click should clear the menu. + clearMenus(); + } else { + clearMenus(); element.firstChild.style.display = 'block'; - currentImageMenu = path; + element.style.opacity = '1'; + currentMenu = element; } window.event.stopPropagation(); } function uploadComplete(result) { + /* if (foundImages[result.path]) { var element = foundImages[result.path]; element.className = 'uploadcomplete'; @@ -1065,7 +1135,7 @@ function uploadComplete(result) { } else { element.textContent = 'Error'; } - } + }*/ }; function findInArray(arr, element) { @@ -1143,37 +1213,46 @@ function createNewItem(title, path, isDirectory) { link.appendChild(span); element.appendChild(link); + + // Setup Menu + var currentPath = pathArray[pathArray.length - 1]; + if (currentPath != 'roots') { + var menuicon = document.createElement('div'); + var menu = document.createElement('div'); + menu.className = 'menu'; + if (pathIsImageFile(path)) { + 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 = 'menuitem'; + flikritem.className = 'menuitemdisabled'; + emailitem.className = 'menuitemdisabled'; + picasaitem.onclick = new Function('uploadImage("' + path + '")'); + menu.appendChild(picasaitem); + menu.appendChild(flikritem); + menu.appendChild(emailitem); + } + var deleteitem = document.createElement('div'); + deleteitem.textContent = 'Delete'; + deleteitem.className = 'menuitem'; + deleteitem.onclick = new Function('deleteFile("' + path +'")'); + menu.appendChild(deleteitem); + menuicon.align = 'right'; + menuicon.className = 'menuicon'; + menuicon.onclick = new Function('showMenu("' + path + '")'); + menuicon.appendChild(menu); + element.appendChild(menuicon); + menus[path] = menuicon; + } if (isDirectory) { var rightarrow = document.createElement('span'); rightarrow.innerHTML = ' »'; rightarrow.className = 'rightarrow'; link.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; }; @@ -1222,7 +1301,7 @@ function createNewList(title, results, main, path) { }; </script> -<body onload='load();' onclick='clearImageMenus()' onselectstart='return false'> +<body onload='load();' onclick='clearMenus()' 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%'> |