1 /***************************************************************************
2 * KSystemLog, a system log viewer tool *
3 * Copyright (C) 2007 by Nicolas Ternisien *
4 * nicolas.ternisien@gmail.com *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 ***************************************************************************/
22 #include "tabLogViewsWidget.h"
24 #include <QPushButton>
29 #include <kiconloader.h>
35 #include "logViewExport.h"
39 #include "logManager.h"
40 #include "tabLogManager.h"
41 #include "logViewWidget.h"
43 class TabLogViewsWidgetPrivate
{
45 QList
<TabLogManager
*> tabLogManagers
;
50 TabLogViewsWidget::TabLogViewsWidget(QWidget
* parent
) :
52 d(new TabLogViewsWidgetPrivate()) {
54 d
->contextMenu
= NULL
;
56 QPushButton
* tabNewTabButton
=new QPushButton(SmallIcon("tab-new"), "", this);
57 connect(tabNewTabButton
, SIGNAL(clicked()), this, SLOT(createTab()));
59 tabNewTabButton
->setToolTip(i18n("Create a new tab"));
60 tabNewTabButton
->setWhatsThis(i18n("Creates a new tab which can display another log."));
62 QPushButton
* tabCloseTabButton
=new QPushButton(SmallIcon("tab-close"), "", this);
63 connect(tabCloseTabButton
, SIGNAL(clicked()), this, SLOT(closeTab()));
65 tabCloseTabButton
->setToolTip(i18n("Close the current tab"));
66 tabCloseTabButton
->setWhatsThis(i18n("Closes the current tab."));
68 setCornerWidget(tabNewTabButton
, Qt::TopLeftCorner
);
69 setCornerWidget(tabCloseTabButton
, Qt::TopRightCorner
);
71 setHoverCloseButton(true);
72 setHoverCloseButtonDelayed(true);
74 setUsesScrollButtons(true);
76 //The context menu is managed manually
77 //setContextMenuPolicy(Qt::ActionsContextMenu);
79 connect(this, SIGNAL(mouseDoubleClick()), this, SLOT(createTab()));
80 connect(this, SIGNAL(contextMenu(const QPoint
&)), this, SLOT(showContextMenu(const QPoint
&)));
81 connect(this, SIGNAL(contextMenu(QWidget
*, const QPoint
&)), this, SLOT(showContextMenu(QWidget
*, const QPoint
&)));
83 //TODO Use this (need to connect to movedTab(int, int) signal and update the QList
84 //setTabReorderingEnabled(true);
86 connect(this, SIGNAL(currentChanged(int)), this, SLOT(changeCurrentTab()));
89 TabLogViewsWidget::~TabLogViewsWidget() {
90 //TODO Try to do not crash KSystemLog at exitting
92 QList<TabLogManager*> copy = d->tabLogManagers;
94 //Delete existing tabs and related tabLogManagers
95 foreach(TabLogManager* tabLogManager, copy) {
96 logDebug() << "Deleting " << tabLogManager->logManager()->logMode()->name() << endl;
97 removePage(tabLogManager->logManager()->usedView());
99 d->tabLogManagers.removeAll(tabLogManager);
100 delete tabLogManager;
101 logDebug() << tabLogManager->logManager()->logMode()->name() << " deleted" << endl;
108 void TabLogViewsWidget::newTab(View
* view
) {
109 logDebug() << "Inserting to a new tab the view " << endl
;
111 //Add a tab at the end of the widget
112 insertTab(count(), view
, SmallIcon(NO_MODE_ICON
), i18n("No Log"));
115 setTabBarHidden(false);
117 setTabBarHidden(true);
121 void TabLogViewsWidget::changeTab(View
* view
, const QIcon
& icon
, const QString
& label
) {
122 logDebug() << "Changing tab " << label
<< endl
;
123 int index
= indexOf(view
);
124 setTabIcon(index
, icon
);
125 setTabText(index
, label
);
128 QList
<LogManager
*> TabLogViewsWidget::logManagers() {
129 QList
<LogManager
*> logManagers
;
130 foreach(TabLogManager
* tabLogManager
, d
->tabLogManagers
) {
131 logManagers
.append(tabLogManager
->logManager());
137 LogManager
* TabLogViewsWidget::findRelatedLogManager(View
* view
) {
138 return findRelatedTabLogManager(view
)->logManager();
141 TabLogManager
* TabLogViewsWidget::findRelatedTabLogManager(View
* view
) {
142 foreach (TabLogManager
* tabLogManager
, d
->tabLogManagers
) {
143 if (tabLogManager
->logManager()->usedView()==view
) {
144 return tabLogManager
;
148 logError() << "No log manager found" << endl
;
152 TabLogManager
* TabLogViewsWidget::activeTabLogManager() {
153 View
* currentView
=static_cast<View
*> (currentWidget());
155 return findRelatedTabLogManager(currentView
);
158 LogManager
* TabLogViewsWidget::activeLogManager() {
159 return activeTabLogManager()->logManager();
162 LogManager
* TabLogViewsWidget::createTab() {
163 logDebug() << "Creating a new tab" << endl
;
165 return newTabLogManager()->logManager();
168 void TabLogViewsWidget::moveTabLeft() {
169 logDebug() << "Duplicate tab to the left" << endl
;
171 TabLogManager
* currentTabLogManager
=activeTabLogManager();
172 int position
=indexOf(currentTabLogManager
->logManager()->usedView());
175 logError() << "Tab Position <= 0 : " << position
<< endl
;
179 d
->tabLogManagers
.removeAt(position
);
180 d
->tabLogManagers
.insert(position
-1, currentTabLogManager
);
182 moveTab(position
, position
-1);
186 void TabLogViewsWidget::moveTabRight() {
187 logDebug() << "Duplicate tab to the right" << endl
;
189 TabLogManager
* currentTabLogManager
=activeTabLogManager();
190 int position
=indexOf(currentTabLogManager
->logManager()->usedView());
192 if (position
>=count()-1) {
193 logError() << "Tab Position >= count()-1 : " << position
<< endl
;
197 d
->tabLogManagers
.removeAt(position
);
198 d
->tabLogManagers
.insert(position
+1, currentTabLogManager
);
200 moveTab(position
, position
+1);
204 LogManager
* TabLogViewsWidget::duplicateTab() {
205 logDebug() << "Duplicate current tab" << endl
;
207 TabLogManager
* currentManager
=activeTabLogManager();
209 TabLogManager
* tabLogManager
=newTabLogManager();
211 LogMode
* mode
=currentManager
->logManager()->logMode();
213 load(mode
, tabLogManager
->logManager());
215 //Returns the newly created LogManager
216 return tabLogManager
->logManager();
219 TabLogManager
* TabLogViewsWidget::newTabLogManager() {
220 logDebug() << "Creating new View..." << endl
;
222 View
* view
= new View(this);
224 logDebug() << "Creating new LogManager..." << endl
;
226 LogManager
* logManager
=new LogManager(view
);
228 //Signals from LogManager to Main Class
229 connect(logManager
, SIGNAL(tabTitleChanged(View
*, const QIcon
&, const QString
&)), this, SLOT(changeTab(View
*, const QIcon
&, const QString
&)));
230 connect(logManager
, SIGNAL(logUpdated(View
*, int)), this, SLOT(changeTitleAddedLines(View
*, int)));
232 TabLogManager
* tabLogManager
= new TabLogManager(logManager
);
233 d
->tabLogManagers
.append(tabLogManager
);
235 logDebug() << "New LogManager created" << endl
;
237 //Finally add the view to the tabs
240 emit
logManagerCreated(logManager
);
242 setCurrentIndex(count()-1);
244 //Set focus to the list
245 view
->logViewWidget()->setFocus();
247 //Returns the newly created TabLogManager
248 return tabLogManager
;
252 void TabLogViewsWidget::closeTab() {
254 logError() << "Cannot close tab, one tab left" << endl
;
258 TabLogManager
* currentTabLogManager
=activeTabLogManager();
260 d
->tabLogManagers
.removeAll(currentTabLogManager
);
262 removePage(currentTabLogManager
->logManager()->usedView());
264 setTabBarHidden(true);
267 delete currentTabLogManager
;
271 void TabLogViewsWidget::load(LogMode
* logMode
, LogManager
* manager
) {
272 logDebug() << "Loading a new mode : " << logMode
->name() << endl
;
274 if (manager
==NULL
|| logMode
==NULL
) {
275 logError() << "Error while loading a manager " << endl
;
279 //The manager is now using the Log mode passed in parameter
280 manager
->initialize(logMode
);
286 void TabLogViewsWidget::reloadCurrent() {
287 logDebug() << "Reloading current log manager..." << endl
;
289 LogManager
* manager
=activeLogManager();
297 void TabLogViewsWidget::reloadAll() {
298 logDebug() << "Reloading all tabs..." << endl
;
300 foreach (TabLogManager
* tabLogManager
, d
->tabLogManagers
) {
301 //Log manager without log mode does not need to be reloaded
302 if (tabLogManager
->logManager()->logMode() == NULL
) {
306 //Do a simple reload if it is an open log mode
307 if (tabLogManager
->logManager()->logMode()->id()=="openLogMode") {
308 tabLogManager
->logManager()->reload();
312 //Do a full loading of other log modes (needed if log files have been modified)
313 load(tabLogManager
->logManager()->logMode(), tabLogManager
->logManager());
320 void TabLogViewsWidget::changeCurrentTab() {
321 logDebug() << "Changing current tab..." << endl
;
323 TabLogManager
* tabLogManager
=activeTabLogManager();
325 //Reinit the new lines count since last selection
326 tabLogManager
->initNewLinesCount();
328 //If the tab displayed the new added line count, rename it to the default log mode name
329 changeTab(tabLogManager
->logManager()->usedView(), logModeIcon(tabLogManager
->logManager()->logMode()), tabLogManager
->title());
331 logDebug() << "Current tab changed" << endl
;
334 void TabLogViewsWidget::changeReloadingTab(View
* view
, bool reloading
) {
335 TabLogManager
* tabLogManager
= findRelatedTabLogManager(view
);
337 if (reloading
== true)
338 changeTab(tabLogManager
->logManager()->usedView(), KIcon("view-refresh"), tabLogManager
->title());
340 changeTab(tabLogManager
->logManager()->usedView(), logModeIcon(tabLogManager
->logManager()->logMode()), tabLogManager
->title());
343 void TabLogViewsWidget::changeTitleAddedLines(View
* view
, int addedLinesSinceLastUpdate
) {
344 logDebug() << "Changing title" << addedLinesSinceLastUpdate
<< " added lines..." << endl
;
345 LogManager
* currentManager
=activeLogManager();
347 //Only display added line on tab title if this is not an update of the current tab
348 if (currentManager
->usedView() != view
) {
349 TabLogManager
* tabLogManager
= findRelatedTabLogManager(view
);
350 tabLogManager
->addNewLinesCount(addedLinesSinceLastUpdate
);
352 //Update the tab title
353 changeTab(tabLogManager
->logManager()->usedView(), logModeIcon(tabLogManager
->logManager()->logMode()), tabLogManager
->title());
356 void TabLogViewsWidget::expandAllCurrentView() {
357 activeLogManager()->usedView()->logViewWidget()->expandAll();
360 void TabLogViewsWidget::collapseAllCurrentView() {
361 activeLogManager()->usedView()->logViewWidget()->collapseAll();
364 void TabLogViewsWidget::selectAllCurrentView() {
365 activeLogManager()->usedView()->logViewWidget()->selectAll();
368 void TabLogViewsWidget::fileSaveCurrentView() {
369 LogViewExport
logViewExport(this, activeLogManager()->usedView()->logViewWidget());
370 connect(&logViewExport
, SIGNAL(statusBarChanged(const QString
&)), this, SIGNAL(statusBarChanged(const QString
&)));
371 logViewExport
.fileSave();
374 void TabLogViewsWidget::copyToClipboardCurrentView() {
375 LogViewExport
logViewExport(this, activeLogManager()->usedView()->logViewWidget());
376 connect(&logViewExport
, SIGNAL(statusBarChanged(const QString
&)), this, SIGNAL(statusBarChanged(const QString
&)));
377 logViewExport
.copyToClipboard();
379 void TabLogViewsWidget::sendMailCurrentView() {
380 LogViewExport
logViewExport(this, activeLogManager()->usedView()->logViewWidget());
381 connect(&logViewExport
, SIGNAL(statusBarChanged(const QString
&)), this, SIGNAL(statusBarChanged(const QString
&)));
382 logViewExport
.sendMail();
384 void TabLogViewsWidget::printSelectionCurrentView() {
385 LogViewExport
logViewExport(this, activeLogManager()->usedView()->logViewWidget());
386 connect(&logViewExport
, SIGNAL(statusBarChanged(const QString
&)), this, SIGNAL(statusBarChanged(const QString
&)));
387 logViewExport
.printSelection();
390 QIcon
TabLogViewsWidget::logModeIcon(LogMode
* logMode
) {
391 if ( logMode
== NULL
)
392 return KIcon(NO_MODE_ICON
);
394 return logMode
->icon();
398 void TabLogViewsWidget::prepareContextMenu(bool /*onTab*/) {
399 if (d
->contextMenu
== NULL
) {
400 d
->contextMenu
= new QMenu(this);
401 d
->contextMenu
->addActions(actions());
404 //TODO Disable some actions, depending of the onTab value
407 void TabLogViewsWidget::showContextMenu(const QPoint
& cursorPosition
) {
408 logDebug() << "Showing context menu at " << cursorPosition
<< endl
;
410 prepareContextMenu(false);
412 d
->contextMenu
->popup(cursorPosition
);
416 void TabLogViewsWidget::showContextMenu(QWidget
* tab
, const QPoint
& cursorPosition
) {
417 logDebug() << "Showing context menu at " << cursorPosition
<< " at " << tab
->objectName() << endl
;
419 prepareContextMenu(true);
421 d
->contextMenu
->popup(cursorPosition
);
424 #include "tabLogViewsWidget.moc"