示例#1
0
void
TaskRulesConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  LoadWindow(NULL, parent,
             Layout::landscape ? _T("IDR_XML_TASKRULESCONFIGPANEL_L") :
                               _T("IDR_XML_TASKRULESCONFIGPANEL"));

  const ComputerSettings &settings_computer = XCSoarInterface::GetComputerSettings();
  const TaskBehaviour &task_behaviour = settings_computer.task;

  LoadFormProperty(form, _T("prpStartMaxSpeed"), ugHorizontalSpeed,
                   task_behaviour.ordered_defaults.start_max_speed);

  LoadFormProperty(form, _T("prpStartMaxSpeedMargin"), ugHorizontalSpeed,
                   task_behaviour.start_max_speed_margin);

  static gcc_constexpr_data StaticEnumChoice start_max_height_ref_list[] = {
    { hrAGL, N_("AGL"), N_("Reference AGL for start maximum height rule (above start point)") },
    { hrMSL, N_("MSL"), N_("Reference MSL for start maximum height rule (above sea level)") },
    { 0 }
  };
  LoadFormProperty(form, _T("prpStartHeightRef"), start_max_height_ref_list,
                   task_behaviour.ordered_defaults.start_max_height_ref);

  LoadFormProperty(form, _T("prpStartMaxHeight"), ugAltitude,
                   task_behaviour.ordered_defaults.start_max_height);

  LoadFormProperty(form, _T("prpStartMaxHeightMargin"), ugAltitude,
                   task_behaviour.start_max_height_margin);

  static gcc_constexpr_data StaticEnumChoice finish_min_height_ref_list[] = {
    { hrAGL, N_("AGL"), N_("Reference AGL for finish minimum height rule (above finish point)") },
    { hrMSL, N_("MSL"), N_("Reference MSL for finish minimum height rule (above sea level)") },
    { 0 }
  };
  LoadFormProperty(form, _T("prpFinishHeightRef"), finish_min_height_ref_list,
                   task_behaviour.ordered_defaults.finish_min_height_ref);

  LoadFormProperty(form, _T("prpFinishMinHeight"), ugAltitude,
                   task_behaviour.ordered_defaults.finish_min_height);

  const StaticEnumChoice contests_list[] = {
    { OLC_FAI, ContestToString(OLC_FAI) },
    { OLC_Classic, ContestToString(OLC_Classic) },
    { OLC_League, ContestToString(OLC_League) },
    { OLC_Plus, ContestToString(OLC_Plus) },
    { OLC_XContest, ContestToString(OLC_XContest) },
    { OLC_DHVXC, ContestToString(OLC_DHVXC) },
    { OLC_SISAT, ContestToString(OLC_SISAT) },
    { 0 }
  };
  LoadFormProperty(form, _T("prpContests"), contests_list,
                   task_behaviour.contest);
}
示例#2
0
void
TaskRulesConfigPanel::Init(WndForm *_wf)
{
  assert(_wf != NULL);
  wf = _wf;
  WndProperty *wp;
  const SETTINGS_COMPUTER &settings_computer = XCSoarInterface::SettingsComputer();

  LoadFormProperty(*wf, _T("prpStartMaxSpeed"), ugHorizontalSpeed,
                   settings_computer.ordered_defaults.start_max_speed);

  LoadFormProperty(*wf, _T("prpStartMaxSpeedMargin"), ugHorizontalSpeed,
                   settings_computer.start_max_speed_margin);

  LoadFormProperty(*wf, _T("prpStartMaxHeight"), ugAltitude,
                   settings_computer.ordered_defaults.start_max_height);

  LoadFormProperty(*wf, _T("prpStartMaxHeightMargin"), ugAltitude,
                   settings_computer.start_max_height_margin);

  wp = (WndProperty*)wf->FindByName(_T("prpStartHeightRef"));
  if (wp) {
    DataFieldEnum* dfe;
    dfe = (DataFieldEnum*)wp->GetDataField();
    dfe->addEnumText(_("AGL"));
    dfe->addEnumText(_("MSL"));
    dfe->Set(settings_computer.ordered_defaults.start_max_height_ref);
    wp->RefreshDisplay();
  }

  LoadFormProperty(*wf, _T("prpFinishMinHeight"), ugAltitude,
                   settings_computer.ordered_defaults.finish_min_height);

  wp = (WndProperty*)wf->FindByName(_T("prpContests"));
  if (wp) {
    DataFieldEnum* dfe;
    dfe = (DataFieldEnum*)wp->GetDataField();
    dfe->addEnumText(ContestToString(OLC_FAI), OLC_FAI);
    dfe->addEnumText(ContestToString(OLC_Classic), OLC_Classic);
    dfe->addEnumText(ContestToString(OLC_League), OLC_League);
    dfe->addEnumText(ContestToString(OLC_Plus), OLC_Plus);
    dfe->addEnumText(ContestToString(OLC_XContest), OLC_XContest);
    dfe->addEnumText(ContestToString(OLC_DHVXC), OLC_DHVXC);
    dfe->addEnumText(ContestToString(OLC_SISAT), OLC_SISAT);
    dfe->Set(settings_computer.contest);
    wp->RefreshDisplay();
  }
}
示例#3
0
static void
Update()
{
  TCHAR sTmp[1000];

  assert(wf != NULL);
  assert(wInfo != NULL);
  assert(wGrid != NULL);
  assert(csw != NULL);
  assert(glide_computer != NULL);

  const ComputerSettings &settings_computer = blackboard->GetComputerSettings();
  const DerivedInfo &calculated = blackboard->Calculated();

  switch (page) {
  case AnalysisPage::BAROGRAPH:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Barograph"));
    wf->SetCaption(sTmp);
    BarographCaption(sTmp, glide_computer->GetFlightStats());
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_("Settings"));
    break;

  case AnalysisPage::CLIMB:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Climb"));
    wf->SetCaption(sTmp);
    ClimbChartCaption(sTmp, glide_computer->GetFlightStats());
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_("Task Calc"));
    break;

  case AnalysisPage::THERMAL_BAND:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Thermal Band"));
    wf->SetCaption(sTmp);
    ClimbChartCaption(sTmp, glide_computer->GetFlightStats());
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_T(""));
    break;

  case AnalysisPage::WIND:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Wind at Altitude"));
    wf->SetCaption(sTmp);
    wInfo->SetCaption(_T(""));
    SetCalcCaption(_("Set Wind"));
    break;

  case AnalysisPage::POLAR:
    _stprintf(sTmp, _T("%s: %s (%s %d kg)"), _("Analysis"),
              _("Glide Polar"), _("Mass"),
              (int)settings_computer.polar.glide_polar_task.GetTotalMass());
    wf->SetCaption(sTmp);
    GlidePolarCaption(sTmp, settings_computer.polar.glide_polar_task);
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_("Settings"));
   break;

  case AnalysisPage::TEMPTRACE:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Temp Trace"));
    wf->SetCaption(sTmp);
    TemperatureChartCaption(sTmp, glide_computer->GetCuSonde());
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_("Settings"));
    break;

  case AnalysisPage::TASK_SPEED:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Task Speed"));
    wf->SetCaption(sTmp);
    wInfo->SetCaption(_T(""));
    SetCalcCaption(_("Task Calc"));
    break;

  case AnalysisPage::TASK:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Task"));
    wf->SetCaption(sTmp);
    FlightStatisticsRenderer::CaptionTask(sTmp, calculated);
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_("Task calc"));
    break;

  case AnalysisPage::OLC:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              ContestToString(settings_computer.contest.contest));
    wf->SetCaption(sTmp);
    SetCalcCaption(_T(""));
    FlightStatisticsRenderer::CaptionOLC(sTmp, settings_computer.contest,
                                         calculated);
    wInfo->SetCaption(sTmp);
    break;

  case AnalysisPage::AIRSPACE:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Airspace"));
    wf->SetCaption(sTmp);
    wInfo->SetCaption(_T(""));
    SetCalcCaption(_("Warnings"));
    break;

  case AnalysisPage::COUNT:
    gcc_unreachable();
  }

  switch (page) {
  case AnalysisPage::AIRSPACE:
    UpdateCrossSection();
    csw->Invalidate();
    csw->Show();
    wGrid->Hide();
    break;

  default:
    csw->Hide();
    wGrid->Show();
    wGrid->Invalidate();
    break;
  }
}
示例#4
0
void
TaskRulesConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  const ComputerSettings &settings_computer = XCSoarInterface::GetComputerSettings();
  const TaskBehaviour &task_behaviour = settings_computer.task;

  RowFormWidget::Prepare(parent, rc);

  AddFloat(_("Start max. speed"), _("Maximum speed allowed in start observation zone.  Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(300), fixed(5), false, UnitGroup::HORIZONTAL_SPEED,
           task_behaviour.ordered_defaults.start_max_speed);
  SetExpertRow(StartMaxSpeed);

  AddFloat(_("Start max. speed margin"),
           _("Maximum speed above maximum start speed to tolerate.  Set to 0 for no tolerance."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(300), fixed(5), false, UnitGroup::HORIZONTAL_SPEED,
           task_behaviour.start_max_speed_margin);
  SetExpertRow(StartMaxSpeedMargin);

  AddSpacer();
  SetExpertRow(spacer_1);

  AddFloat(_("Start max. height"),
           _("Maximum height based on start height reference (AGL or MSL) while starting the task.  "
               "Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.ordered_defaults.start_max_height));
  SetExpertRow(StartMaxHeight);

  AddFloat(_("Start max. height margin"),
           _("Maximum height above maximum start height to tolerate.  Set to 0 for no tolerance."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.start_max_height_margin));
  SetExpertRow(StartMaxHeightMargin);

  static constexpr StaticEnumChoice start_max_height_ref_list[] = {
    { (unsigned)HeightReferenceType::AGL, N_("AGL"), N_("Reference AGL for start maximum height rule (above start point).") },
    { (unsigned)HeightReferenceType::MSL, N_("MSL"), N_("Reference MSL for start maximum height rule (above sea level).") },
    { 0 }
  };
  AddEnum(_("Start height ref."), NULL, start_max_height_ref_list,
          (unsigned)task_behaviour.ordered_defaults.start_max_height_ref);
  SetExpertRow(StartHeightRef);

  AddSpacer();
  SetExpertRow(spacer_2);

  AddFloat(_("Finish min. height"),
           _("Minimum height based on finish height reference (AGL or MSL) while finishing the task.  "
               "Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.ordered_defaults.finish_min_height));
  SetExpertRow(FinishMinHeight);

  static constexpr StaticEnumChoice finish_min_height_ref_list[] = {
    { (unsigned)HeightReferenceType::AGL, N_("AGL"), N_("Reference AGL for finish minimum height rule (above finish point).") },
    { (unsigned)HeightReferenceType::MSL, N_("MSL"), N_("Reference MSL for finish minimum height rule (above sea level).") },
    { 0 }
  };
  AddEnum(_("Finish height ref."), NULL, finish_min_height_ref_list,
          (unsigned)task_behaviour.ordered_defaults.finish_min_height_ref);
  SetExpertRow(FinishHeightRef);

  AddSpacer();
  SetExpertRow(spacer_3);

  const StaticEnumChoice contests_list[] = {
    { OLC_FAI, ContestToString(OLC_FAI),
      N_("Conforms to FAI triangle rules. Three turns and common start and finish. No leg less than 28% "
          "of total except for tasks longer than 500km: No leg less than 25% or larger than 45%.") },
    { OLC_Classic, ContestToString(OLC_Classic),
      N_("Up to seven points including start and finish, finish height must not be lower than "
          "start height less 1000 meters.") },
    { OLC_League, ContestToString(OLC_League),
      N_("The most recent contest with Sprint task rules.") },
    { OLC_Plus, ContestToString(OLC_Plus),
      N_("A combination of Classic and FAI rules. 30% of the FAI score are added to the Classic score.") },
    { OLC_XContest, ContestToString(OLC_XContest), _T("tbd.") },
    { OLC_DHVXC, ContestToString(OLC_DHVXC), _T("tbd.") },
    { OLC_SISAT, ContestToString(OLC_SISAT), _T("tbd.") },
    { OLC_NetCoupe, ContestToString(OLC_NetCoupe), N_("The FFVV NetCoupe \"libre\" competiton.") },
    { 0 }
  };
  AddEnum(_("On-Line Contest"),
      _("Select the rules used for calculating optimal points for the On-Line Contest. "
          "The implementation  conforms to the official release 2010, Sept.23."),
          contests_list, task_behaviour.contest);

  AddBoolean(_("Predict Contest"),
             _("If enabled, then the next task point is included in the "
               "score calculation, assuming that you will reach it."),
             task_behaviour.predict_contest);
}
示例#5
0
static void
Update(void)
{
  TCHAR sTmp[1000];

  assert(wf != NULL);
  assert(wInfo != NULL);
  assert(wGrid != NULL);
  assert(csw != NULL);
  assert(glide_computer != NULL);

  const ComputerSettings &settings_computer = blackboard->GetComputerSettings();
  const DerivedInfo &calculated = blackboard->Calculated();

  FlightStatisticsRenderer fs(glide_computer->GetFlightStats(),
                              look->chart, look->map);

  switch (page) {
  case ANALYSIS_PAGE_BAROGRAPH:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Barograph"));
    wf->SetCaption(sTmp);
    fs.CaptionBarograph(sTmp);
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_("Settings"));
    break;

  case ANALYSIS_PAGE_CLIMB:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Climb"));
    wf->SetCaption(sTmp);
    fs.CaptionClimb(sTmp);
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_("Task Calc"));
    break;

  case ANALYSIS_PAGE_THERMAL_BAND:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Thermal Band"));
    wf->SetCaption(sTmp);
    fs.CaptionClimb(sTmp);
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_T(""));
    break;

  case ANALYSIS_PAGE_WIND:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Wind At Altitude"));
    wf->SetCaption(sTmp);
    wInfo->SetCaption(_T(""));
    SetCalcCaption(_("Set Wind"));
    break;

  case ANALYSIS_PAGE_POLAR:
    _stprintf(sTmp, _T("%s: %s (%s %d kg)"), _("Analysis"),
              _("Glide Polar"), _("Mass"),
              (int)settings_computer.glide_polar_task.GetTotalMass());
    wf->SetCaption(sTmp);
    fs.CaptionPolar(sTmp, settings_computer.glide_polar_task);
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_("Settings"));
   break;

  case ANALYSIS_PAGE_TEMPTRACE:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Temp Trace"));
    wf->SetCaption(sTmp);
    fs.CaptionTempTrace(sTmp, glide_computer->GetCuSonde());
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_("Settings"));
    break;

  case ANALYSIS_PAGE_TASK_SPEED:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Task Speed"));
    wf->SetCaption(sTmp);
    wInfo->SetCaption(_T(""));
    SetCalcCaption(_("Task Calc"));
    break;

  case ANALYSIS_PAGE_TASK:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Task"));
    wf->SetCaption(sTmp);
    fs.CaptionTask(sTmp, calculated);
    wInfo->SetCaption(sTmp);
    SetCalcCaption(_("Task calc"));
    break;

  case ANALYSIS_PAGE_OLC:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              ContestToString(settings_computer.task.contest));
    wf->SetCaption(sTmp);
    SetCalcCaption(_T(""));
    fs.CaptionOLC(sTmp, settings_computer.task, calculated);
    wInfo->SetCaption(sTmp);
    break;

  case ANALYSIS_PAGE_AIRSPACE:
    _stprintf(sTmp, _T("%s: %s"), _("Analysis"),
              _("Airspace"));
    wf->SetCaption(sTmp);
    wInfo->SetCaption(_T(""));
    SetCalcCaption(_("Warnings"));
    break;

  case ANALYSIS_PAGE_COUNT:
    assert(false);
    break;
  }

  switch (page) {
  case ANALYSIS_PAGE_AIRSPACE:
    UpdateCrossSection();
    csw->invalidate();
    csw->show();
    wGrid->hide();
    break;

  default:
    csw->hide();
    wGrid->show();
    wGrid->invalidate();
    break;
  }
}
示例#6
0
void
AnalysisWidget::Update()
{
  TCHAR sTmp[1000];

  const ComputerSettings &settings_computer = blackboard.GetComputerSettings();
  const DerivedInfo &calculated = blackboard.Calculated();

  switch (page) {
  case AnalysisPage::BAROGRAPH:
    StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"),
                       _("Barograph"));
    dialog.SetCaption(sTmp);
    BarographCaption(sTmp, glide_computer.GetFlightStats());
    info.SetText(sTmp);
    SetCalcCaption(_("Settings"));
    break;

  case AnalysisPage::CLIMB:
    StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"),
                       _("Climb"));
    dialog.SetCaption(sTmp);
    ClimbChartCaption(sTmp, glide_computer.GetFlightStats());
    info.SetText(sTmp);
    SetCalcCaption(_("Task Calc"));
    break;

  case AnalysisPage::THERMAL_BAND:
    StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"),
                       _("Thermal Band"));
    dialog.SetCaption(sTmp);
    ClimbChartCaption(sTmp, glide_computer.GetFlightStats());
    info.SetText(sTmp);
    SetCalcCaption(_T(""));
    break;

  case AnalysisPage::WIND:
    StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"),
                       _("Wind at Altitude"));
    dialog.SetCaption(sTmp);
    info.SetText(_T(""));
    SetCalcCaption(_("Set Wind"));
    break;

  case AnalysisPage::POLAR:
    StringFormatUnsafe(sTmp, _T("%s: %s (%s %d kg)"), _("Analysis"),
                       _("Glide Polar"), _("Mass"),
                       (int)settings_computer.polar.glide_polar_task.GetTotalMass());
    dialog.SetCaption(sTmp);
    GlidePolarCaption(sTmp, settings_computer.polar.glide_polar_task);
    info.SetText(sTmp);
    SetCalcCaption(_("Settings"));
    break;

  case AnalysisPage::TEMPTRACE:
    StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"),
                       _("Temp Trace"));
    dialog.SetCaption(sTmp);
    TemperatureChartCaption(sTmp, glide_computer.GetCuSonde());
    info.SetText(sTmp);
    SetCalcCaption(_("Settings"));
    break;

  case AnalysisPage::TASK_SPEED:
    StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"),
                       _("Task Speed"));
    dialog.SetCaption(sTmp);
    info.SetText(_T(""));
    SetCalcCaption(_("Task Calc"));
    break;

  case AnalysisPage::TASK:
    StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"),
                       _("Task"));
    dialog.SetCaption(sTmp);
    FlightStatisticsRenderer::CaptionTask(sTmp, calculated);
    info.SetText(sTmp);
    SetCalcCaption(_("Task calc"));
    break;

  case AnalysisPage::OLC:
    StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"),
                       ContestToString(settings_computer.contest.contest));
    dialog.SetCaption(sTmp);
    SetCalcCaption(_T(""));
    FlightStatisticsRenderer::CaptionOLC(sTmp, settings_computer.contest,
                                         calculated);
    info.SetText(sTmp);
    break;

  case AnalysisPage::AIRSPACE:
    StringFormatUnsafe(sTmp, _T("%s: %s"), _("Analysis"),
                       _("Airspace"));
    dialog.SetCaption(sTmp);
    info.SetText(_T(""));
    SetCalcCaption(_("Warnings"));
    break;

  case AnalysisPage::COUNT:
    gcc_unreachable();
  }

  if (page == AnalysisPage::AIRSPACE)
    chart.UpdateCrossSection(blackboard.Basic(), calculated,
                             settings_computer.task.glide,
                             settings_computer.polar.glide_polar_task,
                             blackboard.GetMapSettings());


  chart.Invalidate();
}
void
TaskRulesConfigPanel::Prepare(ContainerWindow &parent, const PixelRect &rc)
{
  const ComputerSettings &settings_computer = CommonInterface::GetComputerSettings();
  const TaskBehaviour &task_behaviour = settings_computer.task;
  const ContestSettings &contest_settings = settings_computer.contest;

  RowFormWidget::Prepare(parent, rc);

  AddFloat(_("Start max. speed"), _("Maximum speed allowed in start observation zone.  Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(300), fixed(5), false, UnitGroup::HORIZONTAL_SPEED,
           task_behaviour.ordered_defaults.start_constraints.max_speed);
  SetExpertRow(StartMaxSpeed);

  AddFloat(_("Start max. speed margin"),
           _("Maximum speed above maximum start speed to tolerate.  Set to 0 for no tolerance."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(300), fixed(5), false, UnitGroup::HORIZONTAL_SPEED,
           task_behaviour.start_margins.max_speed_margin);
  SetExpertRow(StartMaxSpeedMargin);

  AddSpacer();
  SetExpertRow(spacer_1);

  AddFloat(_("Start max. height"),
           _("Maximum height based on start height reference (AGL or MSL) while starting the task.  "
               "Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.ordered_defaults.start_constraints.max_height));
  SetExpertRow(StartMaxHeight);

  AddFloat(_("Start max. height margin"),
           _("Maximum height above maximum start height to tolerate.  Set to 0 for no tolerance."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.start_margins.max_height_margin));
  SetExpertRow(StartMaxHeightMargin);

  static constexpr StaticEnumChoice altitude_reference_list[] = {
    { (unsigned)AltitudeReference::AGL, N_("AGL"),
      N_("Reference is altitude above mean sea level."), },
    { (unsigned)AltitudeReference::MSL, N_("MSL"),
      N_("Reference is the height above the task point."), },
    { 0 }
  };

  AddEnum(_("Start height ref."),
          _("Reference used for start max height rule."),
          altitude_reference_list,
          (unsigned)task_behaviour.ordered_defaults.start_constraints.max_height_ref);
  SetExpertRow(StartHeightRef);

  AddSpacer();
  SetExpertRow(spacer_2);

  AddFloat(_("Finish min. height"),
           _("Minimum height based on finish height reference (AGL or MSL) while finishing the task.  "
               "Set to 0 for no limit."),
           _T("%.0f %s"), _T("%.0f"), fixed(0), fixed(10000), fixed(50), false, UnitGroup::ALTITUDE,
           fixed(task_behaviour.ordered_defaults.finish_constraints.min_height));
  SetExpertRow(FinishMinHeight);

  AddEnum(_("Finish height ref."),
          _("Reference used for finish min height rule."),
          altitude_reference_list,
          (unsigned)task_behaviour.ordered_defaults.finish_constraints.min_height_ref);
  SetExpertRow(FinishHeightRef);

  AddSpacer();
  SetExpertRow(spacer_3);

  const StaticEnumChoice contests_list[] = {
    { (unsigned)Contest::OLC_FAI, ContestToString(Contest::OLC_FAI),
      N_("Conforms to FAI triangle rules. Three turns and common start and finish. No leg less than 28% "
          "of total except for tasks longer than 500km: No leg less than 25% or larger than 45%.") },
    { (unsigned)Contest::OLC_CLASSIC, ContestToString(Contest::OLC_CLASSIC),
      N_("Up to seven points including start and finish, finish height must not be lower than "
          "start height less 1000 meters.") },
    { (unsigned)Contest::OLC_LEAGUE, ContestToString(Contest::OLC_LEAGUE),
      N_("The most recent contest with Sprint task rules.") },
    { (unsigned)Contest::OLC_PLUS, ContestToString(Contest::OLC_PLUS),
      N_("A combination of Classic and FAI rules. 30% of the FAI score are added to the Classic score.") },
    { (unsigned)Contest::DMST, ContestToString(Contest::DMST),
      /* German competition, no translation */
      _T("Deutsche Meisterschaft im Streckensegelflug.") },
    { (unsigned)Contest::XCONTEST, ContestToString(Contest::XCONTEST),
      _T("tbd.") },
    { (unsigned)Contest::DHV_XC, ContestToString(Contest::DHV_XC),
      _T("tbd.") },
    { (unsigned)Contest::SIS_AT, ContestToString(Contest::SIS_AT),
      _T("tbd.") },
    { (unsigned)Contest::NET_COUPE, ContestToString(Contest::NET_COUPE),
      N_("The FFVV NetCoupe \"libre\" competiton.") },
    { 0 }
  };
  AddEnum(_("On-Line Contest"),
      _("Select the rules used for calculating optimal points for the On-Line Contest. "
          "The implementation  conforms to the official release 2010, Sept.23."),
          contests_list, (unsigned)contest_settings.contest);

  AddBoolean(_("Predict Contest"),
             _("If enabled, then the next task point is included in the "
               "score calculation, assuming that you will reach it."),
             contest_settings.predict);
}