1 /*
2  *    Copyright 2012, 2013 Thomas Schöps
3  *
4  *    This file is part of OpenOrienteering.
5  *
6  *    OpenOrienteering is free software: you can redistribute it and/or modify
7  *    it under the terms of the GNU General Public License as published by
8  *    the Free Software Foundation, either version 3 of the License, or
9  *    (at your option) any later version.
10  *
11  *    OpenOrienteering is distributed in the hope that it will be useful,
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *    GNU General Public License for more details.
15  *
16  *    You should have received a copy of the GNU General Public License
17  *    along with OpenOrienteering.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 
21 #include "map_dialog_rotate.h"
22 
23 #include <Qt>
24 #include <QtMath>
25 #include <QCheckBox>
26 #include <QDialogButtonBox>
27 #include <QDoubleSpinBox>
28 #include <QFlags>
29 #include <QFormLayout>
30 #include <QHBoxLayout>
31 #include <QLabel>
32 #include <QRadioButton>
33 #include <QSpacerItem>
34 
35 #include "core/georeferencing.h"
36 #include "core/map.h"
37 #include "core/map_coord.h"
38 #include "templates/template.h"
39 #include "gui/util_gui.h"
40 
41 
42 namespace OpenOrienteering {
43 
RotateMapDialog(QWidget * parent,Map * map)44 RotateMapDialog::RotateMapDialog(QWidget* parent, Map* map) : QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint), map(map)
45 {
46 	setWindowTitle(tr("Rotate map"));
47 
48 	QFormLayout* layout = new QFormLayout();
49 
50 	layout->addRow(Util::Headline::create(tr("Rotation parameters")));
51 
52 	rotation_edit = Util::SpinBox::create<Util::RotationalDegrees>();
53 	layout->addRow(tr("Angle (counter-clockwise):"), rotation_edit);
54 
55 	layout->addRow(new QLabel(tr("Rotate around:")));
56 
57 	//: Rotation center point
58 	center_origin_radio = new QRadioButton(tr("Map coordinate system origin"));
59 	center_origin_radio->setChecked(true);
60 	layout->addRow(center_origin_radio);
61 
62 	//: Rotation center point
63 	center_georef_radio = new QRadioButton(tr("Georeferencing reference point"));
64 	if (!map->getGeoreferencing().isValid())
65 		center_georef_radio->setEnabled(false);
66 	layout->addRow(center_georef_radio);
67 
68 	//: Rotation center point
69 	center_other_radio = new QRadioButton(tr("Other point,"));
70 	layout->addRow(center_other_radio);
71 
72 	//: x coordinate
73 	other_x_edit = Util::SpinBox::create<MapCoordF>();
74 	layout->addRow(tr("X:"), other_x_edit);
75 
76 	//: y coordinate
77 	other_y_edit = Util::SpinBox::create<MapCoordF>();
78 	layout->addRow(tr("Y:"), other_y_edit);
79 
80 
81 	layout->addItem(Util::SpacerItem::create(this));
82 	layout->addRow(Util::Headline::create(tr("Options")));
83 
84 	adjust_georeferencing_check = new QCheckBox(tr("Adjust georeferencing reference point"));
85 	if (map->getGeoreferencing().isValid())
86 		adjust_georeferencing_check->setChecked(true);
87 	else
88 		adjust_georeferencing_check->setEnabled(false);
89 	layout->addRow(adjust_georeferencing_check);
90 
91 	adjust_declination_check = new QCheckBox(tr("Adjust georeferencing declination"));
92 	if (map->getGeoreferencing().isValid())
93 		adjust_declination_check->setChecked(true);
94 	else
95 		adjust_declination_check->setEnabled(false);
96 	layout->addRow(adjust_declination_check);
97 
98 	adjust_templates_check = new QCheckBox(tr("Rotate non-georeferenced templates"));
99 	bool have_non_georeferenced_template = false;
100 	for (int i = 0; i < map->getNumTemplates() && !have_non_georeferenced_template; ++i)
101 		have_non_georeferenced_template = !map->getTemplate(i)->isTemplateGeoreferenced();
102 	for (int i = 0; i < map->getNumClosedTemplates() && !have_non_georeferenced_template; ++i)
103 		have_non_georeferenced_template = !map->getClosedTemplate(i)->isTemplateGeoreferenced();
104 	if (have_non_georeferenced_template)
105 		adjust_templates_check->setChecked(true);
106 	else
107 		adjust_templates_check->setEnabled(false);
108 	layout->addRow(adjust_templates_check);
109 
110 
111 	QDialogButtonBox* button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
112 
113 	auto* box_layout = new QVBoxLayout();
114 	box_layout->addLayout(layout);
115 	box_layout->addItem(Util::SpacerItem::create(this));
116 	box_layout->addStretch();
117 	box_layout->addWidget(button_box);
118 
119 	setLayout(box_layout);
120 
121 	connect(center_origin_radio, &QAbstractButton::clicked, this, &RotateMapDialog::updateWidgets);
122 	connect(center_georef_radio, &QAbstractButton::clicked, this, &RotateMapDialog::updateWidgets);
123 	connect(center_other_radio, &QAbstractButton::clicked, this, &RotateMapDialog::updateWidgets);
124 	connect(button_box, &QDialogButtonBox::accepted, this, &RotateMapDialog::okClicked);
125 	connect(button_box, &QDialogButtonBox::rejected, this, &QDialog::reject);
126 
127 	updateWidgets();
128 }
129 
setRotationDegrees(double rotation)130 void RotateMapDialog::setRotationDegrees(double rotation)
131 {
132 	rotation_edit->setValue(rotation);
133 }
134 
setRotateAroundGeorefRefPoint()135 void RotateMapDialog::setRotateAroundGeorefRefPoint()
136 {
137 	if (center_georef_radio->isEnabled())
138 	{
139 		center_georef_radio->setChecked(true);
140 		updateWidgets();
141 	}
142 }
143 
setAdjustDeclination(bool adjust)144 void RotateMapDialog::setAdjustDeclination(bool adjust)
145 {
146 	adjust_declination_check->setChecked(adjust);
147 }
148 
showAdjustDeclination(bool show)149 void RotateMapDialog::showAdjustDeclination(bool show)
150 {
151 	adjust_declination_check->setVisible(show);
152 }
153 
updateWidgets()154 void RotateMapDialog::updateWidgets()
155 {
156 	other_x_edit->setEnabled(center_other_radio->isChecked());
157 	other_y_edit->setEnabled(center_other_radio->isChecked());
158 	adjust_georeferencing_check->setEnabled(!center_georef_radio->isChecked());
159 }
160 
okClicked()161 void RotateMapDialog::okClicked()
162 {
163 	double rotation = M_PI * rotation_edit->value() / 180;
164 	MapCoord center = MapCoord(0, 0);
165 	if (center_georef_radio->isChecked())
166 		center = map->getGeoreferencing().getMapRefPoint();
167 	else if (center_other_radio->isChecked())
168 		center = MapCoord(other_x_edit->value(), -1 * other_y_edit->value());
169 
170 	map->rotateMap(rotation, center, adjust_georeferencing_check->isChecked(), adjust_declination_check->isChecked(), adjust_templates_check->isChecked());
171 	accept();
172 }
173 
174 
175 }  // namespace OpenOrienteering
176