@@ -12,8 +12,9 @@ define([
1212 "utils/filesync" ,
1313 "utils/dialogs" ,
1414 "utils/uploader" ,
15+ "utils/clipboard" ,
1516 "core/operations"
16- ] , function ( Q , _ , hr , rpc , vfs , debugManager , Command , string , Url , Languages , FileSync , dialogs , Uploader , operations ) {
17+ ] , function ( Q , _ , hr , rpc , vfs , debugManager , Command , string , Url , Languages , FileSync , dialogs , Uploader , clipboard , operations ) {
1718 var logging = hr . Logger . addNamespace ( "files" ) ;
1819
1920 var File = hr . Model . extend ( {
@@ -58,6 +59,8 @@ define([
5859
5960 // Listen to codebox event
6061 this . listenTo ( this . codebox , "box:watch:change" , function ( e ) {
62+ if ( ! this . isValid ( ) ) return ;
63+
6164 // Event on this file itself
6265 if ( e . data . path == this . path ( ) ) {
6366 this . trigger ( "file:change:" + e . data . change , e . data ) ;
@@ -179,7 +182,7 @@ define([
179182 if ( this . get ( "href" ) . length == 0 ) { return null ; }
180183 path = Url . parse ( this . get ( "href" ) ) . pathname . replace ( "/vfs" , "" ) ;
181184 }
182-
185+
183186 if ( string . endsWith ( path , "/" ) ) {
184187 path = path . slice ( 0 , - 1 )
185188 }
@@ -379,7 +382,7 @@ define([
379382 "size" : 0 ,
380383 "mtime" : 0 ,
381384 "mime" : "inode/directory" ,
382- "href" : "/vfs/" ,
385+ "href" : location . protocol + "//" + location . host + "/vfs/" ,
383386 "exists" : true
384387 } ;
385388 this . set ( fileData ) ;
@@ -529,11 +532,40 @@ define([
529532 rename : function ( name ) {
530533 var parentPath = this . parentPath ( ) ;
531534 var newPath = parentPath + "/" + name ;
532- return this . loading ( this . vfsRequest ( "rename " , this . vfsUrl ( newPath ) , {
535+ return this . loading ( this . vfsRequest ( "special " , this . vfsUrl ( newPath ) , {
533536 "renameFrom" : this . path ( )
534537 } ) ) ;
535538 } ,
536539
540+ /*
541+ * Copy this file
542+ *
543+ * @to : folder to copy to
544+ * @newName : (optional) new name in the to folder
545+ */
546+ copyTo : function ( to , newName ) {
547+ newName = newName || this . get ( "name" ) ;
548+ var toPath = to + "/" + newName ;
549+
550+ return this . loading ( this . vfsRequest ( "special" , this . vfsUrl ( toPath ) , {
551+ "copyFrom" : this . path ( )
552+ } ) ) ;
553+ } ,
554+
555+ /*
556+ * Copy a file in this folder
557+ *
558+ * @from : file to copy
559+ */
560+ copyFile : function ( from , newName ) {
561+ newName = newName || from . split ( "/" ) . pop ( ) ;
562+ var toPath = this . path ( ) + "/" + newName ;
563+
564+ return this . loading ( this . vfsRequest ( "special" , this . vfsUrl ( toPath , false ) , {
565+ "copyFrom" : from
566+ } ) ) ;
567+ } ,
568+
537569 /*
538570 * Run the file
539571 */
@@ -703,14 +735,71 @@ define([
703735 } ) ;
704736 menu . push ( {
705737 'type' : "action" ,
706- 'title' : "Remove" ,
738+ 'title' : "Delete " + ( that . isDirectory ( ) ? "Folder" : "File" ) ,
707739 'action' : function ( ) {
708740 return that . actionRemove ( ) ;
709741 }
710742 } ) ;
711743 menu . push ( { 'type' : "divider" } ) ;
712744 }
713745
746+ if ( ! that . isDirectory ( ) ) {
747+ menu . push ( {
748+ 'type' : "action" ,
749+ 'title' : "Copy" ,
750+ 'action' : function ( ) {
751+ clipboard . setData ( "file" , that . path ( ) ) ;
752+ }
753+ } ) ;
754+ menu . push ( {
755+ 'type' : "action" ,
756+ 'title' : "Cut" ,
757+ 'action' : function ( ) {
758+ clipboard . setData ( "file" , that . path ( ) , {
759+ cut : true
760+ } ) ;
761+ }
762+ } ) ;
763+ } else {
764+ menu . push ( {
765+ 'type' : "action" ,
766+ 'title' : "Paste" ,
767+ 'flags' : ( ! clipboard . hasData ( "file" ) ? "disabled" : "" ) ,
768+ 'action' : function ( ) {
769+ if ( clipboard . hasData ( "file" ) ) {
770+ var path = clipboard . getData ( "file" ) ;
771+ var cut = clipboard . getRaw ( ) . options . cut == true ;
772+
773+ // Load file we are copying
774+ var toCopy = new File ( ) ;
775+ return toCopy . getByPath ( path )
776+ . then ( function ( ) {
777+ // Copy file
778+ return toCopy . copyTo ( that . path ( ) ) ;
779+ } )
780+ . then ( function ( ) {
781+ // If cut then delete the previsous file and clear clipboard
782+ if ( cut == false ) return ;
783+
784+ // Clear clipboard
785+ clipboard . clear ( ) ;
786+
787+ // Remove file copied
788+ return toCopy . remove ( ) ;
789+ } )
790+ . fail ( function ( err ) {
791+ logging . error ( "error copy" , err . stack , err ) ;
792+ } )
793+ . done ( function ( ) {
794+ // Clear temporary model
795+ toCopy . destroy ( ) ;
796+ } )
797+ }
798+ }
799+ } ) ;
800+ }
801+ menu . push ( { 'type' : "divider" } ) ;
802+
714803 if ( that . isDirectory ( ) ) {
715804 // Directory
716805 menu . push ( {
0 commit comments