/* This file is part of the KDE project Copyright 2007 Hamish Rodda This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "statusbar.h" #include "progresswidget/statusbarprogresswidget.h" #include "progresswidget/progressmanager.h" #include "progresswidget/progressdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include "plugincontroller.h" #include "core.h" namespace KDevelop { StatusBar::StatusBar(QWidget* parent) : KStatusBar(parent) , m_timer(new QTimer(this)) , m_currentView(0) , m_errorRemovalMapper(new QSignalMapper(this)) { m_timer->setSingleShot(true); connect(m_timer, SIGNAL(timeout()), SLOT(slotTimeout())); connect(Core::self()->pluginController(), SIGNAL(pluginLoaded(KDevelop::IPlugin*)), SLOT(pluginLoaded(KDevelop::IPlugin*))); foreach (IPlugin* plugin, Core::self()->pluginControllerInternal()->allPluginsForExtension("IStatus")) registerStatus(plugin); registerStatus(Core::self()->languageController()->backgroundParser()); connect(m_errorRemovalMapper, SIGNAL(mapped(QWidget*)), SLOT(removeError(QWidget*))); m_progressController = Core::self()->progressController(); m_progressDialog = new ProgressDialog(this, parent); // construct this first, then progressWidget m_progressDialog->setVisible(false); m_progressWidget = new StatusbarProgressWidget(m_progressDialog, this); addPermanentWidget(m_progressWidget, 0); } void StatusBar::removeError(QWidget* w) { removeWidget(w); w->deleteLater(); } void StatusBar::viewChanged(Sublime::View* view) { if (m_currentView) m_currentView->disconnect(this); m_currentView = view; if (view) { connect(view, SIGNAL(statusChanged(Sublime::View*)), this, SLOT(viewStatusChanged(Sublime::View*))); changeItem(view->viewStatus(), 0); } } void StatusBar::viewStatusChanged(Sublime::View* view) { changeItem(view->viewStatus(), 0); } void StatusBar::pluginLoaded(IPlugin* plugin) { if (qobject_cast(plugin)) registerStatus(plugin); } void StatusBar::registerStatus(QObject* status) { Q_ASSERT(qobject_cast(status)); connect(status, SIGNAL(clearMessage(KDevelop::IStatus*)), SLOT(clearMessage(KDevelop::IStatus*)), Qt::QueuedConnection); connect(status, SIGNAL(showMessage(KDevelop::IStatus*,QString,int)), SLOT(showMessage(KDevelop::IStatus*,QString,int)), Qt::QueuedConnection); connect(status, SIGNAL(hideProgress(KDevelop::IStatus*)), SLOT(hideProgress(KDevelop::IStatus*)), Qt::QueuedConnection); connect(status, SIGNAL(showProgress(KDevelop::IStatus*,int,int,int)), SLOT(showProgress(KDevelop::IStatus*,int,int,int)), Qt::QueuedConnection); // Don't try to connect when the status object doesn't provide an error message signal (ie. avoid warning) if (status->metaObject()->indexOfSignal(SIGNAL(showErrorMessage(QString,int))) != -1) { connect(status, SIGNAL(showErrorMessage(QString,int)), SLOT(showErrorMessage(QString,int)), Qt::QueuedConnection); } } QWidget* errorMessage(QWidget* parent, const QString& text) { KSqueezedTextLabel* label = new KSqueezedTextLabel(parent); KStatefulBrush red(KColorScheme::Window, KColorScheme::NegativeText); QPalette pal = label->palette(); pal.setBrush(QPalette::WindowText, red.brush(label)); label->setPalette(pal); label->setAlignment(Qt::AlignRight); label->setText(text); label->setToolTip(text); return label; } QTimer* StatusBar::errorTimeout(QWidget* error, int timeout) { QTimer* timer = new QTimer(error); timer->setSingleShot(true); timer->setInterval(1000*timeout); m_errorRemovalMapper->setMapping(timer, error); connect(timer, SIGNAL(timeout()), m_errorRemovalMapper, SLOT(map())); return timer; } void StatusBar::showErrorMessage(const QString& message, int timeout) { QWidget* error = errorMessage(this, message); QTimer* timer = errorTimeout(error, timeout); addWidget(error); timer->start(); // triggers removeError() } void StatusBar::slotTimeout() { QMutableMapIterator it = m_messages; while (it.hasNext()) { it.next(); if (it.value().timeout) { it.value().timeout -= m_timer->interval(); if (it.value().timeout == 0) it.remove(); } } updateMessage(); } void StatusBar::updateMessage() { if (m_timer->isActive()) { m_timer->stop(); m_timer->setInterval(m_time.elapsed()); slotTimeout(); } QString ret; int timeout = 0; foreach (const Message& m, m_messages) { if (!ret.isEmpty()) ret += "; "; ret += m.text; if (timeout) timeout = qMin(timeout, m.timeout); else timeout = m.timeout; } if (!ret.isEmpty()) KStatusBar::showMessage(ret); else KStatusBar::clearMessage(); if (timeout) { m_time.start(); m_timer->start(timeout); } } void StatusBar::clearMessage( IStatus* status ) { if (m_messages.contains(status)) { m_messages.remove(status); updateMessage(); } } void StatusBar::showMessage( IStatus* status, const QString & message, int timeout) { if ( m_progressItems.contains(status) ) { ProgressItem* i = m_progressItems[status]; i->setStatus(message); } else { Message m; m.text = message; m.timeout = timeout; m_messages.insert(status, m); updateMessage(); } } void StatusBar::hideProgress( IStatus* status ) { if (m_progressItems.contains(status)) { m_progressItems[status]->setComplete(); m_progressItems.remove(status); } } void StatusBar::showProgress( IStatus* status, int minimum, int maximum, int value) { if (!m_progressItems.contains(status)) { bool canBeCanceled = false; m_progressItems[status] = m_progressController->createProgressItem( ProgressManager::getUniqueID(), status->statusName(), QString(), canBeCanceled);; } ProgressItem* i = m_progressItems[status]; m_progressWidget->raise(); m_progressDialog->raise(); if( minimum == 0 && maximum == 0 ) { i->setUsesBusyIndicator( true ); } else { i->setUsesBusyIndicator( false ); i->setProgress( 100*value/maximum ); } } } #include "moc_statusbar.cpp"