From c957fdb1acec9d790a587518b2479ea241d1e38b Mon Sep 17 00:00:00 2001 From: Wesley Pesetti Date: Mon, 22 Dec 2014 19:44:56 -0800 Subject: [PATCH 1/7] Added Directories and Window colors Added ability for directories to be added to the project. (No support for version control) Added another display item under Fonts and Colors to change the color of the background and text used in the window. --- src/Frontend/AutoCompleteManager.cpp | 9 + src/Frontend/BreakpointsWindow.cpp | 10 +- src/Frontend/BreakpointsWindow.h | 6 + src/Frontend/FontColorSettings.cpp | 7 +- src/Frontend/FontColorSettings.h | 1 + src/Frontend/ListWindow.cpp | 5 + src/Frontend/ListWindow.h | 6 + src/Frontend/MainFrame.cpp | 77 ++- src/Frontend/MainFrame.h | 11 + src/Frontend/OutputWindow.cpp | 12 +- src/Frontend/Project.cpp | 209 +++++++- src/Frontend/Project.h | 100 +++- src/Frontend/ProjectExplorerWindow.cpp | 171 ++++++- src/Frontend/ProjectExplorerWindow.h | 40 +- src/Frontend/ProjectFileInfoCtrl.cpp | 6 + src/Frontend/ProjectFileInfoCtrl.h | 8 + src/Frontend/SearchWindow.cpp | 8 +- src/Frontend/SymbolParser.cpp | 9 + src/Frontend/SymbolParserEvent.h | 4 +- src/Frontend/SymbolParserThread.cpp | 1 - src/Frontend/WatchCtrl.cpp | 8 +- src/Frontend/WatchCtrl.h | 8 +- src/Frontend/res/explorer.xpm | 632 ++++++++++++++----------- 23 files changed, 1013 insertions(+), 335 deletions(-) diff --git a/src/Frontend/AutoCompleteManager.cpp b/src/Frontend/AutoCompleteManager.cpp index 7a763868..3f7ffa8a 100644 --- a/src/Frontend/AutoCompleteManager.cpp +++ b/src/Frontend/AutoCompleteManager.cpp @@ -49,6 +49,15 @@ void AutoCompleteManager::BuildFromProject(const Project* project) { BuildFromFile(project->GetFile(fileIndex)); } + for (unsigned int directoryIndex = 0; directoryIndex < project->GetNumDirectories(); ++directoryIndex) + { + Project::Directory const *directory = project->GetDirectory(directoryIndex); + + for (unsigned int fileIndex = 0; fileIndex < project->GetNumFiles(); ++fileIndex) + { + BuildFromFile(directory->files[fileIndex]); + } + } // Sort the autocompletions (necessary for binary search). std::sort(m_entries.begin(), m_entries.end()); diff --git a/src/Frontend/BreakpointsWindow.cpp b/src/Frontend/BreakpointsWindow.cpp index fa12fadc..a6cb2890 100644 --- a/src/Frontend/BreakpointsWindow.cpp +++ b/src/Frontend/BreakpointsWindow.cpp @@ -95,12 +95,20 @@ BreakpointsWindow::BreakpointsWindow(MainFrame* mainFrame, wxWindowID winid) fgSizer1->Add( m_buttonBar, 0, wxALL|wxEXPAND, 3 ); fgSizer1->Add( m_breakpointList, 0, wxALL|wxEXPAND, 0 ); - + + + SetSizer( fgSizer1 ); Layout(); } +void BreakpointsWindow::SetFontColorSettings(const FontColorSettings& settings) +{ + m_breakpointList->SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); + m_breakpointList->SetTextColour(settings.GetColors(FontColorSettings::DisplayItem_Window).foreColor); +} + void BreakpointsWindow::SetProject(Project* project) { m_project = project; diff --git a/src/Frontend/BreakpointsWindow.h b/src/Frontend/BreakpointsWindow.h index a86ae191..3af4fb86 100644 --- a/src/Frontend/BreakpointsWindow.h +++ b/src/Frontend/BreakpointsWindow.h @@ -24,6 +24,7 @@ along with Decoda. If not, see . #define BREAKPOINTS_WINDOW_H #include "Project.h" +#include "FontColorSettings.h" #include #include @@ -51,6 +52,11 @@ class BreakpointsWindow : public wxPanel */ BreakpointsWindow(MainFrame* mainFrame, wxWindowID winid); + /** + * Updates the colors of the panel to match the settings + */ + void SetFontColorSettings(const FontColorSettings& settings); + /** * Sets the project we're displaying the breakpoints for. */ diff --git a/src/Frontend/FontColorSettings.cpp b/src/Frontend/FontColorSettings.cpp index 49881350..65c83ac7 100644 --- a/src/Frontend/FontColorSettings.cpp +++ b/src/Frontend/FontColorSettings.cpp @@ -25,7 +25,7 @@ along with Decoda. If not, see . #include -const char* FontColorSettings::s_displayItemName[] = { "Default", "Comment", "Keyword", "Operator", "String", "Number", "Error", "Warning", "Selection" }; +const char* FontColorSettings::s_displayItemName[] = { "Default", "Comment", "Keyword", "Operator", "String", "Number", "Error", "Warning", "Selection", "Window" }; FontColorSettings::FontColorSettings() { @@ -77,6 +77,11 @@ FontColorSettings::FontColorSettings() m_colors[DisplayItem_Selection].bold = false; m_colors[DisplayItem_Selection].italic = false; + m_colors[DisplayItem_Window].foreColor = wxColor(255,255,255); + m_colors[DisplayItem_Window].backColor = wxColor(51,51,51); + m_colors[DisplayItem_Window].bold = false; + m_colors[DisplayItem_Window].italic = false; + } unsigned int FontColorSettings::GetNumDisplayItems() const diff --git a/src/Frontend/FontColorSettings.h b/src/Frontend/FontColorSettings.h index d327594c..b8c2c51d 100644 --- a/src/Frontend/FontColorSettings.h +++ b/src/Frontend/FontColorSettings.h @@ -52,6 +52,7 @@ class FontColorSettings DisplayItem_Error, DisplayItem_Warning, DisplayItem_Selection, + DisplayItem_Window, DisplayItem_Last, }; diff --git a/src/Frontend/ListWindow.cpp b/src/Frontend/ListWindow.cpp index a1989adf..3382eb07 100644 --- a/src/Frontend/ListWindow.cpp +++ b/src/Frontend/ListWindow.cpp @@ -49,7 +49,12 @@ ListWindow::ListWindow(MainFrame* mainFrame, wxWindowID winid) imageList->Add( wxMEMORY_BITMAP(Currentline_png) ); AssignImageList(imageList, wxIMAGE_LIST_SMALL); +} +void ListWindow::SetFontColorSettings(const FontColorSettings& settings) +{ + SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); + SetTextColour(settings.GetColors(FontColorSettings::DisplayItem_Window).foreColor); } void ListWindow::Append(const wxString& name) diff --git a/src/Frontend/ListWindow.h b/src/Frontend/ListWindow.h index b592431d..c45c3dfa 100644 --- a/src/Frontend/ListWindow.h +++ b/src/Frontend/ListWindow.h @@ -26,6 +26,7 @@ along with Decoda. If not, see . #include #include "ListView.h" +#include "FontColorSettings.h" // // Forward declarations. @@ -52,6 +53,11 @@ class ListWindow : public ListView */ ListWindow(MainFrame* mainFrame, wxWindowID winid); + /** + * Updates the colors of the panel to match the settings + */ + void SetFontColorSettings(const FontColorSettings& settings); + /** * Adds an item to the list. */ diff --git a/src/Frontend/MainFrame.cpp b/src/Frontend/MainFrame.cpp index c060d579..d933eccb 100644 --- a/src/Frontend/MainFrame.cpp +++ b/src/Frontend/MainFrame.cpp @@ -67,6 +67,7 @@ along with Decoda. If not, see . #include #include #include +#include #include #include #include @@ -132,6 +133,7 @@ BEGIN_EVENT_TABLE(MainFrame, wxFrame) // Project menu events. EVT_MENU(ID_ProjectAddExistingFile, MainFrame::OnProjectAddExistingFile) + EVT_MENU(ID_ProjectAddDirectory, MainFrame::OnProjectAddDirectory) EVT_MENU(ID_ProjectAddNewFile, MainFrame::OnProjectAddNewFile) EVT_MENU(ID_ProjectSettings, MainFrame::OnProjectSettings) EVT_MENU(ID_FileNewProject, MainFrame::OnFileNewProject) @@ -275,6 +277,7 @@ BEGIN_EVENT_TABLE(MainFrame, wxFrame) EVT_COMMAND(wxID_ANY, wxEVT_UPDATE_INFO_EVENT, MainFrame::OnUpdateInfo) EVT_SYMBOL_PARSER( MainFrame::OnSymbolsParsed) + //EVT_SYMBOL_PARSER( MainFrame::OnSymbolsParsed) END_EVENT_TABLE() @@ -490,6 +493,7 @@ MainFrame::MainFrame(const wxString& title, int openFilesMessage, const wxPoint& m_symbolParser = new SymbolParser; m_symbolParser->SetEventHandler(this); + m_waitForFinalSymbolParse = false; // Creating a new project will clear this out, so save it. @@ -630,6 +634,7 @@ void MainFrame::InitializeMenu() menuProject->AppendSeparator(); menuProject->Append(ID_ProjectAddNewFile, _("Add Ne&w File...")); menuProject->Append(ID_ProjectAddExistingFile, _("Add Existin&g File...")); + menuProject->Append(ID_ProjectAddDirectory, _("Add Directory...")); menuProject->AppendSeparator(); menuProject->AppendSubMenu(menuRecentProjects, _("&Recent Files...")); menuProject->AppendSeparator(); @@ -709,7 +714,6 @@ void MainFrame::InitializeMenu() menuBar->Append( menuHelp, _("&Help")); SetMenuBar( menuBar ); - } void MainFrame::OnFileNewProject(wxCommandEvent& WXUNUSED(event)) @@ -1354,6 +1358,29 @@ void MainFrame::OnProjectAddExistingFile(wxCommandEvent& WXUNUSED(event)) } +void MainFrame::OnProjectAddDirectory(wxCommandEvent& event) +{ + wxDirDialog dialog(this, _("Add Directory"), m_project->GetBaseDirectory(), wxDD_DEFAULT_STYLE); + + if (dialog.ShowModal() == wxID_OK) + { + Project::Directory *directory = m_project->AddDirectory(dialog.GetPath()); + + m_projectExplorer->InsertDirectory(directory); + + for (Project::File *file : directory->files) + { + m_symbolParser->QueueForParsing(file); + m_autoCompleteManager.BuildFromProject(m_project); + + // Update the status for the new files. + UpdateProjectFileStatus(file); + } + } + + +} + void MainFrame::OnProjectSettings(wxCommandEvent& WXUNUSED(event)) { ShowProjectSettingsDialog(); @@ -3257,14 +3284,14 @@ void MainFrame::OnProjectExplorerItemActivated(wxTreeEvent& event) ProjectExplorerWindow::ItemData* data = m_projectExplorer->GetDataForItem(item); - if (data != NULL && data->file != NULL) + if (data != NULL && data->file != NULL && data->isFile) { - - OpenFile* file = OpenProjectFile(data->file); + Project::File *dataFile = (Project::File *)data->file; + OpenFile* file = OpenProjectFile(dataFile); if (file == NULL) { - wxMessageBox(wxString::Format("The file '%s' could not be opened.", data->file->fileName.GetFullPath())); + wxMessageBox(wxString::Format("The file '%s' could not be opened.", dataFile->fileName.GetFullPath())); } else { @@ -3298,6 +3325,14 @@ void MainFrame::OnProjectExplorerKeyDown(wxTreeEvent& event) } } + std::vector directories; + m_projectExplorer->GetSelectedDirectories(directories); + for (unsigned int i = 0; i < directories.size(); ++i) + { + DeleteProjectDirectory(directories[i]); + alltemp = false; + } + if (alltemp) { // Tell the user why we didn't delete any of the files the selected. @@ -4425,6 +4460,27 @@ void MainFrame::DeleteProjectFile(Project::File* file) } +void MainFrame::DeleteProjectDirectory(Project::Directory* directory) +{ + for (Project::File *file : directory->files) + { + for (unsigned int i = 0; i < m_openFiles.size(); ++i) + { + if (m_openFiles[i]->file == file) + { + m_notebook->DeletePage(i); + m_openFiles.erase(m_openFiles.begin() + i); + RemovePageFromTabOrder(i); + break; + } + } + m_breakpointsWindow->RemoveFile(file); + } + + m_projectExplorer->RemoveDirectory(directory); + m_project->RemoveDirectory(directory); +} + void MainFrame::AddVmToList(unsigned int vm) { @@ -4670,7 +4726,18 @@ void MainFrame::UpdateEditorOptions() } // Set the font of the output window to match the code editor. + m_mgr.GetArtProvider()->SetColor(wxAUI_DOCKART_SASH_COLOUR, m_fontColorSettings.GetColors(FontColorSettings::DisplayItem_Window).backColor); + + m_searchWindow->SetFontColorSettings(m_fontColorSettings); + m_breakpointsWindow->SetFontColorSettings(m_fontColorSettings); + m_projectExplorer->SetFontColorSettings(m_fontColorSettings); m_output->SetFontColorSettings(m_fontColorSettings); + m_watch->SetFontColorSettings(m_fontColorSettings); + m_callStack->SetFontColorSettings(m_fontColorSettings); + m_vmList->SetFontColorSettings(m_fontColorSettings); + + //Have to repaint to get the sash color. + this->Refresh(); // Set the font of the watch window to match the code editor so // that non-ASCII text will be displayed properly. diff --git a/src/Frontend/MainFrame.h b/src/Frontend/MainFrame.h index c88af491..9fe8aa00 100644 --- a/src/Frontend/MainFrame.h +++ b/src/Frontend/MainFrame.h @@ -244,6 +244,11 @@ class MainFrame: public wxFrame */ void OnProjectAddExistingFile(wxCommandEvent& event); + /** + * Called when the user selects Project/Add Directory from the menu. + */ + void OnProjectAddDirectory(wxCommandEvent& event); + /** * Called when the user selects Project/Add New File from the menu. */ @@ -1081,6 +1086,11 @@ class MainFrame: public wxFrame */ void DeleteProjectFile(Project::File* file); + /** + * Removes a directory from the project (does not delete the directory on disk). + */ + void DeleteProjectDirectory(Project::Directory* directory); + /** * Updates the break point marker in an open file. If set is enabled the * marker will be added at the specified line, otherwise it will be removed. @@ -1369,6 +1379,7 @@ class MainFrame: public wxFrame ID_EditFind = 16, ID_EditFindNext = 17, ID_ProjectAddExistingFile = 18, + ID_ProjectAddDirectory = 88, ID_ProjectSettings = 19, ID_DebugStart = 20, ID_DebugStop = 21, diff --git a/src/Frontend/OutputWindow.cpp b/src/Frontend/OutputWindow.cpp index e5cb5597..c899bc74 100644 --- a/src/Frontend/OutputWindow.cpp +++ b/src/Frontend/OutputWindow.cpp @@ -46,18 +46,18 @@ void OutputWindow::SetFontColorSettings(const FontColorSettings& settings) // happens often enough for it to really make much difference. Clear(); - SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Default).backColor); + SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); - m_messageAttr.SetTextColour(settings.GetColors(FontColorSettings::DisplayItem_Default).foreColor); - m_messageAttr.SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Default).backColor); - m_messageAttr.SetFont(settings.GetFont(FontColorSettings::DisplayItem_Default)); + m_messageAttr.SetTextColour(settings.GetColors(FontColorSettings::DisplayItem_Window).foreColor); + m_messageAttr.SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); + m_messageAttr.SetFont(settings.GetFont(FontColorSettings::DisplayItem_Window)); m_warningAttr.SetTextColour(settings.GetColors(FontColorSettings::DisplayItem_Warning).foreColor); - m_warningAttr.SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Warning).backColor); + m_warningAttr.SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); m_warningAttr.SetFont(settings.GetFont(FontColorSettings::DisplayItem_Warning)); m_errorAttr.SetTextColour(settings.GetColors(FontColorSettings::DisplayItem_Error).foreColor); - m_errorAttr.SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Error).backColor); + m_errorAttr.SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); m_errorAttr.SetFont(settings.GetFont(FontColorSettings::DisplayItem_Error)); } diff --git a/src/Frontend/Project.cpp b/src/Frontend/Project.cpp index e32ba8b6..c85db727 100644 --- a/src/Frontend/Project.cpp +++ b/src/Frontend/Project.cpp @@ -28,6 +28,7 @@ along with Decoda. If not, see . #include "Symbol.h" #include +#include #include #include @@ -281,6 +282,16 @@ const Project::File* Project::GetFile(unsigned int fileIndex) const return m_files[fileIndex]; } +const Project::Directory *Project::GetDirectory(unsigned int dirIndex) const +{ + return m_directories[dirIndex]; +} + +Project::Directory *Project::GetDirectory(unsigned int dirIndex) +{ + return m_directories[dirIndex]; +} + Project::File* Project::GetFileById(unsigned int fileId) { @@ -292,6 +303,18 @@ Project::File* Project::GetFileById(unsigned int fileId) } } + for (unsigned int directoryIndex = 0; directoryIndex < m_directories.size(); ++directoryIndex) + { + Project::Directory *directory = m_directories[directoryIndex]; + for (unsigned int fileIndex = 0; fileIndex < directory->files.size(); ++fileIndex) + { + if (directory->files[fileIndex]->fileId == fileId) + { + return directory->files[fileIndex]; + } + } + } + return NULL; } @@ -301,6 +324,11 @@ unsigned int Project::GetNumFiles() const return m_files.size(); } +unsigned int Project::GetNumDirectories() const +{ + return m_directories.size(); +} + Project::File* Project::AddFile(const wxString& fileName) { @@ -335,6 +363,71 @@ Project::File* Project::AddFile(const wxString& fileName) } +Project::Directory* Project::AddDirectory(const wxString& directoryStr) +{ + wxString directoryName = directoryStr; + + wxString fullDir; + wxFileName path(directoryName); + path.Normalize(wxPATH_NORM_ALL, m_baseDirectory); + path.MakeRelativeTo(m_baseDirectory); + fullDir = path.GetFullPath(); + + for (unsigned int i = 0; i < m_directories.size(); ++i) + { + if (m_directories[i]->path == fullDir) + { + return NULL; + } + } + + wxDir directory(m_baseDirectory + "\\" + fullDir); + wxArrayString filenames; + + Directory *dir = new Directory; + + if (directory.IsOpened()) + { + wxString dirPath = directory.GetName(); + + wxFileName name(m_baseDirectory + "\\" + fullDir); + name.Normalize(); + + dir->name = name.GetFullPath(); + dir->path = fullDir; + + directory.GetAllFiles(dirPath, &filenames, wxEmptyString, wxDIR_DIRS | wxDIR_FILES); + } + + for (auto &filename : filenames) + { + File* file = new File; + + file->state = CodeState_Normal; + file->scriptIndex = -1; + file->temporary = false; + file->status = Status_None; + file->fileId = ++s_lastFileId; + + wxFileName localPath(filename); + localPath.MakeRelativeTo(dir->name); + + file->localPath = localPath.GetPath(); + file->fileName = filename; + if (file->fileName.IsRelative()) + { + file->fileName.MakeAbsolute(m_baseDirectory); + } + + dir->files.push_back(file); + } + + m_directories.push_back(dir); + m_needsSave = true; + + return dir; +} + Project::File* Project::AddTemporaryFile(unsigned int scriptIndex) { @@ -401,7 +494,31 @@ void Project::RemoveFile(File* file) ClearVector(file->symbols); delete file; +} + +void Project::RemoveDirectory(Directory* directory) +{ + std::vector::iterator iterator = m_directories.begin(); + while (iterator != m_directories.end()) + { + if (directory == *iterator) + { + for (File *file : directory->files) + { + ClearVector(file->symbols); + delete file; + } + + m_directories.erase(iterator); + m_needsSave = true; + m_needsUserSave = true; + break; + } + ++iterator; + } + + delete directory; } void Project::CleanUpAfterSession() @@ -544,6 +661,16 @@ wxXmlNode* Project::SaveFileNode(const wxString& baseDirectory, const File* file } +wxXmlNode* Project::SaveDirectoryNode(const Directory* dir) +{ + //Convert empty string to current directory. + wxString path = dir->path; + if (path == "") + path = ".\\"; + + return WriteXmlNode("directory", path); +} + wxXmlNode* Project::SaveUserFileNode(const wxString& baseDirectory, const File* file) const { @@ -717,6 +844,66 @@ bool Project::LoadFileNode(const wxString& baseDirectory, wxXmlNode* node) } +bool Project::LoadDirectoryNode(const wxString& baseDirectory, wxXmlNode* node) +{ + if (node->GetName() != "directory") + { + return false; + } + wxString directoryName; + wxArrayString filenames; + + + if (ReadXmlNode(node, "directory", directoryName)) + { + wxString fullDir; + wxFileName path(directoryName); + path.Normalize(wxPATH_NORM_ALL, m_baseDirectory); + path.MakeRelativeTo(m_baseDirectory); + fullDir = path.GetFullPath(); + + wxDir directory(m_baseDirectory + "\\" + fullDir); + + Directory *dir = new Directory; + + if (directory.IsOpened()) + { + wxString dirPath = directory.GetName(); + + wxFileName name(m_baseDirectory + "\\" + fullDir); + name.Normalize(); + + dir->name = name.GetFullPath(); + dir->path = fullDir; + directory.GetAllFiles(dirPath, &filenames, wxEmptyString, wxDIR_DIRS | wxDIR_FILES); + } + + for (auto &filename : filenames) + { + File* file = new File; + + file->state = CodeState_Normal; + file->scriptIndex = -1; + file->temporary = false; + file->status = Status_None; + file->fileId = ++s_lastFileId; + + wxFileName localPath(filename); + localPath.MakeRelativeTo(dir->name); + + file->localPath = localPath.GetPath(); + file->fileName = filename; + + dir->files.push_back(file); + } + + m_directories.push_back(dir); + } + + return true; + +} + std::vector Project::GetSortedFileList() { struct SortByDisplayName @@ -765,6 +952,15 @@ bool Project::SaveGeneralSettings(const wxString& fileName) } } + for (unsigned int i = 0; i < m_directories.size(); ++i) + { + Directory* dir = m_directories[i]; + assert(dir != NULL); + + wxXmlNode* node = SaveDirectoryNode(dir); + root->AddChild(node); + } + return document.Save(fileName); } @@ -876,7 +1072,7 @@ bool Project::LoadGeneralSettings(const wxString& fileName) // Disable logging. wxLogNull logNo; - wxString baseDirectory = wxFileName(fileName).GetPath(); + m_baseDirectory = wxFileName(fileName).GetPath(); wxXmlDocument document; @@ -896,7 +1092,11 @@ bool Project::LoadGeneralSettings(const wxString& fileName) while (node != NULL) { - LoadFileNode(baseDirectory, node); + if (node->GetName() == "file") + LoadFileNode(m_baseDirectory, node); + else if (node->GetName() == "directory") + LoadDirectoryNode(m_baseDirectory, node); + node = node->GetNext(); } @@ -934,4 +1134,9 @@ bool Project::LoadSccNode(wxXmlNode* root) return true; +} + +wxString Project::GetBaseDirectory() const +{ + return m_baseDirectory; } \ No newline at end of file diff --git a/src/Frontend/Project.h b/src/Frontend/Project.h index c74f62dd..d3c6903b 100644 --- a/src/Frontend/Project.h +++ b/src/Frontend/Project.h @@ -30,6 +30,7 @@ along with Decoda. If not, see . #include +#undef RemoveDirectory // // Forward declarations. // @@ -61,6 +62,7 @@ class Project CodeState state; bool temporary; unsigned int scriptIndex; + wxString localPath; wxFileName fileName; std::vector breakpoints; wxString tempName; @@ -73,6 +75,21 @@ class Project }; + struct Directory + { + ~Directory() + { + for (File *p : files) + { + delete p; + } + } + + wxString path; + wxString name; + std::vector files; + }; + /** * Constructor. */ @@ -225,6 +242,11 @@ class Project */ File* AddFile(const wxString& fileName); + /** + * Adds a directory to the project. The new directory is returned. + */ + Directory* AddDirectory(const wxString& fileName); + /** * Adds a script to the project temporarily (during this debug sesssion). The * new file is returned. @@ -242,6 +264,11 @@ class Project */ void RemoveFile(File* file); + /** + * Removes a directory from the project. + */ + void RemoveDirectory(Directory* directory); + /** * Gets the specified file. */ @@ -252,6 +279,17 @@ class Project */ const File* GetFile(unsigned int fileIndex) const; + + /** + * Gets the specified directory. + */ + Directory* GetDirectory(unsigned int dirIndex); + + /** + * Gets the specified directory. + */ + const Directory *GetDirectory(unsigned int dirIndex) const; + /** * Returns the file with the specified file id, or NULL if the file doesn't * exist in the project. @@ -263,6 +301,12 @@ class Project */ unsigned int GetNumFiles() const; + /** + * Gets the number of directories in the project. + */ + unsigned int GetNumDirectories() const; + + /** * Clears the script indices for all of the files. */ @@ -285,6 +329,11 @@ class Project */ void DeleteAllBreakpoints(File* file); + /** + * Gets the base directory path + */ + wxString GetBaseDirectory() const; + private: /** @@ -293,6 +342,12 @@ class Project */ wxXmlNode* SaveFileNode(const wxString& baseDirectory, const File* file); + /** + * Creates a new XML node representing a directory. The directory name is stored + relative to the project. + */ + wxXmlNode* SaveDirectoryNode(const Directory* file); + /** * Creates a new XML node representing the user settings for a file. The * file name is stored relative to the specified base directory. @@ -307,6 +362,8 @@ class Project */ bool LoadFileNode(const wxString& baseDirectory, wxXmlNode* node); + bool LoadDirectoryNode(const wxString& baseDirectory, wxXmlNode* node); + /** * Loads the user data for a file from an XML node. If the XML node is not * a file node, the method returns false. @@ -363,27 +420,28 @@ class Project // Returns vector for temporary internal use std::vector GetSortedFileList(); - static unsigned int s_lastFileId; - - bool m_needsSave; - bool m_needsUserSave; - wxString m_fileName; - - wxString m_commandLine; - wxString m_commandArguments; - wxString m_workingDirectory; - wxString m_symbolsDirectory; - - std::vector m_files; - - unsigned int m_tempIndex; - - wxString m_sccProvider; - wxString m_sccUser; - wxString m_sccProjName; - wxString m_sccLocalPath; - wxString m_sccAuxProjPath; - + static unsigned int s_lastFileId; + + bool m_needsSave; + bool m_needsUserSave; + wxString m_fileName; + + wxString m_commandLine; + wxString m_commandArguments; + wxString m_workingDirectory; + wxString m_symbolsDirectory; + + std::vector m_files; + std::vector m_directories; + + unsigned int m_tempIndex; + + wxString m_sccProvider; + wxString m_sccUser; + wxString m_sccProjName; + wxString m_sccLocalPath; + wxString m_sccAuxProjPath; + wxString m_baseDirectory; }; #endif diff --git a/src/Frontend/ProjectExplorerWindow.cpp b/src/Frontend/ProjectExplorerWindow.cpp index 56ed75ba..5021566d 100644 --- a/src/Frontend/ProjectExplorerWindow.cpp +++ b/src/Frontend/ProjectExplorerWindow.cpp @@ -31,6 +31,7 @@ along with Decoda. If not, see . #include #include +#include #include #include "res/explorer.xpm" @@ -104,7 +105,7 @@ ProjectExplorerWindow::ProjectExplorerWindow(wxWindow* parent, wxWindowID winid) gSizer2->AddGrowableRow( 0 ); gSizer2->SetFlexibleDirection( wxBOTH ); - m_searchBox = new SearchTextCtrl( this, ID_Filter, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 ); + m_searchBox = new SearchTextCtrl(this, ID_Filter, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_RICH); m_filterButton = new wxBitmapButton( this, ID_FilterButton, wxNullBitmap, wxDefaultPosition, wxSize(18, 17), 0 ); m_filterPopup = NULL; @@ -146,6 +147,22 @@ ProjectExplorerWindow::~ProjectExplorerWindow() delete m_filterImageList; } + +void ProjectExplorerWindow::SetFontColorSettings(const FontColorSettings& settings) +{ + SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); + m_tree->SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); + + m_searchBox->SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); + m_searchBox->SetDefaultStyle(wxTextAttr(settings.GetColors(FontColorSettings::DisplayItem_Window).foreColor)); + + m_infoBox->SetFontColorSettings(settings); + + m_itemColor = settings.GetColors(FontColorSettings::DisplayItem_Window).foreColor; + + Rebuild(); +} + void ProjectExplorerWindow::SetFocusToFilter() { // Select all of the text in the box (makes it easy to clear). @@ -161,8 +178,11 @@ void ProjectExplorerWindow::SetProject(Project* project) ProjectExplorerWindow::ItemData* ProjectExplorerWindow::GetDataForItem(wxTreeItemId id) const { - ItemData* data = static_cast(m_tree->GetItemData(id)); - return data; + ItemData* data = nullptr; + if (id.IsOk()) + data =static_cast(m_tree->GetItemData(id)); + + return data; } wxTreeItemId ProjectExplorerWindow::GetSelection() const @@ -210,9 +230,14 @@ void ProjectExplorerWindow::Rebuild() if (m_project != NULL) { + for (unsigned int i = 0; i < m_project->GetNumDirectories(); ++i) + { + RebuildForDirectory(m_project->GetDirectory(i)); + } + for (unsigned int i = 0; i < m_project->GetNumFiles(); ++i) { - RebuildForFile(m_project->GetFile(i)); + RebuildForFile(m_root, m_project->GetFile(i)); } } @@ -230,7 +255,23 @@ void ProjectExplorerWindow::Rebuild() } -void ProjectExplorerWindow::RebuildForFile(Project::File* file) +void ProjectExplorerWindow::RebuildForDirectory(Project::Directory *directory) +{ + ItemData* data = new ItemData; + data->file = directory; + data->symbol = NULL; + data->isFile = false; + + wxTreeItemId node = m_tree->AppendItem(m_root, directory->name, 8, 8, data); + m_tree->SetItemTextColour(node, m_itemColor); + + for (Project::File *file : directory->files) + { + RebuildForFile(node, file); + } +} + +void ProjectExplorerWindow::RebuildForFile(wxTreeItemId node, Project::File* file) { // Check if the file passes our filter flags. @@ -262,7 +303,7 @@ void ProjectExplorerWindow::RebuildForFile(Project::File* file) if (m_filter.IsEmpty()) { // Just include the files like the standard Visual Studio project view. - AddFile(m_root, file); + AddFile(node, file); } else { @@ -270,9 +311,9 @@ void ProjectExplorerWindow::RebuildForFile(Project::File* file) // Filter all of the symbols, modules and file name. // Check to see if the file name matches the filter. - if (MatchesFilter(file->fileName.GetFullName(), m_filter)) + if (MatchesFilter(file->fileName.GetFullName(), m_filter) || MatchesFilter(file->localPath, m_filter)) { - AddFile(m_root, file); + AddFile(node, file); } for (unsigned int j = 0; j < file->symbols.size(); ++j) @@ -283,7 +324,7 @@ void ProjectExplorerWindow::RebuildForFile(Project::File* file) // Check to see if the symbol matches the filter. if (MatchesFilter(symbol->name, m_filter)) { - AddSymbol(m_root, file, symbol); + AddSymbol(node, file, symbol); } } @@ -328,11 +369,55 @@ void ProjectExplorerWindow::AddFile(wxTreeItemId parent, Project::File* file) ItemData* data = new ItemData; data->file = file; data->symbol = NULL; + data->isFile = true; int image = GetImageForFile(file); + wxTreeItemIdValue cookie; + + bool found = false; + wxString path = file->localPath; + wxString directory = path.BeforeFirst('\\'); + wxTreeItemId node; + wxTreeItemId parentNode = parent; + + if (directory.IsEmpty()) + node = parent; + else + { + while (!directory.IsEmpty()) + { + found = false; + + //Add needed directories for file + node = m_tree->GetFirstChild(parentNode, cookie); + while (node.IsOk()) + { + if (m_tree->GetItemText(node) == directory) + { + found = true; + break; + } + + node = m_tree->GetNextChild(parentNode, cookie); + } + + if (!found) + { + node = m_tree->AppendItem(parentNode, directory, 8, 8, nullptr); + m_tree->SetItemTextColour(node, m_itemColor); + } - wxTreeItemId fileNode = m_tree->AppendItem(parent, file->GetDisplayName(), image, image, data); + path.Remove(0, directory.size() + 1); + directory = path.BeforeFirst('\\'); + + parentNode = node; + } + + } + + wxTreeItemId fileNode = m_tree->AppendItem(node, file->GetDisplayName(), image, image, data); + m_tree->SetItemTextColour(fileNode, m_itemColor); // Add the symbols. stdext::hash_map groups; @@ -351,6 +436,7 @@ void ProjectExplorerWindow::AddFile(wxTreeItemId parent, Project::File* file) if (iterator == groups.end()) { node = m_tree->AppendItem(fileNode, file->symbols[i]->module, Image_Module, Image_Module); + m_tree->SetItemTextColour(node, m_itemColor); groups.insert(std::make_pair(file->symbols[i]->module.ToAscii(), node)); } else @@ -372,6 +458,7 @@ void ProjectExplorerWindow::AddSymbol(wxTreeItemId parent, Project::File* file, ItemData* data = new ItemData; data->file = file; data->symbol = symbol; + data->isFile = true; wxString fullName = symbol->name + " ()"; @@ -380,8 +467,8 @@ void ProjectExplorerWindow::AddSymbol(wxTreeItemId parent, Project::File* file, fullName += " - " + symbol->module; } - m_tree->AppendItem(parent, fullName, Image_Function, Image_Function, data); - + wxTreeItemId node = m_tree->AppendItem(parent, fullName, Image_Function, Image_Function, data); + m_tree->SetItemTextColour(node, m_itemColor); } void ProjectExplorerWindow::OnTreeItemExpanding(wxTreeEvent& event) @@ -459,9 +546,9 @@ void ProjectExplorerWindow::OnTreeItemSelectionChanged(wxTreeEvent& event) m_tree->SelectItem(item); ItemData* itemData = GetDataForItem(item); - if (itemData != NULL && itemData->file != NULL) + if (itemData != NULL && itemData->file != NULL && itemData->isFile) { - file = itemData->file; + file = (Project::File *)itemData->file; } } @@ -476,7 +563,6 @@ void ProjectExplorerWindow::OnTreeItemSelectionChanged(wxTreeEvent& event) void ProjectExplorerWindow::GetSelectedFiles(std::vector& selectedFiles) const { - wxArrayTreeItemIds selectedIds; m_tree->GetSelections(selectedIds); @@ -486,17 +572,58 @@ void ProjectExplorerWindow::GetSelectedFiles(std::vector& select ItemData* itemData = GetDataForItem(selectedIds[i]); // Only add the selected item if it's a file. - if (itemData != NULL && itemData->file != NULL && itemData->symbol == NULL) + if (itemData != NULL && itemData->file != NULL && itemData->symbol == NULL && itemData->isFile) { - selectedFiles.push_back(itemData->file); + selectedFiles.push_back((Project::File *)itemData->file); } } } +void ProjectExplorerWindow::GetSelectedDirectories(std::vector& selectedDirectories) const +{ + wxArrayTreeItemIds selectedIds; + m_tree->GetSelections(selectedIds); + + for (unsigned int i = 0; i < selectedIds.Count(); ++i) + { + + ItemData* itemData = GetDataForItem(selectedIds[i]); + + // Only add the selected item if it's a file. + if (itemData != NULL && itemData->file != NULL && itemData->isFile == false) + { + selectedDirectories.push_back((Project::Directory *)itemData->file); + } + + } + +} + +void ProjectExplorerWindow::InsertDirectory(Project::Directory* directory) +{ + RebuildForDirectory(directory); + m_tree->SortChildren(m_tree->GetRootItem()); +} + +void ProjectExplorerWindow::RemoveDirectory(Project::Directory* directory) +{ + for (Project::File *file : directory->files) + { + RemoveFileSymbols(m_tree->GetRootItem(), file); + + if (m_infoBox->GetFile() == file) + { + m_infoBox->SetFile(NULL); + } + } + + RemoveFileSymbols(m_tree->GetRootItem(), (Project::File *)directory); +} + void ProjectExplorerWindow::InsertFile(Project::File* file) { - RebuildForFile(file); + RebuildForFile(m_root, file); m_tree->SortChildren(m_tree->GetRootItem()); } @@ -559,7 +686,7 @@ void ProjectExplorerWindow::RemoveFileSymbols(wxTreeItemId node, const stdext::h ItemData* data = static_cast(m_tree->GetItemData(node)); - if (data != NULL && fileSet.find(data->file) != fileSet.end()) + if (data != NULL && data->isFile && fileSet.find((Project::File *)data->file) != fileSet.end()) { m_tree->Delete(node); } @@ -633,9 +760,9 @@ void ProjectExplorerWindow::UpdateFileImages() ItemData* data = GetDataForItem(item); - if (data != NULL && data->file != NULL && data->symbol == NULL) + if (data != NULL && data->file != NULL && data->symbol == NULL && data->isFile) { - int image = GetImageForFile(data->file); + int image = GetImageForFile((Project::File *)data->file); m_tree->SetItemImage(item, image); m_tree->SetItemImage(item, image, wxTreeItemIcon_Selected); } @@ -678,7 +805,7 @@ void ProjectExplorerWindow::UpdateFile(Project::File* file) m_tree->Freeze(); RemoveFileSymbols(m_tree->GetRootItem(), file); - RebuildForFile(file); + RebuildForFile(m_root, file); m_tree->SortChildren(m_tree->GetRootItem()); diff --git a/src/Frontend/ProjectExplorerWindow.h b/src/Frontend/ProjectExplorerWindow.h index 72bb8f8f..dd9fb8ff 100644 --- a/src/Frontend/ProjectExplorerWindow.h +++ b/src/Frontend/ProjectExplorerWindow.h @@ -30,7 +30,8 @@ along with Decoda. If not, see . #include #include "Project.h" - +#include "FontColorSettings.h" +#undef RemoveDirectory // // Forward declarations. // @@ -45,6 +46,7 @@ class ProjectFilterPopup; */ class ProjectExplorerWindow : public wxPanel { + friend class MainFrame; public: @@ -53,8 +55,9 @@ class ProjectExplorerWindow : public wxPanel */ struct ItemData : public wxTreeItemData { - Project::File* file; + void* file; Symbol* symbol; + bool isFile; }; enum FilterFlag @@ -75,6 +78,12 @@ class ProjectExplorerWindow : public wxPanel */ virtual ~ProjectExplorerWindow(); + + /** + * Updates the colors of the panel to match the settings + */ + void SetFontColorSettings(const FontColorSettings& settings); + /** * Sets the keyboard focus to the filter text box. */ @@ -136,6 +145,18 @@ class ProjectExplorerWindow : public wxPanel */ wxTreeItemId GetSelection() const; + /** + * Adds references for the directory into the explorer view. This should be + * called when a directory is added to the project. + */ + void InsertDirectory(Project::Directory* file); + + /** + * Removes all references to a directory from the explorer view. This should + * be called when a directory is deleted from the project. + */ + void RemoveDirectory(Project::Directory* file); + /** * Adds references for the file into the explorer view. This should be * called when a file is added to the project. @@ -166,6 +187,12 @@ class ProjectExplorerWindow : public wxPanel */ void GetSelectedFiles(std::vector& selectedFiles) const; + + /** + * Gets a list of all of the directories that are currently selected in the tree. + */ + void GetSelectedDirectories(std::vector& selectedDirectories) const; + /** * Updates the images showing the file status. */ @@ -233,7 +260,12 @@ class ProjectExplorerWindow : public wxPanel /** * Adds the items for the file that match the filter into the tree control. */ - void RebuildForFile(Project::File* file); + void RebuildForFile(wxTreeItemId node, Project::File* file); + + /** + * Adds the items for the file that match the filter into the tree control. + */ + void RebuildForDirectory(Project::Directory *directory); /** * Returns the image that should be used to display the file. @@ -288,7 +320,7 @@ class ProjectExplorerWindow : public wxPanel wxMenu* m_contextMenu; - + wxColor m_itemColor; }; #endif diff --git a/src/Frontend/ProjectFileInfoCtrl.cpp b/src/Frontend/ProjectFileInfoCtrl.cpp index 33548167..f8bb25e0 100644 --- a/src/Frontend/ProjectFileInfoCtrl.cpp +++ b/src/Frontend/ProjectFileInfoCtrl.cpp @@ -51,6 +51,11 @@ ProjectFileInfoCtrl::ProjectFileInfoCtrl(wxWindow* parent, wxWindowID id) } +void ProjectFileInfoCtrl::SetFontColorSettings(const FontColorSettings& settings) +{ + m_fontColor = settings.GetColors(FontColorSettings::DisplayItem_Window).foreColor; +} + void ProjectFileInfoCtrl::OnPaint(wxPaintEvent& event) { @@ -107,6 +112,7 @@ void ProjectFileInfoCtrl::OnPaint(wxPaintEvent& event) result += path + fileName.GetFullName(); + dc.SetTextForeground(m_fontColor); dc.DrawText(result, s_padding, s_padding); } diff --git a/src/Frontend/ProjectFileInfoCtrl.h b/src/Frontend/ProjectFileInfoCtrl.h index f6b2e74a..647fc666 100644 --- a/src/Frontend/ProjectFileInfoCtrl.h +++ b/src/Frontend/ProjectFileInfoCtrl.h @@ -25,6 +25,7 @@ along with Decoda. If not, see . #include "Project.h" #include +#include "FontColorSettings.h" // // Forward declarations. @@ -45,6 +46,12 @@ class ProjectFileInfoCtrl : public wxControl */ explicit ProjectFileInfoCtrl(wxWindow* parent, wxWindowID id = wxID_ANY); + + /** + * Updates the colors of the panel to match the settings + */ + void SetFontColorSettings(const FontColorSettings& settings); + /** * Called when the info box needs to be repainted. */ @@ -80,6 +87,7 @@ class ProjectFileInfoCtrl : public wxControl const Project::File* m_file; bool m_textIsClipped; + wxColor m_fontColor; }; diff --git a/src/Frontend/SearchWindow.cpp b/src/Frontend/SearchWindow.cpp index ef76c503..59e24b95 100644 --- a/src/Frontend/SearchWindow.cpp +++ b/src/Frontend/SearchWindow.cpp @@ -45,11 +45,11 @@ void SearchWindow::SetFontColorSettings(const FontColorSettings& settings) // happens often enough for it to really make much difference. Clear(); - SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Default).backColor); + SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); - m_messageAttr.SetTextColour(settings.GetColors(FontColorSettings::DisplayItem_Default).foreColor); - m_messageAttr.SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Default).backColor); - m_messageAttr.SetFont(settings.GetFont(FontColorSettings::DisplayItem_Default)); + m_messageAttr.SetTextColour(settings.GetColors(FontColorSettings::DisplayItem_Window).foreColor); + m_messageAttr.SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); + m_messageAttr.SetFont(settings.GetFont(FontColorSettings::DisplayItem_Window)); } void SearchWindow::OnDoubleClick(wxMouseEvent& event) diff --git a/src/Frontend/SymbolParser.cpp b/src/Frontend/SymbolParser.cpp index ee9979e4..e6a66a5f 100644 --- a/src/Frontend/SymbolParser.cpp +++ b/src/Frontend/SymbolParser.cpp @@ -65,6 +65,15 @@ void SymbolParser::SetProject(Project* project) { QueueForParsing( m_project->GetFile(fileIndex) ); } + + for (unsigned int dirIndex = 0; dirIndex < m_project->GetNumDirectories(); ++dirIndex) + { + Project::Directory *directory = m_project->GetDirectory(dirIndex); + for (unsigned int fileIndex = 0; fileIndex < directory->files.size(); ++fileIndex) + { + QueueForParsing(directory->files[fileIndex]); + } + } } } diff --git a/src/Frontend/SymbolParserEvent.h b/src/Frontend/SymbolParserEvent.h index 375c9613..bdac5b3d 100644 --- a/src/Frontend/SymbolParserEvent.h +++ b/src/Frontend/SymbolParserEvent.h @@ -37,7 +37,7 @@ class Symbol; // Event definitions. // -DECLARE_EVENT_TYPE(wxEVT_SYMBOL_PARSER_EVENT, -1) +DECLARE_EVENT_TYPE(wxEVT_SYMBOL_PARSER_EVENT, wxID_ANY) /** * Class for events sent by the symbol parser thread. This doesn't really handle @@ -86,7 +86,7 @@ class SymbolParserEvent : public wxEvent typedef void (wxEvtHandler::*SymbolParserEventFunction)(SymbolParserEvent&); #define EVT_SYMBOL_PARSER(fn) \ - DECLARE_EVENT_TABLE_ENTRY( wxEVT_SYMBOL_PARSER_EVENT, 0, -1, \ + DECLARE_EVENT_TABLE_ENTRY( wxEVT_SYMBOL_PARSER_EVENT, wxID_ANY, wxID_ANY, \ (wxObjectEventFunction) (wxEventFunction) wxStaticCastEvent( SymbolParserEventFunction, & fn ), (wxObject *) NULL ), #endif \ No newline at end of file diff --git a/src/Frontend/SymbolParserThread.cpp b/src/Frontend/SymbolParserThread.cpp index 1957fa21..df62ab7f 100644 --- a/src/Frontend/SymbolParserThread.cpp +++ b/src/Frontend/SymbolParserThread.cpp @@ -100,7 +100,6 @@ wxThread::ExitCode SymbolParserThread::Entry() // Dispatch the message to event handler. SymbolParserEvent event(m_headItem->fileId, symbols, isLastItem); m_eventHandler->AddPendingEvent(event); - } delete m_headItem; diff --git a/src/Frontend/WatchCtrl.cpp b/src/Frontend/WatchCtrl.cpp index 9772f45c..ae18a2b7 100644 --- a/src/Frontend/WatchCtrl.cpp +++ b/src/Frontend/WatchCtrl.cpp @@ -52,7 +52,12 @@ WatchCtrl::WatchCtrl(wxWindow *parent, wxWindowID id, const wxPoint& pos, const m_vm = 0; m_stackLevel = 0; +} +void WatchCtrl::SetFontColorSettings(const FontColorSettings& settings) +{ + SetBackgroundColour(settings.GetColors(FontColorSettings::DisplayItem_Window).backColor); + m_fontColor = settings.GetColors(FontColorSettings::DisplayItem_Window).foreColor; } void WatchCtrl::SetValueFont(const wxFont& font) @@ -73,7 +78,8 @@ void WatchCtrl::UpdateFont(wxTreeItemId item) SetItemFont( item, m_valueFont ); UpdateFont( GetNextSibling(item) ); - + SetItemTextColour(item, m_fontColor); + wxTreeItemIdValue cookie; wxTreeItemId child = GetFirstChild(item, cookie); diff --git a/src/Frontend/WatchCtrl.h b/src/Frontend/WatchCtrl.h index d97b9233..05cc6831 100644 --- a/src/Frontend/WatchCtrl.h +++ b/src/Frontend/WatchCtrl.h @@ -25,6 +25,7 @@ along with Decoda. If not, see . #include #include "treelistctrl.h" +#include "FontColorSettings.h" // // Forward declarations. @@ -44,6 +45,11 @@ class WatchCtrl : public wxTreeListCtrl WatchCtrl(wxWindow *parent, wxWindowID id = -1, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxTR_HIDE_ROOT | wxTR_FULL_ROW_HIGHLIGHT | wxTR_ROW_LINES | wxTR_HAS_BUTTONS, const wxValidator &validator = wxDefaultValidator, const wxString& name = ""); + /** + * Updates the colors of the panel to match the settings + */ + void SetFontColorSettings(const FontColorSettings& settings); + /** * Parses a compound expression ({ key = value, key = value, etc. }) and adds it's * key value pairs as subitems for the specified item in the tree. @@ -114,7 +120,7 @@ class WatchCtrl : public wxTreeListCtrl float m_columnProportion; wxFont m_valueFont; - + wxColor m_fontColor; }; #endif \ No newline at end of file diff --git a/src/Frontend/res/explorer.xpm b/src/Frontend/res/explorer.xpm index c6fc826c..f3033ece 100644 --- a/src/Frontend/res/explorer.xpm +++ b/src/Frontend/res/explorer.xpm @@ -1,265 +1,369 @@ /* XPM */ -static char *explorer[] = { -/* columns rows colors chars-per-pixel */ -"144 17 242 2", -" c black", -". c #090909", -"X c #110911", -"o c #160916", -"O c #260926", -"+ c #2E092E", -"@ c #380938", -"# c #390939", -"$ c #751C05", -"% c #761C04", -"& c #4C2904", -"* c #512C04", -"= c #6B3A06", -"- c #693C05", -"; c #26680A", -": c #286D0B", -"> c #2C750C", -", c #2E790D", -"< c #2E7D0D", -"1 c #734106", -"2 c #410941", -"3 c #4B094B", -"4 c #4E094E", -"5 c #500950", -"6 c #530953", -"7 c #690969", -"8 c #6A096A", -"9 c #700970", -"0 c #740974", -"q c #750975", -"w c #354963", -"e c #364A64", -"r c #3C4F69", -"t c #3C5069", -"y c #3D5069", -"u c #42556D", -"i c #43566E", -"p c #4A5C73", -"a c #800000", -"s c #801F04", -"d c #A72605", -"f c #CB2F06", -"g c #D53106", -"h c #E93404", -"j c #F83604", -"k c #945E05", -"l c #BF482C", -"z c #DE4013", -"x c #EF5845", -"c c #D5614A", -"v c #31800F", -"b c #32870E", -"n c #348810", -"m c #368E10", -"M c #399113", -"N c #399214", -"B c #3E9818", -"V c #449D1E", -"C c #4BB11F", -"Z c #49AF20", -"A c #4DAE23", -"S c #52AD2C", -"D c #4DB022", -"F c #60BD38", -"G c #65C33D", -"H c #6DCD42", -"J c #FFC005", -"K c #FFE23F", -"L c #88B279", -"P c #FF9B77", -"I c #970997", -"U c #9C099C", -"Y c #9E099E", -"T c #9F099F", -"R c #A409A4", -"E c #AF09AF", -"W c #BD0CBD", -"Q c #B310B3", -"! c #BC13BC", -"~ c #C015C0", -"^ c #C71EC7", -"/ c #CA1BCA", -"( c #C920C9", -") c #CB23CB", -"_ c #D426D4", -"` c #D028D0", -"' c #D630D6", -"] c #D730D7", -"[ c #DA33DA", -"{ c #DF38DF", -"} c magenta", -"| c #E43EE4", -" . c #E641E6", -".. c #E741E7", -"X. c #F24DF2", -"o. c #F450F4", -"O. c #F550F5", -"+. c #F956F9", -"@. c #FB59FB", -"#. c #FE5BFE", -"$. c #FF5EFF", -"%. c #008080", -"&. c cyan", -"*. c #808080", -"=. c #8087B4", -"-. c #93A2B7", -";. c #9CA6B3", -":. c #9DA6B3", -">. c #96A5BA", -",. c #96A5BB", -"<. c #9AA9BF", -"1. c #9EABBE", -"2. c #A0A9B6", -"3. c #A3ACB8", -"4. c #A6AFBA", -"5. c #EEB5AE", -"6. c #9CABC0", -"7. c #9EADC3", -"8. c #A0ACC3", -"9. c #A3AFC6", -"0. c #A7B2C1", -"q. c #A7B3C2", -"w. c #A2B1C7", -"e. c #A5B1C7", -"r. c #A4B3C9", -"t. c #A5B5CB", -"y. c #A8B3C8", -"u. c #AAB5CA", -"i. c #ABB6CB", -"p. c #A9B9CF", -"a. c #AFB9CD", -"s. c #B0BBCD", -"d. c #B3BDCF", -"f. c #ADBDD3", -"g. c #AEBED4", -"h. c #B7C0D2", -"j. c #B7C1D2", -"k. c #B1C1D7", -"l. c #BBC5D4", -"z. c #BCC4D5", -"x. c #B2C2D8", -"c. c #BFC7D8", -"v. c #BCCDF0", -"b. c #C6CCDB", -"n. c #CAD1DB", -"m. c #CBD3DD", -"M. c #CDD5DF", -"N. c #CFD6DF", -"B. c #CED6E0", -"V. c #CFD7E1", -"C. c #CDD6E2", -"Z. c #CADAEE", -"A. c #D0D6E1", -"S. c #D1D9E3", -"D. c #D2D8E3", -"F. c #D3D9E3", -"G. c #D4D9E0", -"H. c #D4DAE1", -"J. c #D2DAE4", -"K. c #D3DBE5", -"L. c #D4DAE4", -"P. c #D5DBE5", -"I. c #D6DBE5", -"U. c #D5DCE7", -"Y. c #D8DCE6", -"T. c #D8DDE6", -"R. c #D9DDE7", -"E. c #DADEE7", -"W. c #D7DEE9", -"Q. c #D7DFEA", -"!. c #DADFE8", -"~. c #C1D0F1", -"^. c #C2D1F1", -"/. c #C5D4F2", -"(. c #C8D5F3", -"). c #CAD7F3", -"_. c #CDD9F4", -"`. c #CEDBF4", -"'. c #D1DDF4", -"]. c #D2DCF5", -"[. c #D3DEF5", -"{. c #DBE0E9", -"}. c #D9E0EB", -"|. c #DDE2EA", -" X c #DEE2EA", -".X c #D9E1EC", -"XX c #DFE3EC", -"oX c #D5E1F6", -"OX c #D8E2F7", -"+X c #DAE4F7", -"@X c #DCE5F7", -"#X c #DEE6F7", -"$X c #DDE6F8", -"%X c #E2E6ED", -"&X c #E3E6ED", -"*X c #E6EBF0", -"=X c #E5EDF6", -"-X c #E9ECF1", -";X c #ECEEF3", -":X c #EDEFF3", -">X c #E0E8F8", -",X c #E1E8F8", -".l.e q.P P P P P P P P P P P P P P 6 +.# P P P P P P P .XVXVXVXVXVXVXbXm. X:.D.P P P P P P x.VXVXVXVXVXVXbX>.l.e q.P P P P P P .XVXVXVXVXVXVXVXm. X;.H.P P P P P P x.VXVXVXVXVXVXvX>.l.e q.P P P P P P .XVXVXVXVXVXVXbXm. X:.H.P P P ", -"P P & K K J J = 1 & & P P P P P P P P P k.VXc.<.<.<.<.vX1.i r w P P P P P P =.=.=.=.=.P P 6 $.o.{ O P P P P P P !.VXXXM.m.M.M.bXM.4.:.:.P P P P P P k.VXc.<.<.<.<.kX1.i t w P P P P P P !.VXXXM.m.M.m.vXM.3.2.;.P P P P P P k.VXc.<.<.<.<.vX1.i r w P P P P P P W.VXXXM.m.M.M.bXM.3.2.:.P P P ", -"P & J J J J = 1 & P P P } P P P P P f.VXVXVXVXVXvXkXZ.%XR.r P P P P P P P P P P P P 6 $.o. ._ ^ X P P P P P W.VXVXVXVXVXbXVX=X:X;X3.P P P P P P f.VXVXVXVXVXvXkXZ.%XR.t P P P P P P W.VXVXVXVXVXVXbX=XaX;X:.P P P P P P f.VXVXVXVXVXvXkXZ.%XR.r P P P P P P W.VXVXVXVXVXVXbX=XaX-X2.P P P ", -"P P J J k 1 & P *.P } a a P P P P p.VXc.<.<.<.<.<.jXfX!.i P P P P P P =.=.=.=.P 6 @.X...[ ( ! Y . P P P P W.VX XM.M.M.M.m.vXkX:X3.P P P P P P p.VXc.<.<.<.<.6.fXhXR.i P P P P P P W.VXXXM.M.M.M.M.vXvX;X3.P P P P P P p.VXc.<.<.<.<.<.jXfX!.u P P P P P P W.VXXXM.M.M.M.M.bXkX:X3.P P P ", -"P P P = - * P P P } a a P P P P P t.VXVXVXVXVXkXjXqXqXD.p P P P P P P P P P P P 3 2 .' ) ! Y . . P P P P J.VXVXVXVXVXVXbXjXkX-X4.P P P P P P t.VXVXVXVXVXkXfXqXqXD.p P P P P P P J.VXVXVXVXVXbXvXkXgX-X4.P P P P P P r.VXVXVXx 5.jXjXqXqXD.p P P P P P P J.VXVXVXx 5.bXbXhXkX-X4.P P P ", -"P P P P & P *.P P P a P P P P P P w.VXc.<.<.<.<.<.<.>XA.i P P P P P P =.=.=.=.P 2 _ + ` ! Y . 9 . P P P P J.VXXXM.M.M.M.M.M.iX-X3.P P P P P P w.VXc.<.<.<.<.<.6.>XA.i P P P P P P D.VXXXM.M.M.M.M.M.tX-X2.P P P P P P r.VXb.x x <.<.<.<.X#Xb.t P P P P P P S.VXx j 5.kXfXfXtXtX%X2.P P P ", -"P P P P P P P P *.P P P P P P P P P P P P <.VXc.6.<.<.<.<.6.].j.w P P P P P P =.=.=.=.P P . E R . 0 8 . P P P P P C.VXXXM.M.M.M.M.M.wX}.:.P P P P L C D B 9.<.<.1.6.<.<.].j.e P P P P L C D B 7.M.C.M.M.m.C.5X X;.P P P P P P 6.x j j c <.<.<.<.].j.e P P P P P P V.x j j c C.M.M.M.qXR.:.P P P ", -"P P P P P P P P P P P P P P P P P P P P >.fXfXqX>XOXoX]._.(.s.w P P P P P P P P P P P P P . I . 8 . P P P P P P m.bXkXgXsXtXwXqX=XXOXoX]._.(.a.w P P P L D H G V v 7.sXtXwXqX5X5XI.;.P P P P x P x j j 5.XOX[.`.)./.~.v.e.w P P P g j j g s jXqXqX5X5X , ; 7.z.j.d.s.i.y.9.7.w P P P P e > , ; 7. X!.R.I.I.K.D.C.;.P P P P f d % OXb.z.d.d.s.i.y.w.8.w P P P P f d $ tX X X}.R.R.I.J.D.A.;.P P P ", -"P P P P P P P P P P P %. P P P P P P P -.w w w w w w e w w w e P P P P P P P P P P P P P P P P P P P P P P P P n.;.;.:.:.:.:.;.:.:.:.:.P P P P P w w w w w w w w w w w w w P P P P P w w w ;.;.;.:.:.;.;.:.;.;.P P P P P % -.w w e e w w w w w w w P P P P P % m.;.:.:.:.;.:.:.;.:.:.;.P P P ", -"P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P P " -}; +static char * explorer[] = { +"162 17 349 2", +" c None", +". c #FF9B77", +"+ c #4C2904", +"@ c #FFE23F", +"# c #B2C2D8", +"$ c #AEBED4", +"% c #A9B9CF", +"& c #A4B3C9", +"* c #CDD6E2", +"= c #D9E1EC", +"- c #D7DEE9", +"; c #D5DCE7", +"> c #D2DAE4", +", c #E6EBF0", +"' c #D3DBE5", +") c #D2D8E3", +"! c #7D808F", +"~ c #607790", +"{ c #62768D", +"] c #62768E", +"^ c #5A748F", +"/ c #897F88", +"( c #FFC005", +"_ c #FFFFFF", +": c #9CABC0", +"< c #354963", +"[ c #A7B3C2", +"} c #4B094B", +"| c #CDD5DF", +"1 c #9CA6B3", +"2 c #9EABBE", +"3 c #5D7690", +"4 c #9EB2C5", +"5 c #BCC9D8", +"6 c #B8C5D5", +"7 c #BBC8D7", +"8 c #A5B5C8", +"9 c #8C8087", +"0 c #FE9A77", +"a c #6B3A06", +"b c #F9FBFE", +"c c #96A5BA", +"d c #BBC5D4", +"e c #364A64", +"f c #530953", +"g c #F956F9", +"h c #390939", +"i c #FBFCFE", +"j c #CBD3DD", +"k c #DEE2EA", +"l c #9DA6B3", +"m c #D4DAE1", +"n c #667A91", +"o c #7894AE", +"p c #869FB6", +"q c #839DB5", +"r c #859DB5", +"s c #7491AC", +"t c #476E8F", +"u c #8E7E84", +"v c #8C7D83", +"w c #8B7C83", +"x c #8A7C82", +"y c #8A7E86", +"z c #B08B86", +"A c #734106", +"B c #000000", +"C c #B1C1D7", +"D c #BFC7D8", +"E c #9AA9BF", +"F c #43566E", +"G c #3C4F69", +"H c #8087B4", +"I c #FF5EFF", +"J c #F450F4", +"K c #DF38DF", +"L c #260926", +"M c #DADFE8", +"N c #DFE3EC", +"O c #A6AFBA", +"P c #F6F8FC", +"Q c #3C5069", +"R c #A3ACB8", +"S c #A0A9B6", +"T c #677A92", +"U c #6E8BA7", +"V c #7C97B0", +"W c #809AB1", +"X c #849CB2", +"Y c #89A1B6", +"Z c #91A8BD", +"` c #93A9BE", +" . c #96ACBF", +".. c #99AEC0", +"+. c #9BB0C2", +"@. c #A0B4C6", +"#. c #809BB2", +"$. c #6D7A8D", +"%. c #FF00FF", +"&. c #ADBDD3", +"*. c #CADAEE", +"=. c #E2E6ED", +"-. c #D9DDE7", +";. c #E641E6", +">. c #D426D4", +",. c #C71EC7", +"'. c #110911", +"). c #E5EDF6", +"!. c #EDEFF3", +"~. c #ECEEF3", +"{. c #F0F2F6", +"]. c #E9ECF1", +"^. c #62778F", +"/. c #9FB0C5", +"(. c #C6CFDE", +"_. c #CDD5E0", +":. c #D7DCE3", +"<. c #DDE2E7", +"[. c #E1E8EE", +"}. c #ECEFF5", +"|. c #F0F2F8", +"1. c #F8F9F9", +"2. c #FFFEFD", +"3. c #C1CFDB", +"4. c #6E7687", +"5. c #945E05", +"6. c #808080", +"7. c #800000", +"8. c #F4F7FD", +"9. c #F3F6FC", +"0. c #FB59FB", +"a. c #F24DF2", +"b. c #E741E7", +"c. c #DA33DA", +"d. c #C920C9", +"e. c #BC13BC", +"f. c #9E099E", +"g. c #090909", +"h. c #F4F7FC", +"i. c #42556D", +"j. c #63778F", +"k. c #9AACC2", +"l. c #BCC7D7", +"m. c #C2CDDA", +"n. c #CCD4DD", +"o. c #D2DAE1", +"p. c #D7DFE8", +"q. c #DFE5ED", +"r. c #E4E9F0", +"s. c #EBEFF2", +"t. c #F2F4F5", +"u. c #F6F7F8", +"v. c #B9C8D6", +"w. c #6F7687", +"x. c #693C05", +"y. c #512C04", +"z. c #A5B5CB", +"A. c #EAEFFA", +"B. c #4A5C73", +"C. c #410941", +"D. c #D630D6", +"E. c #CB23CB", +"F. c #F4F6FC", +"G. c #EF5845", +"H. c #EEB5AE", +"I. c #63788F", +"J. c #95A8BF", +"K. c #B3BFD1", +"L. c #B7C3D4", +"M. c #C1CCDA", +"N. c #CBD3DE", +"O. c #D1D9E5", +"P. c #D6DFE7", +"Q. c #E0E5ED", +"R. c #E3E9F0", +"S. c #EBEEF2", +"T. c #FFFFFE", +"U. c #B8C7D3", +"V. c #707688", +"W. c #A2B1C7", +"X. c #E0E8F8", +"Y. c #D0D6E1", +"Z. c #2E092E", +"`. c #D028D0", +" + c #700970", +".+ c #EFF3FB", +"++ c #EDF2FA", +"@+ c #C6CCDB", +"#+ c #E2E8F8", +"$+ c #647890", +"%+ c #8DA4B9", +"&+ c #ACBACD", +"*+ c #B0BCD0", +"=+ c #EAEEF2", +"-+ c #FCFCFB", +";+ c #B7C5D2", +">+ c #9EADC3", +",+ c #EFF3FC", +"'+ c #DDE6F8", +")+ c #380938", +"!+ c #CA1BCA", +"~+ c #BD0CBD", +"{+ c #160916", +"]+ c #B310B3", +"^+ c #740974", +"/+ c #6A096A", +"(+ c #CFD7E1", +"_+ c #E3E6ED", +":+ c #88B279", +"<+ c #E6ECF9", +"[+ c #F83604", +"}+ c #F0F3FB", +"|+ c #DEE6F7", +"1+ c #D1D9E3", +"2+ c #647990", +"3+ c #899FB7", +"4+ c #A3B3C6", +"5+ c #A9B7CA", +"6+ c #B0BDD0", +"7+ c #C1CDDA", +"8+ c #CCD3DD", +"9+ c #F4F6F8", +"0+ c #B3C3CF", +"a+ c #707788", +"b+ c #D2DCF5", +"c+ c #B7C1D2", +"d+ c #AF09AF", +"e+ c #A409A4", +"f+ c #EAF0FA", +"g+ c #D9E0EB", +"h+ c #4BB11F", +"i+ c #4DB022", +"j+ c #3E9818", +"k+ c #A3AFC6", +"l+ c #D5614A", +"m+ c #657991", +"n+ c #8097B1", +"o+ c #9BABC1", +"p+ c #A1B2C5", +"q+ c #A8B7CA", +"r+ c #B1BDD0", +"s+ c #CCD3DE", +"t+ c #D6DFE8", +"u+ c #DEE5EC", +"v+ c #F1F2F7", +"w+ c #B1C0D0", +"x+ c #D8E2F7", +"y+ c #D5E1F6", +"z+ c #CDD9F4", +"A+ c #C8D5F3", +"B+ c #B0BBCD", +"C+ c #970997", +"D+ c #49AF20", +"E+ c #6DCD42", +"F+ c #65C33D", +"G+ c #449D1E", +"H+ c #2E7D0D", +"I+ c #AFB9CD", +"J+ c #31800F", +"K+ c #D6DBE5", +"L+ c #DAE4F7", +"M+ c #D3DEF5", +"N+ c #CEDBF4", +"O+ c #C5D4F2", +"P+ c #7692AE", +"Q+ c #8EA2BB", +"R+ c #98AAC0", +"S+ c #D1D9E4", +"T+ c #E9ECF2", +"U+ c #ADBDCE", +"V+ c #707789", +"W+ c #00FFFF", +"X+ c #93A2B7", +"Y+ c #C1D0F1", +"Z+ c #AAB5CA", +"`+ c #CAD1DB", +" @ c #4DAE23", +".@ c #60BD38", +"+@ c #52AD2C", +"@@ c #399113", +"#@ c #E93404", +"$@ c #BF482C", +"%@ c #718CA9", +"&@ c #839AB5", +"*@ c #8CA1BA", +"=@ c #99AAC0", +"-@ c #C2CCD9", +";@ c #CBD4DF", +">@ c #E0E6EE", +",@ c #A7B9CA", +"'@ c #717889", +")@ c #008080", +"!@ c #BCCDF0", +"~@ c #A5B1C7", +"{@ c #348810", +"]@ c #368E10", +"^@ c #32870E", +"/@ c #286D0B", +"(@ c #CAD7F3", +"_@ c #399214", +":@ c #D53106", +"<@ c #DE4013", +"[@ c #761C04", +"}@ c #801F04", +"|@ c #677B92", +"1@ c #6E88A5", +"2@ c #7D94AF", +"3@ c #8FA2BB", +"4@ c #9BACC2", +"5@ c #A4B4C6", +"6@ c #ADBACD", +"7@ c #B4BFD2", +"8@ c #BCC7D8", +"9@ c #C7D0DC", +"0@ c #D0D7E2", +"a@ c #A6B8CA", +"b@ c #BCC4D5", +"c@ c #A8B3C8", +"d@ c #A0ACC3", +"e@ c #2C750C", +"f@ c #2E790D", +"g@ c #26680A", +"h@ c #B3BDCF", +"i@ c #ABB6CB", +"j@ c #CB2F06", +"k@ c #A72605", +"l@ c #751C05", +"m@ c #637A93", +"n@ c #63829F", +"o@ c #7691AD", +"p@ c #889EB7", +"q@ c #8CA3B8", +"r@ c #94A7BE", +"s@ c #97AAC0", +"t@ c #9EB1C5", +"u@ c #A6B7C8", +"v@ c #B2C0D0", +"w@ c #8BA3BA", +"x@ c #70798C", +"y@ c #7C808F", +"z@ c #657A92", +"A@ c #687A91", +"B@ c #677A91", +"C@ c #667990", +"D@ c #657990", +"E@ c #64788F", +"F@ c #63778E", +"G@ c #5E7791", +"H@ c #8D848D", +". . . . . . + . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ", +". . . . . + @ + . . . . . . . . . . . . . # # # # # # $ % & * . . . . . . . . . . . . . . . . . . . . . . . . . . = = = = = = - ; > , . . . . . . . . # # # # # # $ % & * . . . . . . . . = = = = = = - ' > , . . . . . . . . # # # # # # $ % & * . . . . . . . . = = = = = = - - ) , . . . . . . ! ~ { ] ^ / . . . . . . . . . . . ", +". . . . + @ @ ( + . . . . . . . . . . . . # _ _ _ _ _ _ _ : < [ . . . . . . . . . . . . . . . . } . . . . . . . . = _ _ _ _ _ _ _ | 1 ) . . . . . . . # _ _ _ _ _ _ _ : < [ . . . . . . . = _ _ _ _ _ _ _ * 1 ) . . . . . . . # _ _ _ _ _ _ _ 2 < [ . . . . . . . = _ _ _ _ _ _ _ | 1 ) . . . . . 3 4 5 6 7 8 9 . . . . . . . . 0 . ", +". . . + @ @ ( ( a + . . . . . . . . . . . # _ _ _ _ _ _ b c d e [ . . . . . . . . . . . . . . f g h . . . . . . . = _ _ _ _ _ _ i j k l ) . . . . . . # _ _ _ _ _ _ i c d e [ . . . . . . = _ _ _ _ _ _ _ j k 1 m . . . . . . # _ _ _ _ _ _ b c d e [ . . . . . . = _ _ _ _ _ _ i j k l m . . . . n o p q r s t u v v w w x y z . . ", +". . + @ @ ( ( a A + + . . . B . . . . . . C _ D E E E E b 2 F G < . . . . . . H H H H H . . f I J K L . . . . . . M _ N | j | | i | O l l . . . . . . C _ D E E E E P 2 F Q < . . . . . . M _ N | j | j b | R S 1 . . . . . . C _ D E E E E b 2 F G < . . . . . . - _ N | j | | i | R S l . . . . T U V W X Y Z Z ` ...+.@.#.$.. . ", +". + ( ( ( ( a A + B . . . B %.B . . . . . &._ _ _ _ _ b P *.=.-.G . . . . . . . . . . . . f I J ;.>.,.'.. . . . . - _ _ _ _ _ i _ ).!.~.R . . . . . . &._ _ _ _ _ b P *.=.-.Q . . . . . . - _ _ _ _ _ _ i ).{.~.l . . . . . . &._ _ _ _ _ b P *.=.-.G . . . . . . - _ _ _ _ _ _ i ).{.].S . . . . ^./.(._.:.<.[.}.|.1.2._ _ 3.4.. . ", +". . B ( ( 5.A + B . 6.. B %.7.7.B . . . . % _ D E E E E E 8.9.M F . . . . . . H H H H . f 0.a.b.c.d.e.f.g.. . . . - _ k | | | | j b P !.R . . . . . . % _ D E E E E : 9.h.-.F . . . . . . - _ N | | | | | b b ~.R . . . . . . % _ D E E E E E 8.9.M i.. . . . . . - _ N | | | | | i P !.R . . . . j.k.l.m.n.o.p.q.r.s.t.u._ v.w.. . ", +". . . B a x.y.B . . . B %.7.7.B . . . . . z._ _ _ _ _ P 8.A.A.) B.. . . . . . . . . . . } C.;.D.E.e.f.g.g.. . . . > _ _ _ _ _ _ i 8.P ].O . . . . . . z._ _ _ _ _ P 9.A.A.) B.. . . . . . > _ _ _ _ _ i b P F.].O . . . . . . & _ _ _ G.H.8.8.A.A.) B.. . . . . . > _ _ _ G.H.i i h.P ].O . . . . I.J.K.L.M.N.O.P.Q.R.S.t.T.U.V.. . ", +". . . . B + B . 6.. . . B 7.B . . . . . . W._ D E E E E E E X.Y.F . . . . . . H H H H . C.>.Z.`.e.f.g. +g.. . . . > _ N | | | | | | .+].R . . . . . . W._ D E E E E E : X.Y.F . . . . . . ) _ N | | | | | | ++].S . . . . . . & _ @+G.G.E E E E #+) F . . . . . . > _ N G.G.| | | | h.].S . . . . $+%+&+*+L.M.j O.P.Q.r.=+-+;+V.. . ", +". . . . . B . . . . . . . B . . . . . . . >+_ _ P _ ,+A.A.'+#+@+G . . . . . . . . . . . )+!+~+{+]+g.^+/+g.. . . . (+_ _ i _ P 8.h..+.+_+l . . . . . :+:+>+_ b _ ,+A.<+'+#+@+Q . . . . . :+:+>+_ i _ P h.8.++h.=.S . . . . . . >+_ G.[+H.}+A.<+X.|+@+Q . . . . . . 1+_ G.[+H.P 9.9.++++=.S . . . . 2+3+4+5+6+L.7+8+O.P.q.r.9+0+a+. . ", +". . . . . . . . 6.. . . . . . . . . . . . E _ D : E E E E : b+c+< . . . . . . H H H H . . g.d+e+g.^+/+g.. . . . . * _ N | | | | | | f+g+l . . . . :+h+i+j+k+E E 2 : E E b+c+e . . . . :+h+i+j+>+| * | | j * <+k 1 . . . . . . : G.[+[+l+E E E E b+c+e . . . . . . (+G.[+[+l+* | | | A.-.l . . . . m+n+o+p+q+r+L.m.s+O.t+u+v+w+a+. . ", +". . . . . . . . . . . . . B . . . . . . . c 9.9.A.X.x+y+b+z+A+B+< . . . . . . . . . . . . . g.C+g./+g.. . . . . . j i P F.}+++f+A.).#+g+l . . . :+D+E+F+G+H+>+X.x+y+b+z+A+I+< . . . :+i+E+F+G+J+>+}+++f+A.<+<+K+1 . . . . G.. G.[+[+H.#+L+M+b+N+O+B+< . . . . G.. G.[+[+H.++++f+A.<+#+-.l . . . . n P+Q+R+p+q+r+L.m.N.S+p.T+U+V+. . ", +". . . . . . . . 6.. 6.. B W+B . . . . . . X+++D E E : : E E Y+Z+< . . . . . . H H H H H . . . g.g.g.. . . . . . . `+8.k * | * | | j #+K+1 . . . :+ @.@+@@@H+>+E E E E E Y+Z+< . . . :+D+.@+@@@H+>+| | | | | #+K+1 . . . G.[+G.[+#@$@E E E E E E Y+Z+< . . . G.[+G.[+#@$@| | | | | | #+> 1 . . . . n %@&@*@=@p+5+6+L.-@;@S+>@,@'@. . ", +". . . . . . . . . . . B W+)@)@B . . . . . X+#+|+x+b+z+A+O+Y+!@~@< . . . . . . . . . . . . . . . g.. . . . . . . . `+9.,+A.A.<+<+#+#+|+> 1 . . . :+{@@@]@^@/@>+b+z+(@O+Y+!@~@< . . . :+{@_@]@^@/@>+A.<+<+#+#+|+m 1 . . . :@[+[+<@[@X.x+M+N+(@O+Y+!@~@< . . . :@[+[+:@}@8.A.A.<+<+#+#+|+> 1 . . . . |@1@2@&@3@4@5@6@7@8@9@0@Q.a@'@. . ", +". . . . . . . . . . B W+)@)@B . . . . . . X+x+@+b@c+B+B+Z+c@k+d@< . . . . . . . . . . . . . . . . . . . . . . . . `+++k k M -.K+K+) ) * 1 . . . . < e@f@g@>+b@c+h@B+i@c@k+>+< . . . . e e@f@g@>+k M -.K+K+' ) * 1 . . . . j@k@[@x+@+b@h@h@B+i@c@W.d@< . . . . j@k@l@++k k g+-.-.K+> ) Y.1 . . . . m@n@1@%@o@n+p@q@r@s@t@u@v@w@x@. . ", +". . . . . . . . . . . B )@B . . . . . . . X+< < < < < < e < < < e . . . . . . . . . . . . . . . . . . . . . . . . `+1 1 l l l l 1 l l l l . . . . . < < < < < < < < < < < < < . . . . . < < < 1 1 1 l l 1 1 l 1 1 . . . . . [@X+< < e e < < < < < < < . . . . . [@j 1 l l l 1 l l 1 l l 1 . . . . y@z@A@B@B@C@D@D@E@E@E@F@] G@H@. . ", +". . . . . . . . . . . . B . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . "}; From 2a6c8fff9fd860a9c41aac6a1c2c79f6a69bca42 Mon Sep 17 00:00:00 2001 From: Wesley Pesetti Date: Tue, 23 Dec 2014 00:23:42 -0800 Subject: [PATCH 2/7] Bug fixes Many bug fixes with directories --- src/Frontend/AutoCompleteManager.cpp | 16 ++- src/Frontend/AutoCompleteManager.h | 2 +- src/Frontend/CodeEdit.cpp | 17 +-- src/Frontend/MainFrame.cpp | 2 +- src/Frontend/Project.cpp | 5 +- src/Frontend/Project.h | 2 +- src/Frontend/ProjectExplorerWindow.cpp | 137 +++++++++++++++++++++++-- src/Frontend/ProjectExplorerWindow.h | 35 ++++++- 8 files changed, 190 insertions(+), 26 deletions(-) diff --git a/src/Frontend/AutoCompleteManager.cpp b/src/Frontend/AutoCompleteManager.cpp index 3f7ffa8a..a12fb3e4 100644 --- a/src/Frontend/AutoCompleteManager.cpp +++ b/src/Frontend/AutoCompleteManager.cpp @@ -53,7 +53,7 @@ void AutoCompleteManager::BuildFromProject(const Project* project) { Project::Directory const *directory = project->GetDirectory(directoryIndex); - for (unsigned int fileIndex = 0; fileIndex < project->GetNumFiles(); ++fileIndex) + for (unsigned int fileIndex = 0; fileIndex < directory->files.size(); ++fileIndex) { BuildFromFile(directory->files[fileIndex]); } @@ -75,12 +75,12 @@ void AutoCompleteManager::BuildFromFile(const Project::File* file) } -void AutoCompleteManager::GetMatchingItems(const wxString& prefix, bool member, wxString& items) const +void AutoCompleteManager::GetMatchingItems(const wxString& token, const wxString& prefix, bool member, wxString& items) const { // Autocompletion selection is case insensitive so transform everything // to lowercase. - wxString test = prefix.Lower(); + wxString test = token.Lower(); // Add the items to the list that begin with the specified prefix. This // could be done much fater with a binary search since our items are in @@ -88,7 +88,6 @@ void AutoCompleteManager::GetMatchingItems(const wxString& prefix, bool member, for (unsigned int i = 0; i < m_entries.size(); ++i) { - // Check that the scope is correct. bool inScope = false; @@ -98,7 +97,14 @@ void AutoCompleteManager::GetMatchingItems(const wxString& prefix, bool member, // We've got no way of knowing the type of the variable in Lua (since // variables don't have types, only values have types), so we display // all members if the prefix contains a member selection operator (. or :) - inScope = (m_entries[i].scope.IsEmpty() != member); + if (!m_entries[i].scope.IsEmpty() && member) + { + inScope = m_entries[i].scope == prefix; + } + else + { + inScope = m_entries[i].scope.IsEmpty() != member; + } } if (inScope && m_entries[i].lowerCaseName.StartsWith(test)) diff --git a/src/Frontend/AutoCompleteManager.h b/src/Frontend/AutoCompleteManager.h index 0261ba0e..1711b021 100644 --- a/src/Frontend/AutoCompleteManager.h +++ b/src/Frontend/AutoCompleteManager.h @@ -62,7 +62,7 @@ class AutoCompleteManager * only autocompletions that are members of some scope are included. The return items * string is in the format used by Scintilla to display autocompletions. */ - void GetMatchingItems(const wxString& prefix, bool member, wxString& items) const; + void GetMatchingItems(const wxString& token, const wxString& prefix, bool member, wxString& items) const; private: diff --git a/src/Frontend/CodeEdit.cpp b/src/Frontend/CodeEdit.cpp index d45356f7..4688aa40 100644 --- a/src/Frontend/CodeEdit.cpp +++ b/src/Frontend/CodeEdit.cpp @@ -503,13 +503,13 @@ void CodeEdit::HideToolTip() void CodeEdit::OnMouseLeave(wxMouseEvent& event) { - HideToolTip(); + //HideToolTip(); event.Skip(); } void CodeEdit::OnKillFocus(wxFocusEvent& event) { - AutoCompCancel(); + //AutoCompCancel(); HideToolTip(); event.Skip(); } @@ -670,6 +670,7 @@ void CodeEdit::StartAutoCompletion(const wxString& token) // If the token refers to a member, the prefix is the member name. wxString prefix; + wxString newToken; bool member = false; if (GetLexer() == wxSCI_LEX_LUA) @@ -702,8 +703,8 @@ void CodeEdit::StartAutoCompletion(const wxString& token) } int end = std::max(end1, end2); - prefix = token.Right( token.Length() - end ); - + newToken = token.Right(token.Length() - end); + prefix = token.Left(end - 1); } else { @@ -711,15 +712,15 @@ void CodeEdit::StartAutoCompletion(const wxString& token) return; } - if (!member && prefix.Length() < m_minAutoCompleteLength) + if (!member && newToken.Length() < m_minAutoCompleteLength) { // Don't pop up the auto completion if the user hasn't typed in very // much yet. return; } - m_autoCompleteManager->GetMatchingItems(prefix, member, items); - + m_autoCompleteManager->GetMatchingItems(newToken, prefix, member, items); + if (!AutoCompActive() || m_autoCompleteItems != items) { @@ -730,7 +731,7 @@ void CodeEdit::StartAutoCompletion(const wxString& token) if (!items.IsEmpty()) { // Show the autocomplete selection list. - AutoCompShow(prefix.Length(), items); + AutoCompShow(newToken.Length(), items); } else { diff --git a/src/Frontend/MainFrame.cpp b/src/Frontend/MainFrame.cpp index d933eccb..004daac3 100644 --- a/src/Frontend/MainFrame.cpp +++ b/src/Frontend/MainFrame.cpp @@ -6152,7 +6152,7 @@ void MainFrame::OnSymbolsParsed(SymbolParserEvent& event) //Set the project to itself so we can trigger Rebuild() m_projectExplorer->SetProject(m_project); - + m_autoCompleteManager.BuildFromProject(m_project); return; } } diff --git a/src/Frontend/Project.cpp b/src/Frontend/Project.cpp index c85db727..0fe00b21 100644 --- a/src/Frontend/Project.cpp +++ b/src/Frontend/Project.cpp @@ -413,6 +413,8 @@ Project::Directory* Project::AddDirectory(const wxString& directoryStr) localPath.MakeRelativeTo(dir->name); file->localPath = localPath.GetPath(); + file->directoryPath = dir->name; + file->fileName = filename; if (file->fileName.IsRelative()) { @@ -891,7 +893,8 @@ bool Project::LoadDirectoryNode(const wxString& baseDirectory, wxXmlNode* node) wxFileName localPath(filename); localPath.MakeRelativeTo(dir->name); - file->localPath = localPath.GetPath(); + file->localPath = localPath.GetPath(); + file->directoryPath = dir->name; file->fileName = filename; dir->files.push_back(file); diff --git a/src/Frontend/Project.h b/src/Frontend/Project.h index d3c6903b..8dcbde77 100644 --- a/src/Frontend/Project.h +++ b/src/Frontend/Project.h @@ -72,7 +72,7 @@ class Project unsigned int fileId; // Unique id we use to match up symbol parsing results. std::vector symbols; - + wxString directoryPath; }; struct Directory diff --git a/src/Frontend/ProjectExplorerWindow.cpp b/src/Frontend/ProjectExplorerWindow.cpp index 5021566d..e227f630 100644 --- a/src/Frontend/ProjectExplorerWindow.cpp +++ b/src/Frontend/ProjectExplorerWindow.cpp @@ -32,6 +32,9 @@ along with Decoda. If not, see . #include #include #include +#include +WX_DECLARE_STACK(wxTreeItemId, wxStack); + #include #include "res/explorer.xpm" @@ -115,7 +118,7 @@ ProjectExplorerWindow::ProjectExplorerWindow(wxWindow* parent, wxWindowID winid) gSizer1->Add( gSizer2, 1, wxEXPAND, 5 ); - m_tree = new wxTreeCtrl(this, winid, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT | wxTR_HIDE_ROOT | wxTR_MULTIPLE | wxTR_EXTENDED); + m_tree = new wxProjectTree(this, winid, wxDefaultPosition, wxDefaultSize, wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT | wxTR_HIDE_ROOT | wxTR_MULTIPLE | wxTR_EXTENDED); m_tree->AssignImageList(imageList); // The "best size" for the tree component must be 0 so that the tree control doesn't @@ -241,7 +244,7 @@ void ProjectExplorerWindow::Rebuild() } } - m_tree->SortChildren(m_tree->GetRootItem()); + SortTree(m_tree->GetRootItem()); // For whatever reason the unselect event isn't reported properly // after deleting all items, so explicitly clear out the info box. @@ -603,7 +606,7 @@ void ProjectExplorerWindow::GetSelectedDirectories(std::vectorSortChildren(m_tree->GetRootItem()); + SortTree(m_tree->GetRootItem()); } void ProjectExplorerWindow::RemoveDirectory(Project::Directory* directory) @@ -624,7 +627,7 @@ void ProjectExplorerWindow::RemoveDirectory(Project::Directory* directory) void ProjectExplorerWindow::InsertFile(Project::File* file) { RebuildForFile(m_root, file); - m_tree->SortChildren(m_tree->GetRootItem()); + SortTree(m_tree->GetRootItem()); } void ProjectExplorerWindow::RemoveFile(Project::File* file) @@ -801,16 +804,61 @@ void ProjectExplorerWindow::OnFilterButton(wxCommandEvent& event) void ProjectExplorerWindow::UpdateFile(Project::File* file) { - m_tree->Freeze(); + wxArrayTreeItemIds selectedItems; + m_tree->GetSelections(selectedItems); + + wxTreeItemId fileNode = FindFile(m_tree->GetRootItem(), file); + bool isSelected = m_tree->IsSelected(fileNode); + if (isSelected) + m_tree->UnselectItem(fileNode); + RemoveFileSymbols(m_tree->GetRootItem(), file); - RebuildForFile(m_root, file); - m_tree->SortChildren(m_tree->GetRootItem()); + //If only one item is selected, need to remove it later + if (isSelected && selectedItems.size() == 1) + { + selectedItems.clear(); + m_tree->GetSelections(selectedItems); + //fileNode = m_tree->UnselectItem + } + + wxTreeItemId node = m_root; + if (file->directoryPath.IsEmpty() == false) + { + wxStack stack; - m_tree->Thaw(); + wxTreeItemIdValue cookie; + wxTreeItemId temp = m_tree->GetFirstChild(node, cookie); + wxString target = file->directoryPath; + + while (temp.IsOk()) + { + if (m_tree->GetItemText(temp) == target) + break; + + temp = m_tree->GetNextChild(temp, cookie); + } + + if (temp.IsOk() == false) + temp = m_root; + node = temp; + } + + RebuildForFile(node, file); + SortTree(m_tree->GetRootItem()); + if (isSelected) + { + m_tree->SelectItem(FindFile(m_tree->GetRootItem(), file)); + + //Deselect the other node + if (selectedItems.size() == 1) + m_tree->SelectItem(selectedItems[0], false); + } + + m_tree->Thaw(); } void ProjectExplorerWindow::SetFilterFlags(unsigned int filterFlags) @@ -881,4 +929,77 @@ void ProjectExplorerWindow::UpdateFilterButtonImage() m_filterButton->SetBitmapLabel(bitmap); +} + +void ProjectExplorerWindow::SortTree(wxTreeItemId node) +{ + m_tree->SortChildren(node); + + //Sort all childen recursively + wxTreeItemIdValue cookie; + wxTreeItemId temp = m_tree->GetFirstChild(node, cookie); + while (temp.IsOk()) + { + if (m_tree->HasChildren(temp)) + { + SortTree(temp); + } + + temp = m_tree->GetNextChild(temp, cookie); + } +} + +#include +#include + +#define DBOUT( s ) \ +{ \ + std::wostringstream os_; \ + os_ << s; \ + OutputDebugStringW( os_.str().c_str() ); \ +} + + +wxTreeItemId ProjectExplorerWindow::FindFile(wxTreeItemId node, Project::File *file) +{ + ItemData* data = static_cast(m_tree->GetItemData(node)); + if (data && data->isFile && data->file == file) + { + return node; + } + + //Sort all childen recursively + wxTreeItemIdValue cookie; + wxTreeItemId temp = m_tree->GetFirstChild(node, cookie); + while (temp.IsOk()) + { + wxTreeItemId node = FindFile(temp, file); + if (node.IsOk()) + return node; + + temp = m_tree->GetNextChild(temp, cookie); + } + + return wxTreeItemId(); +} + + +IMPLEMENT_DYNAMIC_CLASS(wxProjectTree, wxTreeCtrl); +int wxProjectTree::OnCompareItems(const wxTreeItemId &item1, const wxTreeItemId &item2) +{ + ProjectExplorerWindow::ItemData* data1 = static_cast(GetItemData(item1)); + ProjectExplorerWindow::ItemData* data2 = static_cast(GetItemData(item2)); + + //if (data1 && data2) + //{ + if (data1 && data2) + return GetItemText(item1).Cmp(GetItemText(item2)); + else if (data1 || data2) + { + if (data1) return 1; + else return -1; + } + //} + + return GetItemText(item1).Cmp(GetItemText(item2)); } \ No newline at end of file diff --git a/src/Frontend/ProjectExplorerWindow.h b/src/Frontend/ProjectExplorerWindow.h index dd9fb8ff..56b4695f 100644 --- a/src/Frontend/ProjectExplorerWindow.h +++ b/src/Frontend/ProjectExplorerWindow.h @@ -283,6 +283,15 @@ class ProjectExplorerWindow : public wxPanel */ void UpdateFilterButtonImage(); + /** + * Recursively sorts all levels of the tree + */ + void SortTree(wxTreeItemId node); + + /** + * Finds a node in the tree by the file + */ + wxTreeItemId FindFile(wxTreeItemId node, Project::File *file); private: /** @@ -307,7 +316,7 @@ class ProjectExplorerWindow : public wxPanel bool m_filterMatchAnywhere; wxTreeItemId m_root; - wxTreeCtrl* m_tree; + class wxProjectTree* m_tree; wxImageList* m_filterImageList; wxBitmapButton* m_filterButton; @@ -323,4 +332,28 @@ class ProjectExplorerWindow : public wxPanel wxColor m_itemColor; }; + + +#include +class wxProjectTree : public wxTreeCtrl +{ + DECLARE_DYNAMIC_CLASS(wxProjectTree); + +public: + wxProjectTree() : wxTreeCtrl() + {} + + wxProjectTree(wxWindow *parent, wxWindowID id = wxID_ANY, + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxDefaultSize, + long style = wxTR_HAS_BUTTONS | wxTR_LINES_AT_ROOT, + const wxValidator& validator = wxDefaultValidator, + const wxString& name = wxTreeCtrlNameStr) + { + Create(parent, id, pos, size, style, validator, name); + } + + virtual int OnCompareItems(const wxTreeItemId &item1, const wxTreeItemId &item2); +}; + #endif From ca95ccdf4eada7d2f855b263fc6ac0d6b2754810 Mon Sep 17 00:00:00 2001 From: Wesley Pesetti Date: Tue, 23 Dec 2014 00:26:46 -0800 Subject: [PATCH 3/7] Forgot to uncomment --- src/Frontend/CodeEdit.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Frontend/CodeEdit.cpp b/src/Frontend/CodeEdit.cpp index 4688aa40..4fe40ba4 100644 --- a/src/Frontend/CodeEdit.cpp +++ b/src/Frontend/CodeEdit.cpp @@ -503,13 +503,13 @@ void CodeEdit::HideToolTip() void CodeEdit::OnMouseLeave(wxMouseEvent& event) { - //HideToolTip(); + HideToolTip(); event.Skip(); } void CodeEdit::OnKillFocus(wxFocusEvent& event) { - //AutoCompCancel(); + AutoCompCancel(); HideToolTip(); event.Skip(); } From 4f5ebb94635e2666bc3c8530c94727cbe44dc3b7 Mon Sep 17 00:00:00 2001 From: Wesley Pesetti Date: Thu, 25 Dec 2014 03:44:53 -0800 Subject: [PATCH 4/7] More bugfixes for Directories and Debugging Forgot to put directory code in some places. Moved the LuaJIT workaround variable saving code to every hook call. This was causing breakpoints to never get hit. Changed a gettable call to a rawget call to prevent weird stack issues in CallMetaMethod. --- src/Frontend/BreakpointsWindow.cpp | 10 +++ src/Frontend/MainFrame.cpp | 136 ++++++++++++++++++++++++++++- src/Frontend/Project.cpp | 86 ++++++++++++++++++ src/LuaInject/DebugBackend.cpp | 30 +++---- src/LuaInject/DebugBackend.h | 5 ++ 5 files changed, 250 insertions(+), 17 deletions(-) diff --git a/src/Frontend/BreakpointsWindow.cpp b/src/Frontend/BreakpointsWindow.cpp index a6cb2890..5fbbd8a7 100644 --- a/src/Frontend/BreakpointsWindow.cpp +++ b/src/Frontend/BreakpointsWindow.cpp @@ -132,6 +132,16 @@ void BreakpointsWindow::UpdateBreakpoints() { AddBreakpointsForFile(m_project->GetFile(i)); } + + for (unsigned int directoryIndex = 0; directoryIndex < m_project->GetNumDirectories(); ++directoryIndex) + { + Project::Directory *directory = m_project->GetDirectory(directoryIndex); + for (unsigned int fileIndex = 0; fileIndex < directory->files.size(); ++fileIndex) + { + Project::File *file = directory->files[fileIndex]; + AddBreakpointsForFile(file); + } + } } m_breakpointList->Thaw(); diff --git a/src/Frontend/MainFrame.cpp b/src/Frontend/MainFrame.cpp index 004daac3..dcf022c2 100644 --- a/src/Frontend/MainFrame.cpp +++ b/src/Frontend/MainFrame.cpp @@ -1060,7 +1060,6 @@ void MainFrame::OnEditFindPrevious(wxCommandEvent& event) void MainFrame::OnEditFindInFiles(wxCommandEvent& event) { - FindInFilesDialog dialog(this); dialog.AddLookIn("Current Project"); @@ -1152,6 +1151,30 @@ void MainFrame::OnEditFindInFiles(wxCommandEvent& event) } } + for (unsigned int directoryIndex = 0; directoryIndex < m_project->GetNumDirectories(); ++directoryIndex) + { + Project::Directory *directory = m_project->GetDirectory(directoryIndex); + for (unsigned int fileIndex = 0; fileIndex < directory->files.size(); ++fileIndex) + { + Project::File *file = directory->files[fileIndex]; + if (!file->temporary) + { + + wxString fileName = file->fileName.GetFullPath(); + wxString caseFileName = fileName.Lower(); + + for (unsigned int j = 0; j < fileTypesArray.Count(); ++j) + { + if (caseFileName.Matches(fileTypesArray[j])) + { + fileNames.Add(fileName); + } + } + + } + } + } + baseDirectory = wxFileName(m_project->GetFileName()).GetPath(); } @@ -3053,6 +3076,22 @@ bool MainFrame::ParseErrorMessage(const wxString& error, wxString& fileName, uns } } + + for (unsigned int directoryIndex = 0; directoryIndex < m_project->GetNumDirectories(); ++directoryIndex) + { + Project::Directory *directory = m_project->GetDirectory(directoryIndex); + for (unsigned int fileIndex = 0; fileIndex < directory->files.size(); ++fileIndex) + { + Project::File *file = directory->files[fileIndex]; + wxString fullName = file->fileName.GetFullPath(); + + if (fullName.EndsWith(partialName)) + { + fileName = fullName; + foundMatch = true; + } + } + } } @@ -4936,6 +4975,43 @@ void MainFrame::DeleteAllBreakpoints() m_project->DeleteAllBreakpoints(file); } + for (unsigned int directoryIndex = 0; directoryIndex < m_project->GetNumDirectories(); ++directoryIndex) + { + Project::Directory *directory = m_project->GetDirectory(directoryIndex); + for (unsigned int fileIndex = 0; fileIndex < directory->files.size(); ++fileIndex) + { + Project::File *file = directory->files[fileIndex]; + + unsigned int openFileIndex = GetOpenFileIndex(file); + OpenFile* openFile = NULL; + + if (openFileIndex != -1) + { + openFile = m_openFiles[openFileIndex]; + } + + unsigned int scriptIndex = file->scriptIndex; + + for (unsigned int breakpointIndex = 0; breakpointIndex < file->breakpoints.size(); ++breakpointIndex) + { + + unsigned int newLine = file->breakpoints[breakpointIndex]; + + // This file does not have a counterpart in the script debugger, so just + // set the break point "locally". When the debugger encounters the file + // we'll send it the break points. + + if (openFile != NULL) + { + UpdateFileBreakpoint(openFile, newLine, false); + } + + } + + m_project->DeleteAllBreakpoints(file); + } + } + DebugFrontend::Get().RemoveAllBreakPoints(0); m_breakpointsWindow->UpdateBreakpoints(); @@ -5207,6 +5283,24 @@ void MainFrame::OnThreadExit(ThreadEvent& event) } + for (unsigned int directoryIndex = 0; directoryIndex < m_project->GetNumDirectories(); ++directoryIndex) + { + Project::Directory *directory = m_project->GetDirectory(directoryIndex); + for (unsigned int fileIndex = 0; fileIndex < directory->files.size(); ++fileIndex) + { + Project::File *file = directory->files[fileIndex]; + + stdext::hash_map::iterator iterator; + iterator = statusMap.find(std::string(file->fileName.GetFullPath())); + + if (iterator != statusMap.end()) + { + SourceControl::Status status = iterator->second; + SetFileStatus(file, status); + } + } + } + m_projectExplorer->UpdateFileImages(); m_fileStatusThread[0]->Wait(); @@ -5470,6 +5564,19 @@ void MainFrame::CleanUpTemporaryFiles() } + for (unsigned int directoryIndex = 0; directoryIndex < m_project->GetNumDirectories(); ++directoryIndex) + { + Project::Directory *directory = m_project->GetDirectory(directoryIndex); + for (unsigned int fileIndex = 0; fileIndex < directory->files.size(); ++fileIndex) + { + Project::File *file = directory->files[fileIndex]; + if (file->temporary && GetOpenFileIndex(file) == -1) + { + files.push_back(file); + } + } + } + m_projectExplorer->RemoveFiles(files); for (unsigned int i = 0; i < files.size(); ++i) @@ -5705,6 +5812,16 @@ void MainFrame::UpdateProjectFileStatus() thread->AddFileName(file->fileName.GetFullPath()); } + for (unsigned int directoryIndex = 0; directoryIndex < m_project->GetNumDirectories(); ++directoryIndex) + { + Project::Directory *directory = m_project->GetDirectory(directoryIndex); + for (unsigned int fileIndex = 0; fileIndex < directory->files.size(); ++fileIndex) + { + Project::File *file = directory->files[fileIndex]; + thread->AddFileName(file->fileName.GetFullPath()); + } + } + if (thread == m_fileStatusThread[0]) { thread->Create(); @@ -6110,6 +6227,23 @@ Project::File* MainFrame::GetFileMatchingSource(const wxFileName& fileName, cons } + for (unsigned int directoryIndex = 0; directoryIndex < m_project->GetNumDirectories(); ++directoryIndex) + { + Project::Directory *directory = m_project->GetDirectory(directoryIndex); + + for (unsigned int i = 0; i < directory->files.size(); ++i) + { + + Project::File* file = directory->files[i]; + + if (file->scriptIndex == -1 && file->fileName.GetFullName().CmpNoCase(fileName.GetFullName()) == 0) + { + return file; + } + + } + } + return NULL; } diff --git a/src/Frontend/Project.cpp b/src/Frontend/Project.cpp index 0fe00b21..96d4d92a 100644 --- a/src/Frontend/Project.cpp +++ b/src/Frontend/Project.cpp @@ -76,6 +76,17 @@ Project::~Project() ClearVector(m_files[i]->symbols); } + for (unsigned int i = 0; i < m_directories.size(); ++i) + { + Directory *directory = m_directories[i]; + for (unsigned int j = 0; j < directory->files.size(); ++j) + { + File *file = directory->files[j]; + + ClearVector(file->symbols); + } + } + ClearVector(m_files); } @@ -444,6 +455,7 @@ Project::File* Project::AddTemporaryFile(unsigned int scriptIndex) file->fileName = script->name.c_str(); file->status = Status_None; file->fileId = ++s_lastFileId; + file->localPath = "Debug Temporary Files"; m_files.push_back(file); @@ -531,6 +543,16 @@ void Project::CleanUpAfterSession() m_files[i]->scriptIndex = -1; } + for (unsigned int i = 0; i < m_directories.size(); ++i) + { + Directory *directory = m_directories[i]; + for (unsigned int j = 0; j < directory->files.size(); ++j) + { + File *file = directory->files[j]; + + file->scriptIndex = -1; + } + } } Project::File* Project::GetFileForScript(unsigned int scriptIndex) const @@ -544,6 +566,18 @@ Project::File* Project::GetFileForScript(unsigned int scriptIndex) const } } + for (unsigned int i = 0; i < m_directories.size(); ++i) + { + Directory *directory = m_directories[i]; + for (unsigned int j = 0; j < directory->files.size(); ++j) + { + File *file = directory->files[j]; + + if (file->scriptIndex == scriptIndex) + return file; + } + } + return NULL; } @@ -559,6 +593,18 @@ Project::File* Project::GetFileForFileName(const wxFileName& fileName) const } } + for (unsigned int i = 0; i < m_directories.size(); ++i) + { + Directory *directory = m_directories[i]; + for (unsigned int j = 0; j < directory->files.size(); ++j) + { + File *file = directory->files[j]; + + if (file->fileName.GetFullName().CmpNoCase(fileName.GetFullName()) == 0) + return file; + } + } + return NULL; } @@ -600,6 +646,46 @@ void Project::SetBreakpoint(unsigned int scriptIndex, unsigned int line, bool se } } + for (unsigned int i = 0; i < m_directories.size(); ++i) + { + Directory *directory = m_directories[i]; + for (unsigned int j = 0; j < directory->files.size(); ++j) + { + File *file = directory->files[j]; + + if (file->scriptIndex == scriptIndex) + { + + std::vector::iterator iterator; + iterator = std::find(file->breakpoints.begin(), file->breakpoints.end(), line); + + if (set) + { + if (iterator == file->breakpoints.end()) + { + file->breakpoints.push_back(line); + if (!file->temporary) + { + m_needsUserSave = true; + } + } + } + else + { + if (iterator != file->breakpoints.end()) + { + file->breakpoints.erase(iterator); + if (!file->temporary) + { + m_needsUserSave = true; + } + } + } + + } + } + } + } bool Project::ToggleBreakpoint(File* file, unsigned int line) diff --git a/src/LuaInject/DebugBackend.cpp b/src/LuaInject/DebugBackend.cpp index c7d7c5ce..da61e9fe 100644 --- a/src/LuaInject/DebugBackend.cpp +++ b/src/LuaInject/DebugBackend.cpp @@ -227,7 +227,7 @@ void DebugBackend::Log(const char* fmt, ...) if (GetStartupDirectory(fileName, _MAX_PATH)) { strcat(fileName, "log.txt"); - m_log = fopen("c:/temp/log.txt", "wt"); + m_log = fopen("log.txt", "wt"); } } @@ -697,7 +697,10 @@ void DebugBackend::HookCallback(unsigned long api, lua_State* L, lua_Debug* ar) { m_criticalSection.Enter(); - + + // Log for debugging. + //LogHookEvent(api, L, ar); + if (!lua_checkstack_dll(api, L, 2)) { m_criticalSection.Exit(); @@ -779,9 +782,6 @@ void DebugBackend::HookCallback(unsigned long api, lua_State* L, lua_Debug* ar) lua_pop_dll(api, L, 1); - // Log for debugging. - //LogHookEvent(api, L, ar); - //Only try to downgrade the hook when the debugger is not stepping if(m_mode == Mode_Continue) { @@ -862,15 +862,14 @@ void DebugBackend::HookCallback(unsigned long api, lua_State* L, lua_Debug* ar) if (stop) { BreakFromScript(api, L); - - if(vm->luaJitWorkAround) - { - vm->callStackDepth = GetStackDepth(api, L); - vm->lastStepLine = GetCurrentLine(api, ar); - vm->lastStepScript = scriptIndex; - } } - + + if (vm->luaJitWorkAround) + { + vm->callStackDepth = GetStackDepth(api, L); + vm->lastStepLine = GetCurrentLine(api, ar); + vm->lastStepScript = scriptIndex; + } } else { @@ -2135,10 +2134,8 @@ bool DebugBackend::CallMetaMethod(unsigned long api, lua_State* L, int valueInde if (!lua_isnil_dll(api, L, metaTableIndex)) { - lua_pushstring_dll(api, L, method); - lua_gettable_dll(api, L, metaTableIndex); - + lua_rawget_dll(api, L, metaTableIndex); if (lua_isnil_dll(api, L, -1)) { // The meta-method doesn't exist. @@ -2148,6 +2145,7 @@ bool DebugBackend::CallMetaMethod(unsigned long api, lua_State* L, int valueInde } else { + lua_gettop_dll(api, L); lua_pushvalue_dll(api, L, valueIndex); result = lua_pcall_dll(api, L, 1, numResults, 0); } diff --git a/src/LuaInject/DebugBackend.h b/src/LuaInject/DebugBackend.h index 145ef19b..d889a8d0 100644 --- a/src/LuaInject/DebugBackend.h +++ b/src/LuaInject/DebugBackend.h @@ -580,6 +580,11 @@ class DebugBackend const lua_Debug scriptStack[], unsigned int scriptStackSize, StackEntry unifiedStack[]); + void PrintIndent(); + void Lua_PrintIndex(unsigned long api, lua_State *L, int index); + void Lua_PrintTable(unsigned long api, lua_State *L, int index); + void Lua_stackDump(unsigned long api, lua_State *L); + private: typedef stdext::hash_map StateToVmMap; From de57cdc8d080163a20f16f4f504118125512b915 Mon Sep 17 00:00:00 2001 From: Wesley Pesetti Date: Tue, 30 Dec 2014 22:22:31 -0800 Subject: [PATCH 5/7] Tree remembers expanded state when filtering. --- src/Frontend/MainFrame.cpp | 7 +- src/Frontend/ProjectExplorerWindow.cpp | 99 +++++++++++++++++++++++++- src/Frontend/ProjectExplorerWindow.h | 72 ++++++++++++------- 3 files changed, 146 insertions(+), 32 deletions(-) diff --git a/src/Frontend/MainFrame.cpp b/src/Frontend/MainFrame.cpp index dcf022c2..45dee590 100644 --- a/src/Frontend/MainFrame.cpp +++ b/src/Frontend/MainFrame.cpp @@ -6284,8 +6284,11 @@ void MainFrame::OnSymbolsParsed(SymbolParserEvent& event) m_waitForFinalSymbolParse = false; m_statusBar->SetStatusText("", 0); - //Set the project to itself so we can trigger Rebuild() - m_projectExplorer->SetProject(m_project); + //Rebuild the project and the expansion + m_projectExplorer->SaveExpansion(); + m_projectExplorer->Rebuild(); + m_projectExplorer->LoadExpansion(); + m_autoCompleteManager.BuildFromProject(m_project); return; } diff --git a/src/Frontend/ProjectExplorerWindow.cpp b/src/Frontend/ProjectExplorerWindow.cpp index e227f630..cfdf3e29 100644 --- a/src/Frontend/ProjectExplorerWindow.cpp +++ b/src/Frontend/ProjectExplorerWindow.cpp @@ -140,9 +140,9 @@ ProjectExplorerWindow::ProjectExplorerWindow(wxWindow* parent, wxWindowID winid) m_contextMenu = NULL; m_filterMatchAnywhere = false; + m_hasFilter = false; UpdateFilterButtonImage(); - } ProjectExplorerWindow::~ProjectExplorerWindow() @@ -176,6 +176,7 @@ void ProjectExplorerWindow::SetFocusToFilter() void ProjectExplorerWindow::SetProject(Project* project) { m_project = project; + m_expandedIds.clear(); Rebuild(); } @@ -207,9 +208,18 @@ wxTreeItemId ProjectExplorerWindow::GetSelection() const void ProjectExplorerWindow::OnFilterTextChanged(wxCommandEvent& event) { - + //No previous filter + if (m_hasFilter == false) + { + SaveExpansion(); + m_hasFilter = true; + } + m_filter = m_searchBox->GetValue(); + if (m_filter.size() == 0) + m_hasFilter = false; + // If the filter begins with a space, we'll match the text anywhere in the // the symbol name. unsigned int filterLength = m_filter.Length(); @@ -221,6 +231,20 @@ void ProjectExplorerWindow::OnFilterTextChanged(wxCommandEvent& event) Rebuild(); + if (filterLength > 0) + { + //Expand all directories + TraverseTree(m_root, [&, this](wxTreeItemId const &item) + { + ItemData* data = static_cast(m_tree->GetItemData(item)); + if (!data || data->isFile == false) + m_tree->Expand(item); + }); + } + else + { + LoadExpansion(); + } } void ProjectExplorerWindow::Rebuild() @@ -368,7 +392,6 @@ bool ProjectExplorerWindow::MatchesFilter(const wxString& string, const wxString void ProjectExplorerWindow::AddFile(wxTreeItemId parent, Project::File* file) { - ItemData* data = new ItemData; data->file = file; data->symbol = NULL; @@ -983,6 +1006,76 @@ wxTreeItemId ProjectExplorerWindow::FindFile(wxTreeItemId node, Project::File *f return wxTreeItemId(); } +void ProjectExplorerWindow::TraverseTree(wxTreeItemId node, std::function function) const +{ + //Go through all children in depth first order. + wxTreeItemIdValue cookie; + wxTreeItemId temp = m_tree->GetFirstChild(node, cookie); + while (temp.IsOk()) + { + TraverseTree(temp, function); + function(temp); + + temp = m_tree->GetNextChild(temp, cookie); + } +} + + +void ProjectExplorerWindow::SaveExpansion() +{ + m_expandedIds.clear(); + + //Save all nodes that are expanded + TraverseTree(m_root, [&, this](wxTreeItemId const &item) + { + wxTreeItemId node = m_tree->GetItemParent(item); + ItemData* data = static_cast(m_tree->GetItemData(item)); + + //If the file has a parent and it is expanded, add it to the list + if (node.IsOk() && data && data->isFile && m_tree->IsExpanded(node)) + { + m_expandedIds.push_back(data->file); + } + }); +} + +void ProjectExplorerWindow::LoadExpansion() +{ + //Only expand the previously expanded items. + TraverseTree(m_root, [&, this](wxTreeItemId const &item) + { + ItemData* data = static_cast(m_tree->GetItemData(item)); + for (void* expand_file : m_expandedIds) + { + if (data && data->file == expand_file) + { + wxStack treeStack; + + //Collect all parent nodes + wxTreeItemId node = m_tree->GetItemParent(item); + while (node.IsOk()) + { + if (node != m_root) + treeStack.push(node); + + node = m_tree->GetItemParent(node); + } + + //Expand them in reverse order + while (treeStack.size() > 0) + { + node = treeStack.top(); + treeStack.pop(); + + m_tree->Expand(node); + } + + m_tree->Collapse(item); + } + } + }); +} + IMPLEMENT_DYNAMIC_CLASS(wxProjectTree, wxTreeCtrl); int wxProjectTree::OnCompareItems(const wxTreeItemId &item1, const wxTreeItemId &item2) diff --git a/src/Frontend/ProjectExplorerWindow.h b/src/Frontend/ProjectExplorerWindow.h index 56b4695f..e7a8e7f4 100644 --- a/src/Frontend/ProjectExplorerWindow.h +++ b/src/Frontend/ProjectExplorerWindow.h @@ -28,6 +28,7 @@ along with Decoda. If not, see . #include #include #include +#include #include "Project.h" #include "FontColorSettings.h" @@ -215,6 +216,27 @@ class ProjectExplorerWindow : public wxPanel * explorer window. These are a combination of the FilterFlag enum values. */ unsigned int GetFilterFlags() const; + + /** + * Traverses the tree and calls the function on each item. + */ + void TraverseTree(wxTreeItemId node, std::function function) const; + + /** + * Saves the current state of the tree. + */ + void SaveExpansion(); + + /** + * Loads the expanded state of the tree. + */ + void LoadExpansion(); + + /** + * Rebuilds the entire list in the tree control. This should be done when + * the filter changes. + */ + void Rebuild(); enum ID { @@ -251,12 +273,6 @@ class ProjectExplorerWindow : public wxPanel */ void RemoveFileSymbols(wxTreeItemId node, const stdext::hash_set& file); - /** - * Rebuilds the entire list in the tree control. This should be done when - * the filter changes. - */ - void Rebuild(); - /** * Adds the items for the file that match the filter into the tree control. */ @@ -309,27 +325,29 @@ class ProjectExplorerWindow : public wxPanel Image_FileTempCheckedOut = 7, }; - Project* m_project; - - SearchTextCtrl* m_searchBox; - wxString m_filter; - bool m_filterMatchAnywhere; - - wxTreeItemId m_root; - class wxProjectTree* m_tree; - - wxImageList* m_filterImageList; - wxBitmapButton* m_filterButton; - ProjectFilterPopup* m_filterPopup; - unsigned int m_filterFlags; - - ProjectFileInfoCtrl* m_infoBox; - - wxTreeItemId m_stopExpansion; - - wxMenu* m_contextMenu; - - wxColor m_itemColor; + Project* m_project; + std::vector m_expandedIds; + bool m_hasFilter; + + SearchTextCtrl* m_searchBox; + wxString m_filter; + bool m_filterMatchAnywhere; + + wxTreeItemId m_root; + class wxProjectTree* m_tree; + + wxImageList* m_filterImageList; + wxBitmapButton* m_filterButton; + ProjectFilterPopup* m_filterPopup; + unsigned int m_filterFlags; + + ProjectFileInfoCtrl* m_infoBox; + + wxTreeItemId m_stopExpansion; + + wxMenu* m_contextMenu; + + wxColor m_itemColor; }; From d1bd5706d2e2c99bf3df2eba56db6c63d0d45369 Mon Sep 17 00:00:00 2001 From: Wesley Pesetti Date: Thu, 1 Jan 2015 18:12:47 -0800 Subject: [PATCH 6/7] Adding files to directories and deleting files. Directories can now be right clicked to add a file to that directory. When a file is removed from a directory, it is deleted instead. --- src/Frontend/MainApp.cpp | 1 - src/Frontend/MainFrame.cpp | 42 +++++++++++++--- src/Frontend/MainFrame.h | 1 + src/Frontend/Project.cpp | 64 ++++++++++++++++++++++--- src/Frontend/ProjectExplorerWindow.cpp | 66 ++++++++++++++++++++++++++ src/Frontend/ProjectExplorerWindow.h | 12 +++++ 6 files changed, 172 insertions(+), 14 deletions(-) diff --git a/src/Frontend/MainApp.cpp b/src/Frontend/MainApp.cpp index 60ece961..f77b49c9 100644 --- a/src/Frontend/MainApp.cpp +++ b/src/Frontend/MainApp.cpp @@ -100,7 +100,6 @@ bool MainApp::OnInit() UINT openFilesMessage = RegisterWindowMessage("Decoda_OpenFiles"); // Check to see if another instances is running. - if (!wxApp::OnInit()) { return false; diff --git a/src/Frontend/MainFrame.cpp b/src/Frontend/MainFrame.cpp index 45dee590..e239903a 100644 --- a/src/Frontend/MainFrame.cpp +++ b/src/Frontend/MainFrame.cpp @@ -458,6 +458,11 @@ MainFrame::MainFrame(const wxString& title, int openFilesMessage, const wxPoint& m_projectExplorer->SetFileContextMenu(m_contextMenu); + m_directoryContextMenu = new wxMenu; + m_directoryContextMenu->Append(ID_ProjectAddNewFile, _("Add New File")); + + m_projectExplorer->SetDirectoryContextMenu(m_directoryContextMenu); + m_notebookTabMenu = new wxMenu; m_notebookTabMenu->Append(ID_NotebookTabSave, _("&Save")); @@ -1284,6 +1289,10 @@ void MainFrame::OnProjectAddNewFile(wxCommandEvent& WXUNUSED(event)) wxFileName projectFileName(m_project->GetFileName()); wxString projectPath = projectFileName.GetPathWithSep(); + wxString selectedName = m_projectExplorer->GetSelectedDirectoryName(); + + if (selectedName.IsEmpty() == false) + projectPath = selectedName; // If the project hasn't been saved yet and we're using source control, // use the path in source control. @@ -1324,20 +1333,28 @@ void MainFrame::OnProjectAddNewFile(wxCommandEvent& WXUNUSED(event)) file.Close(); Project::File* file = m_project->AddFile(fileName.GetFullPath()); - UpdateForNewFile(file); - - if (m_sourceControl.GetIsInitialized() && dialog.GetAddToSourceContrl()) + if (file->localPath.IsEmpty()) { + UpdateForNewFile(file); + + if (m_sourceControl.GetIsInitialized() && dialog.GetAddToSourceContrl()) + { // Add the file to source control. m_sourceControl.AddFiles(std::string(fileName.GetFullPath()), NULL); - } + } - // Update the status for the new files. - UpdateProjectFileStatus(file); + // Update the status for the new files. + UpdateProjectFileStatus(file); + } + else + { + m_projectExplorer->SaveExpansion(); + m_projectExplorer->Rebuild(); + m_projectExplorer->LoadExpansion(); + } // Open the file in the editor. OpenProjectFile(file); - } else { @@ -4481,6 +4498,17 @@ MainFrame::OpenFile* MainFrame::OpenProjectFile(Project::File* file) void MainFrame::DeleteProjectFile(Project::File* file) { + if (file->localPath.IsEmpty() == false) + { + wxMessageDialog *dial = new wxMessageDialog(NULL, wxT("Are you sure you want to delete this file?"), wxT("Question"), + wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); + + if (dial->ShowModal() != wxID_YES) + { + return; + } + } + for (unsigned int i = 0; i < m_openFiles.size(); ++i) { diff --git a/src/Frontend/MainFrame.h b/src/Frontend/MainFrame.h index 9fe8aa00..9b989b65 100644 --- a/src/Frontend/MainFrame.h +++ b/src/Frontend/MainFrame.h @@ -1528,6 +1528,7 @@ class MainFrame: public wxFrame SourceControl m_sourceControl; wxMenu* m_contextMenu; + wxMenu* m_directoryContextMenu; wxMenu* m_notebookTabMenu; FileStatusThread* m_fileStatusThread[2]; diff --git a/src/Frontend/Project.cpp b/src/Frontend/Project.cpp index 96d4d92a..5448cf64 100644 --- a/src/Frontend/Project.cpp +++ b/src/Frontend/Project.cpp @@ -364,14 +364,39 @@ Project::File* Project::AddFile(const wxString& fileName) if (fileName.IsEmpty()) { - file->tempName = CreateTempName(); + file->tempName = CreateTempName(); } + + if (fileName.Contains('\\')) + { + Directory *bestDirectory = nullptr; + int bestCompare = 0; - m_files.push_back(file); + for (Directory *directory : m_directories) + { + int compare = fileName.CompareTo(directory->name); + if (compare > bestCompare) + { + bestDirectory = directory; + bestCompare = compare; + } + } + + wxFileName localPath(fileName); + localPath.MakeRelativeTo(bestDirectory->name); + + file->localPath = localPath.GetPath(); + + bestDirectory->files.push_back(file); + } + else + { + m_files.push_back(file); + } + m_needsSave = true; return file; - } Project::Directory* Project::AddDirectory(const wxString& directoryStr) @@ -500,14 +525,41 @@ void Project::RemoveFile(File* file) { m_needsSave = true; m_needsUserSave = true; + } + + ClearVector(file->symbols); + delete file; + break; } ++iterator; } - - ClearVector(file->symbols); - delete file; + + std::vector::iterator dirIterator = m_directories.begin(); + + while (dirIterator != m_directories.end()) + { + iterator = (*dirIterator)->files.begin(); + while (iterator != (*dirIterator)->files.end()) + { + if (file == *iterator) + { + (*dirIterator)->files.erase(iterator); + if (!file->temporary) + { + wxRemoveFile(file->fileName.GetFullPath()); + + m_needsSave = true; + m_needsUserSave = true; + } + break; + } + ++iterator; + } + + ++dirIterator; + } } void Project::RemoveDirectory(Directory* directory) diff --git a/src/Frontend/ProjectExplorerWindow.cpp b/src/Frontend/ProjectExplorerWindow.cpp index cfdf3e29..57ecc81d 100644 --- a/src/Frontend/ProjectExplorerWindow.cpp +++ b/src/Frontend/ProjectExplorerWindow.cpp @@ -139,6 +139,7 @@ ProjectExplorerWindow::ProjectExplorerWindow(wxWindow* parent, wxWindowID winid) m_project = NULL; m_contextMenu = NULL; + m_directoryContextMenu = NULL; m_filterMatchAnywhere = false; m_hasFilter = false; @@ -542,9 +543,18 @@ void ProjectExplorerWindow::OnTreeItemContextMenu(wxTreeEvent& event) if (itemData != NULL && itemData->file != NULL && itemData->symbol == NULL) { wxTreeEvent copy(event); + copy.SetInt(0); copy.SetEventType(wxEVT_TREE_CONTEXT_MENU); AddPendingEvent(copy); } + //Is a basic directory + else if (itemData == NULL) + { + wxTreeEvent copy(event); + copy.SetInt(1); + copy.SetEventType(wxEVT_TREE_CONTEXT_MENU); + AddPendingEvent(copy); + } } @@ -740,6 +750,11 @@ void ProjectExplorerWindow::SetFileContextMenu(wxMenu* contextMenu) m_contextMenu = contextMenu; } +void ProjectExplorerWindow::SetDirectoryContextMenu(wxMenu* contextMenu) +{ + m_directoryContextMenu = contextMenu; +} + int ProjectExplorerWindow::GetImageForFile(const Project::File* file) const { @@ -803,7 +818,10 @@ void ProjectExplorerWindow::UpdateFileImages() void ProjectExplorerWindow::OnMenu(wxTreeEvent& event) { + if (event.GetInt() == 0) m_tree->PopupMenu(m_contextMenu, event.GetPoint()); + else if (event.GetInt() == 1) + m_tree->PopupMenu(m_directoryContextMenu, event.GetPoint()); } void ProjectExplorerWindow::OnFilterButton(wxCommandEvent& event) @@ -1076,6 +1094,54 @@ void ProjectExplorerWindow::LoadExpansion() }); } +wxString ProjectExplorerWindow::GetSelectedDirectoryName() +{ + wxArrayTreeItemIds array; + m_tree->GetSelections(array); + + if (array.size() != 1) + return wxString(); + + wxTreeItemId selection = array[0]; + + if (selection.IsOk()) + { + ItemData* itemData = GetDataForItem(selection); + + if (itemData == NULL) + { + wxStack treeStack; + + treeStack.push(selection); + + //Collect all parent nodes + wxTreeItemId node = m_tree->GetItemParent(selection); + while (node.IsOk()) + { + if (node != m_root) + treeStack.push(node); + + node = m_tree->GetItemParent(node); + } + + wxString directory; + + //Expand them in reverse order + while (treeStack.size() > 0) + { + node = treeStack.top(); + treeStack.pop(); + + directory += m_tree->GetItemText(node) + '\\'; + } + + return directory; + } + } + + return wxString(); +} + IMPLEMENT_DYNAMIC_CLASS(wxProjectTree, wxTreeCtrl); int wxProjectTree::OnCompareItems(const wxTreeItemId &item1, const wxTreeItemId &item2) diff --git a/src/Frontend/ProjectExplorerWindow.h b/src/Frontend/ProjectExplorerWindow.h index e7a8e7f4..f882fb10 100644 --- a/src/Frontend/ProjectExplorerWindow.h +++ b/src/Frontend/ProjectExplorerWindow.h @@ -182,6 +182,12 @@ class ProjectExplorerWindow : public wxPanel */ void SetFileContextMenu(wxMenu* menu); + /** + * Sets the menu displays when the user right clicks on a directory. Ownership + * retains with the caller. + */ + void SetDirectoryContextMenu(wxMenu* menu); + /** * Gets a list of all of the files that are currently selected in the tree. * Non-files that are selected are ignored. @@ -237,6 +243,11 @@ class ProjectExplorerWindow : public wxPanel * the filter changes. */ void Rebuild(); + + /** + * Gets the name of the selected directory. + */ + wxString GetSelectedDirectoryName(); enum ID { @@ -346,6 +357,7 @@ class ProjectExplorerWindow : public wxPanel wxTreeItemId m_stopExpansion; wxMenu* m_contextMenu; + wxMenu* m_directoryContextMenu; wxColor m_itemColor; }; From fbae92a7ad7b11cc36ad7768ba5d407fa7f17862 Mon Sep 17 00:00:00 2001 From: Wesley Pesetti Date: Sat, 3 Jan 2015 02:26:22 -0800 Subject: [PATCH 7/7] Bugfix for projects with no directories --- src/Frontend/Project.cpp | 15 +++++++++++---- src/Frontend/ProjectExplorerWindow.cpp | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Frontend/Project.cpp b/src/Frontend/Project.cpp index 5448cf64..0e0d0fba 100644 --- a/src/Frontend/Project.cpp +++ b/src/Frontend/Project.cpp @@ -382,12 +382,19 @@ Project::File* Project::AddFile(const wxString& fileName) } } - wxFileName localPath(fileName); - localPath.MakeRelativeTo(bestDirectory->name); + if (bestDirectory == nullptr) + { + m_files.push_back(file); + } + else + { + wxFileName localPath(fileName); + localPath.MakeRelativeTo(bestDirectory->name); - file->localPath = localPath.GetPath(); + file->localPath = localPath.GetPath(); - bestDirectory->files.push_back(file); + bestDirectory->files.push_back(file); + } } else { diff --git a/src/Frontend/ProjectExplorerWindow.cpp b/src/Frontend/ProjectExplorerWindow.cpp index 57ecc81d..2aa301b8 100644 --- a/src/Frontend/ProjectExplorerWindow.cpp +++ b/src/Frontend/ProjectExplorerWindow.cpp @@ -1050,7 +1050,7 @@ void ProjectExplorerWindow::SaveExpansion() ItemData* data = static_cast(m_tree->GetItemData(item)); //If the file has a parent and it is expanded, add it to the list - if (node.IsOk() && data && data->isFile && m_tree->IsExpanded(node)) + if (node != m_root && node.IsOk() && data && data->isFile && m_tree->IsExpanded(node)) { m_expandedIds.push_back(data->file); }