1
//=============================================================================
3
// File : LogViewWindow.cpp
4
// Creation date : Tue Apr 23 2002 18:08:22 by Juanjo Alvarez
6
// This file is part of the KVIrc irc client distribution
7
// Copyright (C) 2002 Juanjo Alvarez
8
// Copyright (C) 2002-2010 Szymon Stefanek (pragma at kvirc dot net)
10
// This program is FREE software. You can redistribute it and/or
11
// modify it under the terms of the GNU General Public License
12
// as published by the Free Software Foundation; either version 2
13
// of the License, or (at your opinion) any later version.
15
// This program is distributed in the HOPE that it will be USEFUL,
16
// but WITHOUT ANY WARRANTY; without even the implied warranty of
17
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
18
// See the GNU General Public License for more details.
20
// You should have received a copy of the GNU General Public License
21
// along with this program. If not, write to the Free Software Foundation,
22
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24
//=============================================================================
26
#include "LogViewWindow.h"
27
#include "LogViewWidget.h"
29
#include "KviIconManager.h"
30
#include "KviLocale.h"
31
#include "KviModule.h"
32
#include "KviOptions.h"
33
#include "KviMainWindow.h"
34
#include "KviIrcView.h"
35
#include "KviQString.h"
36
#include "KviApplication.h"
37
#include "KviFileUtils.h"
38
#include "KviTalPopupMenu.h"
42
#include <QToolButton>
46
#include <QHeaderView>
48
#include <QPushButton>
50
#include <QDateTimeEdit>
54
#include <QMouseEvent>
56
#include <QMessageBox>
58
#include <QProgressBar>
60
#ifdef COMPILE_ZLIB_SUPPORT
64
#include <limits.h> //for INT_MAX
66
extern LogViewWindow * g_pLogViewWindow;
68
LogViewWindow::LogViewWindow(KviModuleExtensionDescriptor * d,KviMainWindow * lpFrm)
69
: KviWindow(KviWindow::LogView,lpFrm,"logview"), KviModuleExtension(d)
71
g_pLogViewWindow = this;
72
// m_pLogViewWidget = new KviLogViewWidget(this);
74
m_pSplitter = new KviTalSplitter(Qt::Horizontal,this);
75
m_pSplitter->setObjectName("main_splitter");
76
m_pSplitter->setChildrenCollapsible(false);
78
m_pLeftLayout = new KviTalVBox(m_pSplitter);
79
m_pTabWidget = new QTabWidget(m_pLeftLayout);
80
m_pBottomLayout = new KviTalHBox(m_pLeftLayout);
81
m_pProgressBar = new QProgressBar(m_pBottomLayout);
83
m_pCancelButton = new QPushButton(m_pBottomLayout);
84
m_pCancelButton->setText(__tr2qs_ctx("Cancel","logview"));
85
connect(m_pCancelButton,SIGNAL(clicked()),this,SLOT(abortFilter()));
86
m_pBottomLayout->setVisible(false);
88
m_pIndexTab = new KviTalVBox(m_pTabWidget);
89
m_pTabWidget->addTab(m_pIndexTab,__tr2qs_ctx("HelpIndex","logview"));
91
m_pListView = new LogViewListView(m_pIndexTab);
93
connect(m_pListView,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(itemSelected(QTreeWidgetItem *,QTreeWidgetItem *)));
94
connect(m_pListView,SIGNAL(rightButtonPressed(QTreeWidgetItem *,QPoint)),
95
this,SLOT(rightButtonClicked(QTreeWidgetItem *,QPoint)));
97
m_pSearchTab = new QWidget(m_pTabWidget);
98
m_pTabWidget->addTab(m_pSearchTab,__tr2qs_ctx("Filter","logview"));
100
QGridLayout *layout = new QGridLayout(m_pSearchTab);
102
m_pShowChannelsCheck = new QCheckBox(__tr2qs_ctx("Show channel logs","logview"),m_pSearchTab);
103
m_pShowChannelsCheck->setChecked(true);
104
layout->addWidget(m_pShowChannelsCheck,0,0,1,2);
106
m_pShowQueryesCheck = new QCheckBox(__tr2qs_ctx("Show query logs","logview"),m_pSearchTab);
107
m_pShowQueryesCheck->setChecked(true);
108
layout->addWidget(m_pShowQueryesCheck,1,0,1,2);
110
m_pShowConsolesCheck = new QCheckBox(__tr2qs_ctx("Show console logs","logview"),m_pSearchTab);
111
m_pShowConsolesCheck->setChecked(true);
112
layout->addWidget(m_pShowConsolesCheck,2,0,1,2);
114
m_pShowDccChatCheck = new QCheckBox(__tr2qs_ctx("Show DCC chat logs","logview"),m_pSearchTab);
115
m_pShowDccChatCheck->setChecked(true);
116
layout->addWidget(m_pShowDccChatCheck,3,0,1,2);
118
m_pShowOtherCheck = new QCheckBox(__tr2qs_ctx("Show other logs","logview"),m_pSearchTab);
119
m_pShowOtherCheck->setChecked(true);
120
layout->addWidget(m_pShowOtherCheck,4,0,1,2);
123
l = new QLabel(__tr2qs_ctx("Contents filter","logview"),m_pSearchTab);
124
layout->addWidget(l,5,0,1,2);
126
l = new QLabel(__tr2qs_ctx("Log name mask:","logview"),m_pSearchTab);
127
m_pFileNameMask = new QLineEdit(m_pSearchTab);
128
connect(m_pFileNameMask,SIGNAL(returnPressed()),this,SLOT(applyFilter()));
129
layout->addWidget(l,6,0);
130
layout->addWidget(m_pFileNameMask,6,1);
132
l = new QLabel(__tr2qs_ctx("Log contents mask:","logview"),m_pSearchTab);
133
m_pContentsMask = new QLineEdit(m_pSearchTab);
134
connect(m_pContentsMask,SIGNAL(returnPressed()),this,SLOT(applyFilter()));
135
layout->addWidget(l,7,0);
136
layout->addWidget(m_pContentsMask,7,1);
138
m_pEnableFromFilter = new QCheckBox(__tr2qs_ctx("Only older than","logview"),m_pSearchTab);
139
m_pFromDateEdit = new QDateEdit(m_pSearchTab);
140
m_pFromDateEdit->setDate(QDate::currentDate());
141
layout->addWidget(m_pEnableFromFilter,8,0);
142
layout->addWidget(m_pFromDateEdit,8,1);
143
connect(m_pEnableFromFilter,SIGNAL(toggled(bool)),m_pFromDateEdit,SLOT(setEnabled(bool)));
144
m_pFromDateEdit->setEnabled(false);
146
m_pEnableToFilter = new QCheckBox(__tr2qs_ctx("Only newier than","logview"),m_pSearchTab);
147
m_pToDateEdit = new QDateEdit(m_pSearchTab);
148
m_pToDateEdit->setDate(QDate::currentDate());
149
layout->addWidget(m_pEnableToFilter,9,0);
150
layout->addWidget(m_pToDateEdit,9,1);
151
connect(m_pEnableToFilter,SIGNAL(toggled(bool)),m_pToDateEdit,SLOT(setEnabled(bool)));
152
m_pToDateEdit->setEnabled(false);
154
m_pFilterButton = new QPushButton(__tr2qs_ctx("Apply filter","logview"),m_pSearchTab);
155
connect(m_pFilterButton,SIGNAL(clicked()),this,SLOT(applyFilter()));
156
layout->addWidget(m_pFilterButton,10,1);
158
QWidget *w = new QWidget(m_pSearchTab);
159
w->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
160
layout->addWidget(w,11,1);
162
m_pIrcView = new KviIrcView(m_pSplitter,g_pMainWindow,this);
163
m_pIrcView->setMaxBufferSize(INT_MAX);
164
m_pIrcView->setFocusPolicy(Qt::ClickFocus);
168
li.append(width()-110);
169
m_pSplitter->setSizes(li);
171
g_pApp->getLocalKvircDirectory(m_szLogDirectory,KviApplication::Log);
172
KviQString::ensureLastCharIs(m_szLogDirectory,'/'); // Does this work on Windows?
174
m_pTimer = new QTimer(this);
175
m_pTimer->setSingleShot(true);
176
m_pTimer->setInterval(0);
177
connect(m_pTimer, SIGNAL(timeout()), this, SLOT(filterNext()));
178
//avoid to execute the long time-consuming procedure of log indexing here:
179
//we could still be inside the context of the "Browse log files" QAction
180
QTimer::singleShot( 0, this, SLOT(cacheFileList()) );
183
LogViewWindow::~LogViewWindow()
185
g_pLogViewWindow = 0;
188
void LogViewWindow::keyPressEvent(QKeyEvent *e)
190
//Make CtrlKey and CommandKey ("Apple") behave equally on MacOSX.
191
//This way typical X11 and Apple shortcuts can be used simultanously within the input line.
192
if((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::AltModifier) || (e->modifiers() & Qt::MetaModifier))
194
if(e->key() == Qt::Key_F)
196
m_pIrcView->toggleToolWidget();
200
KviWindow::keyPressEvent(e);
203
void LogViewWindow::applyFilter()
208
QPixmap * LogViewWindow::myIconPtr()
210
return g_pIconManager->getSmallIcon(KviIconManager::Log);
213
void LogViewWindow::resizeEvent(QResizeEvent *)
215
m_pSplitter->setGeometry(0,0,width(),height());
218
void LogViewWindow::fillCaptionBuffers()
220
m_szPlainTextCaption = __tr2qs_ctx("Log Viewer","logview");
223
void LogViewWindow::die()
228
QSize LogViewWindow::sizeHint() const
230
QSize ret(m_pSplitter->sizeHint().width(),m_pIrcView->sizeHint().height());
234
void LogViewWindow::setupItemList()
236
if(m_logList.isEmpty())
239
m_pFilterButton->setEnabled(false);
240
m_pListView->clear();
243
m_pBottomLayout->setVisible(true);
244
m_pProgressBar->setRange(0, m_logList.count());
245
m_pProgressBar->setValue(0);
250
m_pTimer->start(); //singleshot
253
void LogViewWindow::abortFilter()
258
void LogViewWindow::filterNext()
261
LogFile * pFile=m_logList.current();
265
if(pFile->type()==LogFile::Channel && !m_pShowChannelsCheck->isChecked())
267
if(pFile->type()==LogFile::Console && !m_pShowConsolesCheck->isChecked())
269
if(pFile->type()==LogFile::DccChat && !m_pShowDccChatCheck->isChecked())
271
if(pFile->type()==LogFile::Other && !m_pShowOtherCheck->isChecked())
273
if(pFile->type()==LogFile::Query && !m_pShowQueryesCheck->isChecked())
276
if(m_pEnableFromFilter->isChecked())
277
if(pFile->date()>m_pFromDateEdit->date())
280
if(m_pEnableToFilter->isChecked())
281
if(pFile->date()<m_pToDateEdit->date())
284
if(!m_pFileNameMask->text().isEmpty())
285
if(!KviQString::matchString(m_pFileNameMask->text(),pFile->name()))
288
if(!m_pContentsMask->text().isEmpty())
291
pFile->getText(textBuffer,m_szLogDirectory);
292
if(!KviQString::matchString(m_pContentsMask->text(),textBuffer))
298
if(m_pLastCategory->m_type!=pFile->type())
301
for(int i=0;i<m_pListView->topLevelItemCount(); ++i)
303
LogListViewItemType * pTmp = (LogListViewItemType*) m_pListView->topLevelItem(i);
304
if(pTmp->m_type == pFile->type())
306
m_pLastCategory=pTmp;
311
m_pLastCategory = new LogListViewItemType(m_pListView,pFile->type());
314
m_pLastCategory = new LogListViewItemType(m_pListView,pFile->type());
317
szCurGroup = QString(__tr2qs_ctx("%1 on %2","logview")).arg(pFile->name(),pFile->network());
319
if(m_szLastGroup!=szCurGroup)
321
m_szLastGroup=szCurGroup;
323
for(int i=0;i<m_pLastCategory->childCount(); ++i)
325
LogListViewItemFolder * pTmp = (LogListViewItemFolder*) m_pLastCategory->child(i);
326
if(pTmp->text(0) == m_szLastGroup)
328
m_pLastGroupItem=pTmp;
333
if(!m_pLastGroupItem)
334
m_pLastGroupItem=new LogListViewItemFolder(m_pLastCategory,m_szLastGroup);
337
new LogListViewLog(m_pLastGroupItem,pFile->type(),pFile);
340
pFile = m_logList.next();
343
if(pFile && !m_bAborted)
345
m_pProgressBar->setValue(m_pProgressBar->value()+1);
346
m_pTimer->start(); //singleshot
348
m_pBottomLayout->setVisible(false);
349
m_pListView->sortItems(0, Qt::AscendingOrder);
350
m_pProgressBar->setValue(0);
351
m_pFilterButton->setEnabled(true);
355
void LogViewWindow::cacheFileList()
358
g_pApp->getLocalKvircDirectory(logPath,KviApplication::Log);
359
recurseDirectory(logPath);
364
void LogViewWindow::recurseDirectory(const QString& sDir)
367
QFileInfoList list = dir.entryInfoList();
368
for (int iList=0;iList<list.count();iList++)
370
QFileInfo info = list[iList];
374
if (info.fileName()!=".." && info.fileName()!=".")
376
recurseDirectory(info.filePath());
378
} else if(info.suffix()=="gz" || info.suffix()=="log") {
379
m_logList.append(new LogFile(info.filePath()));
384
void LogViewWindow::itemSelected(QTreeWidgetItem * it,QTreeWidgetItem *)
387
m_pIrcView->clearBuffer();
388
if(!it || !it->parent() || !(((LogListViewItem *)it)->m_pFileData) )
394
((LogListViewItem *)it)->m_pFileData->getText(text,m_szLogDirectory);
396
QStringList lines= text.split('\n');
399
for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it ) {
400
QString num=(*it).section(' ',0,0);
401
iMsgType=num.toInt(&bOk);
403
outputNoFmt(iMsgType,(*it).section(' ',1),KviIrcView::NoRepaint | KviIrcView::NoTimestamp);
405
outputNoFmt(0,*it,KviIrcView::NoRepaint | KviIrcView::NoTimestamp);
407
m_pIrcView->repaint();
410
void LogViewWindow::rightButtonClicked ( QTreeWidgetItem * it, const QPoint &)
413
m_pListView->setCurrentItem(it);
415
KviTalPopupMenu* popup = new KviTalPopupMenu(this);
416
if(((LogListViewItem *)it)->childCount())
417
popup->insertItem(*(g_pIconManager->getSmallIcon(KviIconManager::Quit)),__tr2qs_ctx("Remove all these channel/query log files","logview"),this,SLOT(deleteCurrent()));
418
else popup->insertItem(*(g_pIconManager->getSmallIcon(KviIconManager::Quit)),__tr2qs_ctx("Remove file","logview"),this,SLOT(deleteCurrent()));
420
popup->exec( QCursor::pos() );
423
void LogViewWindow::deleteCurrent()
425
LogListViewItem* pItem = (LogListViewItem *)(m_pListView->currentItem());
428
if (pItem->childCount())
430
if(QMessageBox::question(
432
__tr2qs("Confirm current user logs delete"),
433
"Do you really wish to delete all these channel/query logs?", __tr2qs("&Yes"), __tr2qs("&No"),0,1
435
KviPointerList <LogListViewItem> itemsList;
436
itemsList.setAutoDelete(false);
437
for(int i=0;i<pItem->childCount();i++)
439
if (!pItem->child(i)->childCount())
441
itemsList.append((LogListViewItem*)pItem->child(i));
444
LogListViewItem* pChild=(LogListViewItem*)pItem->child(i);
445
for(int j=0;j<pChild->childCount();j++)
447
if (!(LogListViewItem*)pChild->child(j))
449
qDebug("Null pointer in logviewitem");
452
itemsList.append((LogListViewItem*)pChild->child(j));
455
for(unsigned int i=0;i<itemsList.count();i++)
457
LogListViewItem *pCurItem=itemsList.at(i);
458
if(!pCurItem->fileName().isNull())
461
g_pApp->getLocalKvircDirectory(szFname,KviApplication::Log,pCurItem->fileName());
462
KviFileUtils::removeFile(szFname);
468
if(!pItem->fileName().isNull())
471
g_pApp->getLocalKvircDirectory(szFname,KviApplication::Log,pItem->fileName());
472
KviFileUtils::removeFile(szFname);
474
m_pIrcView->clearBuffer();
475
if (!pItem->parent()->childCount()) delete pItem->parent();
480
LogFile::LogFile(const QString & szName)
484
$type_$nick.$network_$YYYY.$MM.$DD.log
486
query_noldor.azzurra_2009.05.20.log
487
channel_#slackware.azzurra_2009.11.03.log
490
m_szFilename = szName;
492
QFileInfo fi(m_szFilename);
493
QString szTmpName = fi.fileName();
495
m_bCompressed = (fi.suffix() == "gz");
498
//removes trailing dot and extension
501
QString szTypeToken = szTmpName.section('_',0,0);
502
// Ignore non-logs files, this includes '.' and '..'
503
if(KviQString::equalCI(szTypeToken,"channel"))
505
else if(KviQString::equalCI(szTypeToken,"console"))
507
else if(KviQString::equalCI(szTypeToken,"dccchat"))
509
else if(KviQString::equalCI(szTypeToken,"query"))
514
KviCString szUndecoded = szTmpName.section('.',0,0);
515
szUndecoded.cutToFirst('_');
516
m_szName = szUndecoded.hexDecode(szUndecoded.ptr()).ptr();
518
szUndecoded = szTmpName.section('.',1).section('_',0,-2);
519
m_szNetwork = szUndecoded.hexDecode(szUndecoded.ptr()).ptr();
521
QString szDate = szTmpName.section('_',-1).section('.',0,-2);
522
int iYear = szDate.section('.',0,0).toInt();
523
int iMonth = szDate.section('.',1,1).toInt();
524
int iDay = szDate.section('.',2,2).toInt();
525
m_date.setYMD(iYear,iMonth,iDay);
527
//qDebug("type=%i, name=%s, net=%s, date=%i %i %i",m_type,m_szName.ascii(),m_szNetwork.ascii(),iYear,iMonth,iDay);
530
void LogFile::getText(QString & text,const QString&)
532
QString logName = fileName();
534
#ifdef COMPILE_ZLIB_SUPPORT
537
gzFile file=gzopen(logName.toLocal8Bit().data(),"rb");
544
len=gzread(file,buff,1024);
549
len=gzread(file,buff,1024);
552
text = QString::fromUtf8(data);
554
qDebug("Cannot open compressed file %s",logName.toLocal8Bit().data());
558
logFile.setFileName(logName);
560
if(!logFile.open(QIODevice::ReadOnly))
564
bytes=logFile.readAll();
565
text = QString::fromUtf8(bytes.data(), bytes.size());
567
#ifdef COMPILE_ZLIB_SUPPORT
572
LogViewListView::LogViewListView(QWidget * par)
575
header()->setSortIndicatorShown(true);
577
setHeaderLabel(__tr2qs_ctx("Log File","logview"));
578
setSelectionMode(QAbstractItemView::SingleSelection);
579
setSortingEnabled(true);
580
setRootIsDecorated(true);
584
void LogViewListView::mousePressEvent (QMouseEvent *e)
586
if (e->button() == Qt::RightButton)
588
QTreeWidgetItem *i=itemAt(e->pos());
589
if (i) emit rightButtonPressed(i,QCursor::pos());
591
QTreeWidget::mousePressEvent(e);
594
#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES
595
#include "LogViewWindow.moc"
596
#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES