VCS: todo checkin handler - visualization

This commit is contained in:
irengrig
2011-02-24 19:09:51 +03:00
parent 8b566634f5
commit b945055ba4
23 changed files with 751 additions and 280 deletions
@@ -67,7 +67,7 @@ public class PaletteManager implements ProjectComponent {
myPaletteWindow,
ToolWindowAnchor.RIGHT,
myProject,
true);
true, false);
myPaletteToolWindow.setIcon(IconLoader.getIcon("/general/toolWindowPalette.png"));
myPaletteToolWindow.setAvailable(false, null);
final MyFileEditorManagerListener myListener = new MyFileEditorManagerListener();
@@ -29,7 +29,7 @@ import org.jetbrains.annotations.Nullable;
*
* @see com.intellij.psi.PsiManager#getSearchHelper()
*/
public interface PsiSearchHelper {
public interface PsiSearchHelper extends PsiTodoSearchHelper {
/**
* Searches the specified scope for comments containing the specified identifier.
*
@@ -49,48 +49,6 @@ public interface PsiSearchHelper {
*/
boolean processCommentsContainingIdentifier(@NotNull String identifier, @NotNull SearchScope searchScope, @NotNull Processor<PsiElement> processor);
/**
* Returns the list of all files in the project which have to do items.
*
* @return the list of files with to do items.
*/
@NotNull PsiFile[] findFilesWithTodoItems();
/**
* Searches the specified file for to do items.
*
* @param file the file to search for to do items.
* @return the array of found items.
*/
@NotNull TodoItem[] findTodoItems(@NotNull PsiFile file);
/**
* Searches the specified range of text in the specified file for to do items.
*
* @param file the file to search for to do items.
* @param startOffset the start offset of the text range to search to do items in.
* @param endOffset the end offset of the text range to search to do items in.
* @return the array of found items.
*/
@NotNull TodoItem[] findTodoItems(@NotNull PsiFile file, int startOffset, int endOffset);
/**
* Returns the number of to do items in the specified file.
*
* @param file the file to return the to do count for.
* @return the count of to do items in the file.
*/
int getTodoItemsCount(@NotNull PsiFile file);
/**
* Returns the number of to do items matching the specified pattern in the specified file.
*
* @param file the file to return the to do count for.
* @param pattern the pattern of to do items to find.
* @return the count of to do items in the file.
*/
int getTodoItemsCount(@NotNull PsiFile file, @NotNull TodoPattern pattern);
/**
* Returns the list of files which contain the specified word in "plain text"
* context (for example, plain text files or attribute values in XML files).
@@ -0,0 +1,71 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* 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.intellij.psi.search;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* @author irengrig
* Date: 2/24/11
* Time: 10:08 AM
*/
public interface PsiTodoSearchHelper {
/**
* Returns the list of all files in the project which have to do items.
*
* @return the list of files with to do items.
*/
@NotNull
PsiFile[] findFilesWithTodoItems();
/**
* Searches the specified file for to do items.
*
* @param file the file to search for to do items.
* @return the array of found items.
*/
@NotNull
TodoItem[] findTodoItems(@NotNull PsiFile file);
/**
* Searches the specified range of text in the specified file for to do items.
*
* @param file the file to search for to do items.
* @param startOffset the start offset of the text range to search to do items in.
* @param endOffset the end offset of the text range to search to do items in.
* @return the array of found items.
*/
@NotNull
TodoItem[] findTodoItems(@NotNull PsiFile file, int startOffset, int endOffset);
/**
* Returns the number of to do items in the specified file.
*
* @param file the file to return the to do count for.
* @return the count of to do items in the file.
*/
int getTodoItemsCount(@NotNull PsiFile file);
/**
* Returns the number of to do items matching the specified pattern in the specified file.
*
* @param file the file to return the to do count for.
* @param pattern the pattern of to do items to find.
* @return the count of to do items in the file.
*/
int getTodoItemsCount(@NotNull PsiFile file, @NotNull TodoPattern pattern);
}
@@ -0,0 +1,58 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* 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.intellij.ide.todo;
import com.intellij.ide.todo.nodes.ToDoRootNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.PsiTodoSearchHelper;
/**
* @author irengrig
* Date: 2/21/11
* Time: 4:28 PM
*/
public class CustomChangelistTodoTreeStructure extends TodoTreeStructure {
private final PsiTodoSearchHelper mySearchHelper;
public CustomChangelistTodoTreeStructure(Project project, PsiTodoSearchHelper searchHelper) {
super(project);
mySearchHelper = searchHelper;
}
public boolean accept(final PsiFile psiFile) {
if (! psiFile.isValid()) return false;
return mySearchHelper.getTodoItemsCount(psiFile) > 0;
}
public boolean getIsPackagesShown() {
return myArePackagesShown;
}
Object getFirstSelectableElement() {
return ((ToDoRootNode)myRootElement).getSummaryNode();
}
protected AbstractTreeNode createRootElement() {
return new ToDoRootNode(myProject, new Object(), myBuilder, mySummaryElement);
}
@Override
public PsiTodoSearchHelper getSearchHelper() {
return mySearchHelper;
}
}
@@ -0,0 +1,187 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* 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.intellij.ide.todo;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.changes.LocalChangeList;
import com.intellij.openapi.vcs.checkin.TodoCheckinHandlerWorker;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.PsiTodoSearchHelper;
import com.intellij.psi.search.TodoItem;
import com.intellij.psi.search.TodoPattern;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import java.util.*;
/**
* @author irengrig
* Date: 2/21/11
* Time: 5:14 PM
*/
public class CustomChangelistTodosTreeBuilder extends TodoTreeBuilder {
public static final TodoItem[] EMPTY_ITEMS = new TodoItem[0];
private final Project myProject;
private final String myTitle;
private final MultiMap<PsiFile, TodoItem> myMap;
private final Set<PsiFile> myIncludedFiles;
private PsiTodoSearchHelper myPsiTodoSearchHelper;
private ChangeListManager myChangeListManager;
public CustomChangelistTodosTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project, final String title,
final List<TodoItem> list) {
super(tree, treeModel, project);
myProject = project;
myTitle = title;
myMap = new MultiMap<PsiFile, TodoItem>();
myIncludedFiles = new HashSet<PsiFile>();
myChangeListManager = ChangeListManager.getInstance(myProject);
initMap(list);
initHelper();
}
private void initMap(List<TodoItem> list) {
buildMap(list);
myIncludedFiles.addAll(myMap.keySet());
}
private void buildMap(List<TodoItem> list) {
for (TodoItem todoItem : list) {
myMap.putValue(todoItem.getFile(), todoItem);
}
}
private void initHelper() {
myPsiTodoSearchHelper = new PsiTodoSearchHelper() {
@NotNull
@Override
public PsiFile[] findFilesWithTodoItems() {
final List<Change> changes = new ArrayList<Change>();
final List<LocalChangeList> changeLists = myChangeListManager.getChangeLists();
final Map<VirtualFile, Change> allChanges = new HashMap<VirtualFile, Change>();
for (LocalChangeList changeList : changeLists) {
final Collection<Change> currChanges = changeList.getChanges();
for (Change currChange : currChanges) {
if (currChange.getAfterRevision() != null && currChange.getAfterRevision().getFile().getVirtualFile() != null) {
allChanges.put(currChange.getAfterRevision().getFile().getVirtualFile(), currChange);
}
}
}
for (Iterator<PsiFile> iterator = myIncludedFiles.iterator(); iterator.hasNext(); ) {
final PsiFile next = iterator.next();
final Change change = allChanges.get(next.getVirtualFile());
if (change != null) {
changes.add(change);
}
}
// a hack here with _todo filter
final TodoCheckinHandlerWorker worker = new TodoCheckinHandlerWorker(myProject, changes, getTodoTreeStructure().getTodoFilter(), true);
worker.execute();
buildMap(worker.inOneList());
final Set<PsiFile> files = myMap.keySet();
return files.toArray(new PsiFile[files.size()]);
}
@NotNull
@Override
public TodoItem[] findTodoItems(@NotNull PsiFile file) {
if (! myIncludedFiles.contains(file)) return EMPTY_ITEMS;
if (myDirtyFileSet.contains(file.getVirtualFile())) {
myMap.remove(file);
final Change change = myChangeListManager.getChange(file.getVirtualFile());
if (change != null) {
final TodoCheckinHandlerWorker worker = new TodoCheckinHandlerWorker(myProject, Collections.singletonList(change), getTodoTreeStructure().getTodoFilter(), true);
worker.execute();
final List<TodoItem> todoItems = worker.inOneList();
if (todoItems != null && ! todoItems.isEmpty()) {
for (TodoItem todoItem : todoItems) {
myMap.putValue(file, todoItem);
}
}
}
}
final Collection<TodoItem> todoItems = myMap.get(file);
return todoItems == null || todoItems.isEmpty() ? EMPTY_ITEMS : todoItems.toArray(new TodoItem[todoItems.size()]);
}
@NotNull
@Override
public TodoItem[] findTodoItems(@NotNull PsiFile file, int startOffset, int endOffset) {
final TodoItem[] todoItems = findTodoItems(file);
if (todoItems.length == 0) {
return todoItems;
}
final TextRange textRange = new TextRange(startOffset, endOffset);
final List<TodoItem> result = new ArrayList<TodoItem>();
for (TodoItem todoItem : todoItems) {
if (todoItem.getTextRange().contains(textRange)) {
result.add(todoItem);
}
}
return result.isEmpty() ? EMPTY_ITEMS : result.toArray(new TodoItem[result.size()]);
}
@Override
public int getTodoItemsCount(@NotNull PsiFile file) {
return findTodoItems(file).length;
}
@Override
public int getTodoItemsCount(@NotNull PsiFile file, @NotNull TodoPattern pattern) {
throw new UnsupportedOperationException();
// just would not work while implemented like that
/*final TodoItem[] todoItems = findTodoItems(file);
if (todoItems.length == 0) return 0;
int cnt = 0;
for (TodoItem todoItem : todoItems) {
if (todoItem.getPattern().equals(pattern)) ++ cnt;
}
return cnt;*/
}
};
}
@Override
protected TodoTreeStructure createTreeStructure() {
return new CustomChangelistTodoTreeStructure(myProject, myPsiTodoSearchHelper);
}
@Override
void rebuildCache() {
myMap.clear();
myFileTree.clear();
myDirtyFileSet.clear();
myFile2Highlighter.clear();
TodoTreeStructure treeStructure=getTodoTreeStructure();
PsiFile[] psiFiles= myPsiTodoSearchHelper.findFilesWithTodoItems();
for(int i=0;i<psiFiles.length;i++){
PsiFile psiFile=psiFiles[i];
if(myPsiTodoSearchHelper.getTodoItemsCount(psiFile) > 0 && treeStructure.accept(psiFile)){
myFileTree.add(psiFile.getVirtualFile());
}
}
treeStructure.validateCache();
}
}
@@ -0,0 +1,122 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* 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.intellij.ide.todo;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.todo.configurable.TodoConfigurable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
import com.intellij.openapi.actionSystem.impl.ActionButton;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.IconLoader;
import com.intellij.util.Consumer;
import javax.swing.*;
/**
* @author irengrig
* Date: 2/24/11
* Time: 3:38 PM
* moved from inner class
*/
public class SetTodoFilterAction extends AnAction implements CustomComponentAction {
private final Project myProject;
private final TodoPanelSettings myToDoSettings;
private final Consumer<TodoFilter> myTodoFilterConsumer;
public SetTodoFilterAction(final Project project, final TodoPanelSettings toDoSettings, final Consumer<TodoFilter> todoFilterConsumer) {
super(IdeBundle.message("action.filter.todo.items"), null, IconLoader.getIcon("/ant/filter.png"));
myProject = project;
myToDoSettings = toDoSettings;
myTodoFilterConsumer = todoFilterConsumer;
}
public void actionPerformed(AnActionEvent e) {
Presentation presentation = e.getPresentation();
JComponent button = (JComponent)presentation.getClientProperty("button");
DefaultActionGroup group = createPopupActionGroup();
ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.TODO_VIEW_TOOLBAR,
group);
popupMenu.getComponent().show(button, button.getWidth(), 0);
}
public JComponent createCustomComponent(Presentation presentation) {
ActionButton button = new ActionButton(
this,
presentation,
ActionPlaces.TODO_VIEW_TOOLBAR,
ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE
);
presentation.putClientProperty("button", button);
return button;
}
private DefaultActionGroup createPopupActionGroup() {
TodoFilter[] filters = TodoConfiguration.getInstance().getTodoFilters();
DefaultActionGroup group = new DefaultActionGroup();
group.add(new TodoFilterApplier(IdeBundle.message("action.todo.show.all"),
IdeBundle.message("action.description.todo.show.all"), null));
for (TodoFilter filter : filters) {
group.add(new TodoFilterApplier(filter.getName(), null, filter));
}
group.addSeparator();
group.add(
new AnAction(IdeBundle.message("action.todo.edit.filters"),
IdeBundle.message("action.todo.edit.filters"), IconLoader.getIcon("/general/ideOptions.png")) {
public void actionPerformed(AnActionEvent e) {
final ShowSettingsUtil util = ShowSettingsUtil.getInstance();
util.editConfigurable(myProject, new TodoConfigurable());
}
}
);
return group;
}
private class TodoFilterApplier extends ToggleAction {
private final TodoFilter myFilter;
/**
* @param text action's text.
* @param description action's description.
* @param filter filter to be applied. <code>null</code> value means "empty" filter.
*/
TodoFilterApplier(String text, String description, TodoFilter filter) {
super(null, description, null);
getTemplatePresentation().setText(text, false);
myFilter = filter;
}
public void update(AnActionEvent e) {
super.update(e);
if (myFilter != null) {
e.getPresentation().setEnabled(!myFilter.isEmpty());
}
}
public boolean isSelected(AnActionEvent e) {
return Comparing.equal(myFilter != null ? myFilter.getName() : null, myToDoSettings.getTodoFilterName());
}
public void setSelected(AnActionEvent e, boolean state) {
if (state) {
myTodoFilterConsumer.consume(myFilter);
//setTodoFilter(myFilter);
}
}
}
}
@@ -23,21 +23,16 @@ import com.intellij.ide.TreeExpander;
import com.intellij.ide.actions.ContextHelpAction;
import com.intellij.ide.actions.NextOccurenceToolbarAction;
import com.intellij.ide.actions.PreviousOccurenceToolbarAction;
import com.intellij.ide.todo.configurable.TodoConfigurable;
import com.intellij.ide.todo.nodes.TodoFileNode;
import com.intellij.ide.todo.nodes.TodoItemNode;
import com.intellij.ide.todo.nodes.TodoTreeHelper;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.CustomComponentAction;
import com.intellij.openapi.actionSystem.impl.ActionButton;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.options.ShowSettingsUtil;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.IconLoader;
import com.intellij.openapi.util.SystemInfo;
@@ -52,6 +47,7 @@ import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.content.Content;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.Consumer;
import com.intellij.util.EditSourceOnDoubleClickHandler;
import com.intellij.util.Icons;
import com.intellij.util.OpenSourceUtil;
@@ -195,7 +191,12 @@ abstract class TodoPanel extends SimpleToolWindowPanel implements OccurenceNavig
autoScrollToSourceHandler.install(myTree);
rightGroup.add(autoScrollToSourceHandler.createToggleAction());
MySetTodoFilterAction setTodoFilterAction = new MySetTodoFilterAction();
SetTodoFilterAction setTodoFilterAction = new SetTodoFilterAction(myProject, mySettings, new Consumer<TodoFilter>() {
@Override
public void consume(TodoFilter todoFilter) {
setTodoFilter(todoFilter);
}
});
rightGroup.add(setTodoFilterAction);
toolBarPanel.add(
ActionManager.getInstance().createActionToolbar(ActionPlaces.TODO_VIEW_TOOLBAR, rightGroup, false).getComponent());
@@ -566,85 +567,6 @@ abstract class TodoPanel extends SimpleToolWindowPanel implements OccurenceNavig
}
}
private final class MySetTodoFilterAction extends AnAction implements CustomComponentAction {
MySetTodoFilterAction() {
super(IdeBundle.message("action.filter.todo.items"), null, IconLoader.getIcon("/ant/filter.png"));
}
public void actionPerformed(AnActionEvent e) {
Presentation presentation = e.getPresentation();
JComponent button = (JComponent)presentation.getClientProperty("button");
DefaultActionGroup group = createPopupActionGroup();
ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(ActionPlaces.TODO_VIEW_TOOLBAR,
group);
popupMenu.getComponent().show(button, button.getWidth(), 0);
}
public JComponent createCustomComponent(Presentation presentation) {
ActionButton button = new ActionButton(
this,
presentation,
ActionPlaces.TODO_VIEW_TOOLBAR,
ActionToolbar.DEFAULT_MINIMUM_BUTTON_SIZE
);
presentation.putClientProperty("button", button);
return button;
}
private DefaultActionGroup createPopupActionGroup() {
TodoFilter[] filters = TodoConfiguration.getInstance().getTodoFilters();
DefaultActionGroup group = new DefaultActionGroup();
group.add(new TodoFilterApplier(IdeBundle.message("action.todo.show.all"),
IdeBundle.message("action.description.todo.show.all"), null));
for (TodoFilter filter : filters) {
group.add(new TodoFilterApplier(filter.getName(), null, filter));
}
group.addSeparator();
group.add(
new AnAction(IdeBundle.message("action.todo.edit.filters"),
IdeBundle.message("action.todo.edit.filters"), IconLoader.getIcon("/general/ideOptions.png")) {
public void actionPerformed(AnActionEvent e) {
final ShowSettingsUtil util = ShowSettingsUtil.getInstance();
util.editConfigurable(myProject, new TodoConfigurable());
}
}
);
return group;
}
private final class TodoFilterApplier extends ToggleAction {
private final TodoFilter myFilter;
/**
* @param text action's text.
* @param description action's description.
* @param filter filter to be applied. <code>null</code> value means "empty" filter.
*/
TodoFilterApplier(String text, String description, TodoFilter filter) {
super(null, description, null);
getTemplatePresentation().setText(text, false);
myFilter = filter;
}
public void update(AnActionEvent e) {
super.update(e);
if (myFilter != null) {
e.getPresentation().setEnabled(!myFilter.isEmpty());
}
}
public boolean isSelected(AnActionEvent e) {
return Comparing.equal(myFilter != null ? myFilter.getName() : null, mySettings.getTodoFilterName());
}
public void setSelected(AnActionEvent e, boolean state) {
if (state) {
setTodoFilter(myFilter);
}
}
}
}
private final class MyVisibilityWatcher extends VisibilityWatcher {
public void visibilityChanged() {
PsiDocumentManager.getInstance(myProject).commitAllDocuments();
@@ -0,0 +1,30 @@
/*
* Copyright 2000-2011 JetBrains s.r.o.
*
* 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.intellij.ide.todo;
import com.intellij.openapi.project.Project;
import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
/**
* @author irengrig
* Date: 2/24/11
* Time: 10:51 AM
*/
public interface TodoTreeBuilderFactory {
TodoTreeBuilder createTreeBuilder(JTree tree,DefaultTreeModel treeModel,Project project);
}
@@ -25,6 +25,7 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.search.PsiTodoSearchHelper;
import com.intellij.psi.search.TodoPattern;
import java.util.Collections;
@@ -111,10 +112,10 @@ public abstract class TodoTreeStructure extends AbstractTreeStructureBase implem
if(myTodoFilter!=null){
for(Iterator i=myTodoFilter.iterator();i.hasNext();){
TodoPattern pattern=(TodoPattern)i.next();
count+=mySearchHelper.getTodoItemsCount(psiFile,pattern);
count+=getSearchHelper().getTodoItemsCount(psiFile,pattern);
}
}else{
count=mySearchHelper.getTodoItemsCount(psiFile);
count=getSearchHelper().getTodoItemsCount(psiFile);
}
}
return count;
@@ -141,7 +142,7 @@ public abstract class TodoTreeStructure extends AbstractTreeStructureBase implem
return myFlattenPackages;
}
public PsiSearchHelper getSearchHelper() {
public PsiTodoSearchHelper getSearchHelper() {
return mySearchHelper;
}
@@ -47,6 +47,8 @@ import javax.swing.*;
import javax.swing.tree.DefaultTreeModel;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
/**
* @author Vladimir Kondratyev
@@ -67,6 +69,8 @@ public class TodoView implements PersistentStateComponent<Element>, Disposable {
private CurrentFileTodosPanel myCurrentFileTodos;
private TodoPanel myAllTodos;
private ChangeListTodosPanel myChangeListTodos;
private final List<TodoPanel> myPanels;
private final List<Content> myNotAddedContent;
private int mySelectedIndex;
private final TodoPanelSettings myCurrentPanelSettings;
@@ -90,6 +94,8 @@ public class TodoView implements PersistentStateComponent<Element>, Disposable {
myCurrentPanelSettings=new TodoPanelSettings();
myAllPanelSettings=new TodoPanelSettings();
myChangeListTodosPanelSettings = new TodoPanelSettings();
myPanels = new ArrayList<TodoPanel>();
myNotAddedContent = new ArrayList<Content>();
myVCSManager.addVcsListener(myVcsListener);
@@ -204,16 +210,26 @@ public class TodoView implements PersistentStateComponent<Element>, Disposable {
myVcsListener.myIsVisible = true;
myContentManager.addContent(myChangeListTodosContent);
}
for (Content content : myNotAddedContent) {
myContentManager.addContent(content);
}
myChangeListTodosContent.setCloseable(false);
allTodosContent.setCloseable(false);
currentFileTodosContent.setCloseable(false);
Content content=myContentManager.getContent(mySelectedIndex);
content = content == null ? allTodosContent : content;
myContentManager.setSelectedContent(content);
myPanels.add(myAllTodos);
myPanels.add(myChangeListTodos);
myPanels.add(myCurrentFileTodos);
}
private final class MyVcsListener implements VcsListener {
private boolean myIsVisible;
public void directoryMappingChanged() {
public void directoryMappingChanged() { // todo ?
ApplicationManager.getApplication().invokeLater(new Runnable(){
public void run() {
if (myContentManager == null) return; //was not initialized yet
@@ -255,9 +271,9 @@ public class TodoView implements PersistentStateComponent<Element>, Disposable {
}
private void updateFilters(){
myCurrentFileTodos.updateTodoFilter();
myAllTodos.updateTodoFilter();
myChangeListTodos.updateTodoFilter();
for (TodoPanel panel : myPanels) {
panel.updateTodoFilter();
}
}
}
@@ -279,17 +295,17 @@ public class TodoView implements PersistentStateComponent<Element>, Disposable {
ApplicationManager.getApplication().runReadAction(
new Runnable(){
public void run(){
myAllTodos.rebuildCache();
myCurrentFileTodos.rebuildCache();
myChangeListTodos.rebuildCache();
for (TodoPanel panel : myPanels) {
panel.rebuildCache();
}
}
}
);
ApplicationManager.getApplication().invokeLater(new Runnable(){
public void run(){
myAllTodos.updateTree();
myCurrentFileTodos.updateTree();
myChangeListTodos.updateTree();
for (TodoPanel panel : myPanels) {
panel.updateTree();
}
}
}, ModalityState.NON_MODAL);
}
@@ -298,4 +314,32 @@ public class TodoView implements PersistentStateComponent<Element>, Disposable {
});
}
}
public void addCustomTodoView(final TodoTreeBuilderFactory factory, final String title, final TodoPanelSettings settings) {
final Content content = ContentFactory.SERVICE.getInstance().createContent(null, title, true);
final ChangeListTodosPanel panel = new ChangeListTodosPanel(myProject, settings, content) {
@Override
protected TodoTreeBuilder createTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project) {
final TodoTreeBuilder todoTreeBuilder = factory.createTreeBuilder(tree, treeModel, project);
todoTreeBuilder.init();
return todoTreeBuilder;
}
};
content.setComponent(panel);
Disposer.register(this, panel);
if (myContentManager != null) {
myContentManager.addContent(content);
} else {
myNotAddedContent.add(content);
}
myPanels.add(panel);
content.setCloseable(true);
content.setDisposer(new Disposable() {
@Override
public void dispose() {
myPanels.remove(panel);
}
});
}
}
@@ -16,52 +16,37 @@
package com.intellij.openapi.vcs.checkin;
import com.intellij.CommonBundle;
import com.intellij.openapi.application.Application;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.todo.*;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.ex.DiffFragment;
import com.intellij.openapi.diff.impl.ComparisonPolicy;
import com.intellij.openapi.diff.impl.DiffUtil;
import com.intellij.openapi.diff.impl.fragments.Fragment;
import com.intellij.openapi.diff.impl.fragments.LineFragment;
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
import com.intellij.openapi.diff.impl.processing.DiffCorrection;
import com.intellij.openapi.diff.impl.processing.DiffFragmentsProcessor;
import com.intellij.openapi.diff.impl.processing.DiffPolicy;
import com.intellij.openapi.diff.impl.processing.TextCompareProcessor;
import com.intellij.openapi.diff.impl.util.TextDiffType;
import com.intellij.openapi.diff.impl.util.TextDiffTypeEnum;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.CheckinProjectPanel;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsConfiguration;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.CommitExecutor;
import com.intellij.openapi.vcs.checkin.CheckinHandler;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.PsiManager;
import com.intellij.psi.impl.search.PsiSearchHelperImpl;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.search.TodoItem;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowManager;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.util.Consumer;
import com.intellij.util.PairConsumer;
import com.intellij.util.SmartList;
import com.intellij.util.containers.Convertor;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import sun.util.LocaleServiceProviderPool;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.Callable;
import javax.swing.tree.DefaultTreeModel;
import java.util.Collection;
/**
* @author irengrig
@@ -72,6 +57,7 @@ public class TodoCheckinHandler extends CheckinHandler {
private final Project myProject;
private final CheckinProjectPanel myCheckinProjectPanel;
private VcsConfiguration myConfiguration;
private TodoFilter myTodoFilter;
private final static Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.checkin.TodoCheckinHandler");
public TodoCheckinHandler(CheckinProjectPanel checkinProjectPanel) {
@@ -82,15 +68,40 @@ public class TodoCheckinHandler extends CheckinHandler {
@Override
public RefreshableOnComponent getBeforeCheckinConfigurationPanel() {
final JCheckBox checkBox = new JCheckBox(VcsBundle.message("before.checkin.new.todo.check"));
final JCheckBox checkBox = new JCheckBox(VcsBundle.message("before.checkin.new.todo.check", ""));
return new RefreshableOnComponent() {
public JComponent getComponent() {
JPanel panel = new JPanel(new BorderLayout());
JPanel panel = new JPanel();
final BoxLayout boxLayout = new BoxLayout(panel, BoxLayout.X_AXIS);
panel.setLayout(boxLayout);
panel.add(checkBox);
setFilterText(myConfiguration.myTodoPanelSettings.getTodoFilterName());
if (myConfiguration.myTodoPanelSettings.getTodoFilterName() != null) {
myTodoFilter = TodoConfiguration.getInstance().getTodoFilter(myConfiguration.myTodoPanelSettings.getTodoFilterName());
}
final DefaultActionGroup group = new DefaultActionGroup();
group.add(new SetTodoFilterAction(myProject, myConfiguration.myTodoPanelSettings, new Consumer<TodoFilter>() {
@Override
public void consume(TodoFilter todoFilter) {
myTodoFilter = todoFilter;
final String name = todoFilter == null ? null : todoFilter.getName();
myConfiguration.myTodoPanelSettings.setTodoFilterName(name);
setFilterText(name);
}
}));
panel.add(ActionManager.getInstance().createActionToolbar("commit dialog todo handler", group, true).getComponent());
refreshEnable(checkBox);
return panel;
}
private void setFilterText(final String filterName) {
if (filterName == null) {
checkBox.setText(VcsBundle.message("before.checkin.new.todo.check", IdeBundle.message("action.todo.show.all")));
} else {
checkBox.setText(VcsBundle.message("before.checkin.new.todo.check", "Filter: " + filterName));
}
}
public void refresh() {
}
@@ -118,7 +129,7 @@ public class TodoCheckinHandler extends CheckinHandler {
public ReturnResult beforeCheckin(@Nullable CommitExecutor executor, PairConsumer<Object, Object> additionalDataConsumer) {
if (! myConfiguration.CHECK_NEW_TODO) return ReturnResult.COMMIT;
if (DumbService.getInstance(myProject).isDumb()) {
final String todoName = VcsBundle.message("before.checkin.new.todo.check");
final String todoName = VcsBundle.message("before.checkin.new.todo.check.title");
if (Messages.showDialog(myProject,
todoName +
" can't be performed while IntelliJ IDEA updates the indices in background.\n" +
@@ -130,11 +141,8 @@ public class TodoCheckinHandler extends CheckinHandler {
return ReturnResult.COMMIT;
}
final Collection<Change> changes = myCheckinProjectPanel.getSelectedChanges();
final TodoCheckinHandlerWorker worker = new TodoCheckinHandlerWorker(myProject, changes);
final TodoCheckinHandlerWorker worker = new TodoCheckinHandlerWorker(myProject, changes, myTodoFilter, true);
// todo: progress, read actions, exceptions handling (report !), report "bad" files
// todo: special pattern
// todo: report window
final Runnable runnable = new Runnable() {
public void run() {
worker.execute();
@@ -147,34 +155,48 @@ public class TodoCheckinHandler extends CheckinHandler {
return showResults(worker, executor);
}
private ReturnResult showResults(TodoCheckinHandlerWorker worker, CommitExecutor executor) {
private ReturnResult showResults(final TodoCheckinHandlerWorker worker, CommitExecutor executor) {
String commitButtonText = executor != null ? executor.getActionText() : myCheckinProjectPanel.getCommitActionName();
if (commitButtonText.endsWith("...")) {
commitButtonText = commitButtonText.substring(0, commitButtonText.length()-3);
}
final StringBuilder text = new StringBuilder();
if (worker.getAddedOrEditedTodos().isEmpty() && worker.getInChangedTodos().isEmpty()) {
text.append("No new, edited, or located in changed fragments TODO items found.\n").append(worker.getSkipped().size())
.append(" file(s) were skipped.\nWould you like to review them?");
} else {
if (worker.getAddedOrEditedTodos().isEmpty()) {
text.append("There were ").append(worker.getInChangedTodos().size()).append(" located in changed fragments TODO item(s) found.\n");
} else if (worker.getInChangedTodos().isEmpty()) {
text.append("There were ").append(worker.getAddedOrEditedTodos().size()).append(" added or edited TODO item(s) found.\n");
} else {
text.append("There were ").append(worker.getAddedOrEditedTodos().size()).append(" added or edited,\nand ")
.append(worker.getInChangedTodos().size()).append(" located in changed fragments TODO item(s) found.\n");
}
if (! worker.getSkipped().isEmpty()) {
text.append(worker.getSkipped().size()).append(" file(s) were skipped.\n");
}
text.append("Would you like to review them?");
}
final int answer = Messages.showDialog(text.toString(), "TODO", new String[]{VcsBundle.message("todo.in.new.review.button"),
commitButtonText, CommonBundle.getCancelButtonText()}, 0, UIUtil.getWarningIcon());
final String text = createMessage(worker);
final String[] buttons = worker.getAddedOrEditedTodos().size() + worker.getInChangedTodos().size() > 0 ?
new String[] {VcsBundle.message("todo.in.new.review.button"), commitButtonText, CommonBundle.getCancelButtonText()} :
new String[] {commitButtonText, CommonBundle.getCancelButtonText()};
final int answer = Messages.showDialog(text, "TODO", buttons, 0, UIUtil.getWarningIcon());
if (answer == 0) {
TodoView todoView = ServiceManager.getService(myProject, TodoView.class);
final String title = "For commit (" + DateFormatUtil.formatDateTime(System.currentTimeMillis()) + ")";
todoView.addCustomTodoView(new TodoTreeBuilderFactory() {
@Override
public TodoTreeBuilder createTreeBuilder(JTree tree, DefaultTreeModel treeModel, Project project) {
return new CustomChangelistTodosTreeBuilder(tree, treeModel, myProject, title, worker.inOneList());
}
}, title, new TodoPanelSettings(myConfiguration.myTodoPanelSettings));
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
final ToolWindowManager manager = ToolWindowManager.getInstance(myProject);
if (manager != null) {
final ToolWindow window = manager.getToolWindow("TODO");
if (window != null) {
window.show(new Runnable() {
@Override
public void run() {
final ContentManager cm = window.getContentManager();
final Content[] contents = cm.getContents();
if (contents.length > 0) {
cm.setSelectedContent(contents[contents.length - 1], true);
}
}
});
}
}
}
}, ModalityState.NON_MODAL, myProject.getDisposed());
// show for review
return ReturnResult.CLOSE_WINDOW;
}
@@ -185,4 +207,35 @@ public class TodoCheckinHandler extends CheckinHandler {
return ReturnResult.COMMIT;
}
}
private static String createMessage(TodoCheckinHandlerWorker worker) {
final StringBuilder text = new StringBuilder("<html><body>");
if (worker.getAddedOrEditedTodos().isEmpty() && worker.getInChangedTodos().isEmpty()) {
text.append("No new, edited, or located in changed fragments TODO items found.<br/>").append(worker.getSkipped().size())
.append(" file(s) were skipped.");
} else {
final int inChanged = worker.getInChangedTodos().size();
final int added = worker.getAddedOrEditedTodos().size();
if (added == 0) {
text.append("There ").append(wereWas(inChanged)).append(inChanged).append(" located in changed fragments TODO item(s) found.<br/>");
} else {
if (inChanged == 0) {
text.append("<b>There ").append(wereWas(added)).append(added).append(" added or edited TODO item(s) found.</b><br/>");
} else {
text.append("<b>There were ").append(added).append(" added or edited,</b><br/>and ")
.append(inChanged).append(" located in changed fragments TODO item(s) found.<br/>");
}
}
if (! worker.getSkipped().isEmpty()) {
text.append(worker.getSkipped().size()).append(" file(s) were skipped.<br/>");
}
text.append("Would you like to review them?");
}
text.append("</body></html>");
return text.toString();
}
private static String wereWas(final int num) {
return num == 1 ? "was " : "were ";
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.vcs.checkin;
import com.intellij.ide.todo.TodoFilter;
import com.intellij.ide.todo.TodoIndexPatternProvider;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.diff.ex.DiffFragment;
@@ -58,6 +59,8 @@ public class TodoCheckinHandlerWorker {
private final static Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.checkin.TodoCheckinHandler");
private final Collection<Change> changes;
private final TodoFilter myTodoFilter;
private final boolean myIncludePattern;
private final PsiManager myPsiManager;
private final PsiSearchHelper mySearchHelper;
@@ -69,8 +72,11 @@ public class TodoCheckinHandlerWorker {
private MyEditedFileProcessor myEditedFileProcessor;
public TodoCheckinHandlerWorker(final Project project, final Collection<Change> changes) {
public TodoCheckinHandlerWorker(final Project project, final Collection<Change> changes, final TodoFilter todoFilter,
final boolean includePattern) {
this.changes = changes;
myTodoFilter = todoFilter;
myIncludePattern = includePattern;
myPsiManager = PsiManager.getInstance(project);
mySearchHelper = myPsiManager.getSearchHelper();
myAddedOrEditedTodos = new ArrayList<TodoItem>();
@@ -91,7 +97,7 @@ public class TodoCheckinHandlerWorker {
public void inChanged(TodoItem todoItem) {
myInChangedTodos.add(todoItem);
}
});
}, myTodoFilter);
}
public void execute() {
@@ -110,7 +116,8 @@ public class TodoCheckinHandlerWorker {
continue;
}
myNewTodoItems = Arrays.asList(mySearchHelper.findTodoItems(myPsiFile));
myNewTodoItems = new ArrayList<TodoItem>(Arrays.asList(mySearchHelper.findTodoItems(myPsiFile)));
applyFilterAndRemoveDuplicates(myNewTodoItems, myTodoFilter);
if (change.getBeforeRevision() == null) {
// take just all todos
if (myNewTodoItems.isEmpty()) continue;
@@ -122,6 +129,22 @@ public class TodoCheckinHandlerWorker {
}
}
private static void applyFilterAndRemoveDuplicates(final List<TodoItem> todoItems, final TodoFilter filter) {
TodoItem previous = null;
for (Iterator<TodoItem> iterator = todoItems.iterator(); iterator.hasNext(); ) {
final TodoItem next = iterator.next();
if (filter != null && ! filter.contains(next.getPattern())) {
iterator.remove();
continue;
}
if (previous != null && next.getTextRange().equals(previous.getTextRange())) {
iterator.remove();
} else {
previous = next;
}
}
}
private static class MyEditedFileProcessor {
//private String myFileText;
private String myBeforeContent;
@@ -133,9 +156,11 @@ public class TodoCheckinHandlerWorker {
private final PsiFileFactory myPsiFileFactory;
private FilePath myAfterFile;
private final Acceptor myAcceptor;
private final TodoFilter myTodoFilter;
private MyEditedFileProcessor(final Project project, Acceptor acceptor) {
private MyEditedFileProcessor(final Project project, Acceptor acceptor, final TodoFilter todoFilter) {
myAcceptor = acceptor;
myTodoFilter = todoFilter;
myPsiFileFactory = PsiFileFactory.getInstance(project);
}
@@ -209,6 +234,7 @@ public class TodoCheckinHandlerWorker {
for (IndexPatternOccurrence occurrence : all) {
myOldItems.add(todoItemsCreator.createTodo(occurrence));
}
applyFilterAndRemoveDuplicates(myOldItems, myTodoFilter);
}
if (myOldTodoTexts == null) {
final StepIntersection<LineFragment, TodoItem> intersection = new StepIntersection<LineFragment, TodoItem>(
@@ -272,7 +298,8 @@ public class TodoCheckinHandlerWorker {
@Override
public TextRange convert(TodoItem o) {
return o.getTextRange();
final TextRange textRange = o.getTextRange();
return new TextRange(textRange.getStartOffset(), textRange.getEndOffset() - 1);
}
}
@@ -285,7 +312,15 @@ public class TodoCheckinHandlerWorker {
@Override
public TextRange convert(LineFragment o) {
return o.getRange(FragmentSide.SIDE2);
final TextRange textRange = o.getRange(FragmentSide.SIDE2);
return new TextRange(textRange.getStartOffset(), textRange.getEndOffset() - 1);
}
}
public List<TodoItem> inOneList() {
final List<TodoItem> list = new ArrayList<TodoItem>();
list.addAll(getAddedOrEditedTodos());
list.addAll(getInChangedTodos());
return list;
}
}
@@ -51,6 +51,9 @@ public class ToolWindowEP extends AbstractExtensionPointBean {
@Attribute("secondary")
public boolean secondary;
@Attribute("canCloseContents")
public boolean canCloseContents;
private ToolWindowFactory myFactory;
public ToolWindowFactory getToolWindowFactory() {
@@ -16,8 +16,8 @@
package com.intellij.openapi.wm;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -54,7 +54,12 @@ public abstract class ToolWindowManager {
/**
* @deprecated {@link com.intellij.openapi.wm.ToolWindowManager#registerToolWindow(String, boolean, ToolWindowAnchor)}
*/
public abstract ToolWindow registerToolWindow(@NotNull String id,@NotNull JComponent component,@NotNull ToolWindowAnchor anchor, Disposable parentDisposable, boolean canWorkInDumbMode);
public abstract ToolWindow registerToolWindow(@NotNull String id,
@NotNull JComponent component,
@NotNull ToolWindowAnchor anchor,
Disposable parentDisposable,
boolean canWorkInDumbMode,
boolean canCloseContents);
public abstract ToolWindow registerToolWindow(@NotNull String id, boolean canCloseContent, @NotNull ToolWindowAnchor anchor);
@@ -251,7 +251,12 @@ public class ToolWindowHeadlessManagerImpl extends ToolWindowManagerEx {
return HEADLESS_WINDOW;
}
public ToolWindow registerToolWindow(@NotNull String id, @NotNull JComponent component, @NotNull ToolWindowAnchor anchor, Disposable parentDisposable, boolean canWorkInDumbMode) {
public ToolWindow registerToolWindow(@NotNull String id,
@NotNull JComponent component,
@NotNull ToolWindowAnchor anchor,
Disposable parentDisposable,
boolean canWorkInDumbMode,
boolean canCloseContents) {
return HEADLESS_WINDOW;
}
@@ -19,12 +19,7 @@ import com.intellij.Patches;
import com.intellij.ide.ui.LafManager;
import com.intellij.ide.ui.LafManagerListener;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.actionSystem.ex.AnActionListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
@@ -48,26 +43,12 @@ import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.FocusCommand;
import com.intellij.openapi.wm.FocusWatcher;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.openapi.wm.IdeFrame;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowAnchor;
import com.intellij.openapi.wm.ToolWindowContentUiType;
import com.intellij.openapi.wm.ToolWindowEP;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.openapi.wm.ToolWindowType;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.ex.ToolWindowEx;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
import com.intellij.openapi.wm.ex.ToolWindowManagerListener;
import com.intellij.openapi.wm.ex.WindowManagerEx;
import com.intellij.openapi.wm.impl.commands.ApplyWindowInfoCmd;
import com.intellij.openapi.wm.impl.commands.FinalizableCommand;
import com.intellij.openapi.wm.impl.commands.InvokeLaterCmd;
import com.intellij.openapi.wm.impl.commands.RequestFocusInEditorComponentCmd;
import com.intellij.openapi.wm.impl.commands.RequestFocusInToolWindowCmd;
import com.intellij.openapi.wm.impl.commands.UpdateRootPaneCmd;
import com.intellij.openapi.wm.impl.commands.*;
import com.intellij.ui.awt.RelativePoint;
import com.intellij.ui.switcher.QuickAccessSettings;
import com.intellij.ui.switcher.SwitchManager;
@@ -83,36 +64,16 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JRootPane;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.*;
import javax.swing.event.EventListenerList;
import javax.swing.event.HyperlinkListener;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @author Anton Katilin
@@ -487,7 +448,7 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
label.setForeground(new Color(treeFg.getRed(), treeFg.getGreen(), treeFg.getBlue(), 180));
final ToolWindowFactory factory = bean.getToolWindowFactory();
final ToolWindowImpl toolWindow =
(ToolWindowImpl)registerToolWindow(bean.id, label, toolWindowAnchor, myProject, DumbService.isDumbAware(factory));
(ToolWindowImpl)registerToolWindow(bean.id, label, toolWindowAnchor, myProject, DumbService.isDumbAware(factory), bean.canCloseContents);
toolWindow.setContentFactory(factory);
if (bean.icon != null) {
Icon icon = IconLoader.findIcon(bean.icon, factory.getClass());
@@ -1026,15 +987,15 @@ public final class ToolWindowManagerImpl extends ToolWindowManagerEx implements
@NotNull JComponent component,
@NotNull ToolWindowAnchor anchor,
Disposable parentDisposable) {
return registerToolWindow(id, component, anchor, parentDisposable, false);
return registerToolWindow(id, component, anchor, parentDisposable, false, false);
}
public ToolWindow registerToolWindow(@NotNull final String id,
@NotNull JComponent component,
@NotNull ToolWindowAnchor anchor,
Disposable parentDisposable,
boolean canWorkInDumbMode) {
return registerDisposable(id, parentDisposable, registerToolWindow(id, component, anchor, canWorkInDumbMode));
boolean canWorkInDumbMode, boolean canCloseContents) {
return registerDisposable(id, parentDisposable, registerToolWindow(id, component, anchor, false, canCloseContents, canWorkInDumbMode));
}
private ToolWindow registerToolWindow(@NotNull final String id,
@@ -228,9 +228,10 @@ before.commit.files.contain.code.smells.edit.them.confirm.text=Some files contai
{0,choice, 0#No errors|1#One error|2#{0} errors} and {1,choice, 0#no warnings|1#one warning|2#{1} warnings} found.\n\
Would you like to review them?
code.smells.review.button=&Review
todo.in.new.review.button=&Review new or changed TODOs
todo.in.new.review.button=&Review
before.checkin.standard.options.check.smells=Perform code analy&sis for affected files
before.checkin.new.todo.check=Check for added TODO items
before.checkin.new.todo.check=Check TODO ({0})
before.checkin.new.todo.check.title=Check TODO
# Changes view
changes.nodetitle.unversioned.files=Unversioned Files
@@ -564,7 +564,7 @@
<toolWindow id="Project" anchor="left" icon="/general/toolWindowProject.png"
factoryClass="com.intellij.ide.projectView.impl.ProjectViewToolWindowFactory"/>
<toolWindow id="TODO" anchor="bottom" icon="/general/toolWindowTodo.png"
factoryClass="com.intellij.ide.todo.TodoToolWindowFactory"/>
factoryClass="com.intellij.ide.todo.TodoToolWindowFactory" canCloseContents="true"/>
<toolWindow id="Structure" anchor="left" icon="/general/toolWindowStructure.png" secondary="true"
factoryClass="com.intellij.ide.structureView.impl.StructureViewToolWindowFactory"/>
<psi.fileReferenceHelper implementation="com.intellij.psi.impl.source.resolve.reference.impl.providers.PsiFileReferenceHelper"/>
@@ -16,6 +16,7 @@
package com.intellij.ide.todo;
import com.intellij.openapi.util.JDOMExternalizable;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
@@ -24,12 +25,12 @@ import java.util.Iterator;
/**
* @author Vladimir Kondratyev
*/
class TodoPanelSettings{
private boolean myArePackagesShown;
private boolean myAreModulesShown;
private boolean myAreFlattenPackages;
private boolean myIsAutoScrollToSource;
private String myTodoFilterName;
public class TodoPanelSettings implements JDOMExternalizable {
public boolean myArePackagesShown;
public boolean myAreModulesShown;
public boolean myAreFlattenPackages;
public boolean myIsAutoScrollToSource;
public String myTodoFilterName;
@NonNls private static final String ATTRIBUTE_VALUE = "value";
@NonNls private static final String ELEMENT_ARE_PACKAGES_SHOWN = "are-packages-shown";
@@ -39,6 +40,17 @@ class TodoPanelSettings{
@NonNls private static final String ELEMENT_TODO_FILTER = "todo-filter";
@NonNls private static final String ATTRIBUTE_NAME = "name";
public TodoPanelSettings() {
}
public TodoPanelSettings(TodoPanelSettings s) {
myArePackagesShown = s.myArePackagesShown;
myAreModulesShown = s.myAreModulesShown;
myAreFlattenPackages = s.myAreFlattenPackages;
myIsAutoScrollToSource = s.myIsAutoScrollToSource;
myTodoFilterName = s.myTodoFilterName;
}
public void readExternal(Element e){
for(Iterator i=e.getChildren().iterator();i.hasNext();){
Element child=(Element)i.next();
@@ -84,7 +96,7 @@ class TodoPanelSettings{
}
}
boolean areModulesShown() {
public boolean areModulesShown() {
return myAreModulesShown;
}
@@ -92,7 +104,7 @@ class TodoPanelSettings{
myAreModulesShown = state;
}
boolean arePackagesShown(){
public boolean arePackagesShown(){
return myArePackagesShown;
}
@@ -100,27 +112,27 @@ class TodoPanelSettings{
myArePackagesShown=state;
}
boolean areFlattenPackages(){
public boolean areFlattenPackages(){
return myAreFlattenPackages;
}
void setAreFlattenPackages(boolean state){
public void setAreFlattenPackages(boolean state){
myAreFlattenPackages=state;
}
boolean isAutoScrollToSource(){
public boolean isAutoScrollToSource(){
return myIsAutoScrollToSource;
}
void setAutoScrollToSource(boolean state){
public void setAutoScrollToSource(boolean state){
myIsAutoScrollToSource=state;
}
String getTodoFilterName(){
public String getTodoFilterName(){
return myTodoFilterName;
}
void setTodoFilterName(String todoFilterName){
public void setTodoFilterName(String todoFilterName){
myTodoFilterName=todoFilterName;
}
}
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.vcs;
import com.intellij.ide.todo.TodoPanelSettings;
import com.intellij.lifecycle.PeriodicalTasksCloser;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.ProjectComponent;
@@ -58,6 +59,7 @@ public final class VcsConfiguration implements PersistentStateComponent<Element>
public boolean OFFER_MOVE_TO_ANOTHER_CHANGELIST_ON_PARTIAL_COMMIT = true;
public boolean CHECK_CODE_SMELLS_BEFORE_PROJECT_COMMIT = true;
public boolean CHECK_NEW_TODO = true;
public TodoPanelSettings myTodoPanelSettings = new TodoPanelSettings();
public boolean PERFORM_UPDATE_IN_BACKGROUND = true;
public boolean PERFORM_COMMIT_IN_BACKGROUND = true;
public boolean PERFORM_EDIT_IN_BACKGROUND = true;
@@ -215,7 +215,7 @@ public class MavenProjectsNavigator extends SimpleProjectComponent implements Pe
JPanel panel = new MavenProjectsNavigatorPanel(myProject, myTree);
final ToolWindowManagerEx manager = ToolWindowManagerEx.getInstanceEx(myProject);
myToolWindow = manager.registerToolWindow(TOOL_WINDOW_ID, panel, ToolWindowAnchor.RIGHT, myProject, true);
myToolWindow = manager.registerToolWindow(TOOL_WINDOW_ID, panel, ToolWindowAnchor.RIGHT, myProject, true, false);
myToolWindow.setIcon(MavenIcons.MAVEN_ICON);
final ToolWindowManagerAdapter listener = new ToolWindowManagerAdapter() {
@@ -102,7 +102,7 @@ public class UIDesignerToolWindowManager implements ProjectComponent {
myToolWindowPanel.setSecondComponent(myPropertyInspector);
myToolWindow = ToolWindowManager.getInstance(myProject).registerToolWindow(UIDesignerBundle.message("toolwindow.ui.designer"),
myToolWindowPanel,
ToolWindowAnchor.LEFT, myProject, true);
ToolWindowAnchor.LEFT, myProject, true, false);
myToolWindow.setIcon(IconLoader.getIcon("/com/intellij/uiDesigner/icons/toolWindowUIDesigner.png"));
myToolWindow.setAvailable(false, null);
}
+1
View File
@@ -744,6 +744,7 @@
<checkinHandlerFactory implementation="com.intellij.openapi.vcs.checkin.StandardCheckinHandlerFactory"/>
<checkinHandlerFactory implementation="com.intellij.openapi.vcs.checkin.CodeAnalysisCheckinHandlerFactory"/>
<checkinHandlerFactory implementation="com.intellij.openapi.vcs.checkin.TodoCheckinHandlerFactory"/>
<configurationProducer implementation="com.intellij.execution.application.ApplicationConfigurationProducer"/>