package krasa.grepconsole.plugin; import com.intellij.execution.ExecutionAdapter; import com.intellij.execution.ExecutionManager; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.ui.actions.CloseAction; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.components.PersistentStateComponent; import com.intellij.openapi.components.ProjectComponent; import com.intellij.openapi.components.State; import com.intellij.openapi.components.Storage; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.util.messages.MessageBusConnection; import krasa.grepconsole.tail.TailContentExecutor; import org.jetbrains.annotations.NotNull; import java.io.File; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @State(name = "GrepConsole", storages = { @Storage(value = "GrepConsole.xml") }) public class GrepProjectComponent implements ProjectComponent, PersistentStateComponent<GrepProjectState> { private static final Logger LOG = Logger.getInstance(GrepProjectComponent.class); private Project project; private GrepProjectState grepProjectState = new GrepProjectState(); private List<WeakReference<TailContentExecutor.PinAction>> listeners = new ArrayList<>(); private List<WeakReference<CloseAction>> tailCloseActions = new ArrayList<>(); public static GrepProjectComponent getInstance(Project project) { return project.getComponent(GrepProjectComponent.class); } public GrepProjectComponent(Project project) { this.project = project; } public Project getProject() { return project; } @Override public void initComponent() { final MessageBusConnection conn = project.getMessageBus().connect(); conn.subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter() { @Override public void processStarting(String executorId, @NotNull ExecutionEnvironment env) { ServiceManager.getInstance().setLastExecutionId(env.getExecutionId()); } }); } @Override public void disposeComponent() { // TODO: insert component disposal logic here } @Override @NotNull public String getComponentName() { return "GrepProjectComponent"; } @Override public void projectOpened() { // called when project is opened try { if (grepProjectState != null) { grepProjectState.openOldPins(project); } } catch (Exception e) { LOG.error(e); } } @Override public void projectClosed() { } @NotNull @Override public GrepProjectState getState() { return grepProjectState; } @Override public void loadState(GrepProjectState grepProjectState) { this.grepProjectState = grepProjectState; } public void register(TailContentExecutor.PinAction action) { listeners.add(new WeakReference<>(action)); } public void pin(@NotNull File pinnedFile) { grepProjectState.addPinned(pinnedFile); refresh(); } public void unpin(File file) { getState().removePinned(file); refresh(); } private void refresh() { for (Iterator<WeakReference<TailContentExecutor.PinAction>> iterator = listeners.iterator(); iterator.hasNext();) { WeakReference<TailContentExecutor.PinAction> listener = iterator.next(); TailContentExecutor.PinAction pinAction = listener.get(); if (pinAction == null) { iterator.remove(); } else { pinAction.refreshPinStatus(this); } } } public boolean isPinned(File file) { return getState().isPinned(file); } public void register(CloseAction action) { tailCloseActions.add(new WeakReference<>(action)); } public void closeAllTails(AnActionEvent e) { for (WeakReference<CloseAction> tailCloseAction : tailCloseActions) { CloseAction closeAction = tailCloseAction.get(); if (closeAction != null) { closeAction.actionPerformed(e); } } tailCloseActions.clear(); } }