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#ifdef __WXMSW__
43// #include "c:\\Program Files\\visual leak detector\\include\\vld.h"
44#endif
45
46#include <wx/wxprec.h>
47
48#ifndef WX_PRECOMP
49#include <wx/wx.h>
50#endif
51
52#include <wx/print.h>
53#include <wx/printdlg.h>
54#include <wx/artprov.h>
55#include <wx/stdpaths.h>
56#include <wx/intl.h>
57#include <wx/listctrl.h>
58#include <wx/aui/aui.h>
59#include <wx/dialog.h>
60#include <wx/progdlg.h>
61#include <wx/brush.h>
62#include <wx/colour.h>
63#include <wx/tokenzr.h>
64
65#include "printtable.h"
66#include "dychart.h"
67
68using namespace std;
69
70void PrintCell::Init(const wxString& _content, wxDC* _dc, int _width,
71 int _cellpadding, bool _bold_font) {
72 bold_font = _bold_font;
73 dc = _dc;
74 width = _width;
75 cellpadding = _cellpadding;
76 content = _content;
77 page = 1;
78 Adjust();
79};
80
81void PrintCell::Adjust() {
82 wxFont orig_font = dc->GetFont();
83 wxFont _font = orig_font;
84 if (bold_font) {
85 _font.SetWeight(wxFONTWEIGHT_BOLD);
86 }
87 dc->SetFont(_font);
88 vector<wxString> list;
89 list.push_back(wxString());
90 wxString separator = " ";
91 wxStringTokenizer tokenizer(content, separator, wxTOKEN_RET_DELIMS);
92 int words_number = 0;
93 while (tokenizer.HasMoreTokens()) {
94 wxString token = tokenizer.GetNextToken();
95 wxCoord h = 0;
96 wxCoord w = 0;
97 wxString tmp = list[list.size() - 1];
98 wxString tmp2 = tmp + token;
99 words_number++;
100 dc->GetMultiLineTextExtent(tmp2, &w, &h);
101 if ((w < width - 2 * cellpadding) || words_number == 1) {
102 list[list.size() - 1] = tmp2;
103 } else {
104 list.push_back(token);
105 }
106 }
107
108 for (size_t i = 0; i < list.size() - 1; i++) {
109 modified_content = modified_content + list[i] + '\n';
110 }
111 // now add last element without new line
112 modified_content = modified_content + list[list.size() - 1];
113
114 wxCoord h = 0;
115 wxCoord w = 0;
116 dc->GetMultiLineTextExtent(modified_content, &w, &h);
117 SetHeight(h + 8);
118
119 dc->SetFont(orig_font);
120}
121
122Table::Table() {
123 nrows = 0;
124 ncols = 0;
125 data.clear();
126 state = TABLE_SETUP_WIDTHS;
127 create_next_row = true;
128}
129
130Table::~Table() {
131 for (vector<vector<wxString> >::iterator iter = data.begin();
132 iter != data.end(); iter++) {
133 (*iter).clear();
134 }
135 data.clear();
136}
137
138void Table::Start() {
139 if (create_next_row) {
140 NewRow();
141 create_next_row = false;
142 }
143}
144
145void Table::NewRow() {
146 vector<wxString> empty_row;
147 data.push_back(empty_row);
148}
149
150Table& Table::operator<<(const double& cellcontent) {
151 if (state == TABLE_SETUP_WIDTHS) {
152 widths.push_back(cellcontent);
153 return *this;
154 }
155 if (state == TABLE_FILL_DATA) {
156 stringstream sstr;
157 sstr << cellcontent;
158 string _cellcontent = sstr.str();
159 Start();
160 wxString _str(_cellcontent.c_str(), wxConvUTF8);
161 data[data.size() - 1].push_back(_str);
162 }
163 return *this;
164}
165
166Table& Table::operator<<(const wxString& cellcontent) {
167 Start();
168 if (state == TABLE_FILL_HEADER) { // if we start to fill with string data, we
169 // change state automatically.
170 header.push_back(cellcontent);
171 return *this;
172 }
173 if (state == TABLE_SETUP_WIDTHS) { // if we start to fill with string data,
174 // we change state automatically.
175 state = TABLE_FILL_DATA;
176 }
177
178 if ((cellcontent == "\n")) {
179 create_next_row = true;
180 return *this;
181 }
182 data[data.size() - 1].push_back(cellcontent);
183 return *this;
184}
185
186Table& Table::operator<<(const int& cellcontent) {
187 if (state == TABLE_SETUP_WIDTHS) {
188 widths.push_back((double)cellcontent);
189 return *this;
190 }
191 if (state == TABLE_FILL_DATA) {
192 stringstream sstr;
193 sstr << cellcontent;
194 string _cellcontent = sstr.str();
195 Start();
196 wxString _str(_cellcontent.c_str(), wxConvUTF8);
197 data[data.size() - 1].push_back(_str);
198 }
199 return *this;
200}
201
202ostream& operator<<(ostream& out, Table& table) {
203 vector<vector<wxString> >& data = table.GetData();
204
205 for (vector<vector<wxString> >::iterator iter = data.begin();
206 iter != data.end(); iter++) {
207 vector<wxString> row = (*iter);
208 for (vector<wxString>::iterator rowiter = row.begin(); rowiter != row.end();
209 rowiter++) {
210 out << (*rowiter).fn_str() << " ";
211 }
212 out << endl;
213 }
214 return out;
215}
216
217PrintTable::PrintTable() : Table() { rows_heights.clear(); }
218
219void PrintTable::AdjustCells(wxDC* dc, int marginX, int marginY) {
220 number_of_pages = -1;
221 contents.clear();
222 int sum = 0;
223 for (size_t j = 0; j < widths.size(); j++) {
224 sum += widths[j];
225 }
226
227 int w, h;
228 dc->GetSize(&w, &h);
229
230 double scale_x, scale_y;
231 dc->GetUserScale(&scale_x, &scale_y);
232 w /= scale_x;
233 h /= scale_y;
234
235 int width = w - 4 * marginX;
236 header_height = -1;
237 for (size_t j = 0; j < header.size(); j++) {
238 int cell_width = (int)((double)width * widths[j] / sum);
239 PrintCell cell_content;
240 cell_content.Init(header[j], dc, cell_width, 10, true);
241 header_content.push_back(cell_content);
242 header_height = std::max(header_height, cell_content.GetHeight());
243 }
244
245 for (size_t i = 0; i < data.size(); i++) {
246 vector<wxString> row = data[i];
247 vector<PrintCell> contents_row;
248 int max_height = -1;
249 for (size_t j = 0; j < row.size(); j++) {
250 int cell_width = (int)((double)width * widths[j] / sum);
251 PrintCell cell_content;
252 cell_content.Init(row[j], dc, cell_width, 10);
253 contents_row.push_back(cell_content);
254 max_height = std::max(max_height, cell_content.GetHeight());
255 }
256 rows_heights.push_back(max_height);
257 contents.push_back(contents_row);
258 }
259
260 int stripped_page = h - 4 * marginY - header_height;
261 int current_page = 1;
262 int current_y = 0;
263 for (size_t i = 0; i < data.size(); i++) {
264 int row_height = rows_heights[i];
265 if (row_height + current_y > stripped_page) {
266 current_page++;
267 current_y = row_height;
268 } else {
269 current_y += row_height;
270 }
271 int row_page = current_page;
272 vector<PrintCell>& contents_row = contents[i];
273 for (size_t j = 0; j < contents_row.size(); j++) {
274 contents_row[j].SetPage(row_page);
275 contents_row[j].SetHeight(row_height);
276 }
277 number_of_pages = std::max(row_page, number_of_pages);
278 }
279}
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
OpenCPN Route table printout.