1 /*
2  *    Copyright 2012, 2013 Thomas Schöps
3  *    Copyright 2012-2016  Kai Pastor
4  *
5  *    This file is part of OpenOrienteering.
6  *
7  *    OpenOrienteering is free software: you can redistribute it and/or modify
8  *    it under the terms of the GNU General Public License as published by
9  *    the Free Software Foundation, either version 3 of the License, or
10  *    (at your option) any later version.
11  *
12  *    OpenOrienteering is distributed in the hope that it will be useful,
13  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *    GNU General Public License for more details.
16  *
17  *    You should have received a copy of the GNU General Public License
18  *    along with OpenOrienteering.  If not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 
22 #ifdef QT_PRINTSUPPORT_LIB
23 
24 #ifndef OPENORIENTEERING_PRINT_WIDGET_H
25 #define OPENORIENTEERING_PRINT_WIDGET_H
26 
27 #include <QFlags>
28 #include <QList>
29 #include <QObject>
30 // IWYU pragma: no_include <QRectF>
31 #include <QSize>
32 #include <QString>
33 #include <QStringList>
34 #include <QWidget>
35 
36 
37 class QAbstractButton;
38 class QButtonGroup;
39 class QCheckBox;
40 class QComboBox;
41 class QDialogButtonBox;
42 class QDoubleSpinBox;
43 class QFormLayout;
44 class QLabel;
45 class QPageSize;
46 class QPushButton;
47 class QPrinterInfo;
48 class QRectF;
49 class QScrollArea;
50 class QSpinBox;
51 class QToolButton;
52 
53 namespace OpenOrienteering {
54 
55 class MainWindow;
56 class Map;
57 class MapEditorController;
58 class MapPrinter;
59 class MapPrinterOptions;
60 class MapPrinterPageFormat;
61 class MapView;
62 class PrintTool;
63 
64 
65 /**
66  * The print widget lets the user adjust targets and parameters
67  * for printing and export.
68  */
69 class PrintWidget : public QWidget
70 {
71 Q_OBJECT
72 public:
73 	enum TaskFlag
74 	{
75 		EXPORT_FLAG    = 0x02,
76 		MULTIPAGE_FLAG = 0x04,
77 
78 		UNDEFINED_TASK     = 0x00,
79 		PRINT_TASK         = 0x14, // 0x10 | 0x04
80 		EXPORT_PDF_TASK    = 0x26, // 0x20 | 0x04 | 0x02
81 		EXPORT_IMAGE_TASK  = 0x42, // 0x40        | 0x02
82 
83 		END_JOB_TYPE
84 	};
85 	Q_DECLARE_FLAGS(TaskFlags, TaskFlag)
86 
87 	/** Constructs a new print widget. */
88 	PrintWidget(Map* map, MainWindow* main_window, MapView* main_view, MapEditorController* editor, QWidget* parent = nullptr);
89 
90 	/** Destroys the widget. */
91 	~PrintWidget() override;
92 
93 	/** Indicates the default widget size. */
94 	QSize sizeHint() const override;
95 
96 public slots:
97 	/** Changes the type of the print or export task. */
98 	void setTask(OpenOrienteering::PrintWidget::TaskFlags type);
99 
100 	/** Saves the print or export settings. */
101 	void savePrinterConfig() const;
102 
103 	/**
104 	 * Sets the active state of the print widget.
105 	 *
106 	 * When the widget becomes active, it saves the map view state and
107 	 * activates a tool on the map editor which allows to move the print area.
108 	 * When the widget becomes inactive, the tool is removed, and the map view
109 	 * state is restored.
110 	 */
111 	void setActive(bool active);
112 
113 	/** Sets the widget's (print/export) target. */
114 	void setTarget(const QPrinterInfo* target);
115 
116 	/** Sets the format of a single page. */
117 	void setPageFormat(const OpenOrienteering::MapPrinterPageFormat& format);
118 
119 	/** Sets the exported area. */
120 	void setPrintArea(const QRectF& area);
121 
122 	/** Sets output options: resolution, overprinting. */
123 	void setOptions(const OpenOrienteering::MapPrinterOptions& options);
124 
125 	/** Listens to view feature changes. */
126 	void onVisibilityChanged();
127 
128 signals:
129 	/**
130 	 * This signal is emitted when the type of task changes.
131 	 * It may be used to set a window title.
132 	 */
133 	void taskChanged(const QString& name);
134 
135 	/**
136 	 * This signal is emitted when a print or export job has been started
137 	 * and finished.
138 	 *
139 	 * The signal is not emitted when the widget is hidden
140 	 * (cf. QDialog::finished(int result) ).
141 	 */
142 	void finished(int result);
143 
144 	/**
145 	 * This signal is emitted when the dialog's close button is clicked.
146 	 */
147 	void closeClicked();
148 
149 protected slots:
150 	/** This slot reacts to changes of the target combobox. */
151 	void targetChanged(int index) const;
152 
153 	/** Opens a dialog to change printer properties. */
154 	void propertiesClicked();
155 
156 	/** This slot reacts to changes of the paper size combobox. */
157 	void paperSizeChanged(int index) const;
158 
159 	/** This slot reacts to changes of the paper dimension widgets. */
160 	void paperDimensionsChanged() const;
161 
162 	/** This slot reacts to changes of the page orientation widget. */
163 	void pageOrientationChanged(int id) const;
164 
165 	/** This slot reacts to changes of the print area policy combobox. */
166 	void printAreaPolicyChanged(int index);
167 
168 	/** This slot applies the map area policy to the current area. */
169 	void applyPrintAreaPolicy() const;
170 
171 	/** This slot applies the center map area policy to the current area. */
172 	void applyCenterPolicy() const;
173 
174 	/** This slot reacts to changes of print area position widgets. */
175 	void printAreaMoved();
176 
177 	/** This slot reacts to changes of print area size widget. */
178 	void printAreaResized();
179 
180 	/** This slot reacts to changes to the page overlap widget. */
181 	void overlapEdited(double overlap);
182 
183 	/** This slot is called when the resolution widget signals that editing finished. */
184 	void resolutionEdited();
185 
186 	/** This slot enables the alternative scale widget, or resets it. */
187 	void differentScaleClicked(bool checked);
188 
189 	/** This slot reacts to changes in the alternative scale widget. */
190 	void differentScaleEdited(int value);
191 
192 	/** This slot reacts to changes in the presence of spot colors in the map.
193 	 *  The following features are enabled only when spot colors are present:
194 	 *  - spot color separations
195 	 *  - overprinting simulation
196 	 */
197 	void spotColorPresenceChanged(bool has_spot_colors);
198 
199 	/** This slot reacts to changes in the print mode buttons. */
200 	void printModeChanged(QAbstractButton* button);
201 
202 	/** This slot reacts to changes of the "Show template" option. */
203 	void showTemplatesClicked(bool checked);
204 
205 	/** This slot reacts to changes of the "Show grid" option. */
206 	void showGridClicked(bool checked);
207 
208 	/** This slot reacts to changes of the "Simulate overprinting" option. */
209 	void overprintingClicked(bool checked);
210 
211 	/** This slot reacts to changes of the "Color mode" option. */
212 	void colorModeChanged();
213 
214 	/** Opens a preview window. */
215 	void previewClicked();
216 
217 	/** Starts printing and terminates this dialog. */
218 	void printClicked();
219 
220 protected:
221 	/** Alternative policies of handling the print area. */
222 	enum PrintAreaPolicy
223 	{
224 		SinglePage         = 2,
225 		CustomArea         = 4
226 	};
227 
228 	/** Re-initializes the list of print/export targets. */
229 	void updateTargets();
230 
231 	/** Updates the list of paper sizes from the given target. */
232 	void updatePaperSizes(const QPrinterInfo* target) const;
233 
234 	/** Updates the list of resolutions from the given target. */
235 	void updateResolutions(const QPrinterInfo* target) const;
236 
237 	/** Updates the color mode combobox from target and mode settings. */
238 	void updateColorMode();
239 
240 	/** A list of paper sizes which is used when the target does not specify
241 	 *  supported paper sizes. */
242 	QList<QPageSize> defaultPageSizes() const;
243 
244 	/** Moves the given rectangle to a position where it is centered on the
245 	 *  map for the current output options. */
246 	void centerOnMap(QRectF& area) const;
247 
248 	/** Shows a warning and returns true if the output would be empty. */
249 	bool checkForEmptyMap();
250 
251 	/** Sets the enabled state of the page overlap field. */
252 	void setOverlapEditEnabled(bool state = true) const;
253 
254 	/** Checks whether the template order warning needs to be displayed. */
255 	void checkTemplateConfiguration();
256 
257 	/** Exports to an image file. */
258 	void exportToImage();
259 
260 	/** Export a world file */
261 	void exportWorldFile(const QString& path) const;
262 
263 	/** Exports to a PDF file. */
264 	void exportToPdf();
265 
266 	/** Print to a printer. */
267 	void print();
268 
269 private:
270 	enum Exporters
271 	{
272 		PdfExporter = -1,
273 		ImageExporter = -2
274 	};
275 	TaskFlags task;
276 
277 	QFormLayout* layout;
278 	QWidget* scrolling_content;
279 	QScrollArea* scroll_area;
280 	QDialogButtonBox* button_box;
281 
282 	QComboBox* target_combo;
283 	QToolButton* printer_properties_button;
284 	QComboBox* paper_size_combo;
285 	QWidget*   page_orientation_widget;
286 	QButtonGroup* page_orientation_group;
287 	QSpinBox* copies_edit;
288 	QDoubleSpinBox* page_width_edit;
289 	QDoubleSpinBox* page_height_edit;
290 
291 	QComboBox* dpi_combo;
292 	QCheckBox* show_templates_check;
293 	QLabel* templates_warning_icon;
294 	QLabel* templates_warning_text;
295 	QCheckBox* show_grid_check;
296 	QCheckBox* overprinting_check;
297 	QCheckBox* world_file_check;
298 	QCheckBox* different_scale_check;
299 	QSpinBox* different_scale_edit;
300 	QComboBox* color_mode_combo;
301 
302 	QComboBox* policy_combo;
303 	QCheckBox* center_check;
304 	QDoubleSpinBox* left_edit;
305 	QDoubleSpinBox* top_edit;
306 	QDoubleSpinBox* width_edit;
307 	QDoubleSpinBox* height_edit;
308 	QDoubleSpinBox* overlap_edit;
309 
310 	QToolButton* vector_mode_button;
311 	QToolButton* raster_mode_button;
312 	QToolButton* separations_mode_button;
313 
314 	QPushButton* preview_button;
315 	QPushButton* print_button;
316 	QPushButton* export_button;
317 
318 	QStringList printers;
319 
320 	PrintAreaPolicy policy;
321 
322 	Map* map;
323 	MapPrinter* map_printer;
324 	MainWindow* main_window;
325 	MapView* main_view;
326 	MapEditorController* editor;
327 	PrintTool* print_tool;
328 	QString saved_view_state;
329 	bool active;
330 };
331 
332 
333 }  // namespace OpenOrienteering
334 
335 
336 Q_DECLARE_OPERATORS_FOR_FLAGS(OpenOrienteering::PrintWidget::TaskFlags)
337 
338 
339 #endif
340 
341 
342 #endif
343