diff --git a/src/project/FileViewController.js b/src/project/FileViewController.js index e4fa0dac653..243cfd79f88 100644 --- a/src/project/FileViewController.js +++ b/src/project/FileViewController.js @@ -142,7 +142,8 @@ define(function (require, exports, module) { * @return {$.Promise} */ function openAndSelectDocument(fullPath, fileSelectionFocus, paneId) { - var result; + var result, + curDocChangedDueToMe = _curDocChangedDueToMe; if (fileSelectionFocus !== PROJECT_MANAGER && fileSelectionFocus !== WORKING_SET_VIEW) { console.error("Bad parameter passed to FileViewController.openAndSelectDocument"); @@ -172,7 +173,7 @@ define(function (require, exports, module) { // clear after notification is done result.always(function () { - _curDocChangedDueToMe = false; + _curDocChangedDueToMe = curDocChangedDueToMe; }); return result; @@ -199,6 +200,9 @@ define(function (require, exports, module) { // image file, we get a null doc here but we still want to keep _fileSelectionFocus // as PROJECT_MANAGER. Regardless of doc is null or not, call _activatePane // to trigger documentSelectionFocusChange event. + _fileSelectionFocus = WORKING_SET_VIEW; + _activatePane(paneId); + result.resolve(file); }).fail(function (err) { result.reject(err); diff --git a/src/project/WorkingSetView.js b/src/project/WorkingSetView.js index 4b99203fa86..67b32c537ee 100644 --- a/src/project/WorkingSetView.js +++ b/src/project/WorkingSetView.js @@ -272,7 +272,7 @@ define(function (require, exports, module) { WorkingSetView.prototype._checkForDuplicatesInWorkingTree = function () { var self = this, map = {}, - fileList = MainViewManager.getWorkingSet(this.paneId); + fileList = MainViewManager.getWorkingSet(MainViewManager.ALL_PANES); // We need to always clear current directories as files could be removed from working tree. this.$openFilesContainer.find("ul > li > a > span.directory").remove(); @@ -301,14 +301,7 @@ define(function (require, exports, module) { * @private */ WorkingSetView.prototype._redraw = function () { - var paneId = MainViewManager.getActivePaneId(); - - if (paneId === this.paneId) { - this.$el.addClass("active"); - } else { - this.$el.removeClass("active"); - } - + this._updateViewState(); this._updateVisibility(); this._adjustForScrollbars(); this._fireSelectionChanged(); @@ -622,13 +615,32 @@ define(function (require, exports, module) { } }; + /** + * Updates the pane view's selection state + * @private + */ + WorkingSetView.prototype._updateViewState = function () { + var paneId = MainViewManager.getActivePaneId(); + if ((FileViewController.getFileSelectionFocus() === FileViewController.WORKING_SET_VIEW) && + (paneId === this.paneId)) { + this.$el.addClass("active"); + this.$openFilesContainer.addClass("active"); + } else { + this.$el.removeClass("active"); + this.$openFilesContainer.removeClass("active"); + } + }; + /** * Updates the pane view's selection marker and scrolls the item into view * @private */ WorkingSetView.prototype._updateListSelection = function () { var file = MainViewManager.getCurrentlyViewedFile(this.paneId); - + + this._updateViewState(); + + // Iterate through working set list and update the selection on each this.$openFilesContainer.find("ul").children().each(function () { _updateListItemSelection(this, file); @@ -650,6 +662,8 @@ define(function (require, exports, module) { WorkingSetView.prototype._handleFileAdded = function (e, fileAdded, index, paneId) { if (paneId === this.paneId) { this._rebuildViewList(true); + } else { + this._checkForDuplicatesInWorkingTree(); } }; @@ -663,6 +677,8 @@ define(function (require, exports, module) { WorkingSetView.prototype._handleFileListAdded = function (e, files, paneId) { if (paneId === this.paneId) { this._rebuildViewList(true); + } else { + this._checkForDuplicatesInWorkingTree(); } }; @@ -675,21 +691,38 @@ define(function (require, exports, module) { * @param {!string} paneId - the id of the pane the item that was to */ WorkingSetView.prototype._handleFileRemoved = function (e, file, suppressRedraw, paneId) { - if (paneId === this.paneId && !suppressRedraw) { - var $listItem = this._findListItemFromFile(file); - if ($listItem) { - // Make the next file in the list show the close icon, - // without having to move the mouse, if there is a next file. - var $nextListItem = $listItem.next(); - if ($nextListItem && $nextListItem.length > 0) { - var canClose = ($listItem.find(".can-close").length === 1); - var isDirty = _isOpenAndDirty($nextListItem.data(_FILE_KEY)); - this._updateFileStatusIcon($nextListItem, isDirty, canClose); + /* + * The suppressRedraw flag is used in cases when we are replacing the working + * set entry with another one. There are only 2 use cases for this: + * + * 1) When an untitled document is being saved. + * 2) When a file is saved with a new name. + */ + if (paneId === this.paneId) { + if (!suppressRedraw) { + var $listItem = this._findListItemFromFile(file); + if ($listItem) { + // Make the next file in the list show the close icon, + // without having to move the mouse, if there is a next file. + var $nextListItem = $listItem.next(); + if ($nextListItem && $nextListItem.length > 0) { + var canClose = ($listItem.find(".can-close").length === 1); + var isDirty = _isOpenAndDirty($nextListItem.data(_FILE_KEY)); + this._updateFileStatusIcon($nextListItem, isDirty, canClose); + } + $listItem.remove(); } - $listItem.remove(); + + this._redraw(); } - - this._redraw(); + } else { + /* + * When this event is handled by a pane that is not being updated then + * the suppressRedraw flag does not need to be respected. + * _checkForDuplicatesInWorkingTree() does not remove any entries so it's + * safe to call at any time. + */ + this._checkForDuplicatesInWorkingTree(); } }; @@ -711,6 +744,8 @@ define(function (require, exports, module) { }); this._redraw(); + } else { + this._checkForDuplicatesInWorkingTree(); } }; @@ -749,6 +784,8 @@ define(function (require, exports, module) { WorkingSetView.prototype._handleWorkingSetUpdate = function (e, paneId) { if (this.paneId === paneId) { this._rebuildViewList(true); + } else { + this._checkForDuplicatesInWorkingTree(); } }; diff --git a/src/styles/brackets.less b/src/styles/brackets.less index 3c428581149..bba18f667a0 100644 --- a/src/styles/brackets.less +++ b/src/styles/brackets.less @@ -769,11 +769,12 @@ a, img { min-height: 18px; vertical-align: baseline; - &.selected { - a, - .extension { - color: #99dbff; - } + &.selected a { + color: @open-working-file-name-highlight; + } + + &.selected .extension { + color: @open-working-file-ext-highlight; } } @@ -805,18 +806,7 @@ a, img { } } -.open-files-container.active { - li { - &.selected a { - color: @open-working-file-name-highlight; - } - - &.selected .extension { - color: @open-working-file-ext-highlight; - } - } -} .sidebar-selection { background: @bc-sidebar-selection; diff --git a/src/view/MainViewManager.js b/src/view/MainViewManager.js index bf811ab9a93..deb9c13b884 100644 --- a/src/view/MainViewManager.js +++ b/src/view/MainViewManager.js @@ -94,7 +94,7 @@ define(function (require, exports, module) { ViewUtils = require("utils/ViewUtils"), Resizer = require("utils/Resizer"), Pane = require("view/Pane").Pane; - + /** * Preference setting name for the MainView Saved State * @const @@ -949,6 +949,16 @@ define(function (require, exports, module) { }); } + /** + * Updates the header text for all panes + */ + function _updatePaneHeaders() { + _forEachPaneOrPanes(ALL_PANES, function (pane) { + pane.updateHeaderText(); + }); + + } + /** * Creates a pane for paneId if one doesn't already exist * @param {!string} paneId - id of the pane to create @@ -969,9 +979,11 @@ define(function (require, exports, module) { }); $(pane).on("viewListChange.mainview", function () { + _updatePaneHeaders(); $(exports).triggerHandler("workingSetUpdate", [pane.id]); }); $(pane).on("currentViewChange.mainview", function (e, newView, oldView) { + _updatePaneHeaders(); if (_activePaneId === pane.id) { $(exports).triggerHandler("currentFileChange", [newView && newView.getFile(), @@ -1502,7 +1514,7 @@ define(function (require, exports, module) { return result; } - /** + /** * Setup a ready event to initialize ourself */ AppInit.htmlReady(function () { diff --git a/src/view/Pane.js b/src/view/Pane.js index ba4ec08bce6..466c35edcb2 100644 --- a/src/view/Pane.js +++ b/src/view/Pane.js @@ -161,6 +161,7 @@ define(function (require, exports, module) { Commands = require("command/Commands"), Strings = require("strings"), ViewUtils = require("utils/ViewUtils"), + ProjectManager = require("project/ProjectManager"), paneTemplate = require("text!htmlContent/pane.html"); @@ -237,12 +238,17 @@ define(function (require, exports, module) { } }); - this._updateHeaderText(); + this.updateHeaderText(); // Listen to document events so we can update ourself $(DocumentManager).on(this._makeEventName("fileNameChange"), _.bind(this._handleFileNameChange, this)); $(DocumentManager).on(this._makeEventName("pathDeleted"), _.bind(this._handleFileDeleted, this)); $(MainViewManager).on(this._makeEventName("activePaneChange"), _.bind(this._handleActivePaneChange, this)); + $(MainViewManager).on(this._makeEventName("workingSetAdd"), _.bind(this.updateHeaderText, this)); + $(MainViewManager).on(this._makeEventName("workingSetRemove"), _.bind(this.updateHeaderText, this)); + $(MainViewManager).on(this._makeEventName("workingSetAddList"), _.bind(this.updateHeaderText, this)); + $(MainViewManager).on(this._makeEventName("workingSetRemoveList"), _.bind(this.updateHeaderText, this)); + } /** @@ -619,8 +625,13 @@ define(function (require, exports, module) { return uniqueFileList; }; + /** + * Dispatches a currentViewChange event + * @param {?View} newView - the view become the current view + * @param {?View} oldView - the view being replaced + */ Pane.prototype._notifyCurrentViewChange = function (newView, oldView) { - this._updateHeaderText(); + this.updateHeaderText(); $(this).triggerHandler("currentViewChange", [newView, oldView]); }; @@ -741,10 +752,21 @@ define(function (require, exports, module) { * Updates text in pane header * @private */ - Pane.prototype._updateHeaderText = function () { - var file = this.getCurrentlyViewedFile(); + Pane.prototype.updateHeaderText = function () { + var file = this.getCurrentlyViewedFile(), + files, + displayName; + if (file) { - this.$header.text(file.name); + files = MainViewManager.getAllOpenFiles().filter(function (item) { + return (item.name === file.name); + }); + if (files.length < 2) { + this.$header.text(file.name); + } else { + displayName = ProjectManager.makeProjectRelativeIfPossible(file.fullPath); + this.$header.text(displayName); + } } else { this.$header.html(Strings.EMPTY_VIEW_HEADER); } @@ -773,7 +795,7 @@ define(function (require, exports, module) { delete this._views[oldname]; } - this._updateHeaderText(); + this.updateHeaderText(); // dispatch the change event if (dispatchEvent) {