/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gradle.ideaplugin.ui.actions; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.project.Project; import org.gradle.ideaplugin.ui.GradleUIApplicationComponent; import org.gradle.ideaplugin.ui.GradleUIAvailabilityObserver; import org.gradle.openapi.external.foundation.favorites.FavoriteTaskVersion1; import org.gradle.openapi.external.foundation.favorites.FavoritesEditorVersion1; import org.gradle.openapi.external.ui.DualPaneUIVersion1; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; /** This create Idea actions that call gradle functionality. This is useful for assigning hot-keys to gradle functions (such as favorites). There should only be 1 instance of this per Idea instance. As such, it tracks actions across multiple projects. @author mhunsicker */ public class GradleActionLord implements GradleUIAvailabilityObserver { private HashMap<Project, List<ActionWrapper>> projectsToActionMap = new HashMap<Project,List<ActionWrapper>>(); public GradleActionLord( GradleUIApplicationComponent gradleUIApplicationComponent ) { gradleUIApplicationComponent.addUIAvailabilityObserver( this, true, true ); } /** Notification that the gradle UI has been loaded. @param gradleUIVersion1 the gradle object that was loaded @author mhunsicker */ public void gradleUILoaded( DualPaneUIVersion1 gradleUIVersion1, Project project ) { unregisterActionsFromIdea( project ); //remove any existing wrappers for this project in case this is being reloaded. List<ActionWrapper> actionWrappers = generateActionWrappers( gradleUIVersion1 ); projectsToActionMap.put( project, actionWrappers ); registerActionsWithIdea( actionWrappers ); } /** Notification that the gradle UI has been unloaded. @param project the idea project that gradle has been unloaded from. @author mhunsicker */ public void gradleUIUnloaded( Project project ) { unregisterActionsFromIdea( project ); } /** Generates all the action wrappers for this project. This does NOT register them with Idea. @param gradleUIVersion1 gradle @return a list of action wrappers */ private List<ActionWrapper> generateActionWrappers( DualPaneUIVersion1 gradleUIVersion1 ) { List<ActionWrapper> actionWrappers = new ArrayList<ActionWrapper>( ); getFavoriteTaskActionWrappers( gradleUIVersion1, actionWrappers ); actionWrappers.add( new ReExecuteLastCommandActionWrapper() ); return actionWrappers; } /** this creates action wrappers for all the favorite tasks. @param gradleUIVersion1 gradle @param actionWrappers where we put the action wrappers we generate */ private void getFavoriteTaskActionWrappers( DualPaneUIVersion1 gradleUIVersion1, List<ActionWrapper> actionWrappers ) { FavoritesEditorVersion1 favoritesEditor = gradleUIVersion1.getFavoritesEditor(); Iterator<FavoriteTaskVersion1> favoriteTask = favoritesEditor.getFavoriteTasks().iterator(); while( favoriteTask.hasNext() ) { FavoriteTaskVersion1 favoriteTaskVersion1 = favoriteTask.next(); actionWrappers.add( new FavoriteTaskActionWrapper( favoriteTaskVersion1.getDisplayName() ) ); } } /** Registers the actions with Idea. This makes Idea aware of them and they can be assigned hot-keys, etc. @param actionWrappers the actions to add */ private void registerActionsWithIdea( List<ActionWrapper> actionWrappers ) { Iterator<ActionWrapper> iterator = actionWrappers.iterator(); while( iterator.hasNext() ) { ActionWrapper actionWrapper = iterator.next(); String name = actionWrapper.getName(); if( ActionManager.getInstance().getAction( name ) == null ) ActionManager.getInstance().registerAction( name, actionWrapper.getAction() ); } } /** This cleans up the actions associated with the specified project. We unregister the actions from Idea. */ private void unregisterActionsFromIdea( Project project ) { List<ActionWrapper> actionWrappers = projectsToActionMap.get( project ); if( actionWrappers == null ) return; //remove it from the map before we unregister them so we can verify no one else is using them. projectsToActionMap.remove( project ); Iterator<ActionWrapper> iterator = actionWrappers.iterator(); while( iterator.hasNext() ) { ActionWrapper actionWrapper = iterator.next(); String name = actionWrapper.getName(); if( ActionManager.getInstance().getAction( name ) != null && isInUse( name ) ) ActionManager.getInstance().unregisterAction( name ); } } /** Determines if an action with the specified name exists and is therefore in use. We look through the project/actions map for an action with the specified name. This is used to unregister actions. We only want to unregister ones that aren't being used. @param name the sought name. @return */ private boolean isInUse( String name ) { Iterator<List<ActionWrapper>> mainIterator = projectsToActionMap.values().iterator(); while( mainIterator.hasNext() ) { List<ActionWrapper> actionWrappers = mainIterator.next(); Iterator<ActionWrapper> innerIterator = actionWrappers.iterator(); while( innerIterator.hasNext() ) { ActionWrapper actionWrapper = innerIterator.next(); if( actionWrapper.getName().equals( name ) ) return true; } } return false; } }