Exemple #1
0
bool AppManager_runCommand(const String& srcFile, const ArrayList<String>& args)
{
	String resultFile = AppManager_resultFile;
	AppManager_clean();
	
	String execPath = FileTools_getExecutableDirectory();
	int slashIndex = execPath.lastIndexOf('/');
	String appFolder;
	if(slashIndex==-1)
	{
		appFolder = execPath.substring(0, slashIndex);
	}
	else
	{
		appFolder = execPath;
	}
	
	String miniCodeInstallerPath = appFolder + "/installer";
	String commandString = miniCodeInstallerPath + ' ';
	for(int i=0; i<args.size(); i++)
	{
		commandString += args.get(i) + ' ';
	}
	commandString += (String)"\"" + srcFile + "\"";
	system(commandString);
	
	while(!FileTools_fileExists(resultFile))
	{
		Thread::sleep(3);
	}
	
	String contents;
	bool success = FileTools::loadFileIntoString(resultFile, contents);
	AppManager_clean();
	if(!success)
	{
		showSimpleMessageBox("Error", "Error reading results from result file. Assuming failure.");
		return false;
	}
	
	for(int i=0; i<contents.length(); i++)
	{
		char c = contents.charAt(i);
		if(!(c>='0' && c<='9'))
		{
			showSimpleMessageBox("Error", "Invalid result string");
			return false;
		}
	}
	
	int result = String::asInt(contents);
	if(result==0)
	{
		return true;
	}
	Console::WriteLine((String)"Installer failed with exit code " + result);
	return false;
}
ProjectData_struct*ProjLoad_loadProjectDataFromSavedProject(const char* projectName)
{
    String plistPath = savedProjectsFolder + '/' + projectName + "/project.plist";
    void* plistDict = ProjLoad_loadAllocatedPlist(plistPath);
    if(plistDict==NULL)
    {
        showSimpleMessageBox("Error loading ProjectData", (String)"Problem occured loading project.plist from saved project " + projectName);
        return NULL;
    }
    ProjectData_struct*projData = ProjLoad_loadProjectDataFromNSDictionary(plistDict);
    if(projData==NULL)
    {
        id_release(plistDict);
        return NULL;
    }
    String settingsPath = savedProjectsFolder + '/' + projectName + "/settings.plist";
    void* settingsPlist = ProjLoad_loadAllocatedPlist(settingsPath);
    if(settingsPlist!=NULL)
    {
        ProjectSettings_struct* projSettings = ProjLoad_loadProjectSettingsFromNSDictionary(settingsPlist);
        if(projSettings!=NULL)
        {
            ((ProjectData*)projData->data)->getProjectSettings() = *((ProjectSettings*)projSettings->data);
            String sdk = ProjectSettings_getSDK(projSettings);
            if(!Global_checkSDKFolderValid(sdk))
            {
                ((ProjectData*)projData->data)->getProjectSettings().setSDK(GlobalPreferences_getDefaultSDK());
            }
        }
        ProjectSettings_destroyInstance(projSettings);
        id_release(settingsPlist);
    }

    ProjectData_setFolderName(projData, projectName);

    FileTools::createDirectory(savedProjectsFolder+'/'+projectName+"/src");
    FileTools::createDirectory(savedProjectsFolder+'/'+projectName+"/res");
    FileTools::createDirectory(savedProjectsFolder+'/'+projectName+"/ext");
    FileTools::createDirectory(savedProjectsFolder+'/'+projectName+"/bin");
    FileTools::createDirectory(savedProjectsFolder+'/'+projectName+"/bin/build");
    FileTools::createDirectory(savedProjectsFolder+'/'+projectName+"/bin/release");

    String buildInfoPath = savedProjectsFolder + '/' + projectName + "/bin/build/buildinfo.plist";
    void* buildInfoPlist = ProjLoad_loadAllocatedPlist(buildInfoPath);
    if(buildInfoPlist!=NULL)
    {
        ProjectBuildInfo_struct* projBuildInfo = ProjLoad_loadProjectBuildInfoFromNSDictionary(buildInfoPlist);
        if(projBuildInfo!=NULL)
        {
            ((ProjectData*)projData->data)->getProjectBuildInfo() = *((ProjectBuildInfo*)projBuildInfo->data);
        }
        ProjectBuildInfo_destroyInstance(projBuildInfo);
        id_release(buildInfoPlist);
    }

    id_release(plistDict);
    return projData;
}
ProjectData_struct*ProjLoad_loadProjectDataFromTemplate(const char*category, const char*templateName, const char*templatesRoot)
{
    String execPath = FileTools_getExecutableDirectory();
    String templatePlistPath = /*execPath + "/Project Templates/"*/(String)templatesRoot + '/' + category + '/' + templateName + "/project.plist";
    void* plistDict = ProjLoad_loadAllocatedPlist(templatePlistPath);
    if(plistDict==NULL)
    {
        showSimpleMessageBox("Error loading ProjectData", (String)"Problem occured loading project.plist in template " + templateName + " in category " + category + " in templates folder " + templatesRoot);
        return NULL;
    }
    ProjectData_struct*projData = ProjLoad_loadProjectDataFromNSDictionary(plistDict);
    if(projData==NULL)
    {
        id_release(plistDict);
        return NULL;
    }
    ProjectData_setFolderName(projData, templateName);
    id_release(plistDict);
    return projData;
}
bool GlobalPreferences_load()
{
	String settingsPath = (String)getenv("HOME") + "/Library/Preferences/" + bundleID + ".plist";
	void*dict = ProjLoad_loadAllocatedPlist(settingsPath);
	if(dict!=NULL)
	{
		void* sdk = NSDictionary_objectForKey(dict, "DefaultSDK");
		if(sdk!=NULL)
		{
			defaultSDK = NSString_UTF8String(sdk);
			//make sure sdk is valid
			if(!Global_checkSDKFolderValid(defaultSDK))
			{
				defaultSDK = "";
			}
		}
		
		void* editorFont = NSDictionary_objectForKey(dict, "EditorFont");
		if(editorFont!=NULL)
		{
			codeEditorFont = NSString_UTF8String(editorFont);
			//TODO check and make sure font is valid
		}
		
		void* editorFontSize = NSDictionary_objectForKey(dict, "EditorFontSize");
		if(editorFontSize!=NULL)
		{
			codeEditorFontSize = NSNumber_intValue(editorFontSize);
			if(codeEditorFontSize < CODEEDITOR_MINFONTSIZE)
			{
				codeEditorFontSize = CODEEDITOR_MINFONTSIZE;
			}
			else if(codeEditorFontSize > CODEEDITOR_MAXFONTSIZE)
			{
				codeEditorFontSize = CODEEDITOR_MAXFONTSIZE;
			}
		}
		
		void* installedAppsArray = NSDictionary_objectForKey(dict, "InstalledApps");
		if(installedAppsArray!=NULL)
		{
			installedApps.clear();
			for(unsigned int i=0; i<NSArray_count(installedAppsArray); i++)
			{
				void*appName = NSArray_objectAtIndex(installedAppsArray, i);
				installedApps.add(NSString_UTF8String(appName));
			}
		}
		
		bool resave = false;
		void* latestVersion = NSDictionary_objectForKey(dict, "LatestVersion");
		if(latestVersion!=NULL)
		{
			double version = NSNumber_doubleValue(latestVersion);
			if(version!=currentVersion)
			{
				resave = true;
				showSimpleMessageBox("miniCode", versionMessage);
			}
		}
		else
		{
			resave = true;
			showSimpleMessageBox("miniCode", versionMessage);
		}
		
		id_release(dict);
		if(resave)
		{
			return GlobalPreferences_save();
		}
		return true;
	}
	else
	{
		showSimpleMessageBox("miniCode", versionMessage);
		return GlobalPreferences_save();
	}
	return false;
}
ProjectData_struct*ProjLoad_prepareProjectFromTemplate(const char*category, const char*templateName, const char*templatesRoot)
{
    ProjectData_struct*projDataStruct = ProjLoad_loadProjectDataFromTemplate(category, templateName, templatesRoot);
    if(projDataStruct==NULL)
    {
        return NULL;
    }
    ProjectData&projData = *((ProjectData*)ProjectData_getData(projDataStruct));

    //path variables
    String execDir = FileTools_getExecutableDirectory();
    String homeDir = getenv("HOME");
    String templateRoot = execDir + "/Project Templates/" + category + '/' + templateName;
    const String&savedProjectsRoot = savedProjectsFolder;

    //create the project info fields
    String var_projectName = ProjLoad_getIntendedProjectNameField();
    String var_authorName = ProjLoad_getIntendedProjectAuthorField();
    String var_projectNameAsIdentifier = ProjectData::createBundlenameFromName(var_projectName);
    String var_executableName = var_projectNameAsIdentifier;
    String var_productName = var_projectNameAsIdentifier;

    //finds and replaces instances of project variables withing the ProjectData object

    String field = projData.getName();
    ProjLoad_fillProjectVarsInString(field, var_projectName,var_authorName,var_projectNameAsIdentifier,var_executableName,var_productName);
    projData.setName(field);

    field = projData.getAuthor();
    ProjLoad_fillProjectVarsInString(field, var_projectName,var_authorName,var_projectNameAsIdentifier,var_executableName,var_productName);
    projData.setAuthor(field);

    field = projData.getBundleIdentifier();
    ProjLoad_fillProjectVarsInString(field, var_projectName,var_authorName,var_projectNameAsIdentifier,var_executableName,var_productName);
    projData.setBundleIdentifier(field);

    field = projData.getExecutableName();
    ProjLoad_fillProjectVarsInString(field, var_projectName,var_authorName,var_projectNameAsIdentifier,var_executableName,var_productName);
    projData.setExecutableName(field);

    field = projData.getProductName();
    ProjLoad_fillProjectVarsInString(field, var_projectName,var_authorName,var_projectNameAsIdentifier,var_executableName,var_productName);
    projData.setProductName(field);

    //set save folder name
    String saveFolder = projData.getName();
    String projectName = projData.getName();

    ArrayList<String> currentProjects = FileTools::getFoldersInDirectory(savedProjectsRoot, false);

    int matchChecks = 0;
    //make sure there aren't any project folders with the same folder name
    //rename save folder if necessary (ex: "miniCode" becomes "miniCode (1)" or "miniCode (2)" etc.)
    bool matchedName = false;
    do
    {
        matchedName = false;
        for(int i=0; i<currentProjects.size(); i++)
        {
            if(saveFolder.equals(currentProjects.get(i)))
            {
                matchedName = true;
                i = currentProjects.size();
            }
        }

        if(matchedName)
        {
            matchChecks++;
            saveFolder = projectName + " (" + matchChecks + ')';
        }
    }
    while(matchedName);

    projData.setFolderName(saveFolder);
    String projectRoot = savedProjectsRoot + '/' + saveFolder;

    //create the project folder
    bool didMakeDirectory = FileTools::createDirectory(projectRoot);
    //checks for errors making the save folder
    if(!didMakeDirectory)
    {
        showSimpleMessageBox("", (String)"Error creating project folder " + projectRoot);
        ProjectData_destroyInstance(projDataStruct);
        return NULL;
    }

    //loop to create the subfolders inside the project folder
    const char*projFolders[4] = {"src", "res", "ext", "bin"};
    for(int i=0; i<4; i++)
    {
        //create the subfolder
        didMakeDirectory = FileTools::createDirectory(projectRoot + '/' + projFolders[i]);
        //checks for errors making the subfolder
        if(!didMakeDirectory)
        {
            showSimpleMessageBox("", (String)"Error creating " + projFolders[i] + " folder in project folder " + projectRoot);
            ProjectData_destroyInstance(projDataStruct);
            return NULL;
        }
    }

    //go through source files, load the files, replace instances within the files, save the files (or attempt to)
    ProjLoad_fillProjectVarsInSourceFiles(projData.getSourceFiles(), templateRoot+"/src", projectRoot+"/src", "",
                                          var_projectName,var_authorName,var_projectNameAsIdentifier,var_executableName,var_productName);

    //go through resource files, save the files with renamed file name (or attempt to)
    ProjLoad_fillProjectVarsInResourceFiles(projData.getResourceFiles(), templateRoot+"/res", projectRoot+"/res", "",
                                            var_projectName,var_authorName,var_projectNameAsIdentifier,var_executableName,var_productName);

    //copy include and lib dirs
    bool success = FileTools::copyFolder(templateRoot + "/ext", projectRoot + "/ext");
    if(!success)
    {
        showSimpleMessageBox("Error creating project", "Problem occured copying \"ext\" folder");
    }

    FileTools::copyFile(templateRoot + "/project.plist", projectRoot + "/project.plist");
    success = ProjectData_saveProjectPlist(projDataStruct);
    if(!success)
    {
        showSimpleMessageBox("Error creating project", "Problem occurred saving project.plist");
    }

    ProjectSettings_struct projSettings = ProjectData_getProjectSettings(projDataStruct);
    success = ProjectSettings_saveSettingsPlist(&projSettings, projDataStruct);
    if(!success)
    {
        showSimpleMessageBox("Error", (String)"Unable to save settings.plist for project " + projData.getFolderName());
    }

    return projDataStruct;
}
void ProjLoad_fillProjectVarsInResourceFiles(StringTree&resourceTree, const String&templateResRoot, const String&projectResRoot, const String&subFolder,
        const String&projectName, const String&authorName, const String&projectNameAsIdentifier,
        const String&executableName, const String& productName)
{
    ArrayList<String> members = resourceTree.getMembers();

    String templateResCurrentFolder = templateResRoot + '/' + subFolder;
    String projectResCurrentFolder = projectResRoot + '/' + subFolder;

    for(int i=0; i<members.size(); i++)
    {
        String filename = members.get(i);
        String filepath = templateResCurrentFolder + '/' + filename;

        String newFilename = filename;
        ProjLoad_fillProjectVarsInString(newFilename, projectName, authorName, projectNameAsIdentifier, executableName, productName);

        String saveFile = newFilename;

        //rename file if necessary
        bool couldRename = false;
        int matchChecks = 0;
        do
        {
            couldRename = resourceTree.renameMember(filename, saveFile);
            if(!couldRename)
            {
                matchChecks++;
                saveFile = newFilename + " (" + matchChecks + ')';
            }
        }
        while (!couldRename);

        bool success = FileTools::copyFile(filepath, projectResCurrentFolder + '/' + saveFile);
        if(!success)
        {

            showSimpleMessageBox("Error creating new project", (String)"Error copying file " + filepath + " to destination " + projectResCurrentFolder + '/' + saveFile);
        }
    }

    ArrayList<String> branchNames = resourceTree.getBranchNames();

    for(int i=0; i<branchNames.size(); i++)
    {
        String branchname = branchNames.get(i);
        String branchpath = templateResCurrentFolder + '/' + branchname;

        String newBranchname = branchname;
        ProjLoad_fillProjectVarsInString(newBranchname, projectName, authorName, projectNameAsIdentifier, executableName, productName);

        String saveFolder = newBranchname;

        //rename file if necessary
        bool couldRename = false;
        int matchChecks = 0;
        do
        {
            couldRename = resourceTree.renameBranch(branchname, saveFolder);
            if(!couldRename)
            {
                matchChecks++;
                saveFolder = newBranchname + " (" + matchChecks + ')';
            }
        }
        while (!couldRename);

        bool success = FileTools::createDirectory(projectResCurrentFolder + '/' + saveFolder);
        if(success)
        {
            StringTree*tree = resourceTree.getBranch(saveFolder);
            ProjLoad_fillProjectVarsInResourceFiles(*tree, templateResRoot, projectResRoot, subFolder + '/' + saveFolder,
                                                    projectName, authorName, projectNameAsIdentifier, executableName, productName);
        }
        else
        {
            showSimpleMessageBox("Error creating new project", (String)"Error creating folder " + projectResCurrentFolder + '/' + saveFolder);
        }
    }
}
void ProjLoad_fillProjectVarsInSourceFiles(StringTree&sourceTree, const String&templateSrcRoot, const String&projectSrcRoot, const String&subFolder,
        const String&projectName, const String&authorName, const String&projectNameAsIdentifier,
        const String&executableName, const String& productName)
{
    ArrayList<String> members = sourceTree.getMembers();

    String templateSrcCurrentFolder = templateSrcRoot;
    String projectSrcCurrentFolder = projectSrcRoot;
    if(!subFolder.equals(""))
    {
        templateSrcCurrentFolder += (String)"/" + subFolder;
        projectSrcCurrentFolder += (String)"/" + subFolder;
    }

    for(int i=0; i<members.size(); i++)
    {
        String filename = members.get(i);
        String filepath = templateSrcCurrentFolder + '/' + filename;

        String fileContents;
        bool loadedFile = FileTools::loadFileIntoString(filepath, fileContents);

        if(!loadedFile)
        {
            showSimpleMessageBox("Error loading ProjectData", (String)"Error loading file " + filepath);
        }
        else
        {
            ProjLoad_fillProjectVarsInString(fileContents, projectName, authorName, projectNameAsIdentifier, executableName, productName);

            String newFilename = filename;
            ProjLoad_fillProjectVarsInString(newFilename, projectName, authorName, projectNameAsIdentifier, executableName, productName);

            String saveFile = newFilename;

            //rename file if necessary
            bool couldRename = false;
            int matchChecks = 0;
            do
            {
                couldRename = sourceTree.renameMember(filename, saveFile);
                if(!couldRename)
                {
                    matchChecks++;
                    saveFile = newFilename + " (" + matchChecks + ')';
                }
            }
            while (!couldRename);

            bool success = FileTools::writeStringToFile(projectSrcCurrentFolder + '/' + saveFile, fileContents);
            if(!success)
            {

                showSimpleMessageBox("Error creating new project", (String)"Error creating file " + projectSrcCurrentFolder + '/' + saveFile);
            }
        }
    }

    ArrayList<String> branchNames = sourceTree.getBranchNames();

    for(int i=0; i<branchNames.size(); i++)
    {
        String branchname = branchNames.get(i);
        String branchpath = templateSrcCurrentFolder + '/' + branchname;

        String newBranchname = branchname;
        ProjLoad_fillProjectVarsInString(newBranchname, projectName, authorName, projectNameAsIdentifier, executableName, productName);

        String saveFolder = newBranchname;

        //rename file if necessary
        bool couldRename = false;
        int matchChecks = 0;
        do
        {
            couldRename = sourceTree.renameBranch(branchname, saveFolder);
            if(!couldRename)
            {
                matchChecks++;
                saveFolder = newBranchname + " (" + matchChecks + ')';
            }
        }
        while (!couldRename);

        bool success = FileTools::createDirectory(projectSrcCurrentFolder + '/' + saveFolder);
        if(success)
        {
            StringTree*tree = sourceTree.getBranch(saveFolder);
            ProjLoad_fillProjectVarsInSourceFiles(*tree, templateSrcRoot, projectSrcRoot, subFolder + '/' + saveFolder,
                                                  projectName, authorName, projectNameAsIdentifier, executableName, productName);
        }
        else
        {
            showSimpleMessageBox("Error creating new project", (String)"Error creating folder " + projectSrcCurrentFolder + '/' + saveFolder);
        }
    }
}
ProjectData_struct*ProjLoad_loadProjectDataFromNSDictionary(void*dict)
{
    if(dict==NULL)
    {
        return NULL;
    }

    const char*name = NSString_UTF8String(NSDictionary_objectForKey(dict,"name"));
    const char*author = NSString_UTF8String(NSDictionary_objectForKey(dict,"author"));
    if(name==NULL || author==NULL || strlen(name)==0 || strlen(author)==0)
    {
        showSimpleMessageBox("Error loading ProjectData", "name or author field in project.plist is empty or not available");
        return NULL;
    }

    ProjectData_struct*projDataStruct = ProjectData_createInstance(name, author);
    ProjectData&projData = *((ProjectData*)ProjectData_getData(projDataStruct));

    const char*bundleID = NSString_UTF8String(NSDictionary_objectForKey(dict,"bundleIdentifier"));
    if(bundleID!=NULL && strlen(bundleID)!=0)
    {
        projData.setBundleIdentifier(bundleID);
    }

    const char*executable = NSString_UTF8String(NSDictionary_objectForKey(dict,"executable"));
    if(executable!=NULL && strlen(executable)!=0)
    {
        projData.setExecutableName(executable);
    }

    const char*product = NSString_UTF8String(NSDictionary_objectForKey(dict,"product"));
    if(product!=NULL && strlen(product)!=0)
    {
        projData.setProductName(product);
    }

    const char*projectType = NSString_UTF8String(NSDictionary_objectForKey(dict,"projectType"));
    if(projectType!=NULL && strlen(projectType)!=0)
    {
        ProjectType projType = ProjectType_convertFromString(projectType);
        if(projType!=PROJECTTYPE_UNKNOWN)
        {
            projData.setProjectType(projType);
        }
    }

    const char*projectDevice = NSString_UTF8String(NSDictionary_objectForKey(dict,"projectDevice"));
    if(projectDevice!=NULL && strlen(projectDevice)!=0)
    {
        ProjectDevice projDevice = ProjectDevice_convertFromString(projectDevice);
        if(projDevice!=DEVICE_UNKNOWN)
        {
            projData.setProjectDevice(projDevice);
        }
    }

    void*frameworks = NSDictionary_objectForKey(dict,"frameworks");
    if(frameworks!=NULL)
    {
        for(unsigned int i=0; i<NSArray_count(frameworks); i++)
        {
            const char*framework = NSString_UTF8String(NSArray_objectAtIndex(frameworks, i));
            projData.addFramework(framework);
        }
    }

    void*sourceFiles = NSDictionary_objectForKey(dict,"sourceFiles");
    if(sourceFiles!=NULL)
    {
        StringTree_struct*sourceTree = StringTree_convertNSArrayToFileTree(sourceFiles);
        projData.getSourceFiles() = *((StringTree*)StringTree_getData(sourceTree));
        StringTree_destroyInstance(sourceTree);
    }

    void*resources = NSDictionary_objectForKey(dict, "resources");
    if(resources!=NULL)
    {
        StringTree_struct*resourceTree = StringTree_convertNSArrayToFileTree(resources);
        projData.getResourceFiles() = *((StringTree*)StringTree_getData(resourceTree));
        StringTree_destroyInstance(resourceTree);
    }

    void*external = NSDictionary_objectForKey(dict, "external");
    if(external!=NULL)
    {
        void*includeArray = NSDictionary_objectForKey(external, "include");
        for(unsigned int i=0; i<NSArray_count(includeArray); i++)
        {
            const char* includePath = NSString_UTF8String(NSArray_objectAtIndex(includeArray, i));
            if(includePath!=NULL && strlen(includePath)!=0)
            {
                projData.getIncludeDirs().add(includePath);
            }
        }

        void*libArray = NSDictionary_objectForKey(external, "lib");
        for(unsigned int i=0; i<NSArray_count(libArray); i++)
        {
            const char* libPath = NSString_UTF8String(NSArray_objectAtIndex(libArray, i));
            if(libPath!=NULL && strlen(libPath)!=0)
            {
                projData.getLibDirs().add(libPath);
            }
        }
    }

    return projDataStruct;
}