811 lines
23 KiB
C++
Executable File
811 lines
23 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;
|
|
}
|