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

Commit

Permalink
Merge pull request #4590 from sathyamoorthi/closeOthers2
Browse files Browse the repository at this point in the history
"close others" extension added to default extensions directory.
  • Loading branch information
JeffryBooher committed Oct 9, 2013
2 parents e49a849 + bd4018d commit b6e786b
Show file tree
Hide file tree
Showing 8 changed files with 343 additions and 31 deletions.
1 change: 1 addition & 0 deletions src/command/Commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ define(function (require, exports, module) {
exports.FILE_SAVE_AS = "file.saveAs"; // DocumentCommandHandlers.js handleFileSaveAs()
exports.FILE_CLOSE = "file.close"; // DocumentCommandHandlers.js handleFileClose()
exports.FILE_CLOSE_ALL = "file.close_all"; // DocumentCommandHandlers.js handleFileCloseAll()
exports.FILE_CLOSE_LIST = "file.close_list"; // DocumentCommandHandlers.js handleFileCloseList()
exports.FILE_ADD_TO_WORKING_SET = "file.addToWorkingSet"; // DocumentCommandHandlers.js handleFileAddToWorkingSet()
exports.FILE_LIVE_FILE_PREVIEW = "file.liveFilePreview"; // LiveDevelopment/main.js _handleGoLiveCommand()
exports.FILE_LIVE_HIGHLIGHT = "file.previewHighlight"; // LiveDevelopment/main.js _handlePreviewHighlightCommand()
Expand Down
79 changes: 48 additions & 31 deletions src/document/DocumentCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -715,20 +715,12 @@ define(function (require, exports, module) {
return $.Deferred().reject().promise();
}

/**
* Saves all unsaved documents. Returns a Promise that will be resolved once ALL the save
* operations have been completed. If ANY save operation fails, an error dialog is immediately
* shown and the other files wait to save until it is dismissed; after all files have been
* processed, the Promise is rejected if any ONE save operation failed.
*
* @return {$.Promise}
*/
function saveAll() {
function _saveFileList(fileList) {
// Do in serial because doSave shows error UI for each file, and we don't want to stack
// multiple dialogs on top of each other
var userCanceled = false;
return Async.doSequentially(
DocumentManager.getWorkingSet(),
fileList,
function (file) {
// Abort remaining saves if user canceled any Save dialog
if (userCanceled) {
Expand All @@ -738,11 +730,16 @@ define(function (require, exports, module) {
var doc = DocumentManager.getOpenDocumentForPath(file.fullPath);
if (doc) {
var savePromise = handleFileSave({doc: doc});
savePromise.fail(function (error) {
if (error === USER_CANCELED) {
userCanceled = true;
}
});
savePromise
.done(function (newFile) {
file.fullPath = newFile.fullPath;
file.name = newFile.name;
})
.fail(function (error) {
if (error === USER_CANCELED) {
userCanceled = true;
}
});
return savePromise;
} else {
// working set entry that was never actually opened - ignore
Expand All @@ -753,6 +750,18 @@ define(function (require, exports, module) {
);
}

/**
* Saves all unsaved documents. Returns a Promise that will be resolved once ALL the save
* operations have been completed. If ANY save operation fails, an error dialog is immediately
* shown and the other files wait to save until it is dismissed; after all files have been
* processed, the Promise is rejected if any ONE save operation failed.
*
* @return {$.Promise}
*/
function saveAll() {
return _saveFileList(DocumentManager.getWorkingSet());
}

/**
* Prompts user with save as dialog and saves document.
* @return {$.Promise} a promise that is resolved once the save has been completed
Expand Down Expand Up @@ -908,21 +917,12 @@ define(function (require, exports, module) {
}
return promise;
}

/**
* Closes all open documents; equivalent to calling handleFileClose() for each document, except
* that unsaved changes are confirmed once, in bulk.
* @param {?{promptOnly: boolean}} If true, only displays the relevant confirmation UI and does NOT
* actually close any documents. This is useful when chaining close-all together with
* other user prompts that may be cancelable.
* @return {$.Promise} a promise that is resolved when all files are closed
*/
function handleFileCloseAll(commandData) {
var result = new $.Deferred(),
promptOnly = commandData && commandData.promptOnly;

var unsavedDocs = [];
DocumentManager.getWorkingSet().forEach(function (file) {
function _doCloseDocumentList(list, promptOnly, clearCurrentDoc) {
var result = new $.Deferred(),
unsavedDocs = [];

list.forEach(function (file) {
var doc = DocumentManager.getOpenDocumentForPath(file.fullPath);
if (doc && doc.isDirty) {
unsavedDocs.push(doc);
Expand Down Expand Up @@ -985,7 +985,7 @@ define(function (require, exports, module) {
result.reject();
} else if (id === Dialogs.DIALOG_BTN_OK) {
// Save all unsaved files, then if that succeeds, close all
saveAll().done(function () {
_saveFileList(list).done(function () {
result.resolve();
}).fail(function () {
result.reject();
Expand All @@ -1002,13 +1002,29 @@ define(function (require, exports, module) {
// guarantees that handlers run in the order they are added.
result.done(function () {
if (!promptOnly) {
DocumentManager.closeAll();
DocumentManager.removeListFromWorkingSet(list, (clearCurrentDoc || true));
}
});

return result.promise();
}

/**
* Closes all open documents; equivalent to calling handleFileClose() for each document, except
* that unsaved changes are confirmed once, in bulk.
* @param {?{promptOnly: boolean}} If true, only displays the relevant confirmation UI and does NOT
* actually close any documents. This is useful when chaining close-all together with
* other user prompts that may be cancelable.
* @return {$.Promise} a promise that is resolved when all files are closed
*/
function handleFileCloseAll(commandData) {
return _doCloseDocumentList(DocumentManager.getWorkingSet(), (commandData && commandData.promptOnly));
}

function handleFileCloseList(commandData) {
return _doCloseDocumentList((commandData && commandData.documentList), false);
}

/**
* @private - tracks our closing state if we get called again
*/
Expand Down Expand Up @@ -1233,6 +1249,7 @@ define(function (require, exports, module) {

CommandManager.register(Strings.CMD_FILE_CLOSE, Commands.FILE_CLOSE, handleFileClose);
CommandManager.register(Strings.CMD_FILE_CLOSE_ALL, Commands.FILE_CLOSE_ALL, handleFileCloseAll);
CommandManager.register(Strings.CMD_FILE_CLOSE_LIST, Commands.FILE_CLOSE_LIST, handleFileCloseList);

if (brackets.platform === "win") {
CommandManager.register(Strings.CMD_EXIT, Commands.FILE_QUIT, handleFileQuit);
Expand Down
27 changes: 27 additions & 0 deletions src/document/DocumentManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,32 @@ define(function (require, exports, module) {
_clearCurrentDocument();
_removeAllFromWorkingSet();
}

function removeListFromWorkingSet(list, clearCurrentDocument) {
var fileList = [], index;

if (!list) {
return;
}

if (clearCurrentDocument) {
_clearCurrentDocument();
}

list.forEach(function (file) {
index = findInWorkingSet(file.fullPath);

if (index !== -1) {
fileList.push(_workingSet[index]);

_workingSet.splice(index, 1);
_workingSetMRUOrder.splice(findInWorkingSet(file.fullPath, _workingSetMRUOrder), 1);
_workingSetAddedOrder.splice(findInWorkingSet(file.fullPath, _workingSetAddedOrder), 1);
}
});

$(exports).triggerHandler("workingSetRemoveList", [fileList]);
}


/**
Expand Down Expand Up @@ -940,6 +966,7 @@ define(function (require, exports, module) {
exports.addToWorkingSet = addToWorkingSet;
exports.addListToWorkingSet = addListToWorkingSet;
exports.removeFromWorkingSet = removeFromWorkingSet;
exports.removeListFromWorkingSet = removeListFromWorkingSet;
exports.getNextPrevFile = getNextPrevFile;
exports.swapWorkingSetIndexes = swapWorkingSetIndexes;
exports.sortWorkingSet = sortWorkingSet;
Expand Down
83 changes: 83 additions & 0 deletions src/extensions/default/CloseOthers/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
* Copyright (c) 2013 Adobe Systems Incorporated. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/

/*jslint vars: true, plusplus: true, devel: true, nomen: true, regexp: true, indent: 4, maxerr: 50 */
/*global define, $, brackets, window, document */

define(function (require, exports, module) {
"use strict";

var Menus = brackets.getModule("command/Menus"),
CommandManager = brackets.getModule("command/CommandManager"),
Commands = brackets.getModule("command/Commands"),
dm = brackets.getModule("document/DocumentManager"),
docCH = brackets.getModule("document/DocumentCommandHandlers"),
strings = brackets.getModule("i18n!nls/strings"),
settings = JSON.parse(require("text!settings.json")),
working_set_cmenu = Menus.getContextMenu(Menus.ContextMenuIds.WORKING_SET_MENU),
close_others = "file.close_others",
close_above = "file.close_above",
close_below = "file.close_below";

function handleClose(mode) {

var targetIndex = dm.findInWorkingSet(dm.getCurrentDocument().file.fullPath),
workingSet = dm.getWorkingSet().slice(0),
start = (mode === close_below) ? (targetIndex + 1) : 0,
end = (mode === close_above) ? (targetIndex) : (workingSet.length),
docList = [],
i;

if (mode === close_others) {
end--;
workingSet.splice(targetIndex, 1);
}

for (i = start; i < end; i++) {
docList.push(workingSet[i]);
}

CommandManager.execute(Commands.FILE_CLOSE_LIST, {documentList: docList});
}

if (settings.close_below) {
CommandManager.register(strings.CMD_FILE_CLOSE_BELOW, close_below, function () {
handleClose(close_below);
});
working_set_cmenu.addMenuItem(close_below, "", Menus.AFTER, Commands.FILE_CLOSE);
}

if (settings.close_others) {
CommandManager.register(strings.CMD_FILE_CLOSE_OTHERS, close_others, function () {
handleClose(close_others);
});
working_set_cmenu.addMenuItem(close_others, "", Menus.AFTER, Commands.FILE_CLOSE);
}

if (settings.close_above) {
CommandManager.register(strings.CMD_FILE_CLOSE_ABOVE, close_above, function () {
handleClose(close_above);
});
working_set_cmenu.addMenuItem(close_above, "", Menus.AFTER, Commands.FILE_CLOSE);
}
});
5 changes: 5 additions & 0 deletions src/extensions/default/CloseOthers/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"close_others": true,
"close_above": true,
"close_below": true
}
1 change: 1 addition & 0 deletions src/extensions/default/CloseOthers/unittest-files/dummy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//This is dummy file. To commit unnittest-files folder git needs a file.
Loading

0 comments on commit b6e786b

Please sign in to comment.