8000 provide better scope detection for Service Generator, add psr-0 class… · Koc/idea-php-symfony2-plugin@8314531 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8314531

Browse files
committed
provide better scope detection for Service Generator, add psr-0 class structure detection fixes: "Create Service" in project tree does nothing Haehnchen#978
1 parent 6ef034a commit 8314531

File tree

4 files changed

+113
-41
lines changed

4 files changed

+113
-41
lines changed

src/fr/adrienbrault/idea/symfony2plugin/action/SymfonyContainerServiceBuilder.java

Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.intellij.openapi.editor.Editor;
66
import com.intellij.openapi.project.DumbAwareAction;
77
import com.intellij.openapi.project.Project;
8+
import com.intellij.openapi.util.Pair;
89
import com.intellij.psi.PsiElement;
910
import com.intellij.psi.PsiFile;
1011
import com.intellij.psi.xml.XmlFile;
@@ -13,9 +14,14 @@
1314
import fr.adrienbrault.idea.symfony2plugin.Symfony2Icons;
1415
import fr.adrienbrault.idea.symfony2plugin.Symfony2ProjectComponent;
1516
import fr.adrienbrault.idea.symfony2plugin.action.ui.SymfonyCreateService;
17+
import fr.adrienbrault.idea.symfony2plugin.util.IdeHelper;
1618
import fr.adrienbrault.idea.symfony2plugin.util.PhpElementsUtil;
19+
import org.jetbrains.annotations.NotNull;
20+
import org.jetbrains.annotations.Nullable;
1721
import org.jetbrains.yaml.psi.YAMLFile;
1822

23+
import java.awt.*;
24+
1925
/**
2026
* @author Daniel Espendiller <daniel@espendiller.net>
2127
*/
@@ -33,29 +39,15 @@ public void update(AnActionEvent event) {
3339
return;
3440
}
3541

36-
PsiFile psiFile = event.getData(PlatformDataKeys.PSI_FILE);
37-
if(psiFile instanceof PhpFile) {
38-
39-
if("ProjectViewPopup".equals(event.getPlace())) {
40-
41-
if(PhpElementsUtil.getFirstClassFromFile((PhpFile) psiFile) == null) {
42-
this.setStatus(event, false);
43-
}
44-
45-
} else {
46-
PsiElement psiElement = event.getData(PlatformDataKeys.PSI_ELEMENT);
47-
if(!(psiElement instanceof PhpClass)) {
48-
this.setStatus(event, false);
49-
}
50-
}
51-
42+
Pair<PsiFile, PhpClass> pair = findPhpClass(event);
43+
if(pair == null) {
5244
return;
5345
}
5446

55-
if(!(psiFile instanceof YAMLFile) && !(psiFile instanceof XmlFile)) {
47+
PsiFile psiFile = pair.getFirst();
48+
if(!(psiFile instanceof YAMLFile) && !(psiFile instanceof XmlFile) && !(psiFile instanceof PhpFile)) {
5649
this.setStatus(event, false);
5750
}
58-
5951
}
6052

6153
private void setStatus(AnActionEvent event, boolean status) {
@@ -64,42 +56,51 @@ private void setStatus(AnActionEvent event, boolean status) {
6456
}
6557

6658
public void actionPerformed(AnActionEvent event) {
67-
6859
Project project = event.getProject();
6960
if(project == null) {
7061
return;
7162
}
7263

7364
Editor editor = event.getData(PlatformDataKeys.EDITOR);
74-
if(editor == null) {
65+
66+
Component applicationWindow = IdeHelper.getWindowComponentFromProject(event.getProject());
67+
if(applicationWindow == null) {
7568
return;
7669
}
7770

78-
PsiFile psiFile = event.getData(PlatformDataKeys.PSI_FILE);
79-
if(!(psiFile instanceof YAMLFile) && !(psiFile instanceof XmlFile) && !(psiFile instanceof PhpFile)) {
71+
Pair<PsiFile, PhpClass> pair = findPhpClass(event);
72+
if(pair == null) {
8073
return;
8174
}
8275

83-
PhpClass phpClass = null;
84-
if(psiFile instanceof PhpFile) {
76+
if(pair.getSecond() == null) {
77+
SymfonyCreateService.create(applicationWindow, project, pair.getFirst(), editor);
78+
return;
79+
}
8580

86-
if("ProjectViewPopup".equals(event.getPlace())) {
87-
phpClass = PhpElementsUtil.getFirstClassFromFile((PhpFile) psiFile);
88-
} else {
89-
PsiElement psiElement = event.getData(PlatformDataKeys.PSI_ELEMENT);
90-
if(psiElement instanceof PhpClass) {
91-
phpClass = (PhpClass) psiElement;
92-
}
93-
}
81+
SymfonyCreateService.create(applicationWindow, project, pair.getFirst(), pair.getSecond(), editor);
82+
}
9483

84+
@Nullable
85+
private Pair<PsiFile, PhpClass> findPhpClass(@NotNull AnActionEvent event) {
86+
PsiFile psiFile = event.getData(PlatformDataKeys.PSI_FILE);
87+
if(!(psiFile instanceof YAMLFile) && !(psiFile instanceof XmlFile) && !(psiFile instanceof PhpFile)) {
88+
return null;
9589
}
9690

97-
if(phpClass == null) {
98-
SymfonyCreateService.create(editor.getComponent(), project, psiFile, editor);
99-
return;
91+
if("ProjectViewPopup".equals(event.getPlace())) {
92+
// menu item
93+
return Pair.create(psiFile, PhpElementsUtil.getFirstClassFromFile((PhpFile) psiFile));
94+
} else {
95+
PsiElement psiElement = event.getData(PlatformDataKeys.PSI_ELEMENT);
96+
if(psiElement instanceof PhpClass) {
97+
// directly got the class
98+
return Pair.create(psiFile, (PhpClass) psiElement);
99+
} else {
100+
// click inside class
101+
return Pair.create(psiFile, PhpElementsUtil.getFirstClassFromFile((PhpFile) psiFile));
102+
}
100103
}
101-
102-
SymfonyCreateService.create(editor.getComponent(), project, psiFile, phpClass, editor);
103104
}
104105
}
105106

src/fr/adrienbrault/idea/symfony2plugin/action/ui/SymfonyCreateService.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -564,24 +564,28 @@ public int compare(ContainerService o1, ContainerService o2) {
564564
}
565565
}
566566

567-
private static SymfonyCreateService prepare(@NotNull Component component, @NotNull SymfonyCreateService service) {
567+
private static SymfonyCreateService prepare(@Nullable Component component, @NotNull SymfonyCreateService service) {
568568
service.init();
569569
service.setTitle("Symfony: Service Generator");
570570
service.setIconImage(Symfony2Icons.getImage(Symfony2Icons.SYMFONY));
571571
service.pack();
572572

573573
service.setMinimumSize(new Dimension(550, 250));
574-
service.setLocationRelativeTo(component);
574+
575+
if(component != null) {
576+
service.setLocationRelativeTo(component);
577+
}
578+
575579
service.setVisible(true);
576580

577581
return service;
578582
}
579583

580-
public static SymfonyCreateService create(@NotNull Component component, @NotNull Project project, @NotNull PsiFile psiFile, @Nullable Editor editor) {
584+
public static SymfonyCreateService create(@Nullable Component component, @NotNull Project project, @NotNull PsiFile psiFile, @Nullable Editor editor) {
581585
return prepare(component, new SymfonyCreateService(project, psiFile, editor));
582586
}
583587

584-
public static SymfonyCreateService create(@NotNull Component component, @NotNull Project project, @NotNull PsiFile psiFile, @NotNull PhpClass phpClass, @Nullable Editor editor) {
588+
public static SymfonyCreateService create(@Nullable Component component, @NotNull Project project, @NotNull PsiFile psiFile, @NotNull PhpClass phpClass, @Nullable Editor editor) {
585589
return prepare(component, new SymfonyCreateService(project, psiFile, editor, phpClass.getFQN()));
586590
}
587591
}

src/fr/adrienbrault/idea/symfony2plugin/util/IdeHelper.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,31 @@
44
import com.intellij.notification.Notification;
55
import com.intellij.notification.NotificationType;
66
import com.intellij.notification.Notifications;
7+
import com.intellij.openapi.application.ex.ApplicationManagerEx;
78
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
89
import com.intellij.openapi.fileTypes.FileType;
910
import com.intellij.openapi.project.Project;
1011
import com.intellij.openapi.vfs.VfsUtil;
1112
import com.intellij.openapi.vfs.VirtualFile;
13+
import com.intellij.openapi.wm.ex.WindowManagerEx;
1214
import com.intellij.pom.Navigatable;
1315
import com.intellij.psi.*;
1416
import com.intellij.psi.codeStyle.CodeStyleManager;
17+
import com.intellij.util.ui.UIUtil;
1518
import fr.adrienbrault.idea.symfony2plugin.Settings;
1619
import fr.adrienbrault.idea.symfony2plugin.SettingsForm;
1720
import org.apache.commons.lang.StringUtils;
1821
import org.jetbrains.annotations.NotNull;
1922
import org.jetbrains.annotations.Nullable;
2023

24+
import java.awt.*;
2125
import java.io.IOException;
2226
import java.net.URISyntaxException;
2327
import java.util.Arrays;
2428

29+
/**
30+
* @author Daniel Espendiller <daniel@espendiller.net>
31+
*/
2532
public class IdeHelper {
2633

2734
public static void openUrl(String url) {
@@ -155,4 +162,47 @@ public static void navigateToPsiElement(@NotNull PsiElement psiElement) {
155162
}
156163
}
157164

165+
/**
166+
* Find a window manager
167+
*
168+
* @see com.intellij.ui.popup.AbstractPopup
169+
*/
170+
@Nullable
171+
private static WindowManagerEx getWindowManager() {
172+
return ApplicationManagerEx.getApplicationEx() != null ? WindowManagerEx.getInstanceEx() : null;
173+
}
174+
175+
/**
176+
* Find current window element of given project.
177+
* Use this to find a component for new dialogs without using JBPopupFactory
178+
*
179+
* @see com.intellij.ui.popup.AbstractPopup#showCenteredInCurrentWindow
180+
*/
181+
@Nullable
182+
public static Window getWindowComponentFromProject(@NotNull Project project) {
183+
WindowManagerEx windowManager = getWindowManager();
184+
if(windowManager == null) {
185+
return null;
186+
}
187+
188+
Window window = null;
189+
190+
Component focusedComponent = windowManager.getFocusedComponent(project);
191+
if (focusedComponent != null) {
192+
Component parent = UIUtil.findUltimateParent(focusedComponent);
193+
if (parent instanceof Window) {
194+
window = (Window)parent;
195+
}
196+
}
197+
198+
if (window == null) {
199+
window = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusedWindow();
200+
}
201+
202+
if (window != null && window.isShowing()) {
203+
return window;
204+
}
205+
206+
return window;
207+
}
158208
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package fr.adrienbrault.idea.symfony2plugin.tests.action;
2+
3+
import fr.adrienbrault.idea.symfony2plugin.action.SymfonyContainerServiceBuilder;
4+
import fr.adrienbrault.idea.symfony2plugin.tests.SymfonyLightCodeInsightFixtureTestCase;
5+
6+
/**
7+
* @author Daniel Espendiller <daniel@espendiller.net>
8+
*/
9+
public class SymfonyContainerServiceBuilderTest extends SymfonyLightCodeInsightFixtureTestCase {
10+
public void testActionAvailableForFileScope() {
11+
myFixture.configureByText("test.php", "<?php\n" +
12+
"class Foobar {}"
13+
);
14+
15+
assertTrue(myFixture.testAction(new SymfonyContainerServiceBuilder()).isEnabledAndVisible());
16+
}
17+
}

0 commit comments

Comments
 (0)
0