/// <summary> /// Builds a new SRS entry editing window designed to add a new /// pre-created SRS entry, or to edit an existing SRS entry. /// </summary> /// <param name="entity">SRS entry to load in the window.</param> public EditSrsEntryWindow(SrsEntry entity) { InitializeComponent(); InitializeViewModel(entity); NavigationActor.Instance.ActiveWindow = this; Owner = NavigationActor.Instance.MainWindow; WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner; }
public VocabAudio(SrsEntry entry) { KanjiReading = entry.AssociatedVocab; KanaReading = MultiValueFieldHelper.Trim(entry.Readings) .Split(MultiValueFieldHelper.ValueSeparator) .FirstOrDefault(); if (string.IsNullOrWhiteSpace(KanaReading) || string.IsNullOrWhiteSpace(KanjiReading)) { State = VocabAudioState.Unavailable; } }
private ImportResult DoConvert(SrsEntry e) { ImportResult r = new ImportResult(); r.Type = string.IsNullOrEmpty(e.AssociatedKanji) ? "V" : "K"; r.Item = string.IsNullOrEmpty(e.AssociatedKanji) ? e.AssociatedVocab : e.AssociatedKanji; r.Level = e.CurrentGrade.ToString(); r.MeaningNotes = e.MeaningNote; r.Meanings = e.Meanings; r.ReadingNotes = e.ReadingNote; r.Readings = e.Readings; r.Tags = e.Tags; r.Date = e.NextAnswerDate.HasValue ? e.NextAnswerDate.ToString() : string.Empty; return r; }
/// <summary> /// Initializes the ViewModel. /// </summary> private void InitializeViewModel(SrsEntry entity) { SrsEntryViewModel vm; if (entity == null) { vm = new SrsEntryViewModel(); } else { vm = new SrsEntryViewModel(entity); } vm.FinishedEditing += OnFinishedEditing; DataContext = vm; }
/// <summary> /// Updates the given SRS entry. /// </summary> /// <param name="entity">Entity to update.</param> /// <returns>True if the operation was sucessful. False otherwise.</returns> public bool Update(SrsEntry entity) { DaoConnection connection = null; bool result = false; try { connection = DaoConnection.Open(DaoConnectionEnum.SrsDatabase); // Create a parameter list and two string builders that will // be used to put the SQL request together. List<DaoParameter> parameters = new List<DaoParameter>(); StringBuilder sqlQueryBuilder = new StringBuilder( "UPDATE " + SqlHelper.Table_SrsEntry + " SET "); // NextAnswerDate sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_NextAnswerDate + "="); if (entity.NextAnswerDate == null) { sqlQueryBuilder.Append("null"); } else { sqlQueryBuilder.Append("@NextAnswerDate"); parameters.Add(new DaoParameter( "@NextAnswerDate", entity.NextAnswerDate.Value.ToUniversalTime().Ticks)); } sqlQueryBuilder.Append(","); // Meanings sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_Meanings + "=@Meanings,"); parameters.Add(new DaoParameter("@Meanings", MultiValueFieldHelper.Trim(entity.Meanings ?? string.Empty))); // Readings sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_Readings + "=@Readings,"); parameters.Add(new DaoParameter("@Readings", MultiValueFieldHelper.Trim(entity.Readings ?? string.Empty))); // CurrentGrade sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_CurrentGrade + "=@CurrentGrade,"); parameters.Add(new DaoParameter("@CurrentGrade", entity.CurrentGrade)); // FailureCount sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_FailureCount + "=@FailureCount,"); parameters.Add(new DaoParameter("@FailureCount", entity.FailureCount)); // SuccessCount sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_SuccessCount + "=@SuccessCount,"); parameters.Add(new DaoParameter("@SuccessCount", entity.SuccessCount)); // SuspensionDate sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_SuspensionDate + "="); if (entity.SuspensionDate == null) { sqlQueryBuilder.Append("null"); } else { sqlQueryBuilder.Append("@SuspensionDate"); parameters.Add(new DaoParameter( "@SuspensionDate", entity.SuspensionDate.Value.ToUniversalTime().Ticks)); } sqlQueryBuilder.Append(","); // AssociatedVocab sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_AssociatedVocab + "=@AssociatedVocab,"); parameters.Add(new DaoParameter( "@AssociatedVocab", entity.AssociatedVocab)); // AssociatedKanji sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_AssociatedKanji + "=@AssociatedKanji,"); parameters.Add(new DaoParameter( "@AssociatedKanji", entity.AssociatedKanji)); // MeaningNote sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_MeaningNote + "=@MeaningNote,"); parameters.Add(new DaoParameter( "@MeaningNote", entity.MeaningNote)); // ReadingNote sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_ReadingNote + "=@ReadingNote,"); parameters.Add(new DaoParameter( "@ReadingNote", entity.ReadingNote)); // ServerId sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_ServerId + "=@ServerId,"); parameters.Add(new DaoParameter( "@ServerId", entity.ServerId)); // IsDeleted sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_IsDeleted + "=@IsDeleted,"); parameters.Add(new DaoParameter( "@IsDeleted", entity.IsDeleted)); // LastUpdateDate sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_LastUpdateDate + "=@LastUpdateDate,"); parameters.Add(new DaoParameter( "@LastUpdateDate", DateTime.UtcNow.Ticks)); // Tags sqlQueryBuilder.Append(SqlHelper.Field_SrsEntry_Tags + "=@Tags"); parameters.Add(new DaoParameter( "@Tags", MultiValueFieldHelper.Trim(entity.Tags))); // We are done with the string builders. // Bring the query pieces together. string finalQuery = sqlQueryBuilder.ToString() + " WHERE " + SqlHelper.Field_SrsEntry_Id + "=@Id"; parameters.Add(new DaoParameter("@Id", entity.ID)); // Execute the query. result = connection.ExecuteNonQuery(finalQuery, parameters.ToArray()) == 1; } catch (Exception ex) { LogHelper.GetLogger(this.GetType().Name).Error( "An error occured during SRS item update.", ex); } finally { if (connection != null) { connection.Dispose(); } } return result; }
/// <summary> /// Inserts the given entity in the database. /// Overrides the ID property of the given entity. /// </summary> /// <param name="entity">Entity to insert.</param> public void Add(SrsEntry entity) { DaoConnection connection = null; try { connection = DaoConnection.Open(DaoConnectionEnum.SrsDatabase); // Create a parameter list and two string builders that will // be used to put the SQL request together. List<DaoParameter> parameters = new List<DaoParameter>(); StringBuilder sqlQueryStart = new StringBuilder( "INSERT INTO " + SqlHelper.Table_SrsEntry + "("); StringBuilder sqlQueryEnd = new StringBuilder( "VALUES("); // CreationDate if (entity.CreationDate != null) { sqlQueryStart.Append(SqlHelper.Field_SrsEntry_CreationDate + ","); sqlQueryEnd.Append("@CreationDate,"); parameters.Add(new DaoParameter( "@CreationDate", entity.CreationDate.Value.ToUniversalTime().Ticks)); } // NextAnswerDate if (entity.NextAnswerDate != null) { sqlQueryStart.Append(SqlHelper.Field_SrsEntry_NextAnswerDate + ","); sqlQueryEnd.Append("@NextAnswerDate,"); parameters.Add(new DaoParameter( "@NextAnswerDate", entity.NextAnswerDate.Value.ToUniversalTime().Ticks)); } // Meanings sqlQueryStart.Append(SqlHelper.Field_SrsEntry_Meanings + ","); sqlQueryEnd.Append("@Meanings,"); parameters.Add(new DaoParameter("@Meanings", MultiValueFieldHelper.Trim(entity.Meanings ?? string.Empty))); // Readings sqlQueryStart.Append(SqlHelper.Field_SrsEntry_Readings + ","); sqlQueryEnd.Append("@Readings,"); parameters.Add(new DaoParameter("@Readings", MultiValueFieldHelper.Trim(entity.Readings ?? string.Empty))); // CurrentGrade sqlQueryStart.Append(SqlHelper.Field_SrsEntry_CurrentGrade + ","); sqlQueryEnd.Append("@CurrentGrade,"); parameters.Add(new DaoParameter("@CurrentGrade", entity.CurrentGrade)); // FailureCount sqlQueryStart.Append(SqlHelper.Field_SrsEntry_FailureCount + ","); sqlQueryEnd.Append("@FailureCount,"); parameters.Add(new DaoParameter("@FailureCount", entity.FailureCount)); // SuccessCount sqlQueryStart.Append(SqlHelper.Field_SrsEntry_SuccessCount + ","); sqlQueryEnd.Append("@SuccessCount,"); parameters.Add(new DaoParameter("@SuccessCount", entity.SuccessCount)); // SuspensionDate if (entity.SuspensionDate.HasValue) { sqlQueryStart.Append(SqlHelper.Field_SrsEntry_SuspensionDate + ","); sqlQueryEnd.Append("@SuspensionDate,"); parameters.Add(new DaoParameter("@SuspensionDate", entity.SuspensionDate.Value.ToUniversalTime().Ticks)); } // AssociatedVocab if (!string.IsNullOrWhiteSpace(entity.AssociatedVocab)) { sqlQueryStart.Append(SqlHelper.Field_SrsEntry_AssociatedVocab + ","); sqlQueryEnd.Append("@AssociatedVocab,"); parameters.Add(new DaoParameter( "@AssociatedVocab", entity.AssociatedVocab)); } // AssociatedKanji if (!string.IsNullOrWhiteSpace(entity.AssociatedKanji)) { sqlQueryStart.Append(SqlHelper.Field_SrsEntry_AssociatedKanji + ","); sqlQueryEnd.Append("@AssociatedKanji,"); parameters.Add(new DaoParameter( "@AssociatedKanji", entity.AssociatedKanji)); } // MeaningNote if (!string.IsNullOrWhiteSpace(entity.MeaningNote)) { sqlQueryStart.Append(SqlHelper.Field_SrsEntry_MeaningNote + ","); sqlQueryEnd.Append("@MeaningNote,"); parameters.Add(new DaoParameter( "@MeaningNote", entity.MeaningNote)); } // ReadingNote if (!string.IsNullOrWhiteSpace(entity.ReadingNote)) { sqlQueryStart.Append(SqlHelper.Field_SrsEntry_ReadingNote + ","); sqlQueryEnd.Append("@ReadingNote,"); parameters.Add(new DaoParameter( "@ReadingNote", entity.ReadingNote)); } // Tags if (!string.IsNullOrWhiteSpace(entity.Tags)) { sqlQueryStart.Append(SqlHelper.Field_SrsEntry_Tags + ","); sqlQueryEnd.Append("@Tags,"); parameters.Add(new DaoParameter( "@Tags", MultiValueFieldHelper.Trim(entity.Tags))); } // LastUpdateDate sqlQueryStart.Append(SqlHelper.Field_SrsEntry_LastUpdateDate + ","); sqlQueryEnd.Append("@LastUpdateDate,"); parameters.Add(new DaoParameter( "@LastUpdateDate", DateTime.UtcNow.Ticks)); // ServerId if (entity.ServerId.HasValue) { sqlQueryStart.Append(SqlHelper.Field_SrsEntry_ServerId + ","); sqlQueryEnd.Append("@ServerId,"); parameters.Add(new DaoParameter( "@ServerId", entity.ServerId)); } // IsDeleted (because why not?) sqlQueryStart.Append(SqlHelper.Field_SrsEntry_IsDeleted + ","); sqlQueryEnd.Append("@IsDeleted,"); parameters.Add(new DaoParameter("@IsDeleted", entity.IsDeleted)); // We are done with the string builders. // Bring the query pieces together. string finalQuery = sqlQueryStart.ToString().TrimEnd(new char[] { ',' }) + ") " + sqlQueryEnd.ToString().TrimEnd(new char[] { ',' }) + ")"; // Execute the query. if (connection.ExecuteNonQuery(finalQuery, parameters.ToArray()) == 1) { // If the row was inserted, put the insert ID in the entity. entity.ID = connection.GetLastInsertId(); } } finally { if (connection != null) { connection.Dispose(); } } }
/// <summary> /// Gets a similar item (same kanji reading and type) if found. /// </summary> /// <param name="entry">Reference entry.</param> /// <returns>The first matching item if found. Null otherwise.</returns> public SrsEntry GetSimilarItem(SrsEntry entry) { SrsEntry r = null; DaoConnection connection = null; try { connection = DaoConnection.Open(DaoConnectionEnum.SrsDatabase); List<DaoParameter> parameters = new List<DaoParameter>(); string request = "SELECT * FROM " + SqlHelper.Table_SrsEntry + " se WHERE se."; if (!string.IsNullOrEmpty(entry.AssociatedKanji)) { request += SqlHelper.Field_SrsEntry_AssociatedKanji; parameters.Add(new DaoParameter("@kr", entry.AssociatedKanji)); } else { request += SqlHelper.Field_SrsEntry_AssociatedVocab; parameters.Add(new DaoParameter("@kr", entry.AssociatedVocab)); } request += "=@kr"; NameValueCollection result = connection.Query(request, parameters.ToArray()).FirstOrDefault(); if (result != null) { SrsEntryBuilder builder = new SrsEntryBuilder(); r = builder.BuildEntity(result, null); } } finally { if (connection != null) { connection.Dispose(); } } return r; }
/// <summary> /// Removes the entity from the database. /// </summary> /// <param name="entity">Entity to delete.</param> /// <returns>True if the operation was successful. False otherwise.</returns> public bool Delete(SrsEntry entity) { DaoConnection connection = null; bool result = false; try { connection = DaoConnection.Open(DaoConnectionEnum.SrsDatabase); // Execute the query. result = connection.ExecuteNonQuery("DELETE FROM " + SqlHelper.Table_SrsEntry + " WHERE " + SqlHelper.Field_SrsEntry_Id + "=@Id", new DaoParameter("@Id", entity.ID)) == 1; } finally { if (connection != null) { connection.Dispose(); } } return result; }
/// <summary> /// Called when the AddToSrsCommand is fired. /// Opens the SRS entry window. /// </summary> private void OnAddToSrs() { // Prepare the new entry. SrsEntry entry = new SrsEntry(); entry.LoadFromKanji(_kanjiEntity.DbKanji); // Show the modal entry edition window. EditSrsEntryWindow wnd = new EditSrsEntryWindow(entry); wnd.ShowDialog(); // When it is closed, get the result. ExtendedSrsEntry result = wnd.Result; if (wnd.IsSaved && result != null && result.AssociatedKanji == _kanjiEntity.DbKanji.Character) { // The result exists and is still associated with this kanji. // We can use it in this ViewModel. SrsEntry = result; } }
public ExtendedSrsEntry(SrsEntry entry) : this(entry, false) { Reference = entry; SrsLevelStore.Instance.IssueWhenLoaded(OnSrsLevelsLoaded); }
/// <summary> /// Gets a question group from an SRS entry. /// </summary> private SrsQuestionGroup ProcessEntry(SrsEntry entry) { return new SrsQuestionGroup(entry); }
public FilteringSrsEntry(SrsEntry reference) : this(reference, false) { }
public override bool OnNextStep() { List<SrsEntry> newEntries = new List<SrsEntry>(); foreach (WkItem wkItem in Result.Items) { SrsEntry entry = new SrsEntry(); if (wkItem.IsKanji) { entry.AssociatedKanji = wkItem.KanjiReading; } else { entry.AssociatedVocab = wkItem.KanjiReading; } entry.CurrentGrade = wkItem.SrsLevel; entry.MeaningNote = wkItem.MeaningNote; entry.Meanings = wkItem.Meanings; entry.NextAnswerDate = wkItem.NextReviewDate; entry.ReadingNote = wkItem.ReadingNote; entry.Readings = wkItem.Readings; entry.SuspensionDate = _parent.IsStartEnabled ? (DateTime?)null : DateTime.Now; entry.Tags = _parent.Tags.Replace(WkImportViewModel.LevelSpecialString, wkItem.WkLevel.ToString()); newEntries.Add(entry); } _parent.NewEntries = newEntries; _parent.ApplyTiming(); return true; }
/// <summary> /// Displays the SRS item edition window to allow the /// user to add a new kanji or vocab item to the SRS. /// </summary> /// <param name="isKanji">True to add a kanji item. /// False to add a vocab item.</param> private void AddSrsItem(bool isKanji) { // Prepare the new entry. SrsEntry entry = new SrsEntry(); if (isKanji) { entry.AssociatedKanji = string.Empty; } else { entry.AssociatedVocab = string.Empty; } // Show the modal entry edition window. EditSrsEntryWindow wnd = new EditSrsEntryWindow(entry); wnd.ShowDialog(); // When it is closed, get the result. ExtendedSrsEntry result = wnd.Result; if (wnd.IsSaved && result != null) { // The new element was added. // Refresh the dashboard. SrsBusiness.Instance.UpdateReviewInfoAsync(); } }
public ExtendedSrsEntry(SrsEntry entry, bool forceLoad) { Reference = entry; if (!forceLoad) { SrsLevelStore.Instance.IssueWhenLoaded(OnSrsLevelsLoaded); } else { OnSrsLevelsLoaded(); } }
/// <summary> /// Reads an SRS item from a field row using the parameters of the view model. /// </summary> /// <param name="row">Row to read.</param> /// <param name="log">Log under the form of a stringbuilder to inform the user about how everything goes.</param> /// <returns>The SRS item read if successful. A null value otherwise.</returns> private SrsEntry ReadEntry(List<string> row, StringBuilder log) { try { SrsEntry entry = new SrsEntry(); string kanjiReading = row[_kanjiReadingColumn]; if (string.IsNullOrEmpty(kanjiReading)) { log.AppendFormat("Empty kanji reading. Skipping."); return null; } // Figure out item type. CsvItemType itemType = ReadItemType(row); if (itemType == CsvItemType.Kanji || (itemType == CsvItemType.Unspecified && (_noTypeBehavior == CsvImportNoTypeBehavior.AllKanji || (_noTypeBehavior == CsvImportNoTypeBehavior.Auto && kanjiReading.Length == 1)))) { // Three solutions to set as kanji: // 1. Item is manually specified as kanji in source data. // 2. Item is not specified and no type behavior is set to AllKanji. // 3. Item is not specified and no type behavior is set to Auto and the length of kanjiReading is exactly 1. entry.AssociatedKanji = kanjiReading; log.AppendFormat("Kanji: \"{0}\". ", kanjiReading); } else { // All other cases will lead to vocab. entry.AssociatedVocab = kanjiReading; log.AppendFormat("Vocab: \"{0}\". ", kanjiReading); } // Find readings. entry.Readings = ReadAcceptedReadings(row); if (string.IsNullOrEmpty(entry.Readings)) { log.Append("Empty readings. Skipping."); return null; } // Find meanings. entry.Meanings = ReadAcceptedMeanings(row); if (string.IsNullOrEmpty(entry.Meanings)) { log.Append("Empty meanings. Skipping."); return null; } // Find all optional info. entry.MeaningNote = ReadMeaningNotes(row); entry.ReadingNote = ReadReadingNotes(row); entry.Tags = ReadTags(row); entry.CurrentGrade = ReadStartLevel(row); entry.NextAnswerDate = ReadNextReviewDate(row); log.Append("OK."); return entry; } catch (Exception ex) { log.AppendFormat("Unknown error: \"{0}\". Skipping.", ex.Message); } return null; }
/// <summary> /// Builds a question group for the given SRS entry. /// </summary> /// <param name="reference">Target SRS entry.</param> public SrsQuestionGroup(SrsEntry reference) { Reference = reference; Questions = new List<SrsQuestion>(); if (!string.IsNullOrWhiteSpace(reference.Meanings)) { Questions.Add(new SrsQuestion() { Question = SrsQuestionEnum.Meaning, ParentGroup = this }); } if (!string.IsNullOrWhiteSpace(reference.Readings)) { Questions.Add(new SrsQuestion() { Question = SrsQuestionEnum.Reading, ParentGroup = this }); } Audio = new VocabAudio(Reference); }
public FilteringSrsEntry(SrsEntry reference, bool forceLoad) : base(reference, forceLoad) { }
/// <summary> /// Updates the given entry. /// </summary> /// <param name="entry">Entry to update.</param> private void UpdateEntry(SrsEntry entry) { _currentTransactionCount++; BackgroundWorker worker = new BackgroundWorker(); worker.DoWork += DoUpdateEntry; worker.RunWorkerCompleted += DoneUpdateEntry; worker.RunWorkerAsync(entry); }
/// <summary> /// Builds a ViewModel aimed at editing an existing SrsEntry, /// or adding a pre-composed SrsEntry. /// </summary> /// <param name="entity">Entity to edit.</param> public SrsEntryViewModel(SrsEntry entity) { // Initialize fields. _entry = new ExtendedSrsEntry(entity); _originalNextReviewDate = entity.NextAnswerDate; _originalLevelValue = entity.CurrentGrade; _associatedKanjiString = Entry.AssociatedKanji; _associatedVocabString = Entry.AssociatedVocab; _srsEntryDao = new SrsEntryDao(); _kanjiDao = new KanjiDao(); _vocabDao = new VocabDao(); if (IsNew) { Entry.Tags = Properties.Settings.Default.LastSrsTagsValue; } // Create the relay commands. SubmitCommand = new RelayCommand(OnSubmit); CancelCommand = new RelayCommand(OnCancel); SrsProgressResetCommand = new RelayCommand(OnSrsProgressReset); ApplyAssociatedKanjiCommand = new RelayCommand(OnApplyAssociatedKanji); ApplyAssociatedVocabCommand = new RelayCommand(OnApplyAssociatedVocab); ToggleSuspendCommand = new RelayCommand(OnToggleSuspend); DeleteCommand = new RelayCommand(OnDelete); ToggleDateEditCommand = new RelayCommand(OnToggleDateEdit); DateToNowCommand = new RelayCommand(OnDateToNow); DateToNeverCommand = new RelayCommand(OnDateToNever); // Get the associated kanji or vocab. GetAssociatedKanji(); GetAssociatedVocab(); // Initialize the VM. _isFirstSrsLevelSelect = true; SrsLevelPickerVm = new SrsLevelPickerViewModel(); SrsLevelPickerVm.SrsLevelSelected += OnSrsLevelSelected; SrsLevelPickerVm.Initialize(_entry.CurrentGrade); }