OpenCPN Partial API docs
Loading...
Searching...
No Matches
printtable.cpp
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2012 by David S. Register *
3 * Copyright (C) 2012 Pavel Saviankou *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
17 **************************************************************************/
18
25#include <iostream>
26#include <sstream>
27#include <vector>
28#include <algorithm>
29
30#ifdef __WXMSW__
31#include <stdlib.h>
32#include <math.h>
33#include <time.h>
34#include <psapi.h>
35#endif
36
37#ifndef __WXMSW__
38#include <signal.h>
39#include <setjmp.h>
40#endif
41
42#include "gl_headers.h" // Must be included before anything using GL stuff
43
44#ifdef __WXMSW__
45// #include "c:\\Program Files\\visual leak detector\\include\\vld.h"
46#endif
47
48#include <wx/wxprec.h>
49
50#ifndef WX_PRECOMP
51#include <wx/wx.h>
52#endif
53
54#include <wx/print.h>
55#include <wx/printdlg.h>
56#include <wx/artprov.h>
57#include <wx/stdpaths.h>
58#include <wx/intl.h>
59#include <wx/listctrl.h>
60#include <wx/aui/aui.h>
61#include <wx/dialog.h>
62#include <wx/progdlg.h>
63#include <wx/brush.h>
64#include <wx/colour.h>
65#include <wx/tokenzr.h>
66
67#include "printtable.h"
68#include "dychart.h"
69
70using namespace std;
71
72void PrintCell::Init(const wxString& _content, wxDC* _dc, int _width,
73 int _cellpadding, bool _bold_font) {
74 bold_font = _bold_font;
75 dc = _dc;
76 width = _width;
77 cellpadding = _cellpadding;
78 content = _content;
79 page = 1;
80 Adjust();
81};
82
83void PrintCell::Adjust() {
84 wxFont orig_font = dc->GetFont();
85 wxFont _font = orig_font;
86 if (bold_font) {
87 _font.SetWeight(wxFONTWEIGHT_BOLD);
88 }
89 dc->SetFont(_font);
90 vector<wxString> list;
91 list.push_back(wxString());
92 wxString separator = " ";
93 wxStringTokenizer tokenizer(content, separator, wxTOKEN_RET_DELIMS);
94 int words_number = 0;
95 while (tokenizer.HasMoreTokens()) {
96 wxString token = tokenizer.GetNextToken();
97 wxCoord h = 0;
98 wxCoord w = 0;
99 wxString tmp = list[list.size() - 1];
100 wxString tmp2 = tmp + token;
101 words_number++;
102 dc->GetMultiLineTextExtent(tmp2, &w, &h);
103 if ((w < width - 2 * cellpadding) || words_number == 1) {
104 list[list.size() - 1] = tmp2;
105 } else {
106 list.push_back(token);
107 }
108 }
109
110 for (size_t i = 0; i < list.size() - 1; i++) {
111 modified_content = modified_content + list[i] + '\n';
112 }
113 // now add last element without new line
114 modified_content = modified_content + list[list.size() - 1];
115
116 wxCoord h = 0;
117 wxCoord w = 0;
118 dc->GetMultiLineTextExtent(modified_content, &w, &h);
119 SetHeight(h + 8);
120
121 dc->SetFont(orig_font);
122}
123
124Table::Table() {
125 nrows = 0;
126 ncols = 0;
127 data.clear();
128 state = TABLE_SETUP_WIDTHS;
129 create_next_row = true;
130}
131
132Table::~Table() {
133 for (vector<vector<wxString> >::iterator iter = data.begin();
134 iter != data.end(); iter++) {
135 (*iter).clear();
136 }
137 data.clear();
138}
139
140void Table::Start() {
141 if (create_next_row) {
142 NewRow();
143 create_next_row = false;
144 }
145}
146
147void Table::NewRow() {
148 vector<wxString> empty_row;
149 data.push_back(empty_row);
150}
151
152Table& Table::operator<<(const double& cellcontent) {
153 if (state == TABLE_SETUP_WIDTHS) {
154 widths.push_back(cellcontent);
155 return *this;
156 }
157 if (state == TABLE_FILL_DATA) {
158 stringstream sstr;
159 sstr << cellcontent;
160 string _cellcontent = sstr.str();
161 Start();
162 wxString _str(_cellcontent.c_str(), wxConvUTF8);
163 data[data.size() - 1].push_back(_str);
164 }
165 return *this;
166}
167
168Table& Table::operator<<(const wxString& cellcontent) {
169 Start();
170 if (state == TABLE_FILL_HEADER) { // if we start to fill with string data, we
171 // change state automatically.
172 header.push_back(cellcontent);
173 return *this;
174 }
175 if (state == TABLE_SETUP_WIDTHS) { // if we start to fill with string data,
176 // we change state automatically.
177 state = TABLE_FILL_DATA;
178 }
179
180 if ((cellcontent == "\n")) {
181 create_next_row = true;
182 return *this;
183 }
184 data[data.size() - 1].push_back(cellcontent);
185 return *this;
186}
187
188Table& Table::operator<<(const int& cellcontent) {
189 if (state == TABLE_SETUP_WIDTHS) {
190 widths.push_back((double)cellcontent);
191 return *this;
192 }
193 if (state == TABLE_FILL_DATA) {
194 stringstream sstr;
195 sstr << cellcontent;
196 string _cellcontent = sstr.str();
197 Start();
198 wxString _str(_cellcontent.c_str(), wxConvUTF8);
199 data[data.size() - 1].push_back(_str);
200 }
201 return *this;
202}
203
204ostream& operator<<(ostream& out, Table& table) {
205 vector<vector<wxString> >& data = table.GetData();
206
207 for (vector<vector<wxString> >::iterator iter = data.begin();
208 iter != data.end(); iter++) {
209 vector<wxString> row = (*iter);
210 for (vector<wxString>::iterator rowiter = row.begin(); rowiter != row.end();
211 rowiter++) {
212 out << (*rowiter).fn_str() << " ";
213 }
214 out << endl;
215 }
216 return out;
217}
218
219PrintTable::PrintTable() : Table() { rows_heights.clear(); }
220
221void PrintTable::AdjustCells(wxDC* dc, int marginX, int marginY) {
222 number_of_pages = -1;
223 contents.clear();
224 int sum = 0;
225 for (size_t j = 0; j < widths.size(); j++) {
226 sum += widths[j];
227 }
228
229 int w, h;
230 dc->GetSize(&w, &h);
231
232 double scale_x, scale_y;
233 dc->GetUserScale(&scale_x, &scale_y);
234 w /= scale_x;
235 h /= scale_y;
236
237 int width = w - 4 * marginX;
238 header_height = -1;
239 for (size_t j = 0; j < header.size(); j++) {
240 int cell_width = (int)((double)width * widths[j] / sum);
241 PrintCell cell_content;
242 cell_content.Init(header[j], dc, cell_width, 10, true);
243 header_content.push_back(cell_content);
244 header_height = std::max(header_height, cell_content.GetHeight());
245 }
246
247 for (size_t i = 0; i < data.size(); i++) {
248 vector<wxString> row = data[i];
249 vector<PrintCell> contents_row;
250 int max_height = -1;
251 for (size_t j = 0; j < row.size(); j++) {
252 int cell_width = (int)((double)width * widths[j] / sum);
253 PrintCell cell_content;
254 cell_content.Init(row[j], dc, cell_width, 10);
255 contents_row.push_back(cell_content);
256 max_height = std::max(max_height, cell_content.GetHeight());
257 }
258 rows_heights.push_back(max_height);
259 contents.push_back(contents_row);
260 }
261
262 int stripped_page = h - 4 * marginY - header_height;
263 int current_page = 1;
264 int current_y = 0;
265 for (size_t i = 0; i < data.size(); i++) {
266 int row_height = rows_heights[i];
267 if (row_height + current_y > stripped_page) {
268 current_page++;
269 current_y = row_height;
270 } else {
271 current_y += row_height;
272 }
273 int row_page = current_page;
274 vector<PrintCell>& contents_row = contents[i];
275 for (size_t j = 0; j < contents_row.size(); j++) {
276 contents_row[j].SetPage(row_page);
277 contents_row[j].SetHeight(row_height);
278 }
279 number_of_pages = std::max(row_page, number_of_pages);
280 }
281}
This class takes multilined string and modifies it to fit into given width for given device.
Definition printtable.h:106
Represents a NxM simple table with captions.
Definition printtable.h:62
Platform independent GL includes.
OpenCPN Route table printout.