[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-bugs-dist
Subject: Bug#1504: KTabListBox displaying stale information after being cleared.
From: Bill Slemer <bill-slemco () mediaone ! net>
Date: 1999-07-02 4:48:55
[Download RAW message or body]
Package: kdelibs
Version: 1.1
KTabListBox will display stale information in a column of a row after
being clear() 'ed. The following code snippet exhibits the problem.
It is a piece of code to fill in a tabbed list box with four columns.
The last column is a "comment" field which may or may not have a
comment. If no comment is present, the comment field is set to null
string which results in KTabListBox putting any previous stale data for
that column of that row from a previous insertItem() call.
<<< begin snippet >>>
KTabListBox voiceListBox;
:
voiceListBox->clear(); // <<<<===== NOTE THE clear();
:
for(i=0;i<voiceDir.count();i++)
{
voiceIndex->setGroup("status");
QString message=voiceDir[i];
if( (flag = voiceIndex->readEntry(message)) == 0)
flag = "new";
message = voiceDir.path();
message += "/";
message += voiceDir[i];
:
//
// If there is no valid comment, set "comment" to a null string.
//
voiceIndex->setGroup("comments");
if((comment = voiceIndex->readEntry(voiceDir[i])) == 0)
comment = ""; // <<<==== NOTE: the null string.
<<<<============<<<<<<
:
message.sprintf("%s\n%s\n%d %s\n%s",(const char *)flag,
(const char *)mydate,
length, (const char *)i18n("secs"),
(const char *)comment);
//debug( " ----> %s",(const char *) message );
voiceListBox->insertItem(message); // <<<<==== NOTE: the last
field of "message" will be null.
}
}
<<< end snippet >>>
Examining the KTabListBox::clear() code (ktablistbox.cpp - revision
1.52) shows that clear() will mark any items in the list box with a "-2"
(apparently to denote that it's been deleted?), but doesn't appear to
delete the items.
Examining the KTabListBox::insertItem() code (ktablistbox.cpp -
revision 1.52) shows that it calls KTabListBox::changeItem(), which
contains the following code:
void KTabListBox::changeItem(const QString& aStr, int row)
{
char sepStr[2];
if (row < 0 || row >= numRows()) return;
char *str = qstrdup(aStr.local8Bit()); // TODO: make it really QString
using
sepStr[0] = sepChar;
sepStr[1] = '\0';
KTabListBoxItem* item = itemList[row];
char *pos = strtok(str, sepStr);
//
// key line follows ---||||
// VVVV
for (int i=0; pos && *pos && i<numCols(); i++)
{
item->setText(i, QString::fromLocal8Bit(pos));
pos = strtok(0L, sepStr);
}
item->setForeground(black);
if (needsUpdate(row)) lbox.repaint();
delete [] str;
}
The "*pos" of the for-loop will terminate without setting the "comment"
field (last column of row) since it was parsed out of aStr using
strtok() which returned a pointer to a null string. That is, the body
of the for-loop was not executed.
A work around for me is to set the "comment" variable to " " (single
space) rather than the null string "". However, this is not desireable.
POSSIBLE FIXES:
===============
(1) remove "*pos" from conditional check of for-loop. However, will
passing a null string to setText() cause a problem?
(2) change KTabListBox::clear() to set the string in the "item" to a
null string rather than just marking it as a "-2".
(3) catch the null string in the body of the for-loop and do something
special to free the memory for the column.
[Attachment #3 (text/html)]
<HTML>
<TT>Package: kdelibs</TT>
<BR><TT>Version: 1.1</TT><TT></TT>
<P><TT>KTabListBox will display stale information in a column of a row
after being clear() 'ed. The following code snippet exhibits
the problem. It is a piece of code to fill in a tabbed list box with
four columns. The last column is a "comment" field which may or may
not have a comment. If no comment is present, the comment field is
set to null string which results in KTabListBox putting any previous stale
data for that column of that row from a previous insertItem() call.</TT><TT></TT>
<P><TT><<< begin snippet >>></TT><TT></TT>
<P><TT>KTabListBox voiceListBox;</TT>
<BR><TT> :</TT>
<BR><TT> voiceListBox->clear(); // <<<<=====
NOTE THE clear();</TT>
<BR><TT> :</TT>
<BR><TT> for(i=0;i<voiceDir.count();i++)</TT>
<BR><TT> {</TT>
<BR><TT> voiceIndex->setGroup("status");</TT>
<BR><TT> QString message=voiceDir[i];</TT>
<BR><TT> if( (flag = voiceIndex->readEntry(message))
== 0)</TT>
<BR><TT> flag = "new";</TT>
<BR><TT> message = voiceDir.path();</TT>
<BR><TT> message += "/";</TT>
<BR><TT> message += voiceDir[i];</TT><TT></TT>
<P><TT> :</TT><TT></TT>
<P><TT> //</TT>
<BR><TT> // If there is no valid comment, set "comment"
to a null string.</TT>
<BR><TT> //</TT>
<BR><TT> voiceIndex->setGroup("comments");</TT>
<BR><TT> if((comment = voiceIndex->readEntry(voiceDir[i]))
== 0)</TT>
<BR><TT> comment = "";
// <<<==== NOTE: the null string. \
<<<<============<<<<<<</TT><TT></TT>
<P><TT> :</TT><TT></TT>
<P><TT> message.sprintf("%s\n%s\n%d %s\n%s",(const char
*)flag,</TT>
<BR><TT>
(const char *)mydate,</TT>
<BR><TT>
length, (const char *)i18n("secs"),</TT>
<BR><TT>
(const char *)comment);</TT>
<BR><TT> //debug( " ----> %s",(const
char *) message );</TT>
<BR><TT> voiceListBox->insertItem(message);
// <<<<==== NOTE: the last field of "message" will be null.</TT>
<BR><TT> }</TT>
<BR><TT>}</TT><TT></TT>
<P><TT><<< end snippet >>></TT><TT></TT>
<P><TT>Examining the KTabListBox::clear() code (ktablistbox.cpp -
revision 1.52) shows that clear() will mark any items in the list box with
a "-2" (apparently to denote that it's been deleted?), but doesn't appear
to delete the items.</TT><TT></TT>
<P><TT>Examining the KTabListBox::insertItem() code (ktablistbox.cpp
- revision 1.52) shows that it calls KTabListBox::changeItem(), which contains
the following code:</TT><TT></TT>
<P><TT>void KTabListBox::changeItem(const QString& aStr, int row)</TT>
<BR><TT>{</TT>
<BR><TT> char sepStr[2];</TT><TT></TT>
<P><TT> if (row < 0 || row >= numRows()) return;</TT><TT></TT>
<P><TT> char *str = qstrdup(aStr.local8Bit()); // TODO: make it really
QString using</TT><TT></TT>
<P><TT> sepStr[0] = sepChar;</TT>
<BR><TT> sepStr[1] = '\0';</TT><TT></TT>
<P><TT> KTabListBoxItem* item = itemList[row];</TT>
<BR><TT> char *pos = strtok(str, sepStr);</TT>
<BR><TT>//</TT>
<BR><TT>// key line follows ---||||</TT>
<BR><TT>//
VVVV</TT>
<BR><TT> for (int i=0; pos && *pos && i<numCols();
i++)</TT>
<BR><TT> {</TT>
<BR><TT> item->setText(i, QString::fromLocal8Bit(pos));</TT>
<BR><TT> pos = strtok(0L, sepStr);</TT>
<BR><TT> }</TT>
<BR><TT> item->setForeground(black);</TT><TT></TT>
<P><TT> if (needsUpdate(row)) lbox.repaint();</TT>
<BR><TT> delete [] str;</TT>
<BR><TT>}</TT>
<BR><TT></TT> <TT></TT>
<P><TT>The "*pos" of the for-loop will terminate without setting the "comment"
field (last column of row) since it was parsed out of aStr using strtok()
which returned a pointer to a null string. That is, the body of the
for-loop was not executed.</TT><TT></TT>
<P><TT>A work around for me is to set the "comment" variable to " " (single
space) rather than the null string "". However, this is not \
desireable.</TT><TT></TT>
<P><TT>POSSIBLE FIXES:</TT>
<BR><TT>===============</TT>
<BR><TT>(1) remove "*pos" from conditional check of for-loop. However,
will passing a null string to setText() cause a problem?</TT>
<BR><TT>(2) change KTabListBox::clear() to set the string in the "item"
to a null string rather than just marking it as a "-2".</TT>
<BR><TT>(3) catch the null string in the body of the for-loop and do something
special to free the memory for the column.</TT></HTML>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic