// ask the user to confirm value propagation from the last value private bool? ConfirmPropagateFromLastValue(String text, int imagesAffected) { text = text.Trim(); MessageBox messageBox = new MessageBox("Please confirm 'Propagate to Here' for this field.", Application.Current.MainWindow, MessageBoxButton.YesNo); messageBox.Message.StatusImage = MessageBoxImage.Question; messageBox.Message.What = "Propagate to here is not undoabl, and can overwrite existing values."; messageBox.Message.Reason = "\u2022 The last non-empty value '" + text + "' was seen " + imagesAffected.ToString() + " files back." + Environment.NewLine; messageBox.Message.Reason += "\u2022 That field's value will be copied across all files between that file and this one in the selection"; messageBox.Message.Result = "If you select yes: " + Environment.NewLine; messageBox.Message.Result = "\u2022 " + imagesAffected.ToString() + " files will be affected."; return messageBox.ShowDialog(); }
/// <summary>Propagate the current value of this control forward from this point across the current selection.</summary> public void CopyForward(DataEntryControl control, bool checkForZeroValue) { int filesAffected = this.FileDatabase.CurrentlySelectedFileCount - this.ImageCache.CurrentRow - 1; if (filesAffected == 0) { // should be unreachable as the menu shouldn't be be enabled on the last file MessageBox messageBox = new MessageBox("Nothing to copy forward.", Application.Current.MainWindow); messageBox.Message.Reason = "As you are on the last file, there are no files after this."; messageBox.ShowDialog(); return; } string valueToCopy = this.ImageCache.Current.GetValueDisplayString(control); if (this.ConfirmCopyForward(valueToCopy, filesAffected, checkForZeroValue) != true) { return; } // update starts on the next row since copying from the current row this.FileDatabase.UpdateFiles(this.ImageCache.Current, control, this.ImageCache.CurrentRow + 1, this.FileDatabase.CurrentlySelectedFileCount - 1); }
// ask the user to confirm value propagation from the last value private bool? ConfirmCopyForward(string text, int imagesAffected, bool checkForZero) { text = text.Trim(); MessageBox messageBox = new MessageBox("Please confirm copy forward for this field...", Application.Current.MainWindow, MessageBoxButton.YesNo); messageBox.Message.StatusImage = MessageBoxImage.Question; messageBox.Message.What = "Copy forward is not undoable and can overwrite existing values."; messageBox.Message.Result = "If you select yes, this operation will:" + Environment.NewLine; if (!checkForZero && text.Equals(String.Empty)) { messageBox.Message.Result += "\u2022 copy the (empty) value '" + text + "' in this field from here to the last of the selected files."; } else { messageBox.Message.Result += "\u2022 copy the value '" + text + "' in this field from here to the last of the selected files."; } messageBox.Message.Result += Environment.NewLine + "\u2022 over-write any existing data values in those fields"; messageBox.Message.Result += Environment.NewLine + "\u2022 will affect " + imagesAffected.ToString() + " files."; return messageBox.ShowDialog(); }
// ask the user to confirm propagation to all selected files private bool? ConfirmCopyCurrentValueToAll(String text, int filesAffected, bool checkForZero) { text = text.Trim(); MessageBox messageBox = new MessageBox("Please confirm copy to all for this field...", Application.Current.MainWindow, MessageBoxButton.YesNo); messageBox.Message.StatusImage = MessageBoxImage.Question; messageBox.Message.What = "Copy to all is not undoable and can overwrite existing values."; messageBox.Message.Result = "If you select yes, this operation will:" + Environment.NewLine; if (!checkForZero && text.Equals(String.Empty)) { messageBox.Message.Result += "\u2022 clear this field across all " + filesAffected.ToString() + " selected files."; } else { messageBox.Message.Result += "\u2022 set this field to '" + text + "' across all " + filesAffected.ToString() + " selected files."; } messageBox.Message.Result += Environment.NewLine + "\u2022 over-write any existing data values in those fields"; return messageBox.ShowDialog(); }
/// <summary> /// Copy the last non-empty value in this control preceding this file up to the current file /// </summary> public string CopyFromLastNonEmptyValue(DataEntryControl control) { bool isCounter = control is DataEntryCounter; bool isFlag = control is DataEntryFlag; ImageRow fileWithLastNonEmptyValue = null; int indexToCopyFrom = Constant.Database.InvalidRow; string valueToCopy = isCounter ? "0" : String.Empty; for (int previousIndex = this.ImageCache.CurrentRow - 1; previousIndex >= 0; previousIndex--) { // Search for the row with some value in it, starting from the previous row ImageRow file = this.FileDatabase.Files[previousIndex]; valueToCopy = file.GetValueDatabaseString(control.DataLabel); if (valueToCopy == null) { continue; } valueToCopy = valueToCopy.Trim(); if (valueToCopy.Length > 0) { if ((isCounter && !valueToCopy.Equals("0")) || // skip zero values for counters (isFlag && !valueToCopy.Equals(Boolean.FalseString, StringComparison.OrdinalIgnoreCase)) || // false values for flags are considered empty (!isCounter && !isFlag)) { indexToCopyFrom = previousIndex; fileWithLastNonEmptyValue = file; break; } } } if (indexToCopyFrom == Constant.Database.InvalidRow) { // Nothing to propagate. If the menu item is deactivated as expected this shouldn't be reachable. MessageBox messageBox = new MessageBox("Nothing to propagate to here.", Application.Current.MainWindow); messageBox.Message.Reason = "None of the earlier files have anything in this field, so there are no values to propagate."; messageBox.ShowDialog(); return this.FileDatabase.Files[this.ImageCache.CurrentRow].GetValueDisplayString(control); // No change, so return the current value } int imagesAffected = this.ImageCache.CurrentRow - indexToCopyFrom; if (this.ConfirmPropagateFromLastValue(valueToCopy, imagesAffected) != true) { return this.FileDatabase.Files[this.ImageCache.CurrentRow].GetValueDisplayString(control); // No change, so return the current value } this.FileDatabase.UpdateFiles(fileWithLastNonEmptyValue, control, indexToCopyFrom + 1, this.ImageCache.CurrentRow); return valueToCopy; }
// Checks for updates by comparing the current version number with a version stored on the Carnassial website in an xml file. public bool TryGetAndParseRelease(bool showNoUpdatesMessage) { Version publicallyAvailableVersion = null; string description = null; using (WebClient webClient = new WebClient()) { webClient.Headers.Add(HttpRequestHeader.UserAgent, "Carnassial-GithubReleaseClient"); try { string releaseJson = webClient.DownloadString(this.latestReleaseAddress); if (String.IsNullOrWhiteSpace(releaseJson) || releaseJson.Contains("\"message\": \"Not Found\"")) { // no releases, so nothing to do return false; } JsonSerializer serializer = JsonSerializer.CreateDefault(); using (StringReader reader = new StringReader(releaseJson)) { using (JsonReader jsonReader = new JsonTextReader(reader)) { GithubRelease latestRelease = serializer.Deserialize<GithubRelease>(jsonReader); if (latestRelease == null || String.IsNullOrWhiteSpace(latestRelease.TagName)) { return false; } // Version's parse implementation requires the leading v of Github convention be removed if (Version.TryParse(latestRelease.TagName.Substring(1), out publicallyAvailableVersion) == false) { return false; } description = latestRelease.Name + Environment.NewLine + latestRelease.Body; } } } catch (WebException exception) { // 404 if no production releases (Github's latest endpoint doesn't return releases with prerelease = true) if ((exception.Response is HttpWebResponse == false) || (((HttpWebResponse)exception.Response).StatusCode != HttpStatusCode.NotFound)) { Debug.Fail(exception.ToString()); } return false; } catch (Exception exception) { Debug.Fail(exception.ToString()); return false; } } // get the running version Version currentVersion = Assembly.GetExecutingAssembly().GetName().Version; // compare the versions if (currentVersion < publicallyAvailableVersion) { // ask the user if they would like to download the new version string title = String.Format("Get the new version of {0}?", this.applicationName); MessageBox messageBox = new MessageBox(title, Application.Current.MainWindow, MessageBoxButton.YesNo); messageBox.Message.StatusImage = MessageBoxImage.Question; messageBox.Message.What = String.Format("You're running an old release, {0} {1}.", this.applicationName, currentVersion); messageBox.Message.Reason = String.Format("A new version is available, {0} {1}", this.applicationName, publicallyAvailableVersion); messageBox.Message.Solution = "Select 'Yes' to go to the website and download it."; messageBox.Message.Result = description; messageBox.Message.Hint = "\u2022 We recommend downloading the latest release." + Environment.NewLine; messageBox.Message.Hint += String.Format(@"\u2022 To see all releases, go to {0}.", CarnassialConfigurationSettings.GetReleasesBrowserAddress()); if (messageBox.ShowDialog() == true) { Uri releasesAddress = CarnassialConfigurationSettings.GetReleasesBrowserAddress(); Process.Start(releasesAddress.AbsoluteUri); } } else if (showNoUpdatesMessage) { MessageBox messageBox = new MessageBox(String.Format("No updates to {0} are available.", this.applicationName), Application.Current.MainWindow); messageBox.Message.Reason = String.Format("You're running the latest release, {0} {1}.", this.applicationName, currentVersion); messageBox.Message.StatusImage = MessageBoxImage.Information; bool? messageBoxResult = messageBox.ShowDialog(); } return true; }
public static void ShowExceptionReportingDialog(string title, UnhandledExceptionEventArgs e, Window owner) { MessageBox exitNotification = new MessageBox("Uh-oh. We're so sorry.", owner); exitNotification.Message.StatusImage = MessageBoxImage.Error; exitNotification.Message.Title = title; exitNotification.Message.Problem = String.Format("This is a bug. The What section below has been copied. Please paste it into a new issue at {0} or an email to {1}. Please also include a clear and specific description of what you were doing at the time.", CarnassialConfigurationSettings.GetIssuesBrowserAddress(), CarnassialConfigurationSettings.GetDevTeamEmailLink().ToEmailAddress()); exitNotification.Message.What = String.Format("{0}, {1}, .NET {2}{3}", typeof(CarnassialWindow).Assembly.GetName(), Environment.OSVersion, Utilities.GetDotNetVersion(), Environment.NewLine); if (e.ExceptionObject != null) { exitNotification.Message.What += e.ExceptionObject.ToString(); } exitNotification.Message.Reason = "It's not you, it's us. If you let us know we'll get it fixed. If you don't tell us probably we don't know there's a problem and things won't get any better."; exitNotification.Message.Result = String.Format("The data file is likely OK. If it's not you can restore from the {0} folder.", Constant.File.BackupFolder); exitNotification.Message.Hint = "\u2022 If you do the same thing this'll probably happen again. If so, that's helpful to know as well." + Environment.NewLine; exitNotification.Message.Hint += "\u2022 If the automatic copy of the What content didn't take click on the What details, hit ctrl+a to select all of it, and ctrl+c to copy."; Clipboard.SetText(exitNotification.Message.What); exitNotification.ShowDialog(); }