Added Clear Conflict action to resolver
[pithos-ms-client] / trunk / NotifyIconWpf / Util.cs
1 // hardcodet.net NotifyIcon for WPF
2 // Copyright (c) 2009 Philipp Sumi
3 // Contact and Information: http://www.hardcodet.net
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the Code Project Open License (CPOL);
7 // either version 1.0 of the License, or (at your option) any later
8 // version.
9 // 
10 // The above copyright notice and this permission notice shall be
11 // included in all copies or substantial portions of the Software.
12 // 
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
14 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
15 // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
16 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
17 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
21 //
22 // THIS COPYRIGHT NOTICE MAY NOT BE REMOVED FROM THIS FILE
23
24
25 using System;
26 using System.ComponentModel;
27 using System.Drawing;
28 using System.Windows;
29 using System.Windows.Input;
30 using System.Windows.Media;
31 using System.Windows.Resources;
32 using System.Windows.Threading;
33 using Hardcodet.Wpf.TaskbarNotification.Interop;
34
35 namespace Hardcodet.Wpf.TaskbarNotification
36 {
37   /// <summary>
38   /// Util and extension methods.
39   /// </summary>
40   internal static class Util
41   {
42     public static readonly object SyncRoot = new object();
43
44     #region IsDesignMode
45
46     private static readonly bool isDesignMode;
47
48     /// <summary>
49     /// Checks whether the application is currently in design mode.
50     /// </summary>
51     public static bool IsDesignMode
52     {
53       get { return isDesignMode; }
54     }
55
56     #endregion
57
58     #region construction
59
60     static Util()
61     {
62       isDesignMode =
63           (bool)
64           DependencyPropertyDescriptor.FromProperty(DesignerProperties.IsInDesignModeProperty, typeof (FrameworkElement))
65               .Metadata.DefaultValue;
66     }
67
68     #endregion
69
70     #region CreateHelperWindow
71
72     /// <summary>
73     /// Creates an transparent window without dimension that
74     /// can be used to temporarily obtain focus and/or
75     /// be used as a window message sink.
76     /// </summary>
77     /// <returns>Empty window.</returns>
78     public static Window CreateHelperWindow()
79     {
80       return new Window
81                {
82                    Width = 0,
83                    Height = 0,
84                    ShowInTaskbar = false,
85                    WindowStyle = WindowStyle.None,
86                    AllowsTransparency = true,
87                    Opacity = 0
88                };
89     }
90
91     #endregion
92
93     #region WriteIconData
94
95     /// <summary>
96     /// Updates the taskbar icons with data provided by a given
97     /// <see cref="NotifyIconData"/> instance.
98     /// </summary>
99     /// <param name="data">Configuration settings for the NotifyIcon.</param>
100     /// <param name="command">Operation on the icon (e.g. delete the icon).</param>
101     /// <returns>True if the data was successfully written.</returns>
102     /// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
103     public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command)
104     {
105       return WriteIconData(ref data, command, data.ValidMembers);
106     }
107
108
109     /// <summary>
110     /// Updates the taskbar icons with data provided by a given
111     /// <see cref="NotifyIconData"/> instance.
112     /// </summary>
113     /// <param name="data">Configuration settings for the NotifyIcon.</param>
114     /// <param name="command">Operation on the icon (e.g. delete the icon).</param>
115     /// <param name="flags">Defines which members of the <paramref name="data"/>
116     /// structure are set.</param>
117     /// <returns>True if the data was successfully written.</returns>
118     /// <remarks>See Shell_NotifyIcon documentation on MSDN for details.</remarks>
119     public static bool WriteIconData(ref NotifyIconData data, NotifyCommand command, IconDataMembers flags)
120     {
121       //do nothing if in design mode
122       if (IsDesignMode) return true;
123
124       data.ValidMembers = flags;
125       lock (SyncRoot)
126       {
127         return WinApi.Shell_NotifyIcon(command, ref data);
128       }
129     }
130
131     #endregion
132
133     #region GetBalloonFlag
134
135     /// <summary>
136     /// Gets a <see cref="BalloonFlags"/> enum value that
137     /// matches a given <see cref="BalloonIcon"/>.
138     /// </summary>
139     public static BalloonFlags GetBalloonFlag(this BalloonIcon icon)
140     {
141       switch (icon)
142       {
143         case BalloonIcon.None:
144           return BalloonFlags.None;
145         case BalloonIcon.Info:
146           return BalloonFlags.Info;
147         case BalloonIcon.Warning:
148           return BalloonFlags.Warning;
149         case BalloonIcon.Error:
150           return BalloonFlags.Error;
151         default:
152           throw new ArgumentOutOfRangeException("icon");
153       }
154     }
155
156     #endregion
157
158     #region ImageSource to Icon
159
160     /// <summary>
161     /// Reads a given image resource into a WinForms icon.
162     /// </summary>
163     /// <param name="imageSource">Image source pointing to
164     /// an icon file (*.ico).</param>
165     /// <returns>An icon object that can be used with the
166     /// taskbar area.</returns>
167     public static Icon ToIcon(this ImageSource imageSource)
168     {
169       if (imageSource == null) return null;
170
171       Uri uri = new Uri(imageSource.ToString());
172       StreamResourceInfo streamInfo = Application.GetResourceStream(uri);
173
174       if (streamInfo == null)
175       {
176         string msg = "The supplied image source '{0}' could not be resolved.";
177         msg = String.Format(msg, imageSource);
178         throw new ArgumentException(msg);
179       }
180
181       return new Icon(streamInfo.Stream);
182     }
183
184     #endregion
185
186     #region evaluate listings
187
188     /// <summary>
189     /// Checks a list of candidates for equality to a given
190     /// reference value.
191     /// </summary>
192     /// <typeparam name="T"></typeparam>
193     /// <param name="value">The evaluated value.</param>
194     /// <param name="candidates">A liste of possible values that are
195     /// regarded valid.</param>
196     /// <returns>True if one of the submitted <paramref name="candidates"/>
197     /// matches the evaluated value. If the <paramref name="candidates"/>
198     /// parameter itself is null, too, the method returns false as well,
199     /// which allows to check with null values, too.</returns>
200     /// <exception cref="ArgumentNullException">If <paramref name="candidates"/>
201     /// is a null reference.</exception>
202     public static bool Is<T>(this T value, params T[] candidates)
203     {
204       if (candidates == null) return false;
205
206       foreach (var t in candidates)
207       {
208         if (value.Equals(t)) return true;
209       }
210
211       return false;
212     }
213
214     #endregion
215
216     #region match MouseEvent to PopupActivation
217
218     /// <summary>
219     /// Checks if a given <see cref="PopupActivationMode"/> is a match for
220     /// an effectively pressed mouse button.
221     /// </summary>
222     public static bool IsMatch(this MouseEvent me, PopupActivationMode activationMode)
223     {
224       switch (activationMode)
225       {
226         case PopupActivationMode.LeftClick:
227           return me == MouseEvent.IconLeftMouseUp;
228         case PopupActivationMode.RightClick:
229           return me == MouseEvent.IconRightMouseUp;
230         case PopupActivationMode.LeftOrRightClick:
231           return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconRightMouseUp);
232         case PopupActivationMode.LeftOrDoubleClick:
233           return me.Is(MouseEvent.IconLeftMouseUp, MouseEvent.IconDoubleClick);
234         case PopupActivationMode.DoubleClick:
235           return me.Is(MouseEvent.IconDoubleClick);
236         case PopupActivationMode.MiddleClick:
237           return me == MouseEvent.IconMiddleMouseUp;
238         case PopupActivationMode.All:
239           //return true for everything except mouse movements
240           return me != MouseEvent.MouseMove;
241         default:
242           throw new ArgumentOutOfRangeException("activationMode");
243       }
244     }
245
246     #endregion
247
248     #region execute command
249
250     /// <summary>
251     /// Executes a given command if its <see cref="ICommand.CanExecute"/> method
252     /// indicates it can run.
253     /// </summary>
254     /// <param name="command">The command to be executed, or a null reference.</param>
255     /// <param name="commandParameter">An optional parameter that is associated with
256     /// the command.</param>
257     /// <param name="target">The target element on which to raise the command.</param>
258     public static void ExecuteIfEnabled(this ICommand command, object commandParameter, IInputElement target)
259     {
260       if (command == null) return;
261
262       RoutedCommand rc = command as RoutedCommand;
263       if (rc != null)
264       {
265         //routed commands work on a target
266         if (rc.CanExecute(commandParameter, target)) rc.Execute(commandParameter, target);
267       }
268       else if (command.CanExecute(commandParameter))
269       {
270         command.Execute(commandParameter);
271       }
272     }
273
274     #endregion
275
276     /// <summary>
277     /// Returns a dispatcher for multi-threaded scenarios
278     /// </summary>
279     /// <returns></returns>
280     internal static Dispatcher GetDispatcher(this DispatcherObject source)
281     {
282       //use the application's dispatcher by default
283       if (Application.Current != null) return Application.Current.Dispatcher;
284
285       //fallback for WinForms environments
286       if (source.Dispatcher != null) return source.Dispatcher;
287
288       //ultimatively use the thread's dispatcher
289       return Dispatcher.CurrentDispatcher;
290     }
291
292
293     /// <summary>
294     /// Checks whether the <see cref="FrameworkElement.DataContextProperty"/>
295     ///  is bound or not.
296     /// </summary>
297     /// <param name="element">The element to be checked.</param>
298     /// <returns>True if the data context property is being managed by a
299     /// binding expression.</returns>
300     /// <exception cref="ArgumentNullException">If <paramref name="element"/>
301     /// is a null reference.</exception>
302     public static bool IsDataContextDataBound(this FrameworkElement element)
303     {
304       if (element == null) throw new ArgumentNullException("element");
305       return element.GetBindingExpression(FrameworkElement.DataContextProperty) != null;
306     }
307   }
308 }