summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordhg@chromium.org <dhg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-24 16:24:27 +0000
committerdhg@chromium.org <dhg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-24 16:24:27 +0000
commitd3d9b4fb5b36702006f903e2d1ed0aa7e9829d64 (patch)
treebb859a5af7d6bfe028ae750622894fbb59e52065
parentb3866e05c2c3fe34c0823d86256833ce78d66f15 (diff)
downloadchromium_src-d3d9b4fb5b36702006f903e2d1ed0aa7e9829d64.zip
chromium_src-d3d9b4fb5b36702006f903e2d1ed0aa7e9829d64.tar.gz
chromium_src-d3d9b4fb5b36702006f903e2d1ed0aa7e9829d64.tar.bz2
Adding copy to the filebrowser. Also fixes a crash bug when the user tries to access a download that no longer exists.
Review URL: http://codereview.chromium.org/2844040 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@60475 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser_resources.grd2
-rw-r--r--chrome/browser/dom_ui/filebrowse_ui.cc97
-rw-r--r--chrome/browser/resources/filebrowse.html155
-rw-r--r--chrome/browser/resources/mediaplayer.html6
-rw-r--r--chrome/browser/resources/playlist.html6
5 files changed, 239 insertions, 27 deletions
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 52c3714..b70f99c 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. eadeae-->
+without changes to the corresponding grd file. eeeeet -->
<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 411e386..0422d4d 100644
--- a/chrome/browser/dom_ui/filebrowse_ui.cc
+++ b/chrome/browser/dom_ui/filebrowse_ui.cc
@@ -166,8 +166,11 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate,
void EnqueueMediaFile(const ListValue* args);
void HandleDeleteFile(const ListValue* args);
+ void HandleCopyFile(const ListValue* value);
+ void CopyFile(const FilePath& src, const FilePath& dest);
void DeleteFile(const FilePath& path);
void FireDeleteComplete(const FilePath& path);
+ void FireCopyComplete(const FilePath& src, const FilePath& dest);
void HandlePauseToggleDownload(const ListValue* args);
@@ -212,10 +215,15 @@ class FilebrowseHandler : public net::DirectoryLister::DirectoryListerDelegate,
class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
public:
- explicit TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler,
- FilePath& path)
+ TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler,
+ const FilePath& path, const FilePath& dest)
: handler_(handler),
- path_(path) {}
+ src_(path),
+ dest_(dest) {}
+ TaskProxy(const base::WeakPtr<FilebrowseHandler>& handler,
+ const FilePath& path)
+ : handler_(handler),
+ src_(path) {}
void ReadInFileProxy() {
if (handler_) {
handler_->ReadInFile();
@@ -237,18 +245,30 @@ class TaskProxy : public base::RefCountedThreadSafe<TaskProxy> {
void DeleteFileProxy() {
if (handler_) {
- handler_->DeleteFile(path_);
+ handler_->DeleteFile(src_);
+ }
+ }
+
+ void CopyFileProxy() {
+ if (handler_) {
+ handler_->CopyFile(src_, dest_);
}
}
void FireDeleteCompleteProxy() {
if (handler_) {
- handler_->FireDeleteComplete(path_);
+ handler_->FireDeleteComplete(src_);
+ }
+ }
+ void FireCopyCompleteProxy() {
+ if (handler_) {
+ handler_->FireCopyComplete(src_, dest_);
}
}
private:
base::WeakPtr<FilebrowseHandler> handler_;
- FilePath path_;
+ FilePath src_;
+ FilePath dest_;
friend class base::RefCountedThreadSafe<TaskProxy>;
DISALLOW_COPY_AND_ASSIGN(TaskProxy);
};
@@ -429,6 +449,8 @@ void FilebrowseHandler::RegisterMessages() {
NewCallback(this, &FilebrowseHandler::HandlePauseToggleDownload));
dom_ui_->RegisterMessageCallback("deleteFile",
NewCallback(this, &FilebrowseHandler::HandleDeleteFile));
+ dom_ui_->RegisterMessageCallback("copyFile",
+ NewCallback(this, &FilebrowseHandler::HandleCopyFile));
dom_ui_->RegisterMessageCallback("cancelDownload",
NewCallback(this, &FilebrowseHandler::HandleCancelDownload));
dom_ui_->RegisterMessageCallback("allowDownload",
@@ -446,6 +468,13 @@ void FilebrowseHandler::FireDeleteComplete(const FilePath& path) {
GetChildrenForPath(dir_path, true);
};
+void FilebrowseHandler::FireCopyComplete(const FilePath& src,
+ const FilePath& dest) {
+ // Notify the UI somehow.
+ FilePath dir_path = dest.DirName();
+ GetChildrenForPath(dir_path, true);
+};
+
void FilebrowseHandler::FireUploadComplete() {
#if defined(OS_CHROMEOS)
DictionaryValue info_value;
@@ -617,6 +646,9 @@ void FilebrowseHandler::HandlePauseToggleDownload(const ListValue* args) {
#if defined(OS_CHROMEOS)
int id;
ExtractIntegerValue(args, &id);
+ if ((id - 1) >= (int)active_download_items_.size()) {
+ return;
+ }
DownloadItem* item = active_download_items_[id];
item->TogglePause();
#endif
@@ -626,6 +658,10 @@ void FilebrowseHandler::HandleAllowDownload(const ListValue* args) {
#if defined(OS_CHROMEOS)
int id;
ExtractIntegerValue(args, &id);
+ if ((id - 1) >= (int)active_download_items_.size()) {
+ return;
+ }
+
DownloadItem* item = active_download_items_[id];
download_manager_->DangerousDownloadValidated(item);
#endif
@@ -635,9 +671,12 @@ void FilebrowseHandler::HandleCancelDownload(const ListValue* args) {
#if defined(OS_CHROMEOS)
int id;
ExtractIntegerValue(args, &id);
+ if ((id - 1) >= (int)active_download_items_.size()) {
+ return;
+ }
DownloadItem* item = active_download_items_[id];
- item->Cancel(true);
FilePath path = item->full_path();
+ item->Cancel(true);
FilePath dir_path = path.DirName();
item->Remove(true);
GetChildrenForPath(dir_path, true);
@@ -883,6 +922,21 @@ void FilebrowseHandler::DeleteFile(const FilePath& path) {
NewRunnableMethod(current_task_, &TaskProxy::FireDeleteCompleteProxy));
}
+void FilebrowseHandler::CopyFile(const FilePath& src, const FilePath& dest) {
+ if (file_util::DirectoryExists(src)) {
+ if (!file_util::CopyDirectory(src, dest, true)) {
+ LOG(ERROR) << "unable to copy directory:" << src.value();
+ }
+ } else {
+ if (!file_util::CopyFile(src, dest)) {
+ LOG(ERROR) << "unable to copy file" << src.value();
+ }
+ }
+ ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE,
+ NewRunnableMethod(current_task_, &TaskProxy::FireCopyCompleteProxy));
+}
+
void FilebrowseHandler::HandleDeleteFile(const ListValue* args) {
#if defined(OS_CHROMEOS)
std::string path = WideToUTF8(ExtractStringValue(args));
@@ -907,6 +961,35 @@ void FilebrowseHandler::HandleDeleteFile(const ListValue* args) {
#endif
}
+void FilebrowseHandler::HandleCopyFile(const ListValue* value) {
+#if defined(OS_CHROMEOS)
+ if (value && value->GetType() == Value::TYPE_LIST) {
+ const ListValue* list_value = static_cast<const ListValue*>(value);
+ std::string src;
+ std::string dest;
+
+ // Get path string.
+ if (list_value->GetString(0, &src) &&
+ list_value->GetString(1, &dest)) {
+ FilePath SrcPath = FilePath(src);
+ FilePath DestPath = FilePath(dest);
+
+ TaskProxy* task = new TaskProxy(AsWeakPtr(), SrcPath, DestPath);
+ task->AddRef();
+ current_task_ = task;
+ ChromeThread::PostTask(
+ ChromeThread::FILE, FROM_HERE,
+ NewRunnableMethod(
+ task, &TaskProxy::CopyFileProxy));
+ } else {
+ LOG(ERROR) << "Unable to get string";
+ return;
+ }
+ }
+#endif
+}
+
+
void FilebrowseHandler::OnDownloadUpdated(DownloadItem* download) {
DownloadList::iterator it = find(active_download_items_.begin(),
active_download_items_.end(),
diff --git a/chrome/browser/resources/filebrowse.html b/chrome/browser/resources/filebrowse.html
index 4588943..22879dd 100644
--- a/chrome/browser/resources/filebrowse.html
+++ b/chrome/browser/resources/filebrowse.html
@@ -29,6 +29,15 @@ div.header {
color: black;
}
+*:-khtml-drag {
+ background-color: rgba(238,238,238, 0.5);
+}
+
+*[draggable] {
+ -khtml-user-drag: element;
+ cursor: move;
+}
+
.rowlink {
height: 100%;
width: 90%;
@@ -172,7 +181,6 @@ li.filebrowserow div.icon {
}
.menuicon {
- background: url('shared/images/filebrowse_menu.png');
position: absolute;
right: 4px;
top: 5px;
@@ -186,6 +194,17 @@ li.filebrowserow div.icon {
-webkit-transition: opacity 0.2s ease-out ;
}
+.spinicon {
+ position: absolute;
+ right: 4px;
+ top: 5px;
+ height: 100%;
+ width: 15px;
+ margin-left: 0;
+ margin-top: 5px;
+ background-repeat: no-repeat;
+}
+
li.filebrowserow:hover .menuicon {
opacity: 0.75;
-webkit-transition: opacity 0.0s ease-out ;
@@ -826,6 +845,31 @@ function browseFileResult(info, results) {
}
} else if (info.functionCall == 'getChildren') {
var main = getCurrentContainer();
+ main.addEventListener('dragover', function(e) {
+ if (e.preventDefault) e.preventDefault();
+ e.dataTransfer.dropEffect = 'copy';
+ return false;
+ }, false);
+ main.addEventListener('drop', function(e) {
+ if (e.stopPropagation) e.stopPropagation();
+ var src = e.dataTransfer.getData('Text');
+ var path = getPathAndFilenameForPath(src);
+ var dest = currentSavedPath + '/' + path[2];
+ var dirId = $('list/dir/' + currentSavedPath);
+ if (dirId) {
+
+ var element = $(dest);
+ if (!element) {
+ // TODO(dhg): We probably should do some checking for
+ // existance.
+ element = createNewFakeItem(path[2], dest, false, true);
+ }
+ dirId.appendChild(element);
+ element.scrollIntoView();
+ }
+ chrome.send('copyFile', [src, dest]);
+ return false;
+ }, false);
main.id = 'dir/' + info.path;
divArray.push(main);
document.location.hash = info.path;
@@ -1026,6 +1070,7 @@ function deleteFileConfirm(path) {
no.className = 'deleteNo';
askingDiv.appendChild(yes);
askingDiv.appendChild(no);
+ yes.scrollIntoView();
var element = menus[path];
if (element) {
element.firstChild.appendChild(askingDiv);
@@ -1082,6 +1127,7 @@ function newDownload(results) {
var dirId = $('list/dir/' + extracted[1]);
if (dirId) {
element = createNewItem(extracted[2], results[x].file_path, false);
+ downloadList.push(element);
if (dirId.firstChild) {
dirId.insertBefore(element, dirId.firstChild);
} else {
@@ -1093,7 +1139,52 @@ function newDownload(results) {
}
}
+function removeDownload(element) {
+ var status = undefined;
+ var pause = undefined;
+ for (var x = 0; x < element.children.length; x++) {
+ if (element.children[x].className == 'downloadstatus') {
+ var child = element.children[x];
+ status = child;
+ } else if (element.children[x].className == 'downloadpause') {
+ var child = element.children[x];
+ pause = child;
+ }
+ }
+ if (status) {
+ element.removeChild(status);
+ }
+ if (pause) {
+ element.removeChild(pause);
+ }
+ element.className = 'filebrowserow';
+ var elementList = [];
+ for (var x = 0; x < downloadList.length; x++) {
+ if (element != downloadList[x]) {
+ elementList.push(downloadList[x]);
+ }
+ }
+ downloadList = elementList;
+}
+
function downloadUpdated(results) {
+ var removeDownloads = [];
+ for (var y = 0; y < downloadList.length; y++) {
+ var found = false;
+ for (var x = 0; x < results.length; x++) {
+ var element = $(results[x].file_path);
+ if (downloadList[y] == element) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ removeDownloads.push(downloadList[y]);
+ }
+ }
+ for (var x = 0; x < removeDownloads.length; x++) {
+ removeDownload(removeDownloads[x]);
+ }
for (var x = 0; x < results.length; x++) {
var element = $(results[x].file_path);
if (!element && results[x].state != 'CANCELLED') {
@@ -1123,6 +1214,7 @@ function downloadUpdated(results) {
}
}
if (progressDiv == null) {
+ downloadList.push(element);
element.className = 'filebrowserow downloading';
var progressDiv = document.createElement('div');
progressDiv.className = 'downloadstatus';
@@ -1162,24 +1254,7 @@ function downloadUpdated(results) {
}
} else {
- var status = undefined;
- var pause = undefined;
- for (var x = 0; x < element.children.length; x++) {
- if (element.children[x].className == 'downloadstatus') {
- var child = element.children[x];
- status = child;
- } else if (element.children[x].className == 'downloadpause') {
- var child = element.children[x];
- pause = child;
- }
- }
- if (status) {
- element.removeChild(status);
- }
- if (pause) {
- element.removeChild(pause);
- }
- element.className = 'filebrowserow';
+ removeDownload(element);
}
}
}
@@ -1320,6 +1395,7 @@ function showMenu(path) {
element.firstChild.style.display = 'block';
element.style.opacity = '1';
currentMenu = element;
+ currentMenu.scrollIntoView();
}
window.event.stopPropagation();
}
@@ -1452,8 +1528,47 @@ function getDoubleClickForItem(path, id, isDirectory) {
var elementIdCounter = 0;
+function createNewFakeItem(title, path, isDirectory, hasspinner) {
+ var element = document.createElement('li');
+
+ element.className = 'filebrowserow';
+ element.id = path;
+ elementIdCounter++;
+ var link;
+ link = document.createElement('div');
+ link.className = 'rowlink';
+
+ var icon = document.createElement('div');
+ icon.className = getClassForPath(path, isDirectory);
+ link.appendChild(icon);
+
+ var span = document.createElement('span');
+ span.className = 'name';
+ span.textContent = title;
+ link.appendChild(span);
+
+ element.appendChild(link);
+
+ // Setup Menu
+ var currentPath = currentSavedPath;
+ if (hasspinner) {
+ var spinicon = document.createElement('div');
+ spinicon.align = 'right';
+ spinicon.className = 'spinicon';
+ element.appendChild(spinicon);
+ }
+ return element;
+}
+
function createNewItem(title, path, isDirectory) {
var element = document.createElement('li');
+ element.setAttribute('draggable', 'true');
+
+ element.addEventListener('dragstart', function (e) {
+ e.dataTransfer.effectAllowed = 'copy';
+ e.dataTransfer.setData('Text', this.id);
+ }, false);
+
element.className = 'filebrowserow';
element.title = title;
/*element.id = 'listItem' + elementIdCounter;*/
@@ -1540,6 +1655,7 @@ function popout(path) {
}
function createNewList(title, results, main, path) {
+ downloadList = [];
clearChildren(main);
var mainList = document.createElement('div');
@@ -1548,6 +1664,7 @@ function createNewList(title, results, main, path) {
} else {
mainList.className = 'columnlist';
}
+
var list = document.createElement('ul');
list.className = 'filebrowselist';
list.id = 'list/dir/' + path;
diff --git a/chrome/browser/resources/mediaplayer.html b/chrome/browser/resources/mediaplayer.html
index 09f7b1e..f3aae4c 100644
--- a/chrome/browser/resources/mediaplayer.html
+++ b/chrome/browser/resources/mediaplayer.html
@@ -322,6 +322,12 @@ var localStrings;
* Window onload handler, sets up the page.
*/
function load() {
+ document.body.addEventListener('dragover', function(e) {
+ if (e.preventDefault) e.preventDefault();
+ });
+ document.body.addEventListener('drop', function(e) {
+ if (e.preventDefault) e.preventDefault();
+ });
localStrings = new LocalStrings();
chrome.send('getCurrentPlaylist', []);
}
diff --git a/chrome/browser/resources/playlist.html b/chrome/browser/resources/playlist.html
index 52aa594..598844c 100644
--- a/chrome/browser/resources/playlist.html
+++ b/chrome/browser/resources/playlist.html
@@ -76,6 +76,12 @@ function pathIsAudioFile(path) {
var currentPlaylist = null;
var currentOffset = -1;
function load() {
+ document.body.addEventListener('dragover', function(e) {
+ if (e.preventDefault) e.preventDefault();
+ });
+ document.body.addEventListener('drop', function(e) {
+ if (e.preventDefault) e.preventDefault();
+ });
chrome.send("getCurrentPlaylist", []);
};