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 #1823 from adobe/pflynn/show-in-tree
Browse files Browse the repository at this point in the history
"Show in Tree" command
  • Loading branch information
redmunds committed Oct 12, 2012
2 parents 0f7bce3 + 1a33aa5 commit b1d87a6
Show file tree
Hide file tree
Showing 7 changed files with 141 additions and 11 deletions.
1 change: 1 addition & 0 deletions src/command/Commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ define(function (require, exports, module) {
// Navigate
exports.NAVIGATE_NEXT_DOC = "navigate.nextDoc";
exports.NAVIGATE_PREV_DOC = "navigate.prevDoc";
exports.NAVIGATE_SHOW_IN_FILE_TREE = "navigate.showInFileTree";
exports.NAVIGATE_QUICK_OPEN = "navigate.quickOpen";
exports.NAVIGATE_GOTO_DEFINITION = "navigate.gotoDefinition";
exports.NAVIGATE_GOTO_LINE = "navigate.gotoLine";
Expand Down
2 changes: 2 additions & 0 deletions src/command/Menus.js
Original file line number Diff line number Diff line change
Expand Up @@ -923,6 +923,8 @@ define(function (require, exports, module) {
menu.addMenuItem(Commands.NAVIGATE_PREV_DOC, [{key: "Ctrl-Shift-Tab", platform: "win"},
{key: "Ctrl-Shift-Tab", platform: "mac"}]);
menu.addMenuDivider();
menu.addMenuItem(Commands.NAVIGATE_SHOW_IN_FILE_TREE);
menu.addMenuDivider();
menu.addMenuItem(Commands.TOGGLE_QUICK_EDIT, "Ctrl-E");
menu.addMenuItem(Commands.QUICK_EDIT_PREV_MATCH, {key: "Alt-Up", displayKey: "Alt-\u2191"});
menu.addMenuItem(Commands.QUICK_EDIT_NEXT_MATCH, {key: "Alt-Down", displayKey: "Alt-\u2193"});
Expand Down
12 changes: 9 additions & 3 deletions src/document/DocumentCommandHandlers.js
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,10 @@ define(function (require, exports, module) {
goNextPrevDoc(-1);
}

function handleShowInTree() {
ProjectManager.showInTree(DocumentManager.getCurrentDocument().file);
}


function init($titleContainerToolbar) {
_$titleContainerToolbar = $titleContainerToolbar;
Expand All @@ -828,16 +832,18 @@ define(function (require, exports, module) {
CommandManager.register(Strings.CMD_FILE_NEW_FOLDER, Commands.FILE_NEW_FOLDER, handleNewFolderInProject);
CommandManager.register(Strings.CMD_FILE_SAVE, Commands.FILE_SAVE, handleFileSave);
CommandManager.register(Strings.CMD_FILE_SAVE_ALL, Commands.FILE_SAVE_ALL, handleFileSaveAll);

CommandManager.register(Strings.CMD_FILE_RENAME, Commands.FILE_RENAME, handleFileRename);

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_RENAME, Commands.FILE_RENAME, handleFileRename);
CommandManager.register(Strings.CMD_CLOSE_WINDOW, Commands.FILE_CLOSE_WINDOW, handleFileCloseWindow);
CommandManager.register(Strings.CMD_QUIT, Commands.FILE_QUIT, handleFileQuit);
CommandManager.register(Strings.CMD_REFRESH_WINDOW, Commands.DEBUG_REFRESH_WINDOW, handleFileReload);
CommandManager.register(Strings.CMD_ABORT_QUIT, Commands.APP_ABORT_QUIT, _handleAbortQuit);

CommandManager.register(Strings.CMD_NEXT_DOC, Commands.NAVIGATE_NEXT_DOC, handleGoNextDoc);
CommandManager.register(Strings.CMD_PREV_DOC, Commands.NAVIGATE_PREV_DOC, handleGoPrevDoc);
CommandManager.register(Strings.CMD_ABORT_QUIT, Commands.APP_ABORT_QUIT, _handleAbortQuit);
CommandManager.register(Strings.CMD_SHOW_IN_TREE, Commands.NAVIGATE_SHOW_IN_FILE_TREE, handleShowInTree);

// Listen for changes that require updating the editor titlebar
$(DocumentManager).on("dirtyFlagChange", handleDirtyChange);
Expand Down
11 changes: 4 additions & 7 deletions src/document/DocumentManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ define(function (require, exports, module) {
FileUtils = require("file/FileUtils"),
CommandManager = require("command/CommandManager"),
Async = require("utils/Async"),
CollectionUtils = require("utils/CollectionUtils"),
PerfUtils = require("utils/PerfUtils"),
Commands = require("command/Commands");

Expand Down Expand Up @@ -171,13 +172,9 @@ define(function (require, exports, module) {
function findInWorkingSet(fullPath, list) {
list = list || _workingSet;

var ret = -1;
var found = list.some(function findByPath(file, i) {
ret = i;
return file.fullPath === fullPath;
});

return (found ? ret : -1);
return CollectionUtils.indexOf(list, function (file, i) {
return file.fullPath === fullPath;
});
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/nls/root/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ define({
"CMD_QUICK_EDIT_NEXT_MATCH" : "Next Match",
"CMD_NEXT_DOC" : "Next Document",
"CMD_PREV_DOC" : "Previous Document",
"CMD_SHOW_IN_TREE" : "Show in File Tree",

// Debug menu commands
"DEBUG_MENU" : "Debug",
Expand Down
73 changes: 72 additions & 1 deletion src/project/ProjectManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ define(function (require, exports, module) {
FileViewController = require("project/FileViewController"),
PerfUtils = require("utils/PerfUtils"),
ViewUtils = require("utils/ViewUtils"),
CollectionUtils = require("utils/CollectionUtils"),
FileUtils = require("file/FileUtils"),
Urls = require("i18n!nls/urls"),
KeyEvent = require("utils/KeyEvent");
Expand Down Expand Up @@ -763,7 +764,76 @@ define(function (require, exports, module) {

return result.promise();
}



/**
* Returns the tree node corresponding to the given file/folder. Returns null if the path lies
* outside the project, or if it doesn't exist.
*
* @param {!Entry} entry FileEntry of DirectoryEntry to show
* @return {$.Promise} Resolved with jQ obj for the jsTree tree node; or rejected if not found
*/
function _findTreeNode(entry) {
var result = new $.Deferred();

// If path not within project, ignore
var projRelativePath = makeProjectRelativeIfPossible(entry.fullPath);
if (projRelativePath === entry.fullPath) {
return result.reject().promise();
}

var treeAPI = $.jstree._reference(_projectTree);

// We're going to traverse from root of tree, one segment at a time
var pathSegments = projRelativePath.split("/");

function findInSubtree($nodes, segmentI) {
var seg = pathSegments[segmentI];
var match = CollectionUtils.indexOf($nodes, function (node, i) {
var nodeName = $(node).data("entry").name;
return nodeName === seg;
});

if (match === -1) {
result.reject(); // path doesn't exist
} else {
var $node = $nodes.eq(match);
if (segmentI === pathSegments.length - 1) {
result.resolve($node); // done searching!
} else {
// Search next level down
var subChildren = treeAPI._get_children($node);
if (subChildren.length > 0) {
findInSubtree(subChildren, segmentI + 1);
} else {
// Subtree not loaded yet: force async load & try again
treeAPI.load_node($node, function (data) {
subChildren = treeAPI._get_children($node);
findInSubtree(subChildren, segmentI + 1);
}, function (err) {
result.reject(); // includes case where folder is empty
});
}
}
}
}

// Begin searching from root
var topLevelNodes = treeAPI._get_children(-1); // -1 means top level in jsTree-ese
findInSubtree(topLevelNodes, 0);

return result.promise();
}

function showInTree(fileEntry) {
_findTreeNode(fileEntry)
.done(function ($node) {
// jsTree will automatically expand parent nodes to ensure visible
_projectTree.jstree("select_node", $node, false);
});
}


/**
* Open a new project. Currently, Brackets must always have a project open, so
* this method handles both closing the current project and opening a new project.
Expand Down Expand Up @@ -1192,4 +1262,5 @@ define(function (require, exports, module) {
exports.createNewItem = createNewItem;
exports.renameSelectedItem = renameSelectedItem;
exports.forceFinishRename = forceFinishRename;
exports.showInTree = showInTree;
});
52 changes: 52 additions & 0 deletions src/utils/CollectionUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (c) 2012 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, $ */

/**
* Utilities functions related to data collections (arrays & maps)
*/
define(function (require, exports, module) {
"use strict";

/**
* Returns the first index in 'array' for which isMatch() returns true, or -1 if none
* @param {!Array.<*>|jQueryObject} array
* @param {!function(*, Number):boolean} isMatch Passed (item, index), same as with forEach()
*/
function indexOf(array, isMatch) {
// Old-fashioned loop, instead of Array.some, to support jQuery "arrays"
var i;
for (i = 0; i < array.length; i++) {
if (isMatch(array[i], i)) {
return i;
}
}
return -1;
}


// Define public API
exports.indexOf = indexOf;
});

0 comments on commit b1d87a6

Please sign in to comment.