From 34ccd733505797a3a439be1fa2a913fc9e9fda6d Mon Sep 17 00:00:00 2001 From: Tim Warren Date: Fri, 17 Apr 2015 16:55:48 -0400 Subject: [PATCH] File loading and saving checks --- Makefile | 4 +- README.md | 2 - src/definitions.h | 6 ++ src/widgets/EditPane.cpp | 140 ++++++++++++++++++++++++++++++----- src/widgets/EditPane.h | 7 +- src/widgets/MainFrame.cpp | 36 ++++++++- src/widgets/TabContainer.cpp | 19 ++--- 7 files changed, 173 insertions(+), 41 deletions(-) diff --git a/Makefile b/Makefile index d8ccaa4..abb47b9 100644 --- a/Makefile +++ b/Makefile @@ -16,8 +16,8 @@ WX_RES = $(shell wx-config --rescomp) LDLIBS = $(TARGET) -DEV_CXXFLAGS = -g -Wall -Wextra -CXXFLAGS = -Os -s +DEV_CXXFLAGS = -g -Wall -Wextra -DDEBUG +CXXFLAGS = -Os -DNDEBUG TEST_SRC = $(wildcard tests/*.cpp) TESTS = $(patsubst %.cpp,%,$(TEST_SRC)) diff --git a/README.md b/README.md index 240ecc0..ad2c49c 100644 --- a/README.md +++ b/README.md @@ -15,9 +15,7 @@ A Cross-platform Code Editor Required packages: * build-essential -* libwxgtk3.0-0 * libwxgtk3.0-dev -* libssh2-1 * libssh2-1-dev Optional: diff --git a/src/definitions.h b/src/definitions.h index 846991c..6a6d6f7 100644 --- a/src/definitions.h +++ b/src/definitions.h @@ -10,6 +10,12 @@ const wxString APP_NAME = "Tyro"; const wxString APP_VENDOR = "Aviat Ion"; const wxString APP_VERSION = "0.0.1"; +// Some boilerplate text +const wxString TYRO_SAVE_ERROR = "Failed to save the file. Maybe you lack the permissions."; +const wxString TYRO_SAVE_ERROR_CAPTION = "Saving Failed"; +const wxString TYRO_OPEN_ERROR = "Failed to open the file. Check that it exists, and that you have read permissions."; +const wxString TYRO_OPEN_ERROR_CAPTION = "Open Failed"; + // EditPane file extension to lexer mapping typedef pair StringConstMapData; typedef map StringConstMap; diff --git a/src/widgets/EditPane.cpp b/src/widgets/EditPane.cpp index e6481ae..0f35a68 100644 --- a/src/widgets/EditPane.cpp +++ b/src/widgets/EditPane.cpp @@ -29,16 +29,21 @@ EditPane::~EditPane() } /** - * Encapsulate lexer selection when opening a file - * + * Handle the highlighting config for the + * selected file + * * @param wxString filePath - * @return bool + * @return void */ -bool EditPane::LoadAndHighlight(wxString filePath) +void EditPane::Highlight(wxString filePath) { - fileName = filePath; - string lang = this->GetLangByFile(); + this->fileName.Assign(filePath); + wxLogDebug("Highlighting method"); + + // Get the configuration name for the selected language + string lang = this->GetLangByFile(); + this->StyleClearAll(); // Font setup @@ -147,29 +152,58 @@ bool EditPane::LoadAndHighlight(wxString filePath) else { string typeMap[] = {"null", "int", "unsigned int", "double", "string", "boolean", "array", "object"}; + stringstream output; - cerr << "current lang is:" << lang << endl; - cerr << "keywords array is not an array" << endl; - cerr << "keyword array is a " << typeMap[keywords_array.type()] << endl; + output << "current lang is:" << lang << endl; + output << "keywords array is not an array" << endl; + output << "keyword array is a " << typeMap[keywords_array.type()] << endl; + + wxLogDebug(output.str().c_str()); } - - return this->LoadFile(filePath); } +/** + * Check file path and open the selected file + * + * @param wxString filePath + * @return bool + */ +bool EditPane::Load(wxString filePath) +{ + this->fileName.Assign(filePath); + + if (this->FileReadable()) + { + this->Highlight(filePath); + bool didLoad = this->LoadFile(filePath); + + // @TODO Toggle controls based on write permission + + return didLoad; + } + + return false; +} + +/** + * Determine the format of the current file by + * matching its extension against the patterns + * in the configuration files + * + * @return string + */ string EditPane::GetLangByFile() { JsonValue langList = config->GetRoot(); JsonValue::iterator it; - wxFileName fname(this->fileName); - wxString curr_file = fname.GetFullName(); + wxString curr_file = this->fileName.GetFullName(); // Loop through each language to find a matching file pattern for (it = langList.begin(); it != langList.end(); ++it) { string lang = it.key().asString(); - // Parse the file pattern wxString file_pattern((*it)["file_pattern"].asString()); @@ -195,7 +229,9 @@ string EditPane::GetLangByFile() bool EditPane::SaveFile() { - if ( ! this->fileName) + wxString fname; + + if ( ! this->fileName.IsOk()) { wxFileDialog dlg ( this, @@ -207,24 +243,88 @@ bool EditPane::SaveFile() ); if (dlg.ShowModal() != wxID_OK) return false; - this->fileName = dlg.GetPath(); + fname = dlg.GetPath(); + } + else + { + fname = this->fileName.GetFullPath(); } - return this->SaveFile(this->fileName); + const wxString cfname(fname); + + return this->SaveFile(cfname); } bool EditPane::SaveFile(const wxString &filename) { if ( ! this->IsModified()) return true; - this->SetSavePoint(); + this->fileName.Assign(filename); - return wxStyledTextCtrl::SaveFile(filename); + // Check file permissions + if (this->FileWritable()) + { + this->SetSavePoint(); + return wxStyledTextCtrl::SaveFile(filename); + } + + return false; } bool EditPane::IsModified() { - return (GetModify() && !GetReadOnly()); + return this->GetModify(); +} + +/** + * Check that the current file can be opened + * + * @return bool + */ +bool EditPane::FileReadable() +{ + if ( + this->fileName.IsOk() && + this->fileName.Exists() && + this->fileName.IsFileReadable() + ) return true; + + // Hmm...well, let's give an error + wxMessageDialog errDlg( + this, + TYRO_OPEN_ERROR, + TYRO_OPEN_ERROR_CAPTION, + wxOK | wxICON_ERROR | wxCENTER + ); + errDlg.ShowModal(); + + return false; +} + +/** + * Check that the current file can be saved + * + * @return bool + */ +bool EditPane::FileWritable() +{ + // Lets see...can we write somewhere? + if ( + this->fileName.IsOk() && + ((this->fileName.Exists() && this->fileName.IsFileWritable()) || + (( ! this->fileName.Exists()) && this->fileName.IsDirWritable())) + ) return true; + + // Hmm...well, let's give an error + wxMessageDialog errDlg( + this, + TYRO_SAVE_ERROR, + TYRO_SAVE_ERROR_CAPTION, + wxOK | wxICON_ERROR | wxCENTER + ); + errDlg.ShowModal(); + + return false; } void EditPane::BindEvents() diff --git a/src/widgets/EditPane.h b/src/widgets/EditPane.h index f4fb9f2..a318dae 100644 --- a/src/widgets/EditPane.h +++ b/src/widgets/EditPane.h @@ -21,9 +21,10 @@ public: wxVSCROLL ); ~EditPane(); - wxString fileName; + wxFileName fileName; string GetLangByFile(); - bool LoadAndHighlight(wxString filePath); + bool Load(wxString filePath); + void Highlight(wxString filePath); bool SaveFile(); bool SaveFile(const wxString &filename); bool IsModified(); @@ -36,6 +37,8 @@ private: MARGIN_FOLD, MARGIN_LINE_NUMBERS }; + bool FileReadable(); + bool FileWritable(); void BindEvents(); void OnMarginClick(wxStyledTextEvent &event); }; diff --git a/src/widgets/MainFrame.cpp b/src/widgets/MainFrame.cpp index d8286c4..7492f3c 100644 --- a/src/widgets/MainFrame.cpp +++ b/src/widgets/MainFrame.cpp @@ -24,7 +24,7 @@ MainFrame::MainFrame(wxFrame *frame, const wxString& title) base_sizer->Add(notebook, 1, wxEXPAND | wxALL, 5); base_sizer->SetContainingWindow(this); - base_sizer->SetMinSize(600,400); + base_sizer->SetMinSize(800,600); this->DisableEditControls(); this->BindEvents(); @@ -222,7 +222,39 @@ void MainFrame::OnSave(wxCommandEvent &WXUNUSED(event)) void MainFrame::OnSaveAs(wxCommandEvent &WXUNUSED(event)) { - // @TODO Implement OnSaveAs + EditPane *editor = notebook->GetCurrentEditor(); + + // If the file hasn't been changed, just return + if ( ! editor->IsModified()) return; + + wxFileDialog dlg( + this, + "Save as...", + wxEmptyString, + wxEmptyString, + TYRO_FILE_SAVE_WILDCARDS, + wxFD_SAVE | wxFD_OVERWRITE_PROMPT + ); + + // Return if the file isn't to be saved + if (dlg.ShowModal() != wxID_OK) return; + + wxString filePath = dlg.GetPath(); + + // Save the file + if(editor->SaveFile(filePath)) + { + wxFileName fileName(filePath); + const wxString fullPath = filePath; + const wxString caption= fileName.GetFullName(); + + // Update the name of the tab + notebook->SetPageToolTip(notebook->GetSelection(), fullPath); + notebook->SetPageText(notebook->GetSelection(), caption); + + // Update the editor highlighting + editor->Highlight(filePath); + } } void MainFrame::OnQuit(wxCommandEvent &WXUNUSED(event)) diff --git a/src/widgets/TabContainer.cpp b/src/widgets/TabContainer.cpp index ae17d67..8a8f2a0 100644 --- a/src/widgets/TabContainer.cpp +++ b/src/widgets/TabContainer.cpp @@ -38,22 +38,15 @@ void TabContainer::AddTab(wxString filePath) wxString caption= fileName.GetFullName(); EditPane *editor = new EditPane(this, wxID_ANY); - bool loaded_file = editor->LoadAndHighlight(filePath); - - if (loaded_file) + if (editor->Load(filePath)) { + wxLogDebug("File should be properly loaded."); this->AddPage(editor, caption, true); + + return; } - else - { - wxMessageDialog err( - this, - _T("Failed to open the specified file. Do you have permission to open it?"), - _T("Could not open file."), - wxOK|wxCENTER|wxICON_WARNING - ); - err.ShowModal(); - } + + wxLogDebug("Failed to load file!?"); } EditPane *TabContainer::GetCurrentEditor()