Ejemplo n.º 1
0
        // Create highlights to and from a point to course controls. If controlDrag is set (optional), it is
        // used to get the correct bends for legs.
        // Static because it is used from DragControlMode also.
        public static CourseObj[] CreateLegHighlights(EventDB eventDB, PointF newPoint, Id <ControlPoint> controlDrag, ControlPointKind controlKind, Id <CourseControl> courseControlId1, Id <CourseControl> courseControlId2, float courseObjRatio, CourseAppearance appearance)
        {
            List <CourseObj> highlights = new List <CourseObj>();

            if (courseControlId1.IsNotNone)
            {
                Id <ControlPoint> controlId1 = eventDB.GetCourseControl(courseControlId1).control;
                ControlPoint      control1   = eventDB.GetControl(controlId1);
                LegCourseObj      highlight  = CreateLegHighlight(eventDB, control1.location, control1.kind, controlId1, newPoint, controlKind, controlDrag, courseObjRatio, appearance);
                if (highlight != null)
                {
                    highlights.Add(highlight);
                }
            }

            if (courseControlId2.IsNotNone)
            {
                Id <ControlPoint> controlId2 = eventDB.GetCourseControl(courseControlId2).control;
                ControlPoint      control2   = eventDB.GetControl(controlId2);
                LegCourseObj      highlight  = CreateLegHighlight(eventDB, newPoint, controlKind, controlDrag, control2.location, control2.kind, controlId2, courseObjRatio, appearance);
                if (highlight != null)
                {
                    highlights.Add(highlight);
                }
            }

            return(highlights.ToArray());
        }
Ejemplo n.º 2
0
 // Get all the boxes we are going to fill into an array.
 // This is just all the regular controls from the course view.
 List <CourseView.ControlView> GetAllBoxes()
 {
     return
         (courseView.ControlViews.FindAll(delegate(CourseView.ControlView ctlView)
     {
         return ctlView.controlId.IsNotNone && eventDB.GetControl(ctlView.controlId).kind == ControlPointKind.Normal;
     }));
 }
Ejemplo n.º 3
0
        public void AddControlGap1()
        {
            Setup("modes\\speciallegs.ppen");

            // Select course 1.
            controller.SelectTab(1);       // Course 1.
            CheckHighlightedLines(controller, -1, -1);

            // Click on control to select it.
            MapViewer.DragAction dragAction = controller.LeftButtonDown(Pane.Map, new PointF(27F, 41F), 0.3F);
            Assert.AreEqual(MapViewer.DragAction.DelayedDrag, dragAction);
            controller.LeftButtonClick(Pane.Map, new PointF(27F, 41F), 0.3F);

            // Begin the add bend mode.
            controller.BeginAddGap();

            // Should have crosshair cursor
            ui.MouseMoved(26.1F, 31.5F, 0.3F);
            Cursor cursor = controller.GetMouseCursor(Pane.Map, new PointF(26.1F, 31.5F), 0.3F);

            Assert.AreSame(Cursors.Cross, cursor);

            // And the adding bend text.
            Assert.AreEqual(StatusBarText.AddingControlGap, controller.StatusText);

            // Check the highlights
            CourseObj[] highlights = (CourseObj[])controller.GetHighlights(Pane.Map);
            Assert.AreEqual(1, highlights.Length);
            Assert.AreEqual(@"Control:        control:4  course-control:4  scale:1  location:(25.1508,40.99792)  gaps:",
                            highlights[0].ToString());

            // Click to add a gap.
            dragAction = controller.LeftButtonDown(Pane.Map, new PointF(26.1F, 31.5F), 0.3F);
            Assert.AreEqual(MapViewer.DragAction.DelayedDrag, dragAction);
            controller.LeftButtonClick(Pane.Map, new PointF(26.1F, 31.5F), 0.3F);

            // Check the status text
            Assert.AreEqual(StatusBarText.DefaultStatus, controller.StatusText);
            // Check the cursor
            cursor = controller.GetMouseCursor(Pane.Map, new PointF(26.1F, 31.5F), 0.3F);
            Assert.AreSame(Cursors.Default, cursor);

            // Check the highlights
            highlights = (CourseObj[])controller.GetHighlights(Pane.Map);
            Assert.AreEqual(2, highlights.Length);
            Assert.AreEqual(@"Control:        control:4  course-control:4  scale:1  location:(25.1508,40.99792)  gaps:260.707031:290.707031",
                            highlights[0].ToString());
            Assert.AreEqual(@"ControlNumber:  control:4  course-control:4  scale:1  text:3  top-left:(21.3,51.07)
                font-name:Roboto  font-style:Regular  font-height:5.57",
                            highlights[1].ToString());

            // Make sure the control has a new gap.
            ControlPoint control = eventDB.GetControl(ControlId(4));

            CollectionAssert.AreEqual(new CircleGap[] { new CircleGap(260.707031F, 290.707031F) }, control.gaps[10000]);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Create the text version of a particular control point.
        /// The distanceText parameter is used for finish, marked route end,
        /// and other similar features, and be the distance, already rounded with "m" suffix. Use "" if none.
        /// Custom text for the control or for symbols are taken into account.
        /// </summary>
        public string CreateTextForControl(Id <ControlPoint> controlId, string distanceText)
        {
            ControlPoint controlPoint = eventDB.GetControl(controlId);

            // If there is custom text, just return it.
            if (!string.IsNullOrEmpty(controlPoint.descriptionText))
            {
                return(controlPoint.descriptionText);
            }

            string text;

            switch (controlPoint.kind)
            {
            case ControlPointKind.Normal:
                text = CreateTextForNormalControl(controlPoint);
                break;

            case ControlPointKind.Start:
            case ControlPointKind.MapExchange:
                text = CreateTextForStartControl(controlPoint);
                break;

            case ControlPointKind.Finish:
            case ControlPointKind.CrossingPoint:
            case ControlPointKind.MapIssue:
                text = CreateTextForDirective(controlPoint.symbolIds[0], distanceText);
                break;

            default:
                Debug.Fail("bad control point kind"); text = ""; break;
            }

            return(CapitalizeFirstLetter(text));
        }
Ejemplo n.º 5
0
        // Determine the type of flagging
        private static string FlaggingType(EventDB eventDB, Id <ControlPoint> controlId1, Id <ControlPoint> controlId2, Id <Leg> legId)
        {
            string       flaggingType = SelectionDescriptionText.None;
            FlaggingKind kind         = QueryEvent.GetLegFlagging(eventDB, controlId1, controlId2, legId);

            switch (kind)
            {
            case FlaggingKind.All: flaggingType = SelectionDescriptionText.EntireLeg; break;

            case FlaggingKind.Begin: flaggingType = SelectionDescriptionText.AwayFromControl; break;

            case FlaggingKind.End: flaggingType = SelectionDescriptionText.IntoControl; break;
            }

            // We use slightly different wording based on the finish control.
            ControlPoint ending = eventDB.GetControl(controlId2);

            if (ending.kind == ControlPointKind.Finish)
            {
                // finish control can influence flagging!
                if (ending.symbolIds[0] == "14.2" && kind == FlaggingKind.None)
                {
                    flaggingType = SelectionDescriptionText.FinishFunnel;
                }
                else if (ending.symbolIds[0] == "14.2" && kind == FlaggingKind.End)
                {
                    flaggingType = SelectionDescriptionText.IntoFinishFunnel;
                }
            }

            return(flaggingType);
        }
Ejemplo n.º 6
0
        public void DontUpdateCircleGapsForItemScaling()
        {
            UndoMgr undomgr = new UndoMgr(5);
            EventDB eventDB = new EventDB(undomgr);

            eventDB.Load(TestUtil.GetTestFile("eventdb\\CircleGapScaling_MapScale_new.ppen"));
            eventDB.Validate();

            ControlPoint control;

            control = eventDB.GetControl(ControlId(4));
            Assert.IsTrue(control.gaps.Count == 1 && control.gaps.ContainsKey(5000));

            control = eventDB.GetControl(ControlId(5));
            Assert.IsTrue(control.gaps.Count == 1 && control.gaps.ContainsKey(10000));

            control = eventDB.GetControl(ControlId(6));
            Assert.IsTrue(control.gaps.Count == 1 && control.gaps.ContainsKey(15000));
        }
Ejemplo n.º 7
0
        public void RotateMandatoryCrossing()
        {
            CourseObj[] highlights;

            // Select Course 3
            controller.SelectTab(3);

            // Select mandatory crossing point.
            var dragAction = controller.LeftButtonDown(Pane.Map, new PointF(25.4F, 25.5F), 0.2F);

            Assert.AreEqual(MapViewer.DragAction.DelayedDrag, dragAction);
            controller.LeftButtonClick(Pane.Map, new PointF(25.4F, 25.5F), 0.3F);

            highlights = (CourseObj[])controller.GetHighlights(Pane.Map);
            Assert.AreEqual(1, highlights.Length);
            Assert.AreEqual(82, highlights[0].controlId.id);

            // Begin rotating mode.
            controller.BeginRotate();
            highlights = (CourseObj[])controller.GetHighlights(Pane.Map);
            Assert.AreEqual(1, highlights.Length);
            CrossingCourseObj obj = (CrossingCourseObj)highlights[0];

            Assert.AreEqual(new PointF(25.9F, 26.4F), obj.location);

            // Should have correct status text.
            Assert.AreEqual(StatusBarText.RotatingObject, controller.StatusText);

            // Move the mouse somewhere (mouse buttons are up).
            ui.MouseMoved(31, -11, 0.1F);

            // The highlight should be in the same place, but rotated.
            highlights = (CourseObj[])controller.GetHighlights(Pane.Map);
            Assert.AreEqual(1, highlights.Length);
            obj = (CrossingCourseObj)highlights[0];
            Assert.AreEqual(new PointF(25.9F, 26.4F), obj.location);
            Assert.AreEqual(187.7F, obj.orientation, 0.1F);

            // Mouse down somewhere.
            MapViewer.DragAction action = controller.LeftButtonDown(Pane.Map, new PointF(44, 29), 0.1F);

            // The highlight should be in the same place, but rotated again.
            highlights = (CourseObj[])controller.GetHighlights(Pane.Map);
            Assert.AreEqual(1, highlights.Length);
            obj = (CrossingCourseObj)highlights[0];
            Assert.AreEqual(new PointF(25.9F, 26.4F), obj.location);
            Assert.AreEqual(278.2F, obj.orientation, 0.1F);

            // The control should have its orientation changed, but not its position.
            ControlPoint control = eventDB.GetControl(ControlId(82));

            Assert.AreEqual(new PointF(25.9F, 26.4F), control.location);
            Assert.AreEqual(278.2F, control.orientation, 0.1F);
        }
Ejemplo n.º 8
0
        // Describe a control point.
        private static TextPart[] DescribeControlPoint(SymbolDB symbolDB, EventDB eventDB, Id <ControlPoint> controlId, DescKind descKind)
        {
            Debug.Assert(descKind == DescKind.DescPane || descKind == DescKind.Tooltip);

            List <TextPart> list    = new List <TextPart>();
            ControlPoint    control = eventDB.GetControl(controlId);

            // Control name/code.
            list.Add(new TextPart(TextFormat.Title, Util.ControlPointName(eventDB, controlId, NameStyle.Long)));

            // Control location.
            if (descKind == DescKind.DescPane)
            {
                list.Add(new TextPart(TextFormat.Header, SelectionDescriptionText.Location + "  "));
                list.Add(new TextPart(TextFormat.SameLine, string.Format("({0:##0.0}, {1:##0.0})", control.location.X, control.location.Y)));
            }

            // Which courses is it used in?
            list.Add(new TextPart(TextFormat.Header, (descKind == DescKind.Tooltip ? SelectionDescriptionText.UsedIn : SelectionDescriptionText.UsedInCourses)));
            Id <Course>[] coursesUsingControl = QueryEvent.CoursesUsingControl(eventDB, controlId);
            list.Add(new TextPart(descKind == DescKind.Tooltip ? TextFormat.SameLine : TextFormat.NewLine, CourseListText(eventDB, coursesUsingControl)));

            // What is the competitor load?
            int load   = QueryEvent.GetControlLoad(eventDB, controlId);
            int visits = QueryEvent.GetControlVisitLoad(eventDB, controlId);

            if (load >= 0)
            {
                list.Add(new TextPart(TextFormat.Header, (descKind == DescKind.Tooltip ? SelectionDescriptionText.Load : SelectionDescriptionText.CompetitorLoad)));
                if (visits != load)
                {
                    list.Add(new TextPart(TextFormat.SameLine, string.Format("{0}/{1}", load, visits)));
                }
                else
                {
                    list.Add(new TextPart(TextFormat.SameLine, string.Format("{0}", load)));
                }
            }

            // Text version of the descriptions
            if (descKind == DescKind.DescPane)
            {
                Textifier textifier = new Textifier(eventDB, symbolDB, QueryEvent.GetDescriptionLanguage(eventDB));
                string    descText  = textifier.CreateTextForControl(controlId, null);
                list.Add(new TextPart(TextFormat.Header, SelectionDescriptionText.TextDescription));
                list.Add(new TextPart(TextFormat.NewLine, descText));
            }

            return(list.ToArray());
        }
Ejemplo n.º 9
0
        // Writes information about all the controls in the event of a certain kind.
        // The code prefix is used for controls without a code set (like start/finish)
        void WriteControls(ControlPointKind controlKind, string codePrefix)
        {
            int emptyCodeSuffix = 1;

            foreach (Id <ControlPoint> controlId in eventDB.AllControlPointIds)
            {
                ControlPoint control = eventDB.GetControl(controlId);
                if (control.kind == controlKind)
                {
                    // Get the code. Synthesize a unique code if necessary.
                    string code = control.code;
                    if (string.IsNullOrEmpty(code))
                    {
                        code = codePrefix + (emptyCodeSuffix++).ToString();
                    }

                    // Record the controlid->code mapping for later use.
                    controlCodeMap[controlId] = code;

                    WriteControlPoint(controlKind, control, code);
                }
            }
        }
Ejemplo n.º 10
0
        // Left mouse button selects the object clicked on, or drag something already selected.
        public override MapViewer.DragAction LeftButtonDown(Pane pane, PointF location, float pixelSize, ref bool displayUpdateNeeded)
        {
            if (pane == Pane.Map)
            {
                CourseLayout activeCourse = controller.GetCourseLayout();
                CourseObj    clickedObject;
                PointF       handleLocation;
                Cursor       handleCursor;

                // Area we initiating a drag of a corner?
                clickedObject = HitTestHandle(location, pixelSize, out handleLocation, out handleCursor);
                if (clickedObject != null)
                {
                    // being dragging the corner
                    DragHandleMode commandMode = new DragHandleMode(controller, clickedObject, handleLocation, location);
                    controller.SetCommandMode(commandMode);
                    displayUpdateNeeded = true;
                    return(MapViewer.DragAction.ImmediateDrag);
                }

                // Are we initiating a drag of an object?
                clickedObject = HitTestDraggable(location, pixelSize);
                if (clickedObject != null)
                {
                    // Begin dragging the clicked object.
                    DragObjectMode commandMode = new DragObjectMode(controller, eventDB, selectionMgr, clickedObject, location);
                    controller.SetCommandMode(commandMode);
                    displayUpdateNeeded = true;
                    return(MapViewer.DragAction.ImmediateDrag);
                }

                return(MapViewer.DragAction.DelayedDrag);
            }
            else if (pane == Pane.Topology)
            {
                CourseObj clickedObject = HitTest(pane, location, pixelSize, (co => !(co is TopologyDropTargetCourseObj)));
                if (clickedObject is ControlNumberCourseObj || clickedObject is CrossingCourseObj ||
                    (clickedObject is StartCourseObj && (eventDB.GetControl(((StartCourseObj)clickedObject).controlId).kind == ControlPointKind.MapExchange)))
                {
                    // Can drag control numbers, crossing points, or map exchanges.
                    selectionMgr.SelectCourseObject(clickedObject);
                    displayUpdateNeeded = true;
                    return(MapViewer.DragAction.DelayedDrag);
                }
            }

            return(MapViewer.DragAction.None);
        }
Ejemplo n.º 11
0
        public void Version100beta2()
        {
            TestLoadFile("compatibility\\Sample Event_100b2.ppen");

            // Make sure gaps converted correctly.
            EventDB      eventDB = controller.GetEventDB();
            ControlPoint control = eventDB.GetControl(ControlId(3));

            Assert.AreEqual(2, control.gaps.Count);
            CollectionAssert.AreEqual(control.gaps[10000], CircleGap.ComputeCircleGaps(0x1FFFFF80));
            CollectionAssert.AreEqual(control.gaps[15000], CircleGap.ComputeCircleGaps(0x1FFFFF80));

            // Make sure all controls scale, description kind is correct by default.
            Assert.AreEqual(15000, eventDB.GetEvent().allControlsPrintScale);
            Assert.AreEqual(DescriptionKind.Symbols, eventDB.GetEvent().allControlsDescKind);
        }
Ejemplo n.º 12
0
        // Hit test a point to see if it is over an existing control, or will create a new control.
        Id <ControlPoint> HitTestPoint(PointF mouseLocation, float pixelSize, out PointF highlightLocation)
        {
            if (allControls)
            {
                // If all controls, always new control.
                highlightLocation = new PointF(mouseLocation.X + PIXELOFFSETX * pixelSize, mouseLocation.Y + PIXELOFFSETY * pixelSize);
                return(Id <ControlPoint> .None);
            }
            else
            {
                // Are we over a control we might add?
                CourseLayout   layout    = controller.GetCourseLayout();
                PointCourseObj courseObj = layout.HitTest(mouseLocation, pixelSize, CourseLayer.AllControls, (co => co is PointCourseObj)) as PointCourseObj;
                if (courseObj != null)
                {
                    highlightLocation = courseObj.location;
                    return(courseObj.controlId);
                }
                else
                {
                    courseObj = layout.HitTest(mouseLocation, pixelSize, CourseLayer.MainCourse, (co => co is PointCourseObj)) as PointCourseObj;
                    if (courseObj != null &&
                        courseObj.controlId.IsNotNone)
                    {
                        // Allow selecting a control in the current course for a butterfly course. But -- it must be a normal control or crossing point, and not adjacent to the control being inserted.
                        if (eventDB.GetControl(courseObj.controlId).kind == controlKind && (controlKind == ControlPointKind.Normal || controlKind == ControlPointKind.CrossingPoint))
                        {
                            Id <CourseControl> courseControl1, courseControl2;
                            CourseDesignator   courseDesignator;
                            LegInsertionLoc    legInsertionLoc;

                            GetControlInsertionPoint(courseObj.location, out courseDesignator, out courseControl1, out courseControl2, out legInsertionLoc);
                            if (eventDB.GetCourse(courseDesignator.CourseId).kind != CourseKind.Score &&
                                (exchangeAtControl ||
                                 (courseObj.courseControlId != courseControl1 && courseObj.courseControlId != courseControl2)))
                            {
                                highlightLocation = courseObj.location;
                                return(courseObj.controlId);
                            }
                        }
                    }

                    highlightLocation = new PointF(mouseLocation.X + PIXELOFFSETX * pixelSize, mouseLocation.Y + PIXELOFFSETY * pixelSize);
                    return(Id <ControlPoint> .None);
                }
            }
        }
Ejemplo n.º 13
0
        public override void LeftButtonDrag(Pane pane, PointF location, PointF locationStart, float pixelSize, ref bool displayUpdateNeeded)
        {
            Debug.Assert(pane == Pane.Map);

            currentLocation = location;

            // Update the highlight.
            courseObjectDrag = ((CourseObj)courseObjectStart.Clone());
            courseObjectDrag.Offset(location.X - startDrag.X, location.Y - startDrag.Y);

            // If we're dragging a control in a course (not all controls) then add additional highlights for the leg(s) to/from the control.
            if (AreDraggingControlPoint() && courseObjectStart.courseControlId.IsNotNone)
            {
                ControlPoint control    = eventDB.GetControl(courseObjectStart.controlId);
                CourseView   courseView = selectionMgr.ActiveCourseView;

                // Find index of this course control in the course view.
                int index;
                for (index = 0; index < courseView.ControlViews.Count; ++index)
                {
                    if (courseView.ControlViews[index].courseControlIds.Contains(courseObjectStart.courseControlId))
                    {
                        break;
                    }
                }

                if (index < courseView.ControlViews.Count)
                {
                    // Get previous and next controls.
                    int prevIndex = courseView.GetPrevControl(index), nextIndex = courseView.GetNextControl(index);
                    Id <CourseControl> prevCourseControl = (prevIndex >= 0) ? courseView.ControlViews[prevIndex].courseControlIds[0] : Id <CourseControl> .None;
                    Id <CourseControl> nextCourseControl = (nextIndex >= 0) ? courseView.ControlViews[nextIndex].courseControlIds[0] : Id <CourseControl> .None;

                    // Get additional highlights to and from those controls.
                    additionalHighlights = AddControlMode.CreateLegHighlights(eventDB, ((PointCourseObj)courseObjectDrag).location, courseObjectDrag.controlId, control.kind, prevCourseControl, nextCourseControl,
                                                                              courseView.CourseObjRatio(courseObjectStart.appearance), courseObjectStart.appearance);

                    // If we're dragging the start, update the angle of the start appropriately.
                    if ((control.kind == ControlPointKind.Start || control.kind == ControlPointKind.MapExchange || control.kind == ControlPointKind.MapIssue) &&
                        additionalHighlights.Length > 0 &&
                        (courseView.Kind == CourseView.CourseViewKind.Normal || courseView.Kind == CourseView.CourseViewKind.AllVariations))
                    {
                        SymPath  pathFromStart = ((LineCourseObj)additionalHighlights[additionalHighlights.Length - 1]).path;
                        PointF[] pts           = pathFromStart.FlattenedPoints;
                        double   angleOut      = Math.Atan2(pts[1].Y - pts[0].Y, pts[1].X - pts[0].X);
                        if (!double.IsNaN(angleOut))
                        {
                            float angleInDegrees = (float)Geometry.RadiansToDegrees(angleOut);
                            if (control.kind == ControlPointKind.MapIssue)
                            {
                                ((MapIssueCourseObj)courseObjectDrag).orientation = angleInDegrees;
                            }
                            else
                            {
                                ((StartCourseObj)courseObjectDrag).orientation = angleInDegrees;
                            }
                        }
                    }
                }
            }

            displayUpdateNeeded = true;
        }
Ejemplo n.º 14
0
        // Get the text name for a control. THe Name Style controls how the control points appear:
        // Long:  "Control 32", "Start", "Finish", "Mandatory crossing point".
        // Medium: "32", "Start", "Finish", "Crossing"
        // Short: "32", "S", "F", "C"
        public static string ControlPointName(EventDB eventDB, Id <ControlPoint> controlId, NameStyle style)
        {
            ControlPoint control = eventDB.GetControl(controlId);

            // Control name/code.
            switch (control.kind)
            {
            case ControlPointKind.Normal:
                if (style == NameStyle.Long)
                {
                    return(string.Format(MiscText.Control_Code, control.code));
                }
                else
                {
                    return(string.Format("{0}", control.code));
                }

            case ControlPointKind.Start:
                if (style == NameStyle.Short)
                {
                    return(MiscText.Start_Short);
                }
                else
                {
                    return(MiscText.Start);
                }

            case ControlPointKind.Finish:
                if (style == NameStyle.Short)
                {
                    return(MiscText.Finish_Short);
                }
                else
                {
                    return(MiscText.Finish);
                }

            case ControlPointKind.CrossingPoint:
                if (style == NameStyle.Long)
                {
                    return(MiscText.MandCrossing_Long);
                }
                else if (style == NameStyle.Medium)
                {
                    return(MiscText.MandCrossing_Medium);
                }
                else
                {
                    return(MiscText.MandCrossing_Short);
                }

            case ControlPointKind.MapExchange:
                if (style == NameStyle.Long)
                {
                    return(MiscText.MapExchange_Long);
                }
                else if (style == NameStyle.Medium)
                {
                    return(MiscText.MapExchange_Medium);
                }
                else
                {
                    return(MiscText.MapExchange_Short);
                }

            case ControlPointKind.MapIssue:
                if (style == NameStyle.Long)
                {
                    return(MiscText.MapIssue_Long);
                }
                else if (style == NameStyle.Medium)
                {
                    return(MiscText.MapIssue_Medium);
                }
                else
                {
                    return(MiscText.MapIssue_Short);
                }

            default:
                Debug.Fail("bad control kind");
                return("");
            }
        }
Ejemplo n.º 15
0
        // Create a set of description lines for a course. If "createKey" is true, then lines for a key are created based on any symbols
        // that have custom text. This is typically done only if text description are not already being printed.
        public DescriptionLine[] CreateDescription(bool createKey)
        {
            EventDB eventDB = courseView.EventDB;

            CourseView.CourseViewKind kind = courseView.Kind;
            int scoreColumn             = courseView.ScoreColumn;
            List <DescriptionLine> list = new List <DescriptionLine>(courseView.ControlViews.Count + 4);
            string          text;
            DescriptionLine line;

            DescriptionLine[]           lines;
            Dictionary <string, string> descriptionKey = new Dictionary <string, string>(); // dictionary for any symbols encountered with custom text.

            // Get the first title line.
            text = GetTitleLine1();
            Debug.Assert(text != null);
            lines = GetTitleLineFromText(DescriptionLineKind.Title, text);
            list.AddRange(lines);

            // Get the second title line.
            text = GetTitleLine2();
            if (text != null)
            {
                lines = GetTitleLineFromText(DescriptionLineKind.SecondaryTitle, text);
                list.AddRange(lines);
            }

            // Get the header line, depending on the kind of course.
            switch (kind)
            {
            case CourseView.CourseViewKind.Normal:
                line = GetNormalHeaderLine(); break;

            case CourseView.CourseViewKind.AllControls:
                line = GetAllControlsHeaderLine(); break;

            case CourseView.CourseViewKind.Score:
                line = GetScoreHeaderLine(); break;

            case CourseView.CourseViewKind.AllVariations:
                line = GetAllVariationsHeaderLine(); break;

            default:
                Debug.Fail("unknown CourseViewKind"); line = null;  break;
            }

            if (line != null)
            {
                list.Add(line);
            }

            // Do all the normal lines
            for (int iLine = 0; iLine < courseView.ControlViews.Count; ++iLine)
            {
                CourseView.ControlView controlView   = courseView.ControlViews[iLine];
                ControlPoint           control       = eventDB.GetControl(controlView.controlId);
                CourseControl          courseControl = controlView.courseControlIds[0].IsNone ? null : eventDB.GetCourseControl(controlView.courseControlIds[0]);

                // CONSIDER: this might need to be updated for relay or split controls.
                ControlPoint controlPrev = (iLine > 0) ? eventDB.GetControl(courseView.ControlViews[iLine - 1].controlId) : null;
                ControlPoint controlNext = (iLine < courseView.ControlViews.Count - 1) ? eventDB.GetControl(courseView.ControlViews[iLine + 1].controlId) : null;
                //Id<CourseControl> courseControlIdNext = (iLine < courseView.ControlViews.Count - 1) ? courseView.ControlViews[iLine + 1].courseControlId : Id<CourseControl>.None;
                //CourseControl courseControlNext = courseControlIdNext.IsNotNone ? eventDB.GetCourseControl(coruseControlIdNext) : null;

                // Do the control.control
                if (FilterControl(kind, control, controlPrev, controlNext))
                {
                    // Text associated with the course or course control (before)
                    AddTextLine(list, control.descTextBefore, controlView.courseControlIds[0], controlView.controlId, DescriptionLine.TextLineKind.BeforeControl);
                    if (courseControl != null)
                    {
                        AddTextLine(list, courseControl.descTextBefore, controlView.courseControlIds[0], controlView.controlId, DescriptionLine.TextLineKind.BeforeCourseControl);
                    }

                    // The control itself.
                    if (control.kind == ControlPointKind.Finish ||
                        control.kind == ControlPointKind.CrossingPoint ||
                        control.kind == ControlPointKind.MapIssue)
                    {
                        line = GetDirectiveLine(kind, controlView, iLine > 0 ? courseView.ControlViews[iLine - 1] : null);
                    }
                    else
                    {
                        line = GetRegularLine(kind, scoreColumn, controlView, descriptionKey);
                    }
                    Debug.Assert(line != null);
                    list.Add(line);

                    // Text associated with the course or course control (after)
                    if (courseControl != null)
                    {
                        AddTextLine(list, courseControl.descTextAfter, controlView.courseControlIds[0], controlView.controlId, DescriptionLine.TextLineKind.AfterCourseControl);
                    }
                    AddTextLine(list, control.descTextAfter, controlView.courseControlIds[0], controlView.controlId, DescriptionLine.TextLineKind.AfterControl);
                }

                // Add any map exchange lines.
                if (courseView.Kind == CourseView.CourseViewKind.Normal || courseView.Kind == CourseView.CourseViewKind.AllVariations)
                {
                    if (controlNext != null && controlNext.kind == ControlPointKind.MapExchange)
                    {
                        line = GetMapExchangeLine(controlView, courseView.ControlViews[controlView.legTo[0]]);
                        list.Add(line);
                    }
                    else if (courseControl != null && courseControl.exchange && control.kind != ControlPointKind.MapExchange && controlPrev != null)
                    {
                        line = GetMapExchangeAtControlLine(controlView);
                        list.Add(line);
                    }
                }

                // Do the leg (if any).
                if (controlView.legTo != null && controlView.legTo.Length > 0)
                {
                    Id <Leg> legId = controlView.legId[0];
                    Leg      leg   = (legId.IsNotNone) ? eventDB.GetLeg(legId) : null;
                    if (FilterLeg(kind, control, controlNext, leg))
                    {
                        line = GetMarkedRouteLine(controlView, courseView.ControlViews[controlView.legTo[0]], legId);
                        Debug.Assert(line != null);
                        list.Add(line);
                    }
                }
            }

            // Add the key if desired.
            if (createKey)
            {
                foreach (string symbolId in descriptionKey.Keys)
                {
                    line          = new DescriptionLine();
                    line.kind     = DescriptionLineKind.Key;
                    line.boxes    = new object[2];
                    line.boxes[0] = symbolDB[symbolId];
                    line.boxes[1] = descriptionKey[symbolId];

                    list.Add(line);
                }
            }

            // And we're done!
            return(list.ToArray());
        }
Ejemplo n.º 16
0
        // Get a regular 8-box line for a start or regular control.
        private DescriptionLine GetRegularLine(CourseView.CourseViewKind kind, int scoreColumn, CourseView.ControlView controlView, Dictionary <string, string> descriptionKey)
        {
            Event         ev      = eventDB.GetEvent();
            ControlPoint  control = eventDB.GetControl(controlView.controlId);
            CourseControl courseControl;

            if (controlView.courseControlIds[0].IsNone)
            {
                courseControl = null;
            }
            else
            {
                courseControl = eventDB.GetCourseControl(controlView.courseControlIds[0]);
            }

            Debug.Assert(control.kind == ControlPointKind.Normal || control.kind == ControlPointKind.Start || control.kind == ControlPointKind.MapExchange);

            DescriptionLine line = new DescriptionLine();

            line.kind  = DescriptionLineKind.Normal;
            line.boxes = new object[8];

            // Box A: ordinal or start triangle or points.
            if (control.kind == ControlPointKind.Start || control.kind == ControlPointKind.MapExchange)
            {
                line.boxes[0] = symbolDB["start"];
            }
            else if (kind != CourseView.CourseViewKind.AllControls && controlView.ordinal > 0)
            {
                line.boxes[0] = Convert.ToString(controlView.ordinal);
            }
            else
            {
                line.boxes[0] = null;
            }

            // Box B: code of the control
            if (control.kind == ControlPointKind.Normal)
            {
                line.boxes[1] = Convert.ToString(control.code);
            }

            // Boxes C-H, from the symbols
            for (int i = 2; i < 8; ++i)
            {
                String symbolID = control.symbolIds[i - 2];
                if (symbolID != null)
                {
                    line.boxes[i] = symbolDB[control.symbolIds[i - 2]];

                    // See if we need to add this to the key.
                    bool addToKey;
                    if (ev.customSymbolKey.TryGetValue(symbolID, out addToKey) && addToKey && Symbol.ContainsLanguage(ev.customSymbolText[symbolID], language))
                    {
                        descriptionKey[symbolID] = Symbol.GetBestSymbolText(symbolDB, ev.customSymbolText[symbolID], language, false, "", "");
                    }
                }
            }

            // Box F -- may be text instead of a symbol.
            if (control.columnFText != null)
            {
                Debug.Assert(line.boxes[5] == null);
                line.boxes[5] = control.columnFText;
            }

            // Put points in the score column, for a score course.
            if (control.kind == ControlPointKind.Normal && scoreColumn >= 0 && courseControl != null)
            {
                int points = courseControl.points;
                if (points > 0)
                {
                    line.boxes[scoreColumn] = Convert.ToString(courseControl.points);
                }
                else
                {
                    line.boxes[scoreColumn] = null;
                }
            }

            // Get the text version of the control using the Textifier.
            Textifier textifier = new Textifier(eventDB, symbolDB, language);

            line.textual = textifier.CreateTextForControl(controlView.controlId, "");

            // The course control ID, for use in coordinating the selection
            line.controlId       = controlView.controlId;
            line.courseControlId = controlView.courseControlIds[0];

            return(line);
        }
Ejemplo n.º 17
0
        public void AutoRenumber2()
        {
            UndoMgr undomgr = new UndoMgr(5);
            EventDB eventDB = new EventDB(undomgr);

            Event ev = new Event();

            Id<ControlPoint>[] ids = new Id<ControlPoint>[10];

            undomgr.BeginCommand(123, "Add controls");
            ids[0] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "64", new PointF()));   //64
            ids[1] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "69", new PointF()));   //69
            ids[2] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "67", new PointF()));   //67
            ids[3] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "71", new PointF()));   //71
            ids[4] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "73", new PointF()));   //65
            ids[5] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "61", new PointF()));   //62
            ids[6] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "66", new PointF()));   //63
            ids[7] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "60", new PointF()));   //60
            ids[8] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "70", new PointF()));   //70
            ev.mapScale = 15000;
            ev.firstControlCode = 60;
            ev.disallowInvertibleCodes = true;
            eventDB.ChangeEvent(ev);

            ChangeEvent.AutoRenumberControls(eventDB);
            undomgr.EndCommand(123);

            Assert.AreEqual("64", eventDB.GetControl(ids[0]).code);
            Assert.AreEqual("69", eventDB.GetControl(ids[1]).code);
            Assert.AreEqual("67", eventDB.GetControl(ids[2]).code);
            Assert.AreEqual("71", eventDB.GetControl(ids[3]).code);
            Assert.AreEqual("65", eventDB.GetControl(ids[4]).code);
            Assert.AreEqual("62", eventDB.GetControl(ids[5]).code);
            Assert.AreEqual("63", eventDB.GetControl(ids[6]).code);
            Assert.AreEqual("60", eventDB.GetControl(ids[7]).code);
            Assert.AreEqual("70", eventDB.GetControl(ids[8]).code);
        }
Ejemplo n.º 18
0
        // Check the validate of the selected course view/selected object and update accordingly.
        void UpdateSelection()
        {
            // Check the selection validity.
            if (!activeCourseDesignator.IsAllControls && !eventDB.IsCoursePresent(activeCourseDesignator.CourseId)) {
                // Active course was deleted. Switch to all controls.
                activeCourseDesignator = CourseDesignator.AllControls;
                ClearSelection();
            }

            // Check that variation still exists.
            if (activeCourseDesignator.IsVariation && QueryEvent.HasVariations(eventDB, activeCourseDesignator.CourseId)) {
                IEnumerable<VariationInfo> variations = QueryEvent.GetAllVariations(eventDB, activeCourseDesignator.CourseId);
                if (!variations.Any(v => v.Equals(activeCourseDesignator.VariationInfo)))
                    activeCourseDesignator = activeCourseDesignator.WithAllVariations();
            }

            // Does the current part still exist?
            int numberOfParts = QueryEvent.CountCourseParts(eventDB, activeCourseDesignator);
            if (!activeCourseDesignator.IsAllControls && !activeCourseDesignator.AllParts && 
                (numberOfParts == 1 || activeCourseDesignator.Part >= numberOfParts)) 
            {
                // No part that large any more.
                if (numberOfParts > 1)
                    activeCourseDesignator = activeCourseDesignator.WithPart(numberOfParts - 1);
                else
                    activeCourseDesignator = activeCourseDesignator.WithAllParts();
                ClearSelection();
            }

            if (selectedCourseControl.IsNotNone && !eventDB.IsCourseControlPresent(selectedCourseControl)) {
                // Selected course control is no longer there.
                selectedCourseControl = Id<CourseControl>.None;
                ClearSelection();
            }

            if (selectedCourseControl.IsNotNone && activeCourseDesignator.IsNotAllControls && 
                (!activeCourseDesignator.AllParts || activeCourseDesignator.IsVariation) && 
                !QueryEvent.IsCourseControlInPart(eventDB, activeCourseDesignator, selectedCourseControl)) {
                // Selected course control is not in active part.
                // Could be allowed if it's the finish.
                Id<ControlPoint> controlId = eventDB.GetCourseControl(selectedCourseControl).control;
                if (!(eventDB.IsControlPresent(controlId) && 
                      eventDB.GetControl(controlId).kind == ControlPointKind.Finish &&
                      QueryEvent.GetPartOptions(eventDB, activeCourseDesignator).ShowFinish))
                {
                    selectedCourseControl = Id<CourseControl>.None;
                    ClearSelection();
                }
            }

            if (selectedCourseControl2.IsNotNone && !eventDB.IsCourseControlPresent(selectedCourseControl2)) {
                // Selected course control 2 is no longer there.
                selectedCourseControl2 = Id<CourseControl>.None;
                ClearSelection();
            }

            if (selectedCourseControl2.IsNotNone && activeCourseDesignator.IsNotAllControls && !activeCourseDesignator.AllParts && 
                !QueryEvent.IsCourseControlInPart(eventDB, activeCourseDesignator, selectedCourseControl2)) {
                // Selected course control 2 is not in active part.
                selectedCourseControl2 = Id<CourseControl>.None;
                ClearSelection();
            }

            if (selectedControl.IsNotNone && !eventDB.IsControlPresent(selectedControl)) {
                // Selected control is no longer there.
                ClearSelection();
            }

            if (selectedSpecial.IsNotNone && !eventDB.IsSpecialPresent(selectedSpecial)) {
                // Selected special is no longer there.
                ClearSelection();
            }

            if (selectedSpecial.IsNotNone && !(activeCourseDesignator.IsAllControls || QueryEvent.CourseContainsSpecial(eventDB, activeCourseDesignator, selectedSpecial))) {
                // Selected special is not in current course
                ClearSelection();
            }
        }
Ejemplo n.º 19
0
        public void AutoRenumber()
        {
            UndoMgr undomgr = new UndoMgr(5);
            EventDB eventDB = new EventDB(undomgr);

            Event ev = new Event();

            Id<ControlPoint>[] ids = new Id<ControlPoint>[10];

            undomgr.BeginCommand(123, "Add controls");
            ids[0] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "36", new PointF()));   //36
            ids[1] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "33", new PointF()));   //33
            ids[2] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "AB", new PointF()));   //40
            ids[3] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "34", new PointF()));   //34
            ids[4] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "31", new PointF()));   //35
            ids[5] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "51", new PointF()));   //39
            ids[6] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "37", new PointF()));   //37
            ids[7] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "38", new PointF()));   //38
            ids[8] = eventDB.AddControlPoint(new ControlPoint(ControlPointKind.Normal, "FA", new PointF()));   //41
            ev.mapScale = 15000;
            ev.firstControlCode = 33;
            ev.disallowInvertibleCodes = false;
            eventDB.ChangeEvent(ev);

            ChangeEvent.AutoRenumberControls(eventDB);
            undomgr.EndCommand(123);

            Assert.AreEqual("36", eventDB.GetControl(ids[0]).code);
            Assert.AreEqual("33", eventDB.GetControl(ids[1]).code);
            Assert.AreEqual("40", eventDB.GetControl(ids[2]).code);
            Assert.AreEqual("34", eventDB.GetControl(ids[3]).code);
            Assert.AreEqual("35", eventDB.GetControl(ids[4]).code);
            Assert.AreEqual("39", eventDB.GetControl(ids[5]).code);
            Assert.AreEqual("37", eventDB.GetControl(ids[6]).code);
            Assert.AreEqual("38", eventDB.GetControl(ids[7]).code);
            Assert.AreEqual("41", eventDB.GetControl(ids[8]).code);
        }