Пример #1
0
 public MergeData(VoteLineBlock fromVote, List <VoteLineBlock> toVotes, UndoActionType actionType)
 {
     FromVote = fromVote;
     ToVote   = fromVote;
     ToVotes.AddRange(toVotes);
     UndoActionType = actionType;
 }
Пример #2
0
        public static void ClassInit(TestContext context)
        {
            serviceProvider = TestStartup.ConfigureServices();

            VoteLine voteLine = new VoteLine("", "X", "", "A sample vote line", MarkerType.Vote, 100);

            vote = new VoteLineBlock(voteLine);
        }
Пример #3
0
        /// <summary>
        /// Adds a merge record.
        /// </summary>
        /// <param name="fromRecord">The original vote string.</param>
        /// <param name="toRecord">The revised vote string.</param>
        /// <param name="partitionMode">The partition mode.</param>
        public void AddMergeRecord(VoteLineBlock fromRecord, List <VoteLineBlock> toRecords,
                                   UndoActionType actionType, PartitionMode partitionMode)
        {
            var merges = GetMergesFor(partitionMode);

            MergeData data = new MergeData(fromRecord, toRecords, actionType);

            merges.Add(data);
        }
Пример #4
0
        /// <summary>
        /// Wrapper for handling replace task, but without adding to merge records.
        /// </summary>
        /// <param name="vote">The vote being modified.</param>
        /// <param name="task">The new task to apply to the vote.</param>
        /// <returns>Returns true if the task replacement was successfully completed.</returns>
        private bool ReplaceTaskImplWrapper(VoteLineBlock vote, string task)
        {
            if (!VoteStorage.TryGetValue(vote, out var supporters))
            {
                return(false);
            }

            // Incoming parameter may be an entry in storage, or a copy of a vote.
            // Adjust so that we're always pointing at an actual vote.
            // If the vote isn't found in VoteStorage, just use the one provided.
            vote = VoteStorage.GetVoteMatching(vote) ?? vote;

            // Remove the version of the vote we're starting with.
            VoteStorage.Remove(vote);

            string originalTask = vote.Task;

            vote.Task = task;

            // If there's a conflict with the newly-tasked vote, we need to merge with the existing vote.
            if (VoteStorage.ContainsKey(vote))
            {
                if (VoteStorage.TryGetValue(vote, out var toSupport))
                {
                    foreach (var(supporterName, supporterVote) in supporters)
                    {
                        if (!toSupport.ContainsKey(supporterName))
                        {
                            supporterVote.Task = task;
                            toSupport.Add(supporterName, supporterVote);
                        }
                    }
                }
                else
                {
                    // Undo the attempt if we couldn't get the conflicting vote data
                    vote.Task = originalTask;

                    VoteStorage.Add(vote, supporters);

                    return(false);
                }
            }
            // If there's no conflict, update the tasks in the supporter votes and add the revised vote.
            else
            {
                foreach (var(_, supporterVote) in supporters)
                {
                    supporterVote.Task = task;
                }

                VoteStorage.Add(vote, supporters);
            }

            return(true);
        }
Пример #5
0
        private void PartitionChildren(VoteLineBlock vote)
        {
            try
            {
                lastPosition1 = VoteView1.CurrentPosition;
                lastPosition2 = VoteView2.CurrentPosition;

                mainViewModel.PartitionChildren(vote);
            }
            catch (ArgumentException ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }
Пример #6
0
 /// <summary>
 /// Handle busywork for merging votes together and updating the VotesCollection.
 /// </summary>
 /// <param name="fromVote">The vote being merged.</param>
 /// <param name="toVote">The vote being merged into.</param>
 private void MergeVotes(VoteLineBlock fromVote, VoteLineBlock toVote)
 {
     try
     {
         lastPosition1 = VoteView1.CurrentPosition;
         lastPosition2 = -1;
         lastSelected2 = VoteView2.CurrentItem ?? lastSelected2;
         mainViewModel.MergeVotes(fromVote, toVote);
     }
     catch (ArgumentException ex)
     {
         MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
     }
 }
Пример #7
0
        /// <summary>
        /// Implement the logic for combining two support blocks of voters.
        /// </summary>
        /// <param name="fromVote">The vote being merged from.</param>
        /// <param name="toVote">The vote being merged into.</param>
        /// <param name="fromSupport">The support block for the from vote.</param>
        /// <param name="toSupport">The support block for the to vote.</param>
        /// <returns>Returns true if any supporters were successfully added to the to block.</returns>
        private bool MergeImpl(VoteLineBlock fromVote, VoteLineBlock toVote,
                               VoterStorage fromSupport, VoterStorage toSupport)
        {
            bool merged = false;

            foreach (var(supporterName, oldVote) in fromSupport)
            {
                if (!toSupport.ContainsKey(supporterName))
                {
                    var newVote = toVote.WithMarker(oldVote.Marker, oldVote.MarkerType, oldVote.MarkerValue);
                    toSupport.Add(supporterName, newVote);
                    merged = true;
                }
            }

            return(merged);
        }
Пример #8
0
        private bool SplitImplWrapper(VoteLineBlock fromVote, List <VoteLineBlock> toVotes)
        {
            if (!VoteStorage.TryGetValue(fromVote, out var fromSupport))
            {
                return(false);
            }

            foreach (var toVote in toVotes)
            {
                if (!VoteStorage.TryGetValue(toVote, out var toSupport))
                {
                    return(false);
                }

                MergeImpl(fromVote, toVote, fromSupport, toSupport);
            }

            // But we still want to remove the from vote.
            return(VoteStorage.Remove(fromVote));
        }
Пример #9
0
        /// <summary>
        /// Merge the vote supporters from one vote into several other votes.
        /// </summary>
        /// <param name="fromVote">The originating vote.</param>
        /// <param name="toVotes">The destination votes.</param>
        /// <returns>Returns true if successfully completed.</returns>
        public bool Split(VoteLineBlock fromVote, List <VoteLineBlock> toVotes)
        {
            UndoBuffer.Push(new UndoAction(UndoActionType.Split, VoteStorage));
            UserMerges.AddMergeRecord(fromVote, toVotes, UndoActionType.Split, Quest !.PartitionMode);

            bool merged = SplitImplWrapper(fromVote, toVotes);

            if (merged)
            {
                OnPropertyChanged("Votes");
                OnPropertyChanged("Voters");
                OnPropertyChanged(nameof(HasUndoActions));
            }
            else
            {
                UndoBuffer.Pop();
            }

            return(merged);
        }
Пример #10
0
        /// <summary>
        /// Replace the task on the provided vote with the requested task.
        /// </summary>
        /// <param name="vote">The vote to update the task on.</param>
        /// <param name="task">The new task label.</param>
        /// <returns>Returns true if the task was updated.</returns>
        public bool ReplaceTask(VoteLineBlock vote, string task)
        {
            if (StringComparer.OrdinalIgnoreCase.Equals(vote.Task, task))
            {
                return(false);
            }

            UndoBuffer.Push(new UndoAction(UndoActionType.ReplaceTask, VoteStorage, vote));
            VoteLineBlock originalVote = vote.Clone();

            if (ReplaceTaskImplWrapper(vote, task))
            {
                UserMerges.AddMergeRecord(originalVote, vote, UndoActionType.ReplaceTask, Quest !.PartitionMode);

                OnPropertyChanged("Votes");
                OnPropertyChanged(nameof(HasUndoActions));
                return(true);
            }

            UndoBuffer.Pop();
            return(false);
        }
Пример #11
0
        /// <summary>
        /// Store a plan's information to allow it to be looked up by plan name or post ID.
        /// If the plan name has already been entered, will not update anything and return false.
        /// </summary>
        /// <param name="planName">The canonical name of the plan.</param>
        /// <param name="postID">The post ID the plan was defined in.</param>
        /// <param name="plan">The the vote line block that defines the plan.</param>
        /// <returns>Returns true if it was added, or false if it already exists.</returns>
        public bool AddReferencePlan(Origin planOrigin, VoteLineBlock plan)
        {
            // If it doesn't exist, we can just add it.
            if (ReferenceOrigins.Add(planOrigin))
            {
                ReferencePlans.Add(planOrigin, plan);
                return(true);
            }
            else if (
                (globalOptions.AllowUsersToUpdatePlans == BoolEx.True ||
                 (globalOptions.AllowUsersToUpdatePlans == BoolEx.Unknown && Quest !.AllowUsersToUpdatePlans)) &&
                ReferenceOrigins.TryGetValue(planOrigin, out Origin currentOrigin)
                )
            {
                // Author can replace existing version of a plan he wrote on conditions:
                // - Options allow plan replacement
                // - Plan written by same author
                // - Plan has the same name (surrounding if check, which includes identity type)
                // - New plan is in a later post than the previous
                // - New plan is more than one line (ie: not simply re-voting for the existing version)
                // - Content of the plan is different

                if (planOrigin.Source != Origin.Empty && planOrigin.Source == currentOrigin.Source &&
                    planOrigin.ID > currentOrigin.ID &&
                    plan.Lines.Count > 1 &&
                    ReferencePlans.TryGetValue(currentOrigin, out VoteLineBlock currentPlan) &&
                    plan != currentPlan)
                {
                    ReferenceOrigins.Remove(currentOrigin);
                    ReferenceOrigins.Add(planOrigin);
                    ReferencePlans[planOrigin] = plan;
                    return(true);
                }
            }

            return(false);
        }
Пример #12
0
        /// <summary>
        /// Delete an entire vote and all associated supporters.
        /// </summary>
        /// <param name="vote">The vote to delete.</param>
        /// <returns>Returns true if successfully completed.</returns>
        public bool Delete(VoteLineBlock vote)
        {
            bool removed = false;

            if (VoteStorage.ContainsKey(vote))
            {
                UndoBuffer.Push(new UndoAction(UndoActionType.Delete, VoteStorage));

                removed = VoteStorage.Remove(vote);
            }

            if (removed)
            {
                OnPropertyChanged("Votes");
                OnPropertyChanged("Voters");
                OnPropertyChanged(nameof(HasUndoActions));
            }
            else
            {
                UndoBuffer.Pop();
            }

            return(removed);
        }
Пример #13
0
        /// <summary>
        /// The wrapper handles the process of extracting the vote support from
        /// the storage before passing the pieces on to the implementation.
        /// </summary>
        /// <param name="fromVote">The vote being merged.</param>
        /// <param name="toVote">The vote being merged into.</param>
        /// <returns>Returns true if there was a successful merge.</returns>
        private bool MergeImplWrapper(VoteLineBlock fromVote, VoteLineBlock toVote)
        {
            if (fromVote == toVote)
            {
                return(false);
            }

            if (!VoteStorage.TryGetValue(fromVote, out var fromSupport))
            {
                return(false);
            }

            if (!VoteStorage.TryGetValue(toVote, out var toSupport))
            {
                return(false);
            }

            // Theoretically, all the supporters in the from vote could already
            // be in the to vote, in which case no merging would happen.
            MergeImpl(fromVote, toVote, fromSupport, toSupport);

            // But we still want to remove the from vote.
            return(VoteStorage.Remove(fromVote));
        }
Пример #14
0
 public bool DeleteVote(VoteLineBlock vote) => VoteCounter.Delete(vote);
Пример #15
0
 public MergeData(VoteLineBlock fromVote, VoteLineBlock toVote, UndoActionType actionType)
 {
     FromVote       = fromVote;
     ToVote         = toVote;
     UndoActionType = actionType;
 }
Пример #16
0
 public bool MergeVotes(VoteLineBlock fromVote, VoteLineBlock toVote) => VoteCounter.Merge(fromVote, toVote);
Пример #17
0
 /// <summary>
 /// Gets all voters that are supporting the specified vote.
 /// </summary>
 /// <param name="vote">The vote to check on.</param>
 /// <returns>Returns an IEnumerable of the voter names that are supporting the given vote.</returns>
 public IEnumerable <Origin> GetVotersFor(VoteLineBlock vote) => VoteStorage.GetVotersFor(vote);
Пример #18
0
 private bool HasChildLines(VoteLineBlock vote)
 {
     return(vote.Lines.Count > 1 && vote.Lines.Skip(1).All(v => v.Depth > 0));
 }
Пример #19
0
 public IEnumerable <Origin> GetVoterListForVote(VoteLineBlock vote) => VoteCounter.GetVotersFor(vote);
Пример #20
0
 public bool ReplaceTask(VoteLineBlock vote, string task) => VoteCounter.ReplaceTask(vote, task);
Пример #21
0
 public bool PartitionChildren(VoteLineBlock vote) => VoteCounter.Split(vote, Tally.VoteConstructor.PartitionChildren(vote));