mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 06:05:58 -06:00
127 lines
3.5 KiB
C++
127 lines
3.5 KiB
C++
#include "AnalyseGui.h"
|
|
#include "Analyse.h"
|
|
|
|
#define IMAGECLASS Images
|
|
#define IMAGEFILE <CodeMetric/AnalyseGui.iml>
|
|
#include <Draw/iml.h>
|
|
|
|
String defaultCode =
|
|
"/*"
|
|
" This tool measures certain source code metrics.\n"
|
|
" You can type, paste, or load the code you would like measure into this text area.\n"
|
|
" Metrics provided are:\n"
|
|
" - Cyclomatic complexity 1: counts the decision points per method, thus estimating the\n"
|
|
" number of testcases needed for each method.\n"
|
|
" - Cyclomatic complexity 2: CC1 extended with the implicit decisions created by the\n"
|
|
" && || and ?: operators. Evaluation:\n"
|
|
" CC2 1-10 simple, low risk method\n"
|
|
" CC2 10-20 moderate complexity & risk method\n"
|
|
" CC2 21-50 high complexity & risk method\n"
|
|
" CC2 >50 too complex, untestable method, should be refactored\n"
|
|
" - Depth: measures deepest scope embedding level per method. This estimates the human\n"
|
|
" memory needed to keep in mind the current context. Any methods with depth > 5 is\n"
|
|
" considered too complex, and candidate for refactoring\n"
|
|
" - Logical Lines Of Code: estimates the amount of source code per method in a way\n"
|
|
" which is mostly independent from code formatting style. Methods longer than 80 LLOC are\n"
|
|
" too long, and should be refactored.\n"
|
|
"*/\n"
|
|
"int main()\n"
|
|
"{\n"
|
|
" return 0;\n"
|
|
"}\n";
|
|
|
|
String defaultTitle = "CodeMetric GUI";
|
|
|
|
|
|
WarningDisplay::WarningDisplay(int limit, Color warningColor) :
|
|
limit(limit), warningColor(warningColor)
|
|
{
|
|
}
|
|
|
|
void WarningDisplay::PaintBackground(Draw& w, const Rect& r, const Value& q,
|
|
Color ink, Color paper, dword style) const
|
|
{
|
|
int v = (int)q;
|
|
if(v >= limit)
|
|
paper = warningColor;
|
|
Display::PaintBackground(w, r, q, ink, paper, style);
|
|
}
|
|
|
|
void AnalyseGui::MainMenu(Bar &bar)
|
|
{
|
|
bar.Add("Load file", THISBACK(Open));
|
|
}
|
|
|
|
void AnalyseGui::Open()
|
|
{
|
|
FileSelector fsel;
|
|
fsel.ExecuteOpen("Select file");
|
|
String fileName = fsel.Get();
|
|
if(fileName == "")
|
|
return;
|
|
source <<= LoadFile(fileName);
|
|
UpdateMetric();
|
|
Title(defaultTitle + " [" + fileName + "]");
|
|
}
|
|
|
|
void AnalyseGui::UpdateMetric()
|
|
{
|
|
String s = ~source;
|
|
CodeMetric metric(s);
|
|
chart.Clear();
|
|
for(int i = 0; i < metric.functions.GetCount(); i++)
|
|
{
|
|
CodeMetric::FunctionEntry & entry =
|
|
metric.functions[i];
|
|
chart.Add(entry.name,
|
|
entry.pos,
|
|
entry.cyclomaticComplexity1,
|
|
entry.cyclomaticComplexity2,
|
|
entry.logicalLinesOfCode,
|
|
entry.scopeDepth);
|
|
}
|
|
|
|
textMetric.SetData(metric.ToString());
|
|
}
|
|
|
|
void AnalyseGui::GotoFunction()
|
|
{
|
|
int cursor = chart.GetCursor();
|
|
if(cursor >= 0 && cursor < chart.GetCount())
|
|
{
|
|
int pos = (int)chart.Get(cursor, 1);
|
|
source.SetCursor( source.GetPos(pos) );
|
|
source.CenterCursor();
|
|
}
|
|
}
|
|
|
|
AnalyseGui::AnalyseGui() :
|
|
ccDisplay(50), llocDisplay(80), depthDisplay(5)
|
|
{
|
|
Title(defaultTitle);
|
|
Icon(Images::GaugeIcon);
|
|
AddFrame(menu);
|
|
menu.Set( THISBACK(MainMenu) );
|
|
source <<= THISBACK(UpdateMetric);
|
|
source <<= defaultCode;
|
|
textMetric.SetEditable(false);
|
|
chart.AddColumn("Function", 80);
|
|
chart.AddColumn("Pos", 15);
|
|
chart.AddColumn("CC1", 15).SetDisplay(ccDisplay);
|
|
chart.AddColumn("CC2", 15).SetDisplay(ccDisplay);
|
|
chart.AddColumn("LLOC", 15).SetDisplay(llocDisplay);
|
|
chart.AddColumn("Depth", 15).SetDisplay(depthDisplay);
|
|
chart.WhenLeftDouble = THISBACK(GotoFunction);
|
|
UpdateMetric();
|
|
splitter.Vert() << source << chart << textMetric;
|
|
splitter.SetPos(9000, 1);
|
|
splitter.SetPos(6500, 0);
|
|
Add(splitter.SizePos());
|
|
Sizeable().Zoomable();
|
|
}
|
|
|
|
|
|
GUI_APP_MAIN
|
|
{
|
|
AnalyseGui().Run();
|
|
}
|