DPath Project::GetPathForFile(SourceFile *file) { if (!file) return DPath(); BString pathstr = file->GetPath().GetFullPath(); if (pathstr[0] != '/') { pathstr.Prepend("/"); pathstr.Prepend(fPath.GetFolder()); } return DPath(pathstr); }
Project * App::CreateNewProject(const BMessage &settings) { Project *proj = NULL; BString projectName, targetName, projectPath, templateName, pldName; int32 projectType, scmType; bool createFolder, populateProject = true; settings.FindString("name",&projectName); settings.FindString("target",&targetName); settings.FindInt32("type",&projectType); settings.FindString("path",&projectPath); settings.FindInt32("scmtype", &scmType); settings.FindBool("createfolder",&createFolder); settings.FindString("template", &templateName); settings.FindString("pldfile", &pldName); if (templateName.CountChars() > 0) { // Templates are now a directory with a TEMPLATEINFO file. All files in the // directory are copies, allowing for much greater flexibility than before. BString projectFileName(projectName); projectFileName << ".pld"; DPath templatePath(gAppPath.GetFolder()); templatePath << "Templates" << templateName; // Copy the contents of the chosen template folder to the project path DPath sourcePath(templatePath); DPath destPath(gProjectPath); if (createFolder) { destPath << projectName; create_directory(destPath.GetFullPath(), 0700); } BString wildcard("'"); wildcard << sourcePath.GetFullPath() << "'/*"; ShellHelper shell("cp -a "); shell << wildcard; shell.AddQuotedArg(destPath.GetFullPath()); shell.Run(); // The copy command copies *everything*, so we have to delete the // TEMPLATEINFO file. DPath templateInfo(destPath); templateInfo << "TEMPLATEINFO"; BEntry infoEntry(templateInfo.GetFullPath()); infoEntry.Remove(); infoEntry.Unset(); DPath finalPath; // Load project and set info or create one, if needed. // If the settings contain the name of a .pld project file, we'll search // for that first. Assuming that it exists, we'll rename that file to the // project name specified. If it doesn't exist or the .pld name is empty, // we'll create a new project with the appropriate name. // The pldname field comes from the TEMPLATEINFO file, which can designate // the main project file in a template. This allows a template to have // multiple project files, such as for the Tracker Add-on development framework // which has both a project file for generating the actual addon and another // one which is the testing framework. bool createProjFile = true; if (pldName.CountChars() > 0) { // If a .pld project file was specified in TEMPLATEINFO, check to see if // the file exists and rename it. If it doesn't exist, we'll create a new // file, and if a .pld file already exists with the intended name, we won't // do anything except tell the user what's happened. DPath oldPldNamePath(destPath); oldPldNamePath << pldName; BEntry oldPldNameEntry(oldPldNamePath.GetFullPath()); DPath newPldNamePath(destPath); newPldNamePath << projectFileName; BEntry newPldNameEntry(newPldNamePath.GetFullPath()); if (newPldNameEntry.Exists()) { // createProjFile is false here only if there is a .pld file with the // user's chosen project name. If that is the case, we keep both files and // let the user sort it out. BString errMsg = B_TRANSLATE( "Project file '%projectname%.pld' already exists. The " "original file for this template is '%pldname%'. You'll need " "to open the project folder and figure out which one you wish to keep."); errMsg.ReplaceFirst("%projectname%", projectName); errMsg.ReplaceFirst("%pldname%", pldName); ShowAlert(errMsg); populateProject = createProjFile = false; finalPath = newPldNamePath; } else if (oldPldNameEntry.Exists()) { oldPldNameEntry.Rename(projectFileName.String()); populateProject = createProjFile = false; finalPath = newPldNamePath; } } if (createProjFile) { proj = Project::CreateProject(projectName.String(), targetName.String(), projectType, projectPath.String(), createFolder); if (proj) finalPath = proj->GetPath(); } else { proj = new Project(); if (proj->Load(finalPath.GetFullPath()) != B_OK) { delete proj; return NULL; } } } else { // This case is for stuff like the Quick Import feature proj = Project::CreateProject(projectName.String(), targetName.String(), projectType, projectPath.String(), createFolder); } if (!proj) return NULL; scm_t detectedSCM = DetectSCM(projectPath); proj->SetSourceControl(detectedSCM == SCM_NONE ? (scm_t)scmType : detectedSCM); gCurrentProject = proj; gProjectList->Lock(); gProjectList->AddItem(proj); gProjectList->Unlock(); BRect r(0,0,200,300); /* r.OffsetTo(gProjectWindowPoint); gProjectWindowPoint.x += 25; gProjectWindowPoint.y += 25; if (gProjectWindowPoint.x < 0) gProjectWindowPoint.x = 0; if (gProjectWindowPoint.y < 0) gProjectWindowPoint.y - 0; */ ProjectWindow *projwin = new ProjectWindow(r,gCurrentProject); projwin->Show(); BEntry entry(gCurrentProject->GetPath().GetFullPath()); if (entry.InitCheck() == B_OK) { entry_ref newprojref; entry.GetRef(&newprojref); UpdateRecentItems(newprojref); } if (populateProject) { entry_ref addRef; int32 i = 0; while (settings.FindRef("libs",i++,&addRef) == B_OK) { if (BEntry(&addRef).Exists()) proj->AddLibrary(DPath(addRef).GetFullPath()); } i = 0; BMessage addMsg(M_IMPORT_REFS); while (settings.FindRef("refs",i++,&addRef) == B_OK) addMsg.AddRef("refs",&addRef); PostToProjectWindow(&addMsg,NULL); } return proj; }
void App::MessageReceived(BMessage *msg) { switch (msg->what) { case M_MAKE_PROJECT: case M_RUN_PROJECT: case M_RUN_IN_TERMINAL: case M_RUN_IN_DEBUGGER: case M_RUN_WITH_ARGS: case M_FORCE_REBUILD: case M_SHOW_ADD_NEW_PANEL: case M_SHOW_FIND_AND_OPEN_PANEL: case M_SHOW_FIND_IN_PROJECT_FILES: case M_SHOW_ERROR_WINDOW: case M_TOGGLE_ERROR_WINDOW: { entry_ref ref; if (msg->FindRef("refs",&ref) == B_OK) PostToProjectWindow(msg,&ref); else PostToProjectWindow(msg,NULL); break; } case M_OPEN_PARTNER: { entry_ref ref; if (msg->FindRef("refs",&ref) == B_OK) OpenPartner(ref); break; } case M_NEW_PROJECT: { TemplateWindow *win = new TemplateWindow(BRect(100, 100, 400, 300)); win->Show(); break; } case M_SHOW_OPEN_PROJECT: { CheckCreateOpenPanel(); fOpenPanel->Show(); break; } case M_CREATE_PROJECT: { CreateNewProject(*msg); break; } case M_QUICK_IMPORT: { entry_ref ref; if (msg->FindRef("refs",&ref) != B_OK || !QuickImportProject(DPath(ref))) { StartWindow *startwin = new StartWindow(); startwin->Show(); break; } break; } // These are for quit determination. We have to use our own counter variable // (sWindowCount) because BFilePanels throw the count off. Using a variable // is much preferable to subclassing just for this reason. case M_REGISTER_WINDOW: { sWindowCount++; break; } case M_DEREGISTER_WINDOW: { sWindowCount--; if (sWindowCount <= 1) PostMessage(B_QUIT_REQUESTED); break; } case EDIT_OPEN_FILE: { int32 index = 0; entry_ref ref; while (msg->FindRef("refs",index,&ref) == B_OK) { int32 line; if (msg->FindInt32("line",index,&line) != B_OK) line = -1; int32 column; if (msg->FindInt32("column",index,&column) != B_OK) column = -1; OpenFile(ref,line,column); index++; } CheckCreateOpenPanel(); fOpenPanel->GetPanelDirectory(&ref); gLastProjectPath.SetTo(ref); BWindow* openWindow = fOpenPanel->Window(); break; } case M_FIND_AND_OPEN_FILE: { FindAndOpenFile(msg); break; } case M_BUILDING_FILE: { SourceFile *file; if (msg->FindPointer("sourcefile",(void**)&file) == B_OK) printf(B_TRANSLATE("Building %s\n"),file->GetPath().GetFileName()); else printf(B_TRANSLATE("NULL pointer in M_BUILDING_FILE\n")); break; } case M_LINKING_PROJECT: { printf(B_TRANSLATE("Linking\n")); break; } case M_UPDATING_RESOURCES: { printf(B_TRANSLATE("Updating resources\n")); break; } case M_BUILD_FAILURE: { BString errstr; if (msg->FindString("errstr",&errstr) == B_OK) printf("%s\n",errstr.String()); else { ErrorList errors; errors.Unflatten(*msg); printf(B_TRANSLATE("Build failure\n%s"), errors.AsString().String()); } sReturnCode = -1; PostMessage(B_QUIT_REQUESTED); break; } case M_BUILD_WARNINGS: { BString errstr; if (msg->FindString("errstr",&errstr) == B_OK) printf("%s\n",errstr.String()); break; } case M_BUILD_SUCCESS: { printf(B_TRANSLATE("Success\n")); PostMessage(B_QUIT_REQUESTED); break; } default: BApplication::MessageReceived(msg); } }
bool SourceFileC::CheckNeedsBuild(BuildInfo &info, bool check_deps) { // The checks for a file needing to be built: // 1) Build flag != BUILD_MAYBE => return result // 2) Object file missing // 3) Source mod time > object mod time // 4) Dependency file needs build // The fast stuff if (!info.objectFolder.GetFullPath()) { STRACE(2,("CheckNeedsBuild: empty file path\n")); return false; } if (BuildFlag() == BUILD_YES) { STRACE(2,("%s::CheckNeedsBuild: build flag == YES\n",GetPath().GetFullPath())); return true; } // Object file existence BString objname(GetPath().GetBaseName()); objname << ".o"; DPath objpath(info.objectFolder); objpath.Append(objname); if (!BEntry(objpath.GetFullPath()).Exists()) { STRACE(2,("%s::CheckNeedsBuild: object doesn't exist\n",GetPath().GetFullPath())); return true; } // source vs object mod time struct stat objstat; if (GetStat(objpath.GetFullPath(),&objstat) != B_OK) { STRACE(2,("%s::CheckNeedsBuild: couldn't stat object\n",GetPath().GetFullPath())); return false; } // Fix mod times set into the future time_t now = real_time_clock(); if (GetModTime() > now) { BNode node(GetPath().GetFullPath()); node.SetModificationTime(now); } if (GetModTime() > objstat.st_mtime) { STRACE(2,("%s::CheckNeedsBuild: file time more recent than object time\n", GetPath().GetFullPath())); return true; } if (!check_deps) { STRACE(2,("%s::CheckNeedsBuild: dependency checking disabled for call\n", GetPath().GetFullPath())); return false; } // Dependency check BString str(GetDependencies()); if (str.CountChars() < 1) { STRACE(2,("%s::CheckNeedsBuild: initial dependency update\n", GetPath().GetFullPath())); UpdateDependencies(info); str = GetDependencies(); } if (str.CountChars() > 0) { char *pathstr; char depString[str.Length() + 1]; sprintf(depString,"%s",str.String()); pathstr = strtok(depString,"|"); while (pathstr) { BString filename(DPath(pathstr).GetFileName()); if (filename.Compare(GetPath().GetFileName()) != 0) { DPath depPath(FindDependency(info,filename.String())); if (!depPath.IsEmpty()) { struct stat depstat; if (GetStat(depPath.GetFullPath(),&depstat) == B_OK && depstat.st_mtime > objstat.st_mtime) { STRACE(2,("%s::CheckNeedsBuild: dependency %s was updated\n", GetPath().GetFullPath(),depPath.GetFullPath())); return true; } } } pathstr = strtok(NULL,"|"); } } return false; }