Rich Text Tale Vol1 : Background colors
Take care it's a confusing film ;) !
I'm sing a QTextEdit to render my text and I would like to color lines for different purposes ( current line, error line, breakpoint...) I have already managed to color lines but there's a twist : the line get colored but that coloration stop after the last character of the QTextBlock while i would like that coloration to reach the rightmost border of the QTextEdit!!!
Hints???
Re: Rich Text Tale Vol1 : Background colors
Hi, first of all let me say that I already download the project that you posted on a previous post :)
I'm trying to do the same thing but with another aproach.
I extends the QTextEdit class and reimplement paintEvent(...) method.
At this point my class behave exactly like QTextEdit with one diference...
I highlight current line and current block of code (text between '{' and '}') from first column to right edge of the widget :D
Ok, you probably thinking: "That's it!"
but I have to tell you: "Houston, we have a problem!"
When I put a large amount of text on my widget (let's say that I open your deveditor.cpp file that has about 1KLOC), it became so slow that I don't think that programers wants to code on this speed.
So... I'm at work now, but when I get home I post the code to you have a look at it, til there, go thinking on a possible solution!
see U
1 Attachment(s)
Re: Rich Text Tale Vol1 : Background colors
Ok, I scape a little just to atach the source code, give a try and feedback me!!!
ps.: I include a header that is not on the zip nor is used, so delete the line that includes "highlighter.h" before you compile it!
Re: Rich Text Tale Vol1 : Background colors
Re: Rich Text Tale Vol1 : Background colors
I pasted something below that should work pretty fast and if you turn off line wrapping.
Also, I took a quick look at that CodeEditor.zip file -- it looks as if a lot of code was copy-and-paste inherited from
in qtextedit.cpp. I didn't really read anywhere past that.
I don't think you need to go that far. To learn scribe better, I'd been playing around with my own custom editor too and QTextEdit::cursorRect and QTextEdit::cursorForPosition are pretty convenient for custom painting. That way if you have a large document, you can ask it for the cursor at point 0,0 and at the viewport's width,height so your paint event only deals with text that's actually visible (for Right-to-left/BiDi text you'll need to account for the difference). That makes more sense if you think of cursorForPosition returning the closest cursor as if you clicked there. That's why it works even if you don't have any text visible at (viewport()->width(), viewport()->height()). Then you can always get the QTextBlock from the cursor. I did that to make tab-stops visible as dots and it works fine for files thousands of lines long.
Anyway, you'll want to adjust the margins at the side, but this seems to work for non-wrapped text:
editor.h
Code:
#ifndef EDITOR_H
#define EDITOR_H
#include <QTextEdit>
{
Q_OBJECT
public:
explicit Editor
(QWidget *parent
= 0);
protected:
private slots:
void highlightCurrentLine();
};
#endif // EDITOR_H
editor.cpp
Code:
#include <QtGui>
#include "editor.h"
{
connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine()));
}
void
Editor::highlightCurrentLine()
{
viewport()->update();
}
void
{
QRect rect
= cursorRect
();
rect.setX(0);
rect.setWidth(viewport()->width());
painter.fillRect(rect, brush);
painter.end();
}
main.cpp
Code:
#include "editor.h"
#include <QtGui>
int
main(int argc, char *argv[])
{
Editor editor;
editor.show();
return app.exec();
}
It might not matter that it doesn't even try to be optimal. You could probably also tell it to update() the effected area(s).
This also won't work right if the text wraps or you want some other sort of multi-line rectangle, but that should be easy enough to change. QTextLayout or QTextEdit::rectForCursor in conjunction with QTextCursor::movePosition should probably come in useful for that.
EDIT: looking a bit more at the CodeEditor.zip file, I'd also not search for matching braces on every paint event.
EDIT: didn't change any of the code, but fixed QTextEdit to QTextCursor::movePosition and made a few small clarifications, like dealing with bidi text.
EDIT: fixed the update code.
Re: Rich Text Tale Vol1 : Background colors
Man, I'm feelling stupid :p, your way is far way better than mine!!!!
But let's talk about it...
Why I copy paint event from QTextEdit? Becouse my editor shoud has two features that QTextEdit doesn't has:
1. Multiline edit;
2. Persistent selection;
the first one you already say that is hard to work in your solution but the second I'm without any idea!
In persistent selection, user could select a text and continue to edit the document without loose the selection. Why this? Imagine that you split your view and on the top you have some part of the code that is close likely the one you are editing on botton. So, obviously you copy and paste some part of the code, if your selection is persistent, you could select on top view and continue edition on botton without loose your selection. It's something like vim do with split view :D .
Ok, now I'm trying to adapt your solution on this two features but I'm not sure that it will not have to many overide method like mine.
On multiline edition and persistent selection I have to alter the paint context of the document to reflect the alctual selection properly. If I do with my way (as I just copy a lot of code of QTextEdit) I just have to add some condition on "if (hasSelection())" control. But with your solution, I had to add an entire "if" control that will be anbiguous with the QTextEdit:: paintEvent(e) and I have to control what to copy and paste when user hit Ctrl+C/Ctrl+V or when he drag N' drop anything, so... I still have to overide all "drag" and "drop" and "mouse..event" methods from QTextEdit making the diference between your solution and mine only the paintEvent method. As I sayd before, if you do in your way you will do ambiguos check on paintEvent, but copying paintEvent from QTextEdit it's possible to minimize this efect.
At this moment I don't think that even mine or your solution is the ideal one, I'm still looking for it. Probably I'll find something usefull and good enought in the middle of our solutions, till there if anyone has a glue, please report here!
ps.: I'm creating a source forge project to a multi-plataform Qt IDE! Coming soon!!!! :D
Re: Rich Text Tale Vol1 : Background colors
Quote:
ps.: I'm creating a source forge project to a multi-plataform Qt IDE! Coming soon!!!! :D
I guess we're all working on such a project! :p
I feel stupid : what do you call multiline edit?
Your way worked fine but I'll try blockd's one!
comments soon!
Re: Rich Text Tale Vol1 : Background colors
Quote:
guess we're all working on such a project!
Why we do not join efforts to create the best Qt IDE ever made :D ? Have you already start a sourceforge project? If not, I could do this.
About multiline edit: multiline edit is something like column selection on MS Word, let me try to illustrate:
| = will be our cursor
Code:
My text01, |my text02, my text03, my text04
My text05, my text06, my text07, my text08
My text09, my text10, my text11, my text12
My text13, my text14, my text15, my text16
In the above text our cursor is on the first line just before "my text02". This is normal edition, now in multiline edition we could have:
Code:
My text01, |my text02, my text03, my text04
My text05, |my text06, my text07, my text08
My text09, |my text10, my text11, my text12
My text13, |my text14, my text15, my text16
Our multiline cursor is on all lines at the same time. If you type an 'a' character on first exemple, the resul shoud be like this:
Code:
My text01, a|my text02, my text03, my text04
My text05, my text06, my text07, my text08
My text09, my text10, my text11, my text12
My text13, my text14, my text15, my text16
and on the multiline exemple the same action should produce:
Code:
My text01, a|my text02, my text03, my text04
My text05, a|my text06, my text07, my text08
My text09, a|my text10, my text11, my text12
My text13, a|my text14, my text15, my text16
Re: Rich Text Tale Vol1 : Background colors
I forget to mention that I'm already working on blockd's example. At this point I alrerady create persistent selection and I'm going to try multiline edition soon.
When I finish the work I post it here ;)
Re: Rich Text Tale Vol1 : Background colors
blockd,
I have seen your code, and I don't get it. You draw the background of a line, and then you call the original code of QTextEdit.
What if that code rewrites the background..?
Not only that, but pressing enter is the only way your code works. (moving up, or down just garbages out the screen). Am I missing something...?
Re: Rich Text Tale Vol1 : Background colors
[quote]Am I missing something...?[\quote]
Shure you are :D, I rewrite the entire code based on your solution (that is no doubt more elegant than mine) and fix some missing features on your snippet too, like if you scroll the screen with mouse wheel for exemple, you get an undesired behavior.
At now I working on make persistant selection works properly, perhaps tomorrow at the end of the day I post the partial result and probably on weekend I post the entire solution with multiline edition.
By the way are you interted in build some kind of multi platafom Qt IDE?
;)
Re: Rich Text Tale Vol1 : Background colors
Quote:
Originally Posted by elcuco
What if that code rewrites the background..?
It depends. If you're talking about the viewport background (white depending on your palette) to enter text on, then it should be OK -- at least in Qt 4.1. If it's Qt 4.0 then all bets are off (read: time to upgrade), since they seem to have changed a lot of how they paint things.
autoFillBackground() on the viewport is true, and from the docs:
Quote:
Originally Posted by http://doc.trolltech.com/4.1/qwidget.html#autoFillBackground-prop
If enabled, this will cause Qt to fill the background using the widget's background role before invoking the paint event. [...] This property was introduced in Qt 4.1.
So the background is already filled in before that rectangle is painted. You can also verify that if you use do this in the ctor: viewport()->setBackgroundRole(QPalette::Window), to get a different colour. If they decide to change this behaviour in the future then the code will have to adapt. But I'll admit, I don't think the API to do your own drawing on the document is as flexible and convenient as it could be.
The text-selection highlighting will overwrite that "current line rectangle" like I think it ought to.
If you're talking about the background that you set through a QText(Block)Format, then it really depends some more. Can you do <whatever> in that paintEvent with the QPainter instead?
Quote:
Originally Posted by elcuco
Not only that, but pressing enter is the only way your code works. (moving up, or down just garbages out the screen). Am I missing something...?
What version of Qt are you using, and if it's Qt 4.1.0 like me, then did you try the exact code I posted or something else? It works for me on X11 and WinXP. The only thing I see is that if you drag text, then it updates the cursor position without a cursorPositionChanged signal being emitted, but that's a Qt library issue -- the cursor stops blinking when dragging text as well. But then it gets that signal once you drop the text.
Re: Rich Text Tale Vol1 : Background colors
Townk, if the rest of that post applied to me...
Quote:
Originally Posted by Townk
...and fix some missing features on your snippet too, like if you scroll the screen with mouse wheel for exemple, you get an undesired behavior.
What sort of behaviour? It's working OK on my end when I scroll with the mouse wheel. Is it possible to post a screen shot of the issue?
It might require some tweaking (like only updating the effected areas), but if you move the cursor across many lines, then the rectangle doesn't look like it's updated too smoothly. I.e., don't jump across many lines, but go through all intervening lines say with the up arrow key.
Quote:
By the way are you interted in build some kind of multi platafom Qt IDE?
I've actually been considering that myself, but I don't know how much time I would have for that right now.
1 Attachment(s)
Re: Rich Text Tale Vol1 : Background colors
Man I think that TT should look a litle closer to Arthur!
The behavior that I report before is notted with WinXP SP2 + Qt 4.1.0, actualy I'm not at work so I cannot put a screenshot of the problem, so I copy and paste your code here in my SuSE 10 + Qt 4.1.1-snapshot-20060127 and looks what it happend on editor.png attached.
Man I don't know what to think!!!!
than I change highlightCurrentLine method to optimize the update to something like this:
Code:
void Editor::highlightCurrentLine(bool fullUpdate) {
QRect newCursorRect
(0, cursorRect
().
y(), viewport
()->width
(), fontMetrics
().
height());
if (fullUpdate)
else {
if (_currentCursorRect.isValid()) {
toUpdate = newCursorRect.unite(_currentCursorRect);
toUpdate.setHeight(toUpdate.height() + 1);
}
else
toUpdate = newCursorRect;
}
_currentCursorRect = newCursorRect;
update(toUpdate);
}
but now... highlight current line even paint!!!!
I will try to see what is happen and post here after.
Re: Rich Text Tale Vol1 : Background colors
Ok, now my new method is working (was in another method the problem), but the behavior is the same as blockd's code.
I think I'll fill a bug report to TT guys, what you think?
I'm downloading the last snapshot (4.1.1-snapshot-20060203) to see how our code looks like on it.
When I finish to download and compile I post results here.
Re: Rich Text Tale Vol1 : Background colors
Townk,
The text will get overridden, but what happens for you if you move the call to the top of the overridden paintEvent function? And then don't call painter.end() (although it *should* be OK). Then do you still see those issues?
If that "fixes" it, then what happens if you go back to the original code, don't call painter.end(), and put the "QPainter painter(...)" definition between curly braces?
I.e,
Code:
void
{
...
{
... do painting stuff ...
}
}
Also, is there any change if you call viewport()->update() instead?
Also for QPaintEvent *e, maybe try qDebug() << e->rect() and qDebug() << e->region()
and compare it to the viewport geometry to see what it even thinks it should repaint.
Re: Rich Text Tale Vol1 : Background colors
Quote:
Originally Posted by Townk
Why we do not join efforts to create the best Qt IDE ever made :D ? Have you already start a sourceforge project? If not, I could do this.
Pretty good idea, I was about to ask exactly yhe same question ! :D That is to say I go for that!!! I didn't started any sourceforge project so we may use the one you started.
:eek: DAMN!!! Multi line edit seems to be a very interesting feature but quite hard to implement!
I already started to embed my editor widget in a real IDE app. screenshots (and alpha version maybe) are coming soon(on next Monday I hope!)
The strange behaviour you encountered are quite confusing, can you post full source code?
Re: Rich Text Tale Vol1 : Background colors
Ok guys, let me update you:
4.1.1-snapshot-20060203 not compiled yet :p
This is the original paint event that I'm using:
Code:
painter.
fillRect(_currentCursorRect, palette
().
brush(QPalette::AlternateBase)) ;
painter.end();
}
so I try this two ways with the very same result as the above:
Code:
painter.
fillRect(_currentCursorRect, palette
().
brush(QPalette::AlternateBase)) ;
}
and
Code:
{
painter.
fillRect(_currentCursorRect, palette
().
brush(QPalette::AlternateBase)) ;
}
}
Than I have an idea! I put a debug message on the firs line of paintEVent like this:
Code:
qDebug() << "Event rect: " << event->rect();
qDebug() << "Event region: " << event->region();
painter.
fillRect(_currentCursorRect, palette
().
brush(QPalette::AlternateBase)) ;
painter.end();
}
What I see is that width of the "event->rect()" or "event->region()" is always 9 when I move arround.
I read that paint engine do not paint imediatly when an update is called, instead, it query the paint to do the job when the main loop gains control. So what I'm thinking is that some other stuff (like the blink timer) is overiden the update rect passed by the highlightCurrentLine method when we move arround with cursor keys or mouse clicks.
Well, its a gess, any other ideas?
Re: Rich Text Tale Vol1 : Background colors
4.1.1-snapshot-20060203 finish to compile.
I recompile the code and get the same result. When I move cursor without enter key, the event->rect() has 9 of width whats make paintEvent paint only arround the cursor not the entire line!!!
I'll report a bug to TT guys.
Re: Rich Text Tale Vol1 : Background colors
My bad... I can see the problem with the latest snapshot of 4.1.1. However, it's gone if I replace update() with viewport()->update() like I suggested. I'm going to edit my code example upthread to reflect this.