Skip to content

Commit 9b978b5

Browse files
Support for warning for infinite loop, localized errors for new generic HTTP code based errors and IntelliSense compatibility
"Create Music with AI" is made StreamContent instead of GenerateContent to apply infinite loop warning, localized errors are extended for new generic HTTP code based errors and methods are made IntelliSense compatible.
1 parent 69cd3a6 commit 9b978b5

72 files changed

Lines changed: 4682 additions & 428 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

NeoBleeper/AIGeneratedNBPMLError.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,14 @@ private void ThemeManager_ThemeChanged(object? sender, EventArgs e)
4141
}
4242
}
4343
}
44+
45+
/// <summary>
46+
/// Applies the current application theme to the control based on user or system settings.
47+
/// </summary>
48+
/// <remarks>This method updates the control's appearance to match the selected theme. If the
49+
/// theme is set to follow the system, the method detects the system's light or dark mode and applies the
50+
/// corresponding theme. The method also enables double buffering to improve rendering performance and
51+
/// temporarily suspends layout updates to prevent flickering during the theme change.</remarks>
4452
private void SetTheme()
4553
{
4654
this.SuspendLayout(); // Suspend layout to batch updates

NeoBleeper/AboutNeobleeper.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ private void ThemeManager_ThemeChanged(object? sender, EventArgs e)
4141
}
4242
}
4343

44+
/// <summary>
45+
/// Applies the current application theme to the control based on user or system settings.
46+
/// </summary>
47+
/// <remarks>This method updates the control's appearance to match the selected theme. If the
48+
/// theme is set to follow the system, the method detects the system's light or dark mode and applies the
49+
/// corresponding theme. The method temporarily suspends layout and enables double buffering to ensure a smooth
50+
/// visual update.</remarks>
4451
private void SetTheme()
4552
{
4653
this.SuspendLayout(); // Suspend layout to batch updates

NeoBleeper/AdvancedSystemSpeakerTest.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ private void ThemeManager_ThemeChanged(object? sender, EventArgs e)
2727
}
2828
}
2929

30+
/// <summary>
31+
/// Applies the current application theme to the control based on user or system settings.
32+
/// </summary>
33+
/// <remarks>This method updates the control's appearance to match the selected theme. If the
34+
/// theme is set to follow the system, the method detects the system's light or dark mode and applies the
35+
/// corresponding theme. The method should be called whenever the theme setting changes to ensure the control
36+
/// reflects the correct appearance.</remarks>
3037
private void SetTheme()
3138
{
3239
this.SuspendLayout(); // Suspend layout to batch updates
@@ -76,6 +83,16 @@ private void DarkTheme()
7683
this.ForeColor = Color.White;
7784
UIHelper.ApplyCustomTitleBar(this, Color.Black, darkTheme);
7885
}
86+
87+
/// <summary>
88+
/// Initiates the advanced system speaker test sequence asynchronously, performing a series of diagnostic checks
89+
/// and updating the user interface with progress and results.
90+
/// </summary>
91+
/// <remarks>This method runs multiple hardware and signal tests on the system speaker, including
92+
/// electrical feedback, port state stability, and frequency sweep diagnostics. Progress and results are logged
93+
/// and displayed to the user. The method is asynchronous and should not be called concurrently. If an error
94+
/// occurs during testing, the user interface is updated to indicate the failure and details are
95+
/// logged.</remarks>
7996
private async void StartTest()
8097
{
8198
try

NeoBleeper/ClearNoteCommand.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ public ClearNoteCommand(ListView listView, int noteIndex, Target target = Target
5252
}
5353
}
5454

55+
/// <summary>
56+
/// Clears the text of the note subitem for each item in the list view corresponding to the previously stored
57+
/// states.
58+
/// </summary>
59+
/// <remarks>This method resets the text of the subitem at the specified note index to an empty string for
60+
/// all items whose indices are present in the previousStates collection. If a subitem at the note index does not
61+
/// exist, it is created. Items with indices outside the valid range of the list view are ignored.</remarks>
5562
public void Execute()
5663
{
5764
foreach (var (Index, _) in previousStates)
@@ -68,6 +75,12 @@ public void Execute()
6875
}
6976
}
7077

78+
/// <summary>
79+
/// Reverts the most recent changes made to the note text in the associated list view items.
80+
/// </summary>
81+
/// <remarks>Use this method to restore the previous state of note text for all affected items. This
82+
/// operation does not raise events or notify listeners of the change. If an item's previous state cannot be
83+
/// restored due to an invalid index, that item is skipped.</remarks>
7184
public void Undo()
7285
{
7386
foreach (var (Index, PreviousText) in previousStates)

NeoBleeper/CommandManager.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,13 @@ public CommandManager(Originator originator)
3434

3535
public event EventHandler StateChanged;
3636

37+
/// <summary>
38+
/// Executes the specified command and records it for undo and redo operations.
39+
/// </summary>
40+
/// <remarks>This method saves the current state before executing the command, enabling the operation to
41+
/// be undone or redone later. After execution, the redo history is cleared. If the command is null, an exception
42+
/// may be thrown.</remarks>
43+
/// <param name="command">The command to execute. Cannot be null.</param>
3744
public void ExecuteCommand(ICommand command)
3845
{
3946
undoMementos.Push(originator.CreateMemento());
@@ -44,6 +51,11 @@ public void ExecuteCommand(ICommand command)
4451
OnStateChanged();
4552
}
4653

54+
/// <summary>
55+
/// Clears all undo and redo history, resetting the state tracking to the current state.
56+
/// </summary>
57+
/// <remarks>After calling this method, all previous undo and redo operations are discarded. The current
58+
/// state becomes the new baseline for future undo and redo actions.</remarks>
4759
public void ClearHistory()
4860
{
4961
undoStack.Clear();
@@ -54,6 +66,11 @@ public void ClearHistory()
5466
OnStateChanged();
5567
}
5668

69+
/// <summary>
70+
/// Reverses the most recent operation, restoring the previous state if an undo is available.
71+
/// </summary>
72+
/// <remarks>This method has no effect if there are no operations to undo. After calling this method, the
73+
/// state can be redone using the corresponding redo functionality, if available.</remarks>
5774
public void Undo()
5875
{
5976
if (CanUndo)
@@ -67,6 +84,11 @@ public void Undo()
6784
}
6885
}
6986

87+
/// <summary>
88+
/// Performs the most recent undone operation, if a redo is available.
89+
/// </summary>
90+
/// <remarks>Call this method to reapply the last operation that was undone using the undo functionality.
91+
/// If there are no operations available to redo, this method has no effect.</remarks>
7092
public void Redo()
7193
{
7294
if (CanRedo)
@@ -80,11 +102,24 @@ public void Redo()
80102
}
81103
}
82104

105+
/// <summary>
106+
/// Raises the StateChanged event to notify subscribers of a change in state.
107+
/// </summary>
108+
/// <remarks>Override this method in a derived class to provide custom logic when the state changes. This
109+
/// method invokes the StateChanged event with the current instance as the sender and an empty EventArgs
110+
/// object.</remarks>
83111
protected virtual void OnStateChanged()
84112
{
85113
StateChanged?.Invoke(this, EventArgs.Empty);
86114
}
87115

116+
/// <summary>
117+
/// Determines whether the current state matches the initial state with no undo or redo operations pending.
118+
/// </summary>
119+
/// <remarks>Use this method to check if all changes have been undone and the object is in its original
120+
/// state. This can be useful for enabling or disabling reset or save functionality in user interfaces.</remarks>
121+
/// <returns>true if the state is unchanged from its initial value and both the undo and redo stacks are empty; otherwise,
122+
/// false.</returns>
88123
public bool IsAtInitialState()
89124
{
90125
return undoStack.Count == 0 && redoStack.Count == 0 && originator.CreateMemento().Equals(initialMemento);

NeoBleeper/ControlExtensions.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ namespace NeoBleeper
2020
{
2121
public static class ControlExtensions
2222
{
23+
/// <summary>
24+
/// Enables or disables double buffering for the specified control to reduce flicker during repaint operations.
25+
/// </summary>
26+
/// <remarks>Double buffering can improve rendering performance and visual quality for controls
27+
/// that experience flickering during redraws. Not all controls support double buffering, and enabling it may
28+
/// have no effect on some controls.</remarks>
29+
/// <param name="control">The control for which to set double buffering. Cannot be null.</param>
30+
/// <param name="enabled">true to enable double buffering; otherwise, false.</param>
2331
public static void DoubleBuffering(this Control control, bool enabled)
2432
{
2533
var method = typeof(Control).GetMethod("SetStyle", BindingFlags.Instance | BindingFlags.NonPublic);

NeoBleeper/ConvertToBeepCommandForLinux.cs

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,19 +55,13 @@ private void ThemeManager_ThemeChanged(object? sender, EventArgs e)
5555
}
5656
}
5757

58-
protected override void WndProc(ref Message m)
59-
{
60-
const int WM_SETTINGCHANGE = 0x001A;
61-
base.WndProc(ref m);
62-
63-
if (m.Msg == WM_SETTINGCHANGE)
64-
{
65-
if (Settings1.Default.theme == 0 && (darkTheme != SystemThemeUtility.IsDarkTheme()))
66-
{
67-
SetTheme();
68-
}
69-
}
70-
}
58+
/// <summary>
59+
/// Applies the current application theme to the form based on user or system preferences.
60+
/// </summary>
61+
/// <remarks>This method selects and applies a light or dark theme according to the application's
62+
/// theme settings. If the theme is set to follow the system, the method detects the system's current theme and
63+
/// applies the corresponding style. The method also ensures that UI updates are performed efficiently and that
64+
/// the form is refreshed to reflect the new theme.</remarks>
7165
private void SetTheme()
7266
{
7367
this.SuspendLayout(); // Suspend layout to batch updates
@@ -131,8 +125,21 @@ private void buttonCopyBeepCommandToClipboard_Click(object sender, EventArgs e)
131125
Toast.ShowToast(this, Resources.MessageConvertedBeepCommandCopied, 2000);
132126
}
133127

128+
134129
StringBuilder beepCommandBuilder = new StringBuilder();
135130
int elapsedElementTime = 0; // Equivalent of Stopwatch.ElapsedMilliseconds for text based timing
131+
132+
/// <summary>
133+
/// Parses a music project string and generates a formatted beep command sequence representing the extracted
134+
/// notes.
135+
/// </summary>
136+
/// <remarks>The returned beep command sequence encodes the timing and pitch information for each
137+
/// note as specified in the input music project. The method applies default values for certain settings if they
138+
/// are missing from the input. The output can be used as input to a beep-compatible audio tool or command-line
139+
/// utility.</remarks>
140+
/// <param name="musicString">A string containing the serialized music project data to parse for note extraction. Cannot be null.</param>
141+
/// <returns>A string containing the formatted beep command sequence for the extracted notes. Returns an empty string if
142+
/// no notes are found or if the input is invalid.</returns>
136143
private String ExtractNotes(string musicString)
137144
{
138145
List<NoteInfo> notes = new List<NoteInfo>();
@@ -202,16 +209,36 @@ private String ExtractNotes(string musicString)
202209
if (silence > 0)
203210
{
204211
// Pass endOfLine so that last element doesn't get a trailing -n
205-
beepCommandBuilder.Append(createDelay(silence, endOfLine).duration);
212+
beepCommandBuilder.Append(CreateDelay(silence, endOfLine).duration);
206213
}
207214

208215
}
209216
string rawOutput = beepCommandBuilder.ToString();
210217
string trimmedOutput = rawOutput.TrimEnd();
211218
return trimmedOutput;
212219
}
220+
221+
/// <summary>
222+
/// Inserts one or more musical notes into the beep command sequence, specifying which notes to play, their
223+
/// order, and duration.
224+
/// </summary>
225+
/// <remarks>The order and alternation of notes depend on the current playback mode. Only notes
226+
/// marked to be played and with non-empty names are included. If no notes are selected, a delay of the
227+
/// specified length is inserted instead.</remarks>
228+
/// <param name="note1">The name of the first note to include in the sequence. Can be null or empty if not used.</param>
229+
/// <param name="note2">The name of the second note to include in the sequence. Can be null or empty if not used.</param>
230+
/// <param name="note3">The name of the third note to include in the sequence. Can be null or empty if not used.</param>
231+
/// <param name="note4">The name of the fourth note to include in the sequence. Can be null or empty if not used.</param>
232+
/// <param name="playNote1">true to play the note specified by note1; otherwise, false.</param>
233+
/// <param name="playNote2">true to play the note specified by note2; otherwise, false.</param>
234+
/// <param name="playNote3">true to play the note specified by note3; otherwise, false.</param>
235+
/// <param name="playNote4">true to play the note specified by note4; otherwise, false.</param>
236+
/// <param name="length">The total duration, in milliseconds, for which the notes should be played. Must be a positive integer.</param>
237+
/// <param name="endOfLine">true to indicate that this is the last note or group of notes in the line; otherwise, false. The default is
238+
/// false.</param>
239+
/// <returns>The total elapsed time, in milliseconds, for the inserted notes or delay.</returns>
213240
private int insert_note_to_beep_command(String note1, String note2, String note3, String note4,
214-
bool playNote1, bool playNote2, bool playNote3, bool playNote4, int length, bool endOfLine = false) // Play note in a line
241+
bool playNote1, bool playNote2, bool playNote3, bool playNote4, int length, bool endOfLine = false) // Play note in a line
215242
{
216243
int elapsedTime = 0;
217244
double note1Frequency = 0, note2Frequency = 0, note3Frequency = 0, note4Frequency = 0;
@@ -355,7 +382,7 @@ private int insert_note_to_beep_command(String note1, String note2, String note3
355382
}
356383
else
357384
{
358-
generatedBeepCommand = createDelay(remainingLength, endOfLine).duration;
385+
generatedBeepCommand = CreateDelay(remainingLength, endOfLine).duration;
359386
beepCommandBuilder.Append(generatedBeepCommand + Environment.NewLine);
360387
remainingLength = 0;
361388
break;
@@ -370,11 +397,26 @@ private int insert_note_to_beep_command(String note1, String note2, String note3
370397
}
371398
else
372399
{
373-
beepCommandBuilder.Append(createDelay(length, endOfLine).duration);
400+
beepCommandBuilder.Append(CreateDelay(length, endOfLine).duration);
374401
return length;
375402
}
376403
return elapsedTime;
377404
}
405+
406+
/// <summary>
407+
/// Creates a command-line argument string representing a beep with the specified frequency and duration, and
408+
/// calculates the total duration including any required delays.
409+
/// </summary>
410+
/// <remarks>If the specified frequency matches a known resonant frequency, it is incremented by 1
411+
/// Hz to prevent potential playback issues. When nonStopping is false, an extra delay is added to ensure the
412+
/// beep plays correctly.</remarks>
413+
/// <param name="frequency">The frequency of the beep, in hertz. If the value matches a known resonant frequency, it is automatically
414+
/// adjusted to avoid issues.</param>
415+
/// <param name="duration">The duration of the beep, in milliseconds. Must be a non-negative integer.</param>
416+
/// <param name="endOfLine">true if the beep is at the end of a line and should not be followed by a new beep; otherwise, false.</param>
417+
/// <param name="nonStopping">true to omit the additional delay and stop sequence after the beep; otherwise, false. The default is false.</param>
418+
/// <returns>A tuple containing the constructed command-line argument string for the beep and the total duration in
419+
/// milliseconds, including any additional delay if applicable.</returns>
378420
private (string frequencyAndLength, int totalDuration) CreateFrequencyAndDurationDuo(int frequency, int duration, bool endOfLine, bool nonStopping = false)
379421
{
380422
if (probableResonantFrequencies.Contains(frequency))
@@ -393,7 +435,14 @@ private int insert_note_to_beep_command(String note1, String note2, String note3
393435
}
394436
return (result, nonStopping ? duration : duration + 5);
395437
}
396-
private (string duration, int totalDuration) createDelay(int duration, bool endOfLine)
438+
439+
/// <summary>
440+
/// Creates a delay command string and returns the corresponding duration information.
441+
/// </summary>
442+
/// <param name="duration">The length of the delay, in milliseconds. Must be a non-negative integer.</param>
443+
/// <param name="endOfLine">true to indicate the delay is at the end of a line; otherwise, false to start a new beep after the delay.</param>
444+
/// <returns>A tuple containing the delay command string and the total duration in milliseconds.</returns>
445+
private (string duration, int totalDuration) CreateDelay(int duration, bool endOfLine)
397446
{
398447
string result = $" -f 0 -l 0 -D {duration}"; // Add delay
399448
if (!endOfLine)
@@ -402,6 +451,14 @@ private int insert_note_to_beep_command(String note1, String note2, String note3
402451
}
403452
return (result, duration);
404453
}
454+
455+
/// <summary>
456+
/// Deserializes an XML representation of a NeoBleeper project file from the specified string reader.
457+
/// </summary>
458+
/// <param name="stringReader">A StringReader containing the XML data to deserialize. Must not be null and must contain a valid XML
459+
/// representation of a NeoBleeper project file.</param>
460+
/// <returns>A NeoBleeperProjectFile object deserialized from the XML data, or null if the XML does not represent a valid
461+
/// NeoBleeper project file.</returns>
405462
private NBPMLFile.NeoBleeperProjectFile? DeserializeXMLFromString(StringReader stringReader)
406463
{
407464
System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(NBPMLFile.NeoBleeperProjectFile));

0 commit comments

Comments
 (0)