/*
* Copyright 2010 Ronnie Kolehmainen
*
* 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 com.googlecode.cssxfire;
import com.googlecode.cssxfire.action.Help;
import com.googlecode.cssxfire.filter.ReduceStrategyManager;
import com.googlecode.cssxfire.tree.CssDeclarationPath;
import com.googlecode.cssxfire.tree.TreeViewModel;
import com.googlecode.cssxfire.ui.CssToolWindow;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
import com.intellij.ide.plugins.PluginManager;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.psi.*;
import com.intellij.psi.css.CssDeclaration;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* Created by IntelliJ IDEA.
* User: Ronnie
*/
public class IncomingChangesComponent implements ProjectComponent
{
public static final String TOOLWINDOW_ID = "CSS-X-Fire";
private final Project project;
private final CssToolWindow cssToolWindow;
private final PsiTreeChangeListener myListener = new PsiTreeChangeAdapter()
{
@Override
public void childReplaced(PsiTreeChangeEvent event)
{
IncomingChangesComponent.this.onPsiChange(event);
}
@Override
public void childRemoved(PsiTreeChangeEvent event)
{
IncomingChangesComponent.this.onPsiChange(event);
}
};
private void onPsiChange(PsiTreeChangeEvent event)
{
if (event.getOldChild() instanceof CssDeclaration || event.getParent() instanceof CssDeclaration)
{
cssToolWindow.refreshLeafs();
}
}
public IncomingChangesComponent(Project project)
{
this.project = project;
this.cssToolWindow = new CssToolWindow(project);
}
/**
* Helper
* @param project the project
* @return the IncomingChangesComponent instance
*/
public static IncomingChangesComponent getInstance(Project project)
{
return project.getComponent(IncomingChangesComponent.class);
}
public void initComponent()
{
if (!CssXFireConnector.getInstance().isInitialized())
{
return;
}
IdeaPluginDescriptor pluginDescriptor = PluginManager.getPlugin(PluginId.getId("CSS-X-Fire"));
if (pluginDescriptor == null)
{
return;
}
String currentVersion = pluginDescriptor.getVersion();
AppMeta appMeta = CssXFireConnector.getInstance().getState();
String previousVersion = appMeta.getVersion();
if (!currentVersion.equals(previousVersion))
{
appMeta.setVersion(currentVersion);
final String message = previousVersion == null
? "CSS-X-Fire has been installed.\n\nPress Yes to install the browser plugin."
: "CSS-X-Fire has been upgraded from " + previousVersion + " to " + currentVersion + ".\n\nPress Yes to update the browser plugin.";
ApplicationManager.getApplication().invokeLater(new Runnable()
{
public void run()
{
int res = Messages.showYesNoDialog(project, message, "CSS-X-Fire", null);
if (res == 0)
{
new Help().actionPerformed(null);
}
}
});
}
}
public void disposeComponent()
{
// TODO: insert component disposal logic here
}
@NotNull
public String getComponentName()
{
return "IncomingChangesComponent";
}
public void projectOpened()
{
if (!CssXFireConnector.getInstance().isInitialized())
{
return;
}
final ToolWindow toolWindow = ToolWindowManager.getInstance(project).registerToolWindow(TOOLWINDOW_ID, true, ToolWindowAnchor.BOTTOM);
final ContentFactory contentFactory = toolWindow.getContentManager().getFactory();
final Content content = contentFactory.createContent(cssToolWindow, "Incoming changes", true);
toolWindow.getContentManager().addContent(content);
toolWindow.setAutoHide(false);
toolWindow.setAvailable(true, null);
CssXFireConnector.getInstance().addProjectComponent(this);
PsiManager.getInstance(project).addPsiTreeChangeListener(myListener);
}
public void projectClosed()
{
if (!CssXFireConnector.getInstance().isInitialized())
{
return;
}
PsiManager.getInstance(project).removePsiTreeChangeListener(myListener);
getTreeViewModel().clearTree();
CssXFireConnector.getInstance().removeProjectComponent(this);
ToolWindowManager.getInstance(project).unregisterToolWindow(TOOLWINDOW_ID);
}
public void processRule(final FirebugChangesBean changesBean)
{
DumbService.getInstance(project).smartInvokeLater(new Runnable()
{
public void run()
{
if (!project.isInitialized())
{
return;
}
// Apply routes
FirebugChangesBean routedChangesBean = changesBean.applyRoutes(project);
// Get all possible candidates from the style info provided by Firebug
final Collection<CssDeclarationPath> candidates = IncomingChangesProcessor.getProjectCandidates(project, routedChangesBean);
// Reduce results if any of the filter options are checked
ReduceStrategyManager.getStrategy(project, routedChangesBean).reduce(candidates);
// Render remaining candidates in the "Incoming changes" tree view
for (CssDeclarationPath candidate : candidates)
{
cssToolWindow.getTreeModel().intersect(candidate);
}
if (ProjectSettings.getInstance(project).isAutoExpand())
{
cssToolWindow.expandAll();
}
}
});
}
@NotNull
public TreeViewModel getTreeViewModel()
{
return cssToolWindow;
}
public void handleEvent(final FirebugEvent event)
{
DumbService.getInstance(project).smartInvokeLater(new Runnable()
{
public void run()
{
if (!project.isInitialized())
{
return;
}
if ("refresh".equals(event.getName()) && ProjectSettings.getInstance(project).isAutoClear())
{
cssToolWindow.clearTree();
}
}
});
}
}