812 lines
26 KiB
C++
Executable File
812 lines
26 KiB
C++
Executable File
#include <wx/intl.h>
|
|
#include "styledialog.h"
|
|
#include "nocasecompare.h"
|
|
#define ngettext wxGetTranslation
|
|
|
|
BEGIN_EVENT_TABLE ( StyleDialog, wxDialog )
|
|
EVT_BUTTON ( ID_STYLE_REPORT, StyleDialog::OnReport )
|
|
EVT_BUTTON ( ID_STYLE_IGNORE_ALL, StyleDialog::OnStyleIgnoreAll )
|
|
EVT_BUTTON ( ID_STYLE_CHANGE_ALL, StyleDialog::OnStyleChangeAll )
|
|
EVT_BUTTON ( ID_STYLE_EDIT, StyleDialog::OnStyleEdit )
|
|
EVT_BUTTON ( ID_STYLE_WEB_REPORT, StyleDialog::OnStyleWebReport )
|
|
EVT_BUTTON ( ID_STYLE_WEB_SUMMARY, StyleDialog::OnStyleWebSummary )
|
|
EVT_BUTTON ( wxID_CANCEL, StyleDialog::OnCancel )
|
|
EVT_MENU ( ID_MENU_CHANGE_ONCE, StyleDialog::OnMenuChangeOnce )
|
|
EVT_MENU ( ID_MENU_CHANGE_ALL, StyleDialog::OnMenuChangeAll )
|
|
EVT_MENU ( ID_MENU_IGNORE_ONCE, StyleDialog::OnMenuIgnoreOnce )
|
|
EVT_MENU ( ID_MENU_IGNORE_ALL, StyleDialog::OnMenuIgnoreAll )
|
|
EVT_MENU ( ID_MENU_NEW_SUGGESTION, StyleDialog::OnMenuNewSuggestion )
|
|
EVT_MENU ( ID_MENU_APPLY_SUGGESTION_ALL, StyleDialog::OnMenuApplySuggestionAll )
|
|
EVT_LIST_COL_CLICK ( ID_STYLE_TABLE, StyleDialog::OnColumnClick )
|
|
EVT_LIST_ITEM_ACTIVATED ( ID_STYLE_TABLE, StyleDialog::OnItemActivated )
|
|
EVT_LIST_ITEM_RIGHT_CLICK ( ID_STYLE_TABLE, StyleDialog::OnItemRightClick )
|
|
EVT_UPDATE_UI_RANGE ( ID_STYLE_EDIT, ID_STYLE_CHANGE_ALL, StyleDialog::OnUpdateTableRange )
|
|
END_EVENT_TABLE()
|
|
|
|
StyleDialog::StyleDialog (
|
|
wxWindow *parent,
|
|
wxIcon icon,
|
|
const std::string& bufferParameterUtf8,
|
|
const wxString& fileNameParameter,
|
|
const wxString& ruleSetDirectoryParameter,
|
|
const wxString& filterDirectoryParameter,
|
|
const wxString& browserParameter,
|
|
const wxString& ruleSetPresetParameter,
|
|
const wxString& filterPresetParameter,
|
|
bool readOnlyParameter,
|
|
wxPoint position,
|
|
wxSize size )
|
|
: wxDialog (
|
|
parent,
|
|
wxID_ANY,
|
|
wxString ( _ ( "Spelling and Style" ) ),
|
|
position,
|
|
size,
|
|
wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER | wxMAXIMIZE_BOX ),
|
|
bufferUtf8 ( bufferParameterUtf8 ),
|
|
fileName ( fileNameParameter ),
|
|
ruleSetDirectory ( ruleSetDirectoryParameter ),
|
|
filterDirectory ( filterDirectoryParameter ),
|
|
browser ( browserParameter ),
|
|
ruleSetPreset ( ruleSetPresetParameter ),
|
|
filterPreset ( filterPresetParameter ),
|
|
readOnly ( readOnlyParameter )
|
|
{
|
|
SetIcon ( icon );
|
|
|
|
wxSize buttonSize ( 100, wxDefaultCoord );
|
|
|
|
// top box
|
|
ruleSetCombo = new wxComboBox (
|
|
this,
|
|
ID_STYLE_COMBO_RULESET,
|
|
_T ( "" ),
|
|
wxDefaultPosition,
|
|
wxSize ( 200, -1 )
|
|
);
|
|
filterCombo = new wxComboBox (
|
|
this,
|
|
ID_STYLE_COMBO_FILTER,
|
|
_T ( "" ),
|
|
wxDefaultPosition,
|
|
wxSize ( 200, -1 )
|
|
);
|
|
|
|
wxButton *createReportButton = new wxButton (
|
|
this,
|
|
ID_STYLE_REPORT,
|
|
_ ( "&Report" ),
|
|
wxDefaultPosition,
|
|
buttonSize,
|
|
0 );
|
|
|
|
wxBoxSizer *comboSizer = new wxBoxSizer ( wxHORIZONTAL );
|
|
comboSizer->Add ( ruleSetCombo, 0, wxRIGHT, 10 );
|
|
comboSizer->Add ( filterCombo, 0, wxRIGHT, 10 );
|
|
comboSizer->Add ( createReportButton, 0, wxRIGHT, 10 );
|
|
|
|
// middle box
|
|
wxListCtrl *myTable = new wxListCtrl (
|
|
this,
|
|
ID_STYLE_TABLE,
|
|
wxPoint ( 0, 0 ),
|
|
wxSize ( -1, -1 ),
|
|
wxLC_REPORT );
|
|
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 ( 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;
|
|
|
|
// lower box
|
|
wxButton *editItemsButton =
|
|
new wxButton (
|
|
this,
|
|
ID_STYLE_EDIT,
|
|
_ ( "&Edit" ),
|
|
wxDefaultPosition,
|
|
buttonSize,
|
|
0 );
|
|
wxButton *webReportButton =
|
|
new wxButton (
|
|
this,
|
|
ID_STYLE_WEB_REPORT,
|
|
_ ( "&Printable report" ),
|
|
wxDefaultPosition,
|
|
buttonSize,
|
|
0 );
|
|
wxButton *webSummaryButton =
|
|
new wxButton (
|
|
this,
|
|
ID_STYLE_WEB_SUMMARY,
|
|
_ ( "Pr&intable summary" ),
|
|
wxDefaultPosition,
|
|
buttonSize,
|
|
0 );
|
|
wxButton *selectAllButton =
|
|
new wxButton (
|
|
this,
|
|
ID_STYLE_CHANGE_ALL,
|
|
_ ( "&Change all" ),
|
|
wxDefaultPosition,
|
|
buttonSize,
|
|
0 );
|
|
wxButton *deselectAllButton =
|
|
new wxButton (
|
|
this,
|
|
ID_STYLE_IGNORE_ALL,
|
|
_ ( "I&gnore all" ),
|
|
wxDefaultPosition,
|
|
buttonSize,
|
|
0 );
|
|
wxButton *cancelButton =
|
|
new wxButton (
|
|
this,
|
|
wxID_CANCEL,
|
|
_ ( "C&ancel" ),
|
|
wxDefaultPosition,
|
|
buttonSize,
|
|
0 );
|
|
|
|
wxBoxSizer *reportButtonSizer = new wxBoxSizer ( wxHORIZONTAL );
|
|
reportButtonSizer->Add ( editItemsButton, 0, wxRIGHT, 10 );
|
|
reportButtonSizer->Add ( webReportButton, 0, wxLEFT | wxRIGHT, 10 );
|
|
reportButtonSizer->Add ( webSummaryButton, 0, wxRIGHT, 10 );
|
|
reportButtonSizer->Add ( selectAllButton, 0, wxLEFT | wxRIGHT, 10 );
|
|
reportButtonSizer->Add ( deselectAllButton, 0, wxRIGHT, 10 );
|
|
reportButtonSizer->Add ( cancelButton, 0, wxLEFT, 10 );
|
|
|
|
// status bar
|
|
status = new wxStatusBar ( this, wxID_ANY );
|
|
|
|
// overall sizer
|
|
wxBoxSizer *reportTopSizer = new wxBoxSizer ( wxVERTICAL );
|
|
reportTopSizer->Add ( comboSizer, 0, wxALL | wxALIGN_CENTER_VERTICAL, 5 );
|
|
reportTopSizer->Add ( table, 1, wxEXPAND | wxALL, 5 );
|
|
reportTopSizer->Add ( reportButtonSizer, 0, wxALL, 5 );
|
|
reportTopSizer->Add ( status, 0 );
|
|
this->SetSizer ( reportTopSizer );
|
|
|
|
// update combo lists
|
|
if ( wxFileName::DirExists ( ruleSetDirectory ) )
|
|
{
|
|
wxString ruleMask, ruleFile;
|
|
ruleMask = ruleSetDirectory + wxFileName::GetPathSeparator() + _T ( "*.xml" );
|
|
ruleFile = wxFindFirstFile ( ruleMask, wxFILE );
|
|
|
|
if ( !ruleFile.empty() )
|
|
{
|
|
ruleFile.Replace ( _T ( ".xml" ), _T ( "" ) );
|
|
ruleSetCombo->Append ( wxFileNameFromPath ( ruleFile ) );
|
|
for ( ;; )
|
|
{
|
|
ruleFile = wxFindNextFile();
|
|
if ( ruleFile.empty() )
|
|
break;
|
|
ruleFile.Replace ( _T ( ".xml" ), _T ( "" ) );
|
|
ruleSetCombo->Append ( wxFileNameFromPath ( ruleFile ) );
|
|
}
|
|
}
|
|
ruleSetCombo->SetValue ( ruleSetPreset );
|
|
}
|
|
else
|
|
{
|
|
ruleSetCombo->Append ( _ ( "(No rule sets found)" ) );
|
|
ruleSetCombo->Select ( 0 );
|
|
}
|
|
|
|
if ( wxFileName::DirExists ( filterDirectory ) )
|
|
{
|
|
filterCombo->Append ( _ ( "(No filter)" ) );
|
|
wxString filterMask, filterFile;
|
|
filterMask = filterDirectory + wxFileName::GetPathSeparator() + _T ( "*.xml" );
|
|
|
|
filterFile = wxFindFirstFile ( filterMask, wxFILE );
|
|
|
|
if ( !filterFile.empty() )
|
|
{
|
|
filterFile.Replace ( _T ( ".xml" ), _T ( "" ) );
|
|
filterCombo->Append ( wxFileNameFromPath ( filterFile ) );
|
|
for ( ;; )
|
|
{
|
|
filterFile = wxFindNextFile();
|
|
if ( filterFile.empty() )
|
|
break;
|
|
filterFile.Replace ( _T ( ".xml" ), _T ( "" ) );
|
|
filterCombo->Append ( wxFileNameFromPath ( filterFile ) );
|
|
}
|
|
}
|
|
filterCombo->SetValue ( filterPreset );
|
|
}
|
|
else
|
|
{
|
|
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()
|
|
{
|
|
std::set<wxString>::iterator it;
|
|
for ( it = tempFiles.begin(); it != tempFiles.end(); it++ )
|
|
wxRemoveFile ( *it );
|
|
}
|
|
|
|
void StyleDialog::OnColumnClick ( wxListEvent& event )
|
|
{
|
|
std::auto_ptr<SortData> data ( new SortData );
|
|
data->column = event.GetColumn();
|
|
data->table = table;
|
|
table->SortItems ( MyCompareFunction, ( long ) data.get() );
|
|
|
|
long itemCount = table->GetItemCount();
|
|
for ( int i = 0; i < itemCount; ++i )
|
|
table->SetItemData ( i, i );
|
|
}
|
|
|
|
void StyleDialog::OnItemActivated ( wxListEvent& event )
|
|
{
|
|
int index = event.GetIndex();
|
|
bool ignore = ( getTextByColumn ( table, index, 6 ) == _ ( "Ignore" ) );
|
|
setIgnore ( index, ( ignore ) ? false : true );
|
|
}
|
|
|
|
void StyleDialog::OnItemRightClick ( wxListEvent& event )
|
|
{
|
|
int index = indexForContextMenu = event.GetIndex();
|
|
|
|
wxString match, suggestion;
|
|
match = getTextByColumn ( table, index, 2 );
|
|
suggestion = getTextByColumn ( table, index, 4 );
|
|
|
|
wxMenu contextMenu;
|
|
contextMenu.Append (
|
|
ID_MENU_IGNORE_ONCE, _ ( "Ignore once" ) );
|
|
contextMenu.Append (
|
|
ID_MENU_IGNORE_ALL, _ ( "Ignore all" ) );
|
|
contextMenu.AppendSeparator();
|
|
contextMenu.Append ( ID_MENU_CHANGE_ONCE, _ ( "Change once" ) );
|
|
contextMenu.Append ( ID_MENU_CHANGE_ALL, _ ( "Change all" ) );
|
|
contextMenu.AppendSeparator();
|
|
contextMenu.Append (
|
|
ID_MENU_NEW_SUGGESTION, _ ( "New suggestion..." ) );
|
|
|
|
wxString menuString;
|
|
menuString.Printf ( _T ( "Change '%s' to '%s' throughout" ), match.c_str(), suggestion.c_str() );
|
|
|
|
contextMenu.Append (
|
|
ID_MENU_APPLY_SUGGESTION_ALL, menuString );
|
|
|
|
bool ignore = ( getTextByColumn ( table, index, 6 ) == _ ( "Ignore" ) );
|
|
contextMenu.Enable ( ( ignore ) ? ID_MENU_IGNORE_ONCE : ID_MENU_CHANGE_ONCE, false );
|
|
PopupMenu ( &contextMenu, wxPoint ( -1, -1 ) );
|
|
}
|
|
|
|
void StyleDialog::OnCancel ( wxCommandEvent& event )
|
|
{
|
|
updateSizeInformation();
|
|
event.Skip();
|
|
}
|
|
|
|
void StyleDialog::OnReport ( wxCommandEvent& event )
|
|
{
|
|
table->DeleteAllItems();
|
|
matchVector.clear();
|
|
status->SetStatusText ( _ ( "Creating report..." ) );
|
|
|
|
// update presets
|
|
ruleSetPreset = ruleSetCombo->GetValue();
|
|
filterPreset = filterCombo->GetValue();
|
|
|
|
// reconstitute short filenames
|
|
wxString ruleSet, filter;
|
|
ruleSet = ruleSetPreset + _T ( ".xml" );
|
|
filter = filterPreset + _T ( ".xml" );
|
|
|
|
std::string ruleSetDirectoryUtf8,
|
|
ruleSetUtf8,
|
|
filterDirectoryUtf8,
|
|
filterUtf8,
|
|
pathSeparatorUtf8;
|
|
ruleSetDirectoryUtf8 = ruleSetDirectory.mb_str ( wxConvUTF8 );
|
|
ruleSetUtf8 = ruleSet.mb_str ( wxConvUTF8 );
|
|
filterDirectoryUtf8 = filterDirectory.mb_str ( wxConvUTF8 );
|
|
filterUtf8 = filter.mb_str ( wxConvUTF8 );
|
|
|
|
wxString separator = wxFileName::GetPathSeparator();
|
|
pathSeparatorUtf8 = separator.mb_str ( wxConvUTF8 );
|
|
|
|
std::auto_ptr<HouseStyle> hs ( new HouseStyle (
|
|
bufferUtf8,
|
|
ruleSetDirectoryUtf8,
|
|
ruleSetUtf8,
|
|
filterDirectoryUtf8,
|
|
filterUtf8,
|
|
pathSeparatorUtf8,
|
|
5 ) );
|
|
|
|
status->SetStatusText ( _ ( "Creating report..." ) );
|
|
if ( !hs->createReport() )
|
|
{
|
|
std::string lastError = hs->getLastError();
|
|
wxString error = wxString ( lastError.c_str(), wxConvUTF8, lastError.size() );
|
|
status->SetStatusText ( _ ( "Cannot create report: " ) + error );
|
|
return;
|
|
}
|
|
matchVector = hs->getMatchVector();
|
|
|
|
vector<ContextMatch>::iterator it;
|
|
std::string prelogUtf8, matchUtf8, postlogUtf8, replaceUtf8, reportUtf8;
|
|
wxString matchNo, prelog, match, postlog, replace, report;
|
|
int i = 0;
|
|
for ( it = matchVector.begin(); it != matchVector.end(); it++ )
|
|
{
|
|
matchNo.Printf ( _T ( "%i" ), i + 1 ); // display numbers from 1
|
|
prelogUtf8 = flatWhiteSpace ( ( *it ).prelog );
|
|
matchUtf8 = flatWhiteSpace ( ( *it ).match );
|
|
postlogUtf8 = flatWhiteSpace ( ( *it ).postlog );
|
|
replaceUtf8 = flatWhiteSpace ( ( *it ).replace );
|
|
reportUtf8 = flatWhiteSpace ( ( *it ).report );
|
|
prelog = wxString ( prelogUtf8.c_str(), wxConvUTF8, ( *it ).prelog.size() );
|
|
match = wxString ( matchUtf8.c_str(), wxConvUTF8, ( *it ).match.size() );
|
|
postlog = wxString ( postlogUtf8.c_str(), wxConvUTF8, ( *it ).postlog.size() );
|
|
replace = wxString ( replaceUtf8.c_str(), wxConvUTF8, ( *it ).replace.size() );
|
|
report = wxString ( reportUtf8.c_str(), wxConvUTF8, ( *it ).report.size() );
|
|
table->InsertItem ( i, matchNo, 0 );
|
|
table->SetItem ( i, 1, prelog );
|
|
table->SetItem ( i, 2, match );
|
|
table->SetItem ( i, 3, postlog );
|
|
table->SetItem ( i, 4, replace );
|
|
table->SetItem ( i, 5, report );
|
|
setIgnore ( i, ( *it ).tentative );
|
|
table->SetItemData ( i, i );
|
|
++i;
|
|
}
|
|
wxString message;
|
|
message.Printf ( ngettext ( L"%i match", L"%i matches", i ), i );
|
|
status->SetStatusText ( message );
|
|
if ( i )
|
|
table->SetFocus();
|
|
}
|
|
|
|
void StyleDialog::OnStyleEdit ( wxCommandEvent& event )
|
|
{
|
|
updateSizeInformation();
|
|
|
|
std::vector<ContextMatch> v;
|
|
getSelectedMatches ( v );
|
|
|
|
if ( v.empty() )
|
|
{
|
|
status->SetStatusText ( _ ( "No items selected" ) );
|
|
return;
|
|
}
|
|
|
|
sort ( v.begin(), v.end(), elementAndOffsetCompareFunction );
|
|
|
|
HouseStyleWriter hsw ( v );
|
|
if ( !hsw.parse ( bufferUtf8 ) )
|
|
{
|
|
std::string error = hsw.getLastError();
|
|
wxString wideError = wxString (
|
|
error.c_str(),
|
|
wxConvUTF8,
|
|
error.size() );
|
|
|
|
status->SetStatusText ( wideError );
|
|
return;
|
|
}
|
|
bufferUtf8 = hsw.getOutput();
|
|
wxCommandEvent e;
|
|
EndModal ( wxID_OK );//OnOK(e);
|
|
}
|
|
|
|
std::string StyleDialog::getEditedString()
|
|
{
|
|
return bufferUtf8;
|
|
}
|
|
|
|
void StyleDialog::OnStyleIgnoreAll ( wxCommandEvent& event )
|
|
{
|
|
styleSetIgnoreAll ( true );
|
|
}
|
|
|
|
void StyleDialog::OnStyleChangeAll ( wxCommandEvent& event )
|
|
{
|
|
styleSetIgnoreAll ( false );
|
|
}
|
|
|
|
void StyleDialog::OnStyleWebReport ( wxCommandEvent& event )
|
|
{
|
|
std::vector<ContextMatch> v;
|
|
getAllMatches ( v );
|
|
|
|
sort ( v.begin(), v.end(), reportCompareFunction );
|
|
|
|
// temporary file should be in default temporary folder
|
|
wxString tempNameWide = wxFileName::CreateTempFileName ( _T ( "" ) );
|
|
if ( tempNameWide.empty() )
|
|
return;
|
|
tempNameWide.Replace ( _T ( ".tmp" ), _T ( "_report.html" ), true );
|
|
tempFiles.insert ( tempNameWide );
|
|
std::string tempNameUtf8 = ( const char * ) tempNameWide.mb_str ( wxConvUTF8 );
|
|
std::ofstream ofs ( tempNameUtf8.c_str() );
|
|
if ( !ofs )
|
|
return;
|
|
ofs << XHTML_START;
|
|
ofs << "<body><h2>";
|
|
ofs << fileName.mb_str ( wxConvUTF8 );
|
|
ofs << "</h2><table><tr>";
|
|
ofs << "<td><b align=\"right\">No.</b></td>";
|
|
ofs << "<td align=\"right\"><b>Context</b></td>";
|
|
ofs << "<td align=\"center\"><b>Match</b></td>";
|
|
ofs << "<td align=\"left\"><b>Context</b></td>";
|
|
ofs << "<td><b>Suggestion</b></td><td><b>Report</b></td></tr>";
|
|
std::vector<ContextMatch>::iterator it;
|
|
int matchCount = 0;
|
|
for ( it = v.begin(); it != v.end(); it++ )
|
|
{
|
|
ofs << "<tr><td align=\"right\">";
|
|
ofs << ++matchCount;
|
|
ofs << "</td>";
|
|
ofs << "<td align=\"right\">";
|
|
ofs << it->prelog;
|
|
ofs << "</td><td align=\"center\"><font color=\"red\"><b>";
|
|
ofs << it->match;
|
|
ofs << "</b></font></td><td align=\"left\">";
|
|
ofs << it->postlog;
|
|
ofs << "</td><td><font color=\"green\"><b>";
|
|
ofs << it->replace;
|
|
ofs << "</b></font></td><td>";
|
|
ofs << it->report;
|
|
ofs << "</td></tr>";
|
|
}
|
|
ofs << "</table></body>";
|
|
ofs << XHTML_END;
|
|
ofs.close();
|
|
|
|
// display file in browser
|
|
if ( !wxFileName::FileExists ( tempNameWide ) )
|
|
return;
|
|
|
|
wxString cmd = browser + _T ( " \"" ) + tempNameWide + _T ( "\"" );
|
|
wxExecute ( cmd, wxEXEC_SYNC );
|
|
}
|
|
|
|
void StyleDialog::OnStyleWebSummary ( wxCommandEvent& event )
|
|
{
|
|
std::vector<ContextMatch> v;
|
|
getAllMatches ( v );
|
|
|
|
std::map<std::string, int, NoCaseCompare> matchMap;
|
|
std::vector<ContextMatch>::iterator vectorIterator;
|
|
for (
|
|
vectorIterator = v.begin();
|
|
vectorIterator != v.end();
|
|
vectorIterator++ )
|
|
{
|
|
if ( ( matchMap.find ( vectorIterator->match ) ) != matchMap.end() )
|
|
++ ( matchMap[vectorIterator->match] );
|
|
else
|
|
matchMap[vectorIterator->match] = 1;
|
|
}
|
|
|
|
// temporary file should be in default temporary folder
|
|
wxString tempNameWide = wxFileName::CreateTempFileName ( _T ( "" ) );
|
|
if ( tempNameWide.empty() )
|
|
return;
|
|
tempNameWide.Replace ( _T ( ".tmp" ), _T ( "_summary.html" ), true );
|
|
tempFiles.insert ( tempNameWide );
|
|
std::string tempNameUtf8 = ( const char * ) tempNameWide.mb_str ( wxConvUTF8 );
|
|
std::ofstream ofs ( tempNameUtf8.c_str() );
|
|
if ( !ofs )
|
|
return;
|
|
ofs << XHTML_START;
|
|
ofs << "<body><h2>";
|
|
ofs << fileName.mb_str ( wxConvUTF8 );
|
|
ofs << "</h2>";
|
|
|
|
WrapExpat we;
|
|
ofs << "<table><tr><th>Match</th><th>Frequency</th></tr>";
|
|
std::map<std::string, int>::iterator mapIterator;
|
|
int matchTotal = 0;
|
|
|
|
for (
|
|
mapIterator = matchMap.begin();
|
|
mapIterator != matchMap.end();
|
|
mapIterator++ )
|
|
{
|
|
ofs << "<tr><td>";
|
|
ofs << we.xmliseTextNode ( mapIterator->first );
|
|
ofs << "</td><td>";
|
|
|
|
// handle number of matches
|
|
matchTotal += mapIterator->second;
|
|
ofs << mapIterator->second;
|
|
ofs << "</td></tr>";
|
|
}
|
|
ofs << "<tr><th>Total</th><th>";
|
|
ofs << matchTotal;
|
|
ofs << "</th></tr></table>";
|
|
ofs << XHTML_END;
|
|
|
|
ofs.close();
|
|
|
|
// display file in browser
|
|
if ( !wxFileName::FileExists ( tempNameWide ) )
|
|
return;
|
|
|
|
wxString cmd = browser + _T ( " \"" ) + tempNameWide + _T ( "\"" );
|
|
wxExecute ( cmd, wxEXEC_SYNC );
|
|
}
|
|
|
|
void StyleDialog::styleSetIgnoreAll ( bool ignore )
|
|
{
|
|
int count = table->GetItemCount();
|
|
for ( int i = 0; i < count; ++i )
|
|
setIgnore ( i, ignore );
|
|
}
|
|
|
|
bool StyleDialog::isIgnore ( int item )
|
|
{
|
|
wxString field = getTextByColumn ( table, item, 6 );
|
|
return ( field == _ ( "Ignore" ) ) ? true : false;
|
|
}
|
|
|
|
void StyleDialog::setIgnore ( int item, bool ignore )
|
|
{
|
|
table->SetItem ( item, 6, ( ignore ) ? _ ( "Ignore" ) : _ ( "Change" ) );
|
|
table->SetItemTextColour ( item, ( ignore ) ? *wxBLUE : *wxBLACK );
|
|
}
|
|
|
|
void StyleDialog::getAllMatches ( vector<ContextMatch> &v )
|
|
{
|
|
v.clear();
|
|
int count = table->GetItemCount();
|
|
wxString matchNoString;
|
|
long matchNo;
|
|
for ( int i = 0; i < count; ++i )
|
|
{
|
|
matchNoString = table->GetItemText ( i );
|
|
if ( !matchNoString.ToLong ( &matchNo ) || matchNo < 1 )
|
|
continue;
|
|
v.push_back ( matchVector.at ( matchNo - 1 ) ); // vector index starts at 0
|
|
}
|
|
}
|
|
|
|
void StyleDialog::getSelectedMatches ( vector<ContextMatch> &v )
|
|
{
|
|
v.clear();
|
|
int count = table->GetItemCount();
|
|
wxString selectionString, matchNoString;
|
|
long matchNo;
|
|
for ( int i = 0; i < count; ++i )
|
|
{
|
|
selectionString = getTextByColumn ( table, i, 6 );
|
|
if ( selectionString != _ ( "Change" ) )
|
|
continue;
|
|
matchNoString = table->GetItemText ( i );
|
|
if ( !matchNoString.ToLong ( &matchNo ) || matchNo < 1 )
|
|
continue;
|
|
v.push_back ( matchVector.at ( matchNo - 1 ) ); // vector index starts at 0
|
|
}
|
|
}
|
|
|
|
int wxCALLBACK StyleDialog::MyCompareFunction (
|
|
long item1,
|
|
long item2,
|
|
long sortData )
|
|
{
|
|
SortData *data = ( SortData * ) sortData;
|
|
int column;
|
|
wxListCtrl *table;
|
|
column = data->column;
|
|
table = data->table;
|
|
|
|
wxString string1 = getTextByColumn ( table, item1, column );
|
|
wxString string2 = getTextByColumn ( table, item2, column );
|
|
|
|
// special case: numerical content
|
|
if ( string1.IsNumber() && string2.IsNumber() )
|
|
{
|
|
long value1, value2;
|
|
string1.ToLong ( &value1 );
|
|
string2.ToLong ( &value2 );
|
|
if ( value1 < value2 )
|
|
return -1;
|
|
else if ( value1 > value2 )
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
if ( string1.CmpNoCase ( string2 ) < 0 )
|
|
return -1;
|
|
else if ( string1.CmpNoCase ( string2 ) > 0 )
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
bool StyleDialog::elementAndOffsetCompareFunction (
|
|
ContextMatch m1,
|
|
ContextMatch m2 )
|
|
{
|
|
if ( m1.elementCount == m2.elementCount )
|
|
return ( m1.offset < m2.offset );
|
|
return ( m1.elementCount < m2.elementCount );
|
|
}
|
|
|
|
bool StyleDialog::reportCompareFunction ( ContextMatch m1, ContextMatch m2 )
|
|
{
|
|
return ( m1.report < m2.report );
|
|
}
|
|
|
|
wxString StyleDialog::getTextByColumn ( wxListCtrl *table, long index, int col )
|
|
{
|
|
wxListItem Item;
|
|
Item.SetId ( index );
|
|
Item.SetColumn ( col );
|
|
Item.SetMask ( wxLIST_MASK_TEXT );
|
|
table->GetItem ( Item );
|
|
return Item.GetText();
|
|
}
|
|
|
|
void StyleDialog::OnUpdateTableRange ( wxUpdateUIEvent& event )
|
|
{
|
|
if ( event.GetId() == ID_STYLE_EDIT && readOnly )
|
|
{
|
|
event.Enable ( false );
|
|
return;
|
|
}
|
|
event.Enable ( table->GetItemCount() );
|
|
}
|
|
|
|
void StyleDialog::OnMenuChangeOnce ( wxCommandEvent& event )
|
|
{
|
|
setIgnore ( indexForContextMenu, false );
|
|
}
|
|
|
|
void StyleDialog::OnMenuChangeAll ( wxCommandEvent& event )
|
|
{
|
|
wxString match, suggestion;
|
|
match = getTextByColumn ( table, indexForContextMenu, 2 );
|
|
suggestion = getTextByColumn ( table, indexForContextMenu, 4 );
|
|
|
|
long itemCount = table->GetItemCount();
|
|
for ( int i = 0; i < itemCount; ++i )
|
|
{
|
|
if ( getTextByColumn ( table, i, 2 ) == match )
|
|
setIgnore ( i, false );
|
|
}
|
|
}
|
|
|
|
void StyleDialog::OnMenuIgnoreOnce ( wxCommandEvent& event )
|
|
{
|
|
setIgnore ( indexForContextMenu, true );
|
|
}
|
|
|
|
void StyleDialog::OnMenuIgnoreAll ( wxCommandEvent& event )
|
|
{
|
|
wxString match, suggestion;
|
|
match = getTextByColumn ( table, indexForContextMenu, 2 );
|
|
suggestion = getTextByColumn ( table, indexForContextMenu, 4 );
|
|
|
|
long itemCount = table->GetItemCount();
|
|
for ( int i = 0; i < itemCount; ++i )
|
|
{
|
|
if ( getTextByColumn ( table, i, 2 ) == match )
|
|
{
|
|
table->SetItem ( i, 4, suggestion );
|
|
setIgnore ( i, true );
|
|
}
|
|
}
|
|
}
|
|
|
|
void StyleDialog::OnMenuNewSuggestion ( wxCommandEvent& event )
|
|
{
|
|
wxString suggestion = getTextByColumn ( table, indexForContextMenu, 4 );
|
|
wxTextEntryDialog *dlg = new wxTextEntryDialog (
|
|
this,
|
|
_ ( "Enter new suggestion:" ),
|
|
_ ( "New Suggestion" ),
|
|
suggestion );
|
|
if ( !dlg )
|
|
return;
|
|
|
|
int ret = dlg->ShowModal();
|
|
if ( ret == wxID_CANCEL )
|
|
return;
|
|
|
|
// identify item in match vector
|
|
wxString noString = getTextByColumn ( table, indexForContextMenu, 0 );
|
|
long no;
|
|
if ( !noString.ToLong ( &no ) || no < 1 || no > ( long ) matchVector.size() )
|
|
return;
|
|
--no; // reverse display offset
|
|
|
|
wxString wideReplace = dlg->GetValue();
|
|
std::string replace = ( const char * ) wideReplace.mb_str ( wxConvUTF8 );
|
|
matchVector[no].replace = replace;
|
|
table->SetItem ( indexForContextMenu, 4, dlg->GetValue() );
|
|
setIgnore ( indexForContextMenu, false );
|
|
}
|
|
|
|
void StyleDialog::OnMenuApplySuggestionAll ( wxCommandEvent& event )
|
|
{
|
|
wxString match, suggestion;
|
|
match = getTextByColumn ( table, indexForContextMenu, 2 );
|
|
suggestion = getTextByColumn ( table, indexForContextMenu, 4 );
|
|
|
|
long itemCount = table->GetItemCount();
|
|
for ( int i = 0; i < itemCount; ++i )
|
|
{
|
|
if ( getTextByColumn ( table, i, 2 ) != match )
|
|
continue;
|
|
|
|
// identify item in match vector
|
|
wxString noString = getTextByColumn ( table, i, 0 );
|
|
long no;
|
|
if ( !noString.ToLong ( &no ) || no < 1 || no > ( long ) matchVector.size() )
|
|
continue;
|
|
--no; // reverse display offset
|
|
|
|
std::string replace = ( const char * ) suggestion.mb_str ( wxConvUTF8 );
|
|
matchVector[no].replace = replace;
|
|
table->SetItem ( i, 4, suggestion );
|
|
setIgnore ( i, false );
|
|
}
|
|
}
|
|
|
|
std::string StyleDialog::flatWhiteSpace ( std::string& s )
|
|
{
|
|
std::string::iterator it;
|
|
std::string output;
|
|
output.reserve ( s.size() );
|
|
for ( it = s.begin(); it != s.end(); it++ )
|
|
{
|
|
if ( *it == '\t' || *it == '\r' || *it == '\n' )
|
|
output += ' ';
|
|
else
|
|
output += *it;
|
|
}
|
|
return output;
|
|
}
|
|
|
|
void StyleDialog::updateSizeInformation()
|
|
{
|
|
framePosition = GetPosition();
|
|
frameSize = GetSize();
|
|
}
|
|
|
|
wxPoint StyleDialog::getPosition()
|
|
{
|
|
return framePosition;
|
|
}
|
|
|
|
wxSize StyleDialog::getSize()
|
|
{
|
|
return frameSize;
|
|
}
|