From 7ce71abc00bf98c23321ea512dc63d62af27a20d Mon Sep 17 00:00:00 2001 From: Timothy Warren Date: Tue, 18 Jun 2019 15:48:28 -0400 Subject: [PATCH] Fix segfault on pref window close, add proper dev build to makefile --- CMakeLists.txt | 2 +- Makefile | 9 ++-- cmake.sh | 4 +- src/TyroApp.cpp | 8 ++- src/widgets/EditPane.cpp | 32 ++--------- src/widgets/EditPane.h | 2 - src/widgets/MainFrame.cpp | 102 +++++++++++++++-------------------- src/widgets/MainFrame.h | 11 ++-- src/widgets/PrefPane.cpp | 20 ++++--- src/widgets/TabContainer.cpp | 2 +- 10 files changed, 77 insertions(+), 115 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4bad572..354412a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,4 +133,4 @@ file(GLOB test_SRC ) add_executable(test_runner ${test_SRC}) -target_link_libraries(test_runner ${wxWidgets_LIBRARIES} ${Libssh2_LIBRARIES} JsonLib BaseLib WidgetLib) +target_link_libraries(test_runner ${wxWidgets_LIBRARIES} ${Libssh2_LIBRARIES} JsonLib WidgetLib) #BaseLib diff --git a/Makefile b/Makefile index 347c1a0..d1516c8 100644 --- a/Makefile +++ b/Makefile @@ -12,9 +12,12 @@ all: ./cmake.sh Tyro -dev: all +dev: + mkdir -p build + cmake -DCMAKE_BUILD_TYPE=Debug -B./build -H. + make -C ./build -run: all +run: ifneq ($(OS),Darwin) ./$(PROGRAM) else @@ -36,12 +39,10 @@ release: all endif ifeq ($(OS),Windows_NT) release: exe -release: strip -SXx $(PROGRAM).exe endif ifeq ($(OS),Linux) release: all -release: strip -SXx $(PROGRAM) endif diff --git a/cmake.sh b/cmake.sh index 25c2422..434e340 100755 --- a/cmake.sh +++ b/cmake.sh @@ -1,7 +1,7 @@ -#!/bin/bash +#!/usr/bin/env bash mkdir -p build cd build -cmake .. +cmake -DCMAKE_BUILD_TYPE=Release .. make "$@" cd .. diff --git a/src/TyroApp.cpp b/src/TyroApp.cpp index dc8f59c..0996896 100644 --- a/src/TyroApp.cpp +++ b/src/TyroApp.cpp @@ -17,7 +17,6 @@ TyroMenu *Glob_menu_bar = nullptr; wxStatusBar *Glob_status_bar = nullptr; MainFrame *Glob_main_frame = nullptr; StringConstMap Glob_lexer_map; -PrefPane *Glob_pref_pane = nullptr; /** * Class with main method @@ -43,7 +42,6 @@ public: Glob_config = wxConfigBase::Get(); Glob_menu_bar = new TyroMenu(); Glob_main_frame = new MainFrame(nullptr, APP_NAME, CalculateWindowSize()); - Glob_pref_pane = new PrefPane(); // Setup Main Window Glob_main_frame->Layout(); @@ -100,12 +98,12 @@ public: bool OnCmdLineParsed(wxCmdLineParser &parser) override { // Get un-named parameters - int i; + size_t i = 0; this->param_count = parser.GetParamCount(); wxLogDebug("%i Parameters", this->param_count); - for (i = 0; i < this->param_count; i++) + for (; i < this->param_count; i++) { this->files.Add(parser.GetParam(i)); } @@ -115,7 +113,7 @@ public: private: // app loading variables wxArrayString files; - int param_count = 0; + size_t param_count = 0; /** * Set up mapping for lexers diff --git a/src/widgets/EditPane.cpp b/src/widgets/EditPane.cpp index 470921e..fbb4f5f 100644 --- a/src/widgets/EditPane.cpp +++ b/src/widgets/EditPane.cpp @@ -3,6 +3,7 @@ */ #include "src/widgets/EditPane.h" +#include "src/widgets/TabContainer.h" extern StringConstMap Glob_lexer_map; static wxConfig *Glob_config = nullptr; @@ -198,7 +199,7 @@ bool EditPane::SaveFile(const wxString &filename) if (saved) { - auto parent = (wxAuiNotebook*) this->GetParent(); + auto parent = (TabContainer*) this->GetParent(); auto currentPage = parent->GetCurrentPage(); auto idx = parent->GetPageIndex(currentPage); wxString currentTitle = parent->GetPageText(idx); @@ -285,7 +286,7 @@ void EditPane::BindEvents() // On modification, update parent tab to show "dirtyness" this->Bind(wxEVT_STC_MODIFIED, [=](wxStyledTextEvent& event) { - auto parent = (wxAuiNotebook*) this->GetParent(); + auto parent = (TabContainer*) this->GetParent(); auto currentPage = parent->GetCurrentPage(); auto idx = parent->GetPageIndex(currentPage); wxString currentTitle = parent->GetPageText(idx); @@ -303,7 +304,7 @@ void EditPane::BindEvents() }, wxID_ANY); this->Bind(wxEVT_STC_SAVEPOINTREACHED, [=](wxStyledTextEvent& event) { - auto parent = (wxAuiNotebook*) this->GetParent(); + auto parent = (TabContainer*) this->GetParent(); auto currentPage = parent->GetCurrentPage(); auto idx = parent->GetPageIndex(currentPage); wxString currentTitle = parent->GetPageText(idx); @@ -318,31 +319,6 @@ void EditPane::BindEvents() // this->Bind(wxEVT_STC_CHARADDED, &EditPane::OnCharAdded, this, wxID_ANY); } -/** - * Look at characters added to help with indentation - * - * @param wxStyledTextEvent& event - * @return void - */ -void EditPane::OnCharAdded(wxStyledTextEvent& event) -{ - char chr = (char) event.GetKey(); - int currentLine = this->GetCurrentLine(); - - if (chr == '\n') - { - int lineInd = 0; - if (currentLine > 0) - { - lineInd = this->GetLineIndentation(currentLine - 1); - } - if (lineInd == 0) return; - - this->SetLineIndentation(currentLine, lineInd); - this->GotoPos(this->PositionFromLine(currentLine) + (lineInd / 4)); - } -} - /** * Iterate through the theme settings and apply them * diff --git a/src/widgets/EditPane.h b/src/widgets/EditPane.h index 74acf64..86122d9 100644 --- a/src/widgets/EditPane.h +++ b/src/widgets/EditPane.h @@ -30,7 +30,5 @@ protected: bool FileReadable(); bool FileWritable(); void BindEvents(); - void OnCharAdded(wxStyledTextEvent &event); - // void SetTheme(const string &theme_name); void _ApplyTheme(JsonValue &lexer_map); }; diff --git a/src/widgets/MainFrame.cpp b/src/widgets/MainFrame.cpp index 3bc33e9..2cff200 100644 --- a/src/widgets/MainFrame.cpp +++ b/src/widgets/MainFrame.cpp @@ -6,11 +6,6 @@ // Nasty globals extern TyroMenu *Glob_menu_bar; extern wxStatusBar *Glob_status_bar; -static TabContainer *notebook = nullptr; -static FilePane *filePane = nullptr; - -extern PrefPane *Glob_pref_pane; - // Frame icon (const static char *tyro_icon[]) #include "resources/xpm/tyro.xpm" @@ -22,9 +17,11 @@ MainFrame::MainFrame(wxFrame *frame, const wxString &title, const wxSize &size) : wxFrame(frame, -1, title, wxDefaultPosition, size) { // Create the tab container - notebook = new TabContainer(this); + this->notebook = new TabContainer(this); - filePane = new FilePane(this); + // Initialize other widgets + this->filePane = new FilePane(this); + this->prefPane = new PrefPane(); // Set the frame icon wxIcon app_icon(tyro_icon); @@ -37,7 +34,7 @@ MainFrame::MainFrame(wxFrame *frame, const wxString &title, const wxSize &size) Glob_status_bar = new wxStatusBar(this, wxID_ANY); Glob_status_bar->SetFieldsCount(6); - this->DoLayout(); + this->MainLayout(); this->BindEvents(); } @@ -54,11 +51,13 @@ MainFrame::~MainFrame() wxDELETE(this->replaceDlg); wxDELETE(this->findReplaceData); wxDELETE(this->toolBar); + wxDELETE(this->prefPane); + wxDELETE(this->filePane); + this->manager->UnInit(); + + wxDELETE(this->notebook); Glob_status_bar->Destroy(); - - - this->manager->UnInit(); } /** @@ -66,7 +65,7 @@ MainFrame::~MainFrame() * * @return void */ -void MainFrame::DoLayout() +void MainFrame::MainLayout() { this->manager = new wxAuiManager(this); this->toolBar = this->SetupToolbar(); @@ -79,7 +78,7 @@ void MainFrame::DoLayout() .Gripper(false) .DockFixed(true) .Resizable(true); - this->manager->AddPane(toolBar, toolBarPaneInfo); + this->manager->AddPane(this->toolBar, toolBarPaneInfo); wxAuiPaneInfo filePaneInfo; filePaneInfo.Left() @@ -87,11 +86,11 @@ void MainFrame::DoLayout() .RightDockable(true) .LeftDockable(true) .Resizable(true); - this->manager->AddPane(filePane, filePaneInfo); + this->manager->AddPane(this->filePane, filePaneInfo); wxAuiPaneInfo notebookPaneInfo; notebookPaneInfo.CenterPane(); - this->manager->AddPane(notebook, notebookPaneInfo); + this->manager->AddPane(this->notebook, notebookPaneInfo); wxAuiPaneInfo statusPaneInfo; statusPaneInfo.Bottom() @@ -105,16 +104,6 @@ void MainFrame::DoLayout() this->EnableEditControls(false); } -/** - * Create the status bar - * - * @return void - */ -void MainFrame::SetupStatusBar() -{ - CreateStatusBar(3); -} - /** * Create the main toolbar * @@ -183,13 +172,13 @@ void MainFrame::BindEvents() this->Bind(wxEVT_MENU, &MainFrame::OnSave, this, wxID_SAVE); this->Bind(wxEVT_MENU, &MainFrame::OnSaveAs, this, wxID_SAVEAS); this->Bind(wxEVT_MENU, &MainFrame::OnCloseTab, this, wxID_CLOSE); - this->Bind(wxEVT_MENU, &TabContainer::OnCloseAllButThis, notebook, myID_CLOSE_ALL_BUT_THIS); - this->Bind(wxEVT_MENU, &TabContainer::OnCloseAll, notebook, myID_CLOSE_ALL); + this->Bind(wxEVT_MENU, &TabContainer::OnCloseAllButThis, this->notebook, myID_CLOSE_ALL_BUT_THIS); + this->Bind(wxEVT_MENU, &TabContainer::OnCloseAll, this->notebook, myID_CLOSE_ALL); this->Bind(wxEVT_MENU, &MainFrame::OnQuit, this, wxID_EXIT); // Edit Menu Events this->Bind(wxEVT_MENU, [=](wxCommandEvent& event) { - EditPane *editor = notebook->GetCurrentEditor(); + EditPane *editor = this->notebook->GetCurrentEditor(); switch(event.GetId()) { @@ -218,7 +207,7 @@ void MainFrame::BindEvents() break; case wxID_PREFERENCES: - Glob_pref_pane->Show(this); + this->prefPane->Show(this); break; case wxID_FIND: @@ -265,7 +254,7 @@ void MainFrame::BindEvents() void MainFrame::OnNew(wxCommandEvent &WXUNUSED(event)) { this->EnableEditControls(); - notebook->AddTab(); + this->notebook->AddTab(); // Make sure the layout is updated immediately this->manager->Update(); @@ -298,7 +287,7 @@ void MainFrame::OnOpenFolder(wxCommandEvent &event) auto path = dlg.GetPath(); - filePane->CreateTree(path); + this->filePane->CreateTree(path); } /** @@ -315,12 +304,12 @@ void MainFrame::OpenFiles(wxArrayString filelist) if (listcount < 1) return; // Open a new tab for each file - notebook->Freeze(); + this->notebook->Freeze(); for (int i = 0; i < listcount; i++) { - notebook->AddTab(filelist[i]); + this->notebook->AddTab(filelist[i]); } - notebook->Thaw(); + this->notebook->Thaw(); this->EnableEditControls(true); } @@ -332,17 +321,17 @@ void MainFrame::OpenFiles(wxArrayString filelist) */ void MainFrame::OnCloseTab(wxCommandEvent &WXUNUSED(event)) { - int current_tab = notebook->GetSelection(); + int current_tab = this->notebook->GetSelection(); - notebook->Freeze(); - notebook->DeletePage(current_tab); + this->notebook->Freeze(); + this->notebook->DeletePage(current_tab); - if (notebook->GetPageCount() == 0) + if (this->notebook->GetPageCount() == 0) { this->EnableEditControls(false); } - notebook->Thaw(); + this->notebook->Thaw(); this->manager->Update(); } @@ -353,10 +342,10 @@ void MainFrame::OnCloseTab(wxCommandEvent &WXUNUSED(event)) */ void MainFrame::OnCloseAll(wxCommandEvent &WXUNUSED(event)) { - notebook->Freeze(); - notebook->DeleteAllPages(); + this->notebook->Freeze(); + this->notebook->DeleteAllPages(); this->EnableEditControls(false); - notebook->Thaw(); + this->notebook->Thaw(); } /** @@ -367,7 +356,7 @@ void MainFrame::OnCloseAll(wxCommandEvent &WXUNUSED(event)) */ void MainFrame::OnSave(wxCommandEvent &event) { - EditPane *editor = notebook->GetCurrentEditor(); + EditPane *editor = this->notebook->GetCurrentEditor(); // Check if the filename is set for the current file if ( ! editor->fileName.IsOk()) @@ -386,7 +375,7 @@ void MainFrame::OnSave(wxCommandEvent &event) */ void MainFrame::OnSaveAs(wxCommandEvent &WXUNUSED(event)) { - EditPane *editor = notebook->GetCurrentEditor(); + EditPane *editor = this->notebook->GetCurrentEditor(); // If the file hasn't been changed, just return if ( ! editor->IsModified()) return; @@ -412,8 +401,8 @@ void MainFrame::OnSaveAs(wxCommandEvent &WXUNUSED(event)) const wxString caption = fileName.GetFullName(); // Update the name of the tab - notebook->SetPageToolTip(notebook->GetSelection(), filePath); - notebook->SetPageText(notebook->GetSelection(), caption); + this->notebook->SetPageToolTip(this->notebook->GetSelection(), filePath); + this->notebook->SetPageText(this->notebook->GetSelection(), caption); // Update the editor highlighting editor->Highlight(filePath); @@ -506,7 +495,7 @@ void MainFrame::OnAbout(wxCommandEvent &WXUNUSED(event)) */ void MainFrame::OnToggleWhitespace(wxCommandEvent& event) { - EditPane *editor = notebook->GetCurrentEditor(); + EditPane *editor = this->notebook->GetCurrentEditor(); int flag = (event.IsChecked()) ? wxSTC_WS_VISIBLEALWAYS : wxSTC_WS_INVISIBLE; @@ -556,7 +545,7 @@ void MainFrame::OnEditReplace(wxCommandEvent &WXUNUSED(event)) void MainFrame::OnFindDialog(wxFindDialogEvent &event) { wxEventType type = event.GetEventType(); - EditPane *editor = notebook->GetCurrentEditor(); + EditPane *editor = this->notebook->GetCurrentEditor(); // Parse flags uint stc_flags = 0; @@ -655,7 +644,7 @@ void MainFrame::OnFindDialog(wxFindDialogEvent &event) */ void MainFrame::OnToggleLineWrap(wxCommandEvent &event) { - EditPane *editor = notebook->GetCurrentEditor(); + EditPane *editor = this->notebook->GetCurrentEditor(); int flag = (event.IsChecked()) ? wxSTC_WRAP_WORD : wxSTC_WRAP_NONE; @@ -671,7 +660,7 @@ void MainFrame::OnToggleLineWrap(wxCommandEvent &event) */ void MainFrame::OnToggleLineEndings(wxCommandEvent &event) { - notebook->GetCurrentEditor()->SetViewEOL(event.IsChecked()); + this->notebook->GetCurrentEditor()->SetViewEOL(event.IsChecked()); } /** @@ -720,7 +709,7 @@ void MainFrame::OnLangSelect(wxCommandEvent &event) wxMenuItem *sel_item = langMenu->FindChildItem(event.GetId()); wxString itemLabel = sel_item->GetItemLabelText(); - notebook->GetCurrentEditor()->SetCurrentLang(itemLabel.ToStdString()); + this->notebook->GetCurrentEditor()->SetCurrentLang(itemLabel.ToStdString()); } else { @@ -736,13 +725,10 @@ void MainFrame::OnLangSelect(wxCommandEvent &event) */ void MainFrame::OnPrefsChanged(wxCommandEvent &WXUNUSED(event)) { - EditPane *editor; - - notebook->Freeze(); - for(size_t i = 0; i < notebook->GetPageCount(); i++) + this->notebook->Freeze(); + for(size_t i = 0; i < this->notebook->GetPageCount(); i++) { - editor = notebook->GetEditor(i); - editor->ReApplyTheme(); + this->notebook->GetEditor(i)->ReApplyTheme(); } - notebook->Thaw(); + this->notebook->Thaw(); } diff --git a/src/widgets/MainFrame.h b/src/widgets/MainFrame.h index d3bd642..248bd24 100644 --- a/src/widgets/MainFrame.h +++ b/src/widgets/MainFrame.h @@ -6,20 +6,21 @@ #include "src/widgets/TyroMenu.h" #include "src/widgets/EditPane.h" #include "src/widgets/TabContainer.h" -#ifndef TRAVIS #include "src/widgets/PrefPane.h" -#endif #include "src/widgets/FilePane.h" class MainFrame: public wxFrame { public: MainFrame(wxFrame *frame, const wxString &title, const wxSize &size); - ~MainFrame(); + ~MainFrame() override; void EnableEditControls(bool enable=true); void OpenFiles(wxArrayString filelist); void OnPrefsChanged(wxCommandEvent &event); private: + PrefPane *prefPane = nullptr; + FilePane *filePane = nullptr; + TabContainer *notebook = nullptr; wxAuiManager *manager = nullptr; wxAuiToolBar *toolBar = nullptr; wxFindReplaceData *findReplaceData = nullptr; @@ -27,16 +28,14 @@ class MainFrame: public wxFrame wxFindReplaceDialog *findDlg = nullptr; wxFindReplaceDialog *replaceDlg = nullptr; wxAuiToolBar* SetupToolbar(); - void SetupStatusBar(); void BindEvents(); - void DoLayout(); + void MainLayout(); // Main Menu Event handlers void OnNew(wxCommandEvent &event); void OnOpen(wxCommandEvent &event); void OnOpenFolder(wxCommandEvent &event); void OnCloseAll(wxCommandEvent &event); - void OnFileClose(wxCommandEvent &event); void OnSave(wxCommandEvent &event); void OnSaveAs(wxCommandEvent &event); diff --git a/src/widgets/PrefPane.cpp b/src/widgets/PrefPane.cpp index 66b830a..52e5aa6 100644 --- a/src/widgets/PrefPane.cpp +++ b/src/widgets/PrefPane.cpp @@ -3,6 +3,13 @@ extern wxConfigBase *Glob_config; +// As much as I dislike this global reference +// it seems to be the safest option for calling +// a method from the Main frame. Even attempting +// to get the Main frame from the GetParent() method +// is more prone to segfaulting. +extern MainFrame *Glob_main_frame; + class GeneralPrefPanePage : public wxPanel { public: explicit GeneralPrefPanePage( @@ -16,8 +23,6 @@ public: { auto BASE_MARGIN = 30; - this->frame = (MainFrame *) parent; - wxFont globalFont = wxSystemSettings::GetFont(wxSYS_ANSI_FIXED_FONT); Glob_config->Read("global_font", &globalFont); @@ -58,19 +63,19 @@ public: { this->showLineNumbers->Bind(wxEVT_CHECKBOX, [=] (wxCommandEvent &event) { Glob_config->Write("show_line_numbers", event.IsChecked()); - this->frame->OnPrefsChanged(event); + Glob_main_frame->OnPrefsChanged(event); Glob_config->Flush(); }, myID_PREFS_LINE_NUMBERS); this->showIndentGuides->Bind(wxEVT_CHECKBOX, [=] (wxCommandEvent &event) { Glob_config->Write("show_indent_guides", event.IsChecked()); - this->frame->OnPrefsChanged(event); + Glob_main_frame->OnPrefsChanged(event); Glob_config->Flush(); }, myID_PREFS_IDENT_GUIDES); this->showCodeFolding->Bind(wxEVT_CHECKBOX, [=] (wxCommandEvent &event) { Glob_config->Write("show_code_folding", event.IsChecked()); - this->frame->OnPrefsChanged(event); + Glob_main_frame->OnPrefsChanged(event); Glob_config->Flush(); }, myID_PREFS_CODE_FOLDING); } @@ -117,8 +122,8 @@ public: Glob_config->Write("show_code_folding", this->showCodeFolding->IsChecked()); Glob_config->Write("global_font", this->fontPicker->GetSelectedFont()); - wxCommandEvent evt = wxCommandEvent(); - this->frame->OnPrefsChanged(evt); + auto evt = wxCommandEvent(); + Glob_main_frame->OnPrefsChanged(evt); Glob_config->Flush(); @@ -126,7 +131,6 @@ public: } private: - MainFrame *frame; wxCheckBox *showLineNumbers = nullptr; wxCheckBox *showIndentGuides = nullptr; wxCheckBox *showCodeFolding = nullptr; diff --git a/src/widgets/TabContainer.cpp b/src/widgets/TabContainer.cpp index ffacae8..8934fd8 100644 --- a/src/widgets/TabContainer.cpp +++ b/src/widgets/TabContainer.cpp @@ -81,7 +81,7 @@ void TabContainer::AddTab(const wxString &filePath) return; } - wxString caption= fileName.GetFullName(); + wxString caption = fileName.GetFullName(); EditPane *editor = this->NewEditor(); if (editor->Load(filePath))