From c8eb8ebb48ac2e5bc3743a2949b003f5f4a6801e Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Oct 21 2011 16:45:01 +0000 Subject: Crash in marker cleanup code (kde#210106) --- diff --git a/konversation-1.3.1-fix_scroll_background.patch b/konversation-1.3.1-fix_scroll_background.patch new file mode 100644 index 0000000..10a5fd5 --- /dev/null +++ b/konversation-1.3.1-fix_scroll_background.patch @@ -0,0 +1,41 @@ +diff --git a/src/viewer/ircview.cpp b/src/viewer/ircview.cpp +index 43a4004..5d67a7d 100644 +--- a/src/viewer/ircview.cpp ++++ b/src/viewer/ircview.cpp +@@ -625,27 +625,27 @@ void IRCView::updateAppearance() + + setVerticalScrollBarPolicy(Preferences::self()->showIRCViewScrollBar() ? Qt::ScrollBarAlwaysOn : Qt::ScrollBarAlwaysOff); + +- QPalette p; +- +- p.setColor(QPalette::Base, Preferences::self()->color(Preferences::TextViewBackground)); +- + if (Preferences::self()->showBackgroundImage()) + { + KUrl url = Preferences::self()->backgroundImage(); + +- if (!url.isEmpty()) ++ if (url.hasPath()) + { +- QBrush brush; +- +- brush.setTexture(QPixmap(url.path())); ++ viewport()->setStyleSheet("QWidget { background-image: url("+url.path()+"); background-attachment:fixed; }"); + +- p.setBrush(QPalette::Base, brush); ++ return; + } + } + ++ if (!viewport()->styleSheet().isEmpty()) ++ viewport()->setStyleSheet(""); ++ ++ QPalette p; ++ p.setColor(QPalette::Base, Preferences::self()->color(Preferences::TextViewBackground)); + setPalette(p); + } + ++ + // Data insertion + + void IRCView::append(const QString& nick, const QString& message) diff --git a/konversation.spec b/konversation.spec index c90b6f1..94c21b0 100644 --- a/konversation.spec +++ b/konversation.spec @@ -1,7 +1,7 @@ Name: konversation Version: 1.3.1 -Release: 4%{?dist} +Release: 5%{?dist} Summary: A user friendly IRC client Group: Applications/Internet @@ -10,7 +10,11 @@ URL: http://konversation.kde.org/ Source0: ftp://ftp.kde.org/pub/kde/%{?pre:un}stable/konversation/%{version}%{?pre:-%{pre}}/src/konversation-%{version}%{?pre:-%{pre}}.tar.bz2 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -Patch10: konvi-1.3.1_fix-scroll_background.patch +#Upstream patches +Patch100: konversation-1.3.1-fix_scroll_background.patch +# Crash in marker cleanup code [QList::*, IRCView::cullMarkedLine] +# http://bugs.kde.org/210106 +Patch101: konverstation-1.3.1-kdebug210106.patch BuildRequires: desktop-file-utils BuildRequires: gettext @@ -34,7 +38,10 @@ to chat windows; configurable background colors and much more %prep %setup -q -n %{name}-%{version}%{?pre:-%{pre}} -%patch10 -p1 + +%patch100 -p1 -b .fix_scroll_background +%patch101 -p1 -b .kdebug210106 + %build mkdir -p %{_target_platform} @@ -86,6 +93,9 @@ fi %changelog +* Fri Oct 21 2011 Rex Dieter 1.3.1-5 +- Crash in marker cleanup code (kde#210106) + * Sat Mar 12 2011 Kevin Kofler - 1.3.1-4 - add Requires: qca-ossl diff --git a/konverstation-1.3.1-kdebug210106.patch b/konverstation-1.3.1-kdebug210106.patch new file mode 100644 index 0000000..ec31781 --- /dev/null +++ b/konverstation-1.3.1-kdebug210106.patch @@ -0,0 +1,418 @@ +From: eli mackenzie +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 + Copyright (C) 2005-2007 Peter Simonsson + Copyright (C) 2006-2008 Eike Hein +- Copyright (C) 2004-2009 Eli Mackenzie ++ Copyright (C) 2004-2011 Eli Mackenzie + */ + + #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 &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(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(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 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 + + diff --git a/konvi-1.3.1_fix-scroll_background.patch b/konvi-1.3.1_fix-scroll_background.patch deleted file mode 100644 index 10a5fd5..0000000 --- a/konvi-1.3.1_fix-scroll_background.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff --git a/src/viewer/ircview.cpp b/src/viewer/ircview.cpp -index 43a4004..5d67a7d 100644 ---- a/src/viewer/ircview.cpp -+++ b/src/viewer/ircview.cpp -@@ -625,27 +625,27 @@ void IRCView::updateAppearance() - - setVerticalScrollBarPolicy(Preferences::self()->showIRCViewScrollBar() ? Qt::ScrollBarAlwaysOn : Qt::ScrollBarAlwaysOff); - -- QPalette p; -- -- p.setColor(QPalette::Base, Preferences::self()->color(Preferences::TextViewBackground)); -- - if (Preferences::self()->showBackgroundImage()) - { - KUrl url = Preferences::self()->backgroundImage(); - -- if (!url.isEmpty()) -+ if (url.hasPath()) - { -- QBrush brush; -- -- brush.setTexture(QPixmap(url.path())); -+ viewport()->setStyleSheet("QWidget { background-image: url("+url.path()+"); background-attachment:fixed; }"); - -- p.setBrush(QPalette::Base, brush); -+ return; - } - } - -+ if (!viewport()->styleSheet().isEmpty()) -+ viewport()->setStyleSheet(""); -+ -+ QPalette p; -+ p.setColor(QPalette::Base, Preferences::self()->color(Preferences::TextViewBackground)); - setPalette(p); - } - -+ - // Data insertion - - void IRCView::append(const QString& nick, const QString& message)