Code folding, save on close prompting, and more

This commit is contained in:
Tim Warren 2015-04-16 17:03:27 -04:00
parent b4a151458e
commit 6dec55b0d2
10 changed files with 213 additions and 107 deletions

View File

@ -51,7 +51,7 @@
"makefile": {
"file_pattern": "Makefile;makefile.*,configure.*;*.mak",
"keywords": [
""
"subst patsubst strip findstring filter filter-out sort word wordlist words firstword lastword dir notdir suffix basename foreach file call value eval origin flavor shell guile"
]
},
"php": {

View File

@ -15,12 +15,16 @@ IMPLEMENT_APP(TyroApp);
bool TyroApp::OnInit()
{
this->SetAppName(APP_NAME);
this->SetVendorName(APP_VENDOR);
MainFrame* frame = new MainFrame(0L, _("Tyro"));
SetTopWindow(frame);
frame->Layout();
frame->CenterOnScreen();
frame->Show(true);
SetTopWindow(frame);
return true;
}

View File

@ -18,9 +18,10 @@
class TyroApp : public wxApp
{
friend class MainFrame;
public:
virtual bool OnInit();
virtual int OnExit();
public:
virtual bool OnInit();
virtual int OnExit();
private:
};
#endif // TYROAPP_H

View File

@ -5,6 +5,10 @@
#ifndef DEFINITIONS_H
#define DEFINITIONS_H
// Application config
const wxString APP_NAME = _T("Tyro");
const wxString APP_VENDOR = _T("Aviat Ion");
// EditPane file extension to lexer mapping
typedef pair<string, int> StringConstMapData;
typedef map<string, int> StringConstMap;
@ -29,24 +33,23 @@ const wxString TYRO_FILE_OPEN_WILDCARDS =
_T("Text (*.txt)|*.txt");
const wxString TYRO_FILE_SAVE_WILDCARDS =
_T("HTML/XHTML (*.html)|*.html|")
_T("CSS (*.css)|*.css|")
_T("JavaScript(*.js)|*.js|")
_T("SQL (*.sql)|*.sql|")
_T("Perl (*.pl, *.cgi)|*.pl;*.cgi|")
_T("PHP (*.php)|*.php|")
_T("Java (*.java)|*.java|")
_T("Fortran (*.f9*, *.f, *.for)|*.f9*;*.f,*.for|")
_T("Pascal (*.pas, *.inc, *.pp)|*.pas;*.inc;*.pp|")
_T("All files (*.*)|*.*|")
_T("Bash (*.sh, *.bsh) |*.sh;*.bsh|")
_T("Batch (*.bat, *.cmd, *.nt)|*.bat;*.cmd,*.nt|")
_T("C/C++ (*.c,*.cpp,*.h)| *.c;*.cc;*.cpp;*.cxx;*.cs;*.h;*.hh;*.hpp;*.hxx;*.sma;*.cp |")
_T("Makefile |Makefile|")
_T("CSS (*.css)|*.css|")
_T("Fortran (*.f9*, *.f, *.for)|*.f9*;*.f,*.for|")
_T("HTML/XHTML (*.html, *.htm)|*.htm*|")
_T("Java (*.java)|*.java|")
_T("JavaScript(*.js)|*.js|")
_T("Makefile |Makefile;makefile.*;MAKEFILE;configure.*;*.mak|")
_T("Pascal (*.pas, *.inc, *.pp)|*.pas;*.inc;*.pp|")
_T("Perl (*.pl, *.cgi)|*.pl;*.pm;*.cgi;*.pod|")
_T("PHP (*.php)|*.php|")
_T("Ruby (*.rb)|*.rb|")
_T("Blitz Basic files (*.bb)|*.bb|")
_T("SQL (*.sql)|*.sql|")
_T("TCL (*.tcl)|*.tcl|")
_T("Bash (*.sh) |*.sh|")
_T("Batch (*.bat)|*.bat|")
_T("Text (*.txt)|*.txt|")
_T("Other (*.*)|*.*");
_T("Text (*.txt)|*.txt");

View File

@ -6,6 +6,7 @@ EditPane::EditPane(
) : wxStyledTextCtrl (parent, id, pos, size, style)
{
config = new TyroConfig();
lexerMap["batch"] = wxSTC_LEX_BATCH;
lexerMap["caml"] = wxSTC_LEX_CAML;
lexerMap["cmake"] = wxSTC_LEX_CMAKE;
@ -14,10 +15,12 @@ EditPane::EditPane(
lexerMap["js"] = wxSTC_LEX_CPP;
lexerMap["html"] = wxSTC_LEX_HTML;
lexerMap["makefile"] = wxSTC_LEX_MAKEFILE;
lexerMap["php"] = wxSTC_LEX_PHPSCRIPT;
lexerMap["php"] = wxSTC_LEX_PHPSCRIPT | wxSTC_LEX_HTML;
lexerMap["perl"] = wxSTC_LEX_PERL;
lexerMap["python"] = wxSTC_LEX_PYTHON;
lexerMap["shell"] = wxSTC_LEX_BASH;
this->BindEvents();
}
EditPane::~EditPane()
@ -25,40 +28,6 @@ EditPane::~EditPane()
delete config;
}
string EditPane::GetLangByFile(const wxString &filename)
{
JsonValue langList = config->GetRoot();
JsonValue::iterator it;
// 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());
file_pattern.Lower();
while ( ! file_pattern.empty())
{
wxString cur = file_pattern.BeforeFirst(';');
if (
(cur == filename) ||
(cur == (filename.BeforeLast('.') + _T(".*"))) ||
(cur == (_T("*.") + filename.AfterLast('.')))
)
{
return lang;
}
file_pattern = file_pattern.AfterFirst(';');
}
}
return "";
}
/**
* Encapsulate lexer selection when opening a file
*
@ -68,10 +37,18 @@ string EditPane::GetLangByFile(const wxString &filename)
bool EditPane::LoadAndHighlight(wxString filePath)
{
fileName = filePath;
string lang = this->GetLangByFile(filePath);
string lang = this->GetLangByFile();
this->StyleClearAll();
// Font setup
wxFont *defaultFont = wxFont::New(
14,
wxFONTFAMILY_MODERN,
wxFONTFLAG_ANTIALIASED,
"Anonymous Pro"
);
if (lexerMap.count(lang) > 0)
{
this->SetLexer(lexerMap[lang]);
@ -88,21 +65,17 @@ bool EditPane::LoadAndHighlight(wxString filePath)
for(int i = 0; i <= wxSTC_STYLE_MAX; i++)
{
this->StyleSetBackground(i, wxColor(253, 246, 227));
this->StyleSetFaceName(i, "Anonymous Pro");
this->StyleSetFont(i, *defaultFont);
}
this->StyleSetForeground (wxSTC_STYLE_DEFAULT, wxColor(101, 123, 131));
this->StyleSetForeground(wxSTC_STYLE_INDENTGUIDE, wxColor(147, 161, 161));
this->SetMarginWidth (MARGIN_LINE_NUMBERS, 50);
this->SetMarginWidth (MARGIN_LINE_NUMBERS, TextWidth(wxSTC_STYLE_LINENUMBER, _T("_9999")));
this->StyleSetForeground (wxSTC_STYLE_LINENUMBER, wxColor(147, 161, 161));
this->StyleSetBackground (wxSTC_STYLE_LINENUMBER, wxColor(238, 232, 213));
this->SetMarginType (MARGIN_LINE_NUMBERS, wxSTC_MARGIN_NUMBER);
this->SetProperty (wxT("fold"), wxT("1") );
this->SetProperty (wxT("fold.comment"), wxT("1") );
this->SetProperty (wxT("fold.compact"), wxT("1") );
this->StyleSetForeground(wxSTC_C_DEFAULT, wxColor(101, 123, 131));
this->StyleSetForeground(wxSTC_C_OPERATOR, wxColor(101, 123, 131));
this->StyleSetForeground(wxSTC_C_HASHQUOTEDSTRING, wxColor(181, 137, 0));
@ -125,6 +98,33 @@ bool EditPane::LoadAndHighlight(wxString filePath)
this->StyleSetBold(wxSTC_C_COMMENTDOCKEYWORD, true);
this->StyleSetBold(wxSTC_C_OPERATOR, true);
// Set up Code folding
this->SetProperty(wxT("fold"), wxT("1"));
this->SetProperty(wxT("fold.comment"), wxT("1"));
this->SetProperty(wxT("fold.compact"), wxT("1"));
this->SetProperty(wxT("fold.html"), wxT("1"));
this->SetFoldFlags(wxSTC_FOLDFLAG_LINEBEFORE_CONTRACTED | wxSTC_FOLDFLAG_LINEAFTER_CONTRACTED);
this->SetMarginType(MARGIN_FOLD, wxSTC_MARGIN_SYMBOL);
this->SetMarginWidth(MARGIN_FOLD, 16);
this->SetMarginSensitive(MARGIN_FOLD, true);
this->SetMarginMask(MARGIN_FOLD, wxSTC_MASK_FOLDERS);
this->MarkerDefine (wxSTC_MARKNUM_FOLDER, wxSTC_MARK_BOXPLUSCONNECTED, _T("WHITE"), _T("BLACK"));
this->MarkerDefine (wxSTC_MARKNUM_FOLDEROPEN, wxSTC_MARK_BOXMINUSCONNECTED, _T("WHITE"), _T("BLACK"));
this->MarkerDefine (wxSTC_MARKNUM_FOLDERSUB, wxSTC_MARK_VLINE, _T("BLACK"), _T("BLACK"));
this->MarkerDefine (wxSTC_MARKNUM_FOLDEREND, wxSTC_MARK_CIRCLEPLUSCONNECTED, _T("WHITE"), _T("BLACK"));
this->MarkerDefine (wxSTC_MARKNUM_FOLDEROPENMID, wxSTC_MARK_CIRCLEMINUSCONNECTED, _T("WHITE"), _T("BLACK"));
this->MarkerDefine (wxSTC_MARKNUM_FOLDERMIDTAIL, wxSTC_MARK_TCORNER, _T("BLACK"), _T("BLACK"));
this->MarkerDefine (wxSTC_MARKNUM_FOLDERTAIL, wxSTC_MARK_LCORNER, _T("BLACK"), _T("BLACK"));
this->SetLayoutCache (wxSTC_CACHE_NONE);
this->SetUseHorizontalScrollBar(1);
// set spaces and indention
this->SetTabWidth(4);
this->SetUseTabs(true);
this->SetTabIndents(true);
this->SetBackSpaceUnIndents(true);
if (keywords_array.isArray())
{
for(int i = 0; i < keywords_array.size(); i++)
@ -134,9 +134,96 @@ bool EditPane::LoadAndHighlight(wxString filePath)
}
else
{
string typeMap[] = {"null", "int", "unsigned int", "double", "string", "boolean", "array", "object"};
cerr << "current lang is:" << lang << endl;
cerr << "keywords array is not an array" << endl;
cerr << "keyword array is a " << keywords_array.type() << endl;
cerr << "keyword array is a " << typeMap[keywords_array.type()] << endl;
}
return this->LoadFile(filePath);
}
string EditPane::GetLangByFile()
{
JsonValue langList = config->GetRoot();
JsonValue::iterator it;
wxFileName fname(this->fileName);
wxString curr_file = fname.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());
file_pattern.Lower();
while ( ! file_pattern.empty())
{
wxString cur = file_pattern.BeforeFirst(';');
if (
(cur == curr_file) ||
(cur == (curr_file.BeforeLast('.') + _T(".*"))) ||
(cur == (_T("*.") + curr_file.AfterLast('.')))
)
{
return lang;
}
file_pattern = file_pattern.AfterFirst(';');
}
}
return "";
}
bool EditPane::SaveFile()
{
if ( ! this->fileName)
{
wxFileDialog dlg (
this,
_T("Save file"),
wxEmptyString,
wxEmptyString,
TYRO_FILE_SAVE_WILDCARDS,
wxFD_SAVE | wxFD_OVERWRITE_PROMPT
);
if (dlg.ShowModal() != wxID_OK) return false;
this->fileName = dlg.GetPath();
}
return this->SaveFile(this->fileName);
}
bool EditPane::SaveFile(const wxString &filename)
{
if ( ! this->IsModified()) return true;
return wxStyledTextCtrl::SaveFile(filename);
}
bool EditPane::IsModified()
{
return (GetModify() && !GetReadOnly());
}
void EditPane::BindEvents()
{
Bind(wxEVT_STC_MARGINCLICK, &EditPane::OnMarginClick, this, wxID_ANY);
}
void EditPane::OnMarginClick(wxStyledTextEvent& event)
{
if (event.GetMargin() == MARGIN_FOLD) {
int lineClick = this->LineFromPosition (event.GetPosition());
int levelClick = this->GetFoldLevel (lineClick);
if ((levelClick & wxSTC_FOLDLEVELHEADERFLAG) > 0) {
this->ToggleFold (lineClick);
}
}
}

View File

@ -22,8 +22,11 @@ public:
);
~EditPane();
wxString fileName;
string GetLangByFile(const wxString &filename);
string GetLangByFile();
bool LoadAndHighlight(wxString filePath);
bool SaveFile();
bool SaveFile(const wxString &filename);
bool IsModified();
private:
StringConstMap lexerMap;
StringConstMap::iterator lexerMapIt;
@ -33,6 +36,8 @@ private:
MARGIN_LINE_NUMBERS,
MARGIN_FOLD
};
void BindEvents();
void OnMarginClick(wxStyledTextEvent &event);
};
#endif // TYRODOC_FRAME_H

View File

@ -1,11 +1,6 @@
/**
* Main Application Frame
*/
#ifdef WX_PRECOMP
#include "wx_pch.h"
#endif
#include "MainFrame.h"
MainFrame::MainFrame(wxFrame *frame, const wxString& title)
@ -23,16 +18,14 @@ MainFrame::MainFrame(wxFrame *frame, const wxString& title)
wxBoxSizer *base_sizer = new wxBoxSizer(wxVERTICAL);
base_sizer->Add(notebook, 1, wxEXPAND | wxALL, 5);
base_sizer->SetContainingWindow(this);
base_sizer->SetMinSize(600,400);
SetSizerAndFit(base_sizer);
this->DisableEditControls();
// Finally, bind events
this->BindEvents();
// Do the layout
SetSizerAndFit(base_sizer);
}
@ -52,6 +45,7 @@ void MainFrame::SetupToolbar()
#include "../../resources/xpm/file_add.xpm"
#include "../../resources/xpm/folder.xpm"
#include "../../resources/xpm/diskette.xpm"
#include "../../resources/xpm/close.xpm"
#include "../../resources/xpm/copy.xpm"
#include "../../resources/xpm/scissors.xpm"
#include "../../resources/xpm/clipboard.xpm"
@ -59,6 +53,7 @@ void MainFrame::SetupToolbar()
wxBitmap new_file_icon(file_add);
wxBitmap open_file_icon(folder);
wxBitmap save_file_icon(diskette);
wxBitmap close_file_icon(close);
wxBitmap copy_icon(copy);
wxBitmap cut_icon(scissors);
wxBitmap paste_icon(clipboard);
@ -66,6 +61,7 @@ void MainFrame::SetupToolbar()
wxBitmap new_file_icon = wxArtProvider::GetBitmap(wxART_NEW);
wxBitmap open_file_icon = wxArtProvider::GetBitmap(wxART_FILE_OPEN);
wxBitmap save_file_icon = wxArtProvider::GetBitmap(wxART_FILE_SAVE);
wxBitmap close_file_icon = wxArtProvider::GetBitmap(wxART_FILE_CLOSE);
wxBitmap copy_icon = wxArtProvider::GetBitmap(wxART_COPY);
wxBitmap cut_icon = wxArtProvider::GetBitmap(wxART_CUT);
wxBitmap paste_icon = wxArtProvider::GetBitmap(wxART_PASTE);
@ -78,6 +74,7 @@ void MainFrame::SetupToolbar()
toolBar->AddTool(wxID_NEW, "New", new_file_icon, "New file");
toolBar->AddTool(wxID_OPEN, "Open", open_file_icon, "Open file");
toolBar->AddTool(wxID_SAVE, "Save", save_file_icon, "Save file");
toolBar->AddTool(wxID_CLOSE, "Close", close_file_icon, "Close file");
toolBar->AddSeparator();
toolBar->AddTool(wxID_COPY, "Copy", copy_icon, "Copy");
toolBar->AddTool(wxID_CUT, "Cut", cut_icon, "Cut");
@ -139,7 +136,7 @@ void MainFrame::BindEvents()
Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnOpen, this, wxID_OPEN);
Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnSave, this, wxID_SAVE);
Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnSaveAs, this, wxID_SAVEAS);
Bind(wxEVT_CLOSE_WINDOW, &TabContainer::OnClose, notebook, wxID_CLOSE);
Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnCloseTab, this, wxID_CLOSE);
Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnAbout, this, wxID_ABOUT);
Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnQuit, this, wxID_EXIT);
Bind(wxEVT_COMMAND_MENU_SELECTED, &MainFrame::OnEditCut, this, wxID_CUT);
@ -172,9 +169,42 @@ void MainFrame::OnOpen(wxCommandEvent &WXUNUSED(event))
notebook->AddTab(filename);
}
void MainFrame::OnFileClose(wxCommandEvent &WXUNUSED(event))
void MainFrame::OnCloseTab(wxCommandEvent &WXUNUSED(event))
{
// @TODO Implement OnFileClose
int current_tab = notebook->GetSelection();
EditPane *editor = notebook->GetCurrentEditor();
if (editor->IsModified())
{
int Msgbox_Choice = wxMessageBox(
_T("File has not been saved, save file before closing?"),
_T("Modified File"),
wxYES_NO | wxCANCEL | wxICON_QUESTION,
this
);
if (Msgbox_Choice == wxYES)
{
editor->SaveFile();
if (editor->IsModified())
{
wxMessageBox(_("File could not be saved"), _("Error"), wxOK | wxICON_EXCLAMATION);
return;
}
//notebook->DeletePage(current_tab);
}
else if (Msgbox_Choice == wxCANCEL)
{
return;
}
}
notebook->DeletePage(current_tab);
// Disable controls
if (notebook->GetPageCount() == 0)
{
this->DisableEditControls();
}
}
void MainFrame::OnSave(wxCommandEvent &WXUNUSED(event))
@ -296,4 +326,4 @@ void MainFrame::DisableEditControls()
toolBar->EnableTool(wxID_COPY, false);
toolBar->EnableTool(wxID_CUT, false);
toolBar->EnableTool(wxID_PASTE, false);
}
}

View File

@ -8,6 +8,8 @@
#include "../wx_common.h"
#include "../TyroApp.h"
#include <wx/cmdline.h>
#include <wx/config.h>
#include <wx/aboutdlg.h>
#include "TabContainer.h"
@ -31,6 +33,7 @@ class MainFrame: public wxFrame
idMenuQuit = 1000,
idMenuAbout
};
wxRect DetermineFrameSize();
void SetupMenu();
void SetupToolbar();
void SetupStatusBar();
@ -48,7 +51,7 @@ class MainFrame: public wxFrame
void OnEditSelectAll(wxCommandEvent &event);
void OnEditUndo(wxCommandEvent &event);
void OnEditRedo(wxCommandEvent &event);
void OnClose(wxCloseEvent &event);
void OnCloseTab(wxCommandEvent &event);
void OnQuit(wxCommandEvent &event);
void OnAbout(wxCommandEvent &event);
};

View File

@ -5,7 +5,6 @@
#include "TabContainer.h"
static unsigned long untitled_document_count = 0;
static unsigned long open_document_count = 0;
TabContainer::TabContainer(
wxWindow* parent,
@ -22,7 +21,6 @@ TabContainer::~TabContainer() {}
void TabContainer::AddTab()
{
untitled_document_count++;
open_document_count++;
wxString caption;
@ -35,8 +33,6 @@ void TabContainer::AddTab()
void TabContainer::AddTab(wxString filePath)
{
open_document_count++;
wxFileName fileName(filePath);
wxString caption= fileName.GetFullName();
@ -63,25 +59,4 @@ void TabContainer::AddTab(wxString filePath)
EditPane *TabContainer::GetCurrentEditor()
{
return (EditPane *) this->GetCurrentPage();
}
void TabContainer::OnClose(wxCloseEvent &event)
{
//EditPane *currentTab = this->GetCurrentEditor();
if (event.CanVeto() && false)//currentTab->isModified())
{
if (
wxMessageBox("The file has not been saved... continue closing?",
"Please confirm",
wxICON_QUESTION | wxYES_NO
) != wxYES
)
{
event.Veto();
return;
}
}
Destroy();
}
}

View File

@ -29,8 +29,6 @@ public:
~TabContainer();
void AddTab();
void AddTab(wxString filePath);
void OnEditSelectAll(wxCommandEvent &event);
void OnClose(wxCloseEvent &event);
EditPane *GetCurrentEditor();
private:
};