r16639 by jghali - #10017 : jump when typing in text frame, provide a more elegant solution
scribus-commit
scribus-commit at lists.scribus.net
Tue Jun 7 21:02:29 UTC 2011
Author: jghali
Date: Tue Jun 7 21:02:29 2011
New Revision: 16639
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=16639
Log:
#10017 : jump when typing in text frame, provide a more elegant solution
- add more functions in StoryText for doing operations directly at current cursor position
- complement object update api by updateLayout() : contrary to update(), updateLayout() will update layout immediately whereas update() will trigger layout() only in following paintEvent
Modified:
trunk/Scribus/scribus/canvasmode_edit.cpp
trunk/Scribus/scribus/observable.h
trunk/Scribus/scribus/pageitem_textframe.cpp
trunk/Scribus/scribus/scribusdoc.cpp
trunk/Scribus/scribus/scribusview.cpp
trunk/Scribus/scribus/scribusview.h
trunk/Scribus/scribus/text/sctext_shared.cpp
trunk/Scribus/scribus/text/sctext_shared.h
trunk/Scribus/scribus/text/storytext.cpp
trunk/Scribus/scribus/text/storytext.h
Modified: trunk/Scribus/scribus/canvasmode_edit.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16639&path=/trunk/Scribus/scribus/canvasmode_edit.cpp
==============================================================================
--- trunk/Scribus/scribus/canvasmode_edit.cpp (original)
+++ trunk/Scribus/scribus/canvasmode_edit.cpp Tue Jun 7 21:02:29 2011
@@ -240,7 +240,7 @@
QPen cPen ( Qt::black, 0.9 , Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin );
// normalize Current Position
- textframe->itemText.setCursorPosition( qMax ( 0, qMin( textframe->itemText.cursorPosition(), textframe->itemText.length() ) ) );
+ textframe->itemText.normalizeCursorPosition();
int textCursorPos ( textframe->itemText.cursorPosition() );
if ( textframe->lastInFrame() >= signed ( textframe->itemText.nrOfItems() )
Modified: trunk/Scribus/scribus/observable.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16639&path=/trunk/Scribus/scribus/observable.h
==============================================================================
--- trunk/Scribus/scribus/observable.h (original)
+++ trunk/Scribus/scribus/observable.h Tue Jun 7 21:02:29 2011
@@ -71,9 +71,11 @@
template<class OBSERVED>
struct Private_Memento : public UpdateMemento
{
- Private_Memento(OBSERVED data) : m_data(data) {};
+ Private_Memento(OBSERVED data) : m_data(data), m_layout(false) {};
+ Private_Memento(OBSERVED data, bool layout) : m_data(data), m_layout(layout) {};
OBSERVED m_data;
+ bool m_layout;
};
@@ -84,7 +86,7 @@
template<class OBSERVED>
class SCRIBUS_API Observer {
public:
- virtual void changed(OBSERVED) = 0;
+ virtual void changed(OBSERVED, bool doLayout) = 0;
virtual ~Observer() {}
};
@@ -124,6 +126,11 @@
will take care of that.
*/
virtual void update(OBSERVED what);
+
+ /**
+ Same as update, except layout will be update immediately
+ */
+ virtual void updateLayout(OBSERVED what);
void connectObserver(Observer<OBSERVED>* o);
void disconnectObserver(Observer<OBSERVED>* o);
@@ -170,6 +177,11 @@
{
m_massObservable->update(dynamic_cast<OBSERVED*>(this));
}
+
+ virtual void updateLayout()
+ {
+ m_massObservable->updateLayout(dynamic_cast<OBSERVED*>(this));
+ }
private:
MassObservable<OBSERVED*>* m_massObservable;
@@ -239,6 +251,15 @@
}
}
+template<class OBSERVED>
+inline void MassObservable<OBSERVED>::updateLayout(OBSERVED what)
+{
+ Private_Memento<OBSERVED>* memento = new Private_Memento<OBSERVED>(what, true);
+ if (m_um == NULL || m_um->requestUpdate(this, memento))
+ {
+ updateNow(memento);
+ }
+}
template<class OBSERVED>
inline void MassObservable<OBSERVED>::updateNow(UpdateMemento* what)
@@ -246,7 +267,7 @@
Private_Memento<OBSERVED>* memento = dynamic_cast<Private_Memento<OBSERVED>*>(what);
foreach (Observer<OBSERVED>* obs, m_observers)
{
- obs->changed(memento->m_data);
+ obs->changed(memento->m_data, memento->m_layout);
}
changedSignal->emitSignal(QVariant::fromValue(memento->m_data));
delete memento;
Modified: trunk/Scribus/scribus/pageitem_textframe.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16639&path=/trunk/Scribus/scribus/pageitem_textframe.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem_textframe.cpp (original)
+++ trunk/Scribus/scribus/pageitem_textframe.cpp Tue Jun 7 21:02:29 2011
@@ -903,7 +903,9 @@
// printBacktrace(24);
if (BackBox != NULL && BackBox->invalid) {
// qDebug("textframe: len=%d, going back", itemText.length());
- invalid = false;
+ // Why that invalid = false here? Calling prevInChain->layout() does
+ // not ensure that this box will be layouted
+ // invalid = false;
PageItem_TextFrame* prevInChain = dynamic_cast<PageItem_TextFrame*>(BackBox);
while (prevInChain && prevInChain->invalid)
{
@@ -2764,10 +2766,10 @@
if (frameUnderflows())
{
itemText.setCursorPosition( itemText.length() );
- m_Doc->view()->Deselect(true);
PageItem * jumpFrame = frameTextEnd();
if (jumpFrame)
{
+ m_Doc->view()->Deselect(true);
m_Doc->scMW()->selectItemsFromOutlines(jumpFrame);
m_Doc->scMW()->setTBvals(jumpFrame);
jumpFrame->update();
@@ -2886,6 +2888,8 @@
else if (kk == Qt::Key_Right)
kk = Qt::Key_Left;
}
+
+ int oldLast = lastInFrame();
switch (kk)
{
case Qt::Key_Home:
@@ -3007,7 +3011,7 @@
{
view->Deselect(true);
// TODO position at the right place in previous frame
- itemText.setCursorPosition( BackBox->lastInFrame() );
+ BackBox->itemText.setCursorPosition( BackBox->lastInFrame() );
m_Doc->scMW()->selectItemsFromOutlines(BackBox);
}
}
@@ -3017,7 +3021,7 @@
if (BackBox != 0)
{
view->Deselect(true);
- itemText.setCursorPosition( BackBox->lastInFrame() );
+ BackBox->itemText.setCursorPosition( BackBox->lastInFrame() );
m_Doc->scMW()->selectItemsFromOutlines(BackBox);
}
}
@@ -3030,7 +3034,7 @@
if (itemText.cursorPosition() == firstInFrame() && BackBox != 0)
{
view->Deselect(true);
- itemText.setCursorPosition( BackBox->firstInFrame() );
+ BackBox->itemText.setCursorPosition( BackBox->firstInFrame() );
m_Doc->scMW()->selectItemsFromOutlines(BackBox);
//currItem = currItem->BackBox;
}
@@ -3065,7 +3069,7 @@
{
int pos = itemText.cursorPosition();
itemText.setCursorPosition(-1, true);
- if (pos > 0)
+ if ( pos > 0 )
ExpandSel(-1, oldPos);
}
else
@@ -3077,7 +3081,7 @@
if (BackBox != 0)
{
view->Deselect(true);
- itemText.setCursorPosition( BackBox->lastInFrame() );
+ BackBox->itemText.setCursorPosition( BackBox->lastInFrame() );
m_Doc->scMW()->selectItemsFromOutlines(BackBox);
//currItem = currItem->BackBox;
}
@@ -3164,7 +3168,7 @@
keyRepeat = false;
return;
}
- cr = itemText.text(itemText.cursorPosition(), 1);
+ cr = itemText.text(1);
if (itemText.lengthOfSelection() == 0)
itemText.select(itemText.cursorPosition(), 1, true);
deleteSelectedTextFromFrame();
@@ -3204,12 +3208,17 @@
// m_Doc->chAbStyle(this, findParagraphStyle(m_Doc, itemText.paragraphStyle(qMax(CPos-1,0))));
// Tinput = false;
}
+ updateLayout();
+ if (oldLast != lastInFrame() && NextBox != 0 && NextBox->invalid)
+ NextBox->updateLayout();
if (itemText.cursorPosition() < firstInFrame())
{
itemText.setCursorPosition( firstInFrame() );
if (BackBox != 0)
{
view->Deselect(true);
+ if (BackBox->invalid)
+ BackBox->updateLayout();
itemText.setCursorPosition( BackBox->lastInFrame() );
m_Doc->scMW()->selectItemsFromOutlines(BackBox);
//currItem = currItem->BackBox;
@@ -3285,14 +3294,20 @@
doUpdate = true;
}
if (doUpdate)
- update();
+ {
+ // update layout immediately, we need MaxChars to be correct to detect
+ // if we need to move to next frame or not
+ updateLayout();
+ if (oldLast != lastInFrame() && NextBox != 0 && NextBox->invalid)
+ NextBox->updateLayout();
+ }
//check if cursor need to jump to next linked frame
- if (lastInFrame() < (itemText.length() -2) && NextBox != 0)
+ if ((itemText.cursorPosition() > lastInFrame() + 1) && (lastInFrame() < (itemText.length() - 2)) && NextBox != 0)
{
view->Deselect(true);
- //NextBox->CPos = CPos;
+ view->Deselect(true);
+ NextBox->update();
m_Doc->scMW()->selectItemsFromOutlines(NextBox);
- NextBox->update();
}
break;
}
Modified: trunk/Scribus/scribus/scribusdoc.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16639&path=/trunk/Scribus/scribus/scribusdoc.cpp
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.cpp (original)
+++ trunk/Scribus/scribus/scribusdoc.cpp Tue Jun 7 21:02:29 2011
@@ -135,7 +135,7 @@
}
}
- void changed(Page* pg)
+ void changed(Page* pg, bool /*doLayout*/)
{
QRectF pagebox(pg->xOffset(), pg->yOffset(), pg->width(), pg->height());
doc->invalidateRegion(pagebox);
@@ -148,9 +148,11 @@
m_docChangeNeeded = true;
}
- void changed(PageItem* it)
+ void changed(PageItem* it, bool doLayout)
{
it->invalidateLayout();
+ if (doLayout)
+ it->layout();
doc->regionsChanged()->update(it->getVisualBoundingRect());
if (m_updateEnabled <= 0)
{
@@ -6942,7 +6944,7 @@
start = currItem->itemText.startOfSelection();
stop = currItem->itemText.endOfSelection();
if (start >= stop)
- start = stop = qMax(0, qMin(currItem->itemText.length(), currItem->itemText.cursorPosition()));
+ start = stop = currItem->itemText.normalizedCursorPosition();
}
for (int pos=start; pos < stop; ++pos)
{
@@ -6996,7 +6998,7 @@
start = currItem->itemText.startOfSelection();
stop = currItem->itemText.endOfSelection();
if (start >= stop)
- start = stop = qMax(0, qMin(currItem->itemText.length(), currItem->itemText.cursorPosition()));
+ start = stop = currItem->itemText.normalizedCursorPosition();
}
for (int pos=start; pos < stop; ++pos)
{
@@ -7060,7 +7062,7 @@
start = currItem->itemText.startOfSelection();
stop = currItem->itemText.endOfSelection();
if (start >= stop)
- start = stop = qMax(0, qMin(currItem->itemText.length(), currItem->itemText.cursorPosition()));
+ start = stop = currItem->itemText.normalizedCursorPosition();
}
for (int pos=start; pos < stop; ++pos)
{
@@ -7116,7 +7118,7 @@
else
{
start = qMax(currItem->firstInFrame(), currItem->itemText.cursorPosition());
- length = (start + 1) < currItem->itemText.length()? 1 : 0;
+ length = (start + 1) < currItem->itemText.length() ? 1 : 0;
}
}
currItem->itemText.applyCharStyle(start, qMax(0, length), newStyle);
Modified: trunk/Scribus/scribus/scribusview.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16639&path=/trunk/Scribus/scribus/scribusview.cpp
==============================================================================
--- trunk/Scribus/scribus/scribusview.cpp (original)
+++ trunk/Scribus/scribus/scribusview.cpp Tue Jun 7 21:02:29 2011
@@ -460,7 +460,7 @@
}
}
-void ScribusView::changed(QRectF re)
+void ScribusView::changed(QRectF re, bool)
{
double scale = m_canvas->scale();
int newCanvasWidth = qRound((Doc->maxCanvasCoordinate.x() - Doc->minCanvasCoordinate.x()) * scale);
Modified: trunk/Scribus/scribus/scribusview.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16639&path=/trunk/Scribus/scribus/scribusview.h
==============================================================================
--- trunk/Scribus/scribus/scribusview.h (original)
+++ trunk/Scribus/scribus/scribusview.h Tue Jun 7 21:02:29 2011
@@ -212,7 +212,7 @@
void setScale(const double newScale);
double scale() const;
- virtual void changed(QRectF re);
+ virtual void changed(QRectF re, bool);
void updateCanvas(QRectF box = QRectF());
void updateCanvas(double x, double y, double width, double height) { updateCanvas(QRectF(x,y,width,height)); }
Modified: trunk/Scribus/scribus/text/sctext_shared.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16639&path=/trunk/Scribus/scribus/text/sctext_shared.cpp
==============================================================================
--- trunk/Scribus/scribus/text/sctext_shared.cpp (original)
+++ trunk/Scribus/scribus/text/sctext_shared.cpp Tue Jun 7 21:02:29 2011
@@ -66,7 +66,6 @@
{
if (this != &other)
{
- cursorPosition = other.cursorPosition;
defaultStyle = other.defaultStyle;
trailingStyle = other.trailingStyle;
pstyleContext = other.pstyleContext;
@@ -90,6 +89,7 @@
}
}
len = count();
+ cursorPosition = other.cursorPosition;
pstyleContext.invalidate();
// qDebug() << QString("StoryText::copy: %1 align=%2 %3").arg(trailingStyle.parentStyle()->name())
// .arg(trailingStyle.alignment()).arg((uint)trailingStyle.context());
Modified: trunk/Scribus/scribus/text/sctext_shared.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16639&path=/trunk/Scribus/scribus/text/sctext_shared.h
==============================================================================
--- trunk/Scribus/scribus/text/sctext_shared.h (original)
+++ trunk/Scribus/scribus/text/sctext_shared.h Tue Jun 7 21:02:29 2011
@@ -21,7 +21,7 @@
StyleContextProxy pstyleContext;
uint refs;
uint len;
- uint cursorPosition;
+ uint cursorPosition;
ParagraphStyle trailingStyle;
ScText_Shared(const StyleContext* pstyles);
Modified: trunk/Scribus/scribus/text/storytext.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16639&path=/trunk/Scribus/scribus/text/storytext.cpp
==============================================================================
--- trunk/Scribus/scribus/text/storytext.cpp (original)
+++ trunk/Scribus/scribus/text/storytext.cpp Tue Jun 7 21:02:29 2011
@@ -162,6 +162,27 @@
return *this;
}
+int StoryText::cursorPosition() const
+{
+ return d->cursorPosition;
+}
+
+void StoryText::setCursorPosition(int pos, bool relative)
+{
+ if (relative)
+ pos += d->cursorPosition;
+ d->cursorPosition = qMin((uint) qMax(pos, 0), d->len);
+}
+
+void StoryText::normalizeCursorPosition()
+{
+ d->cursorPosition = qMax((uint) 0, qMin(d->cursorPosition, d->len));
+}
+
+int StoryText::normalizedCursorPosition()
+{
+ return (int) qMax((uint) 0, qMin(d->cursorPosition, d->len));
+}
void StoryText::clear()
{
@@ -316,7 +337,7 @@
// consistent in functions such as select()
if (i <= selLast) --selLast;
if (i < selFirst) --selFirst;
- if ((i + 1 )<= d->cursorPosition && d->cursorPosition > 0) d->cursorPosition -= 1;
+ if ((i + 1 ) <= d->cursorPosition && d->cursorPosition > 0) d->cursorPosition -= 1;
}
d->len = d->count();
@@ -456,18 +477,6 @@
invalidate(pos, pos + 1);
}
-int StoryText::cursorPosition() const
-{
- return d->cursorPosition;
-}
-
-void StoryText::setCursorPosition(int pos, bool relative)
-{
- if (relative)
- pos += d->cursorPosition;
- d->cursorPosition = qMin((uint) qMax(pos, 0), d->len);
-}
-
void StoryText::hyphenateWord(int pos, uint len, char* hyphens)
{
assert(pos >= 0);
@@ -617,6 +626,11 @@
StoryText* that = const_cast<StoryText *>(this);
return dynamic_cast<const CharStyle &> (*that->d->at(pos));
+}
+
+const ParagraphStyle & StoryText::paragraphStyle() const
+{
+ return paragraphStyle(d->cursorPosition);
}
const ParagraphStyle & StoryText::paragraphStyle(int pos) const
Modified: trunk/Scribus/scribus/text/storytext.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16639&path=/trunk/Scribus/scribus/text/storytext.h
==============================================================================
--- trunk/Scribus/scribus/text/storytext.h (original)
+++ trunk/Scribus/scribus/text/storytext.h Tue Jun 7 21:02:29 2011
@@ -102,27 +102,41 @@
virtual void saxx(SaxHandler& handler, const Xml_string& elemtag) const;
virtual void saxx(SaxHandler& handler) const { saxx(handler, saxxDefaultElem); }
+ int cursorPosition() const;
+ void setCursorPosition(int pos, bool relative = false);
+ void normalizeCursorPosition();
+ int normalizedCursorPosition();
+
void clear();
StoryText copy() const;
+ // Insert chars from another StoryText object at current cursor position
void insert(const StoryText& other, bool onlySelection = false);
+ // Insert chars from another StoryText object at specific position
void insert(int pos, const StoryText& other, bool onlySelection = false);
+ // Append chars from another StoryText object
void append(const StoryText& other) { insert(length(), other, false); }
+ // Remove len chars at specific position
void removeChars(int pos, uint len);
+ // Insert chars at current cursor position
void insertChars(QString txt, bool applyNeighbourStyle = false);
+ // Insert chars ar specific position
void insertChars(int pos, QString txt, bool applyNeighbourStyle = false);
+ // Insert inline object at current cursor position
void insertObject(PageItem* obj);
+ // Insert object at specific position
void insertObject(int pos, PageItem* obj);
void replaceChar(int pos, QChar ch);
- int cursorPosition() const;
- void setCursorPosition(int pos, bool relative = false);
-
void hyphenateWord(int pos, uint len, char* hyphens);
int length() const;
+ // Get char at current cursor position
QChar text() const;
+ // Get char at specific position
QChar text(int pos) const;
+ // Get text with len chars at specific position
QString text(int pos, uint len) const;
+ // Get word at specific position
QString wordAt(int pos) const;
bool hasObject(int pos) const;
@@ -137,8 +151,13 @@
int nextFramePos(int c);
int prevFramePos(int c);
+ // Get charstyle at current cursor position
const CharStyle& charStyle() const;
+ // Get charstyle at specific position
const CharStyle& charStyle(int pos) const;
+ // Get paragraph style at current cursor position
+ const ParagraphStyle& paragraphStyle() const;
+ // Get paragraph style at specific position
const ParagraphStyle& paragraphStyle(int pos) const;
const ParagraphStyle& defaultStyle() const;
void setDefaultStyle(const ParagraphStyle& style);
More information about the scribus-commit
mailing list