void SetItem(object data) { if (data is RoundDebater) { RoundDebater d = (RoundDebater)data; if (d.Role.IsJudge) { FindJudge(d).SetIsInPool(true, roundName); } else if (d.Role.IsTeamMember) { Team t = FindTeam(d.Role.TeamName); t.FindTeamMember(d).SetIsInPool(true, roundName); t.UpdateTeamMembers(); } } else if (data is TeamData) { FindTeam((TeamData)data).SetIsInPool(true, roundName); } else { throw new NotImplementedException("Don't know how to handle data"); } }
// make an abbreviated and small version of this widget! public static DebaterWidget Small(RoundDebater d, bool canFocus) { DebaterWidget dw = new DebaterWidget(d, canFocus, true); dw.btnExpand.LabelText = d.Name.FirstName.Substring(0, 1) + ". " + d.Name.LastName.Substring(0, 1) + ". "; return(dw); }
private double?GetDebaterAveragePoints(int roundIndex, RoundDebater debater) { var debaterConv = Tournament.I.FindDebater(debater); var results = debaterConv == null ? null : debaterConv.RoundResults; var results_ = results == null || results.Count <= roundIndex ? null : results[roundIndex]; return(results_ == null ? null : new Nullable <double>(results_.AvgSpeakerScore)); }
public DebaterWidget(RoundDebater rd, bool canFocus, bool showDebaterName) { this.Build(); roundDebater = rd; debater = null; debaterValid = false; infoWidgets = new Dictionary <string, Widget>(); if (roundDebater == null) { Label lbl = new Label(); lbl.Markup = "<i>No Debater</i>"; lbl.Xalign = 0f; alBtn.Add(lbl); alBtn.ShowAll(); MiscHelpers.SetIsShown(hboxInfo, false); return; } // btnExpand Setup btnExpand = new MyButton(this, rd.Name.ToString(), "weather-clear", "weather-clear-night"); btnExpand.CanFocus = canFocus; btnExpand.Clicked += OnBtnExpandClicked; alBtn.Add(btnExpand); alBtn.ShowAll(); // infoLabels Setup SetupInfo(showDebaterName); // conflict notifications btnConflict = new MyConflictButton(); alConflictBtn.Add(btnConflict); // (default not shown, // activated by ShowJudgeAvail from DebaterPool) btnJudgeState = new MyJudgeStateButton(roundDebater); btnExpand.SetStrikeThrough(!rd.JudgeAvail); btnJudgeState.Changed += delegate { btnExpand.SetStrikeThrough(!rd.JudgeAvail); if (JudgeStateChanged != null) { JudgeStateChanged(this, EventArgs.Empty); } }; alJudgeState.Add(btnJudgeState); alJudgeState.NoShowAll = true; // SetIsShown in Realized so that everything is counted correctly by triggered events Realized += delegate(object sender, EventArgs e) { MiscHelpers.SetIsShown(this, roundDebater.IsShown); MiscHelpers.SetIsShown(hboxInfo, false); }; }
DebaterWidget FindJudge(RoundDebater d) { foreach (DebaterWidget w in vboxJudges) { if (w.Equals(d)) { return(w); } } return(null); }
public DebaterWidget FindTeamMember(RoundDebater d) { foreach (DebaterWidget w in vboxTeamMembers) { if (w.RoundDebater.Equals(d)) { return(w); } } return(null); }
public MyJudgeStateButton(RoundDebater rd_) { rd = rd_; BorderWidth = 0; Relief = ReliefStyle.None; CanFocus = false; lbl = new Label(); Add(lbl); UpdateGui(); SetupMenu(); ButtonPressEvent += OnBtnPressed; Changed += delegate { Tournament.I.Save(); }; }
void RemoveDebaterFromRounds(TreeIter storeIter) { EditableDebater d = (EditableDebater)store.GetValue(storeIter, 0); // removing a judge from existing rounds is easy // but everything else is not (consider non-complete teams...) // so, we rely on the issued warning and hope the user knows // what to do if (!d.Role.IsJudge) { return; } foreach (RoundData round in Tournament.I.Rounds) { RoundDebater rd = round.AllJudges.Find(delegate(RoundDebater obj) { return(obj.Equals(d)); }); // if not found, continue! if (rd == null) { continue; } // d is Judge, so check Chair and Judges in rooms foreach (RoomData room in round.Rooms) { if (rd.Equals(room.Chair)) { room.Chair = null; } else { // if judge isn't there, can't be removed... room.Judges.Remove(rd); } } // remove from all judges round.AllJudges.Remove(rd); } }
public List <RoundDebater> GetBestFreeSpeakers(int nTeams) { // determine speakers in teams first List <RoundDebater> teamSpeakers = new List <RoundDebater>(); foreach (TeamData td in GetBestTeams(nTeams)) { teamSpeakers.AddRange(td); } List <RoundDebater> freeSpeakers = new List <RoundDebater>(); // speakers are ordered as in shown ranking foreach (RankingDataItem item in speakers) { RoundDebater rd = (RoundDebater)item.Data; if (!teamSpeakers.Contains(rd)) { freeSpeakers.Add(rd); } } return(freeSpeakers); }
public DebaterWidget(RoundDebater rd) : this(rd, false, false) { // defaults }
void DoTheExport(MiscHelpers.TemplateType type) { try { ITemplate tmpl = MiscHelpers.GetTemplate("ranking", type); string separator = type == MiscHelpers.TemplateType.PDF ? "+" : "\",\""; ITmplBlock tmplTitle = tmpl.ParseBlock("TITLE"); tmplTitle.Assign("V", Tournament.I.Title); tmplTitle.Out(); ITmplBlock tmplTeams = tmpl.ParseBlock("TEAMS"); int pos = 1; int realPos = 1; foreach (RankingDataItem item in teams) { TeamData td = (TeamData)item.Data; if (!(pos > 1 && teams[pos - 2].TotalPoints == item.TotalPoints)) { realPos = pos; } tmplTeams.Assign("POS", realPos.ToString()); tmplTeams.Assign("NAME", td.TeamName); List <int> speakerPos = new List <int>(3); foreach (RoundDebater rd in td) { int realPos_ = 1; for (int i = 0; i < speakers.Count; i++) { if (!(i > 0 && speakers[i - 1].TotalPoints == speakers[i].TotalPoints)) { realPos_ = i + 1; } if (rd.Equals(speakers[i].Data)) { speakerPos.Add(realPos_); } } } speakerPos.Sort(); ITmplBlock tmplSpeakerPos = tmpl.ParseBlock("SPEAKERPOS"); for (int i = 0; i < speakerPos.Count; i++) { tmplSpeakerPos.Assign("POS", speakerPos[i].ToString()); tmplSpeakerPos.Assign("SEP", i == speakerPos.Count - 1?"":separator); tmplSpeakerPos.Out(); } // we divide the avg by three to make it comparable to team position tmplTeams.Assign("SPEAKERPOSAVG", item.AvgPoints < 0 ? "?" : OPDtabData.MiscHelpers.FmtDecimal(OPDtabData.MiscHelpers.CalcExactAverage(speakerPos) / 3) ); if (mBreakingTeams.Contains(pos - 1)) { tmplTeams.Assign("BREAKMARK", "Break"); } else { tmplTeams.Assign("BREAKMARK", ""); } tmplTeams.Assign("POINTS", OPDtabData.MiscHelpers.DoubleToStr(item.TotalPoints)); ITmplBlock tmplPointsPerRound = tmpl.ParseBlock("POINTSPERROUNDTEAM"); int nPoints = 0; if (item.RoundPoints.Count == 0) { tmplPointsPerRound.Assign("POINTS", "?"); tmplPointsPerRound.Assign("POS", ""); tmplPointsPerRound.Assign("SEP", ""); tmplPointsPerRound.Out(); } else { for (int i = 0; i < item.RoundPoints.Count; i++) { string[] PosToStr = new string[] { "G", "O", "F" }; tmplPointsPerRound.Assign("POINTS", OPDtabData.MiscHelpers.DoubleToStr(item.RoundPoints[i])); tmplPointsPerRound.Assign("POS", PosToStr[(int)RoundResultData.PosToRoleType[item.RoundPositions[i]]]); tmplPointsPerRound.Assign("SEP", i == item.RoundPoints.Count - 1?"":separator); tmplPointsPerRound.Out(); nPoints++; } } if (type == MiscHelpers.TemplateType.CSV) { // in CSV mode pad with more separators for (int i = nPoints; i < Tournament.I.Rounds.Count; i++) { tmplPointsPerRound.Assign("POINTS", ""); tmplPointsPerRound.Assign("SEP", separator); tmplPointsPerRound.Out(); } } tmplTeams.Out(); pos++; } ITmplBlock tmplSpeakers = tmpl.ParseBlock("SPEAKERS"); pos = 1; realPos = 1; foreach (RankingDataItem item in speakers) { RoundDebater rd = (RoundDebater)item.Data; if (!(pos > 1 && speakers[pos - 2].TotalPoints == item.TotalPoints)) { realPos = pos; } tmplSpeakers.Assign("POS", realPos.ToString()); tmplSpeakers.Assign("NAME", rd.Name.FirstName + " " + rd.Name.LastName); tmplSpeakers.Assign("POINTS", OPDtabData.MiscHelpers.DoubleToStr(item.TotalPoints)); if (mTeamSpeakers.Contains(pos - 1)) { tmplSpeakers.Assign("BREAKMARK", "Team"); } else if (mFreeSpeakers.Contains(pos - 1)) { tmplSpeakers.Assign("BREAKMARK", "Tab"); } else if (mBestSpeakers.Contains(pos - 1)) { tmplSpeakers.Assign("BREAKMARK", "Raum"); } else { tmplSpeakers.Assign("BREAKMARK", ""); } tmplSpeakers.Assign("TEAMNAME", rd.Role.TeamName); ITmplBlock tmplPointsPerRound = tmpl.ParseBlock("POINTSPERROUNDSPEAKER"); int nPoints = 0; if (item.Points == null) { tmplPointsPerRound.Assign("POINTS", "?"); tmplPointsPerRound.Assign("POS", ""); tmplPointsPerRound.Assign("SEP", ""); tmplPointsPerRound.Out(); } else { for (int i = 0; i < item.Points.Count; i++) { tmplPointsPerRound.Assign("POINTS", OPDtabData.MiscHelpers.DoubleToStr(item.Points[i])); tmplPointsPerRound.Assign("POS", OPDtabData.MiscHelpers.IntToStr(item.RoundPositions[i] + 1)); tmplPointsPerRound.Assign("SEP", i == item.Points.Count - 1?"":separator); tmplPointsPerRound.Out(); nPoints++; } } if (type == MiscHelpers.TemplateType.CSV) { // in CSV mode pad with more separators for (int i = nPoints; i < Tournament.I.Rounds.Count; i++) { tmplPointsPerRound.Assign("POINTS", ""); tmplPointsPerRound.Assign("POS", ""); tmplPointsPerRound.Assign("SEP", separator); tmplPointsPerRound.Out(); } } tmplSpeakers.Assign("AVERAGEPOINTS", item.AvgPoints < 0 ? "?" : OPDtabData.MiscHelpers.FmtDecimal(item.AvgPoints)); tmplSpeakers.Out(); pos++; } MiscHelpers.AskShowTemplate(this, "Ranking Export successfully generated, see pdfs/ranking.(pdf|csv).", MiscHelpers.MakeExportFromTemplate() ); } catch (Exception ex) { MiscHelpers.ShowMessage(this, "Could not export Ranking: " + ex.Message, MessageType.Error); } }
protected void OnBtnSwapRolesClicked(object sender, EventArgs e) { TreePath[] r = treeDebaters.Selection.GetSelectedRows(); if (r.Length != 2) { MiscHelpers.ShowMessage(this, "Select exactly two Debaters to swap.", MessageType.Error); return; } TreeIter iter1; TreeIter iter2; if (!treeDebaters.Model.GetIter(out iter1, r[0]) || !treeDebaters.Model.GetIter(out iter2, r[1])) { // this should never happen return; } // get the references in the store TreeIter storeIter1 = ConvertModelIterToStoreIter(iter1); TreeIter storeIter2 = ConvertModelIterToStoreIter(iter2); EditableDebater d1 = (EditableDebater) store.GetValue(storeIter1, 0); EditableDebater d2 = (EditableDebater) store.GetValue(storeIter2, 0); // swapping it in the store Role tmp = d2.Role; d2.Role = d1.Role; d1.Role = tmp; // update in existing rounds (this is ugly due to our data model) // this resets the info about available judges... // any other approach wouldn't be future-proof foreach (RoundData round in Tournament.I.Rounds) { // clear all round results of the debaters in the store! d1.SetRoom(round.RoundName, null); d2.SetRoom(round.RoundName, null); // always create new instance for each round RoundDebater rd1 = new RoundDebater(d1); RoundDebater rd2 = new RoundDebater(d2); // search for d1, replace by d2 and vice versa // this should work since d1 and d2 have already swapped roles foreach (RoomData room in round.Rooms) { room.ReplaceRoomMember(rd1, RoundDebater.Dummy()); } foreach (RoomData room in round.Rooms) { room.ReplaceRoomMember(rd2, rd1); } foreach (RoomData room in round.Rooms) { room.ReplaceRoomMember(RoundDebater.Dummy(), rd2); } // update also allArrays, the following UpdateAllArrays // relies on at least consistent arrays round.ReplaceInAllArrays(rd1, RoundDebater.Dummy()); round.ReplaceInAllArrays(rd2, new RoundDebater(rd1)); round.ReplaceInAllArrays(RoundDebater.Dummy(), new RoundDebater(rd2)); // since complicated things can happen above // we make the arrays consistent by brute force // this creates many warnings that round results are cleared, // but the debaters are backed up in store here...complicated, as said round.UpdateAllArrays(); } // overwrite the changes with the changes from the store SaveDebaters(); // and reflect the possible reset of RoundResults ShowRanking.I.UpdateAll(); // tell the treeview to update, don't know why path and iter is necessary store.EmitRowChanged(store.GetPath(storeIter1), storeIter1); store.EmitRowChanged(store.GetPath(storeIter2), storeIter2); }
public void UnsafeSetRoundDebater(RoundDebater debater) { setRoundDebater(debater, prop); }
void CellRendererEdited(CellRendererTextAdv sender, string pathStr, string newText, int colNum) { TreeModelSort model = (TreeModelSort)treeDebaters.Model; TreePath path = new TreePath(pathStr); TreeIter iter = TreeIter.Zero; model.GetIter(out iter, path); EditableDebater d = (EditableDebater)model.GetValue(iter, 0); // only save old data in rd if editing RoundDebater rd = null; if (newDebaterPath == null && colNum < 4) { rd = new RoundDebater(d); } try { string prop = treeDebaters.Columns[colNum].Title; // This parses the given new string, // and updates the data in store d.GetType().InvokeMember("Parse" + prop, BindingFlags.InvokeMethod, null, d, new object[] { newText }); // existing Debater: Update Data in (possibly) existing Rounds // tries to keep data consisting, but there's no guarantee // BlackList/WhiteList and ExtraInfo are not // used in RoundDebater, so skip this by condition colNum<4 if (newDebaterPath == null && colNum < 4) { object p = d.GetType().InvokeMember(prop, BindingFlags.GetProperty, null, d, new object[] {}); // Only simple Renaming of Role is possible if Rounds exist if (colNum == 3 && Tournament.I.Rounds.Count > 0 && ((d.Role.IsTeamMember != rd.Role.IsTeamMember) || (d.Role.IsJudge != rd.Role.IsJudge))) { MiscHelpers.ShowMessage(this, "Changing Role from Judge to TeamMember (or vice versa)" + " is not possible since Rounds are already set.", MessageType.Error); // reset to old role... d.Role = rd.Role; return; } // check if new TeamName is already present if (colNum == 3 && d.Role.IsTeamMember) { int n = 0; foreach (object[] row in store) { EditableDebater d_ = (EditableDebater)row[0]; if (!d.Equals(d_) && d_.Role.TeamName == d.Role.TeamName) { n++; } } if (n == 3) { MiscHelpers.ShowMessage(this, "New TeamName is already present in three other Debaters.", MessageType.Error); // reset to old role... d.Role = rd.Role; return; } } // check for duplicate if (colNum < 3) { // need a temporary flag, throwing exceptions in delegates doesnt work... // the following flag stuff isn't elegant, but it should work bool flag = false; model.Foreach(delegate(TreeModel model_, TreePath path_, TreeIter iter_) { if (!iter.Equals(iter_)) { EditableDebater d_ = (EditableDebater)model_.GetValue(iter_, 0); if (d_.Equals(d)) { // reset to old value... object old = rd.GetType().InvokeMember(prop, BindingFlags.GetProperty, null, rd, new object[] {}); d.GetType().InvokeMember(prop, BindingFlags.SetProperty, null, d, new object[] { old }); flag = true; return(true); } } return(false); }); if (flag) { throw new TargetInvocationException(new Exception("Debater exists.")); } } // keep data consistent in existing rounds foreach (RoundData round in Tournament.I.Rounds) { foreach (RoomData room in round.Rooms) { foreach (RoundDebater rd_ in room.GetRoomMembers()) { if (rd_ == null) { continue; } if (rd_.Equals(rd)) { rd_.GetType().InvokeMember(prop, BindingFlags.SetProperty, null, rd_, new object[] { p }); } if (rd_.Role.TeamName == rd.Role.TeamName) { rd_.Role.TeamName = d.Role.TeamName; } } } if (rd.Role.IsTeamMember) { foreach (TeamData team in round.AllTeams) { foreach (RoundDebater rd_ in team) { if (rd_.Equals(rd)) { rd_.GetType().InvokeMember(prop, BindingFlags.SetProperty, null, rd_, new object[] { p }); } if (rd_.Role.TeamName == rd.Role.TeamName) { rd_.Role.TeamName = d.Role.TeamName; } } } } else if (rd.Role.IsJudge) { foreach (RoundDebater rd_ in round.AllJudges) { if (rd_.Equals(rd)) { rd_.GetType().InvokeMember(prop, BindingFlags.SetProperty, null, rd_, new object[] { p }); } } } } // Renaming TeamName needs extra Handling if (colNum == 3 && rd.Role.IsTeamMember && d.Role.IsTeamMember) { foreach (object[] row in store) { EditableDebater d_ = (EditableDebater)row[0]; if (d_.Role.TeamName == rd.Role.TeamName) { d_.Role.TeamName = d.Role.TeamName; } } } } // newDebater is entered... else if (newDebaterPath != null && colNum < 3) { // continue with entering data (goto next column) // as idle so that cells are resized GLib.Idle.Add(delegate { treeDebaters.SetCursor(ConvertStorePathToModelPath(newDebaterPath), treeDebaters.Columns[colNum + 1], true); return(false); }); } else if (newDebaterPath != null) { // new Debater entered completely (at least all necessary data) iter = TreeIter.Zero; if (store.GetIter(out iter, newDebaterPath)) { // as idle to prevent gtk critical (no idea why this happens) GLib.Idle.Add(delegate { store.Remove(ref iter); newDebaterPath = null; if (IsNotInStore(d)) { store.AppendValues(d); SaveDebaters(); } else { MiscHelpers.ShowMessage(this, "Debater exists.", MessageType.Error); } UpdateDebatersInfo(); btnDebaterAdd.GrabFocus(); return(false); }); } } // Gui stuff treeDebaters.ColumnsAutosize(); // ugly method of resorting the TreeSortModel... SortType st; int sortColumn; model.GetSortColumnId(out sortColumn, out st); if (st == SortType.Descending) { model.SetSortColumnId(sortColumn, SortType.Ascending); model.SetSortColumnId(sortColumn, SortType.Descending); } else { model.SetSortColumnId(sortColumn, SortType.Descending); model.SetSortColumnId(sortColumn, SortType.Ascending); } // save data from store if not adding new debater if (newDebaterPath == null) { SaveDebaters(); } } catch (TargetInvocationException e) { MessageDialog md = new MessageDialog(this, DialogFlags.Modal, MessageType.Error, ButtonsType.OkCancel, e.InnerException.Message + ". Try again?"); md.DefaultResponse = ResponseType.Ok; ResponseType r = (ResponseType)md.Run(); md.Destroy(); if (r == ResponseType.Ok) { // As Idle otherwise Editable isn't destroyed correctly GLib.Idle.Add(delegate { sender.TempEditString = newText; treeDebaters.SetCursor(path, treeDebaters.Columns[colNum], true); return(false); }); } else { if (newDebaterPath == null) { return; } iter = TreeIter.Zero; if (store.GetIter(out iter, newDebaterPath)) { // remove not finished new debater, // with idle call, // prevents Gtk critical filter model assertion. GLib.Idle.Add(delegate { newDebaterPath = null; store.Remove(ref iter); return(false); }); } } } }
string RoundDebaterToString(RoundDebater rd) { return(rd.Name + " (" + rd.Club + ")"); }