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); }