void MusicSongsListWidget::selectRow(int index)
{
    if(index < 0)
    {
        return;
    }
    QTableWidget::selectRow(index);

    replacePlayWidgetRow();
    delete takeItem(index, 0);
    delete takeItem(index, 1);
    delete takeItem(index, 2);
    setItem(index, 0, new QTableWidgetItem);
    setItem(index, 1, new QTableWidgetItem);
    setItem(index, 2, new QTableWidgetItem);

    QString name = !m_musicSongs->isEmpty() ? m_musicSongs->at(index).getMusicName() : QString();
    QString path = !m_musicSongs->isEmpty() ? m_musicSongs->at(index).getMusicPath() : QString();

    m_musicSongsPlayWidget = new MusicSongsListPlayWidget(index, this);
    m_musicSongsPlayWidget->setParameter(name, path);
    QWidget *widget, *widget1;
    m_musicSongsPlayWidget->getWidget(widget, widget1);

    setCellWidget(index, 0, widget);
    setCellWidget(index, 1, m_musicSongsPlayWidget);
    setCellWidget(index, 2, widget1);
    setRowHeight(index, 60);
    m_playRowIndex = index;
}
void MusicSongsListWidget::replacePlayWidgetRow()
{
    if(m_playRowIndex >= rowCount() || m_playRowIndex < 0)
    {
        m_playRowIndex = 0;
    }
    QString name = !m_musicSongs->isEmpty() ? m_musicSongs->at(m_playRowIndex).getMusicName() : QString();

    setRowHeight(m_playRowIndex, 30);
    removeCellWidget(m_playRowIndex, 0);
    removeCellWidget(m_playRowIndex, 1);
    removeCellWidget(m_playRowIndex, 2);

    delete takeItem(m_playRowIndex, 0);
    delete takeItem(m_playRowIndex, 1);
    delete takeItem(m_playRowIndex, 2);
    QTableWidgetItem *item = new QTableWidgetItem;
    setItem(m_playRowIndex, 0, item);
    item = new QTableWidgetItem(QFontMetrics(font()).elidedText(name, Qt::ElideRight, 242));
    item->setTextColor(QColor(50, 50, 50));
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    setItem(m_playRowIndex, 1, item);
    item = new QTableWidgetItem( (*m_musicSongs)[m_playRowIndex].getMusicTime() );
    item->setTextColor(QColor(50, 50, 50));
    item->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    setItem(m_playRowIndex, 2, item);
    delete m_musicSongsPlayWidget;
    m_musicSongsPlayWidget = nullptr;
}
Example #3
0
void pc_record_type::dropItem(short item_num, location where_drop)
{
	short choice, how_many = 0;
	item_record_type item_store;
	bool take_given_item = true;
	location loc;

	item_store = items[item_num];

	if ((equip[item_num] == true) && (items[item_num].isCursed()))
			add_string_to_buf("Drop: Item is cursed.           ");
	else switch (overall_mode) {
		case 0:
			choice = fancy_choice_dialog(1093,0);
			if (choice == 1)
				return;
			add_string_to_buf("Drop: OK");
			if ((item_store.type_flag > 0) && (item_store.charges > 1)) {
				how_many = get_num_of_items(item_store.charges);
				if (how_many == item_store.charges)
					takeItem(item_num);
					else items[item_num].charges -= how_many;
				}
				else takeItem(item_num);
			break;

		case 5: case 15:
			loc = where_drop;
			if ((item_store.type_flag > 0) && (item_store.charges > 1)) {
				how_many = get_num_of_items(item_store.charges);
				if (how_many <= 0)
					return;
				if (how_many < item_store.charges)
					take_given_item = false;
				item_store.charges = how_many;
				}
			if (is_container(loc) == true)
				item_store.item_properties = item_store.item_properties | 8;
			if (place_item(item_store,loc,false) == false) {
				add_string_to_buf("Drop: Too many items on ground");
				item_store.item_properties = item_store.item_properties & 247; // not contained
				}
				else {
					if (item_store.isContained())
						add_string_to_buf("Drop: Item put away");
						else add_string_to_buf("Drop: OK");
					items[item_num].charges -= how_many;
					if (take_given_item) takeItem(item_num);
					}
			break;
		}
}
void PartsBinListView::removeParts() {
	m_hoverItem = NULL;
    m_itemBaseHash.clear();
    while (count() > 0) {
        delete takeItem(0);
    }
}
/****************************************************************************
**
** Copyright (C) 2015
**
** This file is generated by the Magus toolkit
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
****************************************************************************/

// Include
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QDir>
#include <QImageReader>
#include <QListWidgetItem>
#include <QProcess>
#include "magus_core.h"
#include "tool_extended_texturewidget.h"

namespace Magus
{
    //****************************************************************************/
    QtTextureAndText::QtTextureAndText(const QPixmap& pixmap,
                                       const QString& name,
                                       const QString& baseName,
                                       const QSize& size,
                                       QWidget* parent) : QWidget(parent)
    {
        setContentsMargins(-8, -8, -8, -8);
        QHBoxLayout* mainLayout = new QHBoxLayout;
        QVBoxLayout* sphereAndNameLayout = new QVBoxLayout;
        mName = name;
        mBaseName = baseName;
        mSphereWidget = new QtGLSphereWidget(this);
        mSphereWidget->setPixmap(pixmap, name, baseName);
        mBaseNameEdit = new QLineEdit;
        mBaseNameEdit->setText(mBaseName);
        mBaseNameEdit->setEnabled(false);
        connect(mSphereWidget, SIGNAL(selected(QString,QString)), this, SLOT(handleSelected(QString,QString)));
        connect(mSphereWidget, SIGNAL(doubleClicked(QString,QString)), this, SLOT(handleDoubleClicked(QString,QString)));
        setMouseTracking(true);

        // Layout
        sphereAndNameLayout->addWidget(mSphereWidget, 1000);
        sphereAndNameLayout->addWidget(mBaseNameEdit, 1);
        mainLayout->addLayout(sphereAndNameLayout);
        setLayout(mainLayout);
        setMinimumSize(size);
        setMaximumSize(size);
    }

    //****************************************************************************/
    QtTextureAndText::~QtTextureAndText(void)
    {
    }

    //****************************************************************************/
    void QtTextureAndText::handleSelected(const QString& name, const QString& baseName)
    {
        emit selected(name, baseName);
    }

    //****************************************************************************/
    void QtTextureAndText::handleDoubleClicked(const QString& name, const QString& baseName)
    {
        emit doubleClicked(name, baseName);
    }

    //****************************************************************************/
    //****************************************************************************/
    //****************************************************************************/
    QtExtendedTextureListWidget::QtExtendedTextureListWidget(QWidget* parent) : QListWidget(parent)
    {
        setMouseTracking(true);
        setAcceptDrops(true);
        setDropIndicatorShown(true);
    }

    //****************************************************************************/
    QtExtendedTextureListWidget::~QtExtendedTextureListWidget(void)
    {
    }

    //****************************************************************************/
    void QtExtendedTextureListWidget::keyPressEvent(QKeyEvent* event)
    {
        switch (event->key())
        {
            case Qt::Key_Delete:
            {
                if (count() > 0)
                {
                    QListWidgetItem* item = currentItem();
                    if (item)
                    {
                        QWidget* widget = itemWidget(item);
                        if (widget)
                        {
                            int r = row(item);
                            QtTextureAndText* textureAndText = static_cast<QtTextureAndText*>(widget);
                            QString name = textureAndText->mName;
                            QString baseName = textureAndText->mBaseName;
                            removeItemWidget(item);
                            takeItem(r);
                            emit assetDeleted(name, baseName);
                        }
                    }
                }
            }
            break;
        }

        event->accept();
    }
// move selected item one place up in the list
// -----------------------------------------------------------------------------
void TTAudioListView::itemUp()
{
  if ( !currentItem() )
    return;

  TTAudioListItem* above   = (TTAudioListItem*)currentItem()->itemAbove();
  TTAudioListItem* current = (TTAudioListItem*)currentItem();

  if ( above )
  {
    takeItem( above );
    TTAudioListItem* listItem = new TTAudioListItem( this, current);

    listItem->audioFileInfo = above->audioFileInfo;
    listItem->audioFileName = above->audioFileName;
    listItem->audioLength   = above->audioLength;
    listItem->version       = above->version;
    listItem->bitRate       = above->bitRate;
    listItem->sampleRate    = above->sampleRate;
    listItem->channelMode   = above->channelMode;
    listItem->delay         = above->delay;
    listItem->audio_stream  = above->audio_stream;

    listItem->setText( 0, listItem->audioFileName );
    listItem->setText( 1, listItem->audioLength );
    listItem->setText( 2, listItem->version );
    listItem->setText( 3, listItem->bitRate );
    listItem->setText( 4, listItem->sampleRate );
    listItem->setText( 5, listItem->channelMode );
    listItem->setText( 6, listItem->delay );

    delete above;
  }
}
Example #7
0
//-----------------------------------------------------------------------------
//!
//-----------------------------------------------------------------------------
void tAbstractChannelTable::ScrollDown()
{
    TRACE_FUNCTION;
    // Items from rows i+1 are moved to row i, with 0 <= i < TableSize-1
    // Items for Row TableSize-1 (last row) are created 

    tCircularIndex iArt(*m_pIndex);

    for (int iRow = 0; iRow < m_NumberOfRows - 1; iRow++)
    {
        for (int iCol = 0; iCol < m_NumberOfColumns; iCol++)
        {
            // The next row becomes the current row
            if (iCol == m_ArtColumn)
            {
                int j = (++iArt).AsInt();
                setCellWidget(iRow, iCol, GetArtLabel(j, iRow));
            }
            else
            {
                setItem(iRow, iCol, takeItem(iRow + 1, iCol));
            }
        }
    }

    // Populate the last row with new data
    tCircularIndex iFrom(++*m_pIndex);
    iFrom += m_NumberOfRows-1;

    CopyRecordToRow(iFrom.AsInt(), m_NumberOfRows - 1);

    //resizeColumnsToContents();

    emit NewFocusRow(GetFocusRow());
}
Example #8
0
//-----------------------------------------------------------------------------
//!
//-----------------------------------------------------------------------------
void tAbstractChannelTable::ScrollUp()
{
    TRACE_FUNCTION;
    // Row i takes the items from row i-1, with 1 <= i < TableSize-1
    // Items for Row 0 (first row) are created 
    // MUST scan from bottom up, otherwise takeItem will take it away!
    tCircularIndex iArt(*m_pIndex);

    iArt += m_NumberOfRows - 1; // Point to the last data record 

    for (int iRow = m_NumberOfRows - 1; iRow >= 1; iRow--)
    {
        for (int iCol = 0; iCol < m_NumberOfColumns; iCol++)
        {
            // The previous row becomes the current row
            if (iCol == m_ArtColumn)
            {
                int j = (--iArt).AsInt();
                setCellWidget(iRow, iCol, GetArtLabel(j, iRow));
            }
            else
            {
                setItem(iRow, iCol, takeItem(iRow - 1, iCol));
            }
        }
    }

    // Populate the first row with new data
    tCircularIndex iFrom(--*m_pIndex);

    CopyRecordToRow(iFrom.AsInt(), 0);
    //resizeColumnsToContents();
    
    emit NewFocusRow(GetFocusRow());
}
Example #9
0
void ContactListWidget::del_contact()
{
QMessageBox mbx;
mbx.setText(QString(tr("Are you sure you want to remove user \"%1\" from your contact list?")).arg(currentItem()->text()));
mbx.setIcon(QMessageBox::Question);
mbx.addButton(QMessageBox::Yes);
mbx.addButton(QMessageBox::No);
mbx.setDefaultButton(QMessageBox::No);

if (QMessageBox::Yes==mbx.exec())
    {
        QByteArray rm_id;
        QListWidgetItem *rm_ptr;

        storage->Delete(rm_id = wgitem_to_recs[currentItem()]->id);
        delete (rm_ptr=takeItem(currentRow()));

        for(int i=0;i<contact_records.size();i++)
        {
            if (contact_records[i].id==rm_id)
            {
                contact_records.removeAt(i);
                break;
            }
        }

        wgitem_to_recs.remove(rm_ptr);
    }

}
Example #10
0
void pc_record_type::combineThings()
{
	int i,j,test;

	for (i = 0; i < 24; i++) {
		if ((items[i].variety > ITEM_TYPE_NO_ITEM) && (items[i].type_flag > 0) && (items[i].isIdent()))
			{
			for (j = i + 1; j < 24; j++)
				if ((items[j].variety > ITEM_TYPE_NO_ITEM) && (items[j].type_flag == items[i].type_flag) && (items[j].isIdent()))
				 {
					add_string_to_buf("(items combined)");
					test = items[i].charges + items[j].charges;
					if (test > 125) {
						items[i].charges = 125;
						ASB("(Can have at most 125 of any item.");
						}
				 		else items[i].charges += items[j].charges;
				 	if (equip[j] == true) {
				 		equip[i] = true;
				 		equip[j] = false;
				 		}
					takeItem(30 + j);
				}
			}
		if ((items[i].variety > ITEM_TYPE_NO_ITEM) && (items[i].charges < 0))
			items[i].charges = 1;
		}
}
Example #11
0
// move an item one position down
void UserMenuTree::itemDown()
{
	QTreeWidgetItem *current = currentItem();
	bool expanded = current->isExpanded();
	blockSignals(true);

	// get all necessary parameter
	UserMenuItem *parent = dynamic_cast<UserMenuItem *>(current->parent());
	int index = itemIndex(parent,current);
	int children = numChildren(parent);

	// successor exists?
	if ( index < children-1 ) {
		UserMenuItem *successor = dynamic_cast<UserMenuItem *>( itemAtIndex(parent,index+1) );
		takeItem(parent,current);
		if ( successor->menutype() == UserMenuData::Submenu ) {
			successor->insertChild(0,current);
		}
		else {
			insertItem(parent,index+1,current);
		}
	}
	else if ( parent ) {
			QTreeWidgetItem *grandparent = parent->parent();
			int parentindex = itemIndex(grandparent,parent);
			takeItem(parent,current);
			insertItem(grandparent,parentindex+1,current);
	}

	// update model data of old and new parent, if it has changed
	UserMenuItem *newparent = dynamic_cast<UserMenuItem *>(current->parent());
	if ( parent != newparent ) {
		if ( parent ) {
			parent->setModelData();
			parent->setText(0, parent->updateMenutitle());
		}
		if ( newparent ) {
			newparent->setModelData();
			newparent->setText(0, newparent->updateMenutitle());
		}
	}

	current->setExpanded(expanded);
	setCurrentItem(current);
	blockSignals(false);
}
void PartsBinListView::removePart(const QString &moduleID) {
	m_hoverItem = NULL;
	int idxToRemove = position(moduleID);
	if(idxToRemove > -1) {
		m_itemBaseHash.remove(moduleID);
		delete takeItem(idxToRemove);
	}
}
Example #13
0
void SessionListWidget::onRemoveSession(QObject *obj)
{
	Q_D(SessionListWidget);
	ChatSessionImpl *s = reinterpret_cast<ChatSessionImpl*>(obj);
	int index = d->sessions.indexOf(s);
	d->sessions.removeAll(s);	
	delete takeItem(index);
}
Example #14
0
void AclWidget::removeSelectedAddresses()
{
  QList<QListWidgetItem *> selected = selectedItems();
  for (QList<QListWidgetItem *>::iterator iter = selected.begin(); iter != selected.end(); ++iter)
  {
    delete takeItem(row(*iter));
  }
}
Example #15
0
int SP_NKStringList :: remove( int index )
{
    char * item = takeItem( index );

    if( NULL != item ) free( item );

    return NULL == item ? -1 : 0;
}
Example #16
0
void MessagesWidget::showItem( QListWidgetItem *item ) {
	addItem( item );
	scrollToItem( item );

	if ( maximumItemCount_.has_value() ) {
		while ( count() > *maximumItemCount_ )
			delete takeItem( 0 );
	}
}
/** Move the selected track downward. */
void Playlist::moveTrackDown()
{
	if (currentItem()) {
		int currentRow = currentItem()->row();
		if (currentRow < rowCount()-1) {
			for (int c=0; c < columnCount(); c++) {
				QTableWidgetItem *currentItem = takeItem(currentRow, c);
				QTableWidgetItem *nextItem = takeItem(currentRow+1, c);
				setItem(currentRow, c, nextItem);
				setItem(currentRow+1, c, currentItem);
			}
			sources.swap(currentRow, currentRow+1);
			this->setCurrentIndex(model()->index(currentRow+1, 0));
			if (currentRow == track) {
				track++;
			}
		}
	}
}
/** Move the selected track upward. */
void Playlist::moveTrackUp()
{
	if (currentItem()) {
		int currentRow = currentItem()->row();
		if (currentRow > 0) {
			for (int c=0; c < columnCount(); c++) {
				QTableWidgetItem *currentItem = takeItem(currentRow, c);
				QTableWidgetItem *previousItem = takeItem(currentRow-1, c);
				setItem(currentRow, c, previousItem);
				setItem(currentRow-1, c, currentItem);
			}
			sources.swap(currentRow, currentRow-1);
			setCurrentIndex(model()->index(currentRow-1, 0));
			if (currentRow == track) {
				track--;
			}
		}
	}
}
Example #19
0
void MessagesModel::showItem(const QList<QStandardItem *> items ) {
	QList<QStandardItem *> rowItems;

	appendRow( items );

	if ( maximumItemCount_.has_value() ) {
		while ( rowCount() > *maximumItemCount_ )
			delete takeItem( 0 );
	}
}
void WatchListView::addWatch(Variable* var) {
  QListViewItem* item =
    findItem(var->name(), VariablesListView::NameCol);

  if(item) {
    takeItem(item);
    delete item;
  }
  addVariable(var);
}
void BreakpointListView::slotBreakpointUnmarked(QString filePath, int line) {
  //note: TextEditor lines are 0 based
  BreakpointListViewItem*  item = findBreakpoint(filePath, line+1);

  if(item) {
   takeItem(item);
  }
  emit sigBreakpointRemoved(item->breakpoint());
  delete item;
}
void BreakpointListView::removeBreakpoint(DebuggerBreakpoint* bp)
{
  BreakpointListViewItem*  item = findBreakpoint(bp);

  if(item) {
   takeItem(item);
  }
  emit sigBreakpointRemoved(bp);
  delete item;
}
Example #23
0
void TableWidget::cut(){
    QModelIndexList indexes = this->selectedIndexes();
    for(int i=0;i<indexes.size();i++){
        QList<TableWidgetItem*> row_;
        for(int j=0;this->columnCount();j++){
            row_.append(static_cast<TableWidgetItem*>(takeItem(indexes[i].row(),j)));
        }
        this->removeRow(indexes[i].row());
        cutRows_.append(row_);
    }
}
Example #24
0
void TableWidget::insertBlankRow(){

    int ind = currentRow()+1;
    if(ind==-1){
        return;
    }
    bool enabled = isSortingEnabled();
    setSortingEnabled(false);
    int n = rowCount();
    //QList<int> inds;inds<<0<<1<<2<<5;
    QAction *action = qobject_cast<QAction *>(sender());
    ColumnType t = static_cast<ColumnType>(action->data().toInt());
    QList<int> inds;
    if(t==ORIGIN){
        inds = originCols_;
        qDebug()<<"origin columns";
    }else if(t==RESULT){
        qDebug()<<"result columns";
        inds = resultCols_;
    }else{
        QMessageBox::critical(this,"","Bug, unknown columntype in TableWidget::insertBlankRow");
        return;
    }

    for(int i=0;i<inds.size();i++){
        int col = inds[i];
        QList<TableWidgetItem*> tmp;
        for(int row=ind;row<n;row++){
            tmp << (TableWidgetItem*)takeItem( row, col );
        }
        int row = ind+1;
        for(int j=0;j<tmp.size();j++){
            if(row>=rowCount()){
                setRowCount(row+1);
                setNonEditable( row+1, row+1 );
            }
            setItem( row, col, tmp.at(j) );
            //qDebug()<<i<<j;
            row++;
        }
        //blank item
        TableWidgetItem *newItem = new TableWidgetItem;
        newItem->setFlags( newItem->flags() &= ~Qt::ItemIsEditable );
        setItem( ind, col, newItem );
    }
    setSortingEnabled(enabled);
    //nFiles=nFiles+1;

    for(int i=0;i<rowCount();i++){
        item(i,CURRENT_TITLE)->setFlags( item(i,CURRENT_TITLE)->flags() &= ~Qt::ItemIsEditable );
        item(i,CURRENT_TITLE)->setFlags( item(i,CURRENT_TITLE)->flags() &= ~Qt::ItemIsEditable );
    }

}
Example #25
0
void AclWidget::removeAddress(const QString &address)
{
  for (int i = 0; i < count(); ++i)
  {
    if (item(i)->text() == address)
    {
      delete takeItem(i);
      break;
    }
  }
}
Example #26
0
void UsersList::updateOnline( const QStringList & users, const QStringList & hosts)
{
//printf("UsersList::updateOnline:\n");for( int i = 0; i < users.size(); i++) printf("%s\n", users[i].toUtf8().data());
   for( int i = 0; i < count(); i++)
      if( false == users.contains( item(i)->text()))
         delete takeItem(i);

   for( int i = 0; i < users.size(); i++)
      if( findItems( users[i], Qt::MatchExactly).empty()) addItem( users[i]);

   selectOwner();
}
Example #27
0
int SP_NKSmtpAddrList :: deleteItem( int index )
{
	int ret = -1;

	SP_NKSmtpAddr * addr = takeItem( index );
	if( NULL != addr ) {
		ret = 0;
		delete addr;
	}

	return ret;
}
Example #28
0
void pc_record_type::removeCharge(short which_item)
{
	if (items[which_item].charges > 0)
	{
		items[which_item].charges--;
		if (items[which_item].charges == 0) takeItem(which_item);
	}

	if (stat_window == getNum())
		put_item_screen(stat_window,1);

}
Example #29
0
void KCompletionBox::setItems( const QStringList& items )
{
    bool block = signalsBlocked();
    blockSignals( true );

    int rowIndex = 0;

    if (!count()) {
        addItems(items);
    } else {
        // Keep track of whether we need to change anything,
        // so we can avoid a repaint for identical updates,
        // to reduce flicker
        bool dirty = false;

        QStringList::ConstIterator it = items.constBegin();
        const QStringList::ConstIterator itEnd = items.constEnd();

        for ( ; it != itEnd; ++it) {
            if ( rowIndex < count() ) {
                const bool changed = ((KCompletionBoxItem*)item(rowIndex))->reuse( *it );
                dirty = dirty || changed;
            } else {
                dirty = true;
                // Inserting an item is a way of making this dirty
                addItem(*it);
            }
            rowIndex++;
        }

        // If there is an unused item, mark as dirty -> less items now
        if (rowIndex < count()) {
            dirty = true;
        }

        // remove unused items with an index >= rowIndex
        for ( ; rowIndex < count() ; ) {
            QListWidgetItem* item = takeItem(rowIndex);
            Q_ASSERT(item);
            delete item;
        }

        //TODO KDE4 : Port me
        //if (dirty)
        //    triggerUpdate( false );
    }

    if (isVisible() && size().height() != sizeHint().height())
        sizeAndPosition();

    blockSignals(block);
}
Example #30
0
void LogListWidget::appendLine(const QString &line)
{
  QListWidgetItem *item = new QListWidgetItem;
  // We need to use QLabel here to support rich text
  QLabel *lbl = new QLabel(line);
  lbl->setContentsMargins(4, 2, 4, 2);
  item->setSizeHint(lbl->sizeHint());
  insertItem(0, item);
  setItemWidget(item, lbl);
  const int nbLines = count();
  // Limit log size
  if (nbLines > m_maxLines)
    delete takeItem(nbLines - 1);
}