21 colmax = l->GetColumnCount();
22 rowmax = l->GetItemCount();
25 AddPage (wxPORTRAIT, wxPAPER_A4);
28 title = _(
"Timesheet");
30 title = _(
"YATiSh table");
31 SetFont (
"Helvetica",
"B", 12);
32 double titleWidth = GetStringWidth (title) + 6;
33 SetX ( 0.5*(210 - titleWidth) );
35 Cell (titleWidth, 6, title, wxPDF_BORDER_FRAME, 1, wxPDF_ALIGN_CENTER);
49 Cell ( 30, 4, _(
"Summary") );
50 SetFont (
"Times",
"", 10);
51 Cell ( 40, 4, _(
"Number of records:") );
52 wxString info = wxString::Format (
"%d",
rowmax);
54 Cell (30, 4, info, wxPDF_BORDER_NONE, 1);
57 Cell ( 40, 4, _(
"Number of fields:") );
58 info.Printf (
"%d",
colmax);
59 Cell (30, 4, info, wxPDF_BORDER_NONE, 1);
63 if ( filter.IsEmpty() ) {
64 Cell ( 40, 4, _(
"SQL filter:") );
65 SetFont (
"Times",
"I");
66 Cell (30, 4, _(
"none"), wxPDF_BORDER_NONE, 1);
67 SetFont (
"Times",
"");
69 Cell ( 40, 4, _(
"SQL filter:") );
71 Cell (0, 4, filter.Trim (
false), wxPDF_BORDER_NONE, 1);
76 Cell (40, 4, _(
"Date range:") );
78 Cell (0, 4, info, wxPDF_BORDER_NONE, 1);
80 SetFillColour (*wxYELLOW);
81 Cell (40, 4, _(
"Total duration (hours):"), wxPDF_BORDER_NONE, 0, wxPDF_ALIGN_LEFT, 1);
84 info.Printf (
"%d", ts.GetHours() );
85 Cell (GetStringWidth (info) + 2, 4, info, wxPDF_BORDER_NONE, 1, wxPDF_ALIGN_LEFT, 1);
93 unsigned long hours, minutes;
94 Map4pie projects, clients, tasks, tools;
95 for (
int row = 0; row <
rowmax; row++) {
96 timeslot = lst->GetItemText (row, 1);
97 if (row == 0 && timeslot.IsEmpty())
continue;
98 wxStringTokenizer tkz (timeslot,
":");
99 tkz.GetNextToken().ToULong (&hours);
100 tkz.GetNextToken().ToULong (&minutes);
102 projects[lst->GetItemText (row, 2) .ToStdString()] += minutes;
103 clients [lst->GetItemText (row, 3) .ToStdString()] += minutes;
104 tasks [lst->GetItemText (row, 4) .ToStdString()] += minutes;
105 tools [lst->GetItemText (row, 5) .ToStdString()] += minutes;
113 SetFont (
"Helvetica",
"B", 12);
114 Cell (30, 6, _(
"Charts"), wxPDF_BORDER_NONE, 1);
115 double x0 = GetX() + 20, y0 = GetY();
117 wxColour (127, 201, 127),
118 wxColour (190, 174, 212),
119 wxColour (253, 192, 134),
120 wxColour (255, 255, 153),
121 wxColour ( 56, 108, 176),
122 wxColour (240, 2, 127)
133 SetFont (
"Helvetica",
"B", 12);
134 Cell (30, 6, _(
"Listing"), wxBORDER_NONE, 1);
135 double columnWidth = 20, offset = 0.5*(210 - columnWidth*
colmax);
139 SetFont (
"Times",
"B", 9);
141 for (col = 0; col <
colmax; col++) {
142 lst->GetColumn (col, item);
143 Cell (columnWidth, 6, item.GetText(), wxPDF_BORDER_FRAME, 0, wxPDF_ALIGN_CENTER);
146 SetFont (
"Times",
"", 6);
147 for (row = 0; row <
rowmax; row++) {
149 for (col = 0; col <
colmax; col++) {
150 Cell (columnWidth, 3, lst->GetItemText (row, col), wxPDF_BORDER_LEFT|wxPDF_BORDER_RIGHT);
155 Cell (columnWidth*
colmax, 0, wxEmptyString, wxPDF_BORDER_TOP);
160 SetFont (
"Helvetica",
"B", 12);
165 wxLogMessage (_(
"Logo file not found... thus not drawn.\n"
166 "Check out your PDF settings (Ctrl-S).") );
167 Cell (15, 10, wxEmptyString);
171 SetFont (
"Helvetica",
"I", 12);
175 Cell (0, 10, wxDateTime::Now().FormatDate(), wxPDF_BORDER_BOTTOM, 1, wxPDF_ALIGN_RIGHT);
182 SetFont (
"Helvetica",
"", 10);
183 Cell (0, 10, wxString::Format (
"%d/{nb}", PageNo() ),
184 wxPDF_BORDER_NONE, 0, wxPDF_ALIGN_CENTER);
190 SetFont (
"Helvetica",
"", 8);
197 for (
auto element : data) {
198 sum = sum + element.second;
199 labelWidth = GetStringWidth (element.first);
200 if (labelWidth > wLegend) wLegend = labelWidth;
202 double radius = width - 4*margin - hLegend - wLegend;
203 if (radius > height - 2*margin) radius = height - 2*margin;
204 radius = floor (radius/2);
205 double xDiag = xPage + margin + radius;
206 double yDiag = yPage + margin + radius;
210 double angleStart = 0;
213 for (
auto element : data) {
214 angle = (sum != 0) ? floor ( (element.second*360)/sum ) : 0;
216 angleEnd = angleStart + angle;
217 SetFillColour (
colors[color%6] );
218 Sector (xDiag, yDiag, radius, angleStart, angleEnd);
223 if (angleEnd != 360) {
224 Sector (xDiag, yDiag, radius, angleStart - angle, 360);
227 double x1 = xPage + 2*radius + 4*margin;
228 double x2 = x1 + hLegend + margin;
229 double y1 = yDiag - radius + ( 2*radius - data.size()*(hLegend + margin) )/2;
231 for (
auto element : data) {
232 SetFillColour (
colors[color%6] );
233 Rect (x1, y1, hLegend, hLegend, wxPDF_STYLE_FILLDRAW);
235 Cell (wLegend, hLegend, element.first);
236 y1 += hLegend + margin;
245 string key, others = _(
"others").ToStdString();
246 while (map.size() > 6) {
248 for (
auto element : map) {
249 if (element.first == others)
continue;
250 if (element.second < mini) {
251 mini = element.second;
256 map.erase ( map.find (key) );
Interacts with yatish tables in a SQLite database.
wxString GetFilter() const
long FilteredTotal(wxTimeSpan &) const
Returns the total duration of currently viewed timeslots (and their count).
wxDateTime GetFirstDay() const
wxDateTime GetLastDay() const
void Footer()
PDF footer (page count).
void Listing(const wxListCtrl *)
Writes a table corresponding to the current state of panel #2 (Ctrl-T).
~yatishPDF()
Writes the PDF document to the file which was given to the constructor.
void Header()
Creates the header of the PDF document, according to user preferences (Ctrl-P).
void NoMoreThan6(Map4pie &)
Modifies its argument map so that there is no more than six records.
yatishPDF(const Settings &, const wxListCtrl *, const yatishDBsqlite &, const wxString &="yatish.pdf")
Prints a title then calls other member functions for the body of the PDF document.
void Charts(const wxListCtrl *)
Draws charts from the timeslot view only (6 columns).
void Summary(const yatishDBsqlite &)
A few pieces of information about the data to be shown by [Charts() and] Listing().
void PieChart(double, double, double, double, const Map4pie &, const wxColour *)
Modified from charting.cpp in the wxPdfDocument samples.
As its names implies: the class holding YATiSh settings.
int rowLimit
...to rowLimit lines.
bool pdfCharts
PDF charts?
wxString companyName_or_logoPath
Either the company name or its logo.
bool motto4pdf
Print the company motto in the PDF header?
wxString companyMotto
Slogan or short description of the purpose.
bool logo4pdf
If True the company name is replaced by its logo in the PDF header.
map< string, unsigned long > Map4pie