From 4bef2eea7ed971c486ebfcec4c7be9a0b463e248 Mon Sep 17 00:00:00 2001 From: Gerald Schmidt Date: Mon, 21 Jan 2008 23:05:47 +0000 Subject: [PATCH] GNU Aspell integration: spelling/style now separate --- src/housestyle.cpp | 132 ++++++++++++++++++++++++-------------- src/housestyle.h | 10 ++- src/styledialog.cpp | 153 +++++++++++++++++++++++++++++++------------- src/styledialog.h | 8 ++- 4 files changed, 207 insertions(+), 96 deletions(-) diff --git a/src/housestyle.cpp b/src/housestyle.cpp index 50a42d9..f9c1c95 100755 --- a/src/housestyle.cpp +++ b/src/housestyle.cpp @@ -21,6 +21,7 @@ #include "readfile.h" HouseStyle::HouseStyle ( + int typeParameter, const std::string& bufferParameter, const std::string& ruleDirectoryParameter, const std::string& ruleFileParameter, @@ -28,6 +29,7 @@ HouseStyle::HouseStyle ( const std::string& filterFileParameter, const std::string& pathSeparatorParameter, int contextRangeParameter ) : + type ( typeParameter ), buffer ( bufferParameter ), ruleDirectory ( ruleDirectoryParameter ), ruleFile ( ruleFileParameter ), @@ -48,7 +50,7 @@ void HouseStyle::collectFilter ( std::set& excludeSet, int *filterCount ) { - if ( fileName == "(No filter)" ) + if ( type == HS_TYPE_SPELL || fileName == "(No filter)" ) return; string filePath, buffer; @@ -112,6 +114,9 @@ void HouseStyle::collectRules ( string& fileName, std::set& excludeSet, int *ruleCount ) { + if (type == HS_TYPE_SPELL) + return; + std::string filePath, buffer; filePath = ruleDirectory + pathSeparator + fileName; if ( !ReadFile::run ( filePath, buffer ) ) @@ -159,7 +164,7 @@ void HouseStyle::collectRules ( string& fileName, bool HouseStyle::createReport() { - if ( !updateRules() ) + if ( type == HS_TYPE_STYLE && !updateRules() ) { error = "no rules found"; return false; @@ -175,22 +180,25 @@ bool HouseStyle::createReport() } std::vector > nodeVector; xtr->getNodeVector ( nodeVector ); - + int ruleVectorsize, nodeVectorSize; - /* - boost::shared_ptr rule(new Rule( - "_", - false)); - */ - std::vector contextVector; std::vector::iterator matchIterator; ruleVectorsize = ruleVector->size(); nodeVectorSize = nodeVector.size(); - Spellcheck spellcheck ( dictionary, passiveDictionary ); + WrapAspell *spellcheck = NULL; + try { + if (type == HS_TYPE_SPELL) + spellcheck = new WrapAspell( ruleFile ); + } + catch (...) + { + error = "Cannot initialise spellcheck"; + return false; + } std::string nodeBuffer; unsigned elementCount; @@ -202,58 +210,84 @@ bool HouseStyle::createReport() if ( !nodeBuffer.size() ) continue; + // try spelling first + if ( type == HS_TYPE_SPELL && spellcheck ) + { + spellcheck->checkString ( + nodeBuffer, + contextVector, + contextRange ); + + for ( matchIterator = contextVector.begin(); + matchIterator != contextVector.end(); + matchIterator++ ) + { + matchIterator->report = "Not in dictionary"; + matchIterator->elementCount = elementCount; + matchVector.push_back ( *matchIterator ); + } + contextVector.clear(); + continue; // bail out before we reach style loop + } + + // otherwise, proceed with style check for ( int i = 0; i < ruleVectorsize; i++ ) { - //rule = ruleVector->at(i); - boost::shared_ptr rule ( ruleVector->at ( i ) ); - if ( rule->matchPatternGlobal ( - nodeBuffer, - contextVector, - elementCount, - contextRange ) ) + if ( type == HS_TYPE_STYLE ) { - std::string report = rule->getReport(); + boost::shared_ptr rule ( ruleVector->at ( i ) ); + if ( rule->matchPatternGlobal ( + nodeBuffer, + contextVector, + elementCount, + contextRange ) ) + { + std::string report = rule->getReport(); + + for ( matchIterator = contextVector.begin(); + matchIterator != contextVector.end(); + matchIterator++ ) + { + if ( rule->getAdjustCaseAttribute() ) + CaseHandler::adjustCase ( + matchIterator->replace, + matchIterator->match ); + + // tentative? + matchIterator->tentative = + ( rule->getTentativeAttribute() ) ? true : false; + + matchIterator->report = report; + + matchVector.push_back ( *matchIterator ); + } + contextVector.clear(); + } + } +/* + // check spelling + else // if ( !dictionary->empty() ) + { + spellcheck->checkString ( + nodeBuffer, + contextVector, + contextRange ); for ( matchIterator = contextVector.begin(); - matchIterator != contextVector.end(); - matchIterator++ ) + matchIterator != contextVector.end(); + matchIterator++ ) { - if ( rule->getAdjustCaseAttribute() ) - CaseHandler::adjustCase ( - matchIterator->replace, - matchIterator->match ); - - // tentative? - matchIterator->tentative = - ( rule->getTentativeAttribute() ) ? true : false; - - matchIterator->report = report; + matchIterator->report = "Not in dictionary"; + matchIterator->elementCount = elementCount; matchVector.push_back ( *matchIterator ); } contextVector.clear(); } - } - // check spelling - if ( !dictionary->empty() ) - { - spellcheck.checkString ( - nodeBuffer, - contextVector, - contextRange ); - - for ( matchIterator = contextVector.begin(); - matchIterator != contextVector.end(); - matchIterator++ ) - { - matchIterator->report = "Not in dictionary"; - matchIterator->elementCount = elementCount; - - matchVector.push_back ( *matchIterator ); - } - contextVector.clear(); +*/ } } + delete spellcheck; // ok if NULL return true; } diff --git a/src/housestyle.h b/src/housestyle.h index d516157..d7adaee 100755 --- a/src/housestyle.h +++ b/src/housestyle.h @@ -31,13 +31,20 @@ #include "xmlrulereader.h" #include "housestylereader.h" #include "xmlfilterreader.h" -#include "spellcheck.h" +//#include "spellcheck.h" +#include "wrapaspell.h" #include "casehandler.h" +enum { + HS_TYPE_SPELL = 0, + HS_TYPE_STYLE +}; + class HouseStyle { public: HouseStyle ( + int type, const std::string& bufferParameter, const std::string& ruleDirectoryParameter, const std::string& ruleFileParameter, @@ -50,6 +57,7 @@ class HouseStyle std::string getLastError(); std::vector getMatchVector(); private: + int type; std::string buffer, ruleDirectory, diff --git a/src/styledialog.cpp b/src/styledialog.cpp index b71faf1..a7de978 100755 --- a/src/styledialog.cpp +++ b/src/styledialog.cpp @@ -18,10 +18,15 @@ */ #include +#include "aspell.h" #include "styledialog.h" #include "nocasecompare.h" #define ngettext wxGetTranslation +#ifdef __WXMSW__ + #include "aspellpaths.h" +#endif + BEGIN_EVENT_TABLE ( StyleDialog, wxDialog ) EVT_BUTTON ( ID_STYLE_REPORT, StyleDialog::OnReport ) EVT_BUTTON ( ID_STYLE_IGNORE_ALL, StyleDialog::OnStyleIgnoreAll ) @@ -52,13 +57,14 @@ StyleDialog::StyleDialog ( const wxString& browserParameter, const wxString& ruleSetPresetParameter, const wxString& filterPresetParameter, + int typeParameter, bool readOnlyParameter, wxPoint position, wxSize size ) : wxDialog ( parent, wxID_ANY, - wxString ( _ ( "Spelling and Style" ) ), + wxString ( ( typeParameter == ID_TYPE_STYLE) ? _ ( "Style" ) : _ ( "Spelling" ) ), position, size, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX ), @@ -69,11 +75,11 @@ StyleDialog::StyleDialog ( browser ( browserParameter ), ruleSetPreset ( ruleSetPresetParameter ), filterPreset ( filterPresetParameter ), + type(typeParameter), readOnly ( readOnlyParameter ) { SetIcon ( icon ); - wxSize buttonSize ( 100, wxDefaultCoord ); // top box ruleSetCombo = new wxComboBox ( @@ -83,18 +89,25 @@ StyleDialog::StyleDialog ( wxDefaultPosition, wxSize ( 200, -1 ) ); - filterCombo = new wxComboBox ( - this, - ID_STYLE_COMBO_FILTER, - _T ( "" ), - wxDefaultPosition, - wxSize ( 200, -1 ) - ); + + int width, height; + ruleSetCombo->GetSize ( &width, &height ); + wxSize buttonSize ( 100, height ); + + + filterCombo = new wxComboBox ( + this, + ID_STYLE_COMBO_FILTER, + _T ( "" ), + wxDefaultPosition, + wxSize ( 200, -1 ) ); + if (type != ID_TYPE_STYLE) + filterCombo->Show ( false ); wxButton *createReportButton = new wxButton ( this, ID_STYLE_REPORT, - _ ( "&Report" ), + _ ( "&Check" ), wxDefaultPosition, buttonSize, 0 ); @@ -114,9 +127,10 @@ StyleDialog::StyleDialog ( int widthUnit = 35; myTable->InsertColumn ( 0, _ ( "No." ), wxLIST_FORMAT_LEFT, widthUnit * 1 ); myTable->InsertColumn ( 1, _ ( "Context" ), wxLIST_FORMAT_RIGHT, widthUnit * 3 ); - myTable->InsertColumn ( 2, _ ( "Match" ), wxLIST_FORMAT_CENTER, widthUnit * 3 ); + myTable->InsertColumn ( 2, _ ( "Error" ), wxLIST_FORMAT_CENTER, widthUnit * 3 ); myTable->InsertColumn ( 3, _ ( "Context" ), wxLIST_FORMAT_LEFT, widthUnit * 3 ); myTable->InsertColumn ( 4, _ ( "Suggestion" ), wxLIST_FORMAT_LEFT, widthUnit * 3 ); + myTable->InsertColumn ( 5, _ ( "Rule" ), wxLIST_FORMAT_LEFT, widthUnit * 3 ); myTable->InsertColumn ( 6, _ ( "Action" ), wxLIST_FORMAT_LEFT, widthUnit * 3 ); table = myTable; @@ -126,9 +140,9 @@ StyleDialog::StyleDialog ( new wxButton ( this, ID_STYLE_EDIT, - _ ( "&Edit" ), + _ ( "&Apply changes" ), wxDefaultPosition, - buttonSize, + wxSize ( -1, buttonSize.GetHeight() ), 0 ); wxButton *webReportButton = new wxButton ( @@ -136,7 +150,7 @@ StyleDialog::StyleDialog ( ID_STYLE_WEB_REPORT, _ ( "&Printable report" ), wxDefaultPosition, - buttonSize, + wxSize ( -1, buttonSize.GetHeight() ), 0 ); wxButton *webSummaryButton = new wxButton ( @@ -144,15 +158,15 @@ StyleDialog::StyleDialog ( ID_STYLE_WEB_SUMMARY, _ ( "Pr&intable summary" ), wxDefaultPosition, - buttonSize, + wxSize ( -1, buttonSize.GetHeight() ), 0 ); wxButton *selectAllButton = new wxButton ( this, ID_STYLE_CHANGE_ALL, - _ ( "&Change all" ), + _ ( "&Select all" ), wxDefaultPosition, - buttonSize, + wxSize ( -1, buttonSize.GetHeight() ), 0 ); wxButton *deselectAllButton = new wxButton ( @@ -160,15 +174,15 @@ StyleDialog::StyleDialog ( ID_STYLE_IGNORE_ALL, _ ( "I&gnore all" ), wxDefaultPosition, - buttonSize, + wxSize ( -1, buttonSize.GetHeight() ), 0 ); wxButton *cancelButton = new wxButton ( this, wxID_CANCEL, - _ ( "C&ancel" ), + _ ( "Ca&ncel" ), wxDefaultPosition, - buttonSize, + wxSize ( -1, buttonSize.GetHeight() ), 0 ); wxBoxSizer *reportButtonSizer = new wxBoxSizer ( wxHORIZONTAL ); @@ -190,7 +204,72 @@ StyleDialog::StyleDialog ( reportTopSizer->Add ( status, 0 ); this->SetSizer ( reportTopSizer ); + createReportButton->SetFocus(); + + if ( readOnly ) + filterCombo->Enable ( false ); + + // keyboard shortcuts + wxAcceleratorEntry entries[7]; + entries[0].Set ( wxACCEL_ALT, ( int ) 'C', ID_STYLE_REPORT ); + entries[1].Set ( wxACCEL_ALT, ( int ) 'A', ID_STYLE_EDIT ); + entries[2].Set ( wxACCEL_ALT, ( int ) 'W', ID_STYLE_WEB_REPORT ); + entries[3].Set ( wxACCEL_ALT, ( int ) 'B', ID_STYLE_WEB_SUMMARY ); + entries[4].Set ( wxACCEL_ALT, ( int ) 'S', ID_STYLE_CHANGE_ALL ); + entries[5].Set ( wxACCEL_ALT, ( int ) 'I', ID_STYLE_IGNORE_ALL ); + entries[6].Set ( wxACCEL_ALT, ( int ) 'N', wxID_CANCEL ); + + wxAcceleratorTable accel ( 7, entries ); + this->SetAcceleratorTable ( accel ); + // update combo lists + + // special case spellcheck + if (type == ID_TYPE_SPELL) + { + AspellConfig *config; + AspellDictInfoList *dlist; + AspellDictInfoEnumeration *dels; + const AspellDictInfo *entry; + + config = new_aspell_config(); + +#ifdef __WXMSW__ + aspell_config_replace ( config, "data-dir", ASPELL_DATA_PATH ); + aspell_config_replace ( config, "dict-dir", ASPELL_DICT_PATH ); +#endif + dlist = get_aspell_dict_info_list( config ); + + delete_aspell_config ( config ); + + dels = aspell_dict_info_list_elements ( dlist ); + + bool anyFound = false; + while ( ( entry = aspell_dict_info_enumeration_next ( dels ) ) != 0 ) + { + anyFound = true; + std::string stdEntry = entry->name; + wxString entry = wxString ( stdEntry.c_str(), wxConvUTF8, stdEntry.size() ); + ruleSetCombo->Append ( entry ); + } + + if ( anyFound ) + { + if ( ruleSetPreset.empty() ) + ruleSetPreset = _ ( "en_US" ); + ruleSetCombo->SetValue ( ruleSetPreset ); + } + else + { + ruleSetCombo->Append ( _ ( "(No dictionaries found)" ) ); + ruleSetCombo->Select ( 0 ); + createReportButton->Enable ( false ); + } + + return; + } + + // all other branches if ( wxFileName::DirExists ( ruleSetDirectory ) ) { wxString ruleMask, ruleFile; @@ -210,6 +289,8 @@ StyleDialog::StyleDialog ( ruleSetCombo->Append ( wxFileNameFromPath ( ruleFile ) ); } } + if ( ruleSetPreset.empty() ) + ruleSetPreset = _ ( "Default" ); ruleSetCombo->SetValue ( ruleSetPreset ); } else @@ -246,23 +327,6 @@ StyleDialog::StyleDialog ( filterCombo->Append ( _ ( "(No filters found)" ) ); filterCombo->Select ( 0 ); } - createReportButton->SetFocus(); - - if ( readOnly ) - filterCombo->Enable ( false ); - - // keyboard shortcuts - wxAcceleratorEntry entries[7]; - entries[0].Set ( wxACCEL_ALT, ( int ) 'R', ID_STYLE_REPORT ); - entries[1].Set ( wxACCEL_ALT, ( int ) 'E', ID_STYLE_EDIT ); - entries[2].Set ( wxACCEL_ALT, ( int ) 'W', ID_STYLE_WEB_REPORT ); - entries[3].Set ( wxACCEL_ALT, ( int ) 'B', ID_STYLE_WEB_SUMMARY ); - entries[4].Set ( wxACCEL_ALT, ( int ) 'C', ID_STYLE_CHANGE_ALL ); - entries[5].Set ( wxACCEL_ALT, ( int ) 'I', ID_STYLE_IGNORE_ALL ); - entries[6].Set ( wxACCEL_ALT, ( int ) 'A', wxID_CANCEL ); - - wxAcceleratorTable accel ( 7, entries ); - this->SetAcceleratorTable ( accel ); } StyleDialog::~StyleDialog() @@ -332,7 +396,7 @@ void StyleDialog::OnReport ( wxCommandEvent& event ) { table->DeleteAllItems(); matchVector.clear(); - status->SetStatusText ( _ ( "Creating report..." ) ); + status->SetStatusText ( _ ( "Checking document..." ) ); // update presets ruleSetPreset = ruleSetCombo->GetValue(); @@ -357,6 +421,7 @@ void StyleDialog::OnReport ( wxCommandEvent& event ) pathSeparatorUtf8 = separator.mb_str ( wxConvUTF8 ); std::auto_ptr hs ( new HouseStyle ( + (type == ID_TYPE_SPELL) ? HS_TYPE_SPELL : HS_TYPE_STYLE, bufferUtf8, ruleSetDirectoryUtf8, ruleSetUtf8, @@ -365,12 +430,12 @@ void StyleDialog::OnReport ( wxCommandEvent& event ) pathSeparatorUtf8, 5 ) ); - status->SetStatusText ( _ ( "Creating report..." ) ); + status->SetStatusText ( _ ( "Checking document..." ) ); if ( !hs->createReport() ) { std::string lastError = hs->getLastError(); wxString error = wxString ( lastError.c_str(), wxConvUTF8, lastError.size() ); - status->SetStatusText ( _ ( "Cannot create report: " ) + error ); + status->SetStatusText ( _ ( "Cannot check document: " ) + error ); return; } matchVector = hs->getMatchVector(); @@ -403,7 +468,7 @@ void StyleDialog::OnReport ( wxCommandEvent& event ) ++i; } wxString message; - message.Printf ( ngettext ( L"%i match", L"%i matches", i ), i ); + message.Printf ( ngettext ( L"%i error", L"%i errors", i ), i ); status->SetStatusText ( message ); if ( i ) table->SetFocus(); @@ -438,7 +503,7 @@ void StyleDialog::OnStyleEdit ( wxCommandEvent& event ) } bufferUtf8 = hsw.getOutput(); wxCommandEvent e; - EndModal ( wxID_OK );//OnOK(e); + EndModal ( wxID_OK ); } std::string StyleDialog::getEditedString() @@ -547,7 +612,7 @@ void StyleDialog::OnStyleWebSummary ( wxCommandEvent& event ) ofs << ""; WrapExpat we; - ofs << ""; + ofs << "
MatchFrequency
"; std::map::iterator mapIterator; int matchTotal = 0; @@ -567,7 +632,7 @@ void StyleDialog::OnStyleWebSummary ( wxCommandEvent& event ) } ofs << "
TermFrequency
Total"; ofs << matchTotal; - ofs << "
"; + ofs << ""; ofs << XHTML_END; ofs.close(); diff --git a/src/styledialog.h b/src/styledialog.h index 68b6bdd..59ae711 100755 --- a/src/styledialog.h +++ b/src/styledialog.h @@ -20,8 +20,8 @@ #ifndef STYLEDIALOG_H #define STYLEDIALOG_H -#define XHTML_START "XML Copy Editor report" -#define XHTML_END "" +#define XHTML_START "XML Copy Editor report" +#define XHTML_END "" #include #include @@ -50,6 +50,8 @@ enum ID_STYLE_WEB_SUMMARY, ID_STYLE_IGNORE_ALL, ID_STYLE_CHANGE_ALL, + ID_TYPE_SPELL, + ID_TYPE_STYLE }; struct SortData @@ -71,6 +73,7 @@ class StyleDialog : public wxDialog const wxString& browserParameter, const wxString& ruleSetPresetParameter, const wxString& filterPresetParameter, + int type = ID_TYPE_STYLE, bool readOnlyParameter = false, wxPoint position = wxDefaultPosition, wxSize size = wxSize ( 720, 540 ) ); @@ -117,6 +120,7 @@ class StyleDialog : public wxDialog wxString fileName, ruleSetDirectory, filterDirectory, browser; wxString ruleSetPreset, filterPreset; vector matchVector; + int type; bool readOnly; bool isIgnore ( int item ); void setIgnore ( int item, bool ignore );