.NET Winforms textbox - how to account for non-standard linebreaks? - winforms

I have an app that has a multiline text box on it. This is data that comes from a client application elsewhere. There are different versions of the client app for different platforms, and furthermore these platforms have different default rules about line endings.
Thus, the data I want to show in the textbox might have CR+LF line endings, or might just have CR line endings.
How can I make the textbox show these carriage returns in either format? I don't see any property to do so and would prefer to not rewrite the data to change CR only to CR+LF (I want the data, if saved, to be written back out in the form it came in.)

I think you would have to change the data, unless you're going to override the TextBox, and I think that changing the data would be the normal way to go about it. Text data sent between systems usually get converted, for example if you transfer via FTP in text mode it'll normally do it for you (at least any clients I've tried).
Also, if you don't convert the data and the user selects the text and pastes it in to another application that doesn't understand other line endings it might not look like he expects it and he might blame your application. And since you could do it with two simple Replace statements to replace back and forth if you do want to save in that format I'd suggest that that's the way to go.

Related

What is a good way to store text that contains checkboxes in a database?

I'm currently working on a notes app because I really dislike any notes app that I could find on the app store because the lists you can create are either:
only text
only checkboxes
lines of text followed by checkboxes or vice versa
But by now I found no app (except for Samsung's proprietary Samsung Notes app which only works on Samsung smartphones as it seems) that allows alternating use of lines text and checkboxes.
When thinking about how to implement this properly I had some issues coming up with a proper way of identifying when there is a checkbox and when there should be a line of text. For obvious reasons, just storing text and specifying an identifier like <chkbox> (or something along those lines) is not a good solution because checkboxes should only be placeable by clicking the respective icon. The user should neither be restricted to use the term <chkbox> (because for whatever reason he might want to use it) nor should injections like this be possible.
The best thing that came to my mind up until now was to store each line individually (identified by \n) in a list with dynamic datatype and for each line either store it as text object or string or as checkbox item. Finally, I could simply store the list as one single object in the database. However, I'm unsure whether that's good practice as I could imagine that it makes changes to the list quite cumbersome (e.g. for changing the ticked-value of one single checkbox we would need to store the entire datastructure again instead of just changing one boolean in the database)?
I'm working in Flutter and use Firebase Firestore as my backend/database. Although I'm mostly looking for a general approach/solution to this, with the chosen technologies in mind, is there any solution that would work better than what my recent thoughts are, or is there any serious flaws or drawbacks that I overlooked? Thanks in advance for any constructive input.

How to Cancel/Reset page between StartPage/EndPage when printing?

I'm processing a specially formatted text file to send to the printer. I have encountered a condition that would be easiest to handle by discarding the current (incomplete) page and starting a new one instead. So, I have called StartPage() and output one or more lines of output and then I realize that I need to discard what I have output on this page only before I have called EndPage(). To me, this seems like it should be a simple and obvious function, but I have been unable to find any way to do this. Is it possible or am I just dreaming?
EDIT: In case this wasn't clear, I want to remove a single, partially completed page from my output and then continue to output additional pages. I DO NOT want to remove the entire job (or print queue.)
It appears that what I want does not exist.
I have assumed that between StartPage() and EndPage(), my printer output for the page is being buffered to build an image of the page to send to the printer. Apparently I can neither (a) change my mind and discard the incomplete (or completed) page nor (b) change (or remove) what I have already written to the page. I tried (b) and I got two lines of text superimposed upon one another.

How to detect when text is replaced in GtkTextBuffer instead of delete followed by insert?

I have worked a great deal with the text system in Objective-C for macOS/iOS (e.g. NSTextView, NSTextStorage, etc.) I am now experimenting with GTK3 to see how well I can translate my project for use on Linux, etc.
I am brand new to using GTK, but after a few days of Google time and experimenting, I have a working text editor prototype with my custom code plugged in.
The problem is this -- I need to be able to detect when a user highlights a section of text, and then replaces it with other text (e.g. a keystroke). This is distinct from highlighting a section of text, hitting the delete key, and then typing the new text. A specific use example would be highlighting a word, then typing a double quote character in order to wrap the word in quotes (e.g. foo becomes "foo").
In Cocoa, one would receive replaceCharactersInRange: that indicates the range originally selected, as well as the new string to replace it with. I can then detect the presumed intent of the user based on the information received.
In GTK, it seems that we receive a delete-range signal, followed by a separate insert-text signal. Because of this separation, the code in the "insert" section has no way of knowing that the user intended to replace text, not insert new text.
I used the following to receive the signals above:
g_signal_connect(buffer, "insert-text", G_CALLBACK(insert_text_cb), NULL);
g_signal_connect(buffer, "delete-range", G_CALLBACK(delete_range_cb), NULL);
Is there something else I can do in order to tell that there is a delete, followed by an insert as part of the same user action?
Thanks for any pointers offered!
Instead of trying to correlate the delete and insert events, I would suggest creating a GAction for your desired action (e.g. toggle quotes around the selected text) and setting its shortcut key to " using gtk_application_set_accels_for_action().
For more information, check out this HowDoI wiki page.
No answers over the last month, so I kept brainstorming and digging around. I finally came up with this, which works, but is not quite as elegant as I had hoped.
Handle delete-range signal as before, but keep track of the the deleted text for later (e.g. in char * deletedText).
Handle the insert-text signal as before, but if we have a string in deletedText then change the behavior to perform a replacement instead of an insertion. In my case, this actually meant inserting the deleted text back in, and then performing the replacement.
Add a callback for the end-user-action signal, which indicates that all delete/inserts associated with a particular action are complete. In this callback, free deletedText from above and set to NULL (to indicate that everything has been handled).
Again -- this works, but feels a bit inelegant. And depending on how complex your delete/insert routines are, it may slow the performance slightly since some steps have to be duplicated. A better solution would be to detect during the delete-range callback that there is a pending insert-text callback and handle both steps at once. I have thus far not been able to do that.

How can I monitor a text file for *any* change whatsoever?

I'm trying to record how a file changes over time down to the smallest details, which means that reading any changes per file save wouldn't give sufficient data for my use-case, it needs to be per-keystroke.
I just tried out inotify, but it can only notify me on file-save, not file-modification.
I then realized (I'm quite inexperienced with file-system stuff) that this is because text-editors use buffers to store yet-to-happen changes, committing the contents of the buffer on file save (I think, at least).
So, it seems to me that I could
read the buffer of a text-editor (which seems like it would have to be code specific to each particular editor; not viable)
force a save to the file on every keypress (which again seems like it would require editor-specific code)
monitor the keypresses of the user, store my own buffer of them, and then once the file is saved, correlate the keypresses with the diff (this seems way too hard and prone to error)
read the contents of the file on an interval faster than a person is likely the press any keys (this is hacky, and ridiculous)
I can't think of any other ways. It seems that to properly get the behavior I want I'd need to have editing occur within the terminal, or within a web form. I'd love to hear other ideas though, or a potential editor-agnostic solution to this problem. Thank you for your time.

winforms textbox Ctrl-Backspace to Delete Whole Word & Spaces

I found an article here:
Winforms Textbox - Using Ctrl-Backspace to Delete Whole Word
to delete the whole word in a textbox while holding ctrl+backspace, but I noticed that if you don't implement the app.config modifications like so:
<configuration>
<appSettings>
<add key="SendKeys" value="SendInput" />
</appSettings>
</configuration>
that only the current word will be removed and the process of backspacing will be interrupted. For instance, if I typed in "Tim tom" and then used the ctrl + backspace trick, "tom" would be deleted, interrupting any backspace operation and leaving "Tom ".
If you do use the app.config modification, however, "tom" would successfully be removed and backspace operations would continue, but without continuing to remove whole words, as if you were just holding the backspace button.
Does anyone know what causes this or how to fix it?
Your application is choosing a different behavior of sending keypress equivalents to the application.
The historical exposition why the two protocols exist is explained here:
The SendKeys class has been updated for the .NET Framework 3.0 to
enable its use in applications that run on Windows Vista. The enhanced
security of Windows Vista (known as User Account Control or UAC)
prevents the previous implementation from working as expected. The
SendKeys class is susceptible to timing issues, which some developers
have had to work around. The updated implementation is still
susceptible to timing issues, but is slightly faster and may require
changes to the workarounds. The SendKeys class tries to use the
previous implementation first, and if that fails, uses the new
implementation. As a result, the SendKeys class may behave differently
on different operating systems. Additionally, when the SendKeys class
uses the new implementation, the SendWait method will not wait for
messages to be processed when they are sent to another process.
The timing issues mentioned here concern especially continued control of application by characters, not just one character at a time. They include
difficulty in synchronizing typing rate
making sure that the right window receives the input when the app is opening dialogs
making sure that the right app receives the input even when the user meddles with close buttons
However, the real reason between the SendKeys behavior change was not programmer friendliness (which did not improve significantly), but security.
It is definitely a good idea to set the SendKeys parameter to specify the desired behavior. You don't want your application to mysteriously start behaving differently just because UAC was turned on or off.

Resources