Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.

Commit d169320

Browse files
committed
Merge pull request #3879 from adobe/move-to-trash
Move file or folder to the trash
2 parents c918b0b + 0a02712 commit d169320

9 files changed

Lines changed: 143 additions & 14 deletions

File tree

src/command/Commands.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ define(function (require, exports, module) {
4747
exports.FILE_LIVE_HIGHLIGHT = "file.previewHighlight";
4848
exports.FILE_PROJECT_SETTINGS = "file.projectSettings";
4949
exports.FILE_RENAME = "file.rename";
50+
exports.FILE_DELETE = "file.delete";
5051
exports.FILE_INSTALL_EXTENSION = "file.installExtension";
5152
exports.FILE_EXTENSION_MANAGER = "file.extensionManager";
5253
exports.FILE_QUIT = "file.quit"; // string must MATCH string in native code (brackets_extensions)

src/command/DefaultMenus.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ define(function (require, exports, module) {
181181
project_cmenu.addMenuItem(Commands.FILE_NEW);
182182
project_cmenu.addMenuItem(Commands.FILE_NEW_FOLDER);
183183
project_cmenu.addMenuItem(Commands.FILE_RENAME);
184+
project_cmenu.addMenuItem(Commands.FILE_DELETE);
184185
project_cmenu.addMenuItem(Commands.NAVIGATE_SHOW_IN_OS);
185186
project_cmenu.addMenuDivider();
186187
project_cmenu.addMenuItem(Commands.EDIT_FIND_IN_SUBTREE);

src/document/DocumentCommandHandlers.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,11 @@ define(function (require, exports, module) {
845845
ProjectManager.showInTree(DocumentManager.getCurrentDocument().file);
846846
}
847847

848+
function handleFileDelete() {
849+
var entry = ProjectManager.getSelectedItem();
850+
ProjectManager.deleteItem(entry);
851+
}
852+
848853
/** Show the selected sidebar (tree or working set) item in Finder/Explorer */
849854
function handleShowInOS() {
850855
var entry = ProjectManager.getSelectedItem();
@@ -857,7 +862,6 @@ define(function (require, exports, module) {
857862
}
858863
}
859864

860-
861865
// Init DOM elements
862866
AppInit.htmlReady(function () {
863867
var $titleContainerToolbar = $("#titlebar");
@@ -878,6 +882,7 @@ define(function (require, exports, module) {
878882
CommandManager.register(Strings.CMD_FILE_SAVE, Commands.FILE_SAVE, handleFileSave);
879883
CommandManager.register(Strings.CMD_FILE_SAVE_ALL, Commands.FILE_SAVE_ALL, handleFileSaveAll);
880884
CommandManager.register(Strings.CMD_FILE_RENAME, Commands.FILE_RENAME, handleFileRename);
885+
CommandManager.register(Strings.CMD_FILE_DELETE, Commands.FILE_DELETE, handleFileDelete);
881886

882887
CommandManager.register(Strings.CMD_FILE_CLOSE, Commands.FILE_CLOSE, handleFileClose);
883888
CommandManager.register(Strings.CMD_FILE_CLOSE_ALL, Commands.FILE_CLOSE_ALL, handleFileCloseAll);

src/document/DocumentManager.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
*
7777
* - fileNameChange -- When the name of a file or folder has changed. The 2nd arg is the old name.
7878
* The 3rd arg is the new name.
79+
* - pathDeleted -- When a file or folder has been deleted. The 2nd arg is the path that was deleted.
7980
*
8081
* These are jQuery events, so to listen for them you do something like this:
8182
* $(DocumentManager).on("eventname", handler);
@@ -478,8 +479,9 @@ define(function (require, exports, module) {
478479
* This is a subset of notifyFileDeleted(). Use this for the user-facing Close command.
479480
*
480481
* @param {!FileEntry} file
482+
* @param {boolean} skipAutoSelect - if true, don't automatically open and select the next document
481483
*/
482-
function closeFullEditor(file) {
484+
function closeFullEditor(file, skipAutoSelect) {
483485
// If this was the current document shown in the editor UI, we're going to switch to a
484486
// different document (or none if working set has no other options)
485487
if (_currentDocument && _currentDocument.file.fullPath === file.fullPath) {
@@ -491,7 +493,7 @@ define(function (require, exports, module) {
491493
}
492494

493495
// Switch editor to next document (or blank it out)
494-
if (nextFile) {
496+
if (nextFile && !skipAutoSelect) {
495497
CommandManager.execute(Commands.FILE_OPEN, { fullPath: nextFile.fullPath })
496498
.done(function () {
497499
// (Now we're guaranteed that the current document is not the one we're closing)
@@ -1063,10 +1065,11 @@ define(function (require, exports, module) {
10631065
* sort of "project file model," making this just a private event handler.
10641066
*
10651067
* @param {!FileEntry} file
1068+
* @param {boolean} skipAutoSelect - if true, don't automatically open/select the next document
10661069
*/
1067-
function notifyFileDeleted(file) {
1070+
function notifyFileDeleted(file, skipAutoSelect) {
10681071
// First ensure it's not currentDocument, and remove from working set
1069-
closeFullEditor(file);
1072+
closeFullEditor(file, skipAutoSelect);
10701073

10711074
// Notify all other editors to close as well
10721075
var doc = getOpenDocumentForPath(file.fullPath);
@@ -1211,6 +1214,27 @@ define(function (require, exports, module) {
12111214
$(exports).triggerHandler("fileNameChange", [oldName, newName]);
12121215
}
12131216

1217+
/**
1218+
* Called after a file or folder has been deleted. This function is responsible
1219+
* for updating underlying model data and notifying all views of the change.
1220+
*
1221+
* @param {string} path The path of the file/folder that has been deleted
1222+
*/
1223+
function notifyPathDeleted(path) {
1224+
var i, docPath;
1225+
1226+
for (docPath in _openDocuments) {
1227+
if (FileUtils.isAffectedWhenRenaming(docPath, path)) {
1228+
// This will close the doc and remove from the working set
1229+
notifyFileDeleted(new NativeFileSystem.FileEntry(docPath), true);
1230+
delete _openDocuments[docPath];
1231+
}
1232+
}
1233+
1234+
// Send a "pathDeleted" event. This will trigger the views to update.
1235+
$(exports).triggerHandler("pathDeleted", path);
1236+
}
1237+
12141238
/**
12151239
* @private
12161240
* Update document
@@ -1262,6 +1286,7 @@ define(function (require, exports, module) {
12621286
exports.closeAll = closeAll;
12631287
exports.notifyFileDeleted = notifyFileDeleted;
12641288
exports.notifyPathNameChanged = notifyPathNameChanged;
1289+
exports.notifyPathDeleted = notifyPathDeleted;
12651290

12661291
// Setup preferences
12671292
_prefs = PreferencesManager.getPreferenceStorage(module);

src/file/NativeFileSystem.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,13 +365,19 @@ define(function (require, exports, module) {
365365
};
366366

367367
/**
368-
* Deletes a file or directory
368+
* Deletes a file or directory by moving to the trash/recycle bin.
369369
* @param {function()} successCallback Callback function for successful operations
370370
* @param {function(DOMError)=} errorCallback Callback function for error operations
371371
*/
372372
NativeFileSystem.Entry.prototype.remove = function (successCallback, errorCallback) {
373-
// TODO (issue #241)
374-
// http://www.w3.org/TR/2011/WD-file-system-api-20110419/#widl-Entry-remove
373+
var deleteFunc = brackets.fs.moveToTrash || brackets.fs.unlink;
374+
deleteFunc(this.fullPath, function (err) {
375+
if (err === brackets.fs.NO_ERROR) {
376+
successCallback();
377+
} else {
378+
errorCallback(err);
379+
}
380+
});
375381
};
376382

377383
/**

src/nls/root/strings.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ define({
3636
"NOT_READABLE_ERR" : "The file could not be read.",
3737
"NO_MODIFICATION_ALLOWED_ERR" : "The target directory cannot be modified.",
3838
"NO_MODIFICATION_ALLOWED_ERR_FILE" : "The permissions do not allow you to make modifications.",
39-
"FILE_EXISTS_ERR" : "The file already exists.",
39+
"FILE_EXISTS_ERR" : "The file or directory already exists.",
4040

4141
// Project error strings
4242
"ERROR_LOADING_PROJECT" : "Error loading project",
@@ -53,6 +53,8 @@ define({
5353
"ERROR_SAVING_FILE" : "An error occurred when trying to save the file <span class='dialog-filename'>{0}</span>. {1}",
5454
"ERROR_RENAMING_FILE_TITLE" : "Error renaming file",
5555
"ERROR_RENAMING_FILE" : "An error occurred when trying to rename the file <span class='dialog-filename'>{0}</span>. {1}",
56+
"ERROR_DELETING_FILE_TITLE" : "Error deleting file",
57+
"ERROR_DELETING_FILE" : "An error occurred when trying to delete the file <span class='dialog-filename'>{0}</span>. {1}",
5658
"INVALID_FILENAME_TITLE" : "Invalid file name",
5759
"INVALID_FILENAME_MESSAGE" : "Filenames cannot contain the following characters: /?*:;{}<>\\|",
5860
"FILE_ALREADY_EXISTS" : "The file <span class='dialog-filename'>{0}</span> already exists.",
@@ -177,6 +179,7 @@ define({
177179
"CMD_LIVE_HIGHLIGHT" : "Live Highlight",
178180
"CMD_PROJECT_SETTINGS" : "Project Settings\u2026",
179181
"CMD_FILE_RENAME" : "Rename",
182+
"CMD_FILE_DELETE" : "Delete",
180183
"CMD_INSTALL_EXTENSION" : "Install Extension\u2026",
181184
"CMD_EXTENSION_MANAGER" : "Extension Manager\u2026",
182185
"CMD_QUIT" : "Quit",

src/project/ProjectManager.js

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1299,7 +1299,7 @@ define(function (require, exports, module) {
12991299

13001300
result.resolve();
13011301
} else {
1302-
// Show and error alert
1302+
// Show an error alert
13031303
Dialogs.showModalDialog(
13041304
Dialogs.DIALOG_ID_ERROR,
13051305
Strings.ERROR_RENAMING_FILE_TITLE,
@@ -1383,6 +1383,62 @@ define(function (require, exports, module) {
13831383
});
13841384
// No fail handler: silently no-op if file doesn't exist in tree
13851385
}
1386+
1387+
/**
1388+
* Delete file or directore from project
1389+
* @param {!Entry} entry FileEntry or DirectoryEntry to delete
1390+
*/
1391+
function deleteItem(entry) {
1392+
var result = new $.Deferred();
1393+
1394+
entry.remove(function () {
1395+
_findTreeNode(entry).done(function ($node) {
1396+
_projectTree.one("delete_node.jstree", function () {
1397+
// When a node is deleted, the previous node is automatically selected.
1398+
// This works fine as long as the previous node is a file, but doesn't
1399+
// work so well if the node is a folder
1400+
var sel = _projectTree.jstree("get_selected"),
1401+
entry = sel ? sel.data("entry") : null;
1402+
1403+
if (entry && entry.isDirectory) {
1404+
// Make sure it didn't turn into a leaf node. This happens if
1405+
// the only file in the directory was deleted
1406+
if (sel.hasClass("jstree-leaf")) {
1407+
sel.removeClass("jstree-leaf jstree-open");
1408+
sel.addClass("jstree-closed");
1409+
}
1410+
}
1411+
});
1412+
var oldSuppressToggleOpen = suppressToggleOpen;
1413+
suppressToggleOpen = true;
1414+
_projectTree.jstree("delete_node", $node);
1415+
suppressToggleOpen = oldSuppressToggleOpen;
1416+
});
1417+
1418+
// Notify that one of the project files has changed
1419+
$(exports).triggerHandler("projectFilesChange");
1420+
1421+
DocumentManager.notifyPathDeleted(entry.fullPath);
1422+
1423+
_redraw(true);
1424+
result.promise();
1425+
}, function (err) {
1426+
// Show an error alert
1427+
Dialogs.showModalDialog(
1428+
Dialogs.DIALOG_ID_ERROR,
1429+
Strings.ERROR_DELETING_FILE_TITLE,
1430+
StringUtils.format(
1431+
Strings.ERROR_DELETING_FILE,
1432+
StringUtils.htmlEscape(entry.fullPath),
1433+
FileUtils.getFileErrorString(err)
1434+
)
1435+
);
1436+
1437+
result.reject(err);
1438+
});
1439+
1440+
return result;
1441+
}
13861442

13871443
/**
13881444
* Forces createNewItem() to complete by removing focus from the rename field which causes
@@ -1448,6 +1504,7 @@ define(function (require, exports, module) {
14481504
exports.updateWelcomeProjectPath = updateWelcomeProjectPath;
14491505
exports.createNewItem = createNewItem;
14501506
exports.renameItemInline = renameItemInline;
1507+
exports.deleteItem = deleteItem;
14511508
exports.forceFinishRename = forceFinishRename;
14521509
exports.showInTree = showInTree;
14531510
});

src/project/WorkingSetView.js

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -385,14 +385,16 @@ define(function (require, exports, module) {
385385
* Deletes all the list items in the view and rebuilds them from the working set model
386386
* @private
387387
*/
388-
function _rebuildWorkingSet() {
388+
function _rebuildWorkingSet(forceRedraw) {
389389
$openFilesContainer.find("ul").empty();
390390

391391
DocumentManager.getWorkingSet().forEach(function (file) {
392392
_createNewListItem(file);
393393
});
394394

395-
_redraw();
395+
if (forceRedraw) {
396+
_redraw();
397+
}
396398
}
397399

398400
/**
@@ -524,7 +526,7 @@ define(function (require, exports, module) {
524526
* @private
525527
*/
526528
function _handleWorkingSetSort() {
527-
_rebuildWorkingSet();
529+
_rebuildWorkingSet(true);
528530
_scrollSelectedDocIntoView();
529531
}
530532

@@ -550,7 +552,18 @@ define(function (require, exports, module) {
550552
// Rebuild the working set if any file or folder name changed.
551553
// We could be smarter about this and only update the
552554
// nodes that changed, if needed...
553-
_rebuildWorkingSet();
555+
_rebuildWorkingSet(true);
556+
}
557+
558+
/**
559+
* @private
560+
* @param {string} path
561+
*/
562+
function _handlePathDeleted(path) {
563+
// Rebuild the working set if any file or folder was deleted.
564+
// We could be smarter about this and only delete affected
565+
// items.
566+
_rebuildWorkingSet(false);
554567
}
555568

556569
function refresh() {
@@ -592,6 +605,10 @@ define(function (require, exports, module) {
592605
_handleFileNameChanged(oldName, newName);
593606
});
594607

608+
$(DocumentManager).on("pathDeleted", function (event, path) {
609+
_handlePathDeleted(path);
610+
});
611+
595612
$(FileViewController).on("documentSelectionFocusChange fileViewFocusChange", _handleDocumentSelectionChange);
596613

597614
// Show scroller shadows when open-files-container scrolls

src/search/FindInFiles.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ define(function (require, exports, module) {
5151
DocumentManager = require("document/DocumentManager"),
5252
EditorManager = require("editor/EditorManager"),
5353
FileIndexManager = require("project/FileIndexManager"),
54+
FileUtils = require("file/FileUtils"),
5455
KeyEvent = require("utils/KeyEvent"),
5556
AppInit = require("utils/AppInit"),
5657
StatusBar = require("widgets/StatusBar"),
@@ -455,8 +456,21 @@ define(function (require, exports, module) {
455456
_showSearchResults(searchResults, currentQuery, currentScope);
456457
}
457458
}
459+
460+
function _pathDeletedHandler(event, path) {
461+
if ($searchResultsDiv.is(":visible")) {
462+
// Update the search results
463+
searchResults.forEach(function (item, idx) {
464+
if (FileUtils.isAffectedWhenRenaming(item.fullPath, path)) {
465+
searchResults.splice(idx, 1);
466+
}
467+
});
468+
_showSearchResults(searchResults, currentQuery, currentScope);
469+
}
470+
}
458471

459472
$(DocumentManager).on("fileNameChange", _fileNameChangeHandler);
473+
$(DocumentManager).on("pathDeleted", _pathDeletedHandler);
460474
$(ProjectManager).on("beforeProjectClose", _hideSearchResults);
461475

462476
CommandManager.register(Strings.CMD_FIND_IN_FILES, Commands.EDIT_FIND_IN_FILES, doFindInFiles);

0 commit comments

Comments
 (0)