public static record ( string message ) : void | ||
message | string | |
return | void |
/** Note Handling **/ /********************/ // Screenshots: // Saves all screenshots in files, sets the last one to be added to the next note private void ScreenShot_Click(object sender, RoutedEventArgs e) { Logger.record("[ScreenShot_Click]: Capturing screen", "SMWidget", "info"); bool edit = false; if (System.Windows.Forms.Control.ModifierKeys == System.Windows.Forms.Keys.Shift) { edit = true; } if (edit) { this.WindowState = System.Windows.WindowState.Minimized; // <--\ } ScreenShot ss = new ScreenShot(); // ) AddScreenshot2Note(ss.CaptureScreenShot()); // ( Logger.record("[ScreenShot_Click]: Captured " + screenshotName + ", edit: " + edit.ToString(), "SMWidget", "info"); if (edit) // ( { // ) Process paint = new Process(); // ( paint.StartInfo.FileName = "mspaint.exe"; // ) paint.StartInfo.Arguments = "\"" + currentSession.workingDir + screenshotName + "\""; paint.Start(); // ) this.WindowState = System.Windows.WindowState.Normal; // <--/ } }
// ProgressTimer // Makes the progress bar progress, according to the time chosen private void ProgressTimer_Click(object sender, RoutedEventArgs e) { Logger.record("[ProgressTimer_Click]: Time to end: " + sender.ToString(), "SMWidget", "info"); if (sender.ToString().Contains("1 min")) { ProgressGo(1); } if (sender.ToString().Contains("3 min")) { ProgressGo(3); } if (sender.ToString().Contains("60 min")) { ProgressGo(60); } if (sender.ToString().Contains("90 min")) { ProgressGo(90); } if (sender.ToString().Contains("120 min")) { ProgressGo(120); } if (sender.ToString().Contains("Stop")) { ProgressGo(0); } }
// Adding attached screenshot have dedicated functions that deal with the visual // clues as well private void AddScreenshot2Note(Bitmap bitmap) { Logger.record("[AddScreenshot2Note]: Saving screen to file", "SMWidget", "info"); bool exDrRetry = false; // Name the screenshot, save to disk screenshotName = currentScreenshot++.ToString() + "_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".jpg"; do { exDrRetry = false; try { bitmap.Save(currentSession.workingDir + screenshotName, ImageFormat.Jpeg); AutoSaveScrenshot(screenshotName); } catch (Exception ex) { Logger.record("[AddScreenshot2Note]: EXCEPTION reached - Session Note file could not be saved (" + screenshotName + ")", "SMWidget", "error"); exDrRetry = Logger.FileErrorMessage(ex, "SaveToSessionNotes", screenshotName); } } while (exDrRetry); // Put a visual effect to remember the tester there's an image on the attachment barrel BevelBitmapEffect effect = new BevelBitmapEffect(); effect.BevelWidth = 2; effect.EdgeProfile = EdgeProfile.BulgedUp; ScreenShot.BitmapEffect = effect; }
private void ChangeAccount_Click(object sender, RoutedEventArgs e) // #ADDED CODE#________________---------------CHANGE ACCOUNT---------------------_________________________ { Logger.record("[ChangeAccount_Click]: Change Account", "SMWidget", "info"); // string url = flickr.AuthCalcWebUrl(AuthLevel.Write); m_flickr.LogOut(); FlickrInlogg.Text = "Account: offline"; }
// Sets the progress bar to null (stopped, not seen), and hides clock icon private void StopTimers() { Logger.record("[StopTimers]: Stopping timer (setting to null)", "SMWidget", "info"); ProgressBackground.BeginAnimation(System.Windows.Controls.ProgressBar.ValueProperty, null); Logger.record("[StopTimers]: Hiding clock icon", "SMWidget", "info"); timeralarm.Visibility = Visibility.Hidden; }
// Start Session and Close Session prepare/finalize the log file public void StartSession() { FlickrAddon.GetUniqueKey(10); Logger.record("[StartSession]: Session configuration starting", "Session", "info"); startingTime = DateTime.Now; // The time the session started is used for many things, like knowing the session file name sessionFile = startingTime.ToString("yyyyMMdd_HHmmss") + "_" + FlickrAddon.hashcode + ".csv"; //HASCODE VARIABLE ADDED__________<-------###### sessionFileFull = workingDir + sessionFile; // All files should be written to a working directory -- be it current or not. SaveToSessionNotes(columnHeaders + "\n"); // Headers of the notes table UpdateNotes("(Rapid Reporter version)", System.Windows.Forms.Application.ProductVersion); //TWITTERR!!!! // Writing hash code to log file. UpdateNotes("Hash Code", FlickrAddon.hashcode); // Writing the Twitter account name to log file if Twitter is enabled. if (TwitterAddon.ScreenName != null) { UpdateNotes("Twitter Account", TwitterAddon.ScreenName); } UpdateNotes("Session Reporter", tester); UpdateNotes("Hashcode", FlickrAddon.hashcode); //HASCODE VARIABLE ADDED__________<-------####### UpdateNotes("Session Charter", charter); //TWITTER!!!!! // Writing Twitter Link to log file if Twitter is enabled. if (TwitterAddon.twitter) { UpdateNotes("Twitter Link", "https://twitter.com/#!/search?q=%23" + FlickrAddon.hashcode); } }
// RTFNote: // Show or hide the enhanced notes window. // We don't change the note between toggles, we just ide it. Tester can continue to type later. private void RTFNote_Click(object sender, RoutedEventArgs e) { Logger.record("[RTFNote_Click]: Will toggle RTF note screen", "SMWidget", "info"); // The RTF Note button is a toggle button - it has two states: show the note area and hide the note area if (RTFNoteBtn.IsChecked.Equals(true)) // Show the note are { Logger.record("\t[RTFNote_Click]: Repositioning the RTF window", "SMWidget", "info"); // Position is either on top or bottom of SM Widget, with same width as the Widget rtf.Left = this.Left; rtf.Width = this.Width; if (this.Top > rtf.Height + 10) { rtf.Top = this.Top - (rtf.Height + 10); } else { rtf.Top = (this.Top + this.Height) + 10; } Logger.record("\t[RTFNote_Click]: Reposition:" + rtf.Top + "," + rtf.Left + "," + rtf.Width + ",", "SMWidget", "info"); rtf.Show(); rtf.Focus(); } else // Hide the note area { Logger.record("\t[RTFNote_Click]: Hiding the RTF window", "SMWidget", "info"); rtf.Hide(); } }
// AboutBox // Shows About dialog box with software info, contacts and credits private void AboutBox_Click(object sender, RoutedEventArgs e) { Logger.record("[AboutBox_Click]: About box invoked", "SMWidget", "info"); AboutDlg about = new AboutDlg(); about.Owner = this; about.ShowDialog(); }
// timeralarm_MouseLeftButtonDown: // We'll check when the progress bar reaches the end, to trigger the time's up notification private void timeralarm_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { Logger.record("[timeralarm_MouseLeftButtonDown]: Time's Up timer acknowledged by user", "SMWidget", "info"); t0.IsChecked = true; t60.IsChecked = false; t90.IsChecked = false; t120.IsChecked = false; ProgressGo(0); }
// timer_Checked, gets timing commands from the context menu private void timer_Checked(object sender, RoutedEventArgs e) { Logger.record("[timer_Checked]: Timer context menu command: " + sender.ToString(), "SMWidget", "info"); t0.IsChecked = t0.Equals(sender); t60.IsChecked = t60.Equals(sender); t90.IsChecked = t90.Equals(sender); t120.IsChecked = t120.Equals(sender); }
public string workingDir = Directory.GetCurrentDirectory() + @"\"; // The directory to save files // Initialization, and setting focus to the richtextnote area public RTFNote() { Logger.record("[RTFNote]: RTF Note window initializing", "RTFNote", "info"); InitializeComponent(); // With the code below we control when to close the window or hide it. // Didn't use a normal 'EventHandler' because we needed the Cancel option to close the window when appropriate. this.Closing += new CancelEventHandler(this.RTFNoteDialog_Close); Logger.record("[RTFNote]: RTF Note window initialized, including CancelEventHandler", "RTFNote", "info"); }
// TimerEventProcessor // The actions in this fuction will happen every time the timer expires. private void TimerEventProcessor(Object myObject, EventArgs myEventArgs) { Logger.record("[TimerEventProcessor]: Will perform recurring tasks", "SMWidget", "info"); if (100 <= ProgressBackground.Value) { Logger.record("[TimerEventProcessor]: Time's Up! Showing timer icon", "SMWidget", "info"); timeralarm.Visibility = Visibility.Visible; } }
// Constructor // We set the application name, version, and dialog title. public AboutDlg() { Logger.record("[AboutDlg]: Starting About Dialog. Initializing component.", "AboutDlg", "info"); InitializeComponent(); this.Title = System.Windows.Forms.Application.ProductName + " - Help"; this.appName.Content = System.Windows.Forms.Application.ProductName; this.appVers.Content = System.Windows.Forms.Application.ProductVersion; Ok.Focus(); }
public Bitmap CaptureScreenShot() { Logger.record("[CaptureScreenshot]: Will take a screenshot of the monitor.", "ScreenShot", "info"); Rectangle fullBounds = new Rectangle(); int minX = 0, minY = 0, maxX = 0, maxY = 0; /* * * Composite desktop calculations for multiple monitors * * A, B E, B || E, B +--------------+ || * +---------------+ D, B | |E, G || | | | +---------------+ D, G || +--------------+ E, C | | | | || |A, C | | | | | || | | | | | | || | | | +--------------+ E, C | || | +---------------+ D, G | A, C | | || | |E, G +---------------+ D, F || +--------------+ * | E, F || A, F E, F | * We capture from "A, B" to "D, F". * That is, we look for the minimum X,Y coordinate first. * Then we look for the largest width,height. * */ foreach (Screen oneScreen in Screen.AllScreens) { Logger.record("\t[CaptureScreenshot]: AllScreens[]: " + oneScreen.Bounds.ToString(), "ScreenShot", "info"); minX = Math.Min(minX, oneScreen.Bounds.Left); minY = Math.Min(minY, oneScreen.Bounds.Top); maxX = Math.Max(maxX, oneScreen.Bounds.Width + oneScreen.Bounds.X); maxY = Math.Max(maxY, oneScreen.Bounds.Height + oneScreen.Bounds.Y); } fullBounds = new Rectangle(minX, minY, maxX - minX, maxY - minY); Logger.record("[CaptureScreenshot]: fullScreen[]: " + fullBounds.ToString(), "ScreenShot", "info"); IntPtr hDesk = GetDesktopWindow(); IntPtr hSrce = GetWindowDC(hDesk); IntPtr hDest = CreateCompatibleDC(hSrce); // Our bitmap will have the size of the composite screenshot IntPtr hBmp = CreateCompatibleBitmap(hSrce, fullBounds.Width, fullBounds.Height); IntPtr hOldBmp = SelectObject(hDest, hBmp); // We write on coordinate 0,0 of the bitmap buffer, of course. But we write the the fullBoundsX,Y pixels. bool b = BitBlt(hDest, 0, 0, fullBounds.Width, fullBounds.Height, hSrce, fullBounds.X, fullBounds.Y, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt); Bitmap bmp = Bitmap.FromHbitmap(hBmp); SelectObject(hDest, hOldBmp); DeleteObject(hBmp); DeleteDC(hDest); ReleaseDC(hDesk, hSrce); Logger.record("[CaptureScreenshot]: BMP object ready, returning it to calling function", "ScreenShot", "info"); return(bmp); }
// The dialog is generic. // We load a different text every time, and two functions are provided: One to load the text from the pre-defined list of messages, // and one to load a short text, on demand. Both simply write to "this.helpApp.Text". public void LoadText(int helpType) { Logger.record("[LoadText i]: Loading text by type, #" + helpType.ToString(), "HelpDlg", "info"); // Help is: // 0 - Normal help inside application // 1 - -help help // 2 - -report help // 3 - -tohtml help this.helpApp.Text = longstrings.helpstrings.helpstring[helpType]; }
// Change Working Dir // Changes the working Directory for the session private void SetWorkingDir(string newPath) { Logger.record("[SetWorkingDir] Setting directory to " + newDir, "SMWidget", "info"); if (!newPath.EndsWith(@"\")) { newPath += @"\"; // Add the trailing 'slash' to the directory } rtf.workingDir = currentSession.workingDir = newPath; // the workingDir needs to be the same for all files! FolderName.Header = (50 < currentSession.workingDir.Length) ? "..." + currentSession.workingDir.Substring(currentSession.workingDir.Length - 47) : currentSession.workingDir; }
public void UpdateNotes(string type, string note, string screenshot = "", string RTFNote = "") { if (type != "(Rapid Reporter version)" && type != "Session End. Duration" && type != "WebUrl") { m_strTags += "#" + type + " " + note + ","; } sessionNote = DateTime.Now + "," + tester + "," + type + ",\"" + note + "\"," + screenshot + "," + RTFNote + "\n"; SaveToSessionNotes(sessionNote); Logger.record("[UpdateNotes ss]: Note added to session log (" + screenshot + ", " + RTFNote + ")", "Session", "info"); }
public void ShowHelp(string helpText) { Logger.record("\t\t[ShowHelp s]: Showing help dialog >" + helpText, "SMWidget", "info"); Help help = new Help(); help.LoadText(helpText); help.ShowInTaskbar = true; // In this cases we don't show the main window, so at least we show this one help.ShowDialog(); }
// Popping the Help Dialog // Some of the lines below are duplicated in the About dialog code public void ShowHelp(int helpType) { Logger.record("\t\t[ShowHelp i]: Showing help dialog #" + helpType.ToString(), "SMWidget", "info"); // Help is: // 0 - Normal help inside application // 1 - -help help // 2 - -report help // 3 - -tohtml help ShowHelp(longstrings.helpstrings.helpstring[helpType]); }
public sessionStartingStage currentStage = sessionStartingStage.tester; // This is used only in the beginning, in order to receive the tester name and charter text /** Sessions **/ /**************/ // Start Session and Close Session prepare/finalize the log file public void StartSession() { Logger.record("[StartSession]: Session configuration starting", "Session", "info"); startingTime = DateTime.Now; // The time the session started is used for many things, like knowing the session file name sessionFile = startingTime.ToString("yyyyMMdd_HHmmss") + ".csv"; sessionFileFull = workingDir + sessionFile; // All files should be written to a working directory -- be it current or not. SaveToSessionNotes(columnHeaders + "\n"); // Headers of the notes table UpdateNotes("(Rapid Reporter version)", System.Windows.Forms.Application.ProductVersion); UpdateNotes("Session Reporter", tester); UpdateNotes("Session Charter", charter); }
RTFNote rtf = new RTFNote(); // The enhanced note window /** Starting Process **/ /**********************/ /// The application starts by asking for tester and charter information. Only then the session starts // Default constructor, everything is empty/default values public SMWidget() { Logger.record("[SMWidget]: App constructor. Initializing.", "SMWidget", "info"); InitializeComponent(); rtf.InitializeComponent(); rtf.sm = this; NoteContent.Focus(); parseCLI(); handleCLI(); Logger.record("[SMWidget]: App constructor initialized and CLI executed.", "SMWidget", "info"); }
// The function below will change the visuals of the application at the different stages (tester/charter/notes state based behavior) private void StateMove(sessionStartingStage newStage) { Logger.record("[StateMove]: Session Stage now: " + currentStage.ToString(), "SMWidget", "info"); currentStage = newStage; switch (currentStage) { case sessionStartingStage.tester: NoteType.Text = "Reporter:"; prevType.Text = ""; nextType.Text = ""; FlickrInlogg.Text = ""; prevNoteType = 1; nextNoteType = currentSession.noteTypes.Length - 1; OpenFolder.Header = "Change working folder..."; Logger.record("\t[StateMove]: Session Stage moving -> Tester", "SMWidget", "info"); break; case sessionStartingStage.charter: NoteType.Text = "Charter:"; Logger.record("\t[StateMove]: Session Stage moving -> Charter", "SMWidget", "info"); break; case sessionStartingStage.notes: NoteContent.ToolTip = (100 < currentSession.charter.Length) ? currentSession.charter.Remove(100) + "..." : currentSession.charter; NoteType.Text = currentSession.noteTypes[currentNoteType] + ":"; prevType.Text = "↓ " + currentSession.noteTypes[prevNoteType] + ":"; nextType.Text = "↑ " + currentSession.noteTypes[nextNoteType] + ":"; if (m_flickrLoggedIn) // #ADDED CODE#________________---------------This If and Else displays if you are logged in our not in rapid reporter---------------------______________ { FlickrInlogg.Text = "Account: " + m_flickr.GetCurrentUser(); //currentSession.noteTypes[ReporterNoteName] } else { FlickrInlogg.Text = "Offline"; } //-------------------------------------------_________________________________________________________________________________________________________________________________ currentSession.StartSession(); ProgressGo(90); t90.IsChecked = true; ScreenShot.IsEnabled = true; RTFNoteBtn.IsEnabled = true; ToggleUploadIcon.IsEnabled = true; // Change the icon of the image of the buttons, to NOT appear disabled. ScreenShotIcon.Source = new BitmapImage(new Uri("iconshot.png", UriKind.Relative)); RTFNoteBtnIcon.Source = new BitmapImage(new Uri("iconnotes.png", UriKind.Relative)); TimerMenu.IsEnabled = true; ChangeAccount.IsEnabled = true; OpenFolder.Header = "Open working folder..."; Logger.record("\t\t[StateMove]: Session Stage moving -> Notes", "SMWidget", "info"); break; default: Logger.record("\t[StateMove]: Session Stage moving -> NULL", "SMWidget", "error"); break; } }
// ClearNote: // Makes space for a new note private void ClearNote() { Logger.record("[ClearNote]: Will delete note content and attachments indication", "SMWidget", "info"); NoteContent.Text = ""; // New note screenshotName = ""; // New pic attachment rtfNoteName = ""; // New note attachment (RTF note area content is left intact!) // Clear visual effects (screenshots are all always saved anyway) BevelBitmapEffect effect = new BevelBitmapEffect(); effect.BevelWidth = 0; effect.EdgeProfile = EdgeProfile.BulgedUp; ScreenShot.BitmapEffect = effect; RTFNoteBtn.BitmapEffect = effect; }
// Before closing the window, we have to close the session and the RTF note private void ExitApp() { // Session Logger.record("[ExitApp]: Closing Session...", "SMWidget", "info"); currentSession.CloseSession(); // RTF Note Logger.record("[ExitApp]: Closing RTF Note (force = true)...", "SMWidget", "info"); rtf.forceClose = true; // We keep the RTF open (hidden), so we have to force it out Logger.record("[ExitApp]: Closing RTF Note...", "SMWidget", "info"); rtf.Close(); // This form Logger.record("[ExitApp]: End of application!", "SMWidget", "info"); }
// Prepare the session report log (adds the notes types, for example) private void SMWidgetForm_Loaded(object sender, RoutedEventArgs e) { Logger.record("[SMWidgetForm_Loaded]: Form loading to windows", "SMWidget", "info"); SMWidgetForm.Title = System.Windows.Forms.Application.ProductName; SetWorkingDir(currentSession.workingDir); StateMove(sessionStartingStage.tester); // Some of the actions in the tool are recurrent. We do them every 30 seconds. recurrenceTimer.Tick += new EventHandler(TimerEventProcessor); // this is the function called everytime the timer expires recurrenceTimer.Interval = 90 * 1000; // 30 times 1 second (1000 milliseconds) recurrenceTimer.Start(); this.NoteContent.Focus(); }
// When the note is 'saved', it get's saved into an RTF file, and marked for being attached to a session note. private void save_Click(object sender, RoutedEventArgs e) { Logger.record("[save_Click]: RTF Note to be saved", "RTFNote", "info"); bool exDrRetry = false; TextRange tr = new TextRange(richTextNote.Document.ContentStart, richTextNote.Document.ContentEnd); // How do we kow the '3' minimum? By trial and error. Any character entered in the area makes it go 3+. Empty area is 0<=x<=2 if (3 <= tr.Text.Length) { Logger.record("\t[save_Click]: RTF Note not empty, will save", "RTFNote", "info"); // Name the note, save to file sm.rtfNoteName = currentRTFNote++.ToString() + "_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".rtf"; do { exDrRetry = false; try { // Process is: // 1. Save the file // 2. Change the visual cue // 3. Add an autogenerated line to the session CSV // Saves the file FileStream fs = new FileStream(workingDir + sm.rtfNoteName, FileMode.OpenOrCreate, FileAccess.Write); TextRange RTF = new TextRange(richTextNote.Document.ContentStart, richTextNote.Document.ContentEnd); RTF.Save(fs, System.Windows.DataFormats.Rtf); // Set the visual effect to clue the tester there's a note attached BevelBitmapEffect effect = new BevelBitmapEffect(); effect.BevelWidth = 2; effect.EdgeProfile = EdgeProfile.BulgedUp; sm.RTFNoteBtn.BitmapEffect = effect; // Adds an 'autogenerated' line to the session CSV sm.AutoSaveNote(sm.rtfNoteName); Logger.record("\t\t[save_Click]: RTF Note saved: " + sm.rtfNoteName, "RTFNote", "info"); } catch (Exception ex) { Logger.record("\t\t[save_Click]: EXCEPTION reached - RTF Note file could not be saved (" + sm.rtfNoteName + ")", "RTFNote", "error"); exDrRetry = Logger.FileErrorMessage(ex, "save_Click", sm.rtfNoteName); } } while (exDrRetry); } Logger.record("[save_Click]: RTF Note saving mechanism done. Will close (hide).", "RTFNote", "info"); // We not really 'close' the window. Close function deals with whether hiding or closing it. this.Close(); Logger.record("[save_Click]: RTF Note saving mechanism done. Closed (hidden).", "RTFNote", "info"); }
/** Reporting **/ /***************/ // General note on writign the reports to disk: // Some bug reports seem to indicate that we are holding the file while trying to write to it. // This is the reason of adding 150 milliseconds of delay between writes. // I'll only know how dumb an idea is it after continuing (or not) to receive exception reports from users. // When a report collection is requested: public void CollectReport() { Logger.record("[CollectReport]: Report building", "Session", "info"); bool exDrRetry = false; string report_prefix = "report_"; string reportFile = report_prefix + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".csv"; string reportFileFull = workingDir + reportFile; String[] files = Directory.GetFiles(workingDir, "*.csv"); Array.Sort(files); do { exDrRetry = false; try { File.AppendAllText(reportFileFull, columnHeaders + "\n"); Thread.Sleep(150); foreach (string file in files) { // Skip over other report files if (file.Contains(report_prefix)) { continue; } // Skip over files that don't end like ########_######.csv. if (!(System.Text.RegularExpressions.Regex.IsMatch(file, ".*\\d{8}_\\d{6}.csv$", System.Text.RegularExpressions.RegexOptions.IgnoreCase))) { continue; } StreamReader sr = new StreamReader(file); sr.ReadLine(); // We skip the first line (with the headers); string oneFile = sr.ReadToEnd(); File.AppendAllText(reportFileFull, oneFile); Thread.Sleep(150); Logger.record("\t[CollectReport]: Another file concatenated into a report: " + file, "Session", "info"); // TODO: Remove the Thread.Sleep(150) parts? } } catch (Exception ex) { Logger.record("[CollectReport]: EXCEPTION reached - Session Report file could not be saved (" + reportFile + ")", "Session", "error"); exDrRetry = Logger.FileErrorMessage(ex, "CollectReport", reportFile); } } while (exDrRetry); Logger.record("[CollectReport]: Report built, done.", "Session", "info"); MessageBox.Show("Rapid Reporter has finished the report consolidation process.\nFile generated: " + reportFile, "Rapid Reporter -report consolidation", MessageBoxButton.OK, MessageBoxImage.Information); }
// Always hide the window. Unless the app is being closed completely, then close too. // When hidding the window, toggle the button status on the main Widget. private void RTFNoteDialog_Close(object sender, CancelEventArgs e) { Logger.record("[RTFNoteDialog_Close]: Close function called with force flag = " + forceClose.ToString(), "RTFNote", "info"); Logger.record("[RTFNoteDialog_Close]: Toggling button state", "RTFNote", "info"); sm.RTFNoteBtn.IsChecked = false; // The only way I found to control on how to cancel the closing or not, was by using an external flag. if (forceClose != true) { // Apparently, there is an exception in some machines when closing the app and/or RTF // we try to catch it here. // Bug report: [94adb64c91] try { Logger.record("\t[RTFNoteDialog_Close]: Hiding RTF Note window", "RTFNote", "info"); Logger.record("\t[RTFNoteDialog_Close]: Hiding RTF Note window - Step 1: _isClosing = false...", "RTFNote", "info"); typeof(Window).GetField("_isClosing", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(this, false); Logger.record("\t[RTFNoteDialog_Close]: Hiding RTF Note window - Step 2: e.Cancel = true...", "RTFNote", "info"); e.Cancel = true; // Abort the close event Logger.record("\t[RTFNoteDialog_Close]: Hiding RTF Note window - Step 3: this.Hide...", "RTFNote", "info"); this.Hide(); // Hide is throwing an exception: // "Cannot set visibility or call show, showdialog, close, or hide while window is closing" // Step 1 is supposed to overcome this exception. Hopefully. Logger.record("\t[RTFNoteDialog_Close]: Hiding RTF Note window - Step 3: this.Hide finished", "RTFNote", "info"); } catch (Exception ex) { Logger.record("\t[RTFNoteDialog_Close]: EXCEPTION reached - RTF Note closing could not be cancelled", "RTFNote", "error"); System.Windows.Forms.MessageBox.Show( "Hi! An error occured when trying to hide the rich text extended note window.\n" + "Although this does not happen often, it was seen a few times and is under investigation.\n" + "This is a very annoying bug. Meanwhile, let me suggest a way to bypass the problem:\n" + " -- Instead of closing the extended note window (by Alt-F4 or clicking 'X'),\n" + " -- try hiding it by pressing the 'N' button again in the main (golden) window.\n\n" + "Your feedback is very important, please contact us and report the problem if you can/want.\n\n" + "Exception details:\n" + ex.Message, "Framework Error: RTFNote_Closed", MessageBoxButtons.OK, MessageBoxIcon.Error); } } else // forceClose == true; { // Let the window close normally Logger.record("\t[RTFNoteDialog_Close]: Closing RTF Note window completely", "RTFNote", "info"); } Logger.record("[RTFNoteDialog_Close]: Close function finished", "RTFNote", "info"); }
/** Notes **/ /***********/ // Notes are always saved on file, not only when program exists (so no data loss in case of crash) // UpdateNotes: There are two overloads: One receives all strings (custom messages), the other an int (typed messages) public void UpdateNotes(int type, string note, string screenshot, string RTFNote) { UpdateNotes(noteTypes[type], note, screenshot, RTFNote); Logger.record("[UpdateNotes isss]: Note added to session log. Attachments: (" + (screenshot.Length > 0).ToString() + " | " + (RTFNote.Length > 0).ToString() + ")", "Session", "info"); // Truncate if necessary and post on Twitter if Twitter is enabled. if (TwitterAddon.twitter) { TwitterAddon.tempNote = note; TwitterAddon.tempType = type; TwitterAddon.tempTester = tester; TwitterAddon.tempCharter = charter; TwitterAddon.tempNoteTypes = noteTypes; TwitterAddon.PostOnTwitter(); } }
public void CloseSession() // Not closing directly, we first finalize the session { Logger.record("[CloseSession]: Session closing...", "Session", "info"); // Why this if? We will only add the 'end session' note if we were past the charter step. if (!String.Equals(charter, "")) { TimeSpan duration = DateTime.Now - startingTime; UpdateNotes("Session End. Duration", duration.Hours.ToString().PadLeft(2, '0') + ":" + duration.Minutes.ToString().PadLeft(2, '0') + ":" + duration.Seconds.ToString().PadLeft(2, '0')); } // This condition possibly could have been done by: if (currentStage == sessionStartingStage.notes). // I wonder why I did it the wrong way? // TODO: Use the second, more elegant comparison. Make a few tests to make sure it's making sense. Logger.record("[CloseSession]: ...Session closed", "Session", "info"); }