void ReopenEditor::OnEditorClosed(CodeBlocksEvent& event) { EditorBase* eb = event.GetEditor(); if(eb && eb->IsBuiltinEditor()) { cbProject* prj = nullptr; bool isPrjClosing = false; ProjectFile* prjf = ((cbEditor*)eb)->GetProjectFile(); if(prjf) prj = prjf->GetParentProject(); wxString name = wxEmptyString; if(prj) { isPrjClosing = (m_ClosedProjects.Index(prj) != wxNOT_FOUND); name = prj->GetTitle(); } if(!prj || (prj && !isPrjClosing)) { wxArrayString list; list.Add(eb->GetFilename()); if(prj) { list.Add(prj->GetTitle()); list.Add(prj->GetFilename()); } else { list.Add(_("<none>")); list.Add(_("<none>")); } m_pListLog->Prepend(list); m_pListLog->SetProject(0, prj); } } wxMenuBar* menuBar = Manager::Get()->GetAppFrame()->GetMenuBar(); menuBar->Enable(idReopenEditor, (m_pListLog->GetItemsCount() > 0)); event.Skip(); }
// Don't call this function from within the scope of: // ClangPlugin::OnEditorHook // ClangPlugin::OnTimer int ClangPlugin::UpdateCompileCommand(cbEditor* ed) { wxString compileCommand; ProjectFile* pf = ed->GetProjectFile(); m_UpdateCompileCommand++; if ( m_UpdateCompileCommand > 1 ) { // Re-entry is not allowed m_UpdateCompileCommand--; return 0; } ProjectBuildTarget* target = nullptr; Compiler* comp = nullptr; if (pf && pf->GetParentProject() && !pf->GetBuildTargets().IsEmpty()) { target = pf->GetParentProject()->GetBuildTarget(pf->GetBuildTargets()[0]); comp = CompilerFactory::GetCompiler(target->GetCompilerID()); } cbProject* proj = (pf ? pf->GetParentProject() : nullptr); if ( (!comp) && proj) comp = CompilerFactory::GetCompiler(proj->GetCompilerID()); if (!comp) { cbProject* tmpPrj = Manager::Get()->GetProjectManager()->GetActiveProject(); if (tmpPrj) comp = CompilerFactory::GetCompiler(tmpPrj->GetCompilerID()); } if (!comp) comp = CompilerFactory::GetDefaultCompiler(); if (pf && (!pf->GetBuildTargets().IsEmpty()) ) { target = pf->GetParentProject()->GetBuildTarget(pf->GetBuildTargets()[0]); if (pf->GetUseCustomBuildCommand(target->GetCompilerID() )) compileCommand = pf->GetCustomBuildCommand(target->GetCompilerID()).AfterFirst(wxT(' ')); } if (compileCommand.IsEmpty()) compileCommand = wxT("$options $includes"); CompilerCommandGenerator* gen = comp->GetCommandGenerator(proj); if (gen) gen->GenerateCommandLine(compileCommand, target, pf, ed->GetFilename(), g_InvalidStr, g_InvalidStr, g_InvalidStr ); delete gen; wxStringTokenizer tokenizer(compileCommand); compileCommand.Empty(); wxString pathStr; while (tokenizer.HasMoreTokens()) { wxString flag = tokenizer.GetNextToken(); // make all include paths absolute, so clang does not choke if Code::Blocks switches directories if (flag.StartsWith(wxT("-I"), &pathStr)) { wxFileName path(pathStr); if (path.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE)) flag = wxT("-I") + path.GetFullPath(); } compileCommand += flag + wxT(" "); } compileCommand += GetCompilerInclDirs(comp->GetID()); m_UpdateCompileCommand--; if (compileCommand != m_CompileCommand) { m_CompileCommand = compileCommand; return 1; } return 0; }
wxString ClangPlugin::GetSourceOf(cbEditor* ed) { cbProject* project = nullptr; ProjectFile* opf = ed->GetProjectFile(); if (opf) project = opf->GetParentProject(); if (!project) project = Manager::Get()->GetProjectManager()->GetActiveProject(); wxFileName theFile(ed->GetFilename()); wxFileName candidateFile; bool isCandidate; wxArrayString fileArray; wxDir::GetAllFiles(theFile.GetPath(wxPATH_GET_VOLUME), &fileArray, theFile.GetName() + wxT(".*"), wxDIR_FILES | wxDIR_HIDDEN); wxFileName currentCandidateFile = FindSourceIn(fileArray, theFile, isCandidate); if (isCandidate) candidateFile = currentCandidateFile; else if (currentCandidateFile.IsOk()) return currentCandidateFile.GetFullPath(); fileArray.Clear(); EditorManager* edMgr = Manager::Get()->GetEditorManager(); for (int i = 0; i < edMgr->GetEditorsCount(); ++i) { cbEditor* edit = edMgr->GetBuiltinEditor(i); if (!edit) continue; ProjectFile* pf = edit->GetProjectFile(); if (!pf) continue; fileArray.Add(pf->file.GetFullPath()); } currentCandidateFile = FindSourceIn(fileArray, theFile, isCandidate); if (!isCandidate && currentCandidateFile.IsOk()) return currentCandidateFile.GetFullPath(); if (project) { fileArray.Clear(); for (FilesList::const_iterator it = project->GetFilesList().begin(); it != project->GetFilesList().end(); ++it) { ProjectFile* pf = *it; if (!pf) continue; fileArray.Add(pf->file.GetFullPath()); } currentCandidateFile = FindSourceIn(fileArray, theFile, isCandidate); if (isCandidate && !candidateFile.IsOk()) candidateFile = currentCandidateFile; else if (currentCandidateFile.IsOk()) return currentCandidateFile.GetFullPath(); wxArrayString dirs = project->GetIncludeDirs(); for (int i = 0; i < project->GetBuildTargetsCount(); ++i) { ProjectBuildTarget* target = project->GetBuildTarget(i); if (target) { for (size_t ti = 0; ti < target->GetIncludeDirs().GetCount(); ++ti) { wxString dir = target->GetIncludeDirs()[ti]; if (dirs.Index(dir) == wxNOT_FOUND) dirs.Add(dir); } } } for (size_t i = 0; i < dirs.GetCount(); ++i) { wxString dir = dirs[i]; Manager::Get()->GetMacrosManager()->ReplaceMacros(dir); wxFileName dname(dir); if (!dname.IsAbsolute()) dname.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE, project->GetBasePath()); fileArray.Clear(); wxDir::GetAllFiles(dname.GetPath(), &fileArray, theFile.GetName() + wxT(".*"), wxDIR_FILES | wxDIR_HIDDEN); currentCandidateFile = FindSourceIn(fileArray, theFile, isCandidate); if (isCandidate) candidateFile = currentCandidateFile; else if (currentCandidateFile.IsOk()) return currentCandidateFile.GetFullPath(); } } if (candidateFile.IsOk()) return candidateFile.GetFullPath(); return wxEmptyString; }
void ClangPlugin::OnTimer(wxTimerEvent& event) { if (!IsAttached()) return; const int evId = event.GetId(); if (evId == idEdOpenTimer) { cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor(); if (!ed || !IsProviderFor(ed)) return; else if (m_Proxy.GetTranslationUnitId(ed->GetFilename()) != wxNOT_FOUND) { m_DiagnosticTimer.Start(DIAGNOSTIC_DELAY, wxTIMER_ONE_SHOT); return; } wxString compileCommand; ProjectFile* pf = ed->GetProjectFile(); ProjectBuildTarget* target = nullptr; Compiler* comp = nullptr; if (pf && pf->GetParentProject() && !pf->GetBuildTargets().IsEmpty() ) { target = pf->GetParentProject()->GetBuildTarget(pf->GetBuildTargets()[0]); comp = CompilerFactory::GetCompiler(target->GetCompilerID()); if (pf->GetUseCustomBuildCommand(target->GetCompilerID())) { compileCommand = pf->GetCustomBuildCommand(target->GetCompilerID()).AfterFirst(wxT(' ')); } } if (compileCommand.IsEmpty()) compileCommand = wxT("$options $includes"); cbProject* proj = (pf ? pf->GetParentProject() : nullptr); if (!comp && proj) comp = CompilerFactory::GetCompiler(proj->GetCompilerID()); if (!comp) { cbProject* tmpPrj = Manager::Get()->GetProjectManager()->GetActiveProject(); if (tmpPrj) comp = CompilerFactory::GetCompiler(tmpPrj->GetCompilerID()); } if (!comp) comp = CompilerFactory::GetDefaultCompiler(); comp->GetCommandGenerator(proj)->GenerateCommandLine(compileCommand, target, pf, ed->GetFilename(), g_InvalidStr, g_InvalidStr, g_InvalidStr ); wxStringTokenizer tokenizer(compileCommand); compileCommand.Empty(); wxString pathStr; while (tokenizer.HasMoreTokens()) { wxString flag = tokenizer.GetNextToken(); // make all include paths absolute, so clang does not choke if Code::Blocks switches directories if (flag.StartsWith(wxT("-I"), &pathStr)) { wxFileName path(pathStr); if (path.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE)) flag = wxT("-I") + path.GetFullPath(); } compileCommand += flag + wxT(" "); } compileCommand += GetCompilerInclDirs(comp->GetID()); if (FileTypeOf(ed->GetFilename()) == ftHeader) // try to find the associated source { const wxString& source = GetSourceOf(ed); if (!source.IsEmpty()) { m_Proxy.CreateTranslationUnit(source, compileCommand); if (m_Proxy.GetTranslationUnitId(ed->GetFilename()) != wxNOT_FOUND) return; // got it } } m_Proxy.CreateTranslationUnit(ed->GetFilename(), compileCommand); m_DiagnosticTimer.Start(DIAGNOSTIC_DELAY, wxTIMER_ONE_SHOT); } else if (evId == idReparseTimer) { EditorManager* edMgr = Manager::Get()->GetEditorManager(); cbEditor* ed = edMgr->GetBuiltinActiveEditor(); if (!ed) return; if (ed != m_pLastEditor) { m_TranslUnitId = m_Proxy.GetTranslationUnitId(ed->GetFilename()); m_pLastEditor = ed; } if (m_TranslUnitId == wxNOT_FOUND) return; std::map<wxString, wxString> unsavedFiles; for (int i = 0; i < edMgr->GetEditorsCount(); ++i) { ed = edMgr->GetBuiltinEditor(i); if (ed && ed->GetModified()) unsavedFiles.insert(std::make_pair(ed->GetFilename(), ed->GetControl()->GetText())); } m_Proxy.Reparse(m_TranslUnitId, unsavedFiles); DiagnoseEd(m_pLastEditor, dlMinimal); } else if (evId == idDiagnosticTimer) { cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor(); if (!ed) return; if (ed != m_pLastEditor) { m_TranslUnitId = m_Proxy.GetTranslationUnitId(ed->GetFilename()); m_pLastEditor = ed; } if (m_TranslUnitId == wxNOT_FOUND) return; DiagnoseEd(ed, dlFull); } else event.Skip(); }