Ejemplo n.º 1
0
        private List <Marker> GetDisplayMarkers()
        {
            // No markers?
            if (this.markersOnCurrentFile == null)
            {
                return(null);
            }

            // The markable canvas uses a simple list of markers to decide what to do.
            // So we just create that list here, where we also reset the emphasis of some of the markers
            List <Marker>    markers         = new List <Marker>();
            DataEntryCounter selectedCounter = this.FindSelectedCounter();
            int markersOnCurrentFileCount    = this.markersOnCurrentFile.Count;

            for (int counter = 0; counter < markersOnCurrentFileCount; counter++)
            {
                MarkersForCounter markersForCounter = this.markersOnCurrentFile[counter];
                if (this.DataEntryControls.ControlsByDataLabel.TryGetValue(markersForCounter.DataLabel, out _) == false)
                {
                    // If we can't find the counter, its likely because the control was made invisible in the template,
                    // which means that there is no control associated with the marker. So just don't create the
                    // markers associated with this control. Note that if the control is later made visible in the template,
                    // the markers will then be shown.
                    continue;
                }

                // Update the emphasise for each tag to reflect how the user is interacting with tags
                DataEntryCounter currentCounter = (DataEntryCounter)this.DataEntryControls.ControlsByDataLabel[markersForCounter.DataLabel];
                bool             emphasize      = markersForCounter.DataLabel == this.State.MouseOverCounter;
                foreach (Marker marker in markersForCounter.Markers)
                {
                    // the first time through, show an annotation. Otherwise we clear the flags to hide the annotation.
                    if (marker.ShowLabel && !marker.LabelShownPreviously)
                    {
                        marker.ShowLabel            = true;
                        marker.LabelShownPreviously = true;
                    }
                    else
                    {
                        marker.ShowLabel = false;
                    }

                    if (selectedCounter != null && currentCounter.DataLabel == selectedCounter.DataLabel)
                    {
                        marker.Brush = (SolidColorBrush) new BrushConverter().ConvertFromString(Constant.Defaults.SelectionColour);
                    }
                    else
                    {
                        marker.Brush = (SolidColorBrush) new BrushConverter().ConvertFromString(Constant.Defaults.StandardColour);
                    }

                    marker.Emphasise = emphasize;
                    marker.Tooltip   = currentCounter.Label;
                    markers.Add(marker); // Add the MetaTag in the list
                }
            }
            return(markers);
        }
        public void CreateControls(FileDatabase database, DataEntryHandler dataEntryPropagator)
        {
            // Depending on how the user interacts with the file import process image set loading can be aborted after controls are generated and then
            // another image set loaded.  Any existing controls therefore need to be cleared.
            this.ControlGrid.Children.Clear();
            this.Controls.Clear();
            this.ControlsByDataLabel.Clear();

            DataEntryDateTime dateTimeControl = null;
            DataEntryUtcOffset utcOffsetControl = null;
            List<DataEntryControl> visibleControls = new List<DataEntryControl>();
            foreach (ControlRow control in database.Controls)
            {
                // no point in generating a control if it doesn't render in the UX
                if (control.Visible == false)
                {
                    continue;
                }

                if (control.Type == Constant.DatabaseColumn.DateTime)
                {
                    dateTimeControl = new DataEntryDateTime(control, this);
                    visibleControls.Add(dateTimeControl);
                }
                else if (control.Type == Constant.DatabaseColumn.File ||
                         control.Type == Constant.DatabaseColumn.RelativePath ||
                         control.Type == Constant.Control.Note)
                {
                    // standard controls rendering as notes aren't editable by the user
                    List<string> autocompletions = null;
                    bool readOnly = control.Type != Constant.Control.Note;
                    if (readOnly == false)
                    {
                        autocompletions = new List<string>(database.GetDistinctValuesInFileDataColumn(control.DataLabel));
                    }
                    DataEntryNote noteControl = new DataEntryNote(control, autocompletions, this);
                    noteControl.ContentReadOnly = readOnly;
                    visibleControls.Add(noteControl);
                }
                else if (control.Type == Constant.Control.Flag || control.Type == Constant.DatabaseColumn.DeleteFlag)
                {
                    DataEntryFlag flagControl = new DataEntryFlag(control, this);
                    visibleControls.Add(flagControl);
                }
                else if (control.Type == Constant.Control.Counter)
                {
                    DataEntryCounter counterControl = new DataEntryCounter(control, this);
                    visibleControls.Add(counterControl);
                }
                else if (control.Type == Constant.Control.FixedChoice || control.Type == Constant.DatabaseColumn.ImageQuality)
                {
                    DataEntryChoice choiceControl = new DataEntryChoice(control, this);
                    visibleControls.Add(choiceControl);
                }
                else if (control.Type == Constant.DatabaseColumn.UtcOffset)
                {
                    utcOffsetControl = new DataEntryUtcOffset(control, this);
                    visibleControls.Add(utcOffsetControl);
                }
                else
                {
                    Debug.Fail(String.Format("Unhandled control type {0}.", control.Type));
                    continue;
                }
            }

            if ((dateTimeControl != null) && (utcOffsetControl != null))
            {
                dateTimeControl.ShowUtcOffset();
                visibleControls.Remove(utcOffsetControl);
            }

            foreach (DataEntryControl control in visibleControls)
            {
                this.ControlGrid.Children.Add(control.Container);
                this.Controls.Add(control);
                this.ControlsByDataLabel.Add(control.DataLabel, control);
            }

            dataEntryPropagator.SetDataEntryCallbacks(this.ControlsByDataLabel);
        }
        /// <summary>
        /// A new marker associated with a counter control has been created
        /// Increment the counter and add the marker to all data structures (including the database)
        /// </summary>
        private void MarkableCanvas_AddMarker(DataEntryCounter counter, Marker marker)
        {
            // increment the counter to reflect the new marker
            int count;
            if (Int32.TryParse(counter.Content, out count) == false)
            {
                // if the current value's not parseable assume that 
                // 1) the default value is set to a non-integer in the template
                // 2) or it's a space
                // In either case, revert to zero.
                count = 0;
            }
            ++count;

            string counterContent = count.ToString();
            this.dataHandler.IsProgrammaticControlUpdate = true;
            this.dataHandler.FileDatabase.UpdateFile(this.dataHandler.ImageCache.Current.ID, counter.DataLabel, counterContent);
            counter.SetContentAndTooltip(counterContent);
            this.dataHandler.IsProgrammaticControlUpdate = false;

            // Find markers associated with this particular control
            MarkersForCounter markersForCounter = null;
            foreach (MarkersForCounter markers in this.markersOnCurrentFile)
            {
                if (markers.DataLabel == counter.DataLabel)
                {
                    markersForCounter = markers;
                    break;
                }
            }

            // fill in marker information
            marker.ShowLabel = true; // show label on creation, cleared on next refresh
            marker.LabelShownPreviously = false;
            marker.Brush = Brushes.Red;               // Make it Red (for now)
            marker.DataLabel = counter.DataLabel;
            marker.Tooltip = counter.Label;   // The tooltip will be the counter label plus its data label
            marker.Tooltip += "\n" + counter.DataLabel;
            markersForCounter.AddMarker(marker);

            // update this counter's list of points in the database
            this.dataHandler.FileDatabase.SetMarkerPositions(this.dataHandler.ImageCache.Current.ID, markersForCounter);

            this.MarkableCanvas.Markers = this.GetDisplayMarkers(true);
            this.Speak(counter.Content + " " + counter.Label); // Speak the current count
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Add user interface event handler callbacks for (possibly invisible) controls
        /// </summary>
        private void SetUserInterfaceCallbacks()
        {
            // Add data entry callbacks to all editable controls. When the user changes an image's attribute using a particular control,
            // the callback updates the matching field for that image in the database.
            DataEntryNote     date     = null;
            DataEntryDateTime dateTime = null;
            DataEntryNote     time     = null;

            foreach (KeyValuePair <string, DataEntryControl> pair in this.DataEntryControls.ControlsByDataLabel)
            {
                string controlType = this.DataHandler.FileDatabase.FileTableColumnsByDataLabel[pair.Key].ControlType;
                switch (controlType)
                {
                case Constant.Control.Counter:
                    DataEntryCounter counter = (DataEntryCounter)pair.Value;
                    counter.ContentControl.PreviewMouseDown += this.ContentControl_MouseDown;
                    counter.ContentControl.PreviewKeyDown   += this.ContentCtl_PreviewKeyDown;
                    counter.Container.MouseEnter            += this.CounterControl_MouseEnter;
                    counter.Container.MouseLeave            += this.CounterControl_MouseLeave;
                    counter.LabelControl.Click += this.CounterControl_Click;
                    break;

                case Constant.Control.Flag:
                case Constant.DatabaseColumn.DeleteFlag:
                    DataEntryFlag flag = (DataEntryFlag)pair.Value;
                    flag.ContentControl.PreviewMouseDown += this.ContentControl_MouseDown;
                    flag.ContentControl.PreviewKeyDown   += this.ContentCtl_PreviewKeyDown;
                    break;

                case Constant.Control.FixedChoice:
                case Constant.DatabaseColumn.ImageQuality:
                    DataEntryChoice choice = (DataEntryChoice)pair.Value;
                    choice.ContentControl.PreviewMouseDown += this.ContentControl_MouseDown;
                    choice.ContentControl.PreviewKeyDown   += this.ContentCtl_PreviewKeyDown;
                    break;

                case Constant.Control.Note:
                case Constant.DatabaseColumn.Date:
                case Constant.DatabaseColumn.File:
                case Constant.DatabaseColumn.Folder:
                case Constant.DatabaseColumn.RelativePath:
                case Constant.DatabaseColumn.Time:
                    DataEntryNote note = (DataEntryNote)pair.Value;
                    note.ContentControl.PreviewMouseDown += this.ContentControl_MouseDown;
                    note.ContentControl.PreviewKeyDown   += this.ContentCtl_PreviewKeyDown;
                    if (controlType == Constant.DatabaseColumn.Date)
                    {
                        date = note;
                    }
                    if (controlType == Constant.DatabaseColumn.Time)
                    {
                        time = note;
                    }
                    break;

                case Constant.DatabaseColumn.DateTime:
                    dateTime = (DataEntryDateTime)pair.Value;
                    dateTime.ContentControl.PreviewMouseDown += this.ContentControl_MouseDown;
                    dateTime.ContentControl.PreviewKeyDown   += this.ContentCtl_PreviewKeyDown;
                    break;

                case Constant.DatabaseColumn.UtcOffset:
                    DataEntryUtcOffset utcOffset = (DataEntryUtcOffset)pair.Value;
                    utcOffset.ContentControl.PreviewMouseDown += this.ContentControl_MouseDown;
                    utcOffset.ContentControl.PreviewKeyDown   += this.ContentCtl_PreviewKeyDown;
                    break;

                default:
                    TracePrint.PrintMessage(String.Format("Unhandled control type '{0}' in SetUserInterfaceCallbacks.", controlType));
                    break;
                }
            }

            // if needed, link date and time controls to datetime control
            if (dateTime != null && date != null)
            {
                dateTime.DateControl = date;
            }
            if (dateTime != null && time != null)
            {
                dateTime.TimeControl = time;
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// A new marker associated with a counter control has been created;
        /// Increment the counter controls value, and add the marker to all data structures (including the database)
        /// </summary>
        private void MarkableCanvas_AddMarker(DataEntryCounter counter, Marker marker)
        {
            if (counter == null || marker == null)
            {
                // This shouldn't happen, but a user reported a 'null' crash somewhere in this method, so just in case...
                System.Diagnostics.Debug.Print("In MarkableCanvas_AddMarker. Counter or marker is null (and it shouldn't be");
                return;
            }

            // Get the Counter Control's contents,  increment its value (as we have added a new marker)
            // Then update the control's content as well as the database
            // If we can't convert it to an int, assume that someone set the default value to either a non-integer in the template, or that it's a space. In either case, revert it to zero.
            // If we can't convert it to an int, assume that someone set the default value to either a non-integer in the template, or that it's a space. In either case, revert it to zero.
            if (Int32.TryParse(counter.Content, out int count) == false)
            {
                count = 0;
            }
            ++count;

            string counterContent = count.ToString();

            this.DataHandler.IsProgrammaticControlUpdate = true;
            this.DataHandler.FileDatabase.UpdateFile(this.DataHandler.ImageCache.Current.ID, counter.DataLabel, counterContent);
            counter.SetContentAndTooltip(counterContent);
            this.DataHandler.IsProgrammaticControlUpdate = false;

            // Find the MarkersForCounters associated with this particular control so we can add a marker to it
            MarkersForCounter markersForCounter = null;

            // PERFORMANCE: This was a quick hack to insert markers into the MarkersTable if it didn't already exist.
            // It mildely sucks as it means we have to rebuild in memory the entire markers table every time we add a new counter (if there is no row in it)
            // Need to revisit this later and do it far more efficiently.
            if (this.markersOnCurrentFile.Count == 0)
            {
                // Check - If there is no row in the marker table with that ID, an empty row (with null values) will be added to the database
                // and the Markers list held by the database will be updated accordingly
                if (this.DataHandler.FileDatabase.MarkersTryInsertNewMarkerRow(this.DataHandler.ImageCache.Current.ID))
                {
                    // We added a new marker row, so we need to update the various markers data structures to reflect the new marker
                    markersForCounter         = new MarkersForCounter(counter.DataLabel);
                    this.markersOnCurrentFile = this.DataHandler.FileDatabase.MarkersGetMarkersForCurrentFile(this.DataHandler.ImageCache.Current.ID);
                }
            }

            foreach (MarkersForCounter markers in this.markersOnCurrentFile)
            {
                if (markers.DataLabel == counter.DataLabel)
                {
                    markersForCounter = markers;
                    break;
                }
            }

            // fill in marker information
            marker.ShowLabel            = true; // Show the annotation as its created. We will clear it on the next refresh
            marker.LabelShownPreviously = false;
            marker.Brush     = Brushes.Red;     // Make it Red (for now)
            marker.DataLabel = counter.DataLabel;
            marker.Tooltip   = counter.Label;   // The tooltip will be the counter label plus its data label
            marker.Tooltip  += "\n" + counter.DataLabel;
            markersForCounter.AddMarker(marker);

            // update this counter's list of points in the database
            this.DataHandler.FileDatabase.MarkersUpdateMarkerRow(this.DataHandler.ImageCache.Current.ID, markersForCounter);
            this.MarkableCanvas.Markers = this.GetDisplayMarkers();
            this.Speak(counter.Content + " " + counter.Label); // Speak the current count
        }
Ejemplo n.º 6
0
        // Event handler: A marker, as defined in e.Marker, has been either added (if e.IsNew is true) or deleted (if it is false)
        // Depending on which it is, add or delete the tag from the current counter control's list of tags
        // If its deleted, remove the tag from the current counter control's list of tags
        // Every addition / deletion requires us to:
        // - update the contents of the counter control
        // - update the data held by the image
        // - update the list of markers held by that counter
        // - regenerate the list of markers used by the markableCanvas
        private void MarkableCanvas_RaiseMarkerEvent(object sender, MarkerEventArgs e)
        {
            if (e.IsNew)
            {
                // A marker has been added
                DataEntryCounter currentCounter = this.FindSelectedCounter(); // No counters are selected, so don't mark anything
                if (currentCounter == null)
                {
                    return;
                }
                this.MarkableCanvas_AddMarker(currentCounter, e.Marker);
                return;
            }
            // An existing marker has been deleted.
            DataEntryCounter counter = (DataEntryCounter)this.DataEntryControls.ControlsByDataLabel[e.Marker.DataLabel];

            // Part 1. Decrement the counter only if there is a number in it
            string oldCounterData = counter.Content;
            string newCounterData;

            if (!String.IsNullOrEmpty(oldCounterData))
            {
                int count = Convert.ToInt32(oldCounterData);
                count          = (count == 0) ? 0 : count - 1;  // Make sure its never negative, which could happen if a person manually enters the count
                newCounterData = count.ToString();

                if (!newCounterData.Equals(oldCounterData))
                {
                    // Don't bother updating if the value hasn't changed (i.e., already at a 0 count)
                    // Update the datatable and database with the new counter values
                    this.DataHandler.IsProgrammaticControlUpdate = true;
                    counter.SetContentAndTooltip(newCounterData);
                    this.DataHandler.IsProgrammaticControlUpdate = false;
                    this.DataHandler.FileDatabase.UpdateFile(this.DataHandler.ImageCache.Current.ID, counter.DataLabel, newCounterData);
                }
            }

            // Part 2. Remove the marker in memory and from the database
            // Each marker in the countercoords list reperesents a different control.
            // So just check the first markers's DataLabel in each markersForCounters list to see if it matches the counter's datalabel.
            MarkersForCounter markersForCounter = null;

            foreach (MarkersForCounter markers in this.markersOnCurrentFile)
            {
                // If there are no markers, we don't have to do anything.
                if (markers.Markers.Count == 0)
                {
                    continue;
                }

                // There are no markers associated with this counter
                // if (markers.Markers[0].DataLabel == markers.DataLabel)
                if (markers.Markers[0].DataLabel == e.Marker.DataLabel)
                {
                    // We found the marker counter associated with that control
                    markersForCounter = markers;
                    break;
                }
            }

            // Part 3. Remove the found metatag from the metatagcounter and from the database
            if (markersForCounter != null)
            {
                markersForCounter.RemoveMarker(e.Marker);
                this.Speak(counter.Content); // Speak the current count
                this.DataHandler.FileDatabase.MarkersUpdateMarkerRow(this.DataHandler.ImageCache.Current.ID, markersForCounter);
            }
            this.MarkableCanvas_UpdateMarkers(); // Refresh the Markable Canvas, where it will also delete the markers at the same time
        }