diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
index 5f21107dbb66..eb32d6770b9b 100644
--- a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
+++ b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
@@ -206,13 +206,13 @@ public class CompilerTask extends Task.Backgroundable {
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
AppIcon appIcon = AppIcon.getInstance();
- if (appIcon.hideProgress(APP_ICON_ID)) {
+ if (appIcon.hideProgress(myProject, APP_ICON_ID)) {
if (myErrorCount > 0) {
- appIcon.setErrorBadge(String.valueOf(myErrorCount));
- appIcon.requestAttention(true);
+ appIcon.setErrorBadge(myProject, String.valueOf(myErrorCount));
+ appIcon.requestAttention(myProject, true);
} else {
- appIcon.setOkBadge(true);
- appIcon.requestAttention(false);
+ appIcon.setOkBadge(myProject, true);
+ appIcon.requestAttention(myProject, false);
}
}
}
@@ -234,7 +234,7 @@ public class CompilerTask extends Task.Backgroundable {
updateProgressText();
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
- AppIcon.getInstance().setProgress(APP_ICON_ID, AppIconScheme.Progress.BUILD, fraction, true);
+ AppIcon.getInstance().setProgress(myProject, APP_ICON_ID, AppIconScheme.Progress.BUILD, fraction, true);
}
});
}
@@ -608,8 +608,8 @@ public class CompilerTask extends Task.Backgroundable {
if (myIndicator.isRunning()) {
cancel();
}
- if (AppIcon.getInstance().hideProgress("compiler")) {
- AppIcon.getInstance().setErrorBadge(null);
+ if (AppIcon.getInstance().hideProgress(myProject, "compiler")) {
+ AppIcon.getInstance().setErrorBadge(myProject, null);
}
}
}
diff --git a/platform/platform-impl/platform-impl.iml b/platform/platform-impl/platform-impl.iml
index 6352a86e24e3..4f7402a5e714 100644
--- a/platform/platform-impl/platform-impl.iml
+++ b/platform/platform-impl/platform-impl.iml
@@ -33,6 +33,7 @@
+
diff --git a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
index 6a7de8845652..654805d7ab88 100644
--- a/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/project/DumbServiceImpl.java
@@ -298,7 +298,7 @@ public class DumbServiceImpl extends DumbService {
lastFraction = fraction;
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
- AppIcon.getInstance().setProgress("indexUpdate", AppIconScheme.Progress.INDEXING, fraction, true);
+ AppIcon.getInstance().setProgress(myProject, "indexUpdate", AppIconScheme.Progress.INDEXING, fraction, true);
}
});
}
@@ -308,9 +308,9 @@ public class DumbServiceImpl extends DumbService {
UIUtil.invokeLaterIfNeeded(new Runnable() {
public void run() {
AppIcon appIcon = AppIcon.getInstance();
- if (appIcon.hideProgress("indexUpdate")) {
- appIcon.requestAttention(false);
- appIcon.setOkBadge(true);
+ if (appIcon.hideProgress(myProject, "indexUpdate")) {
+ appIcon.requestAttention(myProject, false);
+ appIcon.setOkBadge(myProject, true);
}
}
});
diff --git a/platform/platform-impl/src/com/intellij/ui/AppIcon.java b/platform/platform-impl/src/com/intellij/ui/AppIcon.java
index f7f266744be0..cb22524ee689 100644
--- a/platform/platform-impl/src/com/intellij/ui/AppIcon.java
+++ b/platform/platform-impl/src/com/intellij/ui/AppIcon.java
@@ -20,35 +20,42 @@ import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationActivationListener;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.wm.AppIconScheme;
import com.intellij.openapi.wm.IdeFrame;
+import com.intellij.openapi.wm.WindowManager;
+import org.apache.sanselan.ImageFormat;
+import org.apache.sanselan.Sanselan;
+import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
+import java.io.ByteArrayOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.HashMap;
public abstract class AppIcon {
- static Logger LOG = Logger.getInstance("AppIcon");
+ private static final Logger LOG = Logger.getInstance("AppIcon");
static AppIcon ourMacImpl;
static AppIcon ourWin7Impl;
static AppIcon ourEmptyImpl;
- public abstract boolean setProgress(Object processId, AppIconScheme.Progress scheme, double value, boolean isOk);
+ public abstract boolean setProgress(Project project, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk);
- public abstract boolean hideProgress(Object processId);
+ public abstract boolean hideProgress(Project project, Object processId);
- public abstract void setErrorBadge(String text);
+ public abstract void setErrorBadge(Project project, String text);
- public abstract void setOkBadge(boolean visible);
+ public abstract void setOkBadge(Project project, boolean visible);
- public abstract void requestAttention(boolean critical);
+ public abstract void requestAttention(Project project, boolean critical);
public abstract void requestFocus(IdeFrame frame);
@@ -61,9 +68,11 @@ public abstract class AppIcon {
if (SystemInfo.isMac && SystemInfo.isJavaVersionAtLeast("1.6")) {
return ourMacImpl;
- } else if (SystemInfo.isWindows7) {
+ }
+ else if (SystemInfo.isWindows7) {
return ourWin7Impl;
- } else {
+ }
+ else {
return ourEmptyImpl;
}
}
@@ -72,57 +81,62 @@ public abstract class AppIcon {
private ApplicationActivationListener myAppListener;
protected Object myCurrentProcessId;
+ protected double myLastValue;
@Override
- public final boolean setProgress(Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
+ public final boolean setProgress(Project project, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
if (!isAppActive() && Registry.is("ide.appIcon.progress") && (myCurrentProcessId == null || myCurrentProcessId.equals(processId))) {
- return _setProgress(processId, scheme, value, isOk);
- } else {
+ return _setProgress(getIdeFrame(project), processId, scheme, value, isOk);
+ }
+ else {
return false;
}
}
@Override
- public final boolean hideProgress(Object processId) {
+ public final boolean hideProgress(Project project, Object processId) {
if (Registry.is("ide.appIcon.progress")) {
- return _hideProgress(processId);
- } else {
+ return _hideProgress(getIdeFrame(project), processId);
+ }
+ else {
return false;
}
}
@Override
- public final void setErrorBadge(String text) {
+ public final void setErrorBadge(Project project, String text) {
if (!isAppActive() && Registry.is("ide.appIcon.badge")) {
- _setOkBadge(false);
- _setTextBadge(text);
+ _setOkBadge(getIdeFrame(project), false);
+ _setTextBadge(getIdeFrame(project), text);
}
}
@Override
- public final void setOkBadge(boolean visible) {
+ public final void setOkBadge(Project project, boolean visible) {
if (!isAppActive() && Registry.is("ide.appIcon.badge")) {
- _setTextBadge(null);
- _setOkBadge(visible);
+ _setTextBadge(getIdeFrame(project), null);
+ _setOkBadge(getIdeFrame(project), visible);
}
}
@Override
- public final void requestAttention(boolean critical) {
+ public final void requestAttention(Project project, boolean critical) {
if (!isAppActive() && Registry.is("ide.appIcon.requestAttention")) {
- _requestAttention(critical);
+ _requestAttention(getIdeFrame(project), critical);
}
}
- public abstract boolean _setProgress(Object processId, AppIconScheme.Progress scheme, double value, boolean isOk);
+ public abstract boolean _setProgress(IdeFrame frame, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk);
- public abstract boolean _hideProgress(Object processId);
+ public abstract boolean _hideProgress(IdeFrame frame, Object processId);
- public abstract void _setTextBadge(String text);
+ public abstract void _setTextBadge(IdeFrame frame, String text);
- public abstract void _setOkBadge(boolean visible);
+ public abstract void _setOkBadge(IdeFrame frame, boolean visible);
- public abstract void _requestAttention(boolean critical);
+ public abstract void _requestAttention(IdeFrame frame, boolean critical);
+
+ protected abstract IdeFrame getIdeFrame(Project project);
private boolean isAppActive() {
Application app = ApplicationManager.getApplication();
@@ -131,9 +145,9 @@ public abstract class AppIcon {
myAppListener = new ApplicationActivationListener() {
@Override
public void applicationActivated(IdeFrame ideFrame) {
- hideProgress(myCurrentProcessId);
- _setOkBadge(false);
- _setTextBadge(null);
+ hideProgress(ideFrame.getProject(), myCurrentProcessId);
+ _setOkBadge(ideFrame, false);
+ _setTextBadge(ideFrame, null);
}
@Override
@@ -152,8 +166,6 @@ public abstract class AppIcon {
private static BufferedImage myAppImage;
- private double myLastValue;
-
private BufferedImage getAppImage() {
assertIsDispatchThread();
@@ -171,10 +183,9 @@ public abstract class AppIcon {
Graphics2D g2d = img.createGraphics();
g2d.drawImage(appImage, null, null);
myAppImage = img;
-
}
catch (NoSuchMethodException e) {
- return null;
+ return null;
}
catch (Exception e) {
LOG.error(e);
@@ -184,7 +195,7 @@ public abstract class AppIcon {
}
@Override
- public void _setTextBadge(String text) {
+ public void _setTextBadge(IdeFrame frame, String text) {
assertIsDispatchThread();
try {
@@ -214,7 +225,7 @@ public abstract class AppIcon {
}
@Override
- public void _requestAttention(boolean critical) {
+ public void _requestAttention(IdeFrame frame, boolean critical) {
assertIsDispatchThread();
try {
@@ -229,7 +240,12 @@ public abstract class AppIcon {
}
@Override
- public boolean _hideProgress(Object processId) {
+ protected IdeFrame getIdeFrame(Project project) {
+ return null;
+ }
+
+ @Override
+ public boolean _hideProgress(IdeFrame frame, Object processId) {
assertIsDispatchThread();
if (getAppImage() == null) return false;
@@ -243,7 +259,7 @@ public abstract class AppIcon {
}
@Override
- public void _setOkBadge(boolean visible) {
+ public void _setOkBadge(IdeFrame frame, boolean visible) {
assertIsDispatchThread();
if (getAppImage() == null) return;
@@ -262,7 +278,8 @@ public abstract class AppIcon {
setDockIcon(img.myImg);
}
- public boolean _setProgress(Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
+ @Override
+ public boolean _setProgress(IdeFrame frame, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
assertIsDispatchThread();
if (getAppImage() == null) return false;
@@ -279,8 +296,10 @@ public abstract class AppIcon {
final int width = myAppImage.getWidth() - xInset * 2;
final int y = myAppImage.getHeight() - progressHeight - yInset;
Shape rect = new RoundRectangle2D.Double(xInset, y, width, progressHeight, progressHeight, progressHeight);
- Shape border = new RoundRectangle2D.Double(xInset - 1, y - 1, width + 2, progressHeight + 2, (progressHeight + 2), (progressHeight + 2));
- Shape progress = new RoundRectangle2D.Double(xInset + 1, y + 1, (width - 2) * value, progressHeight - 2, (progressHeight - 2), (progressHeight - 2));
+ Shape border =
+ new RoundRectangle2D.Double(xInset - 1, y - 1, width + 2, progressHeight + 2, (progressHeight + 2), (progressHeight + 2));
+ Shape progress = new RoundRectangle2D.Double(xInset + 1, y + 1, (width - 2) * value, progressHeight - 2, (progressHeight - 2),
+ (progressHeight - 2));
AppImage appImg = createAppImage();
appImg.myG2d.setColor(Color.GRAY.brighter().brighter());
@@ -323,7 +342,6 @@ public abstract class AppIcon {
}
}
-
private void setDockIcon(BufferedImage image) {
try {
getAppMethod("setDockIconImage", Image.class).invoke(getApp(), image);
@@ -344,30 +362,134 @@ public abstract class AppIcon {
private Class> getAppClass() throws ClassNotFoundException {
return Class.forName("com.apple.eawt.Application");
}
-
}
private static class Win7AppIcon extends BaseIcon {
@Override
- public boolean _setProgress(Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
- return false;
+ public boolean _setProgress(IdeFrame frame, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
+ myCurrentProcessId = processId;
+
+ if (Math.abs(myLastValue - value) < 0.02d) {
+ return true;
+ }
+
+ try {
+ Win7TaskBar.setProgress(frame, value, isOk);
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ }
+
+ myLastValue = value;
+ myCurrentProcessId = null;
+ return true;
}
@Override
- public boolean _hideProgress(Object processId) {
- return false;
+ public boolean _hideProgress(IdeFrame frame, Object processId) {
+ if (myCurrentProcessId != null && !myCurrentProcessId.equals(processId)) {
+ return false;
+ }
+
+ try {
+ Win7TaskBar.hideProgress(frame);
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ }
+
+ myCurrentProcessId = null;
+ myLastValue = 0;
+ return true;
+ }
+
+ private static final Color ERROR_COLOR = new Color(197, 54, 13);
+
+ @Override
+ public void _setTextBadge(IdeFrame frame, String text) {
+ Object icon = null;
+
+ if (text != null) {
+ try {
+ int size = 55;
+ BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = image.createGraphics();
+
+ int roundSize = 40;
+ g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g.setPaint(ERROR_COLOR);
+ g.fillRoundRect(size / 2 - roundSize / 2, size / 2 - roundSize / 2, roundSize, roundSize, size, size);
+
+ g.setColor(Color.white);
+ Font font = g.getFont();
+ g.setFont(new Font(font.getName(), font.getStyle(), 22));
+ FontMetrics fontMetrics = g.getFontMetrics();
+ int width = fontMetrics.stringWidth(text);
+ g.drawString(text, size / 2 - width / 2, size / 2 - fontMetrics.getHeight() / 2 + fontMetrics.getAscent());
+
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ Sanselan.writeImage(image, bytes, ImageFormat.IMAGE_FORMAT_ICO, new HashMap());
+ icon = Win7TaskBar.createIcon(bytes.toByteArray());
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ }
+ }
+
+ try {
+ Win7TaskBar.setOverlayIcon(frame, icon, icon != null);
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ }
+ }
+
+ private static Object myOkIcon;
+
+ @Override
+ public void _setOkBadge(IdeFrame frame, boolean visible) {
+ Object icon = null;
+
+ if (visible) {
+ synchronized (Win7AppIcon.class) {
+ if (myOkIcon == null) {
+ try {
+ BufferedImage image = ImageIO.read(getClass().getResource("/mac/appIconOk512.png"));
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ Sanselan.writeImage(image, bytes, ImageFormat.IMAGE_FORMAT_ICO, new HashMap());
+ myOkIcon = Win7TaskBar.createIcon(bytes.toByteArray());
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ myOkIcon = null;
+ }
+ }
+
+ icon = myOkIcon;
+ }
+ }
+
+ try {
+ Win7TaskBar.setOverlayIcon(frame, icon, false);
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ }
}
@Override
- public void _setTextBadge(String text) {
+ public void _requestAttention(IdeFrame frame, boolean critical) {
+ try {
+ Win7TaskBar.attention(frame, critical);
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ }
}
@Override
- public void _setOkBadge(boolean visible) {
- }
-
- @Override
- public void _requestAttention(boolean critical) {
+ protected IdeFrame getIdeFrame(Project project) {
+ return WindowManager.getInstance().getIdeFrame(project);
}
@Override
@@ -377,25 +499,25 @@ public abstract class AppIcon {
private static class EmptyIcon extends AppIcon {
@Override
- public boolean setProgress(Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
+ public boolean setProgress(Project project, Object processId, AppIconScheme.Progress scheme, double value, boolean isOk) {
return false;
}
@Override
- public boolean hideProgress(Object processId) {
+ public boolean hideProgress(Project project, Object processId) {
return false;
}
@Override
- public void setErrorBadge(String text) {
+ public void setErrorBadge(Project project, String text) {
}
@Override
- public void setOkBadge(boolean visible) {
+ public void setOkBadge(Project project, boolean visible) {
}
@Override
- public void requestAttention(boolean critical) {
+ public void requestAttention(Project project, boolean critical) {
}
@Override
@@ -409,9 +531,9 @@ public abstract class AppIcon {
if (!app.isUnitTestMode()) {
app.assertIsDispatchThread();
}
- } else {
+ }
+ else {
assert EventQueue.isDispatchThread();
}
}
-
}
diff --git a/platform/platform-impl/src/com/intellij/ui/Win7TaskBar.java b/platform/platform-impl/src/com/intellij/ui/Win7TaskBar.java
new file mode 100644
index 000000000000..e6a0f0666ad9
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ui/Win7TaskBar.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2000-2012 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.ui;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.wm.IdeFrame;
+import com.sun.jna.Function;
+import com.sun.jna.Memory;
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.platform.win32.*;
+import com.sun.jna.ptr.PointerByReference;
+import com.sun.jna.win32.StdCallLibrary;
+import com.sun.jna.win32.W32APIOptions;
+
+import java.awt.*;
+import java.awt.peer.ComponentPeer;
+import java.lang.reflect.Method;
+
+/**
+ * @author Alexander Lobas
+ */
+class Win7TaskBar {
+ private static final Logger LOG = Logger.getInstance("Win7TaskBar");
+
+ private static final int TaskBarList_Methods = 21;
+ private static final int TaskBarList_SetProgressValue = 9;
+ private static final int TaskBarList_SetProgressState = 10;
+ private static final int TaskBarList_SetOverlayIcon = 18;
+
+ private static final WinDef.DWORD ICO_VERSION = new WinDef.DWORD(0x00030000);
+ private static final WinDef.DWORD DWORD_ZERO = new WinDef.DWORD(0);
+ private static final WinDef.DWORD TBPF_NOPROGRESS = DWORD_ZERO;
+ private static final WinDef.DWORD TBPF_NORMAL = new WinDef.DWORD(0x2);
+ private static final WinDef.DWORD TBPF_ERROR = new WinDef.DWORD(0x4);
+ private static final WinDef.ULONGLONG TOTAL_PROGRESS = new WinDef.ULONGLONG(100);
+
+ private static Pointer myInterfacePointer;
+ private static Function mySetProgressValue;
+ private static Function mySetProgressState;
+ private static Function mySetOverlayIcon;
+
+ public interface User32Ex extends StdCallLibrary {
+ User32Ex INSTANCE = (User32Ex)Native.loadLibrary("user32", User32Ex.class, W32APIOptions.DEFAULT_OPTIONS);
+
+ int LookupIconIdFromDirectoryEx(Memory presbits, boolean fIcon, int cxDesired, int cyDesired, int Flags);
+
+ WinDef.HICON CreateIconFromResourceEx(Pointer presbits,
+ WinDef.DWORD dwResSize,
+ boolean fIcon,
+ WinDef.DWORD dwVer,
+ int cxDesired,
+ int cyDesired,
+ int Flags);
+
+ boolean FlashWindow(WinDef.HWND hwnd, boolean bInvert);
+ }
+
+ private static class MyMemory extends Memory {
+ private MyMemory(long size) {
+ super(size);
+ }
+
+ @Override
+ public synchronized void dispose() {
+ super.dispose();
+ }
+ }
+
+ static {
+ initialize();
+ }
+
+ private static void initialize() {
+ Ole32 ole32 = Ole32.INSTANCE;
+ ole32.CoInitializeEx(Pointer.NULL, 0);
+
+ Guid.GUID CLSID_TaskbarList = Ole32Util.getGUIDFromString("{56FDF344-FD6D-11d0-958A-006097C9A090}");
+ Guid.GUID IID_ITaskbarList3 = Ole32Util.getGUIDFromString("{EA1AFB91-9E28-4B86-90E9-9E9F8A5EEFAF}");
+ PointerByReference p = new PointerByReference();
+ ole32.CoCreateInstance(CLSID_TaskbarList, Pointer.NULL, ObjBase.CLSCTX_ALL, IID_ITaskbarList3, p);
+
+ myInterfacePointer = p.getValue();
+ Pointer vTablePointer = myInterfacePointer.getPointer(0);
+ Pointer[] vTable = new Pointer[TaskBarList_Methods];
+ vTablePointer.read(0, vTable, 0, vTable.length);
+
+ mySetProgressValue = Function.getFunction(vTable[TaskBarList_SetProgressValue], Function.ALT_CONVENTION);
+ mySetProgressState = Function.getFunction(vTable[TaskBarList_SetProgressState], Function.ALT_CONVENTION);
+ mySetOverlayIcon = Function.getFunction(vTable[TaskBarList_SetOverlayIcon], Function.ALT_CONVENTION);
+ }
+
+ static void setProgress(IdeFrame frame, double value, boolean isOk) {
+ WinDef.HWND handle = getHandle(frame);
+ mySetProgressState.invokeInt(new Object[]{myInterfacePointer, handle, isOk ? TBPF_NORMAL : TBPF_ERROR});
+ mySetProgressValue.invokeInt(new Object[]{myInterfacePointer, handle, new WinDef.ULONGLONG((long)(value * 100)), TOTAL_PROGRESS});
+ }
+
+ static void hideProgress(IdeFrame frame) {
+ mySetProgressState.invokeInt(new Object[]{myInterfacePointer, getHandle(frame), TBPF_NOPROGRESS});
+ }
+
+ static void setOverlayIcon(IdeFrame frame, Object icon, boolean dispose) {
+ if (icon == null) {
+ icon = Pointer.NULL;
+ }
+ mySetOverlayIcon.invokeInt(new Object[]{myInterfacePointer, getHandle(frame), icon, Pointer.NULL});
+ if (dispose) {
+ User32.INSTANCE.DestroyIcon((WinDef.HICON)icon);
+ }
+ }
+
+ static Object createIcon(byte[] ico) {
+ MyMemory memory = new MyMemory(ico.length);
+
+ try {
+ memory.write(0, ico, 0, ico.length);
+
+ int nSize = 100;
+ int offset = User32Ex.INSTANCE.LookupIconIdFromDirectoryEx(memory, true, nSize, nSize, 0);
+ if (offset != 0) {
+ return User32Ex.INSTANCE.CreateIconFromResourceEx(memory.share(offset), DWORD_ZERO, true, ICO_VERSION, nSize, nSize, 0);
+ }
+ return null;
+ }
+ finally {
+ memory.dispose();
+ }
+ }
+
+ static void attention(IdeFrame frame, boolean critical) {
+ User32Ex.INSTANCE.FlashWindow(getHandle(frame), true);
+ }
+
+ static WinDef.HWND getHandle(IdeFrame frame) {
+ try {
+ ComponentPeer peer = ((Component)frame).getPeer();
+ Method getHWnd = peer.getClass().getMethod("getHWnd");
+ return new WinDef.HWND(new Pointer((Long)getHWnd.invoke(peer)));
+ }
+ catch (Throwable e) {
+ LOG.error(e);
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java
index 058cec3dac34..9d99c2b90916 100644
--- a/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java
+++ b/platform/smRunner/src/com/intellij/execution/testframework/sm/runner/ui/SMTestRunnerResultsForm.java
@@ -517,7 +517,7 @@ public class SMTestRunnerResultsForm extends TestResultsPanel
final boolean isIndeterminate = myTestsTotal == 0;
final int total = isIndeterminate ? 2 : myTestsTotal;
final int count = isIndeterminate ? 1 : myTestsCurrentCount;
- TestsUIUtil.showIconProgress(count, total, myTestsFailuresCount);
+ TestsUIUtil.showIconProgress(myProject, count, total, myTestsFailuresCount);
}
/**
diff --git a/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java b/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java
index 2a396ac3a340..09e62ac31809 100644
--- a/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java
+++ b/platform/testRunner/src/com/intellij/execution/testframework/TestsUIUtil.java
@@ -129,30 +129,30 @@ public class TestsUIUtil {
return new TestResultPresentation(proxy).getPresentation().getText();
}
- public static void showIconProgress(int n, final int maximum, final int problemsCounter) {
+ public static void showIconProgress(Project project, int n, final int maximum, final int problemsCounter) {
AppIcon icon = AppIcon.getInstance();
if (n < maximum) {
- if (icon.setProgress(TESTS, AppIconScheme.Progress.TESTS, (double)n / (double)maximum, problemsCounter == 0)) {
+ if (icon.setProgress(project, TESTS, AppIconScheme.Progress.TESTS, (double)n / (double)maximum, problemsCounter == 0)) {
if (problemsCounter > 0) {
- icon.setErrorBadge(String.valueOf(problemsCounter));
+ icon.setErrorBadge(project, String.valueOf(problemsCounter));
}
}
} else {
- if (icon.hideProgress(TESTS)) {
+ if (icon.hideProgress(project, TESTS)) {
if (problemsCounter > 0) {
- icon.setErrorBadge(String.valueOf(problemsCounter));
- icon.requestAttention(true);
+ icon.setErrorBadge(project, String.valueOf(problemsCounter));
+ icon.requestAttention(project, true);
} else {
- icon.setOkBadge(true);
- icon.requestAttention(false);
+ icon.setOkBadge(project, true);
+ icon.requestAttention(project, false);
}
}
}
}
- public static void clearIconProgress() {
- AppIcon.getInstance().hideProgress(TESTS);
- AppIcon.getInstance().setErrorBadge(null);
+ public static void clearIconProgress(Project project) {
+ AppIcon.getInstance().hideProgress(project, TESTS);
+ AppIcon.getInstance().setErrorBadge(project, null);
}
private static class TestResultPresentation {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java
index 831e5a9d700a..107025110ea8 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java
@@ -230,7 +230,7 @@ public abstract class DebuggerSessionTabBase implements DebuggerLogConsoleManage
boolean focusWnd = Registry.is("debugger.mayBringFrameToFrontOnBreakpoint");
ProjectUtil.focusProjectWindow(getProject(), focusWnd);
if (!focusWnd) {
- AppIcon.getInstance().requestAttention(true);
+ AppIcon.getInstance().requestAttention(myProject, true);
}
}
});
diff --git a/plugins/junit/src/com/intellij/execution/junit2/ui/TestProgress.java b/plugins/junit/src/com/intellij/execution/junit2/ui/TestProgress.java
index 86dc1a0250b1..1117c26733ba 100644
--- a/plugins/junit/src/com/intellij/execution/junit2/ui/TestProgress.java
+++ b/plugins/junit/src/com/intellij/execution/junit2/ui/TestProgress.java
@@ -27,6 +27,7 @@ import com.intellij.execution.testframework.Filter;
import com.intellij.execution.testframework.TestsUIUtil;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
import com.intellij.rt.execution.junit.states.PoolOfTestStates;
import org.jetbrains.annotations.NonNls;
@@ -38,6 +39,7 @@ public class TestProgress extends DefaultBoundedRangeModel implements Disposable
private TestProxy myCurrentState = null;
private final MyJUnitListener myListener = new MyJUnitListener();
private int myMissingChildren;
+ private Project myProject;
public static final Filter TEST_CASE = new Filter() {
public boolean shouldAccept(final AbstractTestProxy test) {
return test.shouldRun();
@@ -55,6 +57,7 @@ public class TestProgress extends DefaultBoundedRangeModel implements Disposable
public void setModel(final JUnitRunningModel model) {
myMissingChildren = 0;
+ myProject = model.getProject();
final int knownTestCases = TEST_CASE.select(model.getRoot().getAllTests()).size();
final int declaredTestCases = model.getRoot().getInfo().getTestsCount();
if (declaredTestCases > knownTestCases)
@@ -125,10 +128,10 @@ public class TestProgress extends DefaultBoundedRangeModel implements Disposable
@Override
public void setValue(int n) {
super.setValue(n);
- TestsUIUtil.showIconProgress(n, getMaximum(), myProblemsCounter);
+ TestsUIUtil.showIconProgress(myProject, n, getMaximum(), myProblemsCounter);
}
public void dispose() {
- TestsUIUtil.clearIconProgress();
+ TestsUIUtil.clearIconProgress(myProject);
}
}