File indexing completed on 2023-10-01 08:01:43
0001 // Copyright (c) 2003-2004 Rob Kaper <cap@capsi.com> 0002 // 0003 // This library is free software; you can redistribute it and/or 0004 // modify it under the terms of the GNU Lesser General Public 0005 // License version 2.1 as published by the Free Software Foundation. 0006 // 0007 // This library is distributed in the hope that it will be useful, 0008 // but WITHOUT ANY WARRANTY; without even the implied warranty of 0009 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0010 // Lesser General Public License for more details. 0011 // 0012 // You should have received a copy of the GNU Lesser General Public License 0013 // along with this library; see the file COPYING.LIB. If not, write to 0014 // the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0015 // Boston, MA 02110-1301, USA. 0016 0017 #include <iostream> 0018 0019 #include <QLayout> 0020 #include <QDateTime> 0021 #include <QPixmap> 0022 #include <QVBoxLayout> 0023 #include <QHBoxLayout> 0024 #include <QTextStream> 0025 #include <QCloseEvent> 0026 #include <QTreeView> 0027 #include <QHeaderView> 0028 #include <QFileDialog> 0029 #include <QPushButton> 0030 #include <QDialogButtonBox> 0031 0032 #include <klocalizedstring.h> 0033 #include <kiconloader.h> 0034 #include <kguiitem.h> 0035 #include <ksharedconfig.h> 0036 #include <kwindowconfig.h> 0037 0038 #include "event.h" 0039 #include "eventlogwidget.h" 0040 0041 EventLog::EventLog(QObject *parent) 0042 : QAbstractItemModel(parent) 0043 { 0044 } 0045 0046 EventLog::~EventLog() 0047 { 0048 qDeleteAll(m_events); 0049 } 0050 0051 void EventLog::addEvent(const QString &description, EventType type) 0052 { 0053 const int oldCount = m_events.count(); 0054 beginInsertRows(QModelIndex(), oldCount, oldCount); 0055 Event *event = new Event(QDateTime::currentDateTime(), description, type); 0056 m_events.append(event); 0057 endInsertRows(); 0058 } 0059 0060 void EventLog::clear() 0061 { 0062 beginResetModel(); 0063 qDeleteAll(m_events); 0064 m_events.clear(); 0065 endResetModel(); 0066 } 0067 0068 void EventLog::saveAsText(QTextStream &stream) const 0069 { 0070 foreach (Event *e, m_events) 0071 stream << e->dateTime().toString(QStringLiteral("yyyy-MM-dd hh:mm:ss")) << " " << e->description() << '\n'; 0072 } 0073 0074 int EventLog::columnCount(const QModelIndex &parent) const 0075 { 0076 return parent.isValid() ? 0 : 2; 0077 } 0078 0079 QVariant EventLog::data(const QModelIndex &index, int role) const 0080 { 0081 if (!index.isValid() || index.row() < 0 || index.row() >= m_events.count() 0082 || index.column() < 0 || index.column() > 1) 0083 return QVariant(); 0084 0085 Event *e = static_cast<Event *>(index.internalPointer()); 0086 switch (index.column()) 0087 { 0088 case 0: 0089 if (role != Qt::DisplayRole) 0090 return QVariant(); 0091 return e->dateTime().toString(QStringLiteral("yyyy-MM-dd hh:mm:ss zzz")); 0092 case 1: 0093 switch (role) 0094 { 0095 case Qt::DecorationRole: 0096 return cachedIcon(e->type()); 0097 case Qt::DisplayRole: 0098 return e->description(); 0099 } 0100 break; 0101 } 0102 0103 return QVariant(); 0104 } 0105 0106 QVariant EventLog::headerData(int section, Qt::Orientation orientation, int role) const 0107 { 0108 if (orientation != Qt::Horizontal || role != Qt::DisplayRole 0109 || section < 0 || section > 1) 0110 return QVariant(); 0111 0112 switch (section) 0113 { 0114 case 0: 0115 return i18n("Date/Time"); 0116 case 1: 0117 return i18n("Description"); 0118 } 0119 return QVariant(); 0120 } 0121 0122 QModelIndex EventLog::index(int row, int column, const QModelIndex &parent) const 0123 { 0124 return parent.isValid() || row < 0 || row >= m_events.count() 0125 || column < 0 || column > 1 0126 ? QModelIndex() 0127 : createIndex(row, column, m_events.at(row)); 0128 } 0129 0130 QModelIndex EventLog::parent(const QModelIndex &) const 0131 { 0132 return QModelIndex(); 0133 } 0134 0135 int EventLog::rowCount(const QModelIndex &parent) const 0136 { 0137 return parent.isValid() ? 0 : m_events.count(); 0138 } 0139 0140 QIcon EventLog::cachedIcon(EventType type) const 0141 { 0142 if (!m_iconCache[type].isNull()) 0143 return m_iconCache[type]; 0144 0145 QString name; 0146 switch (type) 0147 { 0148 case ET_Generic: 0149 name = QStringLiteral("atlantik"); 0150 break; 0151 case ET_NetIn: 0152 name = QStringLiteral("arrow-left"); 0153 break; 0154 case ET_NetOut: 0155 name = QStringLiteral("arrow-right"); 0156 break; 0157 case ET_NetGeneric: 0158 name = QStringLiteral("network-disconnect"); // FIXME 0159 break; 0160 case ET_NetConnected: 0161 name = QStringLiteral("network-connect"); 0162 break; 0163 case ET_NetError: 0164 name = QStringLiteral("network-disconnect"); 0165 break; 0166 case ET_LastEvent: 0167 return QIcon(); 0168 }; 0169 0170 const QIcon icon = KDE::icon(name); 0171 m_iconCache[type] = icon; 0172 return icon; 0173 } 0174 0175 LastMessagesProxyModel::LastMessagesProxyModel(QObject *parent) 0176 : QSortFilterProxyModel(parent) 0177 , m_count(-1) 0178 { 0179 } 0180 0181 void LastMessagesProxyModel::setMessagesCount(int n) 0182 { 0183 if (n == m_count) 0184 return; 0185 0186 m_count = n; 0187 invalidateFilter(); 0188 } 0189 0190 void LastMessagesProxyModel::setSourceModel(QAbstractItemModel *model) 0191 { 0192 if (sourceModel()) 0193 disconnect(sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(invalidate())); 0194 QSortFilterProxyModel::setSourceModel(model); 0195 if (sourceModel()) 0196 connect(sourceModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(invalidate())); 0197 } 0198 0199 bool LastMessagesProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const 0200 { 0201 if (m_count < 0) 0202 return true; 0203 return source_row + m_count >= sourceModel()->rowCount(source_parent); 0204 } 0205 0206 EventLogWidget::EventLogWidget(EventLog *eventLog, QWidget *parent) 0207 : QDialog(parent, Qt::WindowContextHelpButtonHint) 0208 , m_eventLog(eventLog) 0209 { 0210 setModal(false); 0211 setAttribute(Qt::WA_DeleteOnClose); 0212 0213 setWindowTitle(i18nc("@title:window", "Event Log")); 0214 0215 QVBoxLayout *listCompBox = new QVBoxLayout(this); 0216 0217 m_eventList = new QTreeView(this); 0218 m_eventList->setObjectName(QStringLiteral("eventList")); 0219 listCompBox->addWidget(m_eventList); 0220 0221 QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close, this); 0222 QPushButton *saveButton = buttonBox->addButton(QString(), QDialogButtonBox::ActionRole); 0223 KGuiItem::assign(saveButton, KGuiItem(i18n("&Save As..."), QStringLiteral("document-save-as"))); 0224 QPushButton *clearButton = buttonBox->addButton(QString(), QDialogButtonBox::ActionRole); 0225 KGuiItem::assign(clearButton, KGuiItem(i18n("&Clear Log"), QStringLiteral("edit-clear"))); 0226 listCompBox->addWidget(buttonBox); 0227 0228 LastMessagesProxyModel *proxy = new LastMessagesProxyModel(m_eventList); 0229 // FIXME: allow a way to show older messages 0230 proxy->setMessagesCount(25); 0231 proxy->setSourceModel(m_eventLog); 0232 0233 m_eventList->setModel(proxy); 0234 m_eventList->setRootIsDecorated(false); 0235 m_eventList->header()->setSectionsClickable(false); 0236 m_eventList->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents); 0237 0238 connect(buttonBox, SIGNAL(rejected()), this, SLOT(accept())); 0239 connect(saveButton, SIGNAL(clicked()), this, SLOT(save())); 0240 connect(clearButton, SIGNAL(clicked()), m_eventLog, SLOT(clear())); 0241 } 0242 0243 void EventLogWidget::restoreSettings() 0244 { 0245 const KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("EventLogWidget")); 0246 KWindowConfig::restoreWindowSize(windowHandle(), group); 0247 } 0248 0249 EventLogWidget::~EventLogWidget() 0250 { 0251 KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("EventLogWidget")); 0252 KWindowConfig::saveWindowSize(windowHandle(), group); 0253 } 0254 0255 void EventLogWidget::save() 0256 { 0257 const QString filename = QFileDialog::getSaveFileName(this); 0258 if (filename.isEmpty()) 0259 return; 0260 0261 QFile file(filename); 0262 if ( file.open( QIODevice::WriteOnly ) ) 0263 { 0264 QTextStream stream(&file); 0265 0266 stream << i18n( "Atlantik log file, saved at %1.", QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd hh:mm:ss")) ) << '\n'; 0267 0268 m_eventLog->saveAsText(stream); 0269 } 0270 } 0271 0272 #include "moc_eventlogwidget.cpp"