/********************************************************************************
 * Copyright (C) 2019 Ericsson and others.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the Eclipse
 * Public License v. 2.0 are satisfied: GNU General Public License, version 2
 * with the GNU Classpath Exception which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 ********************************************************************************/ import { inject , injectable , postConstruct } from '@theia/core/shared/inversify' ; import { Diagnostic , DiagnosticSeverity } from '@theia/core/shared/vscode-languageserver-protocol' ; import { Event , Emitter } from '@theia/core/lib/common/event' ; import { Title , Widget } from '@theia/core/shared/@phosphor/widgets' ; import { WidgetDecoration } from '@theia/core/lib/browser/widget-decoration' ; import { TabBarDecorator } from '@theia/core/lib/browser/shell/tab-bar-decorator' ; import { Marker } from '../../common/marker' ; import { ProblemManager } from './problem-manager' ; import { ProblemPreferences , ProblemConfiguration } from './problem-preferences' ; import { PreferenceChangeEvent , Navigatable } from '@theia/core/lib/browser' ; @ injectable ( ) export class ProblemTabBarDecorator implements TabBarDecorator { readonly id = 'theia-problem-tabbar-decorator' ; protected readonly emitter = new Emitter < void > ( ) ; @ inject ( ProblemPreferences ) protected readonly preferences : ProblemPreferences ; @ inject ( ProblemManager ) protected readonly problemManager : ProblemManager ; @ postConstruct ( ) protected init ( ) { this . problemManager . onDidChangeMarkers ( ( ) => this . fireDidChangeDecorations ( ) ) ; this . preferences . onPreferenceChanged ( event => this . handlePreferenceChange ( event ) ) ; } decorate ( title ) { if ( ! this . preferences [ 'problems.decorations.tabbar.enabled' ] ) { return [ ] ; } const widget = title . owner ; if ( Navigatable . is ( widget ) ) { const resourceUri = widget . getResourceUri ( ) ; if ( resourceUri ) { const markers = this . problemManager . findMarkers ( { uri : resourceUri } ) ; if ( markers . length === 0 ) { return [ ] ; } let maxSeverity ; for ( const marker of markers ) { if ( marker . data . severity === DiagnosticSeverity . Error ) { maxSeverity = marker ; break ; } else if ( marker . data . severity === DiagnosticSeverity . Warning ) { maxSeverity = marker ; } } return maxSeverity ? [ this . toDecorator ( maxSeverity ) ] : [ ] ; } } return [ ] ; } get onDidChangeDecorations ( ) : Event < void > { return this . emitter . event ; } protected fireDidChangeDecorations ( ) { this . emitter . fire ( undefined ) ; } param { PreferenceChangeEvent < ProblemConfiguration > } event protected async handlePreferenceChange ( event ) { const { preferenceName } = event ; if ( preferenceName === 'problems.decorations.tabbar.enabled' ) { this . fireDidChangeDecorations ( ) ; } } param { Marker < Diagnostic > } marker returns { WidgetDecoration . Data } protected toDecorator ( marker ) { const position = WidgetDecoration . IconOverlayPosition . BOTTOM_RIGHT ; const icon = this . getOverlayIcon ( marker ) ; const color = this . getOverlayIconColor ( marker ) ; return { iconOverlay : { position , icon , color , background : { shape : 'circle' , color : 'transparent' } } } ; } param { Marker < Diagnostic > } marker returns { string } protected getOverlayIcon ( marker ) { const { severity } = marker . data ; switch ( severity ) { case 1 : return 'times-circle' ; case 2 : return 'exclamation-circle' ; case 3 : return 'info-circle' ; default : return 'hand-o-up' ; } } param { Marker < Diagnostic > } marker returns { WidgetDecoration . Color } protected getOverlayIconColor ( marker ) { const { severity } = marker . data ; switch ( severity ) { case 1 : return 'var(--theia-editorError-foreground)' ; case 2 : return 'var(--theia-editorWarning-foreground)' ; case 3 : return 'var(--theia-editorInfo-foreground)' ; default : return 'var(--theia-successBackground)' ; } } }