/*************************************************************************** * Copyright (C) 2005 by Nicolas Ternisien * * nicolas.ternisien@gmail.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) 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. * ***************************************************************************/ //TQt includes #include //KDE includes #include #include #include #include #include #include #include #include //Project includes #include "logManager.h" #include "reader.h" #include "view.h" #include "ksystemlog.h" #include "readerFactory.h" #include "loadingDialog.h" LogManager::LogManager(KSystemLog* m, LoadingDialog* progress) : main(m), loadingDialog(progress), reader(NULL), view(NULL), groupBy(NO_GROUP_BY), groupByColumn(-1), columns(NULL), sortOrder(TQt::Ascending), sortColumn(0), tooltipEnabled(true), newLinesDisplayed(true), parsingPaused(false), logFiles(), current(false), newLinesSinceLastSelection(0), lastUpdate(TQTime::currentTime()), logMode(Globals::noMode) { //TODO Create the view from a factory for example view=new View(main); view->setLogManager(this); connect(view, TQ_SIGNAL(changeStatusbar(const TQString&)), this, TQ_SLOT(slotChangeStatusbar(const TQString&))); connect(view, TQ_SIGNAL(changeCaption(const TQString&)), this, TQ_SLOT(slotChangeCaption(const TQString&))); connect(view->getLogList(), TQ_SIGNAL(doubleClicked(TQListViewItem *, const TQPoint&, int)), this, TQ_SLOT(slotDetails(TQListViewItem *, const TQPoint&, int))); connect(view->getLogList(), TQ_SIGNAL(selectionChanged()), this, TQ_SLOT(slotSelectionChanged())); connect(view->getLogList(), TQ_SIGNAL(rightButtonPressed(TQListViewItem*, const TQPoint&, int)), this, TQ_SLOT(slotOpenContextualMenu(TQListViewItem*, const TQPoint&, int))); } LogManager::~LogManager() { //TODO Delete all used object (view and reader) delete view; delete reader; } View* LogManager::getView() { return(view); } void LogManager::saveConfig() { view->saveConfig(); } void LogManager::slotSelectionChanged() { emit selectionChanged(); } Reader* LogManager::getReader() { return(reader); } int LogManager::getIndex() { return(main->getIndex(this)); } void LogManager::initView() { if (columns!=NULL) delete columns; //Construct columns list columns=new LogViewColumns(); //Initialize columns list from Reader class reader->initColumns(columns); //If groupBy feature is activated, we must draw the tree lines in the view if (groupBy!=NO_GROUP_BY) view->getLogList()->setRootIsDecorated(true); else view->getLogList()->setRootIsDecorated(false); view->setColumns(columns); } void LogManager::reload() { loadingDialog->show(); loadingDialog->progressBar()->setProgress(0); loadingDialog->setLoadingLog(logMode->name); emit changeStatusbar(i18n("Loading log...")); kdDebug() << "Reloading " << logMode->name << "..." << endl; //Change part of the main interface emit changeTitle(view, logMode->pixmap, logMode->name); emit changeCaption(logMode->name); //Empty the current list, to better fill it clearView(); //Init the Log View initView(); //Read the log files reader->readLog(); emit changeStatusbar(i18n("Log successfully loaded.")); //Emit this signal only when the Log List has been totally reloaded emit reloaded(); loadingDialog->progressBar()->setProgress(100); loadingDialog->hide(); } void LogManager::openingProgress(int percent) { loadingDialog->progressBar()->setProgress(percent); //Move this signal to Loading Dialog class emit GUIUpdated(); //((KSystemLog*)( view->parent()))->kapp->processEvents(); } void LogManager::toggleFilterBar() { view->toggleFilterBar(); } void LogManager::slotDetails(TQListViewItem *, const TQPoint &, int) { emit detailsCalled(); } void LogManager::slotChangeCaption(const TQString& message) { emit changeCaption(message); } void LogManager::slotChangeStatusbar(const TQString& message) { emit changeStatusbar(message); } LogViewColumns* LogManager::getColumns() { return(columns); } void LogManager::clearView() { view->clearLogList(); } void LogManager::setLogFiles(LogFiles* files) { //We first clear the previous list //TODO Also delete pointers in this list before empty it logFiles.clear(); LogFiles::Iterator it; for(it=files->begin(); it!=files->end(); ++it) { logFiles.append(*it); } //The list is (normally) no longer used after that. delete files; } LogFiles& LogManager::getLogFiles() { return(logFiles); } LogMode* LogManager::getLogMode() { return(logMode); } TQTime& LogManager::getLastUpdate() { return(lastUpdate); } void LogManager::slotLogUpdated(int lineCount) { kdDebug() << "Log is updated (from LogManager) : " << lineCount << " current=" << isCurrent() << endl; if (lineCount==0) return; newLinesSinceLastSelection+=lineCount; lastUpdate=TQTime::currentTime(); //Emit this signal even if the current LogManager is selected emit logUpdated(newLinesSinceLastSelection); //If the user is in this log manager, he does have to see that some new log lines have appeared if (isCurrent()==false) { TQString title(i18n("%1 (%2)").arg(logMode->name).arg(newLinesSinceLastSelection)); //This signal is emitted only if the selected tab is not this one emit changeTitle(view, title); } } void LogManager::slotExpandAll() { //If this LogManager is the currently displayed one if (isCurrent()) { TQListViewItem* item=view->getLogList()->firstChild(); while (item!=NULL) { item->setOpen(true); item=item->nextSibling(); } } } void LogManager::slotCollapseAll() { //If this LogManager is the currently displayed one if (isCurrent()) { TQListViewItem* item=view->getLogList()->firstChild(); while (item!=NULL) { item->setOpen(false); item=item->nextSibling(); } } } void LogManager::slotFileSave() { //If this LogManager is the currently displayed one if (isCurrent()) { TQListViewItemIterator it(view->getLogList(), TQListViewItemIterator::Selected); //No item selected if (it.current()==NULL) { emit changeStatusbar(i18n("No items selected. Please select items to be able to save them.")); return; } TQString filename = KFileDialog::getSaveFileName(TQString(), TQString(), main); if (!filename.isEmpty()) { TQIODevice* ioDev = KFilterDev::deviceForFile( filename ); if (ioDev->open(IO_WriteOnly)) { TQTextStream stream(ioDev); int nbCopied=0; TQListViewItem* qtItem=it.current(); while (qtItem!=NULL) { LogListItem* item=static_cast (qtItem); //Copy the item content to the stream stream << item->exportToText(); //Retrieve the next item it++; qtItem=it.current(); nbCopied++; } ioDev->close(); emit changeStatusbar(i18n("1 log line saved to '%1'.", "%n log lines saved to '%1'.", nbCopied).arg(filename)); } else { TQString message(i18n("Unable to save file '%1': Permission Denied.").arg(filename)); KMessageBox::error(main, message, i18n("Unable to save file."), KMessageBox::Notify); } delete ioDev; } } } void LogManager::reinitialize() { //Reinitialize groupBy groupBy=NO_GROUP_BY; groupByColumn=-1; //TODO Reinitialize sorting, order, column order... } void LogManager::initialize(LogMode* mode) { //If this LogManager has already been initialized //with another LogMode, then it needs to be reinitialized if (this->logMode!=Globals::noMode) reinitialize(); //Use now the new mode this->logMode=mode; //Find the reader instance used for this new mode reader=ReaderFactory::createReader(mode); connect(reader, TQ_SIGNAL(statusbarChanged(const TQString&)), this, TQ_SLOT(slotChangeStatusbar(const TQString&))); connect(reader, TQ_SIGNAL(logUpdated(int)), this, TQ_SLOT(slotLogUpdated(int))); connect(reader, TQ_SIGNAL(openingProgressed(int)), this, TQ_SLOT(openingProgress(int))); connect(reader, TQ_SIGNAL(readingBegin()), this, TQ_SLOT(readingBegun())); connect(reader, TQ_SIGNAL(readingFile(int)), this, TQ_SLOT(readingFile(int))); connect(reader, TQ_SIGNAL(readingEnd()), this, TQ_SLOT(readingEnded())); //Inform this reader that this LogManager is now its parent reader->setLogManager(this); //Find the log files used for this kind of mode, and set them to our log manager setLogFiles(ReaderFactory::createLogFiles(mode)); } void LogManager::readingBegun() { //Inform the Loading Dialog on how many Files we have to load loadingDialog->setFileCount(logFiles.count()); } void LogManager::readingFile(int currentFile) { //Inform the Loading Dialog that there is a new file loading loadingDialog->setCurrentFile(currentFile); //Update the Progress Dialog label loadingDialog->show(); loadingDialog->progressBar()->setProgress(0); loadingDialog->setLoadingLog(logMode->name); } void LogManager::readingEnded() { //Reposition the count total to its default value loadingDialog->setFileCount(0); } void LogManager::setParsingPaused(bool paused) { parsingPaused=paused; //If we resume the parsing, then we reparse the files to know if new lines has append if (parsingPaused==false) { if (reader!=NULL) { reader->relaunchLogChanged(); } } } bool LogManager::isParsingPaused() { return(parsingPaused); } void LogManager::setTooltipEnabled(bool enabled) { tooltipEnabled=enabled; } bool LogManager::isTooltipEnabled() { return(tooltipEnabled); } void LogManager::setCurrent(bool cur) { current=cur; //Reinitialize the new line count newLinesSinceLastSelection=0; } bool LogManager::isCurrent() { return(current); } void LogManager::setNewLinesDisplayed(bool displayed) { newLinesDisplayed=displayed; } bool LogManager::isNewLinesDisplayed() { return(newLinesDisplayed); } void LogManager::setGroupBy(groupByType group, int column) { this->groupBy=group; this->groupByColumn=column; } groupByType LogManager::getGroupBy() { return(groupBy); } int LogManager::getGroupByColumn() { return(groupByColumn); } void LogManager::slotSendMail() { //If this LogManager is the currently displayed one if (isCurrent()) { TQString body(i18n("Here are my logs:\n")); body+=i18n("---------------------------------------\n"); TQListViewItemIterator it(view->getLogList(), TQListViewItemIterator::Selected); int i=0; TQListViewItem* qtItem=it.current(); while (qtItem!=NULL) { LogListItem* item=static_cast (qtItem); body+= item->exportToText(); body+='\n'; ++it; qtItem=it.current(); ++i; } body+=i18n("---------------------------------------\n"); //Too much lines selected if (i>1000) { KMessageBox::sorry(main, i18n("You have selected too many lines. Please only select important log lines."), i18n("Too Many Lines Selected")); return; } /* Parameters list of this method const TQString & to, const TQString & cc, const TQString & bcc, const TQString & subject, const TQString & body, const TQString & messageFile, const TQStringList & attachURLs, const TQCString & startup_id */ kapp->invokeMailer("", "", "", i18n("Log Lines of my problem"), body, "", TQStringList(), kapp->startupId()); } } void LogManager::slotCopyToClipboard() { //If this LogManager is the currently displayed one if (isCurrent()) { kdDebug() << "Copy to the clipboard" << endl; TQListView* listView=view->getLogList(); TQListViewItemIterator it(listView, TQListViewItemIterator::Selected); int nbCopied=0; LogListItem* item=static_cast (it.current()); TQString text; while (item!=NULL) { //Copy the item content to the text string text.append(item->exportToText()); text.append('\n'); //Retrieve the next value it++; item=static_cast (it.current()); nbCopied++; } //Copy text value only if it is not empty if (nbCopied==0) { emit changeStatusbar(i18n("No items selected. Nothing copied to clipboard.")); } else { //Copy both to clipboard and X11-selection TQApplication::clipboard()->setText(text, TQClipboard::Clipboard); TQApplication::clipboard()->setText(text, TQClipboard::Selection); emit changeStatusbar(i18n("1 log line copied to clipboard.", "%n log lines copied to clipboard.", nbCopied)); } } } void LogManager::synchronize(LogLineList* buffer) { kdDebug() << "Synchronizing the buffer..." << endl; //Here to find a bug if (buffer==NULL) kdDebug() << "ERROR! Buffer NULL" << endl; else kdDebug() << "Buffer not NULL" << endl; //Here to find a bug if (view==NULL) kdDebug() << "ERROR! View NULL" << endl; else kdDebug() << "View not NULL" << endl; //Synchronize the buffer returned by the reader and get the last added line LogLine* line=buffer->synchronize(view); //Here to find a bug if (line==NULL) kdDebug() << "ERROR! Line NULL" << endl; else kdDebug() << "Line not NULL" << endl; //Here to find a bug if (view->getLogList()==NULL) kdDebug() << "ERROR! TDEListView NULL" << endl; else kdDebug() << "TDEListView not NULL" << endl; if (isNewLinesDisplayed()==true) { if (line!=NULL) { line->ensureItemVisible(view->getLogList()); } } kdDebug() << "Buffer synchronized." << endl; } //TODO Change the method name void LogManager::slotOpenContextualMenu(TQListViewItem* /*item*/, const TQPoint& pos, int /*other*/) { TQPopupMenu menu(main); main->actionCollection()->action("reload")->plug(&menu); main->actionCollection()->action("select_all")->plug(&menu); menu.insertSeparator(); main->actionCollection()->action("copy")->plug(&menu); main->actionCollection()->action("file_save")->plug(&menu); menu.insertSeparator(); main->actionCollection()->action("enable_tooltip")->plug(&menu); main->actionCollection()->action("display_new_line")->plug(&menu); main->actionCollection()->action("group_by")->plug(&menu); menu.insertSeparator(); main->actionCollection()->action("details")->plug(&menu); menu.exec(pos); } #include "logManager.moc"