Skip to content

Commit

Permalink
#101 initial support for exporting GUI to txt
Browse files Browse the repository at this point in the history
  • Loading branch information
pixeltris committed Dec 20, 2020
1 parent e254296 commit 7c8b9ce
Show file tree
Hide file tree
Showing 2 changed files with 263 additions and 1 deletion.
158 changes: 158 additions & 0 deletions GK6X/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,164 @@ static void Run(bool asGUI)
case "gui":
WebGUI.Run();
break;
case "gui_to_txt":
{
if (string.IsNullOrEmpty(WebGUI.UserDataPath))
{
Log("Load GUI first");
}
else
{
string userDataPath = WebGUI.UserDataPath;
int accountId = 0;
string accountDir = Path.Combine(userDataPath, "Account", accountId.ToString());
if (Directory.Exists(accountDir))
{
foreach (KeyboardDevice device in KeyboardDeviceManager.GetConnectedDevices())
{
string deviceDir = Path.Combine(userDataPath, "Account", accountId.ToString(), "Devices", device.State.ModelId.ToString());
if (Directory.Exists(deviceDir))
{
Dictionary<int, UserDataFile.Macro> macrosById = new Dictionary<int, UserDataFile.Macro>();
UserDataFile userDataFile = new UserDataFile();
foreach (string file in Directory.GetFiles(deviceDir, "*.cmf"))
{
string config = Encoding.UTF8.GetString(CMFile.Load(file));
Dictionary<string, object> data = MiniJSON.Json.Deserialize(config) as Dictionary<string, object>;
int modelIndex = (int)Convert.ChangeType(data["ModeIndex"], typeof(int));
KeyboardLayer layer = (KeyboardLayer)modelIndex;

//////////////////////////////////////////
// Keys / macros (NOTE: Macros on different layers might wipe each other. look into.)
//////////////////////////////////////////
for (int i = 0; i < 2; i++)
{
string setStr = i == 0 ? "KeySet" : "FnKeySet";
if (data.ContainsKey(setStr))
{
List<object> keys = data[setStr] as List<object>;
foreach (object keyObj in keys)
{
Dictionary<string, object> key = keyObj as Dictionary<string, object>;
int keyIndex = (int)Convert.ChangeType(key["Index"], typeof(int));
uint driverValue = KeyValues.UnusedKeyValue;
string driverValueStr = (string)key["DriverValue"];
if (driverValueStr.StartsWith("0x"))
{
if (uint.TryParse(driverValueStr.Substring(2), System.Globalization.NumberStyles.HexNumber, null, out driverValue))
{
if (KeyValues.GetKeyType(driverValue) == DriverValueType.Macro && key.ContainsKey("Task"))
{
Dictionary<string, object> task = key["Task"] as Dictionary<string, object>;
if (task != null && (string)task["Type"] == "Macro")
{
Dictionary<string, object> taskData = task["Data"] as Dictionary<string, object>;
string macroGuid = (string)taskData["GUID"];
string macroFile = Path.Combine(userDataPath, "Account", accountId.ToString(), "Macro", macroGuid + ".cms");
if (File.Exists(macroFile))
{
UserDataFile.Macro macro = new UserDataFile.Macro(null);
macro.LoadFile(macroFile);
macro.RepeatCount = (byte)Convert.ChangeType(taskData["Repeats"], typeof(byte));
macro.RepeatType = (MacroRepeatType)(byte)Convert.ChangeType(taskData["StopMode"], typeof(byte));
macro.Id = KeyValues.GetKeyData2(driverValue);
macrosById[macro.Id] = macro;
userDataFile.Macros[macroGuid] = macro;
}
}
}
}
else
{
driverValue = KeyValues.UnusedKeyValue;
}
}
if (keyIndex >= 0 && keyIndex < device.State.MaxLogicCode && driverValue != KeyValues.UnusedKeyValue)
{
KeyboardState.Key keyInfo = device.State.GetKeyByLogicCode(keyIndex);
if (keyInfo != null)
{
Dictionary<string, uint> vals = userDataFile.FindOrAddLayer(layer, i > 0).Keys;
if (Enum.IsDefined(typeof(DriverValue), driverValue))
{
vals[keyInfo.DriverValueName.ToLower()] = driverValue;
}
else
{
Log("Failed to map index " + keyIndex + " to " + driverValue + " on layer " + layer +
(i > 0 ? " fn" : string.Empty));
}
}
}
}
}
}

//////////////////////////////////////////
// Lighting
//////////////////////////////////////////
Dictionary<string, UserDataFile.LightingEffect> effects = new Dictionary<string, UserDataFile.LightingEffect>();
string[] leHeaders = { "ModeLE", "DriverLE" };
foreach (string leHeader in leHeaders)
{
if (data.ContainsKey(leHeader))
{
List<object> leEntries = data[leHeader] as List<object>;
if (leEntries == null)
{
// There's only one ModeLE
leEntries = new List<object>();
leEntries.Add(data[leHeader]);
}
foreach (object entry in leEntries)
{
Dictionary<string, object> modeLE = entry as Dictionary<string, object>;
string leGuid = (string)modeLE["GUID"];
if (!string.IsNullOrEmpty(leGuid))
{
string filePath = Path.Combine(userDataPath, "Account", accountId.ToString(), "LE", leGuid + ".le");
if (!effects.ContainsKey(leGuid) && File.Exists(filePath))
{
UserDataFile.LightingEffect le = new UserDataFile.LightingEffect(userDataFile, null);
le.Load(device.State, Encoding.UTF8.GetString(CMFile.Load(filePath)));
le.Layers.Add(layer);
userDataFile.LightingEffects[leGuid] = le;
effects[leGuid] = le;
}
}
else
{
object leDataObj;
if (modeLE.TryGetValue("LEData", out leDataObj))
{
Dictionary<string, object> leData = leDataObj as Dictionary<string, object>;
if (leData != null)
{
// This should be static lighting data only
UserDataFile.LightingEffect le = new UserDataFile.LightingEffect(userDataFile, null);
le.LoadStatic(device.State, leData);
le.Layers.Add(layer);
userDataFile.LightingEffects[Guid.NewGuid().ToString()] = le;
}
}
}
}
}
}
}
userDataFile.SaveFromGUI(device.State, Path.Combine(UserDataPath, device.State.ModelId + "_exported.txt"));
Log("Done");
break;
}
}
}
else
{
Log("Account settings not found for account id " + accountId);
}
}
}
break;
case "gui_le":
{
string userDataPath = WebGUI.UserDataPath;
Expand Down
106 changes: 105 additions & 1 deletion GK6X/UserDataFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,32 @@ public class Param
public bool UseRawValues;
}

public static Dictionary<string, string> Discover()
{
Dictionary<string, string> names = new Dictionary<string, string>();
string path = Path.Combine(Program.DataBasePath, "lighting");
if (Directory.Exists(path))
{
foreach (string file in Directory.GetFiles(path, "*.le"))
{
try
{
string str = File.ReadAllText(file);
Dictionary<string, object> json = Json.Deserialize(str) as Dictionary<string, object>;
string guid;
if (json != null && Json.TryGetValue(json, "GUID", out guid))
{
names[guid.ToLower()] = Path.GetFileNameWithoutExtension(file);
}
}
catch
{
}
}
}
return names;
}

public bool Load(KeyboardState keyboard)
{
try
Expand Down Expand Up @@ -655,7 +681,7 @@ private bool TryParseDriverValue(string str, out DriverValue result, out string
return false;
}

private Layer FindOrAddLayer(KeyboardLayer layer, bool fn)
public Layer FindOrAddLayer(KeyboardLayer layer, bool fn)
{
Dictionary<KeyboardLayer, Layer> layers = fn ? FnLayers : Layers;
Layer result;
Expand Down Expand Up @@ -1217,5 +1243,83 @@ private void Load(KeyboardState keyboard, string file, params GroupType[] groups
}
}
}

public void SaveFromGUI(KeyboardState keyboard, string path)
{
StringBuilder sb = new StringBuilder();
if (Macros.Count > 0)
{
foreach (Macro macro in Macros.Values)
{
sb.AppendLine("[Macro(" + macro.Name + "," + macro.DefaultDelay + "," + macro.RepeatType + "," + macro.RepeatCount + ")]");
foreach (Macro.Action action in macro.Actions)
{
string delayStr = action.Delay > 0 ? ":" + action.Delay : string.Empty;
string modifierStr = action.Modifier != DriverValueModifer.None ? action.Modifier.ToString() : string.Empty;
string keyStr = (!string.IsNullOrEmpty(modifierStr) ? "+" : string.Empty) + (action.KeyCode > 0 ? ((DriverValue)KeyValues.GetLongDriverValue(action.KeyCode)).ToString() : string.Empty);
if (!string.IsNullOrEmpty(modifierStr) || !string.IsNullOrEmpty(keyStr))
{
sb.AppendLine(action.Type + ":" + modifierStr + keyStr + delayStr);
}
}
sb.AppendLine();
}
sb.AppendLine();
}

if (LightingEffects.Count > 0)
{
// TODO: Copy lighting effect file over from data file
Dictionary<string, string> names = LightingEffect.Discover();
foreach (KeyValuePair<string, LightingEffect> le in LightingEffects)
{
string name;
if (le.Value.Layers.Count > 0 && names.TryGetValue(le.Key.ToLower(), out name))
{
sb.AppendLine("Lighting[(" + name + ")," + string.Join(",", le.Value.Layers) + "]");
}
}
sb.AppendLine();
}


for (int i = 0; i < 2; i++)
{
foreach (KeyValuePair<KeyboardLayer, Layer> layer in i == 0 ? Layers : FnLayers)
{
sb.AppendLine("[" + (i > 0 ? "Fn" : string.Empty) + layer.Key + "]");
uint[] defaultDriverValues = i > 0 ? keyboard.GetLayer(layer.Key).FnKeySet : keyboard.GetLayer(layer.Key).KeySet;
for (int j = 0; j < keyboard.MaxLogicCode; j++)
{
KeyboardState.Key key = keyboard.GetKeyByLogicCode(j);
if (key != null && j < defaultDriverValues.Length)
{
uint driverValue = layer.Value.GetKey(key);
if (driverValue != KeyValues.UnusedKeyValue && driverValue != defaultDriverValues[j])
{
switch (KeyValues.GetKeyType(driverValue))
{
case DriverValueType.Macro:
{
byte macroId = KeyValues.GetKeyData2(driverValue);
Macro macro = Macros.Values.FirstOrDefault(x => x.Id == macroId);
if (macro != null)
{
sb.AppendLine((DriverValue)defaultDriverValues[j] + ":Macro(" + macro.Name + ")");
}
}
break;
default:
sb.AppendLine((DriverValue)defaultDriverValues[j] + ":" + (DriverValue)driverValue);
break;
}
}
}
}
sb.AppendLine();
}
}
File.WriteAllText(path, sb.ToString());
}
}
}

0 comments on commit 7c8b9ce

Please sign in to comment.