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"
45 #include <windef.h> /* for MAX_PATH */
51 * @return True if FAI shape
54 TaskSummaryShape(OrderedTask
* task
, TCHAR
* text
)
56 bool FAIShape
= false;
57 switch (task
->TaskSize()) {
63 _tcscpy(text
, _("Unknown"));
67 _tcscpy(text
, _("Goal"));
73 if (task
->GetFactory().IsClosed()) {
74 _tcscpy(text
, _("Out and return"));
78 _tcscpy(text
, _("Two legs"));
82 if (!task
->GetFactory().IsUnique() ||!task
->GetFactory().IsClosed())
83 _tcscpy(text
, _("Three legs"));
84 else if (FAITriangleValidator::Validate(*task
)) {
85 _tcscpy(text
, _("FAI triangle"));
89 _tcscpy(text
, _("non-FAI triangle"));
93 _stprintf(text
, _("%d legs"), task
->TaskSize() - 1);
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()));
123 if (!task
->TaskSize()) {
124 _stprintf(text
, _("Task is empty (%s)"),
125 OrderedTaskFactoryName(task
->GetFactoryType()));
127 if (task
->HasTargets())
128 _stprintf(text
, _T("%s%s%.0f %s%s%s %.0f %s%s%s %.0f %s (%s)"),
131 (double)Units::ToUserDistance(stats
.distance_nominal
),
132 Units::GetDistanceName(),
135 (double)Units::ToUserDistance(stats
.distance_max
),
136 Units::GetDistanceName(),
139 (double)Units::ToUserDistance(stats
.distance_min
),
140 Units::GetDistanceName(),
141 OrderedTaskFactoryName(task
->GetFactoryType()));
143 _stprintf(text
, _T("%s%s%s %.0f %s (%s)"),
147 (double)Units::ToUserDistance(stats
.distance_nominal
),
148 Units::GetDistanceName(),
149 OrderedTaskFactoryName(task
->GetFactoryType()));
154 OrderedTaskPointLabel(TaskPointType type
, const TCHAR
*name
,
155 unsigned index
, TCHAR
* buffer
)
158 case TaskPointType::START
:
159 _stprintf(buffer
, _T("S: %s"), name
);
162 case TaskPointType::AST
:
163 _stprintf(buffer
, _T("T%d: %s"), index
, name
);
166 case TaskPointType::AAT
:
167 _stprintf(buffer
, _T("A%d: %s"), index
, name
);
170 case TaskPointType::FINISH
:
171 _stprintf(buffer
, _T("F: %s"), name
);
180 OrderedTaskPointRadiusLabel(const ObservationZonePoint
&ozp
, TCHAR
* buffer
)
182 switch (ozp
.GetShape()) {
183 case ObservationZone::Shape::FAI_SECTOR
:
184 _tcscpy(buffer
, _("FAI quadrant"));
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());
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());
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());
206 case ObservationZone::Shape::MAT_CYLINDER
:
207 _stprintf(buffer
,_T("%.1f%s"),
208 (double)Units::ToUserDistance(((const MatCylinderZone
&)ozp
).GetRadius()),
209 Units::GetDistanceName());
212 case ObservationZone::Shape::KEYHOLE
:
213 _tcscpy(buffer
, _("DAeC Keyhole"));
216 case ObservationZone::Shape::BGAFIXEDCOURSE
:
217 _tcscpy(buffer
, _("BGA Fixed Course"));
220 case ObservationZone::Shape::BGAENHANCEDOPTION
:
221 _tcscpy(buffer
, _("BGA Enhanced Option"));
224 case ObservationZone::Shape::BGA_START
:
225 _tcscpy(buffer
, _("BGA Start Sector"));
228 case ObservationZone::Shape::SYMMETRIC_QUADRANT
:
229 _tcscpy(buffer
, _("Symmetric quadrant"));
238 OrderedTaskSave(const OrderedTask
&task
)
240 assert(protected_task_manager
!= NULL
);
242 TCHAR fname
[69] = _T("");
243 if (!dlgTextEntryShowModal(fname
, 64))
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
);
257 getTaskValidationErrors(const TaskValidationErrorSet v
)
259 static TCHAR err
[MAX_PATH
];
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
));
273 TaskValidationError(TaskValidationErrorType 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
: