1 // This file is part of BOINC.
2 // http://boinc.berkeley.edu
3 // Copyright (C) 2008 University of California
4 //
5 // BOINC is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU Lesser General Public License
7 // as published by the Free Software Foundation,
8 // either version 3 of the License, or (at your option) any later version.
9 //
10 // BOINC 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.
13 // See the GNU Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public License
16 // along with BOINC.  If not, see <http://www.gnu.org/licenses/>.
17 
18 #if defined(__GNUG__) && !defined(__APPLE__)
19 #pragma implementation "ViewStatistics.h"
20 #endif
21 
22 #include "stdwx.h"
23 #include "BOINCGUIApp.h"
24 #include "BOINCBaseFrame.h"
25 #include "MainDocument.h"
26 #include "AdvancedFrame.h"
27 #include "BOINCTaskCtrl.h"
28 #include "BOINCListCtrl.h"
29 #include "ViewStatistics.h"
30 #include "Events.h"
31 #include "util.h"
32 
33 #include "res/stats.xpm"
34 
35 enum {  // Command buttons (m_SelectedStatistic)
36     show_user_total = 0,
37     show_user_average,
38     show_host_total,
39     show_host_average,
40     n_command_buttons
41 };
42 
43 enum {  // Mode buttons (m_ModeViewStatistic)
44     mode_one_project = 0,
45     mode_all_separate,
46     mode_all_together,
47     mode_sum
48 };
49 
50 enum {  // Project buttons
51     previous_project = 0,
52     next_project,
53     show_hide_project_list
54 };
55 
BEGIN_EVENT_TABLE(CPaintStatistics,wxWindow)56 BEGIN_EVENT_TABLE (CPaintStatistics, wxWindow)
57 	EVT_PAINT(CPaintStatistics::OnPaint)
58 	EVT_SIZE(CPaintStatistics::OnSize)
59 	EVT_LEFT_DOWN(CPaintStatistics::OnLeftMouseDown)
60 	EVT_LEFT_UP(CPaintStatistics::OnLeftMouseUp)
61 	EVT_RIGHT_DOWN(CPaintStatistics::OnRightMouseDown)
62 	EVT_RIGHT_UP(CPaintStatistics::OnRightMouseUp)
63 	EVT_MOTION(CPaintStatistics::OnMouseMotion)
64 	EVT_LEAVE_WINDOW(CPaintStatistics::OnMouseLeaveWindows)
65 	EVT_ERASE_BACKGROUND(CPaintStatistics::OnEraseBackground)
66     EVT_SCROLL(CPaintStatistics::OnLegendScroll)
67 END_EVENT_TABLE ()
68 
69 // Set USE_MEMORYDC FALSE to aid debugging
70 #define USE_MEMORYDC TRUE
71 
72 CPaintStatistics::CPaintStatistics(wxWindow* parent, wxWindowID id, const wxPoint& pos,	const wxSize& size, long style, const wxString& name
73 ): wxWindow(parent, id, pos, size, style, name)
74 {	m_font_standart = *wxSWISS_FONT;
75 	m_font_bold = *wxSWISS_FONT;
76 	m_font_standart_italic = *wxSWISS_FONT;
77 
78 	m_SelectedStatistic = show_user_total;
79 	heading = wxT("");
80 	m_ModeViewStatistic = mode_one_project;
81 	m_NextProjectStatistic = 0;
82 	m_ViewHideProjectStatistic = -1;
83 
84 	m_GraphLineWidth = 2;
85 	m_GraphPointWidth = 4;
86 
87     m_Space_for_scrollbar = 0;
88     m_Num_projects = 0;
89     m_previous_SelProj = -1;
90     m_scrollBar = new wxScrollBar(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL);
91     int h;
92     m_scrollBar->GetSize(&m_Scrollbar_width, &h);
93     m_scrollBar->SetScrollbar(0, 1, 1, 1);
94     m_scrollBar->Hide();
95 	m_Legend_Shift_Mode1 = 0;
96 	m_Legend_Shift_Mode2 = 0;
97 
98 	m_GraphMarker_X1 = 0;
99 	m_GraphMarker_Y1 = 0;
100 	m_GraphMarker1 = false;
101 
102 	m_GraphZoom_X1 = 0;
103 	m_GraphZoom_Y1 = 0;
104 	m_GraphZoom_X2 = 0;
105 	m_GraphZoom_Y2 = 0;
106 	m_GraphZoom_X2_old = 0;
107 	m_GraphZoom_Y2_old = 0;
108 
109 	m_GraphZoomStart = false;
110 
111 	m_GraphMove_X1 = 0;
112 	m_GraphMove_Y1 = 0;
113 	m_GraphMove_X2 = 0;
114 	m_GraphMove_Y2 = 0;
115 	m_GraphMoveStart = false;
116 	m_GraphMoveGo = false;
117 
118 	m_Zoom_max_val_X = 0;
119 	m_Zoom_min_val_X = 0;
120 	m_Zoom_max_val_Y = 0;
121 	m_Zoom_min_val_Y = 0;
122 	m_Zoom_Auto = true;
123 
124 // XY
125 	m_main_X_start = 0;
126 	m_main_X_end = 0;
127 	m_main_Y_start = 0;
128 	m_main_Y_end = 0;
129 
130 	m_WorkSpace_X_start = 0;
131 	m_WorkSpace_X_end = 0;
132 	m_WorkSpace_Y_start = 0;
133 	m_WorkSpace_Y_end = 0;
134 
135 	m_Legend_X_start = 0;
136 	m_Legend_X_end = 0;
137 	m_Legend_Y_start = 0;
138 	m_Legend_Y_end = 0;
139 
140 	m_Legend_select_X_start = 0;
141 	m_Legend_select_X_end = 0;
142 	m_Legend_select_Y_start = 0;
143 	m_Legend_select_Y_end = 0;
144 
145 	m_Graph_X_start = 0;
146 	m_Graph_X_end = 0;
147 	m_Graph_Y_start = 0;
148 	m_Graph_Y_end = 0;
149 
150 	m_Graph_draw_X_start = 0;
151 	m_Graph_draw_X_end = 0;
152 	m_Graph_draw_Y_start = 0;
153 	m_Graph_draw_Y_end = 0;
154 
155 	m_Legend_dY = 0;
156 	m_LegendDraw = true;
157 
158 // Default colours
159 	m_pen_MarkerLineColour = wxColour(0, 0, 0);
160 	m_pen_ZoomRectColour = wxColour (128, 64, 95);
161 	m_brush_ZoomRectColour = wxColour(24, 31, 0);
162 	m_brush_AxisColour = wxColour(192, 224, 255);
163 	m_pen_AxisColour = wxColour(64, 128, 192);
164 	m_pen_AxisColourZoom = wxColour(255, 64, 0);
165 	m_pen_AxisColourAutoZoom = wxColour(64, 128, 192);
166 	m_pen_AxisXColour = wxColour(64, 128, 192);
167 	m_pen_AxisYColour = wxColour(64, 128, 192);
168 	m_pen_AxisXTextColour = wxColour(0, 0, 0);
169 	m_pen_AxisYTextColour = wxColour(0, 0, 0);
170 
171 	m_brush_LegendColour = wxColour(235, 255, 255);//wxColour(220, 240, 255);
172 	m_brush_LegendSelectColour = wxColour(192, 224, 255);
173 	m_pen_LegendSelectColour = wxColour(64, 128, 192);
174 	m_pen_LegendSelectTextColour = wxColour(0, 0, 0);
175 	m_pen_LegendColour = wxColour(64, 128, 192);
176 	m_pen_LegendTextColour = wxColour(0, 0, 0);
177 
178 	m_brush_MainColour = wxColour(255, 255, 255);
179 	m_pen_MainColour = wxColour(64, 128, 192);
180 
181 	m_pen_HeadTextColour = wxColour(0, 0, 0);
182 	m_pen_ProjectHeadTextColour = wxColour(0, 0, 0);
183 
184 	m_pen_GraphTotalColour = wxColour(255, 0, 0);
185 	m_pen_GraphRACColour = wxColour(0, 160, 0);
186 	m_pen_GraphTotalHostColour = wxColour(0, 0, 255);
187 	m_pen_GraphRACHostColour = wxColour(0, 0, 0);
188 
189 	m_dc_bmp.Create(1, 1);
190 	m_full_repaint = true;
191 	m_bmp_OK = false;
192 
193 #ifdef __WXMAC__
194     m_fauxStatisticsView = NULL;
195     SetupMacAccessibilitySupport();
196 #endif
197 }
198 
~CPaintStatistics()199 CPaintStatistics::~CPaintStatistics() {
200     if (m_scrollBar) {
201         delete m_scrollBar;
202     }
203 #ifdef __WXMAC__
204     RemoveMacAccessibilitySupport();
205 #endif
206 }
207 
208 
getTypePoint(int & typePoint,int number)209 static void getTypePoint(int &typePoint, int number) {typePoint = number / 10;}
210 
CrossTwoLine(const double X1_1,const double Y1_1,const double X1_2,const double Y1_2,const double X2_1,const double Y2_1,const double X2_2,const double Y2_2,double & Xcross,double & Ycross)211 static bool CrossTwoLine(const double X1_1, const double Y1_1, const double X1_2, const double Y1_2,
212 						 const double X2_1, const double Y2_1, const double X2_2, const double Y2_2,
213 						 double &Xcross, double &Ycross) {
214 	double A1 = Y1_1 - Y1_2;
215 	double B1 = X1_2 - X1_1;
216 	double C1 = - X1_1 * A1 - Y1_1 * B1;
217 	double A2 = Y2_1 - Y2_2;
218 	double B2 = X2_2 - X2_1;
219 	double C2 = - X2_1 * A2 - Y2_1 * B2;
220 	double tmp1 = (A1 * B2 - A2 * B1);
221 	if (0 == tmp1){
222 		Xcross = 0;
223 		Ycross = 0;
224 		return false;
225 	}else{
226 		Xcross = (B1 * C2 - B2 * C1) / tmp1;
227 		Ycross = (C1 * A2 - C2 * A1) / tmp1;
228 		return true;
229 	}
230 }
231 
232 //----Draw "Point"
myDrawPoint(wxDC & dc,int X,int Y,wxColour graphColour,int numberTypePoint,int PointWidth)233 static void myDrawPoint(wxDC &dc,int X, int Y, wxColour graphColour,int numberTypePoint, int PointWidth) {
234 	dc.SetPen(wxPen(graphColour , 1 , wxSOLID));
235 	switch (numberTypePoint % 5){
236 	case 1: {wxPoint* points = new wxPoint[3];
237 		points[0] = wxPoint(X, Y - 1 - (PointWidth / 2));
238 		points[1] = wxPoint(X + (PointWidth / 2), Y + (PointWidth / 2));
239 		points[2] = wxPoint(X - (PointWidth / 2), Y + (PointWidth / 2));
240 		dc.DrawPolygon(3, points);
241 		delete[] points;
242 		break;}
243 	case 2: {wxPoint* points = new wxPoint[3];
244 		points[0] = wxPoint(X, Y + 1 + (PointWidth / 2));
245 		points[1] = wxPoint(X + (PointWidth / 2), Y - (PointWidth / 2));
246 		points[2] = wxPoint(X - (PointWidth / 2), Y - (PointWidth / 2));
247 		dc.DrawPolygon(3, points);
248 		delete[] points;
249 		break;}
250 	case 3:	dc.DrawRectangle(wxCoord(X - (PointWidth / 2)),wxCoord(Y - (PointWidth / 2)),wxCoord(PointWidth + 1),wxCoord(PointWidth + 1));
251 		break;
252 	case 4: {wxPoint* points = new wxPoint[4];
253 		points[0] = wxPoint(X, Y - 1 - (PointWidth / 2));
254 		points[1] = wxPoint(X + 1 + (PointWidth / 2), Y);
255 		points[2] = wxPoint(X, Y + 1 + (PointWidth / 2));
256 		points[3] = wxPoint(X - 1 - (PointWidth / 2), Y);
257 		dc.DrawPolygon(4, points);
258 		delete[] points;
259 		break;}
260 	default:dc.DrawCircle(wxCoord(X), wxCoord(Y), wxCoord(PointWidth / 2));
261 	}
262 }
263 //----Find minimum/maximum value----
MinMaxDayCredit(std::vector<PROJECT * >::const_iterator & i,double & min_credit,double & max_credit,double & min_day,double & max_day,const int m_SelectedStatistic,bool first=true)264 static void MinMaxDayCredit(std::vector<PROJECT*>::const_iterator &i, double &min_credit, double &max_credit, double &min_day, double &max_day, const int m_SelectedStatistic, bool first = true) {
265 	for (std::vector<DAILY_STATS>::const_iterator j = (*i)->statistics.begin(); j != (*i)->statistics.end(); ++j) {
266 		if (first){
267 			max_day = j->day;
268 			switch (m_SelectedStatistic){
269 			case show_user_total:	max_credit = j->user_total_credit;	break;
270 			case show_user_average:	max_credit = j->user_expavg_credit;	break;
271 			case show_host_total:	max_credit = j->host_total_credit;	break;
272 			case show_host_average:	max_credit = j->host_expavg_credit;	break;
273 			default: max_credit = 0.0;
274 			}
275 			min_day = max_day;
276 			min_credit = max_credit;
277 			first = false;
278 		} else {
279 			if (j->day < min_day) min_day = j->day;
280 			if (j->day > max_day) max_day = j->day;
281 
282 			switch (m_SelectedStatistic){
283 			case show_user_total:
284 				if (j->user_total_credit > max_credit) max_credit = j->user_total_credit;
285 				if (j->user_total_credit < min_credit) min_credit = j->user_total_credit;
286 				break;
287 			case show_user_average:
288 				if (j->user_expavg_credit > max_credit) max_credit = j->user_expavg_credit;
289 				if (j->user_expavg_credit < min_credit) min_credit = j->user_expavg_credit;
290 				break;
291 			case show_host_total:
292 				if (j->host_total_credit > max_credit) max_credit = j->host_total_credit;
293 				if (j->host_total_credit < min_credit) min_credit = j->host_total_credit;
294 				break;
295 			case show_host_average:
296 				if (j->host_expavg_credit > max_credit) max_credit = j->host_expavg_credit;
297 				if (j->host_expavg_credit < min_credit) min_credit = j->host_expavg_credit;
298 				break;
299 			}
300 		}
301 	}
302 }
CheckMinMaxD(double & min_val,double & max_val)303 static void CheckMinMaxD(double &min_val, double &max_val) {
304 	if (min_val > max_val) min_val = max_val;
305 	if (max_val == min_val){
306 		max_val += 0.5;
307 		min_val -= 0.5;
308 	}
309 }
ClearXY()310 void CPaintStatistics::ClearXY(){
311 	m_main_X_start = 0;
312 	m_main_X_end = 0;
313 	m_main_Y_start = 0;
314 	m_main_Y_end = 0;
315 
316 	m_WorkSpace_X_start = 0;
317 	m_WorkSpace_X_end = 0;
318 	m_WorkSpace_Y_start = 0;
319 	m_WorkSpace_Y_end = 0;
320 
321 	m_Graph_X_start = 0;
322 	m_Graph_X_end = 0;
323 	m_Graph_Y_start = 0;
324 	m_Graph_Y_end = 0;
325 
326 	m_Graph_draw_X_start = 0;
327 	m_Graph_draw_X_end = 0;
328 	m_Graph_draw_Y_start = 0;
329 	m_Graph_draw_Y_end = 0;
330 }
ClearLegendXY()331 void CPaintStatistics::ClearLegendXY(){
332 
333 	m_Legend_X_start = 0;
334 	m_Legend_X_end = 0;
335 	m_Legend_Y_start = 0;
336 	m_Legend_Y_end = 0;
337 
338 	m_Legend_select_X_start = 0;
339 	m_Legend_select_X_end = 0;
340 	m_Legend_select_Y_start = 0;
341 	m_Legend_select_Y_end = 0;
342 
343 	m_Legend_dY = 0;
344 }
AB(const double x_coord1,const double y_coord1,const double x_coord2,const double y_coord2,const double x_val1,const double y_val1,const double x_val2,const double y_val2)345 void CPaintStatistics::AB(const double x_coord1, const double y_coord1, const double x_coord2, const double y_coord2, const double x_val1, const double y_val1, const double x_val2, const double y_val2){
346 // Val -> Coord
347 	if (0.0 == (x_val2 - x_val1)){
348 		m_Ax_ValToCoord = 0.0;
349 		m_Bx_ValToCoord = 0.0;
350 	}else{
351 		m_Ax_ValToCoord = (x_coord2 - x_coord1) / (x_val2 - x_val1);
352 		m_Bx_ValToCoord = x_coord1 - (m_Ax_ValToCoord * x_val1);
353 	}
354 	if (0.0 == (y_val2 - y_val1)){
355 		m_Ay_ValToCoord = 0.0;
356 		m_By_ValToCoord = 0.0;
357 	}else{
358 		m_Ay_ValToCoord = (y_coord2 - y_coord1) / (y_val2 - y_val1);
359 		m_By_ValToCoord = y_coord1 - (m_Ay_ValToCoord * y_val1);
360 	}
361 // Coord -> Val
362 	if (0.0 == (x_coord2 - x_coord1)){
363 		m_Ax_CoordToVal = 0.0;
364 		m_Bx_CoordToVal = 0.0;
365 	}else{
366 		m_Ax_CoordToVal = (x_val2 - x_val1) / (x_coord2 - x_coord1);
367 		m_Bx_CoordToVal = x_val1 - (m_Ax_CoordToVal * x_coord1);
368 	}
369 	if (0.0 == (y_coord2 - y_coord1)){
370 		m_Ay_CoordToVal = 0.0;
371 		m_By_CoordToVal = 0.0;
372 	}else{
373 		m_Ay_CoordToVal = (y_val2 - y_val1) / (y_coord2 - y_coord1);
374 		m_By_CoordToVal = y_val1 - (m_Ay_CoordToVal * y_coord1);
375 	}
376 }
377 
AddToStats(const DAILY_STATS & src,DAILY_STATS & dst)378 void CPaintStatistics::AddToStats(const DAILY_STATS &src, DAILY_STATS &dst) {
379     dst.user_total_credit += src.user_total_credit;
380     dst.user_expavg_credit += src.user_expavg_credit;
381     dst.host_total_credit += src.host_total_credit;
382     dst.host_expavg_credit += src.host_expavg_credit;
383 }
384 
385 //----Draw Main Head----
DrawMainHead(wxDC & dc,const wxString head_name)386 void CPaintStatistics::DrawMainHead(wxDC &dc, const wxString head_name){
387 	wxCoord w_temp = 0, h_temp = 0, des_temp = 0, lead_temp = 0;
388 	dc.GetTextExtent(head_name, &w_temp, &h_temp, &des_temp, &lead_temp);
389 	dc.SetTextForeground (m_pen_HeadTextColour);
390 	wxCoord x0 = wxCoord(m_WorkSpace_X_start + ((m_WorkSpace_X_end - m_WorkSpace_X_start - double(w_temp)) / 2.0));
391 	wxCoord y0 = wxCoord(m_WorkSpace_Y_start + 1.0);
392 	if (x0 > wxCoord(m_WorkSpace_X_end)) x0 = wxCoord(m_WorkSpace_X_end);
393 	if (x0 < wxCoord(m_WorkSpace_X_start)) x0 = wxCoord(m_WorkSpace_X_start);
394 	if (x0 < 0) x0 = 0;
395 	if (y0 > wxCoord(m_WorkSpace_Y_end)) y0 = wxCoord(m_WorkSpace_Y_end);
396 	if (y0 < wxCoord(m_WorkSpace_Y_start)) y0 = wxCoord(m_WorkSpace_Y_start);
397 	if (y0 < 0) y0 = 0;
398 	dc.DrawText (head_name, x0, y0);
399 	m_WorkSpace_Y_start += double(h_temp) + 2.0;
400 	if (m_WorkSpace_Y_start > m_WorkSpace_Y_end) m_WorkSpace_Y_start = m_WorkSpace_Y_end;
401 	if (m_WorkSpace_Y_start < 0.0) m_WorkSpace_Y_start = 0.0;
402 }
403 //----Draw Project Head----
DrawProjectHead(wxDC & dc,PROJECT * project1,const wxString head_name_last)404 void CPaintStatistics::DrawProjectHead(wxDC &dc, PROJECT* project1, const wxString head_name_last){
405 	wxCoord w_temp = 0, h_temp = 0, des_temp = 0, lead_temp = 0;
406 	wxString head_name = wxT("");
407 	wxCoord x0 = 0;
408 	wxCoord y0 = 0;
409 
410 	if (project1) {
411 	    head_name = wxString(_("Project")) + wxT(": ") + wxString(project1->project_name.c_str(), wxConvUTF8);
412 	    dc.GetTextExtent(head_name, &w_temp, &h_temp, &des_temp, &lead_temp);
413 		x0 = wxCoord(m_WorkSpace_X_start + ((m_WorkSpace_X_end - m_WorkSpace_X_start - double(w_temp)) / 2.0));
414 		y0 = wxCoord(m_WorkSpace_Y_start + 1.0);
415 		if (x0 > wxCoord(m_WorkSpace_X_end)) x0 = wxCoord(m_WorkSpace_X_end);
416 		if (x0 < wxCoord(m_WorkSpace_X_start)) x0 = wxCoord(m_WorkSpace_X_start);
417 		if (x0 < 0) x0 = 0;
418 		if (y0 > wxCoord(m_WorkSpace_Y_end)) y0 = wxCoord(m_WorkSpace_Y_end);
419 		if (y0 < wxCoord(m_WorkSpace_Y_start)) y0 = wxCoord(m_WorkSpace_Y_start);
420 		if (y0 < 0) y0 = 0;
421 	    dc.DrawText (head_name, x0, y0);
422 	    m_WorkSpace_Y_start += double(h_temp) + 2.0;
423 		if (m_WorkSpace_Y_start > m_WorkSpace_Y_end) m_WorkSpace_Y_start = m_WorkSpace_Y_end;
424 		if (m_WorkSpace_Y_start < 0.0) m_WorkSpace_Y_start = 0.0;
425 
426 		head_name = wxString(_("Account")) + wxT(": ") + wxString(project1->user_name.c_str(), wxConvUTF8);
427 	    dc.GetTextExtent(head_name, &w_temp, &h_temp, &des_temp, &lead_temp);
428 		x0 = wxCoord(m_WorkSpace_X_start + ((m_WorkSpace_X_end - m_WorkSpace_X_start - double(w_temp)) / 2.0));
429 		y0 = wxCoord(m_WorkSpace_Y_start + 1.0);
430 		if (x0 > wxCoord(m_WorkSpace_X_end)) x0 = wxCoord(m_WorkSpace_X_end);
431 		if (x0 < wxCoord(m_WorkSpace_X_start)) x0 = wxCoord(m_WorkSpace_X_start);
432 		if (x0 < 0) x0 = 0;
433 		if (y0 > wxCoord(m_WorkSpace_Y_end)) y0 = wxCoord(m_WorkSpace_Y_end);
434 		if (y0 < wxCoord(m_WorkSpace_Y_start)) y0 = wxCoord(m_WorkSpace_Y_start);
435 		if (y0 < 0) y0 = 0;
436 	    dc.DrawText (head_name, x0, y0);
437 	    m_WorkSpace_Y_start += double(h_temp) + 2.0;
438 		if (m_WorkSpace_Y_start > m_WorkSpace_Y_end) m_WorkSpace_Y_start = m_WorkSpace_Y_end;
439 		if (m_WorkSpace_Y_start < 0.0) m_WorkSpace_Y_start = 0.0;
440 
441 	    head_name = wxString(_("Team")) + wxT(": ") + wxString(project1->team_name.c_str(), wxConvUTF8);
442 	    dc.GetTextExtent(head_name, &w_temp, &h_temp, &des_temp, &lead_temp);
443 		x0 = wxCoord(m_WorkSpace_X_start + ((m_WorkSpace_X_end - m_WorkSpace_X_start - double(w_temp)) / 2.0));
444 		y0 = wxCoord(m_WorkSpace_Y_start + 1.0);
445 		if (x0 > wxCoord(m_WorkSpace_X_end)) x0 = wxCoord(m_WorkSpace_X_end);
446 		if (x0 < wxCoord(m_WorkSpace_X_start)) x0 = wxCoord(m_WorkSpace_X_start);
447 		if (x0 < 0) x0 = 0;
448 		if (y0 > wxCoord(m_WorkSpace_Y_end)) y0 = wxCoord(m_WorkSpace_Y_end);
449 		if (y0 < wxCoord(m_WorkSpace_Y_start)) y0 = wxCoord(m_WorkSpace_Y_start);
450 		if (y0 < 0) y0 = 0;
451 	    dc.DrawText (head_name, x0, y0);
452 	    m_WorkSpace_Y_start += double(h_temp) + 2.0;
453 		if (m_WorkSpace_Y_start > m_WorkSpace_Y_end) m_WorkSpace_Y_start = m_WorkSpace_Y_end;
454 		if (m_WorkSpace_Y_start < 0.0) m_WorkSpace_Y_start = 0.0;
455 
456 	    dc.GetTextExtent(head_name_last, &w_temp, &h_temp, &des_temp, &lead_temp);
457 		x0 = wxCoord(m_WorkSpace_X_start + ((m_WorkSpace_X_end - m_WorkSpace_X_start - double(w_temp)) / 2.0));
458 		y0 = wxCoord(m_WorkSpace_Y_start + 1.0);
459 		if (x0 > wxCoord(m_WorkSpace_X_end)) x0 = wxCoord(m_WorkSpace_X_end);
460 		if (x0 < wxCoord(m_WorkSpace_X_start)) x0 = wxCoord(m_WorkSpace_X_start);
461 		if (x0 < 0) x0 = 0;
462 		if (y0 > wxCoord(m_WorkSpace_Y_end)) y0 = wxCoord(m_WorkSpace_Y_end);
463 		if (y0 < wxCoord(m_WorkSpace_Y_start)) y0 = wxCoord(m_WorkSpace_Y_start);
464 		if (y0 < 0) y0 = 0;
465 	    dc.DrawText (head_name_last, x0, y0);
466 	    m_WorkSpace_Y_start += double(h_temp) + 2.0;
467 		if (m_WorkSpace_Y_start > m_WorkSpace_Y_end) m_WorkSpace_Y_start = m_WorkSpace_Y_end;
468 		if (m_WorkSpace_Y_start < 0.0) m_WorkSpace_Y_start = 0.0;
469 	}
470 }
471 //----Draw Legend----
DrawLegend(wxDC & dc,PROJECTS * proj,CMainDocument * pDoc,int SelProj,bool bColour,int & m_Legend_Shift)472 void CPaintStatistics::DrawLegend(wxDC &dc, PROJECTS* proj, CMainDocument* pDoc, int SelProj, bool bColour, int &m_Legend_Shift){
473 	wxString head_name = wxT("0");
474 	wxCoord project_name_max_width = 0;
475 	const double radius1 = 5;
476 	const wxCoord buffer_y1 = 3;
477 	const wxCoord buffer_x1 = 3;
478 	int count = -1;
479 //	int project_count = -1;
480 	wxCoord w_temp = 0, h_temp = 0, des_temp = 0, lead_temp = 0;
481 	wxCoord x0 = 0;
482 	wxCoord y0 = 0;
483 	wxCoord h0 = 0;
484 	wxCoord w0 = 0;
485     wxCoord totalTextAreaHeight = 0;
486 
487 	dc.SetFont(m_font_bold);
488 	dc.GetTextExtent(head_name, &w_temp, &h_temp, &des_temp, &lead_temp);
489 	m_Legend_dY = (double)(h_temp) + 4.0;
490 	if (m_Legend_dY < 0) m_Legend_dY = 0;
491 
492 	for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
493 		++count;
494 		PROJECT* state_project = pDoc->state.lookup_project((*i)->master_url);
495 		if (state_project) head_name = wxString(state_project->project_name.c_str(), wxConvUTF8);
496 		dc.GetTextExtent(head_name, &w_temp, &h_temp, &des_temp, &lead_temp);
497 		if (project_name_max_width < w_temp) project_name_max_width = w_temp;
498 	}
499     m_Num_projects = count + 1;
500 	project_name_max_width += wxCoord(8) + buffer_x1 + buffer_x1 + wxCoord(m_GraphPointWidth) + wxCoord(2);
501 	if (project_name_max_width < 0) project_name_max_width = 0;
502     totalTextAreaHeight = (m_Num_projects * m_Legend_dY);
503 
504 	dc.SetBrush(wxBrush(m_brush_LegendColour , wxSOLID));
505 	dc.SetPen(wxPen(m_pen_LegendColour , 1 , wxSOLID));
506 	y0 = wxCoord(m_WorkSpace_Y_start) + buffer_y1;
507 	if (y0 > wxCoord(m_WorkSpace_Y_end)) y0 = wxCoord(m_WorkSpace_Y_end);
508 	if (y0 < wxCoord(m_WorkSpace_Y_start)) y0 = wxCoord(m_WorkSpace_Y_start);
509 	if (y0 < 0) y0 = 0;
510 	w0 = project_name_max_width - buffer_x1 - buffer_x1;
511 	if (w0 < 0) w0 = 0;
512 	h0 = wxCoord(m_WorkSpace_Y_end - m_WorkSpace_Y_start) - buffer_y1 - buffer_y1;
513 	if (h0 < 0) h0 = 0;
514 
515     m_Space_for_scrollbar = 0;
516     if (h0 < (totalTextAreaHeight + (2 * radius1))) m_Space_for_scrollbar = m_Scrollbar_width;
517     int numVisible = (h0 - (2 * radius1)) / m_Legend_dY;
518     int numSteps = m_Num_projects - numVisible + 1;
519     if (numSteps < 2) {
520         m_scrollBar->Hide();
521     } else {
522         m_scrollBar->SetSize(m_WorkSpace_X_end - m_Scrollbar_width, m_WorkSpace_Y_start, m_Scrollbar_width, m_WorkSpace_Y_end - m_WorkSpace_Y_start, 0);
523         m_scrollBar->SetScrollbar(m_scrollBar->GetThumbPosition(), 1, numSteps, 1);
524         m_scrollBar->Show();
525     }
526 
527 	x0 = wxCoord(m_WorkSpace_X_end) - project_name_max_width + buffer_x1 - m_Space_for_scrollbar;
528 	if (x0 > wxCoord(m_WorkSpace_X_end)) x0 = wxCoord(m_WorkSpace_X_end);
529 	if (x0 < wxCoord(m_WorkSpace_X_start)) x0 = wxCoord(m_WorkSpace_X_start);
530 	if (x0 < 0) x0 = 0;
531 
532 	dc.DrawRoundedRectangle(x0, y0, w0, h0, radius1);
533 
534 	m_Legend_X_start = double(x0);
535 	m_Legend_X_end = double(x0 + w0);
536 	m_Legend_Y_start = double(y0);
537 	m_Legend_Y_end = double(y0 + h0);
538 	if (m_Legend_X_end > m_WorkSpace_X_end) m_Legend_X_end = m_WorkSpace_X_end;
539 	if (m_Legend_Y_end > m_WorkSpace_Y_end) m_Legend_Y_end = m_WorkSpace_Y_end;
540 	if (m_Legend_X_start > m_Legend_X_end) m_Legend_X_start = m_Legend_X_end;
541 	if (m_Legend_Y_start > m_Legend_Y_end) m_Legend_Y_start = m_Legend_Y_end;
542 
543 	m_Legend_select_X_start = m_Legend_X_start;
544 	m_Legend_select_X_end = m_Legend_X_end;
545 	m_Legend_select_Y_start = m_Legend_Y_start + radius1;
546 	m_Legend_select_Y_end = m_Legend_Y_end - radius1;
547 	if (m_Legend_select_Y_start < 0.0) m_Legend_select_Y_start = 0.0;
548 	if (m_Legend_select_Y_end < 0.0) m_Legend_select_Y_end = 0.0;
549 	if (m_Legend_select_Y_start > m_Legend_select_Y_end) m_Legend_select_Y_start = m_Legend_select_Y_end;
550 
551 // Legend Shift (start)
552 	int Legend_count_temp = 0;
553 	if (m_Legend_dY > 0) Legend_count_temp = int(floor((m_Legend_select_Y_end - m_Legend_select_Y_start) / m_Legend_dY));
554 
555     if (numSteps > 1) {
556         m_Legend_Shift = m_scrollBar->GetThumbPosition();
557     } else {
558          m_Legend_Shift = 0;
559     }
560 
561 	if ((SelProj >= 0) && (m_previous_SelProj != SelProj)) {
562         m_previous_SelProj = SelProj;
563 		if (Legend_count_temp <= 0){
564 			m_Legend_Shift = SelProj;
565 		}
566 		else {
567 			if (SelProj < m_Legend_Shift) m_Legend_Shift = SelProj;
568 			if (SelProj >= (m_Legend_Shift + Legend_count_temp)) m_Legend_Shift = SelProj - Legend_count_temp + 1;
569 		}
570 	}
571 	if ((m_Legend_Shift + Legend_count_temp) > count) m_Legend_Shift = count - Legend_count_temp + 1;
572 
573 	if (m_Legend_Shift > count) m_Legend_Shift = count; //???
574 	if (m_Legend_Shift < 0) m_Legend_Shift = 0;
575     m_scrollBar->SetThumbPosition(m_Legend_Shift);
576 //	Legend Shift (end)
577 //---------------
578 //	project_count = count;
579 	count = -1;
580 
581 	m_WorkSpace_X_end -= double(project_name_max_width) + m_Space_for_scrollbar;
582 	if (m_WorkSpace_X_end < m_WorkSpace_X_start) m_WorkSpace_X_end = m_WorkSpace_X_start;
583 	if (m_WorkSpace_X_end < 0.0) m_WorkSpace_X_end = 0.0;
584 
585 	for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
586 		++count;
587 		if (count < m_Legend_Shift) continue;
588 	///Draw project name
589 		head_name = wxT("?");
590 		PROJECT* state_project = pDoc->state.lookup_project((*i)->master_url);
591 		if (state_project) head_name = wxString(state_project->project_name.c_str(), wxConvUTF8);
592 
593 		if (SelProj == count){
594 			dc.SetBrush(wxBrush(m_brush_LegendSelectColour , wxSOLID));
595 			dc.SetPen(wxPen(m_pen_LegendSelectColour , 1 , wxSOLID));
596 			x0 = wxCoord(m_WorkSpace_X_end) + buffer_x1 - wxCoord(1);
597 			y0 = wxCoord(m_WorkSpace_Y_start + (double)(count - m_Legend_Shift) * m_Legend_dY + double(buffer_y1) + radius1);
598 			w0 = project_name_max_width - buffer_x1 - buffer_x1 + 2;
599 			h0 = wxCoord(m_Legend_dY);
600 			if (x0 < 0) x0 = 0;
601 			if (y0 < 0) y0 = 0;
602 			if (w0 < 0) w0 = 0;
603 			if (h0 < 0) h0 = 0;
604 			dc.DrawRoundedRectangle(x0 ,y0 , w0, h0, 1);
605 		}
606 
607 		wxColour graphColour = wxColour(0, 0, 0);
608 		int  typePoint = 0;
609 		if (bColour){
610 			getTypePoint(typePoint, count);
611 			color_cycle(count, proj->projects.size(), graphColour);
612 		} else if (SelProj == count) {
613 				graphColour = m_pen_LegendSelectTextColour;
614 			} else {
615 				graphColour = m_pen_LegendTextColour;
616 			}
617 
618 		dc.SetBrush(wxBrush(m_brush_LegendColour , wxSOLID));
619 		x0 = wxCoord(m_WorkSpace_X_end) + buffer_x1 + wxCoord(4) + wxCoord(m_GraphPointWidth / 2);
620 		y0 = wxCoord(m_WorkSpace_Y_start + ((double)(count - m_Legend_Shift) + 0.5) * m_Legend_dY + double(buffer_y1) + radius1);
621 		if (x0 < 0) x0 = 0;
622 		if (y0 < 0) y0 = 0;
623 		if ((SelProj >= 0) || (!(m_HideProjectStatistic.count( wxString( (*i)->master_url, wxConvUTF8 ) )))){
624 			myDrawPoint(dc, int(x0), int(y0), graphColour, typePoint ,m_GraphPointWidth);
625 			dc.SetFont(m_font_bold);
626 		}else {
627 			dc.SetFont(m_font_standart_italic);
628 			graphColour = wxColour(0, 0, 0);
629 		}
630 
631 		x0 = wxCoord(m_WorkSpace_X_end) + buffer_x1 + wxCoord(7) + wxCoord(m_GraphPointWidth);
632 		y0 = wxCoord(m_WorkSpace_Y_start + 1.0 + (double)(count - m_Legend_Shift) * m_Legend_dY + double(buffer_y1) + radius1);
633 		if (x0 < 0) x0 = 0;
634 		if (y0 < 0) y0 = 0;
635 		dc.SetTextForeground(graphColour);
636 		dc.DrawText(head_name, x0, y0);
637 		m_Legend_select_Y_end = m_WorkSpace_Y_start + (double)(count - m_Legend_Shift + 1) * m_Legend_dY + double(buffer_y1) + radius1;
638 		if ((m_Legend_select_Y_end + m_Legend_dY) > (m_WorkSpace_Y_end - double(buffer_y1) - radius1)){
639 			break;
640 		}
641 	}
642 	dc.SetFont(m_font_standart);
643 }
644 //----Draw background, axis(lines), text(01-Jan-1980)----
DrawAxis(wxDC & dc,const double max_val_y,const double min_val_y,const double max_val_x,const double min_val_x,wxColour pen_AxisColour,const double max_val_y_all,const double min_val_y_all)645 void CPaintStatistics::DrawAxis(wxDC &dc, const double max_val_y, const double min_val_y, const double max_val_x, const double min_val_x,
646 								wxColour pen_AxisColour, const double max_val_y_all, const double min_val_y_all) {
647 	wxCoord x0 = wxCoord(m_WorkSpace_X_start);
648 	wxCoord y0 = wxCoord(m_WorkSpace_Y_start);
649 	wxCoord w0 = wxCoord(m_WorkSpace_X_end - m_WorkSpace_X_start);
650 	wxCoord h0 = wxCoord(m_WorkSpace_Y_end - m_WorkSpace_Y_start);
651 	wxCoord x1 = 0;
652 	wxCoord y1 = 0;
653 	if (x0 < 0) x0 = 0;
654 	if (y0 < 0) y0 = 0;
655 	if (w0 < 0) w0 = 0;
656 	if (h0 < 0) h0 = 0;
657 	dc.SetClippingRegion(x0, y0, w0, h0);
658 
659 	dc.SetBrush(wxBrush(m_brush_AxisColour , wxSOLID));
660 	dc.SetPen(wxPen(pen_AxisColour , 1 , wxSOLID));
661 
662 	wxCoord w_temp, h_temp, des_temp, lead_temp;
663 	wxCoord w_temp2;
664 
665 	dc.GetTextExtent(wxString::Format(wxT(" %s"), format_number(max_val_y_all, 2)), &w_temp, &h_temp, &des_temp, &lead_temp);
666 	dc.GetTextExtent(wxString::Format(wxT(" %s"), format_number(min_val_y_all, 2)), &w_temp2, &h_temp, &des_temp, &lead_temp);
667 
668 	if (w_temp < w_temp2) w_temp = w_temp2;
669 
670 	m_WorkSpace_X_start += double(w_temp) + 3.0;
671 	m_WorkSpace_Y_end -= double(h_temp) + 3.0;
672 
673 	dc.GetTextExtent(wxT("0"), &w_temp, &h_temp, &des_temp, &lead_temp);
674 
675 	m_WorkSpace_X_end -= 3.0;//w_temp;
676 	const double radius1 = 5.0;//(double)(h_temp/2.0);
677 	double d_y = (double)(h_temp) / 2.0;
678 	if (d_y < 5.0) d_y = 5.0;
679 
680 	wxDateTime dtTemp1;
681 	wxString strBuffer1;
682 	dtTemp1.Set((time_t)max_val_x);
683 	strBuffer1 = dtTemp1.Format(wxT("%d.%b.%y"), wxDateTime::GMT0);
684 	dc.GetTextExtent(strBuffer1, &w_temp, &h_temp, &des_temp, &lead_temp);
685 
686 	double d_x = (double)(w_temp) / 2.0;
687 
688 // Draw background graph
689 	x0 = wxCoord(m_WorkSpace_X_start);
690 	y0 = wxCoord(m_WorkSpace_Y_start);
691 	w0 = wxCoord(m_WorkSpace_X_end - m_WorkSpace_X_start);
692 	h0 = wxCoord(m_WorkSpace_Y_end - m_WorkSpace_Y_start);
693 	if (x0 < 0) x0 = 0;
694 	if (y0 < 0) y0 = 0;
695 	if (w0 < 0) w0 = 0;
696 	if (h0 < 0) h0 = 0;
697 	dc.DrawRoundedRectangle(x0, y0, w0, h0, radius1);
698 
699 	m_Graph_X_start = m_WorkSpace_X_start;	//x0;
700 	m_Graph_X_end = m_WorkSpace_X_end;		//x0 + w0;
701 	m_Graph_Y_start = m_WorkSpace_Y_start;	//y0;
702 	m_Graph_Y_end = m_WorkSpace_Y_end;		//y0 + h0;
703 
704 	m_WorkSpace_X_start += d_x;
705 	m_WorkSpace_X_end -= d_x;
706 	m_WorkSpace_Y_start += d_y;
707 	m_WorkSpace_Y_end -= d_y;
708 
709 	if (m_WorkSpace_X_end < m_WorkSpace_X_start) m_WorkSpace_X_start = m_WorkSpace_X_end = (m_WorkSpace_X_end + m_WorkSpace_X_start) / 2.0;
710 	if (m_WorkSpace_Y_end < m_WorkSpace_Y_start) m_WorkSpace_Y_start = m_WorkSpace_Y_end = (m_WorkSpace_Y_end + m_WorkSpace_Y_start) / 2.0;
711 
712 	m_Graph_draw_X_start = m_WorkSpace_X_start;
713 	m_Graph_draw_X_end = m_WorkSpace_X_end;
714 	m_Graph_draw_Y_start = m_WorkSpace_Y_start;
715 	m_Graph_draw_Y_end = m_WorkSpace_Y_end;
716 // A B
717 	AB(m_WorkSpace_X_start, m_WorkSpace_Y_end, m_WorkSpace_X_end, m_WorkSpace_Y_start,
718 		min_val_x, min_val_y, max_val_x, max_val_y);
719 //Draw val and lines
720 	dc.SetPen(wxPen(m_pen_AxisYColour , 1 , wxDOT));
721 	dc.SetTextForeground (m_pen_AxisYTextColour);
722 
723 	int d_oy_count = 1;
724 	if (h_temp > 0)	d_oy_count = (int)ceil((m_WorkSpace_Y_end - m_WorkSpace_Y_start) / ( 2.0 * double(h_temp)));
725 	if (d_oy_count <= 0) d_oy_count = 1;
726 	double d_oy_val = fabs((max_val_y - min_val_y) / double(d_oy_count));
727 	double d2 = pow(double(10.0) , floor(log10(d_oy_val)));
728 
729 	if (d2 >= d_oy_val){
730 		d_oy_val = 1.0 * d2;
731 	} else	if (2.0 * d2 >= d_oy_val){
732 			d_oy_val = 2.0 * d2;
733 		} else	if (5.0 * d2 >= d_oy_val){
734 				d_oy_val = 5.0 * d2;
735 			} else {
736 				d_oy_val = 10.0 * d2;
737 			}
738 	if (0 == d_oy_val) d_oy_val = 0.01;
739 	double y_start_val = ceil(min_val_y / d_oy_val) * d_oy_val;
740 	d_oy_count = (int)floor((max_val_y - y_start_val) / d_oy_val);
741 
742 	for (double ny = 0; ny <= double(d_oy_count); ++ny){
743 		dc.GetTextExtent(wxString::Format(wxT("%s"), format_number(y_start_val + ny * d_oy_val, 2)), &w_temp, &h_temp, &des_temp, &lead_temp);
744 		x0 = wxCoord(m_Graph_X_start + 1.0);
745 		y0 = wxCoord(m_Ay_ValToCoord * (y_start_val + ny * d_oy_val) + m_By_ValToCoord);
746 		x1 = wxCoord(m_Graph_X_end - 1.0);
747 		if ((y0 >= wxCoord(m_WorkSpace_Y_start)) && (y0 <= wxCoord(m_WorkSpace_Y_end))){
748 			if (x0 < 0) x0 = 0;
749 			if (y0 < 0) y0 = 0;
750 			if (x1 < 0) x1 = 0;
751 			dc.DrawLine(x0, y0, x1, y0);
752 			x0 = wxCoord(m_Graph_X_start - 2.0) - w_temp;
753 			y0 = wxCoord(m_Ay_ValToCoord * (y_start_val + ny * d_oy_val) + m_By_ValToCoord - double(h_temp) / 2.0);
754 			if (x0 < 0) x0 = 0;
755 			if (y0 < 0) y0 = 0;
756 			dc.DrawText(wxString::Format(wxT("%s"), format_number(y_start_val + ny * d_oy_val, 2)), x0, y0);
757 		}
758 	}
759 
760 //Draw day numbers and lines marking the days
761 	dc.SetPen(wxPen(m_pen_AxisXColour , 1 , wxDOT));
762 	dc.SetTextForeground (m_pen_AxisXTextColour);
763 
764 	dtTemp1.Set((time_t)max_val_x);
765 	strBuffer1 = dtTemp1.Format(wxT("%d.%b.%y"), wxDateTime::GMT0);
766 	dc.GetTextExtent(strBuffer1, &w_temp, &h_temp, &des_temp, &lead_temp);
767 
768 	int d_ox_count = 1;
769 	if (w_temp > 0)	d_ox_count = (int)((m_WorkSpace_X_end - m_WorkSpace_X_start) / (1.2 * double(w_temp)));
770 	if (d_ox_count <= 0) d_ox_count = 1;
771 
772 	double d_ox_val = ceil(((double)(max_val_x - min_val_x) / double(d_ox_count)) / 86400.0) * 86400.0;
773 	if (0 == d_ox_val) d_ox_val = 1;
774 
775 	double x_start_val = ceil(min_val_x / 86400.0) * 86400.0;
776 	d_ox_count = (int)floor((max_val_x - x_start_val) / d_ox_val);
777 
778 	for (double nx = 0; nx <= double(d_ox_count); ++nx){
779 		dtTemp1.Set((time_t)(x_start_val + nx * d_ox_val));
780 		strBuffer1 = dtTemp1.Format(wxT("%d.%b.%y"), wxDateTime::GMT0);
781 		dc.GetTextExtent(strBuffer1, &w_temp, &h_temp, &des_temp, &lead_temp);
782 		x0 = wxCoord(m_Ax_ValToCoord * (x_start_val + nx * d_ox_val) + m_Bx_ValToCoord);
783 		y0 = wxCoord(m_Graph_Y_start + 1.0);
784 		y1 = wxCoord(m_Graph_Y_end - 1.0);
785 		if ((x0 <= wxCoord(m_WorkSpace_X_end)) && (x0 >= wxCoord(m_WorkSpace_X_start))){
786 			if (x0 < 0) x0 = 0;
787 			if (y0 < 0) y0 = 0;
788 			if (y1 < 0) y1 = 0;
789 		    dc.DrawLine(x0, y0, x0, y1);
790 			x0 = wxCoord(m_Ax_ValToCoord * (x_start_val + nx * d_ox_val) + m_Bx_ValToCoord - (double(w_temp) / 2.0));
791 			y0 = (wxCoord)m_Graph_Y_end;
792 			if (x0 < 0) x0 = 0;
793 			if (y0 < 0) y0 = 0;
794 			dc.DrawText(strBuffer1, x0, y0);
795 		}
796 	}
797 	dc.DestroyClippingRegion();
798 }
799 //----Draw graph----
DrawGraph(wxDC & dc,std::vector<PROJECT * >::const_iterator & i,const wxColour graphColour,const int typePoint,const int selectedStatistic)800 void CPaintStatistics::DrawGraph(wxDC &dc, std::vector<PROJECT*>::const_iterator &i, const wxColour graphColour, const int typePoint, const int selectedStatistic) {
801     std::vector<DAILY_STATS> stats = (*i)->statistics;
802     DrawGraph2(dc, stats, graphColour, typePoint, selectedStatistic);
803 }
804 
DrawGraph2(wxDC & dc,std::vector<DAILY_STATS> stats,const wxColour graphColour,const int typePoint,const int selectedStatistic)805 void CPaintStatistics::DrawGraph2(wxDC &dc, std::vector<DAILY_STATS> stats, const wxColour graphColour, const int typePoint, const int selectedStatistic) {
806 	wxCoord x0 = wxCoord(m_Graph_X_start);
807 	wxCoord y0 = wxCoord(m_Graph_Y_start);
808 	wxCoord w0 = wxCoord(m_Graph_X_end - m_Graph_X_start);
809 	wxCoord h0 = wxCoord(m_Graph_Y_end - m_Graph_Y_start);
810 	if (x0 < 0) x0 = 0;
811 	if (y0 < 0) y0 = 0;
812 	if (w0 < 0) w0 = 0;
813 	if (h0 < 0) h0 = 0;
814 	dc.SetClippingRegion(x0, y0, w0, h0);
815 
816 	dc.SetPen(wxPen(graphColour , m_GraphLineWidth , wxSOLID));
817 
818 	wxCoord last_x = 0;
819 	wxCoord last_y = 0;
820 	wxCoord xpos = 0;
821 	wxCoord ypos = 0;
822 
823 	double d_last_x = 0;
824 	double d_last_y = 0;
825 	bool last_point_in = false;
826 
827 	double d_xpos = 0;
828 	double d_ypos = 0;
829 	bool point_in = false;
830 
831 	bool b_point1 = false;
832 	bool b_point2 = false;
833 // cross
834 	double d_cross_x1 = 0;
835 	double d_cross_y1 = 0;
836 // first point (no line)
837 	bool first_point = true;
838 // end point
839 	double d_end_point_x = 0;
840 	double d_end_point_y = 0;
841 	bool end_point = false;
842 //
843 	for (std::vector<DAILY_STATS>::const_iterator j = stats.begin(); j != stats.end(); ++j) {
844 		double d_x1 = 0;
845 		double d_y1 = 0;
846 		double d_x2 = 0;
847 		double d_y2 = 0;
848 		double d_min1 = 0;
849 		double d_max1 = 0;
850 		double d_min2 = 0;
851 		double d_max2 = 0;
852 
853 		b_point1 = false;
854 		b_point2 = false;
855 
856 		d_xpos = (m_Ax_ValToCoord * j->day + m_Bx_ValToCoord);// äîáàâèòü îêðóãëåíèå
857 		switch (selectedStatistic){  // äîáàâèòü îêðóãëåíèå
858 		case show_user_total:	d_ypos = (m_Ay_ValToCoord * j->user_total_credit + m_By_ValToCoord);	break;
859 		case show_user_average:	d_ypos = (m_Ay_ValToCoord * j->user_expavg_credit + m_By_ValToCoord);	break;
860 		case show_host_total:	d_ypos = (m_Ay_ValToCoord * j->host_total_credit + m_By_ValToCoord);	break;
861 		case show_host_average:	d_ypos = (m_Ay_ValToCoord * j->host_expavg_credit + m_By_ValToCoord);	break;
862 		default:d_ypos = (m_Ay_ValToCoord * j->user_total_credit + m_By_ValToCoord);	break;
863 		}
864 
865 		if (first_point) {
866 			if ((d_xpos < m_Graph_X_start) || (d_xpos > m_Graph_X_end) ||
867 				(d_ypos < m_Graph_Y_start) || (d_ypos > m_Graph_Y_end)){
868 				point_in = false;
869 				b_point2 = false;
870 				end_point = false;
871 			}else {
872 				point_in = true;
873 				d_x2 = d_xpos;
874 				d_y2 = d_ypos;
875 				b_point2 = true;
876 				d_end_point_x = d_xpos;
877 				d_end_point_y = d_ypos;
878 				end_point = true;
879 			}
880 			first_point = false;
881 		}else {
882 			dc.SetPen(wxPen(graphColour , m_GraphLineWidth , wxSOLID));
883 			// ïðîâåðêà ïîïàäàíèÿ ïåðâîé òî÷êè ëèíèè â îáëàñòü ðèñîâàíèÿ
884 			if (last_point_in){
885 				d_x1 = d_last_x;
886 				d_y1 = d_last_y;
887 				b_point1 = true;
888 			}else b_point1 = false;
889 			// ïðîâåðêà ïîïàäàíèÿ âòîðîé òî÷êè ëèíèè â îáëàñòü ðèñîâàíèÿ
890 			if ((d_xpos < m_Graph_X_start) || (d_xpos > m_Graph_X_end) ||
891 				(d_ypos < m_Graph_Y_start) || (d_ypos > m_Graph_Y_end)){
892 				point_in = false;
893 				b_point2 = false;
894 			}else {
895 				point_in = true;
896 				d_x2 = d_xpos;
897 				d_y2 = d_ypos;
898 				b_point2 = true;
899 			}
900 			// Èùåì òî÷êó âõîäà ëèíèè â îáëàñòü ðèñîâàíèÿ (1) x=const
901 			if (!b_point1 || !b_point2){
902 				if (CrossTwoLine(d_last_x, d_last_y, d_xpos, d_ypos,
903 								m_Graph_X_start, m_Graph_Y_end, m_Graph_X_start, m_Graph_Y_start,
904 								d_cross_x1, d_cross_y1)){
905 					if (d_last_x > d_xpos){
906 						d_min1 = d_xpos;
907 						d_max1 = d_last_x;
908 					}else{
909 						d_max1 = d_xpos;
910 						d_min1 = d_last_x;
911 					}
912 					if (m_Graph_Y_end > m_Graph_Y_start){
913 						d_min2 = m_Graph_Y_start;
914 						d_max2 = m_Graph_Y_end;
915 					}else{
916 						d_max2 = m_Graph_Y_end;
917 						d_min2 = m_Graph_Y_start;
918 					}
919 					if ((d_cross_x1 <= d_max1) && (d_cross_x1 >= d_min1) &&
920 						(d_cross_y1 <= d_max2) && (d_cross_y1 >= d_min2)){
921 						if (!b_point1){
922 							d_x1 = d_cross_x1;
923 							d_y1 = d_cross_y1;
924 							b_point1 = true;
925 						} else if (!b_point2){
926 							d_x2 = d_cross_x1;
927 							d_y2 = d_cross_y1;
928 							b_point2 = true;
929 						}
930 					}
931 				}
932 			}
933 			// Èùåì òî÷êó âõîäà ëèíèè â îáëàñòü ðèñîâàíèÿ (2) x=const
934 			if (!b_point1 || !b_point2){
935 				if (CrossTwoLine(d_last_x, d_last_y, d_xpos, d_ypos,
936 								m_Graph_X_end, m_Graph_Y_end, m_Graph_X_end, m_Graph_Y_start,
937 								d_cross_x1, d_cross_y1)){
938 					if (d_last_x > d_xpos){
939 						d_min1 = d_xpos;
940 						d_max1 = d_last_x;
941 					}else{
942 						d_max1 = d_xpos;
943 						d_min1 = d_last_x;
944 					}
945 					if (m_Graph_Y_end > m_Graph_Y_start){
946 						d_min2 = m_Graph_Y_start;
947 						d_max2 = m_Graph_Y_end;
948 					}else{
949 						d_max2 = m_Graph_Y_end;
950 						d_min2 = m_Graph_Y_start;
951 					}
952 					if ((d_cross_x1 <= d_max1) && (d_cross_x1 >= d_min1) &&
953 						(d_cross_y1 <= d_max2) && (d_cross_y1 >= d_min2)){
954 						if (!b_point1){
955 							d_x1 = d_cross_x1;
956 							d_y1 = d_cross_y1;
957 							b_point1 = true;
958 						} else if (!b_point2){
959 							d_x2 = d_cross_x1;
960 							d_y2 = d_cross_y1;
961 							b_point2 = true;
962 						}
963 					}
964 				}
965 			}
966 			// Èùåì òî÷êó âõîäà ëèíèè â îáëàñòü ðèñîâàíèÿ (3) y=const
967 			if (!b_point1 || !b_point2){
968 				if (CrossTwoLine(d_last_x, d_last_y, d_xpos, d_ypos,
969 								m_Graph_X_start, m_Graph_Y_start, m_Graph_X_end, m_Graph_Y_start,
970 								d_cross_x1, d_cross_y1)){
971 					if (d_last_y > d_ypos){
972 						d_min1 = d_ypos;
973 						d_max1 = d_last_y;
974 					}else{
975 						d_max1 = d_ypos;
976 						d_min1 = d_last_y;
977 					}
978 					if (m_Graph_X_end > m_Graph_X_start){
979 						d_min2 = m_Graph_X_start;
980 						d_max2 = m_Graph_X_end;
981 					}else{
982 						d_max2 = m_Graph_X_end;
983 						d_min2 = m_Graph_X_start;
984 					}
985 					if ((d_cross_y1 <= d_max1) && (d_cross_y1 >= d_min1) &&
986 						(d_cross_x1 <= d_max2) && (d_cross_x1 >= d_min2)){
987 						if (!b_point1){
988 							d_x1 = d_cross_x1;
989 							d_y1 = d_cross_y1;
990 							b_point1 = true;
991 						} else if (!b_point2){
992 							d_x2 = d_cross_x1;
993 							d_y2 = d_cross_y1;
994 							b_point2 = true;
995 						}
996 					}
997 				}
998 			}
999 			// Èùåì òî÷êó âõîäà ëèíèè â îáëàñòü ðèñîâàíèÿ (4) y=const
1000 			if (!b_point1 || !b_point2){
1001 				if (CrossTwoLine(d_last_x, d_last_y, d_xpos, d_ypos,
1002 								m_Graph_X_start, m_Graph_Y_end, m_Graph_X_end, m_Graph_Y_end,
1003 								d_cross_x1, d_cross_y1)){
1004 					if (d_last_y > d_ypos){
1005 						d_min1 = d_ypos;
1006 						d_max1 = d_last_y;
1007 					}else{
1008 						d_max1 = d_ypos;
1009 						d_min1 = d_last_y;
1010 					}
1011 					if (m_Graph_X_end > m_Graph_X_start){
1012 						d_min2 = m_Graph_X_start;
1013 						d_max2 = m_Graph_X_end;
1014 					}else{
1015 						d_max2 = m_Graph_X_end;
1016 						d_min2 = m_Graph_X_start;
1017 					}
1018 					if ((d_cross_y1 <= d_max1) && (d_cross_y1 >= d_min1) &&
1019 						(d_cross_x1 <= d_max2) && (d_cross_x1 >= d_min2)){
1020 						if (!b_point1){
1021 							d_x1 = d_cross_x1;
1022 							d_y1 = d_cross_y1;
1023 							b_point1 = true;
1024 						} else if (!b_point2){
1025 							d_x2 = d_cross_x1;
1026 							d_y2 = d_cross_y1;
1027 							b_point2 = true;
1028 						}
1029 					}
1030 				}
1031 			}
1032 			if (b_point1 && b_point2){
1033 				last_x = wxCoord(d_x1);
1034 				last_y = wxCoord(d_y1);
1035 				xpos = wxCoord(d_x2);
1036 				ypos = wxCoord(d_y2);
1037 				if (last_x > (wxCoord)m_Graph_X_end) last_x = (wxCoord)m_Graph_X_end;
1038 				if (last_x < 0) last_x = 0;
1039 				if (last_y > (wxCoord)m_Graph_Y_end) last_y = (wxCoord)m_Graph_Y_end;
1040 				if (last_y < 0) last_y = 0;
1041 				if (xpos > (wxCoord)m_Graph_X_end) xpos = (wxCoord)m_Graph_X_end;
1042 				if (xpos < 0) xpos = 0;
1043 				if (ypos > (wxCoord)m_Graph_Y_end) ypos = (wxCoord)m_Graph_Y_end;
1044 				if (ypos < 0) ypos = 0;
1045 
1046 				dc.DrawLine(last_x, last_y, xpos, ypos);
1047 				if (last_point_in) myDrawPoint(dc, last_x, last_y, graphColour, typePoint ,m_GraphPointWidth);
1048 				if (point_in){
1049 					d_end_point_x = d_xpos;
1050 					d_end_point_y = d_ypos;
1051 					end_point = true;
1052 				}else end_point = false;
1053 			}else end_point = false;
1054 		}
1055 		d_last_x = d_xpos;
1056 		d_last_y = d_ypos;
1057 		last_point_in = point_in;
1058 	}
1059 	// draw last point
1060 	if (end_point){
1061 		xpos = wxCoord(d_end_point_x);
1062 		ypos = wxCoord(d_end_point_y);
1063 		if (xpos > (wxCoord)m_Graph_X_end) xpos = (wxCoord)m_Graph_X_end;
1064 		if (xpos < 0) xpos = 0;
1065 		if (ypos > (wxCoord)m_Graph_Y_end) ypos = (wxCoord)m_Graph_Y_end;
1066 		if (ypos < 0) ypos = 0;
1067 		myDrawPoint(dc, xpos, ypos, graphColour, typePoint ,m_GraphPointWidth);
1068 	}
1069 	dc.DestroyClippingRegion();
1070 }
1071 //----Draw marker----
DrawMarker(wxDC & dc)1072 void CPaintStatistics::DrawMarker(wxDC &dc) {
1073 	if (m_GraphMarker1){
1074 		wxCoord x0 = wxCoord(m_Graph_X_start);
1075 		wxCoord y0 = wxCoord(m_Graph_Y_start);
1076 		wxCoord w0 = wxCoord(m_Graph_X_end - m_Graph_X_start);
1077 		wxCoord h0 = wxCoord(m_Graph_Y_end - m_Graph_Y_start);
1078 		if (x0 < 0) x0 = 0;
1079 		if (y0 < 0) y0 = 0;
1080 		if (w0 < 0) w0 = 0;
1081 		if (h0 < 0) h0 = 0;
1082 		dc.SetClippingRegion(x0, y0, w0, h0);
1083 
1084 		dc.SetPen(wxPen(m_pen_MarkerLineColour , 1 , wxSOLID));
1085 		wxCoord x00 = wxCoord(m_Ax_ValToCoord * m_GraphMarker_X1 + m_Bx_ValToCoord);
1086 		wxCoord y00 = wxCoord(m_Ay_ValToCoord * m_GraphMarker_Y1 + m_By_ValToCoord);
1087 		if (x00 < 0) x00 = 0;
1088 		if (y00 < 0) y00 = 0;
1089 		if ((x00 < wxCoord(m_Graph_X_start)) || (x00 > wxCoord(m_Graph_X_end)) ||
1090 			(y00 < wxCoord(m_Graph_Y_start)) || (y00 > wxCoord(m_Graph_Y_end))){
1091 		}else{
1092 			dc.CrossHair(x00, y00);
1093 			wxDateTime dtTemp1;
1094 			wxString strBuffer1;
1095 			dtTemp1.Set((time_t)m_GraphMarker_X1);
1096 			strBuffer1=dtTemp1.Format(wxT("%d.%b.%y"), wxDateTime::GMT0);
1097 
1098 			dc.SetFont(m_font_bold);
1099 			dc.SetTextBackground (m_brush_AxisColour);
1100 			dc.SetBackgroundMode(wxSOLID);
1101 			x0 += 2;
1102 			y0 += 2;
1103 			x00 += 2;
1104 			y00 += 2;
1105 			if (x00 < 0) x00 = 0;
1106 			if (y00 < 0) y00 = 0;
1107 			if (x0 < 0) x0 = 0;
1108 			if (y0 < 0) y0 = 0;
1109 
1110 			dc.SetTextForeground (m_pen_AxisYTextColour);
1111 			dc.DrawText(wxString::Format(wxT("%s"), format_number(m_GraphMarker_Y1, 2)) , x0, y00);
1112 			dc.SetTextForeground (m_pen_AxisXTextColour);
1113 			dc.DrawText(strBuffer1 ,x00, y0);
1114 			dc.SetBackgroundMode(wxTRANSPARENT);
1115 		}
1116 		dc.DestroyClippingRegion();
1117 	}
1118 }
1119 //-------- Draw All ---------
DrawAll(wxDC & dc)1120 void CPaintStatistics::DrawAll(wxDC &dc) {
1121 //Init global
1122 	CMainDocument* pDoc = wxGetApp().GetDocument();
1123 
1124 	wxASSERT(pDoc);
1125 	wxASSERT(wxDynamicCast(pDoc, CMainDocument));
1126 
1127 	PROJECTS *proj = &(pDoc->statistics_status);
1128 	wxASSERT(proj);
1129 
1130 	m_WorkSpace_X_start = m_main_X_start;
1131 	m_WorkSpace_X_end = m_main_X_end;
1132 	m_WorkSpace_Y_start = m_main_Y_start;
1133 	m_WorkSpace_Y_end = m_main_Y_end;
1134 
1135 	dc.SetBackground(m_brush_MainColour);
1136 
1137 //	dc.SetTextForeground (GetForegroundColour ());
1138 	dc.SetTextForeground (m_pen_HeadTextColour);
1139 	dc.SetTextBackground (GetBackgroundColour ());
1140 
1141     // The next 3 lines seem unnecessary and cause problems
1142     // when monitor dpi is set to 125% of normal on MS Windows.
1143 //	m_font_standart = dc.GetFont();
1144 //	m_font_bold = dc.GetFont();
1145 //	m_font_standart_italic = dc.GetFont();
1146 
1147 	m_font_standart.SetWeight(wxNORMAL);
1148 	m_font_bold.SetWeight(wxBOLD);
1149 //	m_font_standart_italic.SetFaceName(_T("Verdana"));
1150 	m_font_standart_italic.SetStyle(wxFONTSTYLE_ITALIC);
1151 
1152 	dc.SetFont(m_font_standart);
1153 //Start drawing
1154 	dc.Clear();
1155 	dc.SetBrush(wxBrush(m_brush_MainColour , wxSOLID));
1156 	dc.SetPen(wxPen(m_pen_MainColour , 1 , wxSOLID));
1157 
1158 	wxCoord x0 = wxCoord(m_main_X_start);
1159 	wxCoord y0 = wxCoord(m_main_Y_start);
1160 	wxCoord w0 = wxCoord(m_main_X_end - m_main_X_start);
1161 	wxCoord h0 = wxCoord(m_main_Y_end - m_main_Y_start);
1162 	if (x0 < 0) x0 = 0;
1163 	if (y0 < 0) y0 = 0;
1164 	if (w0 < 0) w0 = 0;
1165 	if (h0 < 0) h0 = 0;
1166 	dc.SetBrush(wxBrush(m_brush_MainColour , wxSOLID));
1167 	dc.SetPen(wxPen(m_pen_MainColour , 1 , wxSOLID));
1168 	dc.DrawRectangle(x0, y0, w0, h0);
1169 //Number of Projects
1170 	int nb_proj = 0;
1171 	for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) { ++nb_proj; }
1172 	if (0 == nb_proj) {
1173         dc.DrawRectangle(x0, y0, w0, h0);
1174 		return;
1175 	}
1176 // Check m_NextProjectStatistic
1177 	if (m_NextProjectStatistic < 0) m_NextProjectStatistic = nb_proj - 1;
1178 	if ((m_NextProjectStatistic < 0) || (m_NextProjectStatistic >= nb_proj)) m_NextProjectStatistic = 0;
1179 // Initial coord
1180 	switch (m_SelectedStatistic){
1181 	case show_user_total: heading = _("User Total");		break;
1182 	case show_user_average: heading = _("User Average");	break;
1183 	case show_host_total: heading = _("Host Total");		break;
1184 	case show_host_average: heading = _("Host Average");	break;
1185 	default:heading = wxT("");
1186 	}
1187 
1188     if (!m_LegendDraw) {
1189         m_scrollBar->Hide();
1190         m_Space_for_scrollbar = 0;
1191     }
1192 
1193 	switch (m_ModeViewStatistic){
1194 	case mode_all_separate:
1195     {
1196 	//Draw Legend
1197 		if (m_ViewHideProjectStatistic >= 0){
1198 			int count = -1;
1199 			std::set<wxString>::iterator s;
1200 			for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1201 				++count;
1202 				if (m_ViewHideProjectStatistic == count){
1203 					s = m_HideProjectStatistic.find( wxString((*i)->master_url, wxConvUTF8) );
1204 					if (s != m_HideProjectStatistic.end()){
1205 						m_HideProjectStatistic.erase(s);
1206                     } else {
1207                         m_HideProjectStatistic.insert(wxString((*i)->master_url, wxConvUTF8));
1208                     }
1209 					break;
1210 				}
1211 			}
1212 		}
1213 		m_ViewHideProjectStatistic = -1;
1214 
1215 		if (m_LegendDraw) DrawLegend(dc, proj, pDoc, -1, false, m_Legend_Shift_Mode2);
1216 	///Draw heading
1217 		dc.SetFont(m_font_bold);
1218 		DrawMainHead(dc, heading);
1219 		dc.SetFont(m_font_standart);
1220 	//How many rows/colums?
1221 		int nb_proj_show = 0;
1222 		for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1223 			if (!(m_HideProjectStatistic.count( wxString((*i)->master_url, wxConvUTF8) ))){
1224 				++nb_proj_show;
1225 			}
1226 		}
1227 //
1228 		int nb_proj_row = 0, nb_proj_col = 0;
1229 		if (nb_proj_show < 4) {
1230 			nb_proj_col = 1;
1231 			nb_proj_row = nb_proj_show;
1232 		} else {
1233 			nb_proj_col = 2;
1234 			nb_proj_row = (int)ceil(double(nb_proj_show) / double(nb_proj_col));
1235 		}
1236 
1237 		int col = 1, row = 1; //Used to identify the actual row/col
1238 
1239 		double rectangle_x_start = m_WorkSpace_X_start;
1240 		double rectangle_x_end = m_WorkSpace_X_end;
1241 		double rectangle_y_start = m_WorkSpace_Y_start;
1242 		double rectangle_y_end = m_WorkSpace_Y_end;
1243 
1244 		if (0 == nb_proj_col) nb_proj_col = 1;
1245 		if (0 == nb_proj_row) nb_proj_row = 1;
1246 		const double x_fac = (rectangle_x_end - rectangle_x_start) / double(nb_proj_col);
1247 		const double y_fac = (rectangle_y_end - rectangle_y_start) / double(nb_proj_row);
1248 
1249 		double min_val_y_all = 10e32, max_val_y_all = 0;
1250 		double min_val_x_all = 10e32, max_val_x_all = 0;
1251 
1252 		for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1253 			if (!(m_HideProjectStatistic.count( wxString((*i)->master_url, wxConvUTF8) ))){
1254 				MinMaxDayCredit(i, min_val_y_all, max_val_y_all, min_val_x_all, max_val_x_all, m_SelectedStatistic, false);
1255 			}
1256 		}
1257 
1258 		for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1259 			if (!(m_HideProjectStatistic.count( wxString((*i)->master_url, wxConvUTF8) ))){
1260 			//Find minimum/maximum value
1261 				double min_val_y = 10e32, max_val_y = 0;
1262 				double min_val_x = 10e32, max_val_x = 0;
1263 				MinMaxDayCredit(i, min_val_y, max_val_y, min_val_x, max_val_x, m_SelectedStatistic);
1264 				CheckMinMaxD(min_val_x, max_val_x);
1265 				CheckMinMaxD(min_val_y, max_val_y);
1266 				min_val_x = floor(min_val_x / 86400.0) * 86400.0;
1267 				max_val_x = ceil(max_val_x / 86400.0) * 86400.0;
1268 			//Where do we draw in?
1269 				ClearXY();
1270 				m_main_X_start = (wxCoord)(rectangle_x_start + x_fac * (double)(col - 1));
1271 				m_main_X_end = (wxCoord)(rectangle_x_start + x_fac * ((double)col));
1272 				m_main_Y_start = (wxCoord)(rectangle_y_start + y_fac * (double)(row - 1));
1273 				m_main_Y_end = (wxCoord)(rectangle_y_start + y_fac * (double)row);
1274 				if (m_main_X_start < 0) m_main_X_start = 0;
1275 				if (m_main_X_start > m_main_X_end) m_main_X_end = m_main_X_start;
1276 				if (m_main_Y_start < 0) m_main_Y_start = 0;
1277 				if (m_main_Y_start > m_main_Y_end) m_main_Y_end = m_main_Y_start;
1278 
1279 				m_WorkSpace_X_start = m_main_X_start;
1280 				m_WorkSpace_X_end = m_main_X_end;
1281 				m_WorkSpace_Y_start = m_main_Y_start;
1282 				m_WorkSpace_Y_end = m_main_Y_end;
1283 
1284 			//Draw scale Draw Project name
1285 				wxString head_name = wxT("?");
1286 				PROJECT* state_project = pDoc->state.lookup_project((*i)->master_url);
1287 				if (state_project) {
1288 					head_name = wxString(state_project->project_name.c_str(), wxConvUTF8);
1289 				}
1290 			//Draw heading
1291 				DrawMainHead(dc, head_name);
1292 			//Draw axis
1293 				DrawAxis(dc, max_val_y, min_val_y,max_val_x, min_val_x, m_pen_AxisColour, max_val_y_all, min_val_y_all);
1294 			//Draw graph
1295 				wxColour graphColour=wxColour(0,0,0);
1296 				color_cycle(m_SelectedStatistic, n_command_buttons, graphColour);
1297 				DrawGraph(dc, i, graphColour, 0, m_SelectedStatistic);
1298 			//Change row/col
1299 				if (col == nb_proj_col) {
1300 					col = 1;
1301 					++row;
1302 				} else {
1303 					++col;
1304 				}
1305 			}
1306 		}
1307 		break;
1308 		}
1309 	case mode_one_project:
1310     {
1311 	//Draw Legend
1312 		if (m_LegendDraw) DrawLegend(dc, proj, pDoc, m_NextProjectStatistic, false, m_Legend_Shift_Mode1);
1313 	//Draw heading
1314 		dc.SetFont(m_font_bold);
1315 		DrawMainHead(dc, heading);
1316 		dc.SetFont(m_font_standart);
1317 	//Draw project
1318 		int count = -1;
1319 		for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1320 			++count;
1321 			if (count != m_NextProjectStatistic) continue;
1322 		//Find minimum/maximum value
1323 			double min_val_y = 10e32, max_val_y = 0;
1324 			double min_val_x = 10e32, max_val_x = 0;
1325 
1326 			MinMaxDayCredit(i, min_val_y, max_val_y, min_val_x, max_val_x, m_SelectedStatistic);
1327 
1328 			double t_n1 = dtime();
1329 			double t_d1 = floor((t_n1 - max_val_x) / 86400.0);
1330 
1331 			wxString head_name=wxString::Format(_("Last update: %.0f days ago"), t_d1);
1332 
1333 			wxColour pen_AxisColour1 = m_pen_AxisColourAutoZoom;
1334 
1335 			if (m_Zoom_Auto){
1336 				min_val_x = floor(min_val_x / 86400.0) * 86400.0;
1337 				max_val_x = ceil(max_val_x / 86400.0) * 86400.0;
1338 			}else{
1339 				pen_AxisColour1 = m_pen_AxisColourZoom;
1340 				min_val_x = m_Zoom_min_val_X;
1341 				max_val_x = m_Zoom_max_val_X;
1342 				min_val_y = m_Zoom_min_val_Y;
1343 				max_val_y = m_Zoom_max_val_Y;
1344 			}
1345 			CheckMinMaxD(min_val_x, max_val_x);
1346 			CheckMinMaxD(min_val_y, max_val_y);
1347 
1348 		    // Draw heading
1349 			PROJECT* state_project = pDoc->state.lookup_project((*i)->master_url);
1350 			if (state_project) {
1351 				dc.SetFont(m_font_standart_italic);
1352 				DrawProjectHead(dc, state_project, head_name);
1353 				dc.SetFont(m_font_standart);
1354 			}
1355 			m_Zoom_min_val_X = min_val_x;
1356 			m_Zoom_max_val_X = max_val_x;
1357 			m_Zoom_min_val_Y = min_val_y;
1358 			m_Zoom_max_val_Y = max_val_y;
1359 		    // Draw axis
1360 			DrawAxis(dc, max_val_y, min_val_y, max_val_x, min_val_x, pen_AxisColour1, max_val_y, min_val_y);
1361 		    // Draw graph
1362 			wxColour graphColour=wxColour(0,0,0);
1363 			color_cycle(m_SelectedStatistic, n_command_buttons, graphColour);
1364 			DrawGraph(dc, i, graphColour, 0, m_SelectedStatistic);
1365 		    // Draw marker
1366 			DrawMarker(dc);
1367 			break;
1368 		}
1369 		break;
1370 		}
1371 	case mode_all_together:
1372     {
1373 	//Draw Legend
1374 		if (m_ViewHideProjectStatistic >= 0){
1375 			int count = -1;
1376 			std::set<wxString>::iterator s;
1377 			for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1378 				++count;
1379 				if (m_ViewHideProjectStatistic == count){
1380 					s = m_HideProjectStatistic.find( wxString((*i)->master_url, wxConvUTF8) );
1381 					if (s != m_HideProjectStatistic.end()){
1382 						m_HideProjectStatistic.erase(s);
1383 					}else m_HideProjectStatistic.insert( wxString((*i)->master_url, wxConvUTF8) );
1384 					break;
1385 				}
1386 			}
1387 		}
1388 		m_ViewHideProjectStatistic = -1;
1389 
1390 		if (m_LegendDraw) DrawLegend(dc, proj, pDoc, -1, true, m_Legend_Shift_Mode2);
1391 	//Draw heading
1392 		dc.SetFont(m_font_bold);
1393 		DrawMainHead(dc, heading);
1394 		dc.SetFont(m_font_standart);
1395 	//Find minimum/maximum value
1396 		double min_val_y = 10e32, max_val_y = 0;
1397 		double min_val_x = 10e32, max_val_x = 0;
1398 
1399 		wxColour pen_AxisColour1 = m_pen_AxisColourAutoZoom;
1400 
1401 		if (m_Zoom_Auto){
1402 			for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1403 				if (!(m_HideProjectStatistic.count( wxString((*i)->master_url, wxConvUTF8) ))){
1404 					MinMaxDayCredit(i, min_val_y, max_val_y, min_val_x, max_val_x, m_SelectedStatistic, false);
1405 				}
1406 			}
1407 			min_val_x = floor(min_val_x / 86400.0) * 86400.0;
1408 			max_val_x = ceil(max_val_x / 86400.0) * 86400.0;
1409 		}else{
1410 			pen_AxisColour1 = m_pen_AxisColourZoom;
1411 			min_val_x = m_Zoom_min_val_X;
1412 			max_val_x = m_Zoom_max_val_X;
1413 			min_val_y = m_Zoom_min_val_Y;
1414 			max_val_y = m_Zoom_max_val_Y;
1415 		}
1416 		CheckMinMaxD(min_val_x, max_val_x);
1417 		CheckMinMaxD(min_val_y, max_val_y);
1418 
1419 		m_Zoom_min_val_X = min_val_x;
1420         m_Zoom_max_val_X = max_val_x;
1421 		m_Zoom_min_val_Y = min_val_y;
1422 		m_Zoom_max_val_Y = max_val_y;
1423 	//Draw axis
1424 		DrawAxis(dc, max_val_y, min_val_y, max_val_x, min_val_x, pen_AxisColour1, max_val_y, min_val_y);
1425 	//Draw graph
1426 		int count = -1;
1427 		for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1428 			++count;
1429 			if (!(m_HideProjectStatistic.count( wxString((*i)->master_url, wxConvUTF8) ))){
1430 				wxColour graphColour = wxColour(0,0,0);
1431 				int  typePoint = 0;
1432 				getTypePoint(typePoint,count);
1433 				color_cycle(count, proj->projects.size(), graphColour);
1434 				DrawGraph(dc, i, graphColour, typePoint, m_SelectedStatistic);
1435 			}
1436 		}
1437 	//Draw marker
1438 		DrawMarker(dc);
1439 		break;
1440 		}
1441 	case mode_sum:
1442     {
1443 	//Draw Legend
1444 		if (m_ViewHideProjectStatistic >= 0){
1445 			int count = -1;
1446 			std::set<wxString>::iterator s;
1447 			for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1448 				++count;
1449 				if (m_ViewHideProjectStatistic == count){
1450 					s = m_HideProjectStatistic.find( wxString((*i)->master_url, wxConvUTF8) );
1451 					if (s != m_HideProjectStatistic.end()){
1452 						m_HideProjectStatistic.erase(s);
1453 					}else m_HideProjectStatistic.insert( wxString((*i)->master_url, wxConvUTF8) );
1454 					break;
1455 				}
1456 			}
1457 		}
1458 		m_ViewHideProjectStatistic = -1;
1459 
1460 		if (m_LegendDraw) DrawLegend(dc, proj, pDoc, -1, true, m_Legend_Shift_Mode2);
1461 	//Draw heading
1462 		dc.SetFont(m_font_bold);
1463 		DrawMainHead(dc, heading);
1464 		dc.SetFont(m_font_standart);
1465 	//Find minimum/maximum value
1466 		double min_val_y = 10e32, max_val_y = 0;
1467 		double min_val_x = 10e32, max_val_x = 0;
1468         double min_total_y = 0;
1469         double max_total_y = 0;
1470 
1471 		wxColour pen_AxisColour1 = m_pen_AxisColourAutoZoom;
1472 
1473 		if (m_Zoom_Auto){
1474 			for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1475 				if (!(m_HideProjectStatistic.count( wxString((*i)->master_url, wxConvUTF8) ))){
1476 					MinMaxDayCredit(i, min_val_y, max_val_y, min_val_x, max_val_x, m_SelectedStatistic, false);
1477                     min_total_y += min_val_y;
1478                     max_total_y += max_val_y;
1479                     min_val_y = 10e32;
1480                     max_val_y = 0;
1481 				}
1482 			}
1483             // Start graph 30 days before today
1484 			min_val_x = dday() - (30*86400);
1485 			max_val_x = ceil(max_val_x / 86400.0) * 86400.0;
1486             min_val_y = min_total_y;
1487             max_val_y = max_total_y;
1488 		}else{
1489 			pen_AxisColour1 = m_pen_AxisColourZoom;
1490 			min_val_x = m_Zoom_min_val_X;
1491 			max_val_x = m_Zoom_max_val_X;
1492 			min_val_y = m_Zoom_min_val_Y;
1493 			max_val_y = m_Zoom_max_val_Y;
1494 		}
1495 		CheckMinMaxD(min_val_x, max_val_x);
1496 		CheckMinMaxD(min_val_y, max_val_y);
1497 
1498 		m_Zoom_min_val_X = min_val_x;
1499         m_Zoom_max_val_X = max_val_x;
1500 		m_Zoom_min_val_Y = min_val_y;
1501 		m_Zoom_max_val_Y = max_val_y;
1502 	//Draw axis
1503 		DrawAxis(dc, max_val_y, min_val_y, max_val_x, min_val_x, pen_AxisColour1, max_val_y, min_val_y);
1504     // Generate summed data
1505         DAILY_STATS stat, saved_sum_stat, prev_proj_stat;
1506         std::vector<DAILY_STATS> sumstats;
1507         stat.user_total_credit = 0.0;
1508         stat.user_expavg_credit = 0.0;
1509         stat.host_total_credit = 0.0;
1510         stat.host_expavg_credit = 0.0;
1511         stat.day = min_val_x;
1512         sumstats.push_back(stat);
1513         stat.day = max_val_x;
1514         sumstats.push_back(stat);
1515 
1516 		int count = -1;
1517 		for (std::vector<PROJECT*>::const_iterator i = proj->projects.begin(); i != proj->projects.end(); ++i) {
1518 			++count;
1519 			if (m_HideProjectStatistic.count( wxString((*i)->master_url, wxConvUTF8) )) continue;
1520             saved_sum_stat.user_total_credit = 0.0;
1521             saved_sum_stat.user_expavg_credit = 0.0;
1522             saved_sum_stat.host_total_credit = 0.0;
1523             saved_sum_stat.host_expavg_credit = 0.0;
1524             saved_sum_stat.day = 0.0;
1525             prev_proj_stat = saved_sum_stat;
1526 
1527             if (sumstats.size() && (*i)->statistics.size()) {
1528                 std::vector<DAILY_STATS>::iterator sum_iter = sumstats.begin();
1529                 std::vector<DAILY_STATS>::const_iterator proj_iter = (*i)->statistics.begin();
1530                 for (;;) {
1531                     if ((*proj_iter).day >= min_val_x) {
1532                         if ((*proj_iter).day < (*sum_iter).day) {
1533                             sum_iter = sumstats.insert(sum_iter, stat);
1534                             *sum_iter = saved_sum_stat;
1535                             (*sum_iter).day = (*proj_iter).day;
1536                         } else {
1537                             saved_sum_stat = *sum_iter;
1538                         }
1539 
1540                         if ((*proj_iter).day > (*sum_iter).day) {
1541                             AddToStats(prev_proj_stat, *sum_iter);
1542                         } else {
1543                             AddToStats(*proj_iter, *sum_iter);
1544                         }
1545 
1546                         ++sum_iter;
1547                         if (sum_iter == sumstats.end()) {
1548                             break;
1549                         }
1550                     }
1551 
1552                     if ((*proj_iter).day <= (*sum_iter).day) {
1553                         prev_proj_stat = *proj_iter;
1554                         ++proj_iter;
1555                         if (proj_iter == (*i)->statistics.end()) {
1556                             for (; sum_iter != sumstats.end(); ++sum_iter) {
1557                                 AddToStats(prev_proj_stat, *sum_iter);
1558                             }
1559                             break;
1560                         }
1561                     }
1562                 }
1563             }
1564         }
1565 
1566 	//Draw graph
1567         wxColour graphColour = wxColour(0,0,0);
1568         int  typePoint = 0;
1569         getTypePoint(typePoint,count);
1570         color_cycle(m_SelectedStatistic, n_command_buttons, graphColour);
1571         DrawGraph2(dc, sumstats, graphColour, typePoint, m_SelectedStatistic);
1572 //        sumstats.clear();
1573 	//Draw marker
1574 		DrawMarker(dc);
1575 		break;
1576 		}
1577 	default:{
1578 		m_ModeViewStatistic = mode_all_separate;
1579 		break;
1580 		}
1581 	}
1582     if (m_Space_for_scrollbar) {
1583         dc.SetPen(wxPen(m_pen_MainColour , 1 , wxSOLID));
1584         dc.DrawLine(w0 - m_Space_for_scrollbar - x0 - 1, y0, w0 - m_Space_for_scrollbar - x0 - 1, y0 + h0);
1585     }
1586 }
1587 //=================================================================
OnPaint(wxPaintEvent & WXUNUSED (event))1588 void CPaintStatistics::OnPaint(wxPaintEvent& WXUNUSED(event)) {
1589 #if USE_MEMORYDC
1590 	wxPaintDC pdc(this);
1591 	wxMemoryDC mdc;
1592 #else
1593     wxPaintDC mdc(this);
1594     m_full_repaint=true;
1595 #endif
1596 	wxCoord width = 0, height = 0;
1597 	GetClientSize(&width, &height);
1598 	if (m_full_repaint){
1599 		if (!m_GraphZoomStart){
1600 			ClearXY();
1601 			ClearLegendXY();
1602 
1603 			m_main_X_start = 0.0;
1604 			if (width > 0) m_main_X_end = double(width); else m_main_X_end = 0.0;
1605 			m_main_Y_start = 0.0;
1606 			if (height > 0) m_main_Y_end = double(height); else m_main_Y_end = 0.0;
1607 
1608 			if (width < 1) width = 1;
1609 			if (height < 1) height = 1;
1610 #if USE_MEMORYDC
1611 			m_dc_bmp.Create(width, height);
1612 			mdc.SelectObject(m_dc_bmp);
1613 #endif
1614 			DrawAll(mdc);
1615 			m_bmp_OK = true;
1616 			m_full_repaint = false;
1617 		}else if(m_bmp_OK){
1618 #if USE_MEMORYDC
1619 			mdc.SelectObject(m_dc_bmp);
1620 #endif
1621 		}
1622 	}else{
1623 		if (m_bmp_OK){
1624 #if USE_MEMORYDC
1625 			mdc.SelectObject(m_dc_bmp);
1626 #endif
1627 			if (m_GraphZoomStart && (width == m_dc_bmp.GetWidth()) &&(height == m_dc_bmp.GetHeight())){
1628 
1629 				mdc.SetPen(wxPen(m_pen_ZoomRectColour , 1 , wxSOLID));
1630 				mdc.SetBrush(wxBrush(m_brush_ZoomRectColour , wxSOLID));
1631 				mdc.SetLogicalFunction(wxXOR);
1632 
1633 				wxCoord x0 = 0;
1634 				wxCoord y0 = 0;
1635 				wxCoord w0 = 0;
1636 				wxCoord h0 = 0;
1637 
1638 				if (m_GraphZoom_X1 < m_GraphZoom_X2_old) x0 = m_GraphZoom_X1;
1639 				else x0 = m_GraphZoom_X2_old;
1640 				if (m_GraphZoom_Y1 < m_GraphZoom_Y2_old) y0 = m_GraphZoom_Y1;
1641 				else y0 = m_GraphZoom_Y2_old;
1642 				w0 = m_GraphZoom_X2_old - m_GraphZoom_X1;
1643 				h0 = m_GraphZoom_Y2_old - m_GraphZoom_Y1;
1644 				if (x0 < 0) x0 = 0;
1645 				if (y0 < 0) y0 = 0;
1646 				if (w0 < 0) w0 = -w0;
1647 				if (h0 < 0) h0 = -h0;
1648 				mdc.DrawRectangle(x0, y0, w0, h0);
1649 
1650 				if (m_GraphZoom_X1 < m_GraphZoom_X2) x0 = m_GraphZoom_X1;
1651 				else x0 = m_GraphZoom_X2;
1652 				if (m_GraphZoom_Y1 < m_GraphZoom_Y2) y0 = m_GraphZoom_Y1;
1653 				else y0 = m_GraphZoom_Y2;
1654 				w0 = m_GraphZoom_X2 - m_GraphZoom_X1;
1655 				h0 = m_GraphZoom_Y2 - m_GraphZoom_Y1;
1656 				if (x0 < 0) x0 = 0;
1657 				if (y0 < 0) y0 = 0;
1658 				if (w0 < 0) w0 = -w0;
1659 				if (h0 < 0) h0 = -h0;
1660 				mdc.DrawRectangle(x0, y0, w0, h0);
1661 
1662 				m_GraphZoom_X2_old = m_GraphZoom_X2;
1663 				m_GraphZoom_Y2_old = m_GraphZoom_Y2;
1664 
1665 				mdc.SetLogicalFunction(wxCOPY);
1666 			}
1667 		}
1668 	}
1669 #if USE_MEMORYDC
1670 	if (m_bmp_OK && (width == m_dc_bmp.GetWidth()) &&(height == m_dc_bmp.GetHeight())){
1671 		pdc.Blit(0, 0, width - m_Space_for_scrollbar, height,& mdc, 0, 0);
1672 	}
1673 	mdc.SelectObject(wxNullBitmap);
1674 #endif
1675 }
1676 
OnLeftMouseDown(wxMouseEvent & event)1677 void CPaintStatistics::OnLeftMouseDown(wxMouseEvent& event) {
1678 // Legend
1679 	if (m_Legend_dY > 0){
1680 		wxClientDC dc (this);
1681 		wxPoint pt(event.GetLogicalPosition(dc));
1682 		if((double(pt.y) > m_Legend_select_Y_start) && (double(pt.y) < m_Legend_select_Y_end) && (double(pt.x) > m_Legend_select_X_start) && (double(pt.x) < m_Legend_select_X_end)){
1683 			int i1 = (int)floor((double(pt.y) - m_Legend_select_Y_start) / m_Legend_dY);
1684 			switch (m_ModeViewStatistic){
1685 			case mode_one_project:
1686 				m_NextProjectStatistic = i1 + m_Legend_Shift_Mode1;
1687 				m_Zoom_Auto = true;
1688 				m_GraphMarker1 = false;
1689 				break;
1690 			case mode_all_separate:
1691 			case mode_all_together:
1692             case mode_sum:
1693 				m_ViewHideProjectStatistic = i1 + m_Legend_Shift_Mode2;
1694 				break;
1695 			}
1696 			m_full_repaint = true;
1697 			Refresh(false);
1698 		    event.Skip();
1699 			return;
1700 		}
1701 	}
1702 // Graph
1703 	switch (m_ModeViewStatistic){
1704 	case mode_one_project:
1705 	case mode_all_together:
1706     case mode_sum:
1707     {
1708 		wxClientDC dc (this);
1709 		wxPoint pt(event.GetLogicalPosition(dc));
1710 		if((double(pt.y) > m_Graph_Y_start) && (double(pt.y) < m_Graph_Y_end) && (double(pt.x) > m_Graph_X_start) && (double(pt.x) < m_Graph_X_end)){
1711 			m_GraphMarker_X1 = m_Ax_CoordToVal * double(pt.x) + m_Bx_CoordToVal;
1712 			m_GraphMarker_Y1 = m_Ay_CoordToVal * double(pt.y) + m_By_CoordToVal;
1713 			m_GraphMarker1 = true;
1714 
1715 			m_GraphZoom_X1 = wxCoord(pt.x);
1716 			m_GraphZoom_Y1 = wxCoord(pt.y);
1717 			m_GraphZoom_X2 = wxCoord(pt.x);
1718 			m_GraphZoom_Y2 = wxCoord(pt.y);
1719 			m_GraphZoom_X2_old = wxCoord(pt.x);
1720 			m_GraphZoom_Y2_old = wxCoord(pt.y);
1721 
1722 			m_GraphZoomStart = true;
1723 		}
1724 		break;
1725 		}
1726 	}
1727     event.Skip();
1728 }
1729 
OnMouseMotion(wxMouseEvent & event)1730 void CPaintStatistics::OnMouseMotion(wxMouseEvent& event) {
1731 	switch (m_ModeViewStatistic){
1732 	case mode_one_project:
1733 	case mode_all_together:
1734     case mode_sum:
1735     {
1736 		if (m_GraphZoomStart){
1737 			if (event.LeftIsDown()){
1738 				wxClientDC cdc (this);
1739 				wxPoint pt(event.GetLogicalPosition(cdc));
1740 				if((double(pt.y) > m_Graph_Y_start) && (double(pt.y) < m_Graph_Y_end) && (double(pt.x) > m_Graph_X_start) && (double(pt.x) < m_Graph_X_end)){
1741 
1742 				m_GraphZoom_X2 = wxCoord(pt.x);
1743 				m_GraphZoom_Y2 = wxCoord(pt.y);
1744 
1745 				m_full_repaint = false;
1746 				Refresh(false);
1747 				}
1748 			}else{
1749 				m_GraphZoomStart = false;
1750 
1751 				m_full_repaint = true;
1752 				Refresh(false);
1753 			}
1754 		}else if (m_GraphMoveStart){
1755 			if (event.RightIsDown()){
1756 				wxClientDC cdc (this);
1757 				wxPoint pt(event.GetLogicalPosition(cdc));
1758 				if((double(pt.y) > m_Graph_Y_start) && (double(pt.y) < m_Graph_Y_end) && (double(pt.x) > m_Graph_X_start) && (double(pt.x) < m_Graph_X_end)){
1759 
1760 					m_GraphMove_X2 = wxCoord(pt.x);
1761 					m_GraphMove_Y2 = wxCoord(pt.y);
1762 
1763 					double X1 = m_Ax_CoordToVal * double(m_GraphMove_X1 - m_GraphMove_X2);
1764 					double Y1 = m_Ay_CoordToVal * double(m_GraphMove_Y1 - m_GraphMove_Y2);
1765 
1766 					if ( (X1 != 0) || (Y1 != 0)){
1767 						m_GraphMove_X1 = m_GraphMove_X2;
1768 						m_GraphMove_Y1 = m_GraphMove_Y2;
1769 
1770 						m_Zoom_min_val_X = m_Zoom_min_val_X + X1;
1771 						m_Zoom_max_val_X = m_Zoom_max_val_X + X1;
1772 						m_Zoom_min_val_Y = m_Zoom_min_val_Y + Y1;
1773 						m_Zoom_max_val_Y = m_Zoom_max_val_Y + Y1;
1774 
1775 						m_GraphMoveGo = true;
1776 						m_Zoom_Auto = false;
1777 						m_full_repaint = true;
1778 						Refresh(false);
1779 					}
1780 
1781 				}
1782 			}else{
1783 				m_GraphMoveStart = false;
1784 				m_GraphMoveGo = false;
1785 
1786 				m_full_repaint = true;
1787 				Refresh(false);
1788 			}
1789 		}
1790 		break;
1791 		}
1792 	}
1793     event.Skip();
1794 }
OnLeftMouseUp(wxMouseEvent & event)1795 void CPaintStatistics::OnLeftMouseUp(wxMouseEvent& event) {
1796 	switch (m_ModeViewStatistic){
1797 	case mode_one_project:
1798 	case mode_all_together:
1799     case mode_sum:
1800     {
1801 		if (m_GraphZoomStart){
1802 			if ((abs(int(m_GraphZoom_X1 - m_GraphZoom_X2)) > 2) && (abs(int(m_GraphZoom_Y1 - m_GraphZoom_Y2)) > 2)){
1803 				double X1 = m_Ax_CoordToVal * double(m_GraphZoom_X1) + m_Bx_CoordToVal;
1804 				double Y1 = m_Ay_CoordToVal * double(m_GraphZoom_Y1) + m_By_CoordToVal;
1805 				double X2 = m_Ax_CoordToVal * double(m_GraphZoom_X2) + m_Bx_CoordToVal;
1806 				double Y2 = m_Ay_CoordToVal * double(m_GraphZoom_Y2) + m_By_CoordToVal;
1807 
1808 				if (X1 > X2){
1809 					m_Zoom_max_val_X = X1;
1810 					m_Zoom_min_val_X = X2;
1811 				}else{
1812 					m_Zoom_min_val_X = X1;
1813 					m_Zoom_max_val_X = X2;
1814 				}
1815 				if (Y1 > Y2){
1816 					m_Zoom_max_val_Y = Y1;
1817 					m_Zoom_min_val_Y = Y2;
1818 				}else{
1819 					m_Zoom_min_val_Y = Y1;
1820 					m_Zoom_max_val_Y = Y2;
1821 				}
1822 				m_GraphMarker1 = false;
1823 				m_Zoom_Auto = false;
1824 			}
1825 			m_GraphZoomStart = false;
1826 			m_full_repaint = true;
1827 			Refresh(false);
1828 		}
1829 		break;
1830 		}
1831 	}
1832 	event.Skip();
1833 }
OnRightMouseDown(wxMouseEvent & event)1834 void CPaintStatistics::OnRightMouseDown(wxMouseEvent& event) {
1835 	switch (m_ModeViewStatistic){
1836 	case mode_one_project:
1837 	case mode_all_together:
1838     case mode_sum:
1839     {
1840 		if (m_GraphZoomStart){       //???
1841 			m_GraphZoomStart = false;
1842 			m_GraphMarker1 = false;
1843 			m_full_repaint = true;
1844 			Refresh(false);
1845 		}else{
1846 			wxClientDC dc (this);
1847 			wxPoint pt(event.GetLogicalPosition(dc));
1848 			if((double(pt.y) > m_Graph_Y_start) && (double(pt.y) < m_Graph_Y_end) && (double(pt.x) > m_Graph_X_start) && (double(pt.x) < m_Graph_X_end)){
1849 				m_GraphMove_X1 = wxCoord(pt.x);
1850 				m_GraphMove_Y1 = wxCoord(pt.y);
1851 
1852 				m_GraphMoveStart = true;
1853 				m_GraphMoveGo = false;
1854 			}
1855 		}
1856 		break;
1857 		}
1858 	}
1859     event.Skip();
1860 }
OnRightMouseUp(wxMouseEvent & event)1861 void CPaintStatistics::OnRightMouseUp(wxMouseEvent& event) {
1862 	if (m_GraphMoveGo){
1863 		m_GraphMoveStart = false;
1864 		m_GraphMoveGo = false;
1865 	}else if (m_GraphMarker1){
1866 		m_GraphMarker1 = false;
1867 		m_full_repaint = true;
1868 		Refresh(false);
1869 	}else if (!m_Zoom_Auto){
1870 		m_Zoom_Auto = true;
1871 		m_full_repaint = true;
1872 		Refresh(false);
1873 	}
1874 	event.Skip();
1875 }
OnMouseLeaveWindows(wxMouseEvent & event)1876 void CPaintStatistics::OnMouseLeaveWindows(wxMouseEvent& event) {
1877 	if (m_GraphZoomStart){
1878 		m_GraphMarker1 = false;
1879 		m_GraphZoomStart = false;
1880 		m_full_repaint = true;
1881 		Refresh(false);
1882 	}
1883 	if (m_GraphMoveStart || m_GraphMoveGo){
1884 		m_GraphMoveStart = false;
1885 		m_GraphMoveGo = false;
1886 	}
1887 	event.Skip();
1888 }
1889 
OnLegendScroll(wxScrollEvent & event)1890 void CPaintStatistics::OnLegendScroll(wxScrollEvent& event) {
1891     m_full_repaint = true;
1892     Refresh(false);
1893     event.Skip();
1894 }
1895 
OnSize(wxSizeEvent & event)1896 void CPaintStatistics::OnSize(wxSizeEvent& event) {
1897 	m_full_repaint = true;
1898     Refresh(false);
1899 #ifdef __WXMAC__
1900 	ResizeMacAccessibilitySupport();
1901 #endif
1902     event.Skip();
1903 }
1904 
IMPLEMENT_DYNAMIC_CLASS(CViewStatistics,CBOINCBaseView)1905 IMPLEMENT_DYNAMIC_CLASS(CViewStatistics, CBOINCBaseView)
1906 
1907 BEGIN_EVENT_TABLE (CViewStatistics, CBOINCBaseView)
1908     EVT_BUTTON(ID_TASK_STATISTICS_USERTOTAL, CViewStatistics::OnStatisticsUserTotal)
1909     EVT_BUTTON(ID_TASK_STATISTICS_USERAVERAGE, CViewStatistics::OnStatisticsUserAverage)
1910     EVT_BUTTON(ID_TASK_STATISTICS_HOSTTOTAL, CViewStatistics::OnStatisticsHostTotal)
1911     EVT_BUTTON(ID_TASK_STATISTICS_HOSTAVERAGE, CViewStatistics::OnStatisticsHostAverage)
1912     EVT_BUTTON(ID_TASK_STATISTICS_MODEVIEWALLSEPARATE, CViewStatistics::OnStatisticsModeViewAllSeparate)
1913     EVT_BUTTON(ID_TASK_STATISTICS_MODEVIEWONEPROJECT, CViewStatistics::OnStatisticsModeViewOneProject)
1914     EVT_BUTTON(ID_TASK_STATISTICS_MODEVIEWALLTOGETHER, CViewStatistics::OnStatisticsModeViewAllTogether)
1915     EVT_BUTTON(ID_TASK_STATISTICS_MODEVIEWSUM, CViewStatistics::OnStatisticsModeViewSum)
1916     EVT_BUTTON(ID_TASK_STATISTICS_NEXTPROJECT, CViewStatistics::OnStatisticsNextProject)
1917     EVT_BUTTON(ID_TASK_STATISTICS_PREVPROJECT, CViewStatistics::OnStatisticsPrevProject)
1918     EVT_BUTTON(ID_TASK_STATISTICS_HIDEPROJLIST, CViewStatistics::OnShowHideProjectList)
1919 END_EVENT_TABLE ()
1920 
1921 CViewStatistics::CViewStatistics()
1922 {}
1923 
CViewStatistics(wxNotebook * pNotebook)1924 CViewStatistics::CViewStatistics(wxNotebook* pNotebook) :
1925     CBOINCBaseView(pNotebook)
1926 {
1927 	CTaskItemGroup* pGroup = NULL;
1928 	CTaskItem*      pItem = NULL;
1929 
1930     //
1931     // Setup View
1932     //
1933     wxFlexGridSizer* itemFlexGridSizer = new wxFlexGridSizer(2, 0, 0);
1934     wxASSERT(itemFlexGridSizer);
1935 
1936     itemFlexGridSizer->AddGrowableRow(0);
1937     itemFlexGridSizer->AddGrowableCol(1);
1938 
1939     m_pTaskPane = new CBOINCTaskCtrl(this, ID_TASK_STATISTICSVIEW, DEFAULT_TASK_FLAGS);
1940     wxASSERT(m_pTaskPane);
1941 
1942 	m_PaintStatistics = new CPaintStatistics(this, ID_LIST_STATISTICSVIEW, wxDefaultPosition, wxSize(-1, -1), 0);
1943 	wxASSERT(m_PaintStatistics);
1944 
1945     itemFlexGridSizer->Add(m_pTaskPane, 1, wxGROW|wxALL, 1);
1946     itemFlexGridSizer->Add(m_PaintStatistics, 1, wxGROW|wxALL, 1);
1947 
1948     SetSizer(itemFlexGridSizer);
1949 
1950     Layout();
1951 
1952 	pGroup = new CTaskItemGroup( _("Commands") );
1953 	m_TaskGroups.push_back( pGroup );
1954 
1955 	pItem = new CTaskItem(
1956         _("Show user total"),
1957         _("Show total credit for user"),
1958         ID_TASK_STATISTICS_USERTOTAL
1959     );
1960     pGroup->m_Tasks.push_back( pItem );
1961 
1962 	pItem = new CTaskItem(
1963         _("Show user average"),
1964         _("Show average credit for user"),
1965         ID_TASK_STATISTICS_USERAVERAGE
1966     );
1967     pGroup->m_Tasks.push_back( pItem );
1968 
1969 	pItem = new CTaskItem(
1970         _("Show host total"),
1971         _("Show total credit for host"),
1972         ID_TASK_STATISTICS_HOSTTOTAL
1973     );
1974     pGroup->m_Tasks.push_back( pItem );
1975 
1976 	pItem = new CTaskItem(
1977         _("Show host average"),
1978         _("Show average credit for host"),
1979         ID_TASK_STATISTICS_HOSTAVERAGE
1980     );
1981     pGroup->m_Tasks.push_back( pItem );
1982 
1983 	pGroup = new CTaskItemGroup( _("Project") );
1984 	m_TaskGroups.push_back( pGroup );
1985 
1986 	pItem = new CTaskItem(
1987         _("< &Previous project"),
1988         _("Show chart for previous project"),
1989         ID_TASK_STATISTICS_PREVPROJECT
1990     );
1991     pGroup->m_Tasks.push_back( pItem );
1992 	pItem = new CTaskItem(
1993         _("&Next project >"),
1994         _("Show chart for next project"),
1995         ID_TASK_STATISTICS_NEXTPROJECT
1996     );
1997     pGroup->m_Tasks.push_back( pItem );
1998 
1999 	pItem = new CTaskItem(
2000         _("Hide project list"),
2001         _("Use entire area for graphs"),
2002         ID_TASK_STATISTICS_HIDEPROJLIST
2003     );
2004     pGroup->m_Tasks.push_back( pItem );
2005 
2006 	pGroup = new CTaskItemGroup( _("Mode view") );
2007 	m_TaskGroups.push_back( pGroup );
2008 
2009 	pItem = new CTaskItem(
2010         _("One project"),
2011         _("Show one chart with selected project"),
2012         ID_TASK_STATISTICS_MODEVIEWONEPROJECT
2013     );
2014     pGroup->m_Tasks.push_back( pItem );
2015 
2016 	pItem = new CTaskItem(
2017         _("All projects (separate)"),
2018         _("Show all projects, one chart per project"),
2019         ID_TASK_STATISTICS_MODEVIEWALLSEPARATE
2020     );
2021     pGroup->m_Tasks.push_back( pItem );
2022 
2023 	pItem = new CTaskItem(
2024         _("All projects (together)"),
2025         _("Show one chart with all projects"),
2026         ID_TASK_STATISTICS_MODEVIEWALLTOGETHER
2027     );
2028     pGroup->m_Tasks.push_back( pItem );
2029 
2030 	pItem = new CTaskItem(
2031         _("All projects (sum)"),
2032         _("Show one chart with sum of projects"),
2033         ID_TASK_STATISTICS_MODEVIEWSUM
2034     );
2035     pGroup->m_Tasks.push_back( pItem );
2036 
2037     // Create Task Pane Items
2038     m_pTaskPane->UpdateControls();
2039 
2040     UpdateSelection();
2041 }
2042 
~CViewStatistics()2043 CViewStatistics::~CViewStatistics() {
2044     EmptyTasks();
2045 }
2046 
GetViewName()2047 wxString& CViewStatistics::GetViewName() {
2048     static wxString strViewName(wxT("Statistics"));
2049     return strViewName;
2050 }
2051 
GetViewDisplayName()2052 wxString& CViewStatistics::GetViewDisplayName() {
2053     static wxString strViewName(_("Statistics"));
2054     return strViewName;
2055 }
2056 
GetViewIcon()2057 const char** CViewStatistics::GetViewIcon() {
2058     return stats_xpm;
2059 }
2060 
GetViewRefreshRate()2061 int CViewStatistics::GetViewRefreshRate() {
2062     return 60;
2063 }
2064 
GetViewCurrentViewPage()2065 int CViewStatistics::GetViewCurrentViewPage() {
2066     return VW_STAT;
2067 }
2068 
OnStatisticsUserTotal(wxCommandEvent & WXUNUSED (event))2069 void CViewStatistics::OnStatisticsUserTotal( wxCommandEvent& WXUNUSED(event) ) {
2070     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsUserTotal - Function Begin"));
2071 
2072     CAdvancedFrame* pFrame = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
2073 
2074     wxASSERT(pFrame);
2075     wxASSERT(wxDynamicCast(pFrame, CAdvancedFrame));
2076 
2077 	m_PaintStatistics->m_SelectedStatistic = show_user_total;
2078 	m_PaintStatistics->m_Zoom_Auto = true;
2079 	m_PaintStatistics->m_GraphMarker1 = false;
2080 	m_PaintStatistics->m_full_repaint = true;
2081 
2082     UpdateSelection();
2083     pFrame->FireRefreshView();
2084 
2085     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsUserTotal - Function End"));
2086 }
2087 
OnStatisticsUserAverage(wxCommandEvent & WXUNUSED (event))2088 void CViewStatistics::OnStatisticsUserAverage( wxCommandEvent& WXUNUSED(event) ) {
2089     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsUserAverage - Function Begin"));
2090 
2091     CAdvancedFrame* pFrame      = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
2092 
2093     wxASSERT(pFrame);
2094     wxASSERT(wxDynamicCast(pFrame, CAdvancedFrame));
2095 
2096 	m_PaintStatistics->m_SelectedStatistic = show_user_average;
2097 	m_PaintStatistics->m_Zoom_Auto = true;
2098 	m_PaintStatistics->m_GraphMarker1 = false;
2099 	m_PaintStatistics->m_full_repaint = true;
2100 
2101     UpdateSelection();
2102     pFrame->FireRefreshView();
2103 
2104     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsUserAverage - Function End"));
2105 }
2106 
OnStatisticsHostTotal(wxCommandEvent & WXUNUSED (event))2107 void CViewStatistics::OnStatisticsHostTotal( wxCommandEvent& WXUNUSED(event) ) {
2108     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsHostTotal - Function Begin"));
2109 
2110     CAdvancedFrame* pFrame      = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
2111 
2112     wxASSERT(pFrame);
2113     wxASSERT(wxDynamicCast(pFrame, CAdvancedFrame));
2114 
2115 	m_PaintStatistics->m_SelectedStatistic = show_host_total;
2116 	m_PaintStatistics->m_Zoom_Auto = true;
2117 	m_PaintStatistics->m_GraphMarker1 = false;
2118 	m_PaintStatistics->m_full_repaint = true;
2119 
2120     UpdateSelection();
2121     pFrame->FireRefreshView();
2122 
2123     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsHostTotal - Function End"));
2124 }
2125 
2126 
OnStatisticsHostAverage(wxCommandEvent & WXUNUSED (event))2127 void CViewStatistics::OnStatisticsHostAverage( wxCommandEvent& WXUNUSED(event) ) {
2128     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsHostAverage - Function Begin"));
2129 
2130     CAdvancedFrame* pFrame      = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
2131 
2132     wxASSERT(pFrame);
2133     wxASSERT(wxDynamicCast(pFrame, CAdvancedFrame));
2134 
2135 	m_PaintStatistics->m_SelectedStatistic = show_host_average;
2136 	m_PaintStatistics->m_Zoom_Auto = true;
2137 	m_PaintStatistics->m_GraphMarker1 = false;
2138 	m_PaintStatistics->m_full_repaint = true;
2139 
2140     UpdateSelection();
2141     pFrame->FireRefreshView();
2142 
2143     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsHostAverage - Function End"));
2144 }
2145 
OnStatisticsModeViewAllSeparate(wxCommandEvent & WXUNUSED (event))2146 void CViewStatistics::OnStatisticsModeViewAllSeparate( wxCommandEvent& WXUNUSED(event) ) {
2147     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsModeView - Function Begin"));
2148 
2149     CAdvancedFrame* pFrame      = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
2150 
2151     wxASSERT(pFrame);
2152     wxASSERT(wxDynamicCast(pFrame, CAdvancedFrame));
2153 
2154 	m_PaintStatistics->m_ModeViewStatistic = mode_all_separate;
2155 	m_PaintStatistics->m_Zoom_Auto = true;
2156 	m_PaintStatistics->m_GraphMarker1 = false;
2157 	m_PaintStatistics->m_full_repaint = true;
2158 
2159     UpdateSelection();
2160     pFrame->FireRefreshView();
2161 
2162     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsModeView - Function End"));
2163 }
2164 
OnStatisticsModeViewOneProject(wxCommandEvent & WXUNUSED (event))2165 void CViewStatistics::OnStatisticsModeViewOneProject( wxCommandEvent& WXUNUSED(event) ) {
2166     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsModeView - Function Begin"));
2167 
2168     CAdvancedFrame* pFrame      = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
2169 
2170     wxASSERT(pFrame);
2171     wxASSERT(wxDynamicCast(pFrame, CAdvancedFrame));
2172 
2173 	m_PaintStatistics->m_ModeViewStatistic = mode_one_project;
2174 	m_PaintStatistics->m_Zoom_Auto = true;
2175 	m_PaintStatistics->m_GraphMarker1 = false;
2176 	m_PaintStatistics->m_full_repaint = true;
2177 
2178     UpdateSelection();
2179     pFrame->FireRefreshView();
2180 
2181     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsModeView - Function End"));
2182 }
2183 
OnStatisticsModeViewAllTogether(wxCommandEvent & WXUNUSED (event))2184 void CViewStatistics::OnStatisticsModeViewAllTogether( wxCommandEvent& WXUNUSED(event) ) {
2185     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsModeView - Function Begin"));
2186 
2187     CAdvancedFrame* pFrame      = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
2188 
2189     wxASSERT(pFrame);
2190     wxASSERT(wxDynamicCast(pFrame, CAdvancedFrame));
2191 
2192 	m_PaintStatistics->m_ModeViewStatistic = mode_all_together;
2193 	m_PaintStatistics->m_Zoom_Auto = true;
2194 	m_PaintStatistics->m_GraphMarker1 = false;
2195 	m_PaintStatistics->m_full_repaint = true;
2196 
2197     UpdateSelection();
2198     pFrame->FireRefreshView();
2199 
2200     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsModeView - Function End"));
2201 }
2202 
OnStatisticsModeViewSum(wxCommandEvent & WXUNUSED (event))2203 void CViewStatistics::OnStatisticsModeViewSum( wxCommandEvent& WXUNUSED(event) ) {
2204     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsModeView - Function Begin"));
2205 
2206     CAdvancedFrame* pFrame      = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
2207 
2208     wxASSERT(pFrame);
2209     wxASSERT(wxDynamicCast(pFrame, CAdvancedFrame));
2210 
2211 	m_PaintStatistics->m_ModeViewStatistic = mode_sum;
2212 	m_PaintStatistics->m_Zoom_Auto = true;
2213 	m_PaintStatistics->m_GraphMarker1 = false;
2214 	m_PaintStatistics->m_full_repaint = true;
2215 
2216     UpdateSelection();
2217     pFrame->FireRefreshView();
2218 
2219     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsModeView - Function End"));
2220 }
2221 
OnStatisticsNextProject(wxCommandEvent & WXUNUSED (event))2222 void CViewStatistics::OnStatisticsNextProject( wxCommandEvent& WXUNUSED(event) ) {
2223     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsNextProject - Function Begin"));
2224 
2225     CAdvancedFrame* pFrame      = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
2226 
2227     wxASSERT(pFrame);
2228     wxASSERT(wxDynamicCast(pFrame, CAdvancedFrame));
2229 
2230 	if (m_PaintStatistics->m_ModeViewStatistic == mode_one_project) m_PaintStatistics->m_NextProjectStatistic++;
2231 	m_PaintStatistics->m_Zoom_Auto = true;
2232 	m_PaintStatistics->m_GraphMarker1 = false;
2233 	m_PaintStatistics->m_full_repaint = true;
2234 	if (m_PaintStatistics->m_ModeViewStatistic == mode_all_separate) m_PaintStatistics->m_Legend_Shift_Mode2++;
2235 	if (m_PaintStatistics->m_ModeViewStatistic == mode_all_together) m_PaintStatistics->m_Legend_Shift_Mode2++;
2236 	if (m_PaintStatistics->m_ModeViewStatistic == mode_sum) m_PaintStatistics->m_Legend_Shift_Mode2++;
2237 
2238     UpdateSelection();
2239     pFrame->FireRefreshView();
2240 
2241     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsNextProject - Function End"));
2242 }
2243 
OnStatisticsPrevProject(wxCommandEvent & WXUNUSED (event))2244 void CViewStatistics::OnStatisticsPrevProject( wxCommandEvent& WXUNUSED(event) ) {
2245     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsPrevProject - Function Begin"));
2246 
2247     CAdvancedFrame* pFrame      = wxDynamicCast(GetParent()->GetParent()->GetParent(), CAdvancedFrame);
2248 
2249     wxASSERT(pFrame);
2250     wxASSERT(wxDynamicCast(pFrame, CAdvancedFrame));
2251 
2252 	if (m_PaintStatistics->m_ModeViewStatistic == mode_one_project) m_PaintStatistics->m_NextProjectStatistic--;
2253 	m_PaintStatistics->m_Zoom_Auto = true;
2254 	m_PaintStatistics->m_GraphMarker1 = false;
2255 	m_PaintStatistics->m_full_repaint = true;
2256 	if (m_PaintStatistics->m_ModeViewStatistic == mode_all_separate) m_PaintStatistics->m_Legend_Shift_Mode2--;
2257 	if (m_PaintStatistics->m_ModeViewStatistic == mode_all_together) m_PaintStatistics->m_Legend_Shift_Mode2--;
2258 	if (m_PaintStatistics->m_ModeViewStatistic == mode_sum) m_PaintStatistics->m_Legend_Shift_Mode2--;
2259 
2260     UpdateSelection();
2261     pFrame->FireRefreshView();
2262 
2263     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnStatisticsPrevProject - Function End"));
2264 }
2265 
OnShowHideProjectList(wxCommandEvent & WXUNUSED (event))2266 void CViewStatistics::OnShowHideProjectList( wxCommandEvent& WXUNUSED(event) ) {
2267     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnShowHideProjectList - Function Begin"));
2268 
2269 	m_PaintStatistics->m_LegendDraw = !m_PaintStatistics->m_LegendDraw;
2270 	m_PaintStatistics->m_full_repaint = true;
2271 	m_PaintStatistics->Refresh(false);
2272     UpdateSelection();
2273 
2274     wxLogTrace(wxT("Function Start/End"), wxT("CViewStatistics::OnShowHideProjectList - Function End"));
2275 }
2276 
OnSaveState(wxConfigBase * pConfig)2277 bool CViewStatistics::OnSaveState(wxConfigBase* pConfig) {
2278     bool bReturnValue = true;
2279 
2280     wxASSERT(pConfig);
2281     wxASSERT(m_pTaskPane);
2282 
2283     if (!m_pTaskPane->OnSaveState(pConfig)) {
2284         bReturnValue = false;
2285     }
2286 //--
2287     wxString    strBaseConfigLocation = wxEmptyString;
2288     strBaseConfigLocation = wxT("/Statistics");
2289 	pConfig->SetPath(strBaseConfigLocation);
2290 	pConfig->Write(wxT("ModeViewStatistic"), m_PaintStatistics->m_ModeViewStatistic);
2291 	pConfig->Write(wxT("SelectedStatistic"), m_PaintStatistics->m_SelectedStatistic);
2292 	pConfig->Write(wxT("NextProjectStatistic"), m_PaintStatistics->m_NextProjectStatistic);
2293 	strBaseConfigLocation = wxT("/Statistics/ViewAll");
2294 	pConfig->DeleteGroup(strBaseConfigLocation);
2295 	pConfig->SetPath(strBaseConfigLocation);
2296 	int count = -1;
2297 	for (std::set<wxString>::const_iterator i_s = m_PaintStatistics->m_HideProjectStatistic.begin(); i_s != m_PaintStatistics->m_HideProjectStatistic.end(); ++i_s) {
2298 		++count;
2299 		pConfig->Write(wxString::Format(wxT("%d"), count), (*i_s));
2300 	}
2301 //--
2302     return bReturnValue;
2303 }
2304 
OnRestoreState(wxConfigBase * pConfig)2305 bool CViewStatistics::OnRestoreState(wxConfigBase* pConfig) {
2306 	wxASSERT(pConfig);
2307     wxASSERT(m_pTaskPane);
2308 
2309     if (!m_pTaskPane->OnRestoreState(pConfig)) {
2310         return false;
2311     }
2312 //--
2313     int     iTempValue = 0;
2314     wxString    strBaseConfigLocation = wxEmptyString;
2315     strBaseConfigLocation = wxT("/Statistics");
2316 	pConfig->SetPath(strBaseConfigLocation);
2317 
2318 	m_PaintStatistics->m_ModeViewStatistic = mode_all_separate;
2319 	pConfig->Read(wxT("ModeViewStatistic"), &iTempValue, -1);
2320 	if ((iTempValue >= mode_one_project) && (iTempValue <= mode_sum))m_PaintStatistics->m_ModeViewStatistic = iTempValue;
2321 
2322 	m_PaintStatistics->m_SelectedStatistic = show_user_total;
2323 	pConfig->Read(wxT("SelectedStatistic"), &iTempValue, -1);
2324 	if ((iTempValue >= show_user_total) && (iTempValue <= show_host_average))m_PaintStatistics->m_SelectedStatistic = iTempValue;
2325 
2326 	m_PaintStatistics->m_NextProjectStatistic = 0;
2327 	pConfig->Read(wxT("NextProjectStatistic"), &iTempValue, -1);
2328 	if (iTempValue >= 0)m_PaintStatistics->m_NextProjectStatistic = iTempValue;
2329 // -- Hide View All projects
2330 	strBaseConfigLocation = wxT("/Statistics/ViewAll");
2331 	pConfig->SetPath(strBaseConfigLocation);
2332 	wxString tmpstr1;
2333 	if (!(m_PaintStatistics->m_HideProjectStatistic.empty())) m_PaintStatistics->m_HideProjectStatistic.clear();
2334 	for (int count = 0; count < 1000; ++count) {
2335 		pConfig->Read(wxString::Format(wxT("%d"), count), &tmpstr1, wxT(""));
2336 		if (tmpstr1 == wxEmptyString){
2337 			break;
2338 		}else{
2339 			m_PaintStatistics->m_HideProjectStatistic.insert(tmpstr1);
2340 		}
2341 	}
2342 
2343     UpdateSelection();
2344     return true;
2345 }
2346 
OnListRender(wxTimerEvent & WXUNUSED (event))2347 void CViewStatistics::OnListRender( wxTimerEvent& WXUNUSED(event) ) {
2348 	if (wxGetApp().GetDocument()->GetStatisticsCount()) {
2349 		m_PaintStatistics->m_full_repaint = true;
2350 		m_PaintStatistics->Refresh(false);
2351 	}
2352 }
2353 
UpdateSelection()2354 void CViewStatistics::UpdateSelection() {
2355     CTaskItemGroup*     pGroup = m_TaskGroups[0];
2356 
2357     CBOINCBaseView::PreUpdateSelection();
2358 
2359     pGroup->m_Tasks[show_user_total]->m_pButton->Enable(m_PaintStatistics->m_SelectedStatistic != show_user_total);
2360     pGroup->m_Tasks[show_user_average]->m_pButton->Enable(m_PaintStatistics->m_SelectedStatistic != show_user_average);
2361     pGroup->m_Tasks[show_host_total]->m_pButton->Enable(m_PaintStatistics->m_SelectedStatistic != show_host_total);
2362     pGroup->m_Tasks[show_host_average]->m_pButton->Enable(m_PaintStatistics->m_SelectedStatistic != show_host_average);
2363 
2364     pGroup = m_TaskGroups[1];
2365     pGroup->m_Tasks[previous_project]->m_pButton->Enable(m_PaintStatistics->m_ModeViewStatistic == mode_one_project);
2366     pGroup->m_Tasks[next_project]->m_pButton->Enable(m_PaintStatistics->m_ModeViewStatistic == mode_one_project);
2367 
2368     if (m_PaintStatistics->m_LegendDraw) {
2369         m_pTaskPane->UpdateTask(
2370             pGroup->m_Tasks[show_hide_project_list], _("Hide project list"), _("Use entire area for graphs")
2371         );
2372     } else {
2373         m_pTaskPane->UpdateTask(
2374             pGroup->m_Tasks[show_hide_project_list], _("Show project list"), _("Uses smaller area for graphs")
2375         );
2376     }
2377 
2378     pGroup = m_TaskGroups[2];
2379     pGroup->m_Tasks[mode_one_project]->m_pButton->Enable(m_PaintStatistics->m_ModeViewStatistic != mode_one_project);
2380     pGroup->m_Tasks[mode_all_separate]->m_pButton->Enable(m_PaintStatistics->m_ModeViewStatistic != mode_all_separate);
2381     pGroup->m_Tasks[mode_all_together]->m_pButton->Enable(m_PaintStatistics->m_ModeViewStatistic != mode_all_together);
2382     pGroup->m_Tasks[mode_sum]->m_pButton->Enable(m_PaintStatistics->m_ModeViewStatistic != mode_sum);
2383 
2384     CBOINCBaseView::PostUpdateSelection();
2385 }
2386 
2387