Squigglly line under a word (Win32) - c++

I want to implement basic spell checking in a Notepad clone project I'm doing. I want to underline misspelled words with a squiggly like like Word does. I think I need to use GDI and draw on the text field, but I'm not sure how to draw on controls.
Thanks

If you're basing your editor on an edit control (as Notepad does), then I think it's going to be difficult. By subclassing the edit control window, you could probably augment its WM_PAINT handling. But the problem is the control doesn't expose a way for you to find out exactly where a word appears within the control. Thus you won't know where to draw the squiggle.
You might be able to use a Rich Edit control (as WordPad does) and tweak the styling of the misspelled words. I've never used Rich Edit, so I can't help with the details.

Actually, I'm not sure about the method which you're using to render text in your window and I think you need to concretize it.
If everything is done using winapi/gdi (generally speaking, this would be TextOuting the current text block, that fits the window considering wrapping, etc...), you should add another routine, that would handle misspelled words rendering.
Again, this also depends on your way to save current text and it's parameters, but the idea is to implement some sort of function like RenderMisspelledWord(...), which would take your generic text-handling class or some kind of renderer class or even (X, Y, Length) as params. This function would be called from a more general Render method, which would be called from WM_PAINT handler.
What it would do also depends on your notepad architecture, but, for example, in last case that would require drawing * /\ /\ /\ * parts of your underlining using GDI (line) routines.
Generally speaking, every other case (with handling classes) would lead to the following action too, but with higher level of abstraction.

Related

Multiple visual text cursors in QPlainTextEdit

In Sublime Text, if you hold control while clicking, you can add another cursor to the document, allowing you to type and edit in multiple places at once. I'm trying to recreate this with Qt's QPlainTextEdit. The logic seems pretty simple...
On Ctrl+click, create and store a new cursor at location of the click
Draw all cursors
When any key events happen, make sure the other cursors also receive them
However, it seems that in order to do these things, I have to understand exactly how QPlainTextEdit works, and while I have a loose understanding, I find the source to be very dense and difficult to navigate.
While this feature is very important to me, I can't afford to spend a month on it. I don't know how to reasonably proceed. Is there some open source text editor built with Qt that has this feature? Can I in fact implement it without thoroughly understanding how QPlainTextEdit works? Is there some other solution I have not considered? I thought this would be trivial, or at the very least someone might have solved it before, but that doesn't appear to be the case. Any advice is appreciated.
Is there some open source text editor built with Qt that has this feature?
QtCreator is open-source (source code) and has partial multiple-cursor functionality. While it does not support Ctrl+Click to add a new cursor, you can do Shift+Alt+DownArrow to add a cursor to the following line (same column), like in SublimeText, and then insert text to all the lines at once.
It seems implemented in their class TextEditorWidget, which inherits QPlainTextEdit and reimplements plenty of its virtual methods. I don't exactly know how they implemented the multi-cursor functionality, but probably looking at the code of TextEditorWidget can give hints.
However, keep in mind that QtCreator does not have full multi-cursor functionality like in Sublime Text or CLion: the mutliple cursors are necessarily in the same column, and you cannot move the multiple cursors left/right. For example something I often do in Sublime is multiple selection at the beginning of lines, followed by Ctrl+RightArrow to jump all cursors "one word to the right". You cannot do that in QtCreator as of August 2020.
There is an open feature request for having true multiple-cursor functionality in QtCreator:
https://bugreports.qt.io/browse/QTCREATORBUG-16013
However, it seems that in order to do these things, I have to
understand exactly how QPlainTextEdit works, and while I have a loose
understanding, I find the source to be very dense and difficult to
navigate.
To some extent, but not a lot. Once you get the cursor positions, you know the positions in the document where text needs to be inserted. QTextEdit already supports multiple cursor positions:
https://doc.qt.io/qt-5/richtext-cursor.html
Rich text documents can have multiple cursors associated with them,
and each of these contains information about their position in the
document and any selections that they may hold. This cursor-based
paradigm makes common operations, such as cutting and pasting text,
simple to implement programmatically, yet it also allows more complex
editing operations to be performed on the document.
and
Multiple Cursors
Multiple cursors can be used to simultaneously edit the same document,
although only one will be visible to the user in a QTextEdit widget.
The QTextDocument ensures that each cursor writes text correctly and
does not interfere with any of the others.
Since this feature already exists, it may not be as difficult as thought to read the documentation and implement the feature.
As QPlainTextEdit is implemented by using most of the tech behind QTextEdit and QTextDocument, maybe it will meet your requirements.

How to draw connections between items in a QTreeView

I wonder how to draw the lines connecting the items in a QTreeView as illustrated in the picture under Tree Model. My program will run on different platforms and thus use different styles. Can I guarantee that the items are drawn as desired?
I feel, using style sheets might be problematic because certain styles do not print such lines and using a delagate might lead me into issues of double drawing.
There's an example in the documentation here showing exactly what you want to achieve using style sheets.
Please note that when you use style sheets QStyleSheetStyle kicks in, irregardless from the QStyle your application is using at the moment. So if you decide to go this way you will override the look and feel of your control the same way, irregardless from the target platform.
If that is a problem, you may consider to use style sheets only for certain platforms. As an example:
#ifdef Q_OS_MAC
myControl->setStyleSheet(":/my_stylesheet_for_mac.qss");
#endif
Back to the example in the documentation, it uses a few images containing all the various lines (vertical, horizontal, branch, etc) and the ::branch subcontrol and its states to determine which image to use.
The result is something like this:
.
Obviously, you must change the code to show the vline picture instead of the arrows.
As a side node, I may suggest to consider why you want to do this if you are using native styles. If your application has a native look and feel, you should not alter it in any way. That is, if the target platform doesn't render lines to connect tree view items, then you shouldn't add those.
However, if your application is not required to look native across all the target platforms, you may consider using the same style (e.g. Fusion) and deliver the same user experience no matter what the platform is.

Making a fancy looking window with messages stack

I try to make fancy looking messages viewer, where messages divided by formatting, other background of smth. similar. They need to looks like this - http://pastebin.com/GU1Lq087. What I found in wxWidgets to solve this problem, and why I can't use it:
wxHtmlWindow
Supports minimal HTML (a few tags). But big problem with this - html representation doesnt fill parent window. So element with width=100% will have 100% width only on standard window size. And even p tag doesnt have word wrapping (long long paragraph goes in one line with vertical scroolbar).
wxWebWiew
I need to have the ability to set generated HTML to it, but IE must to load some page first and I can rely only on IE background. It has some time to load page, even if I set HTML-string.
wxRichText
Most suitable for me. But I can't draw line like HTML's hr, or change background for the entire message block (to distinguish it from common background)
I need to show messages like this. But i didn't know how and which tool is better.
One way of achieving this would be using wxWebView with WebKit backend but I am afraid that Windows can only use IE's engine. However, there is project which allows you to use Gecko engine. I use WebKit for rendering chat in my application and it works really good (although I am using Qt). (http://www.kirix.com/labs/wxwebconnect.html)
You can always do it regular way - just create separate widget (I think it is called "frame" in wxWidgets) for single message. This way you get almost infinite possibilities. E.g. you can make "AbstractMessage" with virtual methods and then things like "AdministratorMessage", "MOTD" etc. will be a breeze.
wxRichText Most suitable for me. But I can't draw line like HTML's hr
Really? Have you looked at the docs?
( http://docs.wxwidgets.org/trunk/overview_richtextctrl.html )
Here's a couple simple ideas:
a. Write a line of blanks, underlined.
http://docs.wxwidgets.org/trunk/classwx_rich_text_ctrl.html#a333b2e675617ed2299cf91e7c0dbd0d8
b. Create an image of a horizontal line, display it using WriteImage
http://docs.wxwidgets.org/trunk/classwx_rich_text_ctrl.html#a1315611c0741d03e852ee26eba3a9d94
The funny thing is that what you want can be done using any of the 3 controls you mention. With wxHtmlWindow you just need to set its size correctly, with wxWebView I don't understand what your problem with it is at all and with wxRichTextCtrl you could just use separate controls for the areas with different backgrounds (you could almost certainly use a single control with different styles but using several controls seems simpler).

How to draw to a certain part of the console/terminal?

I'm curious to know how you can draw/update a certain region of the terminal/console. Is there any cross-platform libraries to do so?
The reason I want to know is because I am developing an instant message command line application, and I was curious to know how I can update the message viewer (where all the messages go) separately to where you write commands/text for other people in the chat. Obviously if I just tried to get input and write to cout then the input the user is entering and the messages would be "interfered" (by interfered I mean split in multiple lines).
I was thinking of using two stream objects: one to store the view (messages/output from the server) and one to store the input from the user, and just redraw whenever required. However, this seems inefficient and it requires me to clear the screen (in which case I don't know how to clear the screen efficiently and in a cross-platform manner).
I was also thinking of just switching to Qt/wxWidgets as it might simpler to make a GUI.
Use ncurses library to write text-based user interfaces in a terminal-independent manner.
As suggested by #Naruto, ncurses is a good way to go. At a much more basic level, you can also just use ANSI escape codes to move the cursor around the screen too:
For example, to position the cursor at line 5, column 23, you can enter this
echo -n "\033[5;23H"
There are more examples here.

The C++ Programming Language 12.7 question 2

I am doing an exercise from The C++ Programming language (page 325, exercise 12.7, question 2).
It says:
Implement a simple graphics system using whatever graphics facilities
are available on your system (if you dont have a good graphics system
or have no experience with one, you might consider a simple "Huge bit
ASCII implementation" where a point is a character position and you
write by placing a suitable container, such as * in a position)
Now, what I gather from that, is that if I dont want to use GDI+ or Direct X then I can do this in a console app using chars like _,*, or -.
Am I thinking about this the right way?
If I am, am I right in thinking that I need to be able to draw a character anywhere on the console?
If so, how do I draw a char anywhere on the console?
Or I could be wrong and you can tell he what I might want to try (not GDI+ / DirectX if possible)
In order to draw a character anywhere to the console you really need to use an operating system specific library for console access, or a cross-platform console library.
If you were doing this for Windows you would use the Windows Console API (MSDN), a function that could draw a character to a specific location is FillConsoleOutputCharacter (MSDN).
It used to be that ANSI escape sequences could be used, but having read your question and investigated here, it seems these no longer exist.
The best option appears to be to use the windows console APIs, documented here.
There looks to be a pretty good example of how you might proceed here.
Good luck with this, it sounds interesting!
Fond memories of doing this in computer class, back when we had chaarcter sets with ▄ ▀ █. Double-resolution graphics ;). If you wanted one in column 8, you'd print 7 spaces in front of it. And if you wanted it at line 3, you'd print two \n in front. But yes, you'd have to consider up front what you were going to draw. To redraw one character, you'd have to redraw everything.