Commit | Line | Data |
---|---|---|
f017f3c4 LOK |
1 | /* |
2 | * This file is part of the libCEC(R) library. | |
3 | * | |
16f47961 | 4 | * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved. |
f017f3c4 LOK |
5 | * libCEC(R) is an original work, containing original code. |
6 | * | |
7 | * libCEC(R) is a trademark of Pulse-Eight Limited. | |
8 | * | |
9 | * This program is dual-licensed; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License as published by | |
11 | * the Free Software Foundation; either version 2 of the License, or | |
12 | * (at your option) any later version. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, | |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 | * GNU General Public License for more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License | |
20 | * along with this program; if not, write to the Free Software | |
21 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
22 | * | |
23 | * | |
24 | * Alternatively, you can license this library under a commercial license, | |
25 | * please contact Pulse-Eight Licensing for more information. | |
26 | * | |
27 | * For more information contact: | |
28 | * Pulse-Eight Licensing <license@pulse-eight.com> | |
29 | * http://www.pulse-eight.com/ | |
30 | * http://www.pulse-eight.net/ | |
31 | */ | |
32 | ||
33 | using System; | |
34 | using System.Collections.Generic; | |
35 | using System.Text; | |
36 | using System.Windows.Forms; | |
37 | using CecSharp; | |
38 | using LibCECTray.Properties; | |
39 | ||
40 | namespace LibCECTray.controller.applications | |
41 | { | |
42 | /// <summary> | |
43 | /// The type of the action that is executed | |
44 | /// </summary> | |
45 | enum ActionType | |
46 | { | |
47 | Generic = 0, | |
48 | CloseControllerApplication = 1, | |
49 | StartApplication = 2, | |
50 | SendKey = 3 | |
51 | } | |
52 | ||
53 | /// <summary> | |
54 | /// Class that contains one or more actions that can be executed or sent to the application | |
55 | /// </summary> | |
56 | abstract class ApplicationAction | |
57 | { | |
58 | /// <summary> | |
59 | /// Constructor | |
60 | /// </summary> | |
61 | /// <param name="controller">The controller instance of the application that this action is targeting</param> | |
62 | /// <param name="type">The type of the action that is executed</param> | |
63 | protected ApplicationAction(ApplicationController controller, ActionType type) | |
64 | { | |
65 | Controller = controller; | |
66 | ActionType = type; | |
67 | } | |
68 | ||
69 | /// <summary> | |
70 | /// The type of the action that is executed | |
71 | /// </summary> | |
72 | public ActionType ActionType { private set; get; } | |
73 | ||
74 | /// <summary> | |
75 | /// Execute the action | |
76 | /// </summary> | |
77 | /// <param name="windowHandle">The window of the application that is targeted</param> | |
78 | /// <returns>True when executed, false otherwise</returns> | |
79 | public abstract bool Transmit(IntPtr windowHandle); | |
80 | ||
81 | /// <summary> | |
82 | /// Serialisable string representation of this action | |
83 | /// </summary> | |
84 | /// <returns>The requested string</returns> | |
85 | public abstract string AsString(); | |
86 | ||
87 | /// <summary> | |
88 | /// String representation of this action in human readable form | |
89 | /// </summary> | |
90 | /// <returns>The requested string</returns> | |
91 | public abstract string AsFriendlyString(); | |
92 | ||
93 | /// <summary> | |
94 | /// Check whether this action is empty (not doing anything) | |
95 | /// </summary> | |
96 | /// <returns>True when empty, false otherwise</returns> | |
97 | public abstract bool Empty(); | |
98 | ||
99 | /// <summary> | |
100 | /// Checks whether the given action can be appended to this one. | |
101 | /// </summary> | |
102 | /// <param name="value">The action to check</param> | |
103 | /// <returns>True when it can be appended, false otherwise</returns> | |
104 | public abstract bool CanAppend(ApplicationAction value); | |
105 | ||
106 | /// <summary> | |
107 | /// Append the given action to this action, and return the combined result | |
108 | /// </summary> | |
109 | /// <param name="value">The action to append to this one</param> | |
110 | /// <returns>The combined result</returns> | |
111 | public abstract ApplicationAction Append(ApplicationAction value); | |
112 | ||
113 | /// <summary> | |
114 | /// Remove item at the given index from this action | |
115 | /// </summary> | |
116 | /// <param name="index">The index of the item to remove</param> | |
117 | /// <returns>True when removed, false otherwise</returns> | |
118 | public abstract ApplicationAction RemoveKey(int index); | |
119 | ||
120 | /// <summary> | |
121 | /// The prefix to use for serialisation for this type | |
122 | /// </summary> | |
123 | protected string TypePrefix | |
124 | { | |
125 | get { return Enum.GetName(typeof(ActionType), ActionType); } | |
126 | } | |
127 | ||
128 | /// <summary> | |
129 | /// Get the parameter value from a string representation of an action of this type | |
130 | /// </summary> | |
131 | /// <param name="value">The value to get the parameter from</param> | |
132 | /// <returns>The parameter</returns> | |
133 | protected string GetParameterFromString(string value) | |
134 | { | |
135 | var trimmedItem = value.Trim(); | |
136 | if (!trimmedItem.StartsWith(TypePrefix + "(") || !trimmedItem.EndsWith(")")) | |
137 | return string.Empty; | |
138 | ||
139 | return trimmedItem.Substring(TypePrefix.Length + 1, trimmedItem.Length - TypePrefix.Length - 2); | |
140 | } | |
141 | ||
142 | protected readonly ApplicationController Controller; | |
143 | } | |
144 | ||
145 | /// <summary> | |
146 | /// Closes LibCecTray | |
147 | /// </summary> | |
148 | internal class ApplicationActionCloseController : ApplicationAction | |
149 | { | |
150 | public ApplicationActionCloseController(ApplicationController controller) | |
151 | : base(controller, ActionType.CloseControllerApplication) | |
152 | { | |
153 | } | |
154 | ||
155 | public override bool Transmit(IntPtr windowHandle) | |
156 | { | |
157 | Application.Exit(); | |
158 | return true; | |
159 | } | |
160 | ||
161 | public override string AsString() | |
162 | { | |
163 | return TypePrefix; | |
164 | } | |
165 | ||
166 | public override string AsFriendlyString() | |
167 | { | |
168 | return string.Format("[{0}]", Resources.action_type_close_controller_application); | |
169 | } | |
170 | ||
171 | public static bool HasDefaultValue(CecKeypress key) | |
172 | { | |
173 | return DefaultValue(key) != null; | |
174 | } | |
175 | ||
176 | public static ApplicationAction DefaultValue(CecKeypress key) | |
177 | { | |
178 | switch (key.Keycode) | |
179 | { | |
180 | case CecUserControlCode.Power: | |
181 | case CecUserControlCode.PowerOnFunction: | |
182 | case CecUserControlCode.PowerOffFunction: | |
183 | case CecUserControlCode.PowerToggleFunction: | |
184 | return new ApplicationActionCloseController(null); | |
185 | } | |
186 | return null; | |
187 | } | |
188 | ||
189 | public override bool Empty() | |
190 | { | |
191 | return false; | |
192 | } | |
193 | ||
194 | public override bool CanAppend(ApplicationAction value) | |
195 | { | |
196 | return false; | |
197 | } | |
198 | ||
199 | public override ApplicationAction Append(ApplicationAction value) | |
200 | { | |
201 | return this; | |
202 | } | |
203 | ||
204 | public override ApplicationAction RemoveKey(int index) | |
205 | { | |
206 | return null; | |
207 | } | |
208 | ||
209 | public static ApplicationAction FromString(ApplicationController controller, string value) | |
210 | { | |
211 | ApplicationActionCloseController retVal = new ApplicationActionCloseController(controller); | |
212 | return value.Trim().Equals(retVal.AsString()) ? retVal : null; | |
213 | } | |
214 | } | |
215 | ||
216 | /// <summary> | |
217 | /// Starts an application | |
218 | /// </summary> | |
219 | internal class ApplicationActionStart : ApplicationAction | |
220 | { | |
221 | public ApplicationActionStart(ApplicationController controller) : | |
222 | base(controller, ActionType.StartApplication) | |
223 | { | |
224 | } | |
225 | ||
226 | public override bool Transmit(IntPtr windowHandle) | |
227 | { | |
228 | return Controller.Start(false); | |
229 | } | |
230 | ||
231 | public override string AsString() | |
232 | { | |
233 | return TypePrefix; | |
234 | } | |
235 | ||
236 | public override string AsFriendlyString() | |
237 | { | |
238 | return string.Format("[{0}]", Resources.action_type_start_application); | |
239 | } | |
240 | ||
241 | public override bool Empty() | |
242 | { | |
243 | return false; | |
244 | } | |
245 | ||
246 | public override bool CanAppend(ApplicationAction value) | |
247 | { | |
248 | return false; | |
249 | } | |
250 | ||
251 | public override ApplicationAction Append(ApplicationAction value) | |
252 | { | |
253 | return this; | |
254 | } | |
255 | ||
256 | public override ApplicationAction RemoveKey(int index) | |
257 | { | |
258 | return null; | |
259 | } | |
260 | ||
261 | public static ApplicationAction FromString(ApplicationController controller, string value) | |
262 | { | |
263 | ApplicationActionStart retVal = new ApplicationActionStart(controller); | |
264 | return value.Trim().Equals(retVal.AsString()) ? retVal : null; | |
265 | } | |
266 | ||
267 | public static bool HasDefaultValue(CecKeypress key) | |
268 | { | |
269 | return DefaultValue(key) != null; | |
270 | } | |
271 | ||
272 | public static ApplicationAction DefaultValue(CecKeypress key) | |
273 | { | |
274 | return null; | |
275 | } | |
276 | } | |
277 | ||
278 | /// <summary> | |
279 | /// Sends one or more actions to an application | |
280 | /// </summary> | |
281 | internal class ApplicationInput : ApplicationAction | |
282 | { | |
283 | public ApplicationInput(ApplicationController controller) : | |
284 | base(controller, ActionType.Generic) | |
285 | { | |
286 | } | |
287 | ||
288 | public static string FriendlyActionName(ActionType type) | |
289 | { | |
290 | switch (type) | |
291 | { | |
292 | case ActionType.Generic: | |
293 | return Resources.action_type_generic; | |
294 | case ActionType.CloseControllerApplication: | |
295 | return Resources.action_type_close_controller_application; | |
296 | case ActionType.StartApplication: | |
297 | return Resources.action_type_start_application; | |
298 | case ActionType.SendKey: | |
299 | return Resources.action_type_sendkey; | |
300 | default: | |
301 | return type.ToString(); | |
302 | } | |
303 | } | |
304 | ||
305 | public static ApplicationAction DefaultValue(ApplicationController controller, CecKeypress key) | |
306 | { | |
307 | return controller.HasDefaultValue(key) ? controller.DefaultValue(key) : new ApplicationInput(null); | |
308 | } | |
309 | ||
310 | public override bool Empty() | |
311 | { | |
312 | foreach (var item in _input) | |
313 | if (!item.Empty()) | |
314 | return false; | |
315 | return true; | |
316 | } | |
317 | ||
318 | public override bool CanAppend(ApplicationAction value) | |
319 | { | |
320 | return true; | |
321 | } | |
322 | ||
323 | public override ApplicationAction Append(ApplicationAction value) | |
324 | { | |
325 | if (value.Empty()) | |
326 | return this; | |
327 | ||
328 | var added = false; | |
329 | if (_input.Count > 0) | |
330 | { | |
331 | if (_input[_input.Count - 1].CanAppend(value)) | |
332 | { | |
333 | _input[_input.Count - 1].Append(value); | |
334 | added = true; | |
335 | } | |
336 | } | |
337 | if (!added) | |
338 | _input.Add(value); | |
339 | ||
340 | return this; | |
341 | } | |
342 | ||
343 | public override bool Transmit(IntPtr windowHandle) | |
344 | { | |
345 | var retval = true; | |
346 | foreach (var input in _input) | |
347 | { | |
348 | retval &= input.Transmit(windowHandle); | |
349 | } | |
350 | return retval; | |
351 | } | |
352 | ||
353 | public override string AsString() | |
354 | { | |
355 | StringBuilder sb = new StringBuilder(); | |
356 | foreach (var input in _input) | |
357 | { | |
358 | sb.AppendFormat("{0} ", input.AsString()); | |
359 | } | |
360 | return sb.ToString().TrimEnd(); | |
361 | } | |
362 | ||
363 | public override string AsFriendlyString() | |
364 | { | |
365 | StringBuilder sb = new StringBuilder(); | |
366 | foreach (var input in _input) | |
367 | sb.AppendFormat("{0} ", input.AsFriendlyString()); | |
368 | return sb.ToString().Trim(); | |
369 | } | |
370 | ||
371 | public override ApplicationAction RemoveKey(int index) | |
372 | { | |
373 | var ptr = 0; | |
374 | for (var itemPtr = 0; itemPtr < _input.Count; itemPtr++) | |
375 | { | |
376 | var item = _input[itemPtr]; | |
377 | var currentPtr = item.AsFriendlyString().Length; | |
378 | if (index <= ptr + currentPtr) | |
379 | { | |
380 | var newItem = item.RemoveKey(index - ptr); | |
381 | if (newItem == null || newItem.Empty()) | |
382 | _input.Remove(item); | |
383 | else | |
384 | _input[itemPtr] = newItem; | |
385 | break; | |
386 | } | |
387 | ptr += currentPtr; | |
388 | } | |
389 | return this; | |
390 | } | |
391 | ||
392 | public ApplicationInput RemoveItem(int index) | |
393 | { | |
394 | return RemoveKey(index) as ApplicationInput; | |
395 | } | |
396 | ||
397 | public static ApplicationInput FromString(ApplicationController controller, string value) | |
398 | { | |
399 | ApplicationInput retVal = new ApplicationInput(controller); | |
400 | var split = value.Trim().Split(' '); | |
401 | foreach (var item in split) | |
402 | { | |
403 | var addAction = KeyInput.FromString(controller, item); | |
404 | ||
405 | if (addAction == null || addAction.Empty()) | |
406 | addAction = ApplicationActionCloseController.FromString(controller, item); | |
407 | ||
408 | if (addAction == null || addAction.Empty()) | |
409 | addAction = ApplicationActionStart.FromString(controller, item); | |
410 | ||
411 | if (addAction != null && !addAction.Empty()) | |
412 | retVal.Append(addAction); | |
413 | } | |
414 | return retVal; | |
415 | } | |
416 | ||
417 | public ApplicationInput AddKey(WindowsAPI.VirtualKeyCode keyCode) | |
418 | { | |
419 | var key = new KeyInput(Controller, keyCode); | |
420 | if (!key.Empty()) | |
421 | Append(key); | |
422 | return this; | |
423 | } | |
424 | ||
425 | public ApplicationInput AddAction(ActionType action) | |
426 | { | |
427 | switch (action) | |
428 | { | |
429 | case ActionType.CloseControllerApplication: | |
430 | Append(new ApplicationActionCloseController(Controller)); | |
431 | break; | |
432 | case ActionType.StartApplication: | |
433 | Append(new ApplicationActionStart(Controller)); | |
434 | break; | |
435 | } | |
436 | return this; | |
437 | } | |
438 | ||
439 | private readonly List<ApplicationAction> _input = new List<ApplicationAction>(); | |
440 | } | |
441 | } |