From 469c6d4acfcfb31c6fd6d504651903e4b1d952a6 Mon Sep 17 00:00:00 2001 From: Tim Warren Date: Wed, 13 May 2015 16:55:44 -0400 Subject: [PATCH] Prepartion for properly selecting a new language for highlighting --- .travis.yml | 5 +- src/TyroApp.cpp | 34 ++++++++++++ src/settings/LangConfig.cpp | 23 ++++++++ src/settings/LangConfig.h | 1 + src/widgets/EditPane.cpp | 101 +++++++++++++++++++++--------------- src/widgets/EditPane.h | 2 +- src/widgets/MainFrame.cpp | 34 +++++++++++- src/widgets/MainFrame.h | 2 + src/widgets/TyroMenu.cpp | 7 +-- 9 files changed, 158 insertions(+), 51 deletions(-) diff --git a/.travis.yml b/.travis.yml index 283c57b..c30d22e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,10 @@ language: cpp -#Install dependencies before_install: + # Setup virtual x server for gui testing + - export DISPLAY=:99.0 + - sh -e /etc/init.d/xvfb start + # Install dependencies - sudo apt-get update -qq - sudo apt-get install -qq libwxgtk3.0-dev libssh2-1-dev diff --git a/src/TyroApp.cpp b/src/TyroApp.cpp index 3bdeac5..6f63b53 100644 --- a/src/TyroApp.cpp +++ b/src/TyroApp.cpp @@ -12,6 +12,7 @@ wxConfigBase *Glob_config; TyroMenu *Glob_menu_bar; MainFrame *Glob_main_frame; +StringConstMap Glob_lexer_map; /** * Class with main method @@ -30,6 +31,7 @@ public: this->SetVendorName(APP_VENDOR); // Initialize globals + this->InitLexerMap(); Glob_config = wxConfigBase::Get(); Glob_menu_bar = new TyroMenu(); Glob_main_frame = new MainFrame(0L, APP_NAME); @@ -56,6 +58,38 @@ public: return close(true); } +private: + /** + * Set up mapping for lexers + */ + void InitLexerMap() + { + Glob_lexer_map[""] = wxSTC_LEX_NULL; + Glob_lexer_map["batch"] = wxSTC_LEX_BATCH; + Glob_lexer_map["caml"] = wxSTC_LEX_CAML; + Glob_lexer_map["cmake"] = wxSTC_LEX_CMAKE; + Glob_lexer_map["coffeescript"] = wxSTC_LEX_COFFEESCRIPT; + Glob_lexer_map["cpp"] = wxSTC_LEX_CPP; + Glob_lexer_map["css"] = wxSTC_LEX_CSS; + Glob_lexer_map["fortran"] = wxSTC_LEX_FORTRAN; + Glob_lexer_map["haskell"] = wxSTC_LEX_HASKELL; + Glob_lexer_map["html"] = wxSTC_LEX_HTML; + Glob_lexer_map["java"] = wxSTC_LEX_CPP; + Glob_lexer_map["js"] = wxSTC_LEX_CPP; + Glob_lexer_map["lisp"] = wxSTC_LEX_LISP; + Glob_lexer_map["lua"] = wxSTC_LEX_LUA; + Glob_lexer_map["makefile"] = wxSTC_LEX_MAKEFILE; + Glob_lexer_map["markdown"] = wxSTC_LEX_MARKDOWN; + Glob_lexer_map["php"] = wxSTC_LEX_HTML; + Glob_lexer_map["perl"] = wxSTC_LEX_PERL; + Glob_lexer_map["python"] = wxSTC_LEX_PYTHON; + Glob_lexer_map["ruby"] = wxSTC_LEX_RUBY; + Glob_lexer_map["rust"] = wxSTC_LEX_CPP; + Glob_lexer_map["shell"] = wxSTC_LEX_BASH; + Glob_lexer_map["sql"] = wxSTC_LEX_SQL; + Glob_lexer_map["xml"] = wxSTC_LEX_XML; + Glob_lexer_map["yaml"] = wxSTC_LEX_YAML; + } }; IMPLEMENT_APP(TyroApp); diff --git a/src/settings/LangConfig.cpp b/src/settings/LangConfig.cpp index 5aa2db1..9a5788c 100644 --- a/src/settings/LangConfig.cpp +++ b/src/settings/LangConfig.cpp @@ -16,6 +16,9 @@ LangConfig::LangConfig() JsonValue langList = this->GetRoot(); JsonValue::iterator it; + // Special case for non-recognized language + reverseMap["Plain Text"] = ""; + for (it = langList.begin(); it != langList.end(); ++it) { JsonValue langObj = *it; @@ -130,6 +133,26 @@ string LangConfig::GetCurrentLangName() .asString(); } +/** + * Get the "key" of the language based on its name attribute + * + * @param string name + * @return string + */ +string LangConfig::GetLangByName(string name) +{ + StringMap::iterator it; + + it = this->reverseMap.find(name); + + if (it != reverseMap.end()) + { + return it->second; + } + + return ""; +} + /** * Gets the list of languages available * diff --git a/src/settings/LangConfig.h b/src/settings/LangConfig.h index b538870..e933ae1 100644 --- a/src/settings/LangConfig.h +++ b/src/settings/LangConfig.h @@ -15,6 +15,7 @@ public: JsonValue GetLexerMap(string lang="none"); StringMap GetLangList(); string GetCurrentLangName(); + string GetLangByName(string name); private: string lang; StringMap reverseMap; diff --git a/src/widgets/EditPane.cpp b/src/widgets/EditPane.cpp index e969ce0..dde2b58 100644 --- a/src/widgets/EditPane.cpp +++ b/src/widgets/EditPane.cpp @@ -4,6 +4,16 @@ #include "widget.h" +extern StringConstMap Glob_lexer_map; + +/** + * Constructor + * + * @param wxWindow* parent + * @param wxWindowID id + * @param const wxPoint& pos + * @param const wxSize& size + */ EditPane::EditPane( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size ) : wxStyledTextCtrl (parent, id, pos, size, wxBORDER_NONE) @@ -11,32 +21,6 @@ EditPane::EditPane( lang_config = new LangConfig(); theme_config = new ThemeConfig(); - // Map language types to their lexers - lexerMap["batch"] = wxSTC_LEX_BATCH; - lexerMap["caml"] = wxSTC_LEX_CAML; - lexerMap["cmake"] = wxSTC_LEX_CMAKE; - lexerMap["coffeescript"] = wxSTC_LEX_COFFEESCRIPT; - lexerMap["cpp"] = wxSTC_LEX_CPP; - lexerMap["css"] = wxSTC_LEX_CSS; - lexerMap["fortran"] = wxSTC_LEX_FORTRAN; - lexerMap["haskell"] = wxSTC_LEX_HASKELL; - lexerMap["html"] = wxSTC_LEX_HTML; - lexerMap["java"] = wxSTC_LEX_CPP; - lexerMap["js"] = wxSTC_LEX_CPP; - lexerMap["lisp"] = wxSTC_LEX_LISP; - lexerMap["lua"] = wxSTC_LEX_LUA; - lexerMap["makefile"] = wxSTC_LEX_MAKEFILE; - lexerMap["markdown"] = wxSTC_LEX_MARKDOWN; - lexerMap["php"] = wxSTC_LEX_HTML; - lexerMap["perl"] = wxSTC_LEX_PERL; - lexerMap["python"] = wxSTC_LEX_PYTHON; - lexerMap["ruby"] = wxSTC_LEX_RUBY; - lexerMap["rust"] = wxSTC_LEX_CPP; - lexerMap["shell"] = wxSTC_LEX_BASH; - lexerMap["sql"] = wxSTC_LEX_SQL; - lexerMap["xml"] = wxSTC_LEX_XML; - lexerMap["yaml"] = wxSTC_LEX_YAML; - this->BindEvents(); // Some basic properties to set @@ -66,7 +50,7 @@ EditPane::EditPane( this->MarkerDefine(wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_TCORNER, "BLACK", "BLACK"); this->MarkerDefine(wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_LCORNER, "BLACK", "BLACK"); - this->SetLayoutCache (wxSTC_CACHE_DOCUMENT); + //this->SetLayoutCache (wxSTC_CACHE_DOCUMENT); // set spaces and indention this->SetTabWidth(4); @@ -75,6 +59,9 @@ EditPane::EditPane( this->Highlight(""); } +/** + * Destructor + */ EditPane::~EditPane() { wxLogDebug("Called EditPane Destructor"); @@ -96,17 +83,6 @@ void EditPane::Highlight(wxString filePath) // Get the configuration name for the selected language string lang = lang_config->GetLangByFile(this->fileName); - this->StyleClearAll(); - - if (lexerMap.count(lang) > 0) - { - this->SetLexer(lexerMap[lang]); - } - else - { - this->SetLexer(wxSTC_LEX_NULL); - } - // Apply the theme this->ApplyTheme(lang); @@ -125,7 +101,18 @@ void EditPane::Highlight(wxString filePath) * @return void */ void EditPane::ApplyTheme(string lang, string theme) -{ +{ + this->StyleClearAll(); + + if (Glob_lexer_map.count(lang) > 0) + { + this->SetLexer(Glob_lexer_map[lang]); + } + else + { + this->SetLexer(wxSTC_LEX_NULL); + } + if (theme != "") { theme_config->SetTheme(theme); @@ -184,11 +171,16 @@ bool EditPane::Load(wxString filePath) return false; } +/** + * Save the current file + * + * @return bool + */ bool EditPane::SaveFile() { wxString fname; - if ( ! this->fileName.IsOk()) + /*if ( ! this->fileName.IsOk()) { wxFileDialog dlg ( this, @@ -202,7 +194,7 @@ bool EditPane::SaveFile() if (dlg.ShowModal() != wxID_OK) return false; fname = dlg.GetPath(); } - else + else*/ { fname = this->fileName.GetFullPath(); } @@ -212,6 +204,12 @@ bool EditPane::SaveFile() return this->SaveFile(cfname); } +/** + * Save the current file with the specified filename + * + * @param const wxString filename + * @return bool + */ bool EditPane::SaveFile(const wxString &filename) { if ( ! this->IsModified()) return true; @@ -279,6 +277,11 @@ bool EditPane::FileWritable() return false; } +/** + * Wire Event handlers + * + * @return void + */ void EditPane::BindEvents() { Bind(wxEVT_STC_MARGINCLICK, &EditPane::OnMarginClick, this, wxID_ANY); @@ -428,3 +431,19 @@ string EditPane::GetCurrentLang() { return lang_config->GetCurrentLangName(); } + +/** + * Set the highlighting language + * + * @param string name + * @return void + */ +void EditPane::SetCurrentLang(string name) +{ + // Update the current lang in the config + string langKey = lang_config->GetLangByName(name); + lang_config->SetLang(langKey); + + // Re-highlight the page with the new langauge + this->ApplyTheme(langKey); +} diff --git a/src/widgets/EditPane.h b/src/widgets/EditPane.h index 6b2f117..5458ad2 100644 --- a/src/widgets/EditPane.h +++ b/src/widgets/EditPane.h @@ -21,8 +21,8 @@ public: bool SaveFile(const wxString &filename); void ApplyTheme(string lang, string theme=""); string GetCurrentLang(); + void SetCurrentLang(string name); private: - StringConstMap lexerMap; StringConstMap::iterator lexerMapIt; LangConfig *lang_config; ThemeConfig *theme_config; diff --git a/src/widgets/MainFrame.cpp b/src/widgets/MainFrame.cpp index 8284825..b9fee72 100644 --- a/src/widgets/MainFrame.cpp +++ b/src/widgets/MainFrame.cpp @@ -166,6 +166,9 @@ void MainFrame::BindEvents() Bind(wxEVT_FIND_REPLACE_ALL, &MainFrame::OnFindDialog, this, wxID_ANY); Bind(wxEVT_FIND_CLOSE, &MainFrame::OnFindDialog, this, wxID_ANY); + // Language Selection + Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnLangSelect, this, wxID_ANY); + // Help Menu Events Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnAbout, this, wxID_ABOUT); } @@ -404,8 +407,8 @@ void MainFrame::OnAbout(wxCommandEvent &WXUNUSED(event)) info.SetVersion(APP_VERSION, APP_VERSION_MORE); info.AddDeveloper("Tim Warren"); - info.AddArtist("Main icon by Brian Smith"); - info.AddArtist("Other icons by http://dryicons.com"); + info.AddArtist("Brian Smith: Main icon"); + info.AddArtist("http://dryicons.com: Other icons"); info.SetDescription("Tyro, a text editor for all development"); info.SetCopyright(" (C) 2015"); @@ -595,3 +598,30 @@ void MainFrame::EnableEditControls(bool enable) // Make sure the toolbar is refreshed instantly this->manager->Update(); } + +/** + * Handle selection of highlighting language + * + * @param wxCommandEvent& event + * @return void + */ +void MainFrame::OnLangSelect(wxCommandEvent &event) +{ + int selection = event.GetSelection(); + + wxMenu *langMenu = Glob_menu_bar->GetMenu(myLANG_MENU); + wxMenuItem *sel_item = langMenu->FindItem(selection); + + if (sel_item != NULL) + { + wxLogDebug("New language selection"); + + wxString itemLabel = sel_item->GetItemLabelText(); + notebook->GetCurrentEditor()->SetCurrentLang(itemLabel.ToStdString()); + } + else + { + // Go to the more specific event handlers + event.Skip(true); + } +} diff --git a/src/widgets/MainFrame.h b/src/widgets/MainFrame.h index 40258e2..564bb61 100644 --- a/src/widgets/MainFrame.h +++ b/src/widgets/MainFrame.h @@ -46,6 +46,8 @@ class MainFrame: public wxFrame void OnToggleLineWrap(wxCommandEvent &event); void OnToggleLineEndings(wxCommandEvent &event); + void OnLangSelect(wxCommandEvent &event); + void OnCloseTab(wxCommandEvent &event); void OnQuit(wxCommandEvent &event); void OnAbout(wxCommandEvent &event); diff --git a/src/widgets/TyroMenu.cpp b/src/widgets/TyroMenu.cpp index 7e5ae8c..a888971 100644 --- a/src/widgets/TyroMenu.cpp +++ b/src/widgets/TyroMenu.cpp @@ -72,11 +72,9 @@ void TyroMenu::SetupLangMenu() StringMap::iterator last = langs.end(); - langMenu->Append(wxID_ANY, "Plain Text", "Don't highlight file", wxITEM_CHECK); - for (it = langs.begin(); it != last; ++it) { - langMenu->Append(wxID_ANY, it->second, "Highlight file as " + it->second, wxITEM_CHECK); + langMenu->Append(wxID_ANY, it->second, "Highlight file as " + it->second, wxITEM_RADIO); } } @@ -149,8 +147,5 @@ void TyroMenu::SetCurrentLanguage(string lang) lang = "Plain Text"; } - // Clear checks in the current menu - this->EnableEntireMenu(myLANG_MENU, langMenu, true); - this->Check(this->FindMenuItem("&Language", lang), true); } \ No newline at end of file