Below is an example demonstrating how you can obtain a [recursive] list of files from a given folder (e.g., Figure Metrics configuration files, part of the Measure Metrics product) and recursively copy them to another folder.
// Define an anonymous function; // serves as our main loop, // limits the scope of variables (function(){ // Define "globals" for identifying the script var g_sScript = getScriptFileName(); var g_oFileInfo = new DzFileInfo( g_sScript ); // Initialize 'static' variables that hold modifier key state var s_bShiftPressed = false; var s_bControlPressed = false; var s_bAltPressed = false; var s_bMetaPressed = false; // If the "Action" global transient is defined, and its the correct type if( typeof( Action ) != "undefined" && Action.inherits( "DzScriptAction" ) ){ // If the current key sequence for the action is not pressed if( !App.isKeySequenceDown( Action.shortcut ) ){ updateModifierKeyState(); } // If the "Action" global transient is not defined } else if( typeof( Action ) == "undefined" ) { updateModifierKeyState(); } /*********************************************************************/ // void : A function for updating the keyboard modifier state function updateModifierKeyState() { // Get the current modifier key state var nModifierState = App.modifierKeyState(); // Update variables that hold modifier key state s_bShiftPressed = (nModifierState & 0x02000000) != 0; s_bControlPressed = (nModifierState & 0x04000000) != 0; s_bAltPressed = (nModifierState & 0x08000000) != 0; s_bMetaPressed = (nModifierState & 0x10000000) != 0; }; /*********************************************************************/ // void : A function for printing only if debugging function debug() { // If we are not debugging if( !s_bAltPressed ){ // We are done... return; } // Convert the arguments object into an array var aArguments = [].slice.call( arguments ); // Print the array print( aArguments.join(" ") ); }; /*********************************************************************/ // String : A function for retrieving a translation if one exists function text( sText ) { // If the version of the application supports qsTr() if( typeof( qsTr ) != "undefined" ){ // Return the translated (if any) text return qsTr( sText ); } // Return the original text return sText; }; /*********************************************************************** ***** DsFileSystem Prototype ***** ***********************************************************************/ /*********************************************************************/ function DsFileSystem() { }; /***********************************************************************/ DsFileSystem.superclass = Object; /*********************************************************************/ // Array<String|DzDir> : Method for collecting an array of directory objects DsFileSystem.prototype.getDirectories = function( oDir, regxFilter, nFilter, nSort, sType, bRecurse ) { // Provide feedback debug( String("DsFileSystem::getDirectories( %1, \"%2\", %3, %4, \"%5\", %6 )") .arg( oDir.path() ) .arg( regxFilter ) .arg( nFilter ) .arg( nSort ) .arg( sType ) .arg( bRecurse ) ); // Declare working variable var sAbsPath; // Get the directory names var aDirs = oDir.entryList( regxFilter, nFilter, nSort ); // Iterate over the directory names for( var i = 0, nDirs = aDirs.length; i < nDirs; i += 1 ){ // Get the absolute path of the 'current' dir sAbsPath = String( "%1/%2" ).arg( oDir.absPath() ).arg( aDirs[ i ] ); // Based on the type requested switch( sType ){ default: case "String": // Update the name with the absolute path of the directory aDirs[ i ] = sAbsPath; // If we are recursing if( bRecurse ){ // Recursively collect the directory paths aDirs = aDirs.concat( this.getSubDirectories( new DzDir( sAbsPath ), regxFilter, nFilter, nSort, sType ) ); } break; case "DzDir": // Update the name with a directory object aDirs[ i ] = new DzDir( sAbsPath ); // If we are recursing if( bRecurse ){ // Recursively collect the directories aDirs = aDirs.concat( this.getSubDirectories( aDirs[ i ], regxFilter, nFilter, nSort, sType ) ); } break; } } // Return the result return aDirs; }; /*********************************************************************/ // Array<String|DzDir> : Method for recursively collecting an array of directory objects DsFileSystem.prototype.getSubDirectories = function( oDir, regxFilter, nFilter, nSort, sType ) { // Provide feedback debug( String( "DsFileSystem::getSubDirectories( %1, \"%2\", %3, %4, \"%5\" )" ) .arg( oDir.path() ) .arg( regxFilter ) .arg( nFilter ) .arg( nSort ) .arg( sType ) ); // Get the immediate child directories var aDirs = this.getDirectories( oDir, regxFilter, nFilter, nSort, sType, true ); // Iterate over the directories for( var i = 0, nDirs = aDirs.length; i < nDirs; i += 1 ){ // Based on the type requested switch( sType ){ default: case "String": // Recursively collect the directory paths aDirs = aDirs.concat( this.getSubDirectories( new DzDir( aDirs[ i ] ), regxFilter, nFilter, nSort, sType ) ); break; case "DzDir": // Recursively collect the directories aDirs = aDirs.concat( this.getSubDirectories( aDirs[ i ], regxFilter, nFilter, nSort, sType, true ) ); break; } } // Return the result return aDirs; }; /*********************************************************************/ // Array<String|DzFileInfo|DzFile> : Method for collecting an array of files DsFileSystem.prototype.getFiles = function( oDir, regxFilter, nFilter, nSort, sType ) { // Provide feedback debug( String( "DsFileSystem::getFiles( %1, \"%2\", %3, %4, \"%5\" )" ) .arg( oDir.path() ) .arg( regxFilter ) .arg( nFilter ) .arg( nSort ) .arg( sType ) ); // Declare working variable var sAbsFilePath; // Get the file names var aFiles = oDir.entryList( regxFilter, nFilter, nSort ); // Iterate over the file names for( var i = 0, nFiles = aFiles.length; i < nFiles; i += 1 ){ // Get the absolute path of the 'current' file sAbsFilePath = oDir.absFilePath( aFiles[ i ] ); // Based on the type requested switch( sType ){ default: case "String": // Update the name with the absolute path of a file aFiles[ i ] = sAbsFilePath; break; case "DzFileInfo": // Update the name with a file info object aFiles[ i ] = new DzFileInfo( sAbsFilePath ); break; case "DzFile": // Update the name with a file object aFiles[ i ] = new DzFile( sAbsFilePath ); break; } } // Return the result return aFiles; }; /*********************************************************************/ // Array<String|DzDir> : Method for retrieving a list of directories DsFileSystem.prototype.getDirectoryList = function( sPath, sFilter, sType, bRecurse, bRelative ) { // Declare the output var aDirs = []; // Create a directory object var oBaseDir = new DzDir( sPath ); // If the directory doesn't exist if( !oBaseDir.exists() ){ // We are done... return aDirs; } // Get the directories var aDirs = this.getDirectories( oBaseDir, sFilter, DzDir.Dirs | DzDir.NoDotAndDotDot, DzDir.Name, sType, bRecurse ); // If we do not want relative if( !bRelative ){ // Return the result return aDirs; } // Declare working variable var sAbsPath, sRelPath; var oDir; // Iterate over the directories for( var i = 0, nDirs = aDirs.length; i < nDirs; i += 1 ){ // Based on the type requested switch( sType ){ default: case "String": // Get the 'current' path sAbsPath = aDirs[ i ]; // Get the relative portion of the path sRelPath = sAbsPath.substring( sPath.length ); // Update the path aDirs[ i ] = sRelPath; break; case "DzDir": // Get the 'current' directory oDir = aDirs[ i ]; // Get the path sAbsPath = oDir.path(); // Get the relative portion of the path sRelPath = sAbsPath.substring( sPath.length ); // Update the path oDir.setPath( sRelPath ); // Update the directory aDirs[ i ] = oDir; break; } } // Return the result return aDirs; }; /*********************************************************************/ // Array<String|DzFileInfo|DzFile> : Method for retrieving a list of files DsFileSystem.prototype.getFileList = function( sPath, sFilter, sType, bRecurse ) { // Declare the output var aFiles = []; // Get the directories var aDirs = this.getDirectoryList( sPath, "*", "DzDir", bRecurse ); // Iterate over the directories for( var i = 0, nDirs = aDirs.length; i < nDirs; i += 1 ){ // Append the files from the 'current' directory to the output aFiles = aFiles.concat( this.getFiles( aDirs[ i ], sFilter, DzDir.Files, DzDir.Name, sType ) ); } // Return the result return aFiles; }; /*********************************************************************/ // String : A function for prompting the user to pick from a list function promptUserChoice( sLabel, aChoices ) { // Create a basic dialog var wDlg = new DzBasicDialog(); // Get the wrapped widget for the dialog var oDlgWgt = wDlg.getWidget(); // Get the name of this file var sName = g_oFileInfo.baseName(); // Set the title of the dialog wDlg.caption = sName.replace( /_/g, " " ); // Strip the space for a settings key var sKey = String("%1Dlg").arg( sName.replace( / /g, "" ) ); // Set an [unique] object name on the wrapped dialog widget; // this is used for recording position and size separately // from all other [uniquely named] DzBasicDialog instances oDlgWgt.objectName = sKey; // Create a label var wLabel = new DzLabel( wDlg ); // Set its text wLabel.text = sLabel; // Add the widget to the dialog wDlg.addWidget( wLabel ); // Create a combobox var wChoicesCmb = new DzComboBox( wDlg ); // Populate the choices wChoicesCmb.addItems( aChoices ); // Add the widget to the dialog wDlg.addWidget( wChoicesCmb ); // Get the minimum size for the dialog var sizeHint = oDlgWgt.minimumSizeHint; // Set the fixed size to the minimum size wDlg.setFixedSize( sizeHint.width, sizeHint.height ); // If the user cancels the dialog if( !wDlg.exec() ){ // We are done... return ""; } // return the user's choice return wChoicesCmb.currentText; }; /*********************************************************************/ // Get the application data directory var oAppDataDir = new DzDir( App.getAppDataPath() ); // var sTgtDataDir = oAppDataDir.path(); debug( "Target =", sTgtDataDir ); // Get the words in the application name var aAppName = App.appName.split(" "); // Get the numbers in the version var aVersion = App.versionString.split("."); // Construct the name of the (general release) application data folder var sFolderName = String("%1%2").arg( aAppName[ aAppName.length - 1 ] ).arg( aVersion[ 0 ] ); // Initialize to the application data directory var oSrcDataDir = new DzDir( sTgtDataDir ); // Go up a directory oSrcDataDir.cdUp(); // Get a list of the directory names that start with the prefix we want var aAppDataDirs = oSrcDataDir.entryList( String("%1*").arg( sFolderName ), DzDir.Dirs | DzDir.NoDotAndDotDot ); // Get the index of the current directory in the list var nSelf = aAppDataDirs.indexOf( oAppDataDir.dirName() ); // Remove the current directory from the list aAppDataDirs.splice( nSelf, 1 ); // Prompt the user for which channel to copy from var sFolder = promptUserChoice( text( "Copy Figure Metrics files from:" ), aAppDataDirs ); // If the user cancelled if( sFolder.isEmpty() ){ // We are done... return; } // Let the user know we are busy setBusyCursor(); // Change the directory to the one chosen by the user oSrcDataDir.cd( sFolder ); // var sSrcDataDir = oSrcDataDir.path(); debug( "Source =", sSrcDataDir ); // Create a file system object var oFileSystem = new DsFileSystem(); var oTgtFile; var sSrcFile, sTgtFile, sRelFile; // Get the list of files that match the filters var aSrcFiles = oFileSystem.getFileList( sSrcDataDir, "*.json", "String", true ); // Iterate over the file paths for( var i = 0, nFiles = aSrcFiles.length; i < nFiles; i += 1 ){ // Get the 'current' source file path sSrcFile = aSrcFiles[ i ]; // Get the relative portion of the file path sRelFile = sSrcFile.substring( sSrcDataDir.length ); // Construct the target file path sTgtFile = sTgtDataDir + sRelFile; // Create a file info object oTgtFile = new DzFileInfo( sTgtFile ); // Ensure the target path exists if( oAppDataDir.mkpath( oTgtFile.absolutePath() ) ){ // Copy the source file to the target path oSrcDataDir.copy( sSrcFile, sTgtFile ); } // Do not leak memory oTgtFile.deleteLater(); } // Let the user know we are done clearBusyCursor(); // Finalize the function and invoke })();