NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
duplicatecodedialog.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2017 Erik Haenel et al.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17******************************************************************************/
18
19
21#include "../../kernel/core/ui/language.hpp"
22#include "../../kernel/core/utils/stringtools.hpp"
23#include "../editor/editor.h"
24#include <wx/clipbrd.h>
25#include <algorithm>
26
27#define ID_DUPLICATECODE_START 12000
28#define ID_DUPLICATECODE_COPY 12001
29#define ID_DUPLICATECODE_REPORT 12002
30#define SEMANTICS_VAR 1
31#define SEMANTICS_STRING 2
32#define SEMANTICS_NUM 4
33#define SEMANTICS_FUNCTION 8
34
35extern Language _guilang;
36
38{
39 const std::vector<double> base_arr;
40 compare_index (const std::vector<double>& arr) : base_arr (arr)
41 {}
42
43 bool operator () (int a, int b) const
44 {
45 return (base_arr[a] < base_arr[b]);
46 }
47};
48
49
50BEGIN_EVENT_TABLE(DuplicateCodeDialog, ViewerFrame)
51 EVT_BUTTON (wxID_OK, DuplicateCodeDialog::OnButtonOK)
56 EVT_LIST_ITEM_SELECTED (-1, DuplicateCodeDialog::OnItemClick)
57 EVT_LIST_ITEM_RIGHT_CLICK (-1, DuplicateCodeDialog::OnItemRightClick)
58 EVT_LIST_COL_CLICK (wxID_ANY, DuplicateCodeDialog::OnColumnHeaderClick)
60
61DuplicateCodeDialog::DuplicateCodeDialog(wxWindow* _parent, const wxString& title) : ViewerFrame(_parent, title)
62{
63 m_parent = _parent;
64 m_mainPanel = new wxPanel(this, wxID_ANY, wxDefaultPosition);
65
66 wxBoxSizer* vSizer = new wxBoxSizer(wxVERTICAL);
67 wxBoxSizer* hSizer = new wxBoxSizer(wxHORIZONTAL);
68 wxBoxSizer* paramSizer = new wxBoxSizer(wxHORIZONTAL);
69
70 wxStaticBoxSizer* checkBox = new wxStaticBoxSizer(wxVERTICAL, m_mainPanel, _guilang.get("GUI_DUPCODE_SETTINGS"));
71
72 m_varSemantics = new wxCheckBox(checkBox->GetStaticBox(), wxID_ANY, _guilang.get("GUI_DUPCODE_VARSEMANTICS"));
73 m_StringSemantics = new wxCheckBox(checkBox->GetStaticBox(), wxID_ANY, _guilang.get("GUI_DUPCODE_STRINGSEMANTICS"));
74 m_NumSemantics = new wxCheckBox(checkBox->GetStaticBox(), wxID_ANY, _guilang.get("GUI_DUPCODE_NUMSEMANTICS"));
75 m_FunctionSemantics = new wxCheckBox(checkBox->GetStaticBox(), wxID_ANY, _guilang.get("GUI_DUPCODE_FUNCTIONSEMANTICS"));
76 wxStaticText* spinctrlLabel = new wxStaticText(m_mainPanel, wxID_ANY, _guilang.get("GUI_DUPCODE_NUMLINES"));
77 m_NumLines = new wxSpinCtrl(m_mainPanel, wxID_ANY, "6", wxDefaultPosition, wxDefaultSize, 0x4000 | wxALIGN_RIGHT, 3, 100, 6);
78
79 checkBox->Add(m_varSemantics, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5);
80 checkBox->Add(m_StringSemantics, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5);
81 checkBox->Add(m_NumSemantics, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5);
82 checkBox->Add(m_FunctionSemantics, 1, wxALIGN_CENTER_VERTICAL | wxALL, 5);
83
84 paramSizer->Add(checkBox, 0, wxEXPAND | wxALL, 5);
85 paramSizer->Add(m_NumLines, 1, wxALIGN_LEFT | wxALL, 5);
86 paramSizer->Add(spinctrlLabel, 0, wxEXPAND | wxALL, 5);
87
88 wxButton* buttonStart = new wxButton(m_mainPanel, ID_DUPLICATECODE_START, _guilang.get("GUI_DUPCODE_START"));
89 wxButton* buttonCopy = new wxButton(m_mainPanel, ID_DUPLICATECODE_COPY, _guilang.get("GUI_DUPCODE_COPY"));
90 wxButton* buttonReport = new wxButton(m_mainPanel, ID_DUPLICATECODE_REPORT, _guilang.get("GUI_DUPCODE_REPORT"));
91 wxButton* buttonOK = new wxButton(m_mainPanel, wxID_OK);
92
93 hSizer->Add(buttonStart, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
94 hSizer->Add(buttonCopy, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
95 hSizer->Add(buttonReport, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
96 hSizer->Add(buttonOK, 0, wxALIGN_CENTER_VERTICAL | wxALL, 5);
97
98 m_resultList = new wxListCtrl(m_mainPanel, wxID_ANY, wxDefaultPosition, wxSize(400*g_pixelScale, 400*g_pixelScale), wxLC_REPORT);
99 m_resultList->AppendColumn(_guilang.get("GUI_DUPCODE_MATCH"));
100 m_resultList->AppendColumn(_guilang.get("GUI_DUPCODE_PERCENTAGE"));
101 m_resultList->AppendColumn(_guilang.get("GUI_DUPCODE_LINES"));
102
103 m_progressGauge = new wxGauge(m_mainPanel, wxID_ANY, 100, wxDefaultPosition, wxSize(-1, 24*g_pixelScale), wxHORIZONTAL);
104
105 vSizer->Add(m_resultList, 2, wxEXPAND | wxALL, 5);
106 vSizer->Add(m_progressGauge, 0, wxEXPAND | wxALL, 5);
107 vSizer->Add(paramSizer, 0, wxEXPAND | wxALL, 5);
108 vSizer->Add(hSizer, 0, wxALIGN_CENTER_HORIZONTAL, 5);
109
110 m_mainPanel->SetSizer(vSizer);
111
112 m_progressGauge->SetValue(0);
113 m_varSemantics->SetValue(true);
114
115 this->SetSize(480*g_pixelScale, 500*g_pixelScale);
116}
117
118
120{
121 wxString sText;
122 for (int i = 0; i < m_resultList->GetItemCount(); i++)
123 {
124 sText += m_resultList->GetItemText(i) + "\t" + m_resultList->GetItemText(i, 1) + "\t" + m_resultList->GetItemText(i, 2) + "\n";
125 }
126 if (sText.length())
127 return this->GetTitle() + "\n" + _guilang.get("GUI_DUPCODE_MATCH") + "\t" + _guilang.get("GUI_DUPCODE_PERCENTAGE") + "\t" + _guilang.get("GUI_DUPCODE_LINES") + "\n" + sText;
128 return sText;
129}
130
131void DuplicateCodeDialog::SetProgress(double dPercentage)
132{
133 if ((int)(dPercentage) != m_progressGauge->GetValue())
134 m_progressGauge->SetValue((int)(dPercentage));
135}
136
137void DuplicateCodeDialog::SetResult(const std::vector<std::string>& vResult)
138{
139 for (size_t i = 0; i < vResult.size(); i++)
140 {
141 m_resultList->InsertItem(i, vResult[i].substr(0, vResult[i].find('[')));
142 std::string itemtext = m_resultList->GetItemText(i).ToStdString();
143 int line1 = atoi(itemtext.substr(0, itemtext.find('-')).c_str());
144 int line2 = atoi(itemtext.substr(itemtext.find('-') + 1, itemtext.find('=') - itemtext.find('-') - 1).c_str());
145 m_resultList->SetItem(i, 1, vResult[i].substr(vResult[i].find('[')));
146 m_resultList->SetItem(i, 2, toString(line2 - line1 + 1));
147 }
148 m_resultList->SetColumnWidth(0, 200);
149 m_resultList->SetColumnWidth(1, 120);
150 m_resultList->SetColumnWidth(2, 120);
151}
152
153void DuplicateCodeDialog::OnButtonOK(wxCommandEvent& event)
154{
155 Close();
156 NumeReEditor* edit = static_cast<NumeReEditor*>(m_parent);
157 edit->IndicateDuplicatedLine(-1, -1, -1, -1, -1);
158}
159
160void DuplicateCodeDialog::OnClose(wxCloseEvent& event)
161{
162 NumeReEditor* edit = static_cast<NumeReEditor*>(m_parent);
163 edit->notifyDialogClose();
164 this->Destroy();
165}
166
167void DuplicateCodeDialog::OnButtonStart(wxCommandEvent& event)
168{
170}
171
172void DuplicateCodeDialog::OnButtonCopy(wxCommandEvent& event)
173{
174 wxString sSelection = createTextFromList();
175 if (!sSelection.length())
176 return;
177 if (wxTheClipboard->Open())
178 {
179 wxTheClipboard->SetData(new wxTextDataObject(sSelection));
180 wxTheClipboard->Close();
181 }
182}
183
184void DuplicateCodeDialog::OnButtonReport(wxCommandEvent& event)
185{
186 wxString sSelection = createTextFromList();
187 if (!sSelection.length())
188 return;
189
190 wxFileDialog filedialog(this, _guilang.get("GUI_DUPCODE_SAVEREPORT"), wxEmptyString, "duplicatecodereport.txt", _guilang.get("COMMON_FILETYPE_TXT") + " (*.txt)|*.txt", wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
191 if (filedialog.ShowModal() == wxID_CANCEL)
192 return;
193 wxString filename = filedialog.GetPath();
194 wxFile file(filename, wxFile::write);
195 if (file.IsOpened())
196 file.Write(sSelection);
197 file.Close();
198}
199
200void DuplicateCodeDialog::OnItemClick(wxListEvent& event)
201{
202 this->highlightSelection(event.GetText(), true);
203}
204
206{
207 this->highlightSelection(event.GetText(), false);
208}
209
210void DuplicateCodeDialog::highlightSelection(const wxString& sSelection, bool firstMatch)
211{
212 std::string sItemText = sSelection.ToStdString();
213 int nStart1, nEnd1, nStart2, nEnd2, nSelection;
214
215 nStart1 = StrToInt(sItemText.substr(0, sItemText.find('-')));
216 nEnd1 = StrToInt(sItemText.substr(sItemText.find('-') + 1, sItemText.find(' ') - sItemText.find('-') - 1));
217 sItemText.erase(0, sItemText.find("== ") + 3);
218 nStart2 = StrToInt(sItemText.substr(0, sItemText.find('-')));
219 nEnd2 = StrToInt(sItemText.substr(sItemText.find('-') + 1));
220
221 if (firstMatch)
222 nSelection = nStart1 - 1;
223 else
224 nSelection = nStart2 - 1;
225
226 NumeReEditor* edit = static_cast<NumeReEditor*>(m_parent);
227 edit->IndicateDuplicatedLine(nStart1 - 1, nEnd1 - 1, nStart2 - 1, nEnd2 - 1, nSelection);
228}
229
231{
232 int nFlags = 0;
233 if (m_varSemantics->IsChecked())
234 nFlags |= SEMANTICS_VAR;
235 if (m_StringSemantics->IsChecked())
236 nFlags |= SEMANTICS_STRING;
237 if (m_NumSemantics->IsChecked())
238 nFlags |= SEMANTICS_NUM;
239 if (m_FunctionSemantics->IsChecked())
240 nFlags |= SEMANTICS_FUNCTION;
241 m_resultList->DeleteAllItems();
242 NumeReEditor* edit = static_cast<NumeReEditor*>(m_parent);
243 edit->OnFindDuplicateCode(nFlags, m_NumLines->GetValue());
244}
245
247{
248 int nCol = event.GetColumn();
249
250 if (!m_resultList->GetItemCount())
251 return;
252
253 std::vector<double> vData;
254 std::vector<int> vIndex;
255 std::vector<wxString> vStringData;
256
257 std::string sCurrentItem;
258
259 for (int i = 0; i < m_resultList->GetItemCount(); i++)
260 {
261 sCurrentItem = m_resultList->GetItemText(i, nCol).ToStdString();
262 vIndex.push_back(vData.size());
263 switch (nCol)
264 {
265 case 0:
266 while (sCurrentItem.find_first_of("-= ") != std::string::npos)
267 sCurrentItem.erase(sCurrentItem.find_first_of("-= "), 1);
268 vData.push_back(StrToDb(sCurrentItem));
269 break;
270 case 1:
271 vData.push_back(StrToDb(sCurrentItem.substr(sCurrentItem.find('[') + 1, sCurrentItem.find(']') - sCurrentItem.find('[') - 1)));
272 break;
273 case 2:
274 vData.push_back(StrToDb(sCurrentItem));
275 break;
276 }
277 }
278
279 std::stable_sort(vIndex.begin(), vIndex.end(), compare_index(vData));
280
281 for (int j = 0; j < m_resultList->GetColumnCount(); j++)
282 {
283 for (int i = 0; i < m_resultList->GetItemCount(); i++)
284 {
285 vStringData.push_back(m_resultList->GetItemText(i, j));
286 }
287 for (int i = 0; i < m_resultList->GetItemCount(); i++)
288 {
289 m_resultList->SetItem(i, j, vStringData[vIndex[i]]);
290 }
291 vStringData.clear();
292 }
293}
294
295
double g_pixelScale
wxCheckBox * m_FunctionSemantics
void SetResult(const std::vector< std::string > &vResult)
void OnButtonCopy(wxCommandEvent &event)
void OnColumnHeaderClick(wxListEvent &event)
void OnItemClick(wxListEvent &event)
void OnItemRightClick(wxListEvent &event)
void OnClose(wxCloseEvent &event)
void OnButtonReport(wxCommandEvent &event)
void highlightSelection(const wxString &sSelection, bool firstMatch)
void OnButtonStart(wxCommandEvent &event)
void OnButtonOK(wxCommandEvent &event)
void SetProgress(double dPercentage)
This class handles the internal language system and returns the language strings of the selected lang...
Definition: language.hpp:38
std::string get(const std::string &sMessage, const std::vector< std::string > &vTokens) const
This member function returns the language string for the passed language identifier and replaces all ...
Definition: language.cpp:292
The class of the editor window.
Definition: editor.h:53
void notifyDialogClose()
Notifies the editor that the duplicated code dialog had been closed.
Definition: editor.cpp:2786
void OnFindDuplicateCode(int nDuplicateFlag=1, int nNumDuplicatedLines=6)
Wrapper for detectCodeDuplicates.
Definition: editor.cpp:6989
void IndicateDuplicatedLine(int nStart1, int nEnd1, int nStart2, int nEnd2, int nSelectionLine)
Highlights differences between two blocks of code.
Definition: editor.cpp:7050
This class generalizes a set of basic floating window functionalities like being closable by pressing...
Definition: viewerframe.hpp:31
#define ID_DUPLICATECODE_COPY
Language _guilang
#define SEMANTICS_STRING
#define SEMANTICS_NUM
#define ID_DUPLICATECODE_START
#define SEMANTICS_VAR
#define SEMANTICS_FUNCTION
#define ID_DUPLICATECODE_REPORT
int StrToInt(const std::string &)
Converts a string into an integer.
double StrToDb(const std::string &sString)
Converts a string into a double.
compare_index(const std::vector< double > &arr)
const std::vector< double > base_arr
bool operator()(int a, int b) const
std::string toString(int)
Converts an integer to a string without the Settings bloat.
END_EVENT_TABLE()