diff --git a/plugins/standardoutputview/outputwidget.cpp b/plugins/standardoutputview/outputwidget.cpp index 7f248c4924..dc1d79048a 100644 --- a/plugins/standardoutputview/outputwidget.cpp +++ b/plugins/standardoutputview/outputwidget.cpp @@ -1,629 +1,637 @@ /* This file is part of KDevelop * * Copyright 2007 Andreas Pakulat * Copyright 2007 Dukju Ahn * * 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. */ #include "outputwidget.h" #include "standardoutputview.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include +#include #include #include #include "toolviewdata.h" OutputWidget::OutputWidget(QWidget* parent, const ToolViewData* tvdata) : QWidget( parent ) , tabwidget(0) , stackwidget(0) , data(tvdata) , m_closeButton(0) , m_closeOthersAction(0) , nextAction(0) , previousAction(0) , activateOnSelect(0) , focusOnSelect(0) , filterInput(0) , filterAction(0) { setWindowTitle(i18n("Output View")); setWindowIcon(tvdata->icon); QVBoxLayout* layout = new QVBoxLayout(this); layout->setMargin(0); if( data->type & KDevelop::IOutputView::MultipleView ) { tabwidget = new KTabWidget(this); layout->addWidget( tabwidget ); m_closeButton = new QToolButton( this ); connect( m_closeButton, SIGNAL(clicked()), SLOT(closeActiveView()) ); m_closeButton->setIcon( KIcon("tab-close") ); m_closeButton->setToolTip( i18n( "Close the currently active output view") ); m_closeOthersAction = new QAction( this ); connect(m_closeOthersAction, SIGNAL(triggered(bool)), SLOT(closeOtherViews())); m_closeOthersAction->setIcon(KIcon("tab-close-other")); m_closeOthersAction->setToolTip( i18n( "Close all other output views" ) ); m_closeOthersAction->setText( m_closeOthersAction->toolTip() ); addAction(m_closeOthersAction); tabwidget->setCornerWidget(m_closeButton, Qt::TopRightCorner); } else if ( data->type == KDevelop::IOutputView::HistoryView ) { stackwidget = new QStackedWidget( this ); layout->addWidget( stackwidget ); previousAction = new KAction( KIcon( "go-previous" ), i18n("Previous"), this ); connect(previousAction, SIGNAL(triggered()), this, SLOT(previousOutput())); addAction(previousAction); nextAction = new KAction( KIcon( "go-next" ), i18n("Next"), this ); connect(nextAction, SIGNAL(triggered()), this, SLOT(nextOutput())); addAction(nextAction); } + prevmarkAction = dynamic_cast(data->plugin->actionCollection()->action("prev_error")); + connect(prevmarkAction, SIGNAL(triggered()), this, SLOT(selectPrevItem())); + addAction(prevmarkAction); + nextmarkAction = dynamic_cast(data->plugin->actionCollection()->action("next_error")); + connect(nextmarkAction, SIGNAL(triggered()), this, SLOT(selectNextItem())); + addAction(nextmarkAction); + activateOnSelect = new KToggleAction( KIcon(), i18n("Select activated Item"), this ); activateOnSelect->setChecked( true ); focusOnSelect = new KToggleAction( KIcon(), i18n("Focus when selecting Item"), this ); focusOnSelect->setChecked( false ); if( data->option & KDevelop::IOutputView::ShowItemsButton ) { addAction(activateOnSelect); addAction(focusOnSelect); } QAction *separator = new QAction(this); separator->setSeparator(true); KAction *selectAllAction = KStandardAction::selectAll(this, SLOT(selectAll()), this); selectAllAction->setShortcut(KShortcut()); //FIXME: why does CTRL-A conflict with Katepart (while CTRL-Cbelow doesn't) ? selectAllAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); addAction(selectAllAction); KAction *copyAction = KStandardAction::copy(this, SLOT(copySelection()), this); copyAction->setShortcutContext(Qt::WidgetWithChildrenShortcut); addAction(copyAction); if( data->option & KDevelop::IOutputView::AddFilterAction ) { addAction(separator); filterInput = new KLineEdit(); filterInput->setMaximumWidth(150); filterInput->setMinimumWidth(100); filterInput->setClickMessage(i18n("Search...")); filterInput->setClearButtonShown(true); filterInput->setToolTip(i18n("Enter a wild card string to filter the output view")); filterAction = new QWidgetAction(this); filterAction->setDefaultWidget(filterInput); addAction(filterAction); connect(filterInput, SIGNAL(textEdited(QString)), this, SLOT(outputFilter(QString)) ); if( data->type & KDevelop::IOutputView::MultipleView ) { connect(tabwidget, SIGNAL(currentChanged(int)), this, SLOT(updateFilter(int))); } else if ( data->type == KDevelop::IOutputView::HistoryView ) { connect(stackwidget, SIGNAL(currentChanged(int)), this, SLOT(updateFilter(int))); } } addActions(data->actionList); connect( data, SIGNAL(outputAdded(int)), this, SLOT(addOutput(int)) ); connect( this, SIGNAL(outputRemoved(int,int)), data->plugin, SIGNAL(outputRemoved(int,int)) ); connect( data->plugin, SIGNAL(selectNextItem()), this, SLOT(selectNextItem()) ); connect( data->plugin, SIGNAL(selectPrevItem()), this, SLOT(selectPrevItem()) ); foreach( int id, data->outputdata.keys() ) { changeModel( id ); changeDelegate( id ); } enableActions(); } void OutputWidget::addOutput( int id ) { QTreeView* listview = createListView(id); setCurrentWidget( listview ); connect( data->outputdata.value(id), SIGNAL(modelChanged(int)), this, SLOT(changeModel(int))); connect( data->outputdata.value(id), SIGNAL(delegateChanged(int)), this, SLOT(changeDelegate(int))); enableActions(); } void OutputWidget::setCurrentWidget( QTreeView* view ) { if( data->type & KDevelop::IOutputView::MultipleView ) { tabwidget->setCurrentWidget( view ); } else if( data->type & KDevelop::IOutputView::HistoryView ) { stackwidget->setCurrentWidget( view ); } } void OutputWidget::changeDelegate( int id ) { if( data->outputdata.contains( id ) && views.contains( id ) ) { views.value(id)->setItemDelegate(data->outputdata.value(id)->delegate); } else { addOutput(id); } } void OutputWidget::changeModel( int id ) { if( data->outputdata.contains( id ) && views.contains( id ) ) { OutputData* od = data->outputdata.value(id); views.value( id )->setModel(od->model); if (!od->model) return; disconnect( od->model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted(QModelIndex,int,int)) ); if( od->behaviour & KDevelop::IOutputView::AutoScroll ) { connect( od->model,SIGNAL(rowsInserted(QModelIndex,int,int)), SLOT(rowsInserted(QModelIndex,int,int)) ); } } else { addOutput( id ); } } void OutputWidget::removeOutput( int id ) { if( data->outputdata.contains( id ) && views.contains( id ) ) { if( data->type & KDevelop::IOutputView::MultipleView || data->type & KDevelop::IOutputView::HistoryView ) { QTreeView* w = views.value(id); if( data->type & KDevelop::IOutputView::MultipleView ) { int idx = tabwidget->indexOf( w ); if( idx != -1 ) { tabwidget->removeTab( idx ); if( proxyModels.contains( idx ) ) { delete proxyModels.take( idx ); filters.remove( idx ); } } } else { int idx = stackwidget->indexOf( w ); if( idx != -1 && proxyModels.contains( idx ) ) { delete proxyModels.take( idx ); filters.remove( idx ); } stackwidget->removeWidget( w ); } delete w; views.remove( id ); } else { views.value( id )->setModel( 0 ); views.value( id )->setItemDelegate( 0 ); if( proxyModels.contains( 0 ) ) { delete proxyModels.take( 0 ); filters.remove( 0 ); } } disconnect( data->outputdata.value( id )->model,SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(rowsInserted(QModelIndex,int,int)) ); views.remove( id ); emit outputRemoved( data->toolViewId, id ); } enableActions(); } void OutputWidget::closeActiveView() { QWidget* widget = tabwidget->currentWidget(); if( !widget ) return; foreach( int id, views.keys() ) { if( views.value(id) == widget ) { OutputData* od = data->outputdata.value(id); if( od->behaviour & KDevelop::IOutputView::AllowUserClose ) { data->plugin->removeOutput( id ); } } } enableActions(); } void OutputWidget::closeOtherViews() { QWidget* widget = tabwidget->currentWidget(); if (!widget) return; foreach (int id, views.keys()) { if (views.value(id) == widget) { continue; // leave the active view open } OutputData* od = data->outputdata.value(id); if (od->behaviour & KDevelop::IOutputView::AllowUserClose) { data->plugin->removeOutput( id ); } } enableActions(); } QWidget* OutputWidget::currentWidget() const { QWidget* widget; if( data->type & KDevelop::IOutputView::MultipleView ) { widget = tabwidget->currentWidget(); } else if( data->type & KDevelop::IOutputView::HistoryView ) { widget = stackwidget->currentWidget(); } else { widget = views.begin().value(); } return widget; } KDevelop::IOutputViewModel *OutputWidget::outputViewModel() const { QWidget* widget = currentWidget(); if( !widget || !widget->isVisible() ) return nullptr; auto view = qobject_cast(widget); if( !view ) return nullptr; QAbstractItemModel *absmodel = view->model(); KDevelop::IOutputViewModel *iface = dynamic_cast(absmodel); if ( ! iface ) { // try if it's a proxy model? if ( QAbstractProxyModel* proxy = qobject_cast(absmodel) ) { iface = dynamic_cast(proxy->sourceModel()); } } return iface; } void OutputWidget::eventuallyDoFocus() { QWidget* widget = currentWidget(); if( focusOnSelect->isChecked() && !widget->hasFocus() ) { widget->setFocus( Qt::OtherFocusReason ); } } QAbstractItemView *OutputWidget::outputView() const { auto widget = currentWidget(); return qobject_cast(widget); } void OutputWidget::activateIndex(const QModelIndex &index, QAbstractItemView *view, KDevelop::IOutputViewModel *iface) { if( ! index.isValid() ) return; view->setCurrentIndex( index ); view->scrollTo( index ); int tabIndex = currentOutputIndex(); QModelIndex mapped = index; if( QAbstractProxyModel* proxy = proxyModels.value(tabIndex) ) { if ( index.model() == proxy ) { mapped = proxy->mapToSource(index); } } if( activateOnSelect->isChecked() ) { iface->activate( mapped ); } } void OutputWidget::selectNextItem() { auto view = outputView(); auto iface = outputViewModel(); if ( ! view || ! iface ) return; eventuallyDoFocus(); kDebug() << "selecting next item"; QModelIndex index = iface->nextHighlightIndex( view->currentIndex() ); activateIndex(index, view, iface); } void OutputWidget::selectPrevItem() { auto view = outputView(); auto iface = outputViewModel(); if ( ! view || ! iface ) return; eventuallyDoFocus(); kDebug() << "activating previous item"; QModelIndex index = iface->previousHighlightIndex( view->currentIndex() ); activateIndex(index, view, iface); } void OutputWidget::activate(const QModelIndex& index) { auto iface = outputViewModel(); auto view = outputView(); if( ! view || ! iface ) return; activateIndex(index, view, iface); } static QTreeView* createFocusedTreeView( QWidget* parent ) { QTreeView* listview = new KDevelop::FocusedTreeView(parent); listview->setEditTriggers( QAbstractItemView::NoEditTriggers ); listview->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); //Always enable the scrollbar, so it doesn't flash around listview->setHeaderHidden(true); listview->setUniformRowHeights(true); listview->setRootIsDecorated(false); listview->setSelectionMode( QAbstractItemView::ContiguousSelection ); return listview; } QTreeView* OutputWidget::createListView(int id) { QTreeView* listview = 0; if( !views.contains(id) ) { if( data->type & KDevelop::IOutputView::MultipleView || data->type & KDevelop::IOutputView::HistoryView ) { kDebug() << "creating listview"; listview = createFocusedTreeView(this); views[id] = listview; connect( listview, SIGNAL(activated(QModelIndex)), this, SLOT(activate(QModelIndex))); connect( listview, SIGNAL(clicked(QModelIndex)), this, SLOT(activate(QModelIndex))); if( data->type & KDevelop::IOutputView::MultipleView ) { tabwidget->addTab( listview, data->outputdata.value(id)->title ); } else { stackwidget->addWidget( listview ); stackwidget->setCurrentWidget( listview ); } } else { if( views.isEmpty() ) { listview = createFocusedTreeView(this); layout()->addWidget( listview ); connect( listview, SIGNAL(activated(QModelIndex)), this, SLOT(activate(QModelIndex))); connect( listview, SIGNAL(clicked(QModelIndex)), this, SLOT(activate(QModelIndex))); } else { listview = views.begin().value(); } views[id] = listview; } changeModel( id ); changeDelegate( id ); } else { listview = views.value(id); } enableActions(); return listview; } void OutputWidget::raiseOutput(int id) { if( views.contains(id) ) { if( data->type & KDevelop::IOutputView::MultipleView ) { int idx = tabwidget->indexOf( views.value(id) ); if( idx >= 0 ) { tabwidget->setCurrentIndex( idx ); } } else if( data->type & KDevelop::IOutputView::HistoryView ) { int idx = stackwidget->indexOf( views.value(id) ); if( idx >= 0 ) { stackwidget->setCurrentIndex( idx ); } } } enableActions(); } void OutputWidget::nextOutput() { if( stackwidget && stackwidget->currentIndex() < stackwidget->count()-1 ) { stackwidget->setCurrentIndex( stackwidget->currentIndex()+1 ); } enableActions(); } void OutputWidget::previousOutput() { if( stackwidget && stackwidget->currentIndex() > 0 ) { stackwidget->setCurrentIndex( stackwidget->currentIndex()-1 ); } enableActions(); } void OutputWidget::enableActions() { if( data->type == KDevelop::IOutputView::HistoryView ) { Q_ASSERT(stackwidget); Q_ASSERT(nextAction); Q_ASSERT(previousAction); previousAction->setEnabled( ( stackwidget->currentIndex() > 0 ) ); nextAction->setEnabled( ( stackwidget->currentIndex() < stackwidget->count() - 1 ) ); } } void OutputWidget::rowsInserted(const QModelIndex& parent, int from, int to) { Q_UNUSED(parent); for( QMap< int, QTreeView* >::const_iterator it = views.constBegin(); it != views.constEnd(); ++it) { if((*it)->model() == sender()) { QModelIndex pre = (*it)->model()->index(from-1, 0); if(!pre.isValid() || ((*it)->visualRect(pre).isValid() && (*it)->viewport()->rect().intersects((*it)->visualRect(pre)) && to == (*it)->model()->rowCount()-1)) { (*it)->scrollToBottom(); } } } } void OutputWidget::scrollToIndex( const QModelIndex& idx ) { QWidget* w = currentWidget(); if( !w ) return; QAbstractItemView *view = dynamic_cast(w); view->scrollTo( idx ); } void OutputWidget::copySelection() { QWidget* widget = currentWidget(); if( !widget ) return; QAbstractItemView *view = dynamic_cast(widget); if( !view ) return; QClipboard *cb = QApplication::clipboard(); QModelIndexList indexes = view->selectionModel()->selectedRows(); QString content; Q_FOREACH( const QModelIndex& index, indexes) { content += view->model()->data(index).toString() + '\n'; } cb->setText(content); } void OutputWidget::selectAll() { QWidget* widget = currentWidget(); if( !widget ) return; QAbstractItemView *view = dynamic_cast(widget); if( !view ) return; view->selectAll(); } int OutputWidget::currentOutputIndex() { int index = 0; if( data->type & KDevelop::IOutputView::MultipleView ) { index = tabwidget->currentIndex(); } else if( data->type & KDevelop::IOutputView::HistoryView ) { index = stackwidget->currentIndex(); } return index; } void OutputWidget::outputFilter(const QString filter) { QWidget* widget = currentWidget(); if( !widget ) return; QAbstractItemView *view = dynamic_cast(widget); if( !view ) return; int index = currentOutputIndex(); if( !dynamic_cast(view->model()) ) { QSortFilterProxyModel* _proxyModel = new QSortFilterProxyModel(view->model()); _proxyModel->setDynamicSortFilter(true); _proxyModel->setSourceModel(view->model()); proxyModels.insert(index, _proxyModel); view->setModel(_proxyModel); } QRegExp regExp(filter,Qt::CaseInsensitive); proxyModels[index]->setFilterRegExp(regExp); filters[index] = filter; } void OutputWidget::updateFilter(int index) { if(filters.contains(index)) { filterInput->setText(filters[index]); } else { filterInput->clear(); } } #include "outputwidget.moc" diff --git a/plugins/standardoutputview/outputwidget.h b/plugins/standardoutputview/outputwidget.h index 98cd94988b..b265db4a2d 100644 --- a/plugins/standardoutputview/outputwidget.h +++ b/plugins/standardoutputview/outputwidget.h @@ -1,110 +1,112 @@ /* This file is part of KDevelop * * Copyright 2007 Andreas Pakulat * Copyright 2007 Dukju Ahn * * 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. */ #ifndef KDEVPLATFORM_PLUGIN_OUTPUTWIDGET_H #define KDEVPLATFORM_PLUGIN_OUTPUTWIDGET_H #include #include #include #include class QAbstractProxyModel; class QAbstractItemView; class QString; class StandardOutputView; class QSignalMapper; class QStackedWidget; class QTreeView; class QToolButton; class QWidgetAction; class QSortFilterProxyModel; class QModelIndex; class ToolViewData; class KTabWidget; class KToggleAction; class KAction; class KLineEdit; class StandardOutputViewTest; class OutputWidget : public QWidget { Q_OBJECT friend class StandardOutputViewTest; public: OutputWidget(QWidget* parent, const ToolViewData* data); void removeOutput( int id ); void raiseOutput( int id ); public Q_SLOTS: void addOutput( int id ); void changeModel( int id ); void changeDelegate( int id ); void closeActiveView(); void closeOtherViews(); void selectNextItem(); void selectPrevItem(); void activate(const QModelIndex&); void scrollToIndex( const QModelIndex& ); Q_SIGNALS: void outputRemoved( int, int ); private slots: void nextOutput(); void previousOutput(); void rowsInserted(const QModelIndex&, int, int); void copySelection(); void selectAll(); void outputFilter(const QString filter); void updateFilter(int index); private: QTreeView* createListView(int id); void setCurrentWidget( QTreeView* view ); QWidget* currentWidget() const; void enableActions(); KDevelop::IOutputViewModel* outputViewModel() const; QAbstractItemView* outputView() const; void activateIndex(const QModelIndex& index, QAbstractItemView* view, KDevelop::IOutputViewModel* iface); void eventuallyDoFocus(); int currentOutputIndex(); QMap views; QMap scrollTimers; QMap proxyModels; QMap filters; KTabWidget* tabwidget; QStackedWidget* stackwidget; const ToolViewData* data; QToolButton* m_closeButton; QAction* m_closeOthersAction; KAction* nextAction; KAction* previousAction; KToggleAction* activateOnSelect; KToggleAction* focusOnSelect; KLineEdit *filterInput; QWidgetAction* filterAction; + KAction* prevmarkAction; + KAction* nextmarkAction; }; #endif diff --git a/plugins/standardoutputview/standardoutputview.cpp b/plugins/standardoutputview/standardoutputview.cpp index 60379a9a90..03a2925359 100644 --- a/plugins/standardoutputview/standardoutputview.cpp +++ b/plugins/standardoutputview/standardoutputview.cpp @@ -1,334 +1,336 @@ /* KDevelop Standard OutputView * * Copyright 2006-2007 Andreas Pakulat * Copyright 2007 Dukju Ahn * * 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. */ #include "standardoutputview.h" #include "outputwidget.h" #include "toolviewdata.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY(StandardOutputViewFactory, registerPlugin(); ) K_EXPORT_PLUGIN(StandardOutputViewFactory(KAboutData("kdevstandardoutputview","kdevstandardoutputview",ki18n("Output View"), "0.1", ki18n("Provides toolviews for presenting the output of running apps"), KAboutData::License_GPL))) class OutputViewFactory : public KDevelop::IToolViewFactory{ public: OutputViewFactory(const ToolViewData* data): m_data(data) {} virtual QWidget* create(QWidget *parent = 0) { return new OutputWidget( parent, m_data ); } virtual Qt::DockWidgetArea defaultPosition() { return Qt::BottomDockWidgetArea; } virtual void viewCreated( Sublime::View* view ) { m_data->views << view; } virtual QString id() const { //NOTE: id must be unique, see e.g. https://bugs.kde.org/show_bug.cgi?id=287093 return "org.kdevelop.OutputView." + QString::number(m_data->toolViewId); } private: const ToolViewData *m_data; }; StandardOutputView::StandardOutputView(QObject *parent, const QVariantList &) : KDevelop::IPlugin(StandardOutputViewFactory::componentData(), parent) { KDEV_USE_EXTENSION_INTERFACE( KDevelop::IOutputView ) setXMLFile("kdevstandardoutputview.rc"); // setup actions KAction *action; action = actionCollection()->addAction("next_error"); action->setText(i18n("Jump to Next Outputmark")); action->setShortcut( QKeySequence(Qt::Key_F4) ); + action->setIcon(KIcon("arrow-right")); connect(action, SIGNAL(triggered(bool)), this, SIGNAL(selectNextItem())); action = actionCollection()->addAction("prev_error"); action->setText(i18n("Jump to Previous Outputmark")); action->setShortcut( QKeySequence(Qt::SHIFT | Qt::Key_F4) ); + action->setIcon(KIcon("arrow-left")); connect(action, SIGNAL(triggered(bool)), this, SIGNAL(selectPrevItem())); connect(KDevelop::ICore::self()->uiController()->controller(), SIGNAL(aboutToRemoveView(Sublime::View*)), this, SLOT(removeSublimeView(Sublime::View*))); } void StandardOutputView::removeSublimeView( Sublime::View* v ) { foreach( ToolViewData* d, toolviews ) { if( d->views.contains(v) ) { if( d->views.count() == 1 ) { toolviews.remove( d->toolViewId ); ids.removeAll( d->toolViewId ); delete d; } else { d->views.removeAll(v); } } } } StandardOutputView::~StandardOutputView() { } int StandardOutputView::standardToolView( KDevelop::IOutputView::StandardToolView view ) { if( standardViews.contains( view ) ) { return standardViews.value( view ); } int ret = -1; switch( view ) { case KDevelop::IOutputView::BuildView: { ret = registerToolView( i18nc("@title:window", "Build"), KDevelop::IOutputView::HistoryView, KIcon("run-build"), KDevelop::IOutputView::AddFilterAction ); break; } case KDevelop::IOutputView::RunView: { ret = registerToolView( i18nc("@title:window", "Run"), KDevelop::IOutputView::MultipleView, KIcon("system-run"), KDevelop::IOutputView::AddFilterAction ); break; } case KDevelop::IOutputView::DebugView: { ret = registerToolView( i18nc("@title:window", "Debug"), KDevelop::IOutputView::MultipleView, KIcon("debugger"), KDevelop::IOutputView::AddFilterAction ); break; } case KDevelop::IOutputView::TestView: { ret = registerToolView( i18nc("@title:window", "Test"), KDevelop::IOutputView::HistoryView, KIcon("system-run")); break; } case KDevelop::IOutputView::VcsView: { ret = registerToolView( i18nc("@title:window", "Version Control"), KDevelop::IOutputView::HistoryView, KIcon("system-run")); break; } } Q_ASSERT(ret != -1); standardViews[view] = ret; return ret; } int StandardOutputView::registerToolView( const QString& title, KDevelop::IOutputView::ViewType type, const KIcon& icon, Options option, const QList& actionList ) { // try to reuse existing toolview foreach( ToolViewData* d, toolviews ) { if ( d->type == type && d->title == title ) { return d->toolViewId; } } // register new tool view const int newid = ids.isEmpty() ? 0 : (ids.last() + 1); kDebug() << "Registering view" << title << "with type:" << type << "id:" << newid; ToolViewData* tvdata = new ToolViewData( this ); tvdata->toolViewId = newid; tvdata->type = type; tvdata->title = title; tvdata->icon = icon; tvdata->plugin = this; tvdata->option = option; tvdata->actionList = actionList; core()->uiController()->addToolView( title, new OutputViewFactory( tvdata ) ); ids << newid; toolviews[newid] = tvdata; return newid; } int StandardOutputView::registerOutputInToolView( int toolViewId, const QString& title, KDevelop::IOutputView::Behaviours behaviour ) { if( !toolviews.contains( toolViewId ) ) return -1; int newid; if( ids.isEmpty() ) { newid = 0; } else { newid = ids.last()+1; } ids << newid; toolviews.value( toolViewId )->addOutput( newid, title, behaviour ); return newid; } void StandardOutputView::raiseOutput(int outputId) { foreach( int _id, toolviews.keys() ) { if( toolviews.value( _id )->outputdata.contains( outputId ) ) { foreach( Sublime::View* v, toolviews.value( _id )->views ) { if( v->hasWidget() ) { OutputWidget* w = qobject_cast( v->widget() ); w->raiseOutput( outputId ); v->requestRaise(); } } } } } void StandardOutputView::setModel( int outputId, QAbstractItemModel* model ) { int tvid = -1; foreach( int _id, toolviews.keys() ) { if( toolviews.value( _id )->outputdata.contains( outputId ) ) { tvid = _id; break; } } if( tvid == -1 ) kDebug() << "Trying to set model on unknown view-id:" << outputId; else { toolviews.value( tvid )->outputdata.value( outputId )->setModel( model ); } } void StandardOutputView::setDelegate( int outputId, QAbstractItemDelegate* delegate ) { int tvid = -1; foreach( int _id, toolviews.keys() ) { if( toolviews.value( _id )->outputdata.contains( outputId ) ) { tvid = _id; break; } } if( tvid == -1 ) kDebug() << "Trying to set model on unknown view-id:" << outputId; else { toolviews.value( tvid )->outputdata.value( outputId )->setDelegate( delegate ); } } void StandardOutputView::removeToolView( int toolviewId ) { if( toolviews.contains(toolviewId) ) { ToolViewData* td = toolviews.value(toolviewId); foreach( Sublime::View* view, td->views ) { if( view->hasWidget() ) { OutputWidget* outputWidget = qobject_cast( view->widget() ); foreach( int outid, td->outputdata.keys() ) { outputWidget->removeOutput( outid ); } } foreach( Sublime::Area* area, KDevelop::ICore::self()->uiController()->controller()->allAreas() ) { area->removeToolView( view ); } } delete td; toolviews.remove(toolviewId); emit toolViewRemoved(toolviewId); } } OutputWidget* StandardOutputView::outputWidgetForId( int outputId ) const { foreach( ToolViewData* td, toolviews ) { if( td->outputdata.contains( outputId ) ) { foreach( Sublime::View* view, td->views ) { if( view->hasWidget() ) return qobject_cast( view->widget() ); } } } return 0; } void StandardOutputView::scrollOutputTo( int outputId, const QModelIndex& idx ) { OutputWidget* widget = outputWidgetForId( outputId ); if( widget ) widget->scrollToIndex( idx ); } void StandardOutputView::removeOutput( int outputId ) { foreach( ToolViewData* td, toolviews ) { if( td->outputdata.contains( outputId ) ) { foreach( Sublime::View* view, td->views ) { if( view->hasWidget() ) qobject_cast( view->widget() )->removeOutput( outputId ); } td->outputdata.remove( outputId ); } } } #include "standardoutputview.moc"