PDA

View Full Version : QPlainTextEdit inherited + invisibleQTextBlock + INVALID vertical scroll bar



chmirko
23rd September 2011, 17:01
Hello,

I am using inherited class from QPlainTextEdit,
modifications are line numbering and inclusion of QCompleter only

Now I want to make some code folding,
for start, I just want to make text folding working, before mixing it up with grammar

so my problem is, when I fold some lines, using cursor keys in text is relatively ok

problem is horizontal scroll bar (visible scroll bar, or mouse middle wheel)

when I am scrolling up (towards line 0), and I am scrolling through hidden lines,
they are somewhat included, so each click up, all lines scroll one down (wrong), and in place of hidden line, is last visible top line (so doubled now),
when I move cursor through incorrectly moved lines, they (?refresh) to what they should be, I solved this by calling
update(); // which calls lineAreaUpdate + viewport()->update();
so no more rubbish scrolling,
now you are "dud" clicking arrow up, till you skip all hidden lines, and then it scrolls,
annoying, but let us say tolerable

another problem (this post related) is moments when I hide or show lines,
if all lines are visible (no scroll bar needed), because some are hidden, and I unhide them, scrollbar WILL NOT APPEAR,
adding empty lines, will make scroll bar to appear, but only to length of added lines (some lines still inaccessible),
using arrow keys will move cursor on inaccessible lines, but textedit will not scroll (therefore relatively ok), so you can't see them,

problem solving events are:
- resize window VERTICALY (horizontaly WILL NOT help)
- maximize/restore window state
- backspace out one line
QPlainTextEdit inherited widget is being resized with window,
also setPlainText(toPlainText); solve the problem

so my first question, which event to call, to FORCE scrollbars to refresh their (?state, ?linesCounting),
second is, what else is wrong and how to correct it (not by using other widgets, I think this is almost done and need only small repair)

PS: on events when scrollbar (horizontal) correctly resizes, scrolling is working as supposed (no more dud-clicking), therefore I think calling right updateLikeMethodOnScrollsBar could resolve all problems

here are some sources,
lineTextEdit is inherited from QPlainTextEdit

line numbering, correct on folding when update called


// process all valid blocks
while (block.isValid() && top <= event->rect().bottom())
{
// print number
if (block.isVisible())
painter.drawText(0, top, lineCntr->width(), fontMetrics().height(), Qt::AlignRight, QString::number(blockNumber));

// update data
block = block.next();
top = bottom;
bottom = top + (int) blockBoundingRect(block).height();

// next
++blockNumber;
}



code colapsing method


/// manager of code collapsing
void lineTextEdit::blockMaster()
{
// acquire first block
QTextBlock block(firstVisibleBlock());

// default visibility depth
int depth(0);

// process all blocks
while (block.isValid())
{
// set visibility
block.setVisible(!depth);

// conditions
if (block.text().left(5) == ";HIDE")
++depth;
else if (depth && block.text().left(5) == ";SHOW")
{
--depth;
block.setVisible(!depth);
}

// next block
block = block.next();
}

// update
this->viewport()->update();//////// part of lineCntr->update (not directly, but DO IS called)
this->lineCntr->update();//////// currently connected on updateRequest()

update();
}

PS: I do not care about point&click hide/show arrows till this manager is not working properly, this is easier for me to test

chmirko
27th September 2011, 11:00
So I traced it to resizeEvent,
the method needed to call is
d->relayoutDocument();,
but is private so i can't call it directly,

it is bounded by if (old_width != now_width),

so questions are:
- how to call private member
- how to make old_width dirty, as calling resize event is quite simple
- which other member is calling this private member (of QPlainTextEdit)

member I traced it in is


void QPlainTextEdit::resizeEvent(QResizeEvent *e)
{
Q_D(QPlainTextEdit);
if (e->oldSize().width() != e->size().width())
d->relayoutDocument();
d->_q_adjustScrollbars();
}

experimentaly verified with debugger (by tikering code flow) that d->_q_adjustScrollbars(); is NOT doing what it is supposed to,
d->relayoutDocument(); is the one I need,

So will there be any quick answer for any of my three questions or am I about to look inside the method where more exactly the problem is being solved?

chmirko
27th September 2011, 13:46
solved by calling resizeEvent(...) with faked QResizeEvent