From: eli mackenzie <argonel@gmail.com>
Date: Fri, 30 Sep 2011 10:41:58 +0000
Subject: reformulation of cbe876c for v1.3.1
X-Git-Url: http://quickgit.kde.org/?p=konversation.git&a=commitdiff&h=4a9627ef625342b450b1101ac1575bab44b5641a
---
reformulation of cbe876c for v1.3.1
CCBUG:210106
---
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+Changes from 1.3.1 to 1.3.1 #4056.1
+This patch was created as a stop-gap measure to allow
+Konversation 1.3.1 to work with Qt 4.7.4 and newer. Nokia allowed a
+source-incompatible change to fix a bug in QtCreator, which
+causes Konversation to crash when keeping track of the marker and
+remember lines.
+
+As this is not a released version, do not report bugs against it.
+
+For more information about the Qt change, see QTBUG-20916.
+
+
Changes from 1.3 to 1.3.1:
Konversation 1.3.1 is a maintenance release that improves program behavior
and fixes defects, the most serious of which is a regression that unfortu-
--- a/src/commit.h
+++ b/src/commit.h
@@ -1,4 +1,4 @@
// This COMMIT number is added to version string to be used as "patch level"
#ifndef COMMIT
-#define COMMIT 4056
+#define COMMIT 4056.1
#endif
--- a/src/version.h
+++ b/src/version.h
@@ -1,3 +1,3 @@
#ifndef KONVI_VERSION
-#define KONVI_VERSION "1.3.1"
+#define KONVI_VERSION "1.3.1 #4056.1"
#endif
--- a/src/viewer/ircview.cpp
+++ b/src/viewer/ircview.cpp
@@ -11,7 +11,7 @@
Copyright (C) 2002 Dario Abatianni <eisfuchs@tigress.com>
Copyright (C) 2005-2007 Peter Simonsson <psn@linux.se>
Copyright (C) 2006-2008 Eike Hein <hein@kde.org>
- Copyright (C) 2004-2009 Eli Mackenzie <argonel@gmail.com>
+ Copyright (C) 2004-2011 Eli Mackenzie <argonel@gmail.com>
*/
#include "ircview.h"
@@ -111,7 +111,10 @@ class SelectionPin
if (d->textCursor().hasSelection())
{
int end = d->document()->rootFrame()->lastPosition();
- QTextBlock b = d->document()->lastBlock();
+
+ //WARNING if selection pins don't work in some build environments, we need to keep the result
+ d->document()->lastBlock();
+
pos = d->textCursor().position();
anc = d->textCursor().anchor();
if (pos != end && anc != end)
@@ -132,7 +135,7 @@ class SelectionPin
};
-IRCView::IRCView(QWidget* parent, Server* newServer) : KTextBrowser(parent), m_nextCullIsMarker(false), m_rememberLinePosition(-1), m_rememberLineDirtyBit(false), markerFormatObject(this)
+IRCView::IRCView(QWidget* parent, Server* newServer) : KTextBrowser(parent), m_rememberLine(0), m_lastMarkerLine(0), m_rememberLineDirtyBit(false), markerFormatObject(this)
{
m_copyUrlMenu = false;
m_resetScrollbar = true;
@@ -325,34 +328,6 @@ bool IRCView::searchNext(bool reversed)
return find(m_pattern, m_searchFlags);
}
-//// Marker lines
-
-#define _S(x) #x << (x)
-void dump_doc(QTextDocument* document)
-{
- QTextBlock b(document->firstBlock());
- while (b.isValid())
- {
- kDebug() << _S(b.position())
- << _S(b.length())
- << _S(b.userState())
- ;
- b=b.next();
- };
-}
-
-QDebug operator<<(QDebug dbg, QList<QTextBlock> &l)
-{
- dbg.space() << _S(l.count()) << endl;
- for (int i=0; i< l.count(); ++i)
- {
- QTextBlock b=l[i];
- dbg.space() << _S(i) << _S(b.blockNumber()) << _S(b.length()) << _S(b.userState()) << endl;
- }
-
- return dbg.space();
-}
-
class IrcViewMimeData : public QMimeData
{
public:
@@ -417,13 +392,52 @@ void IRCView::dropEvent(QDropEvent* e)
emit urlsDropped(KUrl::List::fromMimeData(e->mimeData(), KUrl::List::PreferLocalUrls));
}
+// Marker lines
+
+// This object gets stuffed into the userData field of a text block.
+// Qt does not give us a way to track blocks, so we have to
+// rely on the destructor of this object to notify us that a
+// block we care about was removed from the document. This does not
+// prevent the first block bug from deleting the wrong block's data,
+// however that should not result in a crash.
+struct Burr: public QTextBlockUserData
+{
+ Burr(IRCView* o, Burr* prev, QTextBlock b, int objFormat)
+ : m_block(b), m_format(objFormat), m_prev(prev), m_next(0),
+ m_owner(o)
+ {
+ if (m_prev)
+ m_prev->m_next = this;
+ }
+
+ ~Burr()
+ {
+ m_owner->blockDeleted(this);
+ unlink();
+ }
+
+ void unlink()
+ {
+ if (m_prev)
+ m_prev->m_next = m_next;
+ if (m_next)
+ m_next->m_prev = m_prev;
+ }
+
+ QTextBlock m_block;
+ int m_format;
+ Burr* m_prev, *m_next;
+ IRCView* m_owner;
+};
+
void IrcViewMarkerLine::drawObject(QPainter *painter, const QRectF &r, QTextDocument *doc, int posInDocument, const QTextFormat &format)
{
Q_UNUSED(format);
QTextBlock block=doc->findBlock(posInDocument);
QPen pen;
- switch (block.userState())
+ Burr* b = dynamic_cast<Burr*>(block.userData());
+ switch (b->m_format)
{
case IRCView::BlockIsMarker:
pen.setColor(Preferences::self()->color(Preferences::ActionMessage));
@@ -456,33 +470,36 @@ QSizeF IrcViewMarkerLine::intrinsicSize(
return QSizeF(width, 6); // FIXME this is a hardcoded value...
}
+QTextCharFormat IRCView::getFormat(ObjectFormats x)
+{
+ QTextCharFormat f;
+ f.setObjectType(x);
+ return f;
+}
+
+void IRCView::blockDeleted(Burr* b) //slot
+{
+ //tracking only the tail
+ if (b == m_lastMarkerLine)
+ m_lastMarkerLine = b->m_prev;
+
+ if (b == m_rememberLine)
+ m_rememberLine = 0;
+}
+
void IRCView::cullMarkedLine(int where, int rem, int add) //slot
{
- if (where == 0 && add == 0 && rem !=0)
- {
- if (document()->blockCount() == 1 && document()->firstBlock().length() == 1)
- {
+ int blockCount = document()->blockCount();
+ QTextBlock prime = document()->firstBlock();
+
+ if (prime.length() == 1 && document()->blockCount() == 1)
wipeLineParagraphs();
- }
- else
- {
- if (m_nextCullIsMarker)
- {
- //move the remember line up.. if the cull removed it, this will forget its position
- if (m_rememberLinePosition >= 0)
- --m_rememberLinePosition;
- m_markers.takeFirst();
- }
- int s = document()->firstBlock().userState();
- m_nextCullIsMarker = (s == BlockIsMarker || s == BlockIsRemember);
- }
- }
}
void IRCView::insertMarkerLine() //slot
{
//if the last line is already a marker of any kind, skip out
- if (lastBlockIsLine())
+ if (lastBlockIsLine(BlockIsMarker))
return;
//the code used to preserve the dirty bit status, but that was never affected by appendLine...
@@ -505,7 +522,12 @@ void IRCView::cancelRememberLine() //slo
bool IRCView::lastBlockIsLine(int select)
{
- int state = document()->lastBlock().userState();
+ Burr *b = dynamic_cast<Burr*>(document()->lastBlock().userData());
+
+ int state = -1;
+
+ if (b)
+ state = b->m_format;
if (select == -1)
return (state == BlockIsRemember || state == BlockIsMarker);
@@ -522,81 +544,51 @@ void IRCView::appendRememberLine()
if (lastBlockIsLine(BlockIsRemember))
return;
- // if we already have a rememberline, remove the previous one
- if (m_rememberLinePosition > -1)
+ if (m_rememberLine)
{
- //get the block that is the remember line
- QTextBlock rem = m_markers[m_rememberLinePosition];
- m_markers.removeAt(m_rememberLinePosition); //probably will be in there only once
- m_rememberLinePosition=-1;
+ QTextBlock rem = m_rememberLine->m_block;
voidLineBlock(rem);
+ if (m_rememberLine != 0)
+ {
+ kDebug() << "%%%%%%%%%%%%%%%%% m_rememberLine still set!";
+ // this probably means we had a block containing only 0x2029, so Scribe merged the userData/userState into the next
+ m_rememberLine = 0;
+ }
}
- //tell the control we did stuff
- //FIXME do we still do something like this?
- //repaintChanged();
+ m_rememberLine = appendLine(IRCView::RememberLine);
- //actually insert a line
- appendLine(IRCView::RememberLine);
-
- //store the index of the remember line
- m_rememberLinePosition = m_markers.count() - 1;
}
void IRCView::voidLineBlock(QTextBlock rem)
{
- if (rem.blockNumber() == 0)
- {
- Q_ASSERT(m_nextCullIsMarker);
- m_nextCullIsMarker = false;
- }
QTextCursor c(rem);
- //FIXME make sure this doesn't flicker
+
c.select(QTextCursor::BlockUnderCursor);
c.removeSelectedText();
}
void IRCView::clearLines()
{
- //if we have a remember line, put it in the list
- //its already in the list
- kDebug() << _S(m_nextCullIsMarker) << _S(m_rememberLinePosition) << _S(textCursor().position()) << m_markers;
- dump_doc(document());
-
- //are there any markers?
- if (hasLines())
+ while (hasLines())
{
- for (int i=0; i < m_markers.count(); ++i)
- voidLineBlock(m_markers[i]);
-
- wipeLineParagraphs();
-
- //FIXME do we have this? //repaintChanged();
- }
-
+ //IRCView::blockDeleted takes care of the pointers
+ voidLineBlock(m_lastMarkerLine->m_block);
+ };
}
void IRCView::wipeLineParagraphs()
{
- m_nextCullIsMarker = false;
- m_rememberLinePosition = -1;
- m_markers.clear();
+ m_rememberLine = m_lastMarkerLine = 0;
}
bool IRCView::hasLines()
{
- return m_markers.count() > 0;
+ return m_lastMarkerLine != 0;
}
-QTextCharFormat IRCView::getFormat(ObjectFormats x)
-{
- QTextCharFormat f;
- f.setObjectType(x);
- return f;
-}
-
-void IRCView::appendLine(IRCView::ObjectFormats type)
+Burr* IRCView::appendLine(IRCView::ObjectFormats type)
{
ScrollBarPin barpin(verticalScrollBar());
SelectionPin selpin(this);
@@ -604,13 +596,21 @@ void IRCView::appendLine(IRCView::Object
QTextCursor cursor(document());
cursor.movePosition(QTextCursor::End);
- cursor.insertBlock();
+ if (cursor.block().length() > 1) // this will be a 0x2029
+ cursor.insertBlock();
cursor.insertText(QString(QChar::ObjectReplacementCharacter), getFormat(type));
- cursor.block().setUserState(type == MarkerLine? BlockIsMarker : BlockIsRemember);
- m_markers.append(cursor.block());
-}
+ QTextBlock block = cursor.block();
+ Burr *b = new Burr(this, m_lastMarkerLine, block, type == MarkerLine? BlockIsMarker : BlockIsRemember);
+ block.setUserData(b);
+
+ m_lastMarkerLine = b;
+ //TODO figure out what this is for
+ cursor.setPosition(block.position());
+
+ return b;
+}
//// Other stuff
--- a/src/viewer/ircview.h
+++ b/src/viewer/ircview.h
@@ -24,7 +24,7 @@
class Server;
class ChatWindow;
-
+class Burr;
class KToggleAction;
class KMenu;
@@ -139,9 +139,10 @@ class IRCView : public KTextBrowser
void appendRememberLine();
/// Create a remember line and insert it.
- void appendLine(ObjectFormats=MarkerLine);
+ /// @return - Pointer to the Burr that was inserted into the block
+ Burr* appendLine(ObjectFormats=MarkerLine);
- /// Forget the position of the remember line and markers.
+ /// Convenience method - forget the position of the remember line and markers.
void wipeLineParagraphs();
/// Convenience method - is the last block any sort of line, or a specific line?
@@ -154,16 +155,22 @@ class IRCView : public KTextBrowser
/// Shortcut to get an object format of the desired type
QTextCharFormat getFormat(ObjectFormats);
+ public slots:
+ // Doesn't have to be a slot, but what the hay.
+ /// Called *only* from ~Burr(), by QTextBlockData::free
+ void blockDeleted(Burr* b);
+
private slots:
- /** Called to see if a marker is queued up for deletion. Only triggers if
- "where" is the beginning and there was nothing added.
- */
+ /** Called every time a change occurs to the document.
+ *
+ * Used to infer the clearing of the entire document,
+ * because Trolltech removed virtual from the method
+ * that would indicate authoritatively.
+ */
void cullMarkedLine(int, int, int);
private: //marker/remember line data
- bool m_nextCullIsMarker; ///< the next time a cull occurs, it'll be a marker
- QList<QTextBlock> m_markers; ///< what blocks are markers?
- int m_rememberLinePosition; ///< position of remember line in m_markers
+ Burr *m_rememberLine, *m_lastMarkerLine;
bool m_rememberLineDirtyBit; ///< the next append needs a remember line
IrcViewMarkerLine markerFormatObject; ///< a QTextObjectInterface