[longomatch] Start with hotkeys handling



commit 105df8212a732cfb3d28039855c59fcfda172547
Author: Andoni Morales Alastruey <ylatuya gmail com>
Date:   Thu Oct 23 14:35:08 2014 +0200

    Start with hotkeys handling

 LongoMatch.Core/Common/Enums.cs                    |   30 +++++-
 LongoMatch.Core/Common/EventsBroker.cs             |    4 +-
 LongoMatch.Core/Common/ExtensionMethods.cs         |    5 +
 LongoMatch.Core/Common/Hotkeys.cs                  |  113 +++++++++++++++++++
 LongoMatch.Core/Common/Keyboard.cs                 |   74 ++++++++++++
 LongoMatch.Core/Config.cs                          |   16 +++
 LongoMatch.Core/Handlers/Handlers.cs               |    2 +-
 LongoMatch.Core/Interfaces/GUI/IAnalysisWindow.cs  |    6 +
 LongoMatch.Core/Interfaces/GUI/IPlayerBin.cs       |    1 +
 LongoMatch.Core/LongoMatch.Core.csproj             |    2 +
 LongoMatch.Core/Makefile.am                        |    2 +
 LongoMatch.Core/Store/HotKey.cs                    |   66 ++++--------
 LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs         |    5 +
 LongoMatch.GUI.Multimedia/Gui/PlayerCapturerBin.cs |    6 +
 .../gtk-gui/LongoMatch.Gui.PlayerBin.cs            |    1 -
 LongoMatch.GUI.Multimedia/gtk-gui/gui.stetic       |    1 -
 LongoMatch.GUI/Gui/Component/AnalysisComponent.cs  |   30 +++++-
 LongoMatch.GUI/Gui/Component/CodingWidget.cs       |   23 ++++-
 LongoMatch.GUI/Gui/Component/Timeline.cs           |   12 ++
 LongoMatch.GUI/Gui/MainWindow.cs                   |   10 +--
 LongoMatch.GUI/LongoMatch.GUI.csproj               |    2 -
 LongoMatch.GUI/Makefile.am                         |    2 -
 .../gtk-gui/LongoMatch.Gui.Component.Timeline.cs   |    1 +
 .../LongoMatch.Gui.Dialog.ShortcutsHelpDialog.cs   |   89 ---------------
 .../gtk-gui/LongoMatch.Gui.MainWindow.cs           |    7 +-
 LongoMatch.GUI/gtk-gui/gui.stetic                  |  118 +-------------------
 LongoMatch.Services/Services/EventsManager.cs      |   28 +++++
 LongoMatch.Services/Services/HotKeysManager.cs     |   46 ++++++--
 LongoMatch.Services/Services/PlaylistManager.cs    |   75 +++++++++++++
 LongoMatch.Services/Services/ProjectsManager.cs    |   42 -------
 30 files changed, 486 insertions(+), 333 deletions(-)
---
diff --git a/LongoMatch.Core/Common/Enums.cs b/LongoMatch.Core/Common/Enums.cs
index 8b17530..faa060f 100644
--- a/LongoMatch.Core/Common/Enums.cs
+++ b/LongoMatch.Core/Common/Enums.cs
@@ -281,5 +281,33 @@ namespace LongoMatch.Core.Common
                Angle3,
                Angle4,
        }
+       
+       public enum KeyAction {
+               None,
+               TogglePlay,
+               FrameUp,
+               FrameDown,
+               SpeedUp,
+               SpeedDown,
+               JumpUp,
+               JumpDown,
+               Prev,
+               Next,
+               CloseEvent,
+               DrawFrame,
+               EditEvent,
+               DeleteEvent,
+               StartPeriod,
+               StopPeriod,
+               PauseClock,
+               LocalPlayer,
+               VisitorPlayer,
+               Substitution,
+               ShowDashboard,
+               ShowTimeline,
+               ShowPositions,
+               ZoomIn,
+               ZoomOut,
+               FitTimeline,
+       }
 }
-
diff --git a/LongoMatch.Core/Common/EventsBroker.cs b/LongoMatch.Core/Common/EventsBroker.cs
index 412a33f..bfb0184 100644
--- a/LongoMatch.Core/Common/EventsBroker.cs
+++ b/LongoMatch.Core/Common/EventsBroker.cs
@@ -176,9 +176,9 @@ namespace LongoMatch.Core.Common
                                DuplicateEventsEvent (events);
                }
                
-               public void EmitKeyPressed(object sender, int key, int modifier) {
+               public void EmitKeyPressed(object sender, HotKey key) {
                        if (KeyPressed != null)
-                               KeyPressed(sender, key, modifier);
+                               KeyPressed(sender, key);
                }
                
                public bool EmitCloseOpenedProject () {
diff --git a/LongoMatch.Core/Common/ExtensionMethods.cs b/LongoMatch.Core/Common/ExtensionMethods.cs
index 45a4627..d13f56d 100644
--- a/LongoMatch.Core/Common/ExtensionMethods.cs
+++ b/LongoMatch.Core/Common/ExtensionMethods.cs
@@ -42,5 +42,10 @@ namespace LongoMatch.Core.Common
                        }
                        return res.ToArray ();
                }
+               
+               public static TKey GetKeyByValue<TKey, TValue>(this Dictionary<TKey, TValue> dict, TValue 
value)
+               {
+                       return dict.SingleOrDefault(x => x.Value.Equals(value)).Key;
+               }
        }
 }
diff --git a/LongoMatch.Core/Common/Hotkeys.cs b/LongoMatch.Core/Common/Hotkeys.cs
new file mode 100644
index 0000000..8b06f29
--- /dev/null
+++ b/LongoMatch.Core/Common/Hotkeys.cs
@@ -0,0 +1,113 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using System.Collections.Generic;
+using LongoMatch.Core.Store;
+using Mono.Unix;
+using Newtonsoft.Json;
+
+namespace LongoMatch.Core.Common
+{
+       
+       public class Hotkeys
+       {
+       
+               public Hotkeys ()
+               {
+                       ActionsDescriptions = new Dictionary<KeyAction, string> ();
+                       ActionsHotkeys = new Dictionary<KeyAction, HotKey> ();
+                       FillDefaults ();
+               }
+
+               [JsonIgnore]
+               public Dictionary<KeyAction, string> ActionsDescriptions {
+                       get;
+                       set;
+               }
+
+               public Dictionary<KeyAction, HotKey> ActionsHotkeys {
+                       get;
+                       set;
+               }
+               
+               void UpdateMapping (KeyAction action, string name)
+               {
+                       HotKey key = Keyboard.ParseName (name);
+                       ActionsHotkeys [action] = key;
+               }
+
+               void FillDefaults() {
+                       ActionsDescriptions [KeyAction.DeleteEvent] = Catalog.GetString ("Delete selected 
event");
+                       ActionsDescriptions [KeyAction.DrawFrame] = Catalog.GetString ("Draw frame");
+                       ActionsDescriptions [KeyAction.EditEvent] = Catalog.GetString ("Edit selected event");
+                       ActionsDescriptions [KeyAction.FitTimeline] = Catalog.GetString ("Adjust timeline to 
current position");
+                       ActionsDescriptions [KeyAction.FrameDown] = Catalog.GetString ("Frame step backward");
+                       ActionsDescriptions [KeyAction.FrameUp] = Catalog.GetString ("Frame step forward");
+                       ActionsDescriptions [KeyAction.JumpDown] = Catalog.GetString ("Jump backward");
+                       ActionsDescriptions [KeyAction.JumpUp] = Catalog.GetString ("Jump forward");
+                       ActionsDescriptions [KeyAction.CloseEvent] = Catalog.GetString ("Close loaded event");
+                       ActionsDescriptions [KeyAction.LocalPlayer] = Catalog.GetString ("Start tagging home 
player");
+                       ActionsDescriptions [KeyAction.VisitorPlayer] = Catalog.GetString ("Start tagging 
away player");
+                       ActionsDescriptions [KeyAction.Next] = Catalog.GetString ("Jump to next event");
+                       ActionsDescriptions [KeyAction.Prev] = Catalog.GetString ("Jump to prev event");
+                       ActionsDescriptions [KeyAction.PauseClock] = Catalog.GetString ("Pause clock");
+                       ActionsDescriptions [KeyAction.ShowDashboard] = Catalog.GetString ("Show dashboard");
+                       ActionsDescriptions [KeyAction.ShowPositions] = Catalog.GetString ("Show zonal tags");
+                       ActionsDescriptions [KeyAction.ShowTimeline] = Catalog.GetString ("Show timeline");
+                       ActionsDescriptions [KeyAction.LocalPlayer] = Catalog.GetString ("Start tagging home 
player");
+                       ActionsDescriptions [KeyAction.VisitorPlayer] = Catalog.GetString ("Start tagging 
away player");
+                       ActionsDescriptions [KeyAction.SpeedDown] = Catalog.GetString ("Increase playback 
speed");
+                       ActionsDescriptions [KeyAction.SpeedUp] = Catalog.GetString ("Decrease playback 
speed");
+                       ActionsDescriptions [KeyAction.StartPeriod] = Catalog.GetString ("Start recording 
period");
+                       ActionsDescriptions [KeyAction.StopPeriod] = Catalog.GetString ("Stop recording 
period");
+                       ActionsDescriptions [KeyAction.Substitution] = Catalog.GetString ("Toggle 
substitutions mode");
+                       ActionsDescriptions [KeyAction.TogglePlay] = Catalog.GetString ("Toggle playback");
+                       ActionsDescriptions [KeyAction.ZoomIn] = Catalog.GetString ("Zoom timeline in");
+                       ActionsDescriptions [KeyAction.ZoomOut] = Catalog.GetString ("Zoom timeline out");
+                       
+                       UpdateMapping (KeyAction.DeleteEvent, "<Shift_L>+d");
+                       UpdateMapping (KeyAction.DrawFrame, "f");
+                       UpdateMapping (KeyAction.EditEvent, "e");
+                       UpdateMapping (KeyAction.FitTimeline, "t");
+                       UpdateMapping (KeyAction.FrameDown, "Left");
+                       UpdateMapping (KeyAction.FrameUp, "Right");
+                       UpdateMapping (KeyAction.JumpUp, "<Shift_L>+Right");
+                       UpdateMapping (KeyAction.JumpDown, "<Shift_L>+Left");
+                       UpdateMapping (KeyAction.CloseEvent, "a");
+                       UpdateMapping (KeyAction.LocalPlayer, "q");
+                       UpdateMapping (KeyAction.VisitorPlayer, "w");
+                       UpdateMapping (KeyAction.LocalPlayer, "n");
+                       UpdateMapping (KeyAction.VisitorPlayer, "b");
+                       UpdateMapping (KeyAction.PauseClock, "p");
+                       UpdateMapping (KeyAction.ShowTimeline, "z");
+                       UpdateMapping (KeyAction.ShowDashboard, "x");
+                       UpdateMapping (KeyAction.ShowPositions, "c");
+                       UpdateMapping (KeyAction.SpeedDown, "Down");
+                       UpdateMapping (KeyAction.SpeedUp, "Up");
+                       UpdateMapping (KeyAction.StartPeriod, "<Shift_L>+i");
+                       UpdateMapping (KeyAction.StopPeriod, "<Shitft_L>+o");
+                       UpdateMapping (KeyAction.Substitution, "s");
+                       UpdateMapping (KeyAction.TogglePlay, "space");
+                       UpdateMapping (KeyAction.ZoomIn, "plus");
+                       UpdateMapping (KeyAction.ZoomOut, "minus");
+                       UpdateMapping (KeyAction.Next, "plus");
+                       UpdateMapping (KeyAction.Prev, "minus");
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Common/Keyboard.cs b/LongoMatch.Core/Common/Keyboard.cs
new file mode 100644
index 0000000..931a201
--- /dev/null
+++ b/LongoMatch.Core/Common/Keyboard.cs
@@ -0,0 +1,74 @@
+//
+//  Copyright (C) 2014 Andoni Morales Alastruey
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 2 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+using System;
+using LongoMatch.Core.Store;
+
+namespace LongoMatch.Core.Common
+{
+       public class Keyboard
+       {
+               public static uint KeyvalFromName (string name)
+               {
+                       return Gdk.Keyval.FromName (name);
+               }
+
+               public static string NameFromKeyval (uint keyval)
+               {
+                       return Gdk.Keyval.Name (keyval);
+               }
+
+               public static HotKey ParseEvent (Gdk.EventKey evt)
+               {
+                       int modifier = -1;
+
+                       if (evt.State == Gdk.ModifierType.ShiftMask) {
+                               modifier = (int)KeyvalFromName ("Shift_L");
+                       } else if (evt.State == Gdk.ModifierType.Mod1Mask || evt.State == 
Gdk.ModifierType.Mod5Mask) {
+                               modifier = (int)KeyvalFromName ("Alt_L");
+                       } else if (evt.State == Gdk.ModifierType.ControlMask) {
+                               modifier = (int)KeyvalFromName ("Control_L");
+                       }
+                       return new HotKey { Key = (int) evt.KeyValue, Modifier = modifier };
+               }
+
+               public static HotKey ParseName (string name)
+               {
+                       int key = -1, modifier = -1, i;
+                       
+                       if (name.Contains (">+")) {
+                               i = name.IndexOf ('+');
+                               modifier = (int)KeyvalFromName (name.Substring (1, i - 2));
+                               key = (int)KeyvalFromName (name.Substring (i + 1)); 
+                       } else {
+                               key = (int)KeyvalFromName (name);
+                       }
+                       return new HotKey { Key = key, Modifier = modifier };
+               }
+
+               public static string HotKeyName (HotKey hotkey)
+               {
+                       if (hotkey.Modifier != -1) {
+                               return string.Format ("<{0}>+{1}", NameFromKeyval ((uint)hotkey.Modifier),
+                                                     NameFromKeyval ((uint)hotkey.Key));
+                       } else {
+                               return string.Format ("{0}", NameFromKeyval ((uint)hotkey.Key));
+                       }
+               }
+       }
+}
+
diff --git a/LongoMatch.Core/Config.cs b/LongoMatch.Core/Config.cs
index 680e6c5..0a905c6 100644
--- a/LongoMatch.Core/Config.cs
+++ b/LongoMatch.Core/Config.cs
@@ -23,6 +23,9 @@ using LongoMatch.Core.Interfaces;
 using LongoMatch.Core.Interfaces.GUI;
 using LongoMatch.Core.Interfaces.Multimedia;
 using LongoMatch.Core.Interfaces.Drawing;
+using LongoMatch.Core.Store;
+using System.Collections.Generic;
+using Newtonsoft.Json;
 
 namespace LongoMatch
 {
@@ -402,11 +405,22 @@ namespace LongoMatch
                                Save ();
                        }
                }
+               
+               public static Hotkeys Hotkeys {
+                       get {
+                               return state.hotkeys;
+                       }
+                       set {
+                               state.hotkeys = value;
+                               Save ();
+                       }
+               }
                #endregion
 
        }
        
        [Serializable]
+       //[JsonConverter (typeof (LongoMatchConverter))]
        public class ConfigState{
                public bool fastTagging;
                public bool autoSave;
@@ -427,6 +441,7 @@ namespace LongoMatch
                public string lastRenderDir;
                public bool reviewPlaysInSameWindow;
                public string defaultTemplate;
+               public Hotkeys hotkeys;
                
                public ConfigState () {
                        /* Set default values */
@@ -449,6 +464,7 @@ namespace LongoMatch
                        lastRenderDir = null;
                        reviewPlaysInSameWindow = true;
                        defaultTemplate = null;
+                       hotkeys = new Hotkeys ();
                }
        }
 }
diff --git a/LongoMatch.Core/Handlers/Handlers.cs b/LongoMatch.Core/Handlers/Handlers.cs
index d313306..11074ae 100644
--- a/LongoMatch.Core/Handlers/Handlers.cs
+++ b/LongoMatch.Core/Handlers/Handlers.cs
@@ -116,7 +116,7 @@ namespace LongoMatch.Core.Handlers
        /* A list of projects have been selected */
        public delegate void ProjectsSelectedHandler (List<ProjectDescription> projects);
        public delegate void ProjectSelectedHandler (ProjectDescription project);
-       public delegate void KeyHandler (object sender,int key,int modifier);
+       public delegate void KeyHandler (object sender, HotKey key);
        /* The plays filter was updated */
        public delegate void FilterUpdatedHandler ();
        public delegate void DetachPlayerHandler ();
diff --git a/LongoMatch.Core/Interfaces/GUI/IAnalysisWindow.cs 
b/LongoMatch.Core/Interfaces/GUI/IAnalysisWindow.cs
index 82441cb..bbf2c70 100644
--- a/LongoMatch.Core/Interfaces/GUI/IAnalysisWindow.cs
+++ b/LongoMatch.Core/Interfaces/GUI/IAnalysisWindow.cs
@@ -34,6 +34,12 @@ namespace LongoMatch.Core.Interfaces.GUI
                void UpdateCategories ();
                void DeletePlays (List<TimelineEvent> plays);
                void DetachPlayer ();
+               void ZoomIn ();
+               void ZoomOut ();
+               void FitTimeline ();
+               void ShowDashboard ();
+               void ShowTimeline ();
+               void ShowZonalTags ();
                
                IPlayerBin Player{get;}
                ICapturerBin Capturer{get;}
diff --git a/LongoMatch.Core/Interfaces/GUI/IPlayerBin.cs b/LongoMatch.Core/Interfaces/GUI/IPlayerBin.cs
index faba7fc..0e0fe34 100644
--- a/LongoMatch.Core/Interfaces/GUI/IPlayerBin.cs
+++ b/LongoMatch.Core/Interfaces/GUI/IPlayerBin.cs
@@ -36,6 +36,7 @@ namespace LongoMatch.Core.Interfaces.GUI
                bool SeekingEnabled {set;}
                bool Sensitive {set; get;}
                bool Playing { get; }
+               MediaFileAngle ActiveAngle { get; }
 
                void Open (MediaFileSet fileSet);
                void Close();
diff --git a/LongoMatch.Core/LongoMatch.Core.csproj b/LongoMatch.Core/LongoMatch.Core.csproj
index 0476430..34650da 100644
--- a/LongoMatch.Core/LongoMatch.Core.csproj
+++ b/LongoMatch.Core/LongoMatch.Core.csproj
@@ -129,6 +129,8 @@
     <Compile Include="Stats\EventTypeStats.cs" />
     <Compile Include="Store\Drawables\Circle.cs" />
     <Compile Include="Store\MediaFileSet.cs" />
+    <Compile Include="Common\Hotkeys.cs" />
+    <Compile Include="Common\Keyboard.cs" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="Common\" />
diff --git a/LongoMatch.Core/Makefile.am b/LongoMatch.Core/Makefile.am
index 6567b9c..a7dad10 100644
--- a/LongoMatch.Core/Makefile.am
+++ b/LongoMatch.Core/Makefile.am
@@ -19,8 +19,10 @@ SOURCES = Common/Area.cs \
        Common/Exceptions.cs \
        Common/ExtensionMethods.cs \
        Common/Gettext.cs \
+       Common/Hotkeys.cs \
        Common/Image.cs \
        Common/Job.cs \
+       Common/Keyboard.cs \
        Common/Log.cs \
        Common/Serializer.cs \
        Common/SysInfo.cs \
diff --git a/LongoMatch.Core/Store/HotKey.cs b/LongoMatch.Core/Store/HotKey.cs
index 9dbe918..5272f7b 100644
--- a/LongoMatch.Core/Store/HotKey.cs
+++ b/LongoMatch.Core/Store/HotKey.cs
@@ -17,24 +17,13 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 //
-//
-
-
 using System;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
 using Mono.Unix;
 using Newtonsoft.Json;
 using LongoMatch.Core.Common;
 
-
-#if HAVE_GTK
-using Gdk;
-#endif
-
 namespace LongoMatch.Core.Store
 {
-
        /// <summary>
        /// A key combination used to tag plays using the keyboard. <see 
cref="LongoMatch.Store.SectionsTimeNodes"/>
        /// It can only be used with the Shith and Alt modifiers to avoid interfering with ohter shortcuts.
@@ -48,13 +37,12 @@ namespace LongoMatch.Core.Store
                /// <summary>
                /// Creates a new undefined HotKey
                /// </summary>
-               public HotKey()
+               public HotKey ()
                {
                        Key = -1;
                        Modifier = -1;
                }
                #endregion
-
                #region Properties
                /// <summary>
                /// Gdk Key
@@ -78,72 +66,60 @@ namespace LongoMatch.Core.Store
                [JsonIgnore]
                public Boolean Defined {
                        get {
-                               return (Key!=-1 && Modifier != -1);
+                               return (Key != -1 && Modifier != -1);
                        }
                }
                #endregion
-
                #region Public Methods
-               public bool Equals (HotKey hotkeyComp) {
+               public bool Equals (HotKey hotkeyComp)
+               {
                        if (hotkeyComp == null)
                                return false;
                        return (this.Key == hotkeyComp.Key && this.Modifier == hotkeyComp.Modifier);
                }
                #endregion
-
                #region Operators
-               static public bool operator == (HotKey a, HotKey b) {
+               static public bool operator == (HotKey a, HotKey b)
+               {
                        // If both are null, or both are same instance, return true.
-                       if (System.Object.ReferenceEquals(a, b))
-                       {
+                       if (System.Object.ReferenceEquals (a, b)) {
                                return true;
                        }
 
                        // If one is null, but not both, return false.
-                       if (((object)a == null) || ((object)b == null))
-                       {
+                       if (((object)a == null) || ((object)b == null)) {
                                return false;
                        }
-                       return a.Equals(b);
+                       return a.Equals (b);
                }
 
-               static public bool operator != (HotKey a, HotKey b) {
+               static public bool operator != (HotKey a, HotKey b)
+               {
                        return !(a == b);
                }
                #endregion
-
                #region Overrides
-               public override bool Equals(object obj)
+               public override bool Equals (object obj)
                {
-                       if(obj is HotKey) {
-                               HotKey hotkey= obj as HotKey;
-                               return Equals(hotkey);
-                       }
-                       else
+                       if (obj is HotKey) {
+                               HotKey hotkey = obj as HotKey;
+                               return Equals (hotkey);
+                       } else
                                return false;
                }
 
-               public override int GetHashCode()
+               public override int GetHashCode ()
                {
                        return Key ^ Modifier;
                }
 
-               public override string ToString()
+               public override string ToString ()
                {
                        string modifierS = "";
                                
-                       if(!Defined)
-                               return Catalog.GetString("Not defined");
-
-#if HAVE_GTK
-                       if(Modifier == (int)ModifierType.Mod1Mask)
-                               modifierS = "<Alt>+";
-                       else if(Modifier == (int)ModifierType.ShiftMask)
-                               modifierS = "<Shift>+";
-                       return string.Format("{0}{1}", modifierS,((Gdk.Key)Key).ToString().ToLower());
-#else
-                       return string.Format("{0}{1}", modifierS,(Key.ToString()).ToLower());
-#endif
+                       if (!Defined)
+                               return Catalog.GetString ("Not defined");
+                       return Keyboard.HotKeyName (this);
                }
                #endregion
        }
diff --git a/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs b/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs
index ad81c0b..2dcd38a 100644
--- a/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs
+++ b/LongoMatch.GUI.Multimedia/Gui/PlayerBin.cs
@@ -131,6 +131,11 @@ namespace LongoMatch.Gui
                        }
                }
 
+               public MediaFileAngle ActiveAngle {
+                       get {
+                               return angle;
+                       }
+               }
                public bool SeekingEnabled {
                        set {
                                timescale.Sensitive = value;
diff --git a/LongoMatch.GUI.Multimedia/Gui/PlayerCapturerBin.cs 
b/LongoMatch.GUI.Multimedia/Gui/PlayerCapturerBin.cs
index 8cf370c..ccf6789 100644
--- a/LongoMatch.GUI.Multimedia/Gui/PlayerCapturerBin.cs
+++ b/LongoMatch.GUI.Multimedia/Gui/PlayerCapturerBin.cs
@@ -167,6 +167,12 @@ namespace LongoMatch.Gui
                        }
                }
                
+               public MediaFileAngle ActiveAngle {
+                       get {
+                               return playerbin.ActiveAngle;
+                       }
+               }
+               
                public bool SeekingEnabled {
                        set {
                                playerbin.SeekingEnabled = value;
diff --git a/LongoMatch.GUI.Multimedia/gtk-gui/LongoMatch.Gui.PlayerBin.cs 
b/LongoMatch.GUI.Multimedia/gtk-gui/LongoMatch.Gui.PlayerBin.cs
index 44b1e4c..05c8d42 100644
--- a/LongoMatch.GUI.Multimedia/gtk-gui/LongoMatch.Gui.PlayerBin.cs
+++ b/LongoMatch.GUI.Multimedia/gtk-gui/LongoMatch.Gui.PlayerBin.cs
@@ -266,7 +266,6 @@ namespace LongoMatch.Gui
                        this.timescale.Adjustment.Upper = 1;
                        this.timescale.Adjustment.PageIncrement = 1;
                        this.timescale.Adjustment.StepIncrement = 1;
-                       this.timescale.Adjustment.Value = 1;
                        this.timescale.DrawValue = false;
                        this.timescale.Digits = 0;
                        this.timescale.ValuePos = ((global::Gtk.PositionType)(2));
diff --git a/LongoMatch.GUI.Multimedia/gtk-gui/gui.stetic b/LongoMatch.GUI.Multimedia/gtk-gui/gui.stetic
index 11747f1..da02b2c 100644
--- a/LongoMatch.GUI.Multimedia/gtk-gui/gui.stetic
+++ b/LongoMatch.GUI.Multimedia/gtk-gui/gui.stetic
@@ -368,7 +368,6 @@
                     <property name="Upper">1</property>
                     <property name="PageIncrement">1</property>
                     <property name="StepIncrement">1</property>
-                    <property name="Value">1</property>
                     <property name="DrawValue">False</property>
                     <property name="Digits">0</property>
                     <property name="ValuePos">Top</property>
diff --git a/LongoMatch.GUI/Gui/Component/AnalysisComponent.cs 
b/LongoMatch.GUI/Gui/Component/AnalysisComponent.cs
index 939ed0b..2a7d889 100644
--- a/LongoMatch.GUI/Gui/Component/AnalysisComponent.cs
+++ b/LongoMatch.GUI/Gui/Component/AnalysisComponent.cs
@@ -76,6 +76,30 @@ namespace LongoMatch.Gui.Component
                        codingwidget.DeletePlays (plays);
                }
                
+               public void ZoomIn () {
+                       codingwidget.ZoomIn ();
+               }
+               
+               public void ZoomOut () {
+                       codingwidget.ZoomOut ();
+               }
+               
+               public void FitTimeline () {
+                       codingwidget.FitTimeline ();
+               }
+               
+               public void ShowDashboard () {
+                       codingwidget.ShowDashboard ();
+               }
+
+               public void ShowTimeline () {
+                       codingwidget.ShowTimeline ();
+               }
+               
+               public void ShowZonalTags () {
+                       codingwidget.ShowZonalTags ();
+               }
+
                public void DetachPlayer ()
                {
                        bool isPlaying = playercapturer.Playing;
@@ -92,9 +116,9 @@ namespace LongoMatch.Gui.Component
                                playerWindow.DeleteEvent += (o, args) => DetachPlayer ();
                                box = new EventBox ();
                                box.Name = "lightbackgroundeventbox";
-                               box.KeyPressEvent += (o, args) => Config.EventsBroker.EmitKeyPressed (this,
-                                                                                                     (int) 
args.Event.Key,
-                                                                                                     (int) 
args.Event.State);
+                               box.KeyPressEvent += (o, args) => {
+                                       Config.EventsBroker.EmitKeyPressed(this, Keyboard.ParseEvent 
(args.Event));
+                               };
                                playerWindow.Add (box);
                                
                                box.Show ();
diff --git a/LongoMatch.GUI/Gui/Component/CodingWidget.cs b/LongoMatch.GUI/Gui/Component/CodingWidget.cs
index b6705ef..4157125 100644
--- a/LongoMatch.GUI/Gui/Component/CodingWidget.cs
+++ b/LongoMatch.GUI/Gui/Component/CodingWidget.cs
@@ -109,6 +109,27 @@ namespace LongoMatch.Gui.Component
                        base.OnDestroyed ();
                }
 
+               public void ZoomIn () {
+                       timeline.ZoomIn ();
+               }
+               
+               public void ZoomOut () {
+                       timeline.ZoomOut ();
+               }
+               
+               public void FitTimeline () {
+                       timeline.Fit ();
+               }
+               
+               public void ShowDashboard () {
+               }
+
+               public void ShowTimeline () {
+               }
+               
+               public void ShowZonalTags () {
+               }
+
                public void SetProject (Project project, ProjectType projectType, EventsFilter filter)
                {
                        this.projectType = projectType;
@@ -205,7 +226,7 @@ namespace LongoMatch.Gui.Component
                        notebook.ShowTabs = false;
                        //notebook.Group = source.Group;
                        window.Add (notebook);
-                       window.SetDefaultSize (300, 300);
+                       window.SetDefaultSize (page.Allocation.Width, page.Allocation.Height);
                        window.Move (x, y);
                        window.ShowAll ();
                        activeWindows.Add (window);
diff --git a/LongoMatch.GUI/Gui/Component/Timeline.cs b/LongoMatch.GUI/Gui/Component/Timeline.cs
index 50c8c9b..a3c7619 100644
--- a/LongoMatch.GUI/Gui/Component/Timeline.cs
+++ b/LongoMatch.GUI/Gui/Component/Timeline.cs
@@ -101,6 +101,18 @@ namespace LongoMatch.Gui.Component
                        }
                }
 
+               public void Fit () {
+                       focusbutton.Click ();
+               }
+
+               public void ZoomIn () {
+                       focusscale.Adjustment.Value -= focusscale.Adjustment.StepIncrement;
+               }
+               
+               public void ZoomOut () {
+                       focusscale.Adjustment.Value += focusscale.Adjustment.StepIncrement;
+               }
+
                public void SetProject (Project project, EventsFilter filter)
                {
                        this.project = project;
diff --git a/LongoMatch.GUI/Gui/MainWindow.cs b/LongoMatch.GUI/Gui/MainWindow.cs
index b2f6116..a25a5dc 100644
--- a/LongoMatch.GUI/Gui/MainWindow.cs
+++ b/LongoMatch.GUI/Gui/MainWindow.cs
@@ -166,7 +166,7 @@ namespace LongoMatch.Gui
                        if (Focus is Entry) {
                                return ret;
                        } else {
-                               Config.EventsBroker.EmitKeyPressed(this, (int)evnt.Key, (int)evnt.State);
+                               Config.EventsBroker.EmitKeyPressed(this, 
LongoMatch.Core.Common.Keyboard.ParseEvent (evnt));
                                return true;
                        }
                }
@@ -317,14 +317,6 @@ namespace LongoMatch.Gui
                        about.Destroy();
                }
                
-               protected void OnDialogInfoActionActivated (object sender, System.EventArgs e)
-               {
-                       var info = new LongoMatch.Gui.Dialog.ShortcutsHelpDialog();
-                       info.TransientFor = this;
-                       info.Run();
-                       info.Destroy();
-               }
-
                protected void OnMigrationToolActionActivated(object sender, EventArgs e)
                {
                        Config.EventsBroker.EmitMigrateDB ();
diff --git a/LongoMatch.GUI/LongoMatch.GUI.csproj b/LongoMatch.GUI/LongoMatch.GUI.csproj
index ca99c66..9fd8a20 100644
--- a/LongoMatch.GUI/LongoMatch.GUI.csproj
+++ b/LongoMatch.GUI/LongoMatch.GUI.csproj
@@ -103,8 +103,6 @@
     <Compile Include="Gui\TreeView\PlayersFilterTreeView.cs" />
     <Compile Include="Gui\TreeView\FilterBaseView.cs" />
     <Compile Include="Gui\TreeView\CategoriesFilterTreeView.cs" />
-    <Compile Include="Gui\Dialog\ShortcutsHelpDialog.cs" />
-    <Compile Include="gtk-gui\LongoMatch.Gui.Dialog.ShortcutsHelpDialog.cs" />
     <Compile Include="Gui\Dialog\VideoConversionTool.cs" />
     <Compile Include="gtk-gui\LongoMatch.Gui.Dialog.VideoConversionTool.cs" />
     <Compile Include="Gui\Dialog\DatabasesManager.cs" />
diff --git a/LongoMatch.GUI/Makefile.am b/LongoMatch.GUI/Makefile.am
index 6ae53c0..d2b5ea1 100644
--- a/LongoMatch.GUI/Makefile.am
+++ b/LongoMatch.GUI/Makefile.am
@@ -53,7 +53,6 @@ SOURCES = Gui/Cairo.cs \
        Gui/Dialog/HotKeySelectorDialog.cs \
        Gui/Dialog/PlayEditor.cs \
        Gui/Dialog/RenderingJobsDialog.cs \
-       Gui/Dialog/ShortcutsHelpDialog.cs \
        Gui/Dialog/SnapshotsDialog.cs \
        Gui/Dialog/StatsViewer.cs \
        Gui/Dialog/SubstitutionsEditor.cs \
@@ -128,7 +127,6 @@ SOURCES = Gui/Cairo.cs \
        gtk-gui/LongoMatch.Gui.Dialog.HotKeySelectorDialog.cs \
        gtk-gui/LongoMatch.Gui.Dialog.PlayEditor.cs \
        gtk-gui/LongoMatch.Gui.Dialog.RenderingJobsDialog.cs \
-       gtk-gui/LongoMatch.Gui.Dialog.ShortcutsHelpDialog.cs \
        gtk-gui/LongoMatch.Gui.Dialog.SnapshotsDialog.cs \
        gtk-gui/LongoMatch.Gui.Dialog.StatsViewer.cs \
        gtk-gui/LongoMatch.Gui.Dialog.SubstitutionsEditor.cs \
diff --git a/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.Timeline.cs 
b/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.Timeline.cs
index e2f2da5..6208f8f 100644
--- a/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.Timeline.cs
+++ b/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.Component.Timeline.cs
@@ -56,6 +56,7 @@ namespace LongoMatch.Gui.Component
                        this.focusbuttonimage = new global::Gtk.Image ();
                        this.focusbuttonimage.Name = "focusbuttonimage";
                        this.focusbutton.Add (this.focusbuttonimage);
+                       this.focusbutton.Label = null;
                        this.hbox2.Add (this.focusbutton);
                        global::Gtk.Box.BoxChild w2 = ((global::Gtk.Box.BoxChild)(this.hbox2 
[this.focusbutton]));
                        w2.Position = 0;
diff --git a/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.MainWindow.cs 
b/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.MainWindow.cs
index 80a377a..f559d47 100644
--- a/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.MainWindow.cs
+++ b/LongoMatch.GUI/gtk-gui/LongoMatch.Gui.MainWindow.cs
@@ -26,7 +26,6 @@ namespace LongoMatch.Gui
                private global::Gtk.Action ExportProjectAction1;
                private global::Gtk.Action Action;
                private global::Gtk.Action ExportToProjectFileAction;
-               private global::Gtk.Action dialogInfoAction;
                private global::Gtk.Action ImportFromFileAction;
                private global::Gtk.ToggleAction TagSubcategoriesAction;
                private global::Gtk.Action VideoConverterToolAction;
@@ -114,9 +113,6 @@ namespace LongoMatch.Gui
                        this.ExportToProjectFileAction = new global::Gtk.Action ("ExportToProjectFileAction", 
global::Mono.Unix.Catalog.GetString ("Export to project file"), null, null);
                        this.ExportToProjectFileAction.ShortLabel = global::Mono.Unix.Catalog.GetString 
("Export to project file");
                        w1.Add (this.ExportToProjectFileAction, null);
-                       this.dialogInfoAction = new global::Gtk.Action ("dialogInfoAction", 
global::Mono.Unix.Catalog.GetString ("Shortcuts"), null, "gtk-dialog-info");
-                       this.dialogInfoAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Shortcuts");
-                       w1.Add (this.dialogInfoAction, null);
                        this.ImportFromFileAction = new global::Gtk.Action ("ImportFromFileAction", 
global::Mono.Unix.Catalog.GetString ("Import from file"), null, null);
                        this.ImportFromFileAction.ShortLabel = global::Mono.Unix.Catalog.GetString ("Import 
from file");
                        w1.Add (this.ImportFromFileAction, null);
@@ -155,7 +151,7 @@ namespace LongoMatch.Gui
                        this.menubox.Name = "menubox";
                        this.menubox.Spacing = 6;
                        // Container child menubox.Gtk.Box+BoxChild
-                       this.UIManager.AddUiFromString ("<ui><menubar name='menubar1'><menu name='FileAction' 
action='FileAction'><menuitem name='NewPojectAction' action='NewPojectAction'/><menuitem name='openAction' 
action='openAction'/><menuitem name='SaveProjectAction' action='SaveProjectAction'/><menuitem 
name='CloseProjectAction' action='CloseProjectAction'/><separator/><menuitem name='ImportProjectAction' 
action='ImportProjectAction'/><separator/><menuitem name='PreferencesAction' 
action='PreferencesAction'/><separator/><menuitem name='QuitAction' action='QuitAction'/></menu><menu 
name='ToolsAction' action='ToolsAction'><menuitem name='ProjectsManagerAction' 
action='ProjectsManagerAction'/><menuitem name='CategoriesTemplatesManagerAction' 
action='CategoriesTemplatesManagerAction'/><menuitem name='TeamsTemplatesManagerAction' 
action='TeamsTemplatesManagerAction'/><menuitem name='DatabasesManagerAction' 
action='DatabasesManagerAction'/><separator/><menuitem name='ShowProjectStatsAction' acti
 on='ShowProjectStatsAction'/><menu name='ExportProjectAction1' action='ExportProjectAction1'><menuitem 
name='ExportToProjectFileAction' action='ExportToProjectFileAction'/></menu><separator/><menuitem 
name='VideoConverterToolAction' action='VideoConverterToolAction'/><menuitem name='MigrationToolAction' 
action='MigrationToolAction'/></menu><menu name='ViewAction' action='ViewAction'><menuitem 
name='FullScreenAction' action='FullScreenAction'/><separator/><menuitem name='TagSubcategoriesAction' 
action='TagSubcategoriesAction'/></menu><menu name='HelpAction' action='HelpAction'><menuitem 
name='AboutAction' action='AboutAction'/><menuitem name='HelpAction1' action='HelpAction1'/><menuitem 
name='dialogInfoAction' action='dialogInfoAction'/></menu></menubar></ui>");
+                       this.UIManager.AddUiFromString ("<ui><menubar name='menubar1'><menu name='FileAction' 
action='FileAction'><menuitem name='NewPojectAction' action='NewPojectAction'/><menuitem name='openAction' 
action='openAction'/><menuitem name='SaveProjectAction' action='SaveProjectAction'/><menuitem 
name='CloseProjectAction' action='CloseProjectAction'/><separator/><menuitem name='ImportProjectAction' 
action='ImportProjectAction'/><separator/><menuitem name='PreferencesAction' 
action='PreferencesAction'/><separator/><menuitem name='QuitAction' action='QuitAction'/></menu><menu 
name='ToolsAction' action='ToolsAction'><menuitem name='ProjectsManagerAction' 
action='ProjectsManagerAction'/><menuitem name='CategoriesTemplatesManagerAction' 
action='CategoriesTemplatesManagerAction'/><menuitem name='TeamsTemplatesManagerAction' 
action='TeamsTemplatesManagerAction'/><menuitem name='DatabasesManagerAction' 
action='DatabasesManagerAction'/><separator/><menuitem name='ShowProjectStatsAction' acti
 on='ShowProjectStatsAction'/><menu name='ExportProjectAction1' action='ExportProjectAction1'><menuitem 
name='ExportToProjectFileAction' action='ExportToProjectFileAction'/></menu><separator/><menuitem 
name='VideoConverterToolAction' action='VideoConverterToolAction'/><menuitem name='MigrationToolAction' 
action='MigrationToolAction'/></menu><menu name='ViewAction' action='ViewAction'><menuitem 
name='FullScreenAction' action='FullScreenAction'/><separator/><menuitem name='TagSubcategoriesAction' 
action='TagSubcategoriesAction'/></menu><menu name='HelpAction' action='HelpAction'><menuitem 
name='AboutAction' action='AboutAction'/><menuitem name='HelpAction1' 
action='HelpAction1'/></menu></menubar></ui>");
                        this.menubar1 = ((global::Gtk.MenuBar)(this.UIManager.GetWidget ("/menubar1")));
                        this.menubar1.Name = "menubar1";
                        this.menubox.Add (this.menubar1);
@@ -202,7 +198,6 @@ namespace LongoMatch.Gui
                        this.Show ();
                        this.AboutAction.Activated += new global::System.EventHandler 
(this.OnAboutActionActivated);
                        this.HelpAction1.Activated += new global::System.EventHandler 
(this.OnHelpAction1Activated);
-                       this.dialogInfoAction.Activated += new global::System.EventHandler 
(this.OnDialogInfoActionActivated);
                        this.VideoConverterToolAction.Activated += new global::System.EventHandler 
(this.OnVideoConverterToolActionActivated);
                        this.MigrationToolAction.Activated += new global::System.EventHandler 
(this.OnMigrationToolActionActivated);
                }
diff --git a/LongoMatch.GUI/gtk-gui/gui.stetic b/LongoMatch.GUI/gtk-gui/gui.stetic
index 8b5348d..82031d3 100644
--- a/LongoMatch.GUI/gtk-gui/gui.stetic
+++ b/LongoMatch.GUI/gtk-gui/gui.stetic
@@ -815,13 +815,6 @@ Sort by competition</property>
         <property name="Label" translatable="yes">Export to project file</property>
         <property name="ShortLabel" translatable="yes">Export to project file</property>
       </action>
-      <action id="dialogInfoAction">
-        <property name="Type">Action</property>
-        <property name="Label" translatable="yes">Shortcuts</property>
-        <property name="ShortLabel" translatable="yes">Shortcuts</property>
-        <property name="StockId">gtk-dialog-info</property>
-        <signal name="Activated" handler="OnDialogInfoActionActivated" />
-      </action>
       <action id="ImportFromFileAction">
         <property name="Type">Action</property>
         <property name="Label" translatable="yes">Import from file</property>
@@ -913,7 +906,6 @@ Sort by competition</property>
                   <node type="Menu" action="HelpAction">
                     <node type="Menuitem" action="AboutAction" />
                     <node type="Menuitem" action="HelpAction1" />
-                    <node type="Menuitem" action="dialogInfoAction" />
                   </node>
                 </node>
               </widget>
@@ -4545,114 +4537,6 @@ You can continue with the current capture, cancel it or save your project.
       </widget>
     </child>
   </widget>
-  <widget class="Gtk.Dialog" id="LongoMatch.Gui.Dialog.ShortcutsHelpDialog" design-size="538 248">
-    <property name="MemberName" />
-    <property name="Icon">stock:longomatch Menu</property>
-    <property name="WindowPosition">CenterOnParent</property>
-    <property name="Modal">True</property>
-    <property name="SkipPagerHint">True</property>
-    <property name="SkipTaskbarHint">True</property>
-    <property name="Buttons">2</property>
-    <property name="HelpButton">False</property>
-    <child internal-child="VBox">
-      <widget class="Gtk.VBox" id="dialog1_VBox">
-        <property name="MemberName" />
-        <property name="BorderWidth">2</property>
-        <child>
-          <widget class="Gtk.HBox" id="hbox1">
-            <property name="MemberName" />
-            <property name="Spacing">6</property>
-            <child>
-              <widget class="Gtk.VBox" id="shortcutsvbox">
-                <property name="MemberName" />
-                <property name="Spacing">6</property>
-                <child>
-                  <placeholder />
-                </child>
-                <child>
-                  <placeholder />
-                </child>
-                <child>
-                  <placeholder />
-                </child>
-              </widget>
-              <packing>
-                <property name="Position">0</property>
-                <property name="AutoSize">False</property>
-                <property name="Expand">False</property>
-                <property name="Fill">False</property>
-              </packing>
-            </child>
-            <child>
-              <widget class="Gtk.VBox" id="desc_vbox">
-                <property name="MemberName" />
-                <property name="Spacing">6</property>
-                <child>
-                  <placeholder />
-                </child>
-                <child>
-                  <placeholder />
-                </child>
-                <child>
-                  <placeholder />
-                </child>
-              </widget>
-              <packing>
-                <property name="Position">1</property>
-                <property name="AutoSize">True</property>
-              </packing>
-            </child>
-          </widget>
-          <packing>
-            <property name="Position">0</property>
-            <property name="AutoSize">True</property>
-          </packing>
-        </child>
-      </widget>
-    </child>
-    <child internal-child="ActionArea">
-      <widget class="Gtk.HButtonBox" id="dialog1_ActionArea">
-        <property name="MemberName" />
-        <property name="Spacing">10</property>
-        <property name="BorderWidth">5</property>
-        <property name="Size">2</property>
-        <property name="LayoutStyle">End</property>
-        <child>
-          <widget class="Gtk.Button" id="buttonCancel">
-            <property name="MemberName" />
-            <property name="CanDefault">True</property>
-            <property name="CanFocus">True</property>
-            <property name="UseStock">True</property>
-            <property name="Type">StockItem</property>
-            <property name="StockId">gtk-cancel</property>
-            <property name="ResponseId">-6</property>
-            <property name="label">gtk-cancel</property>
-          </widget>
-          <packing>
-            <property name="Expand">False</property>
-            <property name="Fill">False</property>
-          </packing>
-        </child>
-        <child>
-          <widget class="Gtk.Button" id="buttonOk">
-            <property name="MemberName" />
-            <property name="CanDefault">True</property>
-            <property name="CanFocus">True</property>
-            <property name="UseStock">True</property>
-            <property name="Type">StockItem</property>
-            <property name="StockId">gtk-ok</property>
-            <property name="ResponseId">-5</property>
-            <property name="label">gtk-ok</property>
-          </widget>
-          <packing>
-            <property name="Position">1</property>
-            <property name="Expand">False</property>
-            <property name="Fill">False</property>
-          </packing>
-        </child>
-      </widget>
-    </child>
-  </widget>
   <widget class="Gtk.Dialog" id="LongoMatch.Gui.Dialog.VideoConversionTool" design-size="456 363">
     <property name="MemberName" />
     <property name="Title" translatable="yes">Video converter tool</property>
@@ -11620,4 +11504,4 @@ You can continue with the current capture, cancel it or save your project.
       </widget>
     </child>
   </widget>
-</stetic-interface>
\ No newline at end of file
+</stetic-interface>
diff --git a/LongoMatch.Services/Services/EventsManager.cs b/LongoMatch.Services/Services/EventsManager.cs
index e52fb1d..145cdd7 100644
--- a/LongoMatch.Services/Services/EventsManager.cs
+++ b/LongoMatch.Services/Services/EventsManager.cs
@@ -107,6 +107,8 @@ namespace LongoMatch.Services
                        Config.EventsBroker.Detach += HandleDetach;
                        
                        Config.EventsBroker.ShowFullScreenEvent += HandleShowFullScreenEvent;
+                       
+                       Config.EventsBroker.KeyPressed += HandleKeyPressed;
                }
 
                void DeletePlays (List<TimelineEvent> plays, bool update=true)
@@ -366,5 +368,31 @@ namespace LongoMatch.Services
                        analysisWindow.ReloadProject ();
                }
 
+               void HandleKeyPressed (object sender, HotKey key)
+               {
+                       KeyAction action;
+
+                       try {
+                               action = Config.Hotkeys.ActionsHotkeys.GetKeyByValue (key);
+                       } catch (Exception ex) {
+                               /* The dictionary contains 2 equal values for different keys */
+                               Log.Exception (ex);
+                               return;
+                       }
+                       
+                       if (action == KeyAction.None) {
+                               return;
+                       }
+                       
+                       switch (action) {
+                       case KeyAction.EditEvent:
+                               Config.GUIToolkit.EditPlay (loadedPlay, openedProject, true, true, true, 
true);
+                               break;
+                       case KeyAction.DeleteEvent:
+                               DeletePlays (new List<TimelineEvent> {loadedPlay});
+                               break;
+                       }
+                       
+               }
        }
 }
diff --git a/LongoMatch.Services/Services/HotKeysManager.cs b/LongoMatch.Services/Services/HotKeysManager.cs
index 9d3c4a5..81855f1 100644
--- a/LongoMatch.Services/Services/HotKeysManager.cs
+++ b/LongoMatch.Services/Services/HotKeysManager.cs
@@ -22,6 +22,7 @@ using System.Collections.Generic;
 using LongoMatch.Core.Common;
 using LongoMatch.Core.Interfaces.GUI;
 using LongoMatch.Core.Store;
+using System;
 
 #if HAVE_GTK
 using Gdk;
@@ -33,6 +34,7 @@ namespace LongoMatch.Services
        public class HotKeysManager
        {
                Dictionary<HotKey, DashboardButton> dic;
+               IAnalysisWindow analysisWindow;
                bool ignoreKeys;
 
                public HotKeysManager ()
@@ -45,6 +47,7 @@ namespace LongoMatch.Services
                void HandleOpenedProjectChanged (Project project, ProjectType projectType,
                                                 EventsFilter filter, IAnalysisWindow analysisWindow)
                {
+                       this.analysisWindow = analysisWindow;
                        if (project == null) {
                                ignoreKeys = true;
                                return;
@@ -59,21 +62,42 @@ namespace LongoMatch.Services
                        }
                }
 
-               public void KeyListener (object sender, int key, int state)
+               public void KeyListener (object sender, HotKey key)
                {
-                       if (ignoreKeys)
+                       KeyAction action;
+
+                       try {
+                               action = Config.Hotkeys.ActionsHotkeys.GetKeyByValue (key);
+                       } catch (Exception ex) {
+                               /* The dictionary contains 2 equal values for different keys */
+                               Log.Exception (ex);
                                return;
+                       }
                        
-#if HAVE_GTK
-                       DashboardButton button = null;
-                       HotKey hotkey = new HotKey ();
-
-                       hotkey.Key = key;
-                       hotkey.Modifier = (int)((ModifierType)state & (ModifierType.Mod1Mask | 
ModifierType.Mod5Mask | ModifierType.ShiftMask));
-                       if (dic.TryGetValue (hotkey, out button)) {
-                               Config.EventsBroker.EmitPressButton (button);
-#endif
+                       if (action != KeyAction.None && analysisWindow != null) {
+                               switch (action) {
+                               case KeyAction.ZoomIn:
+                                       analysisWindow.ZoomIn ();
+                                       return;
+                               case KeyAction.ZoomOut:
+                                       analysisWindow.ZoomOut ();
+                                       return;
+                               case KeyAction.ShowDashboard:
+                                       analysisWindow.ShowDashboard ();
+                                       return;
+                               case KeyAction.ShowTimeline:
+                                       analysisWindow.ShowTimeline ();
+                                       return;
+                               case KeyAction.ShowPositions:
+                                       analysisWindow.ShowZonalTags ();
+                                       return;
+                               case KeyAction.FitTimeline:
+                                       analysisWindow.FitTimeline ();
+                                       return;
+                               }
                        }
+                       if (ignoreKeys)
+                               return;
                }
        }
 }
diff --git a/LongoMatch.Services/Services/PlaylistManager.cs b/LongoMatch.Services/Services/PlaylistManager.cs
index 96ec498..195ae32 100644
--- a/LongoMatch.Services/Services/PlaylistManager.cs
+++ b/LongoMatch.Services/Services/PlaylistManager.cs
@@ -15,6 +15,7 @@
 //  along with this program; if not, write to the Free Software
 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
 // 
+using System.Linq;
 using System.Collections.Generic;
 using System.Threading;
 using LongoMatch.Core.Common;
@@ -24,6 +25,7 @@ using LongoMatch.Core.Store;
 using LongoMatch.Core.Store.Playlists;
 using Mono.Unix;
 using Timer = System.Threading.Timer;
+using System;
 
 namespace LongoMatch.Services
 {
@@ -33,6 +35,7 @@ namespace LongoMatch.Services
                IPlayerBin player;
                IRenderingJobsManager videoRenderer;
                Project openedProject;
+               ProjectType openedProjectType;
                IPlaylistElement loadedElement;
                Playlist loadedPlaylist;
                TimelineEvent loadedPlay;
@@ -59,6 +62,7 @@ namespace LongoMatch.Services
                        Config.EventsBroker.TimeNodeChanged += HandlePlayChanged;
                        Config.EventsBroker.SeekEvent += HandleSeekEvent;
                        Config.EventsBroker.TogglePlayEvent += HandleTogglePlayEvent;
+                       Config.EventsBroker.KeyPressed += HandleKeyPressed;
                }
 
                void LoadPlay (TimelineEvent play, Time seekTime, bool playing)
@@ -106,6 +110,7 @@ namespace LongoMatch.Services
                                                 EventsFilter filter, IAnalysisWindow analysisWindow)
                {
                        openedProject = project;
+                       openedProjectType = projectType;
                        if (project != null) {
                                player = analysisWindow.Player;
                                this.filter = filter;
@@ -222,6 +227,76 @@ namespace LongoMatch.Services
                                }
                        }
                }
+               
+               void HandleKeyPressed (object sender, HotKey key)
+               {
+                       if (openedProject == null)
+                               return;
+
+                       if (openedProjectType != ProjectType.CaptureProject &&
+                               openedProjectType != ProjectType.URICaptureProject &&
+                               openedProjectType != ProjectType.FakeCaptureProject) {
+                               KeyAction action;
+                               if (player == null)
+                                       return;
+
+                               try {
+                                       action = Config.Hotkeys.ActionsHotkeys.GetKeyByValue (key);
+                               } catch (Exception ex) {
+                                       /* The dictionary contains 2 equal values for different keys */
+                                       Log.Exception (ex);
+                                       return;
+                               }
+                               
+                               if (action == KeyAction.None) {
+                                       return;
+                               }
+
+                               switch (action) {
+                               case KeyAction.FrameUp:
+                                       player.SeekToPreviousFrame ();
+                                       return;
+                               case KeyAction.FrameDown:
+                                       player.SeekToNextFrame ();
+                                       return;
+                               case KeyAction.JumpUp:
+                                       player.StepForward ();
+                                       return;
+                               case KeyAction.JumpDown:
+                                       player.StepBackward ();
+                                       return;
+                               case KeyAction.DrawFrame:
+                                       TimelineEvent evt = loadedPlay;
+                                       if (evt == null && loadedElement is PlaylistPlayElement) {
+                                               evt = (loadedElement as PlaylistPlayElement).Play;
+                                       }
+                                       Config.EventsBroker.EmitDrawFrame (evt, -1, player.ActiveAngle, true);
+                                       return;
+                               case KeyAction.TogglePlay:
+                                       player.TogglePlay ();
+                                       return;
+                               case KeyAction.SpeedUp:
+                                       player.FramerateUp ();
+                                       return;
+                               case KeyAction.SpeedDown:
+                                       player.FramerateDown ();
+                                       return;
+                               case KeyAction.CloseEvent:
+                                       Config.EventsBroker.EmitLoadEvent (null);
+                                       return;
+                               case KeyAction.Prev:
+                                       HandlePrev (loadedPlaylist);
+                                       return;
+                               case KeyAction.Next:
+                                       HandleNext (loadedPlaylist);
+                                       return;
+                               }
+                       } else {
+                               //if (Capturer == null)
+                               //      return;
+                       }
+               }
+               
 
        }
 }
diff --git a/LongoMatch.Services/Services/ProjectsManager.cs b/LongoMatch.Services/Services/ProjectsManager.cs
index 146b655..8f5aa09 100644
--- a/LongoMatch.Services/Services/ProjectsManager.cs
+++ b/LongoMatch.Services/Services/ProjectsManager.cs
@@ -50,7 +50,6 @@ namespace LongoMatch.Services
                        Config.EventsBroker.OpenNewProjectEvent += OpenNewProject;
                        Config.EventsBroker.CloseOpenedProjectEvent += PromptCloseProject;
                        Config.EventsBroker.SaveProjectEvent += SaveProject;
-                       Config.EventsBroker.KeyPressed += HandleKeyPressed;
                        Config.EventsBroker.CaptureError += HandleCaptureError;
                        Config.EventsBroker.CaptureFinished += HandleCaptureFinished;
                        Config.EventsBroker.MultimediaError += HandleMultimediaError;
@@ -401,46 +400,5 @@ namespace LongoMatch.Services
                        HandleCaptureFinished (false);
                }
 
-               void HandleKeyPressed (object sender, int key, int modifier)
-               {
-                       if (OpenedProject == null)
-                               return;
-
-                       if (OpenedProjectType != ProjectType.CaptureProject &&
-                               OpenedProjectType != ProjectType.URICaptureProject &&
-                               OpenedProjectType != ProjectType.FakeCaptureProject) {
-                               if (Player == null)
-                                       return;
-
-                               switch (key) {
-                               case Constants.SEEK_FORWARD:
-                                       if (modifier == Constants.STEP)
-                                               Player.StepForward ();
-                                       else
-                                               Player.SeekToNextFrame ();
-                                       break;
-                               case Constants.SEEK_BACKWARD:
-                                       if (modifier == Constants.STEP)
-                                               Player.StepBackward ();
-                                       else
-                                               Player.SeekToPreviousFrame ();
-                                       break;
-                               case Constants.FRAMERATE_UP:
-                                       Player.FramerateUp ();
-                                       break;
-                               case Constants.FRAMERATE_DOWN:
-                                       Player.FramerateDown ();
-                                       break;
-                               case Constants.TOGGLE_PLAY:
-                                       Player.TogglePlay ();
-                                       break;
-                               }
-                       } else {
-                               if (Capturer == null)
-                                       return;
-                               switch (key) {
-                               }
-                       }
-               }
        }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]