private void Cell_Click(object sender, EventArgs e) { TableLayoutPanelCellPosition cell = calendar.GetPositionFromControl((Control)sender); if (cell.Column == 0 && cell.Row == 0) { return; } Training training; TrainingDetailsMode mode = TrainingDetailsMode.View; Button btn = (Button)sender; if (btn.Text == "") { if (!user.isCoach) { return; } training = new Training(); mode = TrainingDetailsMode.New; training.coachId = user.id; training.date = date.AddDays(cell.Column - 1).AddHours(cell.Row - 1 + startHour); } else { training = localTrainings.Find(t => DateTime.Compare(t.date, date.AddDays(cell.Column - 1).AddHours(cell.Row - 1 + startHour)) == 0 && t.syncState != SyncState.Deleted); if (training == null) { return; } if (user.id == training.coachId) { mode = TrainingDetailsMode.Edit; } } Debug.WriteLine("{0}:{1}, mode {2}, coach {3}", cell.Row, cell.Column, mode, training.coachId); TrainingDetailsForm details = new TrainingDetailsForm(user, users, training, mode); DialogResult result = details.ShowDialog(); if (result == DialogResult.Abort) { return; } Cursor = Cursors.WaitCursor; trainingsMutex.WaitOne(); if (result == DialogResult.OK) { training.name = details.nameEdit.Text; localTrainings.Add(training); AddTrainingToCell(btn, training); } else if (result == DialogResult.Ignore) { training.syncState = SyncState.Deleted; if (training.id == -1) { localTrainings.Remove(training); } ClearCell(btn); } else if (result == DialogResult.Yes) { training.traineesId.Remove(user.id); training.syncState = SyncState.Updated; } else if (result == DialogResult.No) { training.traineesId.Add(user.id); training.syncState = SyncState.Updated; } trainingsMutex.Release(); Cursor = Cursors.Default; }
public async Task <bool> SyncTrainings(User user, List <Training> trainings, Semaphore mutex) { command.Parameters.Clear(); command.CommandText = ""; mutex.WaitOne(); for (int i = 0; i < trainings.Count; i++) { switch (trainings[i].syncState) { case SyncState.Unsynced: AddSyncTrainingQuery(trainings[i], command); break; case SyncState.Deleted: AddDeleteTrainingQuery(trainings[i], command); break; case SyncState.Updated: AddUpdateTrainingQuery(user, trainings[i], command); break; } } command.CommandText += "SELECT id, name, coach_id, date " + "FROM Trainings " + "ORDER BY id;"; command.CommandType = CommandType.Text; await db.FetchDb(); List <object[]> table = db.ExecuteReader(command); command.CommandText = "SELECT * FROM Trainees ORDER BY training_id;"; List <object[]> trainees = db.ExecuteReader(command); await db.CommitDb(); if (table.Count <= 0) { Debug.WriteLine("No trainings to sync"); trainings.Clear(); return(false); } trainings.RemoveAll(x => table.FindIndex(t => (long)t[0] == x.id) < 0); for (int i = 0; i < table.Count; i++) { int idx = trainings.FindIndex(x => x.id == (long)table[i][0]); Training t = idx >= 0 ? trainings[idx] : new Training(); t.id = (long)table[i][0]; t.name = (string)table[i][1]; t.coachId = (long)table[i][2]; t.date = UnixTimestampToDateTime((long)table[i][3]); bool isUserSubLocal = t.traineesId.FindIndex(x => x == user.id) >= 0; int ti = trainees.FindIndex(x => (long)x[0] == t.id); bool isUserSubRemote = false; t.traineesId.Clear(); if (ti >= 0) { for (int j = ti; j < trainees.Count; j++) { if ((long)trainees[j][0] != t.id) { break; } t.traineesId.Add((long)trainees[j][1]); if (user.id == (long)trainees[j][1]) { isUserSubRemote = true; } } } t.syncState = isUserSubRemote == isUserSubLocal ? SyncState.Synced : SyncState.Updated; Debug.WriteLine("Training fetched {0}, {1}, {2}, {3}", t.id, t.name, t.coachId, t.date.ToString()); if (idx < 0) { trainings.Add(t); } } Debug.WriteLine("Load trainings"); mutex.Release(); return(true); }