dlgTaskHelpers: remove useless question "Save task?"
[xcsoar.git] / src / Dialogs / Task / dlgTaskHelpers.cpp
blobfd6d5254b9d2907dd3db67f37888d76fcceadc4e
1 /*
2 Copyright_License {
4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "dlgTaskHelpers.hpp"
25 #include "Dialogs/TextEntry.hpp"
26 #include "Dialogs/Message.hpp"
27 #include "Language/Language.hpp"
28 #include "Units/Units.hpp"
29 #include "Task/TypeStrings.hpp"
30 #include "Task/ProtectedTaskManager.hpp"
31 #include "Task/ObservationZones/CylinderZone.hpp"
32 #include "Task/ObservationZones/MatCylinderZone.hpp"
33 #include "Task/ObservationZones/SectorZone.hpp"
34 #include "Task/ObservationZones/LineSectorZone.hpp"
35 #include "Task/Shapes/FAITriangleTask.hpp"
36 #include "Engine/Task/Ordered/OrderedTask.hpp"
37 #include "Engine/Task/Points/Type.hpp"
38 #include "Engine/Task/Factory/AbstractTaskFactory.hpp"
39 #include "Components.hpp"
40 #include "LocalPath.hpp"
41 #include "OS/FileUtil.hpp"
43 #include <assert.h>
44 #include <stdio.h>
45 #include <windef.h> /* for MAX_PATH */
47 /**
49 * @param task
50 * @param text
51 * @return True if FAI shape
53 static bool
54 TaskSummaryShape(OrderedTask* task, TCHAR* text)
56 bool FAIShape = false;
57 switch (task->TaskSize()) {
58 case 0:
59 text[0] = '\0';
60 break;
62 case 1:
63 _tcscpy(text, _("Unknown"));
64 break;
66 case 2:
67 _tcscpy(text, _("Goal"));
68 FAIShape = true;
70 break;
72 case 3:
73 if (task->GetFactory().IsClosed()) {
74 _tcscpy(text, _("Out and return"));
75 FAIShape = true;
77 else
78 _tcscpy(text, _("Two legs"));
79 break;
81 case 4:
82 if (!task->GetFactory().IsUnique() ||!task->GetFactory().IsClosed())
83 _tcscpy(text, _("Three legs"));
84 else if (FAITriangleValidator::Validate(*task)) {
85 _tcscpy(text, _("FAI triangle"));
86 FAIShape = true;
88 else
89 _tcscpy(text, _("non-FAI triangle"));
90 break;
92 default:
93 _stprintf(text, _("%d legs"), task->TaskSize() - 1);
94 break;
96 return FAIShape;
98 void
99 OrderedTaskSummary(OrderedTask* task, TCHAR* text, bool linebreaks)
101 const TaskStats &stats = task->GetStats();
102 TCHAR summary_shape[100];
103 bool FAIShape = TaskSummaryShape(task, summary_shape);
104 if (FAIShape || task->GetFactoryType() == TaskFactoryType::FAI_GENERAL) {
105 if (!task->GetFactory().ValidateFAIOZs()) {
106 _tcscat(summary_shape, _T("/ "));
107 _tcscat(summary_shape, getTaskValidationErrors(
108 task->GetFactory().GetValidationErrors()));
113 TCHAR linebreak[3];
114 if (linebreaks) {
115 linebreak[0] = '\n';
116 linebreak[1] = 0;
117 } else {
118 linebreak[0] = ',';
119 linebreak[1] = ' ';
120 linebreak[2] = 0;
123 if (!task->TaskSize()) {
124 _stprintf(text, _("Task is empty (%s)"),
125 OrderedTaskFactoryName(task->GetFactoryType()));
126 } else {
127 if (task->HasTargets())
128 _stprintf(text, _T("%s%s%.0f %s%s%s %.0f %s%s%s %.0f %s (%s)"),
129 summary_shape,
130 linebreak,
131 (double)Units::ToUserDistance(stats.distance_nominal),
132 Units::GetDistanceName(),
133 linebreak,
134 _("max."),
135 (double)Units::ToUserDistance(stats.distance_max),
136 Units::GetDistanceName(),
137 linebreak,
138 _("min."),
139 (double)Units::ToUserDistance(stats.distance_min),
140 Units::GetDistanceName(),
141 OrderedTaskFactoryName(task->GetFactoryType()));
142 else
143 _stprintf(text, _T("%s%s%s %.0f %s (%s)"),
144 summary_shape,
145 linebreak,
146 _("dist."),
147 (double)Units::ToUserDistance(stats.distance_nominal),
148 Units::GetDistanceName(),
149 OrderedTaskFactoryName(task->GetFactoryType()));
153 void
154 OrderedTaskPointLabel(TaskPointType type, const TCHAR *name,
155 unsigned index, TCHAR* buffer)
157 switch (type) {
158 case TaskPointType::START:
159 _stprintf(buffer, _T("S: %s"), name);
160 break;
162 case TaskPointType::AST:
163 _stprintf(buffer, _T("T%d: %s"), index, name);
164 break;
166 case TaskPointType::AAT:
167 _stprintf(buffer, _T("A%d: %s"), index, name);
168 break;
170 case TaskPointType::FINISH:
171 _stprintf(buffer, _T("F: %s"), name);
172 break;
174 default:
175 break;
179 void
180 OrderedTaskPointRadiusLabel(const ObservationZonePoint &ozp, TCHAR* buffer)
182 switch (ozp.GetShape()) {
183 case ObservationZone::Shape::FAI_SECTOR:
184 _tcscpy(buffer, _("FAI quadrant"));
185 return;
187 case ObservationZone::Shape::SECTOR:
188 case ObservationZone::Shape::ANNULAR_SECTOR:
189 _stprintf(buffer,_T("%s - %s: %.1f%s"), _("Sector"), _("Radius"),
190 (double)Units::ToUserDistance(((const SectorZone &)ozp).GetRadius()),
191 Units::GetDistanceName());
192 return;
194 case ObservationZone::Shape::LINE:
195 _stprintf(buffer,_T("%s - %s: %.1f%s"), _("Line"), _("Gate Width"),
196 (double)Units::ToUserDistance(((const LineSectorZone &)ozp).GetLength()),
197 Units::GetDistanceName());
198 return;
200 case ObservationZone::Shape::CYLINDER:
201 _stprintf(buffer,_T("%s - %s: %.1f%s"), _("Cylinder"), _("Radius"),
202 (double)Units::ToUserDistance(((const CylinderZone &)ozp).GetRadius()),
203 Units::GetDistanceName());
204 return;
206 case ObservationZone::Shape::MAT_CYLINDER:
207 _stprintf(buffer,_T("%.1f%s"),
208 (double)Units::ToUserDistance(((const MatCylinderZone &)ozp).GetRadius()),
209 Units::GetDistanceName());
210 return;
212 case ObservationZone::Shape::KEYHOLE:
213 _tcscpy(buffer, _("DAeC Keyhole"));
214 return;
216 case ObservationZone::Shape::BGAFIXEDCOURSE:
217 _tcscpy(buffer, _("BGA Fixed Course"));
218 return;
220 case ObservationZone::Shape::BGAENHANCEDOPTION:
221 _tcscpy(buffer, _("BGA Enhanced Option"));
222 return;
224 case ObservationZone::Shape::BGA_START:
225 _tcscpy(buffer, _("BGA Start Sector"));
226 return;
228 case ObservationZone::Shape::SYMMETRIC_QUADRANT:
229 _tcscpy(buffer, _("Symmetric quadrant"));
230 return;
233 gcc_unreachable();
234 assert(false);
237 bool
238 OrderedTaskSave(const OrderedTask &task)
240 assert(protected_task_manager != NULL);
242 TCHAR fname[69] = _T("");
243 if (!dlgTextEntryShowModal(fname, 64))
244 return false;
246 TCHAR path[MAX_PATH];
247 LocalPath(path, _T("tasks"));
248 Directory::Create(path);
250 _tcscat(fname, _T(".tsk"));
251 LocalPath(path, _T("tasks"), fname);
252 protected_task_manager->TaskSave(path, task);
253 return true;
256 const TCHAR*
257 getTaskValidationErrors(const TaskValidationErrorSet v)
259 static TCHAR err[MAX_PATH];
260 err[0] = '\0';
262 for (unsigned i = 0; i < v.N; i++) {
263 const TaskValidationErrorType error = TaskValidationErrorType(i);
264 if (v.Contains(error) &&
265 _tcslen(err) + _tcslen(TaskValidationError(error)) < MAX_PATH)
266 _tcscat(err, TaskValidationError(error));
269 return err;
272 const TCHAR*
273 TaskValidationError(TaskValidationErrorType type)
275 switch (type) {
276 case TaskValidationErrorType::NO_VALID_START:
277 return _("No valid start.\n");
278 case TaskValidationErrorType::NO_VALID_FINISH:
279 return _("No valid finish.\n");
280 case TaskValidationErrorType::TASK_NOT_CLOSED:
281 return _("Task not closed.\n");
282 case TaskValidationErrorType::TASK_NOT_HOMOGENEOUS:
283 return _("All turnpoints not the same type.\n");
284 case TaskValidationErrorType::INCORRECT_NUMBER_TURNPOINTS:
285 return _("Incorrect number of turnpoints.\n");
286 case TaskValidationErrorType::EXCEEDS_MAX_TURNPOINTS:
287 return _("Too many turnpoints.\n");
288 case TaskValidationErrorType::UNDER_MIN_TURNPOINTS:
289 return _("Not enough turnpoints.\n");
290 case TaskValidationErrorType::TURNPOINTS_NOT_UNIQUE:
291 return _("Turnpoints not unique.\n");
292 case TaskValidationErrorType::INVALID_FAI_TRIANGLE_GEOMETRY:
293 return _("Invalid FAI triangle shape.\n");
294 case TaskValidationErrorType::EMPTY_TASK:
295 return _("Empty task.\n");
296 case TaskValidationErrorType::NON_FAI_OZS:
297 return _("non-FAI turn points");
299 case TaskValidationErrorType::NON_MAT_OZS:
300 return _("non-MAT turn points");
302 case TaskValidationErrorType::COUNT:
303 gcc_unreachable();
306 gcc_unreachable();