@@ -95,9 +95,13 @@ define(function (require, exports, module) {
9595 }
9696 }
9797
98- function handleCurrentDocumentChange ( ) {
98+ function updateDocumentTitle ( ) {
9999 var newDocument = DocumentManager . getCurrentDocument ( ) ;
100- var perfTimerName = PerfUtils . markStart ( "DocumentCommandHandlers._onCurrentDocumentChange():\t" + ( ! newDocument || newDocument . file . fullPath ) ) ;
100+
101+ // TODO: This timer is causing a "Recursive tests with the same name are not supporte"
102+ // exception. This code should be removed (if not needed), or updated with a unique
103+ // timer name (if needed).
104+ // var perfTimerName = PerfUtils.markStart("DocumentCommandHandlers._onCurrentDocumentChange():\t" + (!newDocument || newDocument.file.fullPath));
101105
102106 if ( newDocument ) {
103107 var fullPath = newDocument . file . fullPath ;
@@ -113,7 +117,7 @@ define(function (require, exports, module) {
113117 // Update title text & "dirty dot" display
114118 updateTitle ( ) ;
115119
116- PerfUtils . addMeasurement ( perfTimerName ) ;
120+ // PerfUtils.addMeasurement(perfTimerName);
117121 }
118122
119123 function handleDirtyChange ( event , changedDoc ) {
@@ -253,10 +257,11 @@ define(function (require, exports, module) {
253257 * @param {string } dir The directory to use
254258 * @param {string } baseFileName The base to start with, "-n" will get appened to make unique
255259 * @param {string } fileExt The file extension
260+ * @param {boolean } isFolder True if the suggestion is for a folder name
256261 * @return {$.Promise } a jQuery promise that will be resolved with a unique name starting with
257262 * the given base name
258263 */
259- function _getUntitledFileSuggestion ( dir , baseFileName , fileExt ) {
264+ function _getUntitledFileSuggestion ( dir , baseFileName , fileExt , isFolder ) {
260265 var result = new $ . Deferred ( ) ;
261266 var suggestedName = baseFileName + fileExt ;
262267 var dirEntry = new NativeFileSystem . DirectoryEntry ( dir ) ;
@@ -269,18 +274,30 @@ define(function (require, exports, module) {
269274 }
270275
271276 //check this name
272- dirEntry . getFile (
273- suggestedName ,
274- { } ,
275- function successCallback ( entry ) {
276- //file exists, notify to the next progress
277- result . notify ( baseFileName + "-" + nextIndexToUse + fileExt , nextIndexToUse + 1 ) ;
278- } ,
279- function errorCallback ( error ) {
280- //most likely error is FNF, user is better equiped to handle the rest
281- result . resolve ( suggestedName ) ;
282- }
283- ) ;
277+ var successCallback = function ( entry ) {
278+ //file exists, notify to the next progress
279+ result . notify ( baseFileName + "-" + nextIndexToUse + fileExt , nextIndexToUse + 1 ) ;
280+ } ;
281+ var errorCallback = function ( error ) {
282+ //most likely error is FNF, user is better equiped to handle the rest
283+ result . resolve ( suggestedName ) ;
284+ } ;
285+
286+ if ( isFolder ) {
287+ dirEntry . getDirectory (
288+ suggestedName ,
289+ { } ,
290+ successCallback ,
291+ errorCallback
292+ ) ;
293+ } else {
294+ dirEntry . getFile (
295+ suggestedName ,
296+ { } ,
297+ successCallback ,
298+ errorCallback
299+ ) ;
300+ }
284301 } ) ;
285302
286303 //kick it off
@@ -297,9 +314,11 @@ define(function (require, exports, module) {
297314 * file creation call is outstanding
298315 */
299316 var fileNewInProgress = false ;
300-
301- function handleFileNewInProject ( ) {
302-
317+
318+ /**
319+ * Bottleneck function for creating new files and folders in the project tree.
320+ */
321+ function _handleNewItemInProject ( isFolder ) {
303322 if ( fileNewInProgress ) {
304323 ProjectManager . forceFinishRename ( ) ;
305324 return ;
@@ -320,21 +339,37 @@ define(function (require, exports, module) {
320339
321340 // Create the new node. The createNewItem function does all the heavy work
322341 // of validating file name, creating the new file and selecting.
323- var deferred = _getUntitledFileSuggestion ( baseDir , Strings . UNTITLED , " .js") ;
342+ var deferred = _getUntitledFileSuggestion ( baseDir , Strings . UNTITLED , isFolder ? "" : " .js", isFolder ) ;
324343 var createWithSuggestedName = function ( suggestedName ) {
325- ProjectManager . createNewItem ( baseDir , suggestedName , false )
344+ ProjectManager . createNewItem ( baseDir , suggestedName , false , isFolder )
326345 . pipe ( deferred . resolve , deferred . reject , deferred . notify )
327346 . always ( function ( ) { fileNewInProgress = false ; } )
328347 . done ( function ( entry ) {
329- FileViewController . addToWorkingSetAndSelect ( entry . fullPath , FileViewController . PROJECT_MANAGER ) ;
348+ if ( ! isFolder ) {
349+ FileViewController . addToWorkingSetAndSelect ( entry . fullPath , FileViewController . PROJECT_MANAGER ) ;
350+ }
330351 } ) ;
331352 } ;
332353
333354 deferred . done ( createWithSuggestedName ) ;
334- deferred . fail ( function createWithDefault ( ) { createWithSuggestedName ( "Untitled.js" ) ; } ) ;
355+ deferred . fail ( function createWithDefault ( ) { createWithSuggestedName ( isFolder ? "Untitled" : "Untitled.js" ) ; } ) ;
335356 return deferred ;
336357 }
358+
359+ /**
360+ * Create a new file in the project tree.
361+ */
362+ function handleFileNewInProject ( ) {
363+ _handleNewItemInProject ( false ) ;
364+ }
337365
366+ /**
367+ * Create a new folder in the project tree.
368+ */
369+ function handleNewFolderInProject ( ) {
370+ _handleNewItemInProject ( true ) ;
371+ }
372+
338373 function showSaveFileError ( code , path ) {
339374 return Dialogs . showModalDialog (
340375 Dialogs . DIALOG_ID_ERROR ,
@@ -711,6 +746,10 @@ define(function (require, exports, module) {
711746 ) ;
712747 }
713748
749+ function handleFileRename ( ) {
750+ ProjectManager . renameSelectedItem ( ) ;
751+ }
752+
714753 /** Closes the window, then quits the app */
715754 function handleFileQuit ( commandData ) {
716755 return _handleWindowGoingAway (
@@ -791,11 +830,13 @@ define(function (require, exports, module) {
791830 // File > New should open a new blank tab, and handleFileNewInProject should
792831 // be called from a "+" button in the project
793832 CommandManager . register ( Strings . CMD_FILE_NEW , Commands . FILE_NEW , handleFileNewInProject ) ;
833+ CommandManager . register ( Strings . CMD_FILE_NEW_FOLDER , Commands . FILE_NEW_FOLDER , handleNewFolderInProject ) ;
794834 CommandManager . register ( Strings . CMD_FILE_SAVE , Commands . FILE_SAVE , handleFileSave ) ;
795835 CommandManager . register ( Strings . CMD_FILE_SAVE_ALL , Commands . FILE_SAVE_ALL , handleFileSaveAll ) ;
796836
797837 CommandManager . register ( Strings . CMD_FILE_CLOSE , Commands . FILE_CLOSE , handleFileClose ) ;
798838 CommandManager . register ( Strings . CMD_FILE_CLOSE_ALL , Commands . FILE_CLOSE_ALL , handleFileCloseAll ) ;
839+ CommandManager . register ( Strings . CMD_FILE_RENAME , Commands . FILE_RENAME , handleFileRename ) ;
799840 CommandManager . register ( Strings . CMD_CLOSE_WINDOW , Commands . FILE_CLOSE_WINDOW , handleFileCloseWindow ) ;
800841 CommandManager . register ( Strings . CMD_QUIT , Commands . FILE_QUIT , handleFileQuit ) ;
801842 CommandManager . register ( Strings . CMD_REFRESH_WINDOW , Commands . DEBUG_REFRESH_WINDOW , handleFileReload ) ;
@@ -805,7 +846,7 @@ define(function (require, exports, module) {
805846
806847 // Listen for changes that require updating the editor titlebar
807848 $ ( DocumentManager ) . on ( "dirtyFlagChange" , handleDirtyChange ) ;
808- $ ( DocumentManager ) . on ( "currentDocumentChange" , handleCurrentDocumentChange ) ;
849+ $ ( DocumentManager ) . on ( "currentDocumentChange fileNameChange " , updateDocumentTitle ) ;
809850 }
810851
811852 // Define public API
0 commit comments