1
//=============================================================================
3
// File : logviewmdiwindow.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-2008 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 "logviewmdiwindow.h"
27
#include "logviewwidget.h"
29
#include "kvi_iconmanager.h"
30
#include "kvi_locale.h"
31
#include "kvi_module.h"
32
#include "kvi_options.h"
33
#include "kvi_frame.h"
34
#include "kvi_ircview.h"
35
#include "kvi_qstring.h"
37
#include "kvi_fileutils.h"
38
#include "kvi_tal_popupmenu.h"
42
#include <QToolButton>
46
#include <QHeaderView>
48
#include <QPushButton>
49
#include <QProgressDialog>
51
#include <QDateTimeEdit>
55
#include <QMouseEvent>
57
#include <QMessageBox>
59
#ifdef COMPILE_ZLIB_SUPPORT
63
#include <limits.h> //for INT_MAX
65
extern KviLogViewMDIWindow * g_pLogViewWindow;
67
KviLogViewMDIWindow::KviLogViewMDIWindow(KviModuleExtensionDescriptor * d,KviFrame * lpFrm)
68
: KviWindow(KVI_WINDOW_TYPE_LOGVIEW,lpFrm,"logview"), KviModuleExtension(d)
70
g_pLogViewWindow = this;
71
// m_pLogViewWidget = new KviLogViewWidget(this);
73
m_pSplitter = new KviTalSplitter(Qt::Horizontal,this);
74
m_pSplitter->setObjectName("main_splitter");
75
m_pTabWidget = new QTabWidget(m_pSplitter);
77
m_pIndexTab = new KviTalVBox(m_pTabWidget);
78
m_pTabWidget->addTab(m_pIndexTab,__tr2qs_ctx("Index","logview"));
80
m_pListView = new KviLogViewListView(m_pIndexTab);
82
connect(m_pListView,SIGNAL(currentItemChanged(QTreeWidgetItem *,QTreeWidgetItem *)),this,SLOT(itemSelected(QTreeWidgetItem *,QTreeWidgetItem *)));
83
connect(m_pListView,SIGNAL(rightButtonPressed(QTreeWidgetItem *,QPoint)),
84
this,SLOT(rightButtonClicked(QTreeWidgetItem *,QPoint)));
86
m_pSearchTab = new QWidget(m_pTabWidget);
87
m_pTabWidget->addTab(m_pSearchTab,__tr2qs_ctx("Filter","logview"));
89
QGridLayout *layout = new QGridLayout(m_pSearchTab);
91
m_pShowChannelsCheck = new QCheckBox(__tr2qs_ctx("Show channel logs","logview"),m_pSearchTab);
92
m_pShowChannelsCheck->setChecked(true);
93
layout->addWidget(m_pShowChannelsCheck,0,0,1,2);
95
m_pShowQueryesCheck = new QCheckBox(__tr2qs_ctx("Show query logs","logview"),m_pSearchTab);
96
m_pShowQueryesCheck->setChecked(true);
97
layout->addWidget(m_pShowQueryesCheck,1,0,1,2);
99
m_pShowConsolesCheck = new QCheckBox(__tr2qs_ctx("Show console logs","logview"),m_pSearchTab);
100
m_pShowConsolesCheck->setChecked(true);
101
layout->addWidget(m_pShowConsolesCheck,2,0,1,2);
103
m_pShowDccChatCheck = new QCheckBox(__tr2qs_ctx("Show DCC chat logs","logview"),m_pSearchTab);
104
m_pShowDccChatCheck->setChecked(true);
105
layout->addWidget(m_pShowDccChatCheck,3,0,1,2);
107
m_pShowOtherCheck = new QCheckBox(__tr2qs_ctx("Show other logs","logview"),m_pSearchTab);
108
m_pShowOtherCheck->setChecked(true);
109
layout->addWidget(m_pShowOtherCheck,4,0,1,2);
112
l = new QLabel(__tr2qs_ctx("Contents filter","logview"),m_pSearchTab);
113
layout->addWidget(l,5,0,1,2);
115
l = new QLabel(__tr2qs_ctx("Log name mask:","logview"),m_pSearchTab);
116
m_pFileNameMask = new QLineEdit(m_pSearchTab);
117
connect(m_pFileNameMask,SIGNAL(returnPressed()),this,SLOT(applyFilter()));
118
layout->addWidget(l,6,0);
119
layout->addWidget(m_pFileNameMask,6,1);
121
l = new QLabel(__tr2qs_ctx("Log contents mask:","logview"),m_pSearchTab);
122
m_pContentsMask = new QLineEdit(m_pSearchTab);
123
connect(m_pContentsMask,SIGNAL(returnPressed()),this,SLOT(applyFilter()));
124
layout->addWidget(l,7,0);
125
layout->addWidget(m_pContentsMask,7,1);
127
m_pEnableFromFilter = new QCheckBox(__tr2qs_ctx("Only older than","logview"),m_pSearchTab);
128
m_pFromDateEdit = new QDateEdit(m_pSearchTab);
129
m_pFromDateEdit->setDate(QDate::currentDate());
130
layout->addWidget(m_pEnableFromFilter,8,0);
131
layout->addWidget(m_pFromDateEdit,8,1);
132
connect(m_pEnableFromFilter,SIGNAL(toggled(bool)),m_pFromDateEdit,SLOT(setEnabled(bool)));
133
m_pFromDateEdit->setEnabled(false);
135
m_pEnableToFilter = new QCheckBox(__tr2qs_ctx("Only newier than","logview"),m_pSearchTab);
136
m_pToDateEdit = new QDateEdit(m_pSearchTab);
137
m_pToDateEdit->setDate(QDate::currentDate());
138
layout->addWidget(m_pEnableToFilter,9,0);
139
layout->addWidget(m_pToDateEdit,9,1);
140
connect(m_pEnableToFilter,SIGNAL(toggled(bool)),m_pToDateEdit,SLOT(setEnabled(bool)));
141
m_pToDateEdit->setEnabled(false);
143
m_pFilterButton = new QPushButton(__tr2qs_ctx("Apply filter","logview"),m_pSearchTab);
144
connect(m_pFilterButton,SIGNAL(clicked()),this,SLOT(applyFilter()));
145
layout->addWidget(m_pFilterButton,10,1);
147
QWidget *w = new QWidget(m_pSearchTab);
148
w->setSizePolicy(QSizePolicy::Ignored,QSizePolicy::Ignored);
149
layout->addWidget(w,11,1);
151
m_pIrcView = new KviIrcView(m_pSplitter,g_pFrame,this);
152
m_pIrcView->setMaxBufferSize(INT_MAX);
153
m_pIrcView->setFocusPolicy(Qt::ClickFocus);
157
li.append(width()-110);
158
m_pSplitter->setSizes(li);
160
g_pApp->getLocalKvircDirectory(m_szLogDirectory,KviApp::Log);
161
KviQString::ensureLastCharIs(m_szLogDirectory,'/'); // Does this work on Windows?
163
//avoid to execute the long time-consuming procedure of log indexing here:
164
//we could still be inside the context of the "Browse log files" QAction
165
QTimer::singleShot( 0, this, SLOT(cacheFileList()) );
168
KviLogViewMDIWindow::~KviLogViewMDIWindow()
170
g_pLogViewWindow = 0;
173
void KviLogViewMDIWindow::keyPressEvent(QKeyEvent *e)
175
//Make CtrlKey and CommandKey ("Apple") behave equally on MacOSX.
176
//This way typical X11 and Apple shortcuts can be used simultanously within the input line.
177
if((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::AltModifier) || (e->modifiers() & Qt::MetaModifier))
179
if(e->key() == Qt::Key_F)
181
m_pIrcView->toggleToolWidget();
185
KviWindow::keyPressEvent(e);
188
void KviLogViewMDIWindow::applyFilter()
193
QPixmap * KviLogViewMDIWindow::myIconPtr()
195
return g_pIconManager->getSmallIcon(KVI_SMALLICON_LOG);
198
void KviLogViewMDIWindow::resizeEvent(QResizeEvent *)
200
m_pSplitter->setGeometry(0,0,width(),height());
203
void KviLogViewMDIWindow::fillCaptionBuffers()
205
m_szPlainTextCaption = __tr2qs_ctx("Log Viewer","logview");
208
void KviLogViewMDIWindow::die()
213
QSize KviLogViewMDIWindow::sizeHint() const
215
QSize ret(m_pSplitter->sizeHint().width(),m_pIrcView->sizeHint().height());
219
void KviLogViewMDIWindow::setupItemList()
221
m_pFilterButton->setEnabled(false);
222
m_pListView->clear();
224
KviLogListViewItem *pLastCategory=0;
225
KviLogListViewItemFolder *pLastGroupItem=0;
228
const bool bShowChannel=m_pShowChannelsCheck->isChecked();
229
const bool bShowQuery=m_pShowQueryesCheck->isChecked();
230
const bool bShowConsole=m_pShowConsolesCheck->isChecked();
231
const bool bShowOther=m_pShowOtherCheck->isChecked();
232
const bool bShowDccChat=m_pShowDccChatCheck->isChecked();
234
const bool filterFromDate=m_pEnableFromFilter->isChecked();
235
const bool filterToDate=m_pEnableToFilter->isChecked();
237
const QString nameFilterText = m_pFileNameMask->text();
238
const bool enableNameFilter = !nameFilterText.isEmpty();
240
const QString contentFilterText = m_pContentsMask->text();
241
const bool enableContentFilter = !contentFilterText.isEmpty();
243
QDate fromDate = m_pFromDateEdit->date();
244
QDate toDate = m_pToDateEdit->date();
247
QProgressDialog progress( __tr2qs_ctx("Filtering files...","logview"),
248
__tr2qs_ctx("Abort filtering","logview"), 0, m_logList.count(),
250
progress.setObjectName("progress");
253
for(pFile=m_logList.first();pFile;pFile=m_logList.next())
255
progress.setValue( i );
257
g_pApp->processEvents();
259
if ( progress.wasCanceled() )
262
if(pFile->type()==KviLogFile::Channel && !bShowChannel)
264
if(pFile->type()==KviLogFile::Console && !bShowConsole)
266
if(pFile->type()==KviLogFile::DccChat && !bShowDccChat)
268
if(pFile->type()==KviLogFile::Other && !bShowOther)
270
if(pFile->type()==KviLogFile::Query && !bShowQuery)
274
if(pFile->date()>fromDate)
278
if(pFile->date()<toDate)
282
if(!KviQString::matchString(nameFilterText,pFile->name()))
285
if(enableContentFilter)
287
pFile->getText(textBuffer,m_szLogDirectory);
288
if(!KviQString::matchString(contentFilterText,textBuffer))
294
if(pLastCategory->m_type!=pFile->type())
295
pLastCategory = new KviLogListViewItemType(m_pListView,pFile->type());
297
pLastCategory = new KviLogListViewItemType(m_pListView,pFile->type());
300
KviQString::sprintf(szCurGroup,__tr2qs_ctx("%Q on %Q","logview"),&(pFile->name()),
304
if(szLastGroup!=szCurGroup) {
305
szLastGroup=szCurGroup;
306
pLastGroupItem=new KviLogListViewItemFolder(pLastCategory,szLastGroup);
308
new KviLogListViewLog(pLastGroupItem,pFile->type(),pFile);
310
progress.setValue( m_logList.count() );
311
m_pListView->sortItems(0, Qt::AscendingOrder);
312
m_pFilterButton->setEnabled(true);
315
void KviLogViewMDIWindow::cacheFileList()
317
QStringList m_pFileNames = getFileNames();
321
for(QStringList::Iterator it = m_pFileNames.begin(); it != m_pFileNames.end(); ++it)
324
QFileInfo fi(szFname);
325
if(fi.suffix()=="gz" || fi.suffix()=="log")
326
m_logList.append(new KviLogFile(szFname));
332
void KviLogViewMDIWindow::itemSelected(QTreeWidgetItem * it,QTreeWidgetItem *)
335
m_pIrcView->clearBuffer();
336
if(!it || !it->parent() || !(((KviLogListViewItem *)it)->m_pFileData) )
342
((KviLogListViewItem *)it)->m_pFileData->getText(text,m_szLogDirectory);
344
QStringList lines= text.split('\n');
347
for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it ) {
348
QString num=(*it).section(' ',0,0);
349
iMsgType=num.toInt(&bOk);
351
outputNoFmt(iMsgType,(*it).section(' ',1),KviIrcView::NoRepaint | KviIrcView::NoTimestamp);
353
outputNoFmt(0,*it,KviIrcView::NoRepaint | KviIrcView::NoTimestamp);
355
m_pIrcView->repaint();
358
QStringList KviLogViewMDIWindow::getFileNames()
361
g_pApp->getLocalKvircDirectory(logPath,KviApp::Log);
362
QString qPath(logPath);
364
return logDir.entryList();
367
void KviLogViewMDIWindow::rightButtonClicked ( QTreeWidgetItem * it, const QPoint &)
370
m_pListView->setCurrentItem(it);
372
KviTalPopupMenu* popup = new KviTalPopupMenu(this);
373
if(((KviLogListViewItem *)it)->childCount())
374
popup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Remove all these channel/query log files","logview"),this,SLOT(deleteCurrent()));
375
else popup->insertItem(*(g_pIconManager->getSmallIcon(KVI_SMALLICON_QUIT)),__tr2qs_ctx("Remove file","logview"),this,SLOT(deleteCurrent()));
377
popup->exec( QCursor::pos() );
380
void KviLogViewMDIWindow::deleteCurrent()
382
KviLogListViewItem* pItem = (KviLogListViewItem *)(m_pListView->currentItem());
385
if (pItem->childCount())
387
if(QMessageBox::question(
389
__tr2qs("Confirm current user logs delete"),
390
"Do you really wish to delete all these channel/query logs?", __tr2qs("&Yes"), __tr2qs("&No"),0,1
392
KviPointerList <KviLogListViewItem> itemsList;
393
itemsList.setAutoDelete(false);
394
for(int i=0;i<pItem->childCount();i++)
396
if (!pItem->child(i)->childCount())
398
itemsList.append((KviLogListViewItem*)pItem->child(i));
401
KviLogListViewItem* pChild=(KviLogListViewItem*)pItem->child(i);
402
for(int j=0;j<pChild->childCount();j++)
404
if (!(KviLogListViewItem*)pChild->child(j))
406
debug ("Null pointer in logviewitem");
409
itemsList.append((KviLogListViewItem*)pChild->child(j));
412
for(unsigned int i=0;i<itemsList.count();i++)
414
KviLogListViewItem *pCurItem=itemsList.at(i);
415
if(!pCurItem->fileName().isNull())
418
g_pApp->getLocalKvircDirectory(szFname,KviApp::Log,pCurItem->fileName());
419
KviFileUtils::removeFile(szFname);
425
if(!pItem->fileName().isNull())
428
g_pApp->getLocalKvircDirectory(szFname,KviApp::Log,pItem->fileName());
429
KviFileUtils::removeFile(szFname);
431
m_pIrcView->clearBuffer();
432
if (!pItem->parent()->childCount()) delete pItem->parent();
437
KviLogFile::KviLogFile(const QString & szName)
441
$type_$nick.$network_$YYYY.$MM.$DD.log
443
query_noldor.azzurra_2009.05.20.log
444
channel_#slackware.azzurra_2009.11.03.log
447
QString szTmpName = szName;
448
m_szFilename = szName;
450
QFileInfo fi(m_szFilename);
451
m_bCompressed = (fi.suffix() == "gz");
454
//removes trailing dot and extension
457
QString szTypeToken = szTmpName.section('_',0,0);
458
// Ignore non-logs files, this includes '.' and '..'
459
if(KviQString::equalCI(szTypeToken,"channel"))
461
else if(KviQString::equalCI(szTypeToken,"console"))
463
else if(KviQString::equalCI(szTypeToken,"dccchat"))
465
else if(KviQString::equalCI(szTypeToken,"query"))
470
KviStr szUndecoded = szTmpName.section('.',0,0);
471
szUndecoded.cutToFirst('_');
472
m_szName = szUndecoded.hexDecode(szUndecoded.ptr()).ptr();
474
szUndecoded = szTmpName.section('.',1).section('_',0,-2);
475
m_szNetwork = szUndecoded.hexDecode(szUndecoded.ptr()).ptr();
477
QString szDate = szTmpName.section('_',-1).section('.',0,-2);
478
int iYear = szDate.section('.',0,0).toInt();
479
int iMonth = szDate.section('.',1,1).toInt();
480
int iDay = szDate.section('.',2,2).toInt();
481
m_date.setYMD(iYear,iMonth,iDay);
483
//debug("type=%i, name=%s, net=%s, date=%i %i %i",m_type,m_szName.ascii(),m_szNetwork.ascii(),iYear,iMonth,iDay);
486
void KviLogFile::getText(QString & text,const QString& logDir){
487
QString logName = logDir;
489
logName.append(fileName());
490
#ifdef COMPILE_ZLIB_SUPPORT
493
gzFile file=gzopen(logName.toLocal8Bit().data(),"rb");
500
len=gzread(file,buff,1024);
505
len=gzread(file,buff,1024);
508
text = QString::fromUtf8(data);
510
debug("Cannot open compressed file %s",logName.toLocal8Bit().data());
514
logFile.setFileName(logName);
516
if(!logFile.open(QIODevice::ReadOnly))
520
bytes=logFile.readAll();
521
text = QString::fromUtf8(bytes.data(), bytes.size());
523
#ifdef COMPILE_ZLIB_SUPPORT
528
KviLogViewListView::KviLogViewListView(QWidget * par)
531
header()->setSortIndicatorShown(true);
533
setHeaderLabel(__tr2qs_ctx("Log File","logview"));
534
setSelectionMode(QAbstractItemView::SingleSelection);
535
setSortingEnabled(true);
536
setRootIsDecorated(true);
540
void KviLogViewListView::mousePressEvent (QMouseEvent *e)
542
if (e->button() == Qt::RightButton)
544
QTreeWidgetItem *i=itemAt(e->pos());
545
if (i) emit rightButtonPressed(i,QCursor::pos());
547
QTreeWidget::mousePressEvent(e);
550
#ifndef COMPILE_USE_STANDALONE_MOC_SOURCES
551
#include "logviewmdiwindow.moc"
552
#endif //!COMPILE_USE_STANDALONE_MOC_SOURCES