# HG changeset patch
# User StephaneLenclud
# Date 1471523750 -7200
# Node ID c92587ddabcdd4da1984d03612b5263ea6fb1121
# Parent 1a1c2ae3a29c7ea86f55eda3527cddfad2ca6069
Support for launch action and WMC HID events.
diff -r 1a1c2ae3a29c -r c92587ddabcd .hgignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgignore Thu Aug 18 14:35:50 2016 +0200
@@ -0,0 +1,5 @@
+obj/*.*
+bin/*.*
+packages/*.*
+.vs/*.*
+ipch/*.*
\ No newline at end of file
diff -r 1a1c2ae3a29c -r c92587ddabcd Server/Actions/ActionHarmonyCommand.cs
--- a/Server/Actions/ActionHarmonyCommand.cs Wed Aug 17 16:39:36 2016 +0200
+++ b/Server/Actions/ActionHarmonyCommand.cs Thu Aug 18 14:35:50 2016 +0200
@@ -36,7 +36,7 @@
///
public override string Brief()
{
- string brief="";
+ string brief="Harmony: ";
if (Program.HarmonyConfig != null)
{
diff -r 1a1c2ae3a29c -r c92587ddabcd Server/Events/EventHidConsumerControl.cs
--- a/Server/Events/EventHidConsumerControl.cs Wed Aug 17 16:39:36 2016 +0200
+++ b/Server/Events/EventHidConsumerControl.cs Thu Aug 18 14:35:50 2016 +0200
@@ -42,10 +42,14 @@
///
public override bool Equals(object obj)
{
- EventHidConsumerControl e = (EventHidConsumerControl) obj;
- bool res = (e != null && e.Usage == Usage);
- return res;
+ if (obj is EventHidConsumerControl)
+ {
+ EventHidConsumerControl e = (EventHidConsumerControl)obj;
+ bool res = (e.Usage == Usage);
+ return res;
+ }
+
+ return false;
}
-
}
}
diff -r 1a1c2ae3a29c -r c92587ddabcd Server/Events/EventHidWindowsMediaCenter.cs
--- a/Server/Events/EventHidWindowsMediaCenter.cs Wed Aug 17 16:39:36 2016 +0200
+++ b/Server/Events/EventHidWindowsMediaCenter.cs Thu Aug 18 14:35:50 2016 +0200
@@ -3,10 +3,54 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Runtime.Serialization;
+using Ear = SharpLib.Ear;
+using Hid = SharpLib.Hid;
-namespace SharpDisplayManager.Events
+namespace SharpDisplayManager
{
- class EventHidWindowsMediaCenter
+ [DataContract]
+ [Ear.AttributeObject(Id = "Event.Hid.WindowsMediaCenter", Name = "HID Windows Media Center", Description = "Corresponding HID message received.")]
+ public class EventHidWindowsMediaCenter : Ear.Event
{
+ public EventHidWindowsMediaCenter()
+ {
+ }
+
+ [DataMember]
+ [Ear.AttributeObjectProperty
+ (
+ Id = "HID.WMC.Usage",
+ Name = "Usage",
+ Description = "The usage corresponding to your remote button."
+ )]
+ public Hid.Usage.WindowsMediaCenterRemoteControl Usage { get; set; }
+
+ ///
+ /// Make sure we distinguish between various configuration of this event
+ ///
+ ///
+ public override string Brief()
+ {
+ return Name + ": " + Usage.ToString();
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public override bool Equals(object obj)
+ {
+ if (obj is EventHidWindowsMediaCenter)
+ {
+ EventHidWindowsMediaCenter e = (EventHidWindowsMediaCenter)obj;
+ bool res = (e.Usage == Usage);
+ return res;
+ }
+
+ return false;
+ }
+
}
}
diff -r 1a1c2ae3a29c -r c92587ddabcd Server/FormEditObject.cs
--- a/Server/FormEditObject.cs Wed Aug 17 16:39:36 2016 +0200
+++ b/Server/FormEditObject.cs Thu Aug 18 14:35:50 2016 +0200
@@ -13,6 +13,7 @@
using System.Reflection;
using Microsoft.VisualBasic.CompilerServices;
using SharpLib.Utils;
+using CodeProject.Dialog;
namespace SharpDisplayManager
{
@@ -146,6 +147,12 @@
TextBox ctrl = (TextBox)aControl;
aInfo.SetValue(aObject, ctrl.Text);
}
+ else if (aInfo.PropertyType == typeof(PropertyFile))
+ {
+ Button ctrl = (Button)aControl;
+ PropertyFile value = new PropertyFile {FullPath=ctrl.Text};
+ aInfo.SetValue(aObject, value);
+ }
//TODO: add support for other types here
}
@@ -218,6 +225,31 @@
ctrl.Text = (string)aInfo.GetValue(aObject);
return ctrl;
}
+ else if (aInfo.PropertyType == typeof(PropertyFile))
+ {
+ // We have a file property
+ // Create a button that will trigger the open file dialog to select our file.
+ Button ctrl = new Button();
+ ctrl.AutoSize = true;
+ ctrl.Text = ((PropertyFile)aInfo.GetValue(aObject)).FullPath;
+ // Add lambda expression to Click event
+ ctrl.Click += (sender, e) =>
+ {
+ // Create open file dialog
+ OpenFileDialog ofd = new OpenFileDialog();
+ ofd.RestoreDirectory = true;
+ // Use file filter specified by our property
+ ofd.Filter = aAttribute.Filter;
+ // Show our dialog
+ if (DlgBox.ShowDialog(ofd) == DialogResult.OK)
+ {
+ // Fetch selected file name
+ ctrl.Text = ofd.FileName;
+ }
+ };
+
+ return ctrl;
+ }
//TODO: add support for other control type here
return null;
@@ -245,6 +277,10 @@
{
return true;
}
+ else if (aInfo.PropertyType == typeof(PropertyFile))
+ {
+ return true;
+ }
//TODO: add support for other type here
return false;
diff -r 1a1c2ae3a29c -r c92587ddabcd Server/FormMain.Hid.cs
--- a/Server/FormMain.Hid.cs Wed Aug 17 16:39:36 2016 +0200
+++ b/Server/FormMain.Hid.cs Thu Aug 18 14:35:50 2016 +0200
@@ -127,6 +127,12 @@
//We are in the proper thread
if (aHidEvent.UsagePage == (ushort) Hid.UsagePage.WindowsMediaCenterRemoteControl)
{
+ //Trigger events as needed
+ EventHidWindowsMediaCenter e = new EventHidWindowsMediaCenter { Usage = (Hid.Usage.WindowsMediaCenterRemoteControl)aHidEvent.Usages[0] };
+ Properties.Settings.Default.EarManager.TriggerEvent(e);
+
+ //Old legacy hard coded stuff
+ //TODO: remove it
switch (aHidEvent.Usages[0])
{
case (ushort)Hid.Usage.WindowsMediaCenterRemoteControl.GreenStart:
@@ -140,16 +146,14 @@
}
else if (aHidEvent.UsagePage == (ushort)Hid.UsagePage.Consumer)
{
+ EventHidConsumerControl e = new EventHidConsumerControl { Usage = (Hid.Usage.ConsumerControl)aHidEvent.Usages[0] };
+ Properties.Settings.Default.EarManager.TriggerEvent(e);
+
//Keep this for debug when only ThinkPad keyboard is available
//if (aHidEvent.Usages[0] == (ushort)Hid.Usage.ConsumerControl.ThinkPadFullscreenMagnifier)
//{
// HandleEject();
//}
-
- EventHidConsumerControl e = new EventHidConsumerControl {Usage = (Hid.Usage.ConsumerControl)aHidEvent.Usages[0]};
- Properties.Settings.Default.EarManager.TriggerEvent(e);
-
-
}
}
diff -r 1a1c2ae3a29c -r c92587ddabcd SharpLibEar/Action.cs
--- a/SharpLibEar/Action.cs Wed Aug 17 16:39:36 2016 +0200
+++ b/SharpLibEar/Action.cs Thu Aug 18 14:35:50 2016 +0200
@@ -9,8 +9,7 @@
namespace SharpLib.Ear
{
[DataContract]
- [KnownType("DerivedTypes")]
- public abstract class Action: IComparable
+ public abstract class Action: Object
{
protected abstract void DoExecute();
@@ -29,28 +28,6 @@
DoExecute();
}
- public string Name {
- //Get the name of this object action attribute
- get { return Utils.Reflection.GetAttribute(GetType()).Name; }
- private set { }
- }
-
- public virtual string Brief()
- {
- return Name;
- }
-
- public int CompareTo(object obj)
- {
- //Sort by action name
- return Utils.Reflection.GetAttribute(GetType()).Name.CompareTo(obj.GetType());
- }
-
- private static IEnumerable DerivedTypes()
- {
- return SharpLib.Utils.Reflection.GetDerivedTypes();
- }
-
}
diff -r 1a1c2ae3a29c -r c92587ddabcd SharpLibEar/ActionLaunchApp.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SharpLibEar/ActionLaunchApp.cs Thu Aug 18 14:35:50 2016 +0200
@@ -0,0 +1,88 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace SharpLib.Ear
+{
+ [DataContract]
+ [AttributeObject(Id = "Action.Launch.App", Name = "Launch application", Description = "Launch an application.")]
+ public class ActionLaunchApp : Action
+ {
+ [DataMember]
+ [AttributeObjectProperty
+ (
+ Id = "Action.Launch.App.File",
+ Name = "File to launch",
+ Description = "Specifies the application file to launch.",
+ Filter = "EXE files (*.exe)|*.exe"
+ )
+ ]
+ public PropertyFile File { get; set; } = new PropertyFile();
+
+ [DataMember]
+ [AttributeObjectProperty
+ (
+ Id = "Action.Launch.App.SwitchTo",
+ Name = "Switch to",
+ Description = "Specifies if we should switch the application if it's already launched."
+ )
+ ]
+ public bool SwitchTo { get; set; } = true;
+
+ [DataMember]
+ [AttributeObjectProperty
+ (
+ Id = "Action.Launch.App.MultipleInstance",
+ Name = "Multiple Instance",
+ Description = "Specifies if We should launch multiple instance."
+ )
+ ]
+ public bool MultipleInstance { get; set; } = false;
+
+ public override string Brief()
+ {
+ return Name + ": " + Path.GetFileName(File.FullPath);
+ }
+
+ [System.Runtime.InteropServices.DllImportAttribute("user32.dll", EntryPoint = "SwitchToThisWindow")]
+ public static extern void SwitchToThisWindow([System.Runtime.InteropServices.InAttribute()] System.IntPtr hwnd, [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.Bool)] bool fUnknown);
+
+
+ protected override void DoExecute()
+ {
+ //First check if the process we want to launch already exists
+ string procName = Path.GetFileNameWithoutExtension(File.FullPath);
+ Process[] existingProcesses = Process.GetProcessesByName(procName);
+ if (existingProcesses == null || existingProcesses.Length == 0 || MultipleInstance)
+ {
+ // Process do not exists just try to launch it
+ ProcessStartInfo start = new ProcessStartInfo();
+ // Enter in the command line arguments, everything you would enter after the executable name itself
+ //start.Arguments = arguments;
+ // Enter the executable to run, including the complete path
+ start.FileName = File.FullPath;
+ start.WindowStyle = ProcessWindowStyle.Normal;
+ start.CreateNoWindow = true;
+ start.UseShellExecute = true;
+ // Run the external process & wait for it to finish
+ Process proc = Process.Start(start);
+
+ //SL: We could have used that too
+ //Shell32.Shell shell = new Shell32.Shell();
+ //shell.ShellExecute(Properties.Settings.Default.StartFileName);
+ }
+ else if (SwitchTo)
+ {
+ //This won't work properly until we have a manifest that enables uiAccess.
+ //However uiAccess just won't work with ClickOnce so we will have to use a different deployment system.
+ SwitchToThisWindow(existingProcesses[0].MainWindowHandle, true);
+ }
+
+ }
+ }
+}
diff -r 1a1c2ae3a29c -r c92587ddabcd SharpLibEar/AttributeObjectProperty.cs
--- a/SharpLibEar/AttributeObjectProperty.cs Wed Aug 17 16:39:36 2016 +0200
+++ b/SharpLibEar/AttributeObjectProperty.cs Thu Aug 18 14:35:50 2016 +0200
@@ -19,6 +19,8 @@
public string Minimum;
public string Maximum;
public string Increment;
+ // For file dialog
+ public string Filter;
}
diff -r 1a1c2ae3a29c -r c92587ddabcd SharpLibEar/Event.cs
--- a/SharpLibEar/Event.cs Wed Aug 17 16:39:36 2016 +0200
+++ b/SharpLibEar/Event.cs Thu Aug 18 14:35:50 2016 +0200
@@ -8,8 +8,7 @@
namespace SharpLib.Ear
{
[DataContract]
- [KnownType("DerivedTypes")]
- public abstract class Event
+ public abstract class Event : Object
{
[DataMember]
[AttributeObjectProperty
@@ -24,24 +23,7 @@
[DataMember]
public List Actions = new List();
- public string Name
- {
- //Get the name of this object attribute
- get { return Utils.Reflection.GetAttribute(GetType()).Name; }
- private set { }
- }
- public string Description
- {
- //Get the description of this object attribute
- get { return Utils.Reflection.GetAttribute(GetType()).Description; }
- private set { }
- }
-
- public virtual string Brief()
- {
- return Name;
- }
protected Event()
{
@@ -68,15 +50,6 @@
}
}
- ///
- /// So that data contract knows all our types.
- ///
- ///
- private static IEnumerable DerivedTypes()
- {
- return SharpLib.Utils.Reflection.GetDerivedTypes();
- }
-
//
public override bool Equals(object obj)
{
diff -r 1a1c2ae3a29c -r c92587ddabcd SharpLibEar/Object.cs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SharpLibEar/Object.cs Thu Aug 18 14:35:50 2016 +0200
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+
+namespace SharpLib.Ear
+{
+
+ ///
+ /// EAR object provides serialization support.
+ /// It assumes most derived class is decorated with AttributeObject.
+ ///
+ [DataContract]
+ [KnownType("DerivedTypes")]
+ public abstract class Object: IComparable
+ {
+
+ public string Name
+ {
+ //Get the name of this object attribute
+ get { return Utils.Reflection.GetAttribute(GetType()).Name; }
+ private set { }
+ }
+
+ public string Description
+ {
+ //Get the description of this object attribute
+ get { return Utils.Reflection.GetAttribute(GetType()).Description; }
+ private set { }
+ }
+
+ public virtual string Brief()
+ {
+ return Name;
+ }
+
+ public int CompareTo(object obj)
+ {
+ //Sort by object name
+ return Utils.Reflection.GetAttribute(GetType()).Name.CompareTo(obj.GetType());
+ }
+
+ ///
+ /// So that data contract knows all our types.
+ ///
+ ///
+ private static IEnumerable DerivedTypes()
+ {
+ return SharpLib.Utils.Reflection.GetDerivedTypes