From c601b5a27f74b16158adafe429faefbe573e64a2 Mon Sep 17 00:00:00 2001 From: Szymon Tomasz Stefanek Date: Sat, 1 Jan 2011 20:19:56 +0000 Subject: The big rename for modules. Still some details remaining. git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@5284 17fca916-40b9-46aa-a4ea-0a15b648b75c --- src/modules/list/ListWindow.cpp | 590 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 590 insertions(+) create mode 100644 src/modules/list/ListWindow.cpp (limited to 'src/modules/list/ListWindow.cpp') diff --git a/src/modules/list/ListWindow.cpp b/src/modules/list/ListWindow.cpp new file mode 100644 index 000000000..3e596cb3c --- /dev/null +++ b/src/modules/list/ListWindow.cpp @@ -0,0 +1,590 @@ +//============================================================================= +// +// File : ListWindow.cpp +// Creation date : Thu Oct 7 2001 13:27:55 CEST by Szymon Stefanek +// +// This file is part of the KVIrc irc client distribution +// Copyright (C) 2001-2010 Szymon Stefanek (pragma at kvirc dot net) +// +// This program is FREE software. You can redistribute it and/or +// modify it under the lists of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your opinion) any later version. +// +// This program is distributed in the HOPE that it will be USEFUL, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, write to the Free Software Foundation, +// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +//============================================================================= + +#include "ListWindow.h" + +#include "kvi_debug.h" +#include "KviIconManager.h" +#include "KviIrcView.h" +#include "kvi_out.h" +#include "KviOptions.h" +#include "KviLocale.h" +#include "kvi_out.h" +#include "KviMircCntrl.h" +#include "KviThemedLabel.h" +#include "KviOptions.h" +#include "KviIrcConnection.h" +#include "KviIrcConnection.h" +#include "KviQString.h" +#include "KviTopicWidget.h" +#include "KviConfigurationFile.h" +#include "KviFileDialog.h" +#include "KviMessageBox.h" +#include "kvi_fileextensions.h" +#include "KviTalHBox.h" +#include "KviHtmlGenerator.h" +#include "KviThemedLineEdit.h" + +#include +#include +#include +#include +#include +#include +#include // for Qt::escape + +extern KviPointerList * g_pListWindowList; + +ChannelTreeWidgetItemData::ChannelTreeWidgetItemData(const QString & szChan, const QString & szUsers, const QString & szTopic) +{ + m_szChan = szChan; + m_szUsers = szUsers; + m_szTopic = szTopic; +} + +ChannelTreeWidgetItemData::~ChannelTreeWidgetItemData() +{ +} + + +ChannelTreeWidgetItem::ChannelTreeWidgetItem(QTreeWidget * v,ChannelTreeWidgetItemData * pData) +: QTreeWidgetItem(v), m_pData(pData) +{ + setToolTip(0, m_pData->m_szChan); + setToolTip(1, m_pData->m_szUsers); + setToolTip(2, KviHtmlGenerator::convertToHtml(Qt::escape(m_pData->m_szTopic))); +} + +ChannelTreeWidgetItem::~ChannelTreeWidgetItem() +{ +} + +int ChannelTreeWidgetItem::width(const QFontMetrics & fm, const QTreeWidget *, int iColumn) const +{ + switch(iColumn) + { + case 0: + //channel + return fm.width(m_pData->m_szChan); + break; + case 1: + //users + return fm.width(m_pData->m_szUsers.toInt()); + break; + case 2: + default: + //topic + return fm.width(KviMircCntrl::stripControlBytes(m_pData->m_szTopic)); + break; + } +} + +bool ChannelTreeWidgetItem::operator<(const QTreeWidgetItem & other) const +{ + switch(treeWidget()->sortColumn()) + { + case 0: + //channel + return m_pData->m_szChan.toUpper() < ((ChannelTreeWidgetItem*)&other)->itemData()->m_szChan.toUpper(); + break; + case 1: + //users + return m_pData->m_szUsers.toInt() < ((ChannelTreeWidgetItem*)&other)->itemData()->m_szUsers.toInt(); + break; + case 2: + default: + //topic + return KviMircCntrl::stripControlBytes(m_pData->m_szTopic.toUpper()) < KviMircCntrl::stripControlBytes(((ChannelTreeWidgetItem*)&other)->itemData()->m_szTopic.toUpper()); + break; + } +} + +ChannelTreeWidgetItemDelegate::ChannelTreeWidgetItemDelegate(QTreeWidget * pWidget) +: QItemDelegate(pWidget) +{ +} + +ChannelTreeWidgetItemDelegate::~ChannelTreeWidgetItemDelegate() +{ +} + +void ChannelTreeWidgetItemDelegate::paint(QPainter * p, const QStyleOptionViewItem & option, const QModelIndex & index) const +{ + ChannelTreeWidgetItem* obj = static_cast(index.internalPointer()); + + if (option.state & QStyle::State_Selected) + p->fillRect(option.rect, option.palette.brush( QPalette::Highlight ) ); + + //reset the color + p->setPen(option.palette.text().color()); + + switch(index.column()) + { + case 0: + //channel + p->drawText(option.rect, obj->itemData()->m_szChan); + break; + case 1: + //users + p->drawText(option.rect, Qt::AlignHCenter, obj->itemData()->m_szUsers); + break; + case 2: + default: + //topic + KviTopicWidget::paintColoredText(p,obj->itemData()->m_szTopic,option.palette,option.rect); + break; + } +} + +ListWindow::ListWindow(KviMainWindow * lpFrm, KviConsoleWindow * lpConsole) +: KviWindow(KVI_WINDOW_TYPE_LIST,lpFrm,"list",lpConsole), KviExternalServerDataParser() +{ + g_pListWindowList->append(this); + + m_pFlushTimer = 0; + + m_pItemList = new KviPointerList; + m_pItemList->setAutoDelete(false); + + m_pSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pSplitter->setObjectName("splitter"); + m_pSplitter->setChildrenCollapsible(false); + m_pTopSplitter = new KviTalSplitter(Qt::Horizontal,this); + m_pTopSplitter->setObjectName("top_splitter"); + m_pTopSplitter->setChildrenCollapsible(false); + m_pVertSplitter = new KviTalSplitter(Qt::Vertical,m_pSplitter); + m_pVertSplitter->setObjectName("vsplitter"); + m_pVertSplitter->setChildrenCollapsible(false); + + KviTalHBox * pBox = new KviTalHBox(m_pTopSplitter); + pBox->setSpacing(1); + pBox->setMargin(0); + + m_pOpenButton = new QToolButton(pBox); + m_pOpenButton->setObjectName("import_list"); + m_pOpenButton->setIconSize(QSize(16,16)); + m_pOpenButton->setIcon(QIcon(*(g_pIconManager->getBigIcon(KVI_BIGICON_OPEN)))); + KviTalToolTip::add(m_pOpenButton,__tr2qs("Import List")); + connect(m_pOpenButton,SIGNAL(clicked()),this,SLOT(importList())); + + m_pSaveButton = new QToolButton(pBox); + m_pSaveButton->setObjectName("export_list"); + m_pSaveButton->setIconSize(QSize(16,16)); + m_pSaveButton->setIcon(QIcon(*(g_pIconManager->getBigIcon(KVI_BIGICON_SAVE)))); + KviTalToolTip::add(m_pSaveButton,__tr2qs("Export List")); + connect(m_pSaveButton,SIGNAL(clicked()),this,SLOT(exportList())); + + m_pRequestButton = new QToolButton(pBox); + m_pRequestButton->setObjectName("request_button"); + m_pRequestButton->setIconSize(QSize(16,16)); + m_pRequestButton->setIcon(QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_LIST)))); + KviTalToolTip::add(m_pRequestButton,__tr2qs("Request List")); + connect(m_pRequestButton,SIGNAL(clicked()),this,SLOT(requestList())); + + m_pStopListDownloadButton = new QToolButton(pBox); + m_pStopListDownloadButton->setObjectName("stoplistdownload_button"); + m_pStopListDownloadButton->setIconSize(QSize(16,16)); + m_pStopListDownloadButton->setIcon(QIcon(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_NICKNAMEPROBLEM)))); + KviTalToolTip::add(m_pStopListDownloadButton,__tr2qs("Stop list download")); + connect(m_pStopListDownloadButton,SIGNAL(clicked()),this,SLOT(stoplistdownload())); + + m_pParamsEdit = new KviThemedLineEdit(pBox, this, "lineedit"); + pBox->setStretchFactor(m_pParamsEdit,1); + KviTalToolTip::add(m_pParamsEdit,__tr2qs("
/LIST command parameters:
Many servers accept special parameters that " \ + "allow you to filter the returned entries.
" \ + "Commonly, masked channel names (*kvirc*) are accepted as parameters, as well as strings " \ + "like c<n or c>n where n is the minimum or maximum of users on the channel.
")); + + connect(m_pParamsEdit,SIGNAL(textEdited(const QString &)),this,SLOT(liveSearch(const QString &))); + + m_pInfoLabel = new KviThemedLabel(m_pTopSplitter, this, "info_label"); + + m_pTreeWidget = new KviThemedTreeWidget(m_pVertSplitter, this, "list_treewidget"); + m_pTreeWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + m_pTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection); + m_pTreeWidget->setItemDelegate(new ChannelTreeWidgetItemDelegate(m_pTreeWidget)); + QStringList columnLabels; + columnLabels.append(__tr2qs("Channel")); + columnLabels.append(__tr2qs("Users")); + columnLabels.append(__tr2qs("Topic")); + m_pTreeWidget->setColumnCount(3); + m_pTreeWidget->setHeaderLabels(columnLabels); + m_pTreeWidget->setAllColumnsShowFocus(TRUE); + m_pTreeWidget->setSortingEnabled(TRUE); + m_pTreeWidget->sortItems(0,Qt::AscendingOrder); + connect(m_pTreeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),this,SLOT(itemDoubleClicked(QTreeWidgetItem *, int))); + + m_pIrcView = new KviIrcView(m_pVertSplitter,lpFrm,this); + + m_pConsole->context()->setListWindowPointer(this); + connect(m_pConsole->context(),SIGNAL(stateChanged()),this,SLOT(connectionStateChange())); + + connectionStateChange(); +} + +ListWindow::~ListWindow() +{ + g_pListWindowList->removeRef(this); + m_pConsole->context()->setListWindowPointer(0); + + if(m_pFlushTimer) + delete m_pFlushTimer; + m_pItemList->setAutoDelete(true); + delete m_pItemList; +} + +void ListWindow::getBaseLogFileName(QString & szBuffer) +{ + szBuffer.sprintf("LIST_%d",context()->id()); +} + +void ListWindow::requestList() +{ + if(m_pConsole->isConnected()) + { + KviCString parms = m_pParamsEdit->text(); + if(parms.isEmpty()) + m_pConsole->connection()->sendFmtData("list"); + else + m_pConsole->connection()->sendFmtData("list %s",m_pConsole->connection()->encodeText(parms.ptr()).data()); + + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Sent list request, waiting for reply...")); + m_pRequestButton->setEnabled(false); + } else { + outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Cannot request list: No active connection")); + } +} + +void ListWindow::stoplistdownload() +{ + if(m_pConsole->isConnected()) + { + m_pConsole->connection()->sendFmtData("list stoplistdownloadnow"); + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Stopping the list download...")); //G&N mar 2005 + } else { + outputNoFmt(KVI_OUT_SYSTEMERROR,__tr2qs("Cannot stop list download, no active connection.")); + } +} + +void ListWindow::connectionStateChange() +{ + KviIrcContext::State st = m_pConsole->context()->state(); + m_pRequestButton->setEnabled(st == KviIrcContext::Connected); + if(st == KviIrcContext::Connected) + { + QString szTmp; + KviQString::sprintf(szTmp, + __tr2qs("Connected to %s (%s)"), + m_pConsole->connection()->currentServerName().toUtf8().data(), + m_pConsole->currentNetworkName().toUtf8().data()); + m_pInfoLabel->setText(szTmp); + } else { + m_pInfoLabel->setText(__tr2qs("List cannot be requested: Not connected to a server")); + } +} + +QPixmap * ListWindow::myIconPtr() +{ + return g_pIconManager->getSmallIcon(KVI_SMALLICON_LIST); +} + +void ListWindow::resizeEvent(QResizeEvent *) +{ + int iHeight = m_pTopSplitter->sizeHint().height(); + m_pTopSplitter->setGeometry(0,0,width(),iHeight); + m_pSplitter->setGeometry(0,iHeight,width(),height() - iHeight); +} + +QSize ListWindow::sizeHint() const +{ + return m_pSplitter->sizeHint(); +} + +void ListWindow::fillCaptionBuffers() +{ + KviQString::sprintf(m_szPlainTextCaption,__tr2qs("Channel List [IRC Context %u]"),m_pConsole->context()->id()); +} + +void ListWindow::die() +{ + close(); +} + +void ListWindow::exportList() +{ + if(!m_pTreeWidget->topLevelItemCount()) + { + KviMessageBox::warning(__tr2qs("You cannot export an empty list")); + return; + } + + QString szFile; + if(connection()) + { + QString szDate; + QDateTime date = QDateTime::currentDateTime(); + + switch(KVI_OPTION_UINT(KviOption_uintOutputDatetimeFormat)) + { + case 0: + szDate = date.toString("d MMM yyyy hh-mm"); + break; + case 1: + szDate = date.toString(Qt::ISODate); + break; + case 2: + szDate = date.toString(Qt::SystemLocaleDate); + break; + } + KviQString::sprintf(szFile,__tr2qs("Channel list for %Q - %Q"), + &(connection()->currentNetworkName()),&(szDate)); + } else { + szFile = __tr2qs("Channel list"); + } + + if(KviFileDialog::askForSaveFileName(szFile,__tr2qs("Choose filename"),szFile,__tr2qs("Configuration files (*.kvc)"),false,false,true,this)) + { + if(QFileInfo(szFile).completeSuffix() != "kvc") + szFile.append(".kvc"); + + KviConfigurationFile cfg(szFile,KviConfigurationFile::Write); + cfg.clear(); + + ChannelTreeWidgetItem * it; + for(int i=0; i < m_pTreeWidget->topLevelItemCount(); i++) + { + it = (ChannelTreeWidgetItem *)m_pTreeWidget->topLevelItem(i); + cfg.setGroup(it->itemData()->m_szChan); + // Write properties + cfg.writeEntry("topic",it->itemData()->m_szTopic); + cfg.writeEntry("users",it->itemData()->m_szUsers); + } + } +} + +void ListWindow::importList() +{ + QString szFile; + + if(KviFileDialog::askForOpenFileName(szFile,__tr2qs("Choose filename"),QString(),KVI_FILTER_CONFIG,false,false,this)) + { + + m_pItemList->setAutoDelete(true); + m_pItemList->clear(); + m_pItemList->setAutoDelete(false); + + m_pTreeWidget->clear(); + + + KviConfigurationFile cfg(szFile,KviConfigurationFile::Read); + KviConfigurationFileIterator it(*cfg.dict()); + while(it.current()) + { + cfg.setGroup(it.currentKey()); + m_pItemList->append( + new ChannelTreeWidgetItemData( + it.currentKey(), + cfg.readEntry("users","0"), + cfg.readEntry("topic","") + ) + ); + ++it; + } + flush(); + } +} + +void ListWindow::control(int iMsg) +{ + switch(iMsg) + { + case EXTERNAL_SERVER_DATA_PARSER_CONTROL_RESET: + reset(); + break; + case EXTERNAL_SERVER_DATA_PARSER_CONTROL_STARTOFDATA: + startOfList(); + break; + case EXTERNAL_SERVER_DATA_PARSER_CONTROL_ENDOFDATA: + endOfList(); + break; + } +} + +void ListWindow::reset() +{ + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Reset")); +} + +void ListWindow::endOfList() +{ + if(m_pFlushTimer) + { + delete m_pFlushTimer; + m_pFlushTimer = 0; + } + m_pRequestButton->setEnabled(true); + outputNoFmt(KVI_OUT_SYSTEMMESSAGE,__tr2qs("Channels list download finished")); + flush(); // give it the last kick +} + +void ListWindow::startOfList() +{ + m_pItemList->setAutoDelete(true); + m_pItemList->clear(); + m_pItemList->setAutoDelete(false); + + m_pTreeWidget->clear(); + + m_pRequestButton->setEnabled(false); +} + +void ListWindow::liveSearch(const QString & szText) +{ + QRegExp res(szText,Qt::CaseInsensitive,QRegExp::Wildcard); + + ChannelTreeWidgetItem * pItem=0; + for(int i=0; itopLevelItemCount(); i++) + { + pItem = (ChannelTreeWidgetItem*) m_pTreeWidget->topLevelItem(i); + if(pItem->itemData()->m_szChan.contains(res) || + pItem->itemData()->m_szTopic.contains(res)) + { + pItem->setHidden(false); + } else { + pItem->setHidden(true); + } + } +} + +void ListWindow::processData(KviIrcMessage * pMsg) +{ + if(!m_pFlushTimer) + { + m_pFlushTimer = new QTimer(this); + connect(m_pFlushTimer,SIGNAL(timeout()),this,SLOT(flush())); + m_pFlushTimer->start(1000); + m_pRequestButton->setEnabled(false); + } + + if(m_pParamsEdit->text().isEmpty()) + { + m_pItemList->append( + new ChannelTreeWidgetItemData( + pMsg->connection()->decodeText(pMsg->safeParam(1)), + pMsg->connection()->decodeText(pMsg->safeParam(2)), + pMsg->connection()->decodeText(pMsg->safeTrailing())) + ); + } else { + //rfc2812 permits wildcards here (section 3.2.6) + QRegExp res(m_pParamsEdit->text(),Qt::CaseInsensitive,QRegExp::Wildcard); + if( + res.exactMatch(pMsg->connection()->decodeText(pMsg->safeParam(1))) || + res.exactMatch(pMsg->connection()->decodeText(pMsg->safeTrailing())) + ) + { + m_pItemList->append( + new ChannelTreeWidgetItemData( + pMsg->connection()->decodeText(pMsg->safeParam(1)), + pMsg->connection()->decodeText(pMsg->safeParam(2)), + pMsg->connection()->decodeText(pMsg->safeTrailing()) + ) + ); + } + } + + if(_OUTPUT_VERBOSE) + { + QString szTmp = pMsg->connection()->decodeText(pMsg->allParams()); + output(KVI_OUT_LIST,__tr2qs("Processing list: %Q"),&szTmp); + } +} + +void ListWindow::flush() +{ + m_pTreeWidget->setUpdatesEnabled(true); /* for v_scroolbar */ + while(ChannelTreeWidgetItemData * d = m_pItemList->first()) + { + (void)new ChannelTreeWidgetItem(m_pTreeWidget,d); + m_pItemList->removeFirst(); + } + m_pTreeWidget->setUpdatesEnabled(true); + m_pTreeWidget->viewport()->update(); +} + +void ListWindow::itemDoubleClicked(QTreeWidgetItem * it, int) +{ + QString szText = ((ChannelTreeWidgetItem*)it)->itemData()->m_szChan; + + if(szText.isEmpty()) return; + if(!connection()) return; + + QByteArray dat = connection()->encodeText(szText); + if(!dat.data()) return; + + m_pConsole->connection()->sendFmtData("join %s",dat.data()); +} + + +// +//#warning "Load & save properties of this kind of window" + +//void ListWindow::saveProperties() +//{ +// KviWindowProperty p; +// p.rect = externalGeometry(); +// p.isDocked = isAttacched(); +// QValueList l(m_pSplitter->sizes()); +// if(l.count() >= 1)p.splitWidth1 = *(l.at(0)); +// if(l.count() >= 2)p.splitWidth2 = *(l.at(1)); +// p.timestamp = m_pView->timestamp(); +// p.imagesVisible = m_pView->imagesVisible(); +// p.isMaximized = isAttacched() && isMaximized(); +// p.topSplitWidth1 = 0; +// p.topSplitWidth2 = 0; +// p.topSplitWidth3 = 0; +// g_pOptions->m_pWinPropertiesList->setProperty(caption(),&p); +//} +// +//void ListWindow::setProperties(KviWindowProperty *p) +//{ +// QValueList l; +// l.append(p->splitWidth1); +// l.append(p->splitWidth2); +// m_pVertSplitter->setSizes(l); +// m_pIrcView->setTimestamp(p->timestamp); +// m_pIrcView->setShowImages(p->imagesVisible); +//} + +void ListWindow::applyOptions() +{ + m_pTreeWidget->applyOptions(); + m_pIrcView->applyOptions(); + m_pParamsEdit->applyOptions(); + m_pInfoLabel->applyOptions(); + KviWindow::applyOptions(); +} + +#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES +#include "ListWindow.moc" +#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES -- cgit v1.3.1-10-gc9f91