Skip to content

Commit

Permalink
Add error handling when copying empty string
Browse files Browse the repository at this point in the history
  • Loading branch information
ThioJoe committed Jan 21, 2025
1 parent 15db984 commit 70a3f54
Show file tree
Hide file tree
Showing 6 changed files with 267 additions and 226 deletions.
370 changes: 185 additions & 185 deletions MainForm.Designer.cs

Large diffs are not rendered by default.

21 changes: 12 additions & 9 deletions MainForm.EventHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,24 +191,24 @@ private void dataGridViewClipboard_KeyDown(object sender, KeyEventArgs e)
if (e.Control && e.KeyCode == Keys.C)
{
e.Handled = true; // Prevents the default copy operation
copyTableRows(copyAllRows: null); // Null means entire table will be copied if no rows are selected, otherwise just selected rows
copyTableRows(copyAllRows: null, noError:true); // Null means entire table will be copied if no rows are selected, otherwise just selected rows
}
}

private void copyRowDataToolStripMenuItem_Click(object sender, EventArgs e)
private void contextMenu_copyRowData_Click(object sender, EventArgs e)
{
copyTableRows(copyAllRows: false);
}

private void copyCellToolStripMenuItem_Click(object sender, EventArgs e)
private void contextMenu_copyCell_Click(object sender, EventArgs e)
{
// Get the contents of the selected cell
string cellContents = dataGridViewClipboard.CurrentCell.Value.ToString();
// Copy the cell contents to the clipboard
Clipboard.SetText(cellContents);
Utils.CopyIfValid(cellContents, useTooltip: true, relativeForm: this);
}

private void copySelectedRowsNoHeaderToolStripMenuItem_Click(object sender, EventArgs e)
private void contextMenu_copySelectedRowsNoHeader_Click(object sender, EventArgs e)
{
copyTableRows(copyAllRows: false, forceNoHeader: true);
}
Expand Down Expand Up @@ -500,7 +500,7 @@ private void menuEdit_CopyHexAsText_Click(object sender, EventArgs e)
string data = BitConverter.ToString(itemToCopy.RawData).Replace("-", " ");

// Copy the hex information to the clipboard
Clipboard.SetText(data);
Utils.CopyIfValid(data, useTooltip: false);
}

private void menuEdit_CopyObjectInfoAsText_Click(object sender, EventArgs e)
Expand All @@ -513,7 +513,8 @@ private void menuEdit_CopyObjectInfoAsText_Click(object sender, EventArgs e)
}
// Get the struct / object info that would be displayed in object view of rich text box and copy it to clipboard
string data = FormatStructurePrinter.GetDataStringForTextbox(formatName: Utils.GetClipboardFormatNameFromId(itemToCopy.FormatId), fullItem: itemToCopy, plaintext:true);
Clipboard.SetText(data);

Utils.CopyIfValid(data, useTooltip: false);
}

private void menuEdit_CopyEditedHexAsText_Click(object sender, EventArgs e)
Expand All @@ -527,7 +528,8 @@ private void menuEdit_CopyEditedHexAsText_Click(object sender, EventArgs e)

// Get the hex information that would be displayed in the hex view and copy it to clipboard
string data = BitConverter.ToString(itemToCopy.RawData).Replace("-", " ");
Clipboard.SetText(data);

Utils.CopyIfValid(data, useTooltip: false);
}

private void menuEdit_CopySelectedRows_Click(object sender, EventArgs e)
Expand Down Expand Up @@ -1381,7 +1383,8 @@ private void menuDebug_CopyRTFStructInfo_Click(object sender, EventArgs e)
string data = FormatStructurePrinter.GetDataStringForTextbox(formatName: Utils.GetClipboardFormatNameFromId(itemToCopy.FormatId), fullItem: itemToCopy, plaintext: false);
// Add in newlines for readability wherever there's a \line
data = Regex.Replace(data, @"\\line ?", @"\line" + "\n"); // For both with space and not
Clipboard.SetText(data);

Utils.CopyIfValid(data, useTooltip: false);
}


Expand Down
4 changes: 2 additions & 2 deletions MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2331,7 +2331,7 @@ private void MarkIndividualClipboardItemForRemoval(Guid uniqueID)
}

// Copies the selected rows to the clipboard, or the entire table if chosen. Null automatically determines entire table if no rows are selected, otherwise just selected
private void copyTableRows(bool? copyAllRows = false, bool forceNoHeader = false, int onlyColumnIndex=-1)
private void copyTableRows(bool? copyAllRows = false, bool forceNoHeader = false, int onlyColumnIndex=-1, bool noError=true)
{
// Get the selected rows and put them in a list, each row a list of strings for the cell values
List<List<string>> selectedRowsContents = new List<List<string>>();
Expand Down Expand Up @@ -2500,7 +2500,7 @@ private void copyTableRows(bool? copyAllRows = false, bool forceNoHeader = false
}

// Copy the list to the clipboard
Clipboard.SetText(finalCombinedString);
Utils.CopyIfValid(finalCombinedString, useTooltip: true, noError: noError, relativeForm: this);
}

private void setCopyModeChecks(MenuItem newlyCheckedOption)
Expand Down
45 changes: 21 additions & 24 deletions MainForm.resx
Original file line number Diff line number Diff line change
Expand Up @@ -129,19 +129,18 @@
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>322, 23</value>
</metadata>
<data name="checkBoxPlainTextEditing.ToolTip" xml:space="preserve">
<value>Be sure to select the correct encoding to edit with.

If you see lots of periods in the text, those are likely null
characters that were converted, and you probably
therefore want to use UTF-16.
<data name="labelSynthesizedTypeWarn.ToolTip" xml:space="preserve">
<value>The selected format type is "synthesized", meaning it will be automatically
re-created by Windows if deleted (edits should still work).

The plaintext will be converted directly back to bytes, so when
editing in plaintext, null characters are represented by \0
so that you can use that to signify a null character.
Synthesized formats are automatically created by Windows if there are certain
corresponding formats in the clipboard. For example, if the "CF_TEXT" format
exists, Windows will automatically convert it and also add the formats
"CF_UNICODETEXT" and "CF_OEMTEXT" if they don't exist already.

Still, the conversion from plaintext to hex might not be perfect,
so if accuracy is important, just edit the hex values directly!</value>
Tips:
- Windows won't overwrite a synthesized format if it already exists, like you edit it
- You can get rid of the synthesized formats by also deleting the other associated formats</value>
</data>
<data name="labelCustomFormatNameID.ToolTip" xml:space="preserve">
<value>Windows automatically assigns format ID numbers. Names can be assigned
Expand All @@ -153,21 +152,19 @@ a random format ID.

A format ID of zero is just a placeholder.</value>
</data>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>322, 23</value>
</metadata>
<data name="labelSynthesizedTypeWarn.ToolTip" xml:space="preserve">
<value>The selected format type is "synthesized", meaning it will be automatically
re-created by Windows if deleted (edits should still work).
<data name="checkBoxPlainTextEditing.ToolTip" xml:space="preserve">
<value>Be sure to select the correct encoding to edit with.

Synthesized formats are automatically created by Windows if there are certain
corresponding formats in the clipboard. For example, if the "CF_TEXT" format
exists, Windows will automatically convert it and also add the formats
"CF_UNICODETEXT" and "CF_OEMTEXT" if they don't exist already.
If you see lots of periods in the text, those are likely null
characters that were converted, and you probably
therefore want to use UTF-16.

Tips:
- Windows won't overwrite a synthesized format if it already exists, like you edit it
- You can get rid of the synthesized formats by also deleting the other associated formats</value>
The plaintext will be converted directly back to bytes, so when
editing in plaintext, null characters are represented by \0
so that you can use that to signify a null character.

Still, the conversion from plaintext to hex might not be perfect,
so if accuracy is important, just edit the hex values directly!</value>
</data>
<data name="labelPendingChanges.ToolTip" xml:space="preserve">
<value>Changes you have "Applied" are not saved to the actual
Expand Down
23 changes: 17 additions & 6 deletions RichTextBoxContextMenuManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ private void MenuItemCopyAllPlaintext_Click(object sender, EventArgs e)
&& contextMenu.SourceControl is RichTextBox richTextBox )
{
// Since we're copying everything, we can use the Text property instead of SelectedText, which gives us the contents in plaintext
Clipboard.SetText(richTextBox.Text);
CopyIfValid(richTextBox.Text);
}
}

Expand All @@ -113,7 +113,7 @@ private void MenuItemCopy_Click(object sender, EventArgs e)
&& contextMenu.SourceControl is RichTextBox richTextBox )
{
// Use SelectedText property to get the plaintext, instead of doing .Copy() method which would copy with formatting
Clipboard.SetText(richTextBox.SelectedText);
CopyIfValid(richTextBox.SelectedText);
}
}

Expand Down Expand Up @@ -145,10 +145,7 @@ private void MenuItemOpenLink_Click(object sender, EventArgs e)

private void MenuItemCopyLink_Click(object sender, EventArgs e)
{
if ( !String.IsNullOrEmpty(lastSelectedHyperlink) ) // Should not be null or empty here but just in case
{
Clipboard.SetText(lastSelectedHyperlink);
}
CopyIfValid(lastSelectedHyperlink);
}

private void RichTextBox_MouseDown(object sender, MouseEventArgs e)
Expand Down Expand Up @@ -261,5 +258,19 @@ private string GetLinkAtPosition(RichTextBox richTextBox, int charIndex)
}
}
}

private static void CopyIfValid(string text)
{
if ( !string.IsNullOrEmpty(text) )
Clipboard.SetText(text);
else
{
// Show a tooltip if the user tries to copy an empty string
ToolTip tt = new ToolTip();
Point cursorPosition = Form.ActiveForm.PointToClient(Cursor.Position);
cursorPosition.Y += 20; // Offset the Y coordinate by 20 pixels downward
tt.Show("Nothing to copy", Form.ActiveForm, cursorPosition, 1500);
}
}
}
}
30 changes: 30 additions & 0 deletions Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,36 @@ public static void ShowToolTip(object sender, System.Windows.Forms.ToolTip toolT
}
}

public static void CopyIfValid(string text, bool useTooltip = true, bool noError=false, Form? relativeForm = null)
{

if ( !string.IsNullOrEmpty(text) )
{
Clipboard.SetText(text);
}
else if ( noError )
{
return;
}
else if ( useTooltip )
{
if ( relativeForm == null )
relativeForm = Form.ActiveForm;

// Show a tooltip if the user tries to copy an empty string
ToolTip tt = new ToolTip();
Point cursorPosition = Form.ActiveForm.PointToClient(Cursor.Position);
cursorPosition.Y += 25; // Offset the Y coordinate by 20 pixels downward
tt.Show("Nothing to copy", Form.ActiveForm, cursorPosition, 1500);
}
else
{
string boxTitle = "Copied Contents Empty";
string boxMessage = "Can't copy empty data.";

MessageBox.Show(boxMessage, boxTitle, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}

} // ----------------- End of class -----------------
} // ----------------- End of namespace -----------------

0 comments on commit 70a3f54

Please sign in to comment.