Imported Upstream version 2.2.0
[deb_libcec.git] / src / LibCecTray / controller / applications / ApplicationInput.cs
CommitLineData
cbbe90dd
JB
1/*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
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
33using System;
34using System.Collections.Generic;
35using System.Text;
36using System.Windows.Forms;
37using CecSharp;
38using LibCECTray.Properties;
39
40namespace 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}