mirror of
https://github.com/cemu-project/DS4Windows.git
synced 2024-11-26 02:54:20 +01:00
Support auto-profile matching using both program path and application window title values. Support wildchar string match logic in auto-profile path and window title values. Re-wrote auto-profile checking thread to be less RAM hungry and better performance (caching to remember the previous application and window handle values)
This commit is contained in:
parent
19a96973ff
commit
e9d9e9f428
@ -39,12 +39,20 @@ namespace DS4Windows.Forms
|
||||
protected CheckBox[] linkedProfileCB;
|
||||
NonFormTimer hotkeysTimer = null;// new NonFormTimer();
|
||||
NonFormTimer autoProfilesTimer = null;// new NonFormTimer();
|
||||
string tempProfileProgram = string.Empty;
|
||||
double dpix, dpiy;
|
||||
|
||||
List<ProgramPathItem> programpaths = new List<ProgramPathItem>();
|
||||
List<string> profilenames = new List<string>();
|
||||
List<string> programpaths = new List<string>();
|
||||
List<string>[] proprofiles;
|
||||
List<bool> turnOffTempProfiles;
|
||||
ProgramPathItem tempProfileProgram = null;
|
||||
|
||||
public static int autoProfileDebugLogLevel = 0; // 0=Dont log debug messages about active process and window titles to GUI Log screen. 1=Show debug log messages
|
||||
private static IntPtr prevForegroundWnd = IntPtr.Zero;
|
||||
private static uint prevForegroundProcessID = 0;
|
||||
private static string prevForegroundWndTitleName = string.Empty;
|
||||
private static string prevForegroundProcessName = string.Empty;
|
||||
private static StringBuilder autoProfileCheckTextBuilder = null;
|
||||
|
||||
private bool systemShutdown = false;
|
||||
private bool wasrunning = false;
|
||||
@ -87,6 +95,9 @@ namespace DS4Windows.Forms
|
||||
[DllImport("psapi.dll")]
|
||||
private static extern uint GetModuleFileNameEx(IntPtr hWnd, IntPtr hModule, StringBuilder lpFileName, int nSize);
|
||||
|
||||
[DllImport("user32.dll", CharSet= CharSet.Auto)]
|
||||
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nSize);
|
||||
|
||||
public DS4Form(string[] args)
|
||||
{
|
||||
Global.FindConfigLocation();
|
||||
@ -546,20 +557,87 @@ namespace DS4Windows.Forms
|
||||
}
|
||||
}
|
||||
|
||||
public static string GetTopWindowName()
|
||||
public static bool GetTopWindowName(out string topProcessName, out string topWndTitleName, bool autoProfileTimerCheck = false)
|
||||
{
|
||||
IntPtr hWnd = GetForegroundWindow();
|
||||
uint lpdwProcessId;
|
||||
if (hWnd == IntPtr.Zero)
|
||||
{
|
||||
// Top window unknown or cannot acquire a handle. Return FALSE and return unknown process and wndTitle values
|
||||
prevForegroundWnd = IntPtr.Zero;
|
||||
prevForegroundProcessID = 0;
|
||||
topProcessName = topWndTitleName = String.Empty;
|
||||
return false;
|
||||
}
|
||||
|
||||
//
|
||||
// If this function was called from "auto-profile watcher timer" then check cached "previous hWnd handle". If the current hWnd is the same
|
||||
// as during the previous check then return cached previous wnd and name values (ie. foreground app and window are assumed to be the same, so no need to re-query names).
|
||||
// This should optimize the auto-profile timer check process and causes less burden to .NET GC collector because StringBuffer is not re-allocated every second.
|
||||
//
|
||||
// Note! hWnd handles may be re-cycled but not during the lifetime of the window. This "cache" optimization still works because when an old window is closed
|
||||
// then foreground window changes to something else and the cached prevForgroundWnd variable is updated to store the new hWnd handle.
|
||||
// It doesn't matter even when the previously cached handle is recycled by WinOS to represent some other window (it is no longer used as a cached value anyway).
|
||||
//
|
||||
if(autoProfileTimerCheck)
|
||||
{
|
||||
if(hWnd == prevForegroundWnd)
|
||||
{
|
||||
// The active window is still the same. Return cached process and wndTitle values and FALSE to indicate caller that no changes since the last call of this method
|
||||
topProcessName = prevForegroundProcessName;
|
||||
topWndTitleName = prevForegroundWndTitleName;
|
||||
return false;
|
||||
}
|
||||
|
||||
prevForegroundWnd = hWnd;
|
||||
}
|
||||
|
||||
IntPtr hProcess = IntPtr.Zero;
|
||||
uint lpdwProcessId = 0;
|
||||
GetWindowThreadProcessId(hWnd, out lpdwProcessId);
|
||||
|
||||
IntPtr hProcess = OpenProcess(0x0410, false, lpdwProcessId);
|
||||
if (autoProfileTimerCheck)
|
||||
{
|
||||
if (autoProfileCheckTextBuilder == null) autoProfileCheckTextBuilder = new StringBuilder(1000);
|
||||
|
||||
StringBuilder text = new StringBuilder(1000);
|
||||
GetModuleFileNameEx(hProcess, IntPtr.Zero, text, text.Capacity);
|
||||
if (lpdwProcessId == prevForegroundProcessID)
|
||||
{
|
||||
topProcessName = prevForegroundProcessName;
|
||||
}
|
||||
else
|
||||
{
|
||||
prevForegroundProcessID = lpdwProcessId;
|
||||
|
||||
CloseHandle(hProcess);
|
||||
hProcess = OpenProcess(0x0410, false, lpdwProcessId);
|
||||
if (hProcess != IntPtr.Zero) GetModuleFileNameEx(hProcess, IntPtr.Zero, autoProfileCheckTextBuilder, autoProfileCheckTextBuilder.Capacity);
|
||||
else autoProfileCheckTextBuilder.Clear();
|
||||
|
||||
return text.ToString();
|
||||
prevForegroundProcessName = topProcessName = autoProfileCheckTextBuilder.Replace('/', '\\').ToString().ToLower();
|
||||
}
|
||||
|
||||
GetWindowText(hWnd, autoProfileCheckTextBuilder, autoProfileCheckTextBuilder.Capacity);
|
||||
prevForegroundWndTitleName = topWndTitleName = autoProfileCheckTextBuilder.ToString().ToLower();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Caller function was not the autoprofile timer check thread, so create a new buffer to make this call thread safe and always query process and window title names.
|
||||
// Note! At the moment DS4Win app doesn't call this method with autoProfileTimerCheck=false option, but this is here just for potential future usage.
|
||||
StringBuilder text = new StringBuilder(1000);
|
||||
|
||||
hProcess = OpenProcess(0x0410, false, lpdwProcessId);
|
||||
if (hProcess != IntPtr.Zero) GetModuleFileNameEx(hProcess, IntPtr.Zero, text, text.Capacity);
|
||||
else text.Clear();
|
||||
topProcessName = text.ToString();
|
||||
|
||||
GetWindowText(hWnd, text, text.Capacity);
|
||||
topWndTitleName = text.ToString();
|
||||
}
|
||||
|
||||
if (hProcess != IntPtr.Zero) CloseHandle(hProcess);
|
||||
|
||||
if(DS4Form.autoProfileDebugLogLevel > 0 )
|
||||
AppLogger.LogToGui($"DEBUG: Auto-Profile. PID={lpdwProcessId} Path={topProcessName} | WND={hWnd} Title={topWndTitleName}", false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void PowerEventArrive(object sender, EventArrivedEventArgs e)
|
||||
@ -651,69 +729,110 @@ namespace DS4Windows.Forms
|
||||
|
||||
private void CheckAutoProfiles(object sender, EventArgs e)
|
||||
{
|
||||
string topProcessName, topWindowTitle;
|
||||
string[] newProfileName = new string[4] { String.Empty, String.Empty, String.Empty, String.Empty };
|
||||
bool turnOffDS4WinApp = false;
|
||||
ProgramPathItem matchingProgramPathItem = null;
|
||||
|
||||
autoProfilesTimer.Stop();
|
||||
|
||||
//Check for process for auto profiles
|
||||
if (string.IsNullOrEmpty(tempProfileProgram))
|
||||
if (GetTopWindowName(out topProcessName, out topWindowTitle, true))
|
||||
{
|
||||
string windowName = GetTopWindowName().ToLower().Replace('/', '\\');
|
||||
// Find a profile match based on autoprofile program path and wnd title list.
|
||||
// The same program may set different profiles for each of the controllers, so we need an array of newProfileName[controllerIdx] values.
|
||||
for (int i = 0, pathsLen = programpaths.Count; i < pathsLen; i++)
|
||||
{
|
||||
string name = programpaths[i].ToLower().Replace('/', '\\');
|
||||
if (name == windowName)
|
||||
if (programpaths[i].IsMatch(topProcessName, topWindowTitle))
|
||||
{
|
||||
if (DS4Form.autoProfileDebugLogLevel > 0)
|
||||
AppLogger.LogToGui($"DEBUG: Auto-Profile. Rule#{i+1} Path={programpaths[i].path} Title={programpaths[i].title}", false);
|
||||
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (proprofiles[j][i] != "(none)" && proprofiles[j][i] != Properties.Resources.noneProfile)
|
||||
{
|
||||
LoadTempProfile(j, proprofiles[j][i], true, Program.rootHub); // j is controller index, i is filename
|
||||
//if (LaunchProgram[j] != string.Empty) Process.Start(LaunchProgram[j]);
|
||||
newProfileName[j] = proprofiles[j][i]; // j is controller index, i is filename
|
||||
}
|
||||
}
|
||||
|
||||
if (turnOffTempProfiles[i])
|
||||
{
|
||||
turnOffTemp = true;
|
||||
if (btnStartStop.Text == Properties.Resources.StopText)
|
||||
{
|
||||
//autoProfilesTimer.Stop();
|
||||
//hotkeysTimer.Stop();
|
||||
ChangeAutoProfilesStatus(false);
|
||||
ChangeHotkeysStatus(false);
|
||||
|
||||
this.Invoke((System.Action)(() => {
|
||||
this.changingService = true;
|
||||
BtnStartStop_Clicked();
|
||||
}));
|
||||
|
||||
while (this.changingService)
|
||||
{
|
||||
Thread.SpinWait(500);
|
||||
}
|
||||
|
||||
this.Invoke((System.Action)(() =>
|
||||
{
|
||||
//hotkeysTimer.Start();
|
||||
ChangeHotkeysStatus(true);
|
||||
ChangeAutoProfilesStatus(true);
|
||||
//autoProfilesTimer.Start();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
tempProfileProgram = name;
|
||||
// Matching autoprofile rule found
|
||||
turnOffDS4WinApp = turnOffTempProfiles[i];
|
||||
matchingProgramPathItem = programpaths[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string windowName = GetTopWindowName().ToLower().Replace('/', '\\');
|
||||
if (tempProfileProgram != windowName)
|
||||
|
||||
if (matchingProgramPathItem != null)
|
||||
{
|
||||
tempProfileProgram = string.Empty;
|
||||
// Program match found. Check if the new profile is different than current profile of the controller. Load the new profile only if it is not already loaded.
|
||||
for (int j = 0; j < 4; j++)
|
||||
LoadProfile(j, false, Program.rootHub);
|
||||
{
|
||||
if (newProfileName[j] != String.Empty)
|
||||
{
|
||||
if ((Global.useTempProfile[j] && newProfileName[j] != Global.tempprofilename[j]) || (!Global.useTempProfile[j] && newProfileName[j] != Global.ProfilePath[j]))
|
||||
{
|
||||
if (DS4Form.autoProfileDebugLogLevel > 0)
|
||||
AppLogger.LogToGui($"DEBUG: Auto-Profile. LoadProfile Controller {j+1}={newProfileName[j]}", false);
|
||||
|
||||
LoadTempProfile(j, newProfileName[j], true, Program.rootHub); // j is controller index, i is filename
|
||||
//if (LaunchProgram[j] != string.Empty) Process.Start(LaunchProgram[j]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DS4Form.autoProfileDebugLogLevel > 0)
|
||||
AppLogger.LogToGui($"DEBUG: Auto-Profile. LoadProfile Controller {j + 1}={newProfileName[j]} (already loaded)", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (turnOffDS4WinApp)
|
||||
{
|
||||
turnOffTemp = true;
|
||||
if (btnStartStop.Text == Properties.Resources.StopText)
|
||||
{
|
||||
//autoProfilesTimer.Stop();
|
||||
//hotkeysTimer.Stop();
|
||||
ChangeAutoProfilesStatus(false);
|
||||
ChangeHotkeysStatus(false);
|
||||
|
||||
this.Invoke((System.Action)(() =>
|
||||
{
|
||||
this.changingService = true;
|
||||
BtnStartStop_Clicked();
|
||||
}));
|
||||
|
||||
while (this.changingService)
|
||||
{
|
||||
Thread.SpinWait(500);
|
||||
}
|
||||
|
||||
this.Invoke((System.Action)(() =>
|
||||
{
|
||||
//hotkeysTimer.Start();
|
||||
ChangeHotkeysStatus(true);
|
||||
ChangeAutoProfilesStatus(true);
|
||||
//autoProfilesTimer.Start();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
tempProfileProgram = matchingProgramPathItem;
|
||||
}
|
||||
else if (tempProfileProgram != null)
|
||||
{
|
||||
// The current active program doesn't match any of the programs in autoprofile path list.
|
||||
// Unload temp profile if controller is not using the default profile already.
|
||||
tempProfileProgram = null;
|
||||
for (int j = 0; j < 4; j++)
|
||||
{
|
||||
if (Global.useTempProfile[j])
|
||||
{
|
||||
if (DS4Form.autoProfileDebugLogLevel > 0)
|
||||
AppLogger.LogToGui($"DEBUG: Auto-Profile. RestoreProfile Controller {j + 1}={Global.ProfilePath[j]} (default)", false);
|
||||
|
||||
LoadProfile(j, false, Program.rootHub);
|
||||
}
|
||||
}
|
||||
|
||||
if (turnOffTemp)
|
||||
{
|
||||
@ -746,18 +865,25 @@ namespace DS4Windows.Forms
|
||||
doc.Load(appdatapath + "\\Auto Profiles.xml");
|
||||
XmlNodeList programslist = doc.SelectNodes("Programs/Program");
|
||||
foreach (XmlNode x in programslist)
|
||||
programpaths.Add(x.Attributes["path"].Value);
|
||||
programpaths.Add(new ProgramPathItem(x.Attributes["path"]?.Value, x.Attributes["title"]?.Value));
|
||||
|
||||
foreach (string s in programpaths)
|
||||
int nodeIdx=0;
|
||||
foreach (ProgramPathItem pathItem in programpaths)
|
||||
{
|
||||
XmlNode item;
|
||||
|
||||
nodeIdx++;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
proprofiles[i].Add(doc.SelectSingleNode("/Programs/Program[@path=\"" + s + "\"]"
|
||||
+ "/Controller" + (i + 1)).InnerText);
|
||||
item = doc.SelectSingleNode($"/Programs/Program[{nodeIdx}]/Controller{i+1}");
|
||||
if (item != null)
|
||||
proprofiles[i].Add(item.InnerText);
|
||||
else
|
||||
proprofiles[i].Add("(none)");
|
||||
}
|
||||
|
||||
XmlNode item = doc.SelectSingleNode("/Programs/Program[@path=\"" + s + "\"]"
|
||||
+ "/TurnOff");
|
||||
item = doc.SelectSingleNode($"/Programs/Program[{nodeIdx}]/TurnOff");
|
||||
|
||||
bool turnOff;
|
||||
if (item != null && bool.TryParse(item.InnerText, out turnOff))
|
||||
turnOffTempProfiles.Add(turnOff);
|
||||
@ -2701,4 +2827,78 @@ Properties.Resources.DS4Update, MessageBoxButtons.YesNo, MessageBoxIcon.Question
|
||||
FlashWhenLateAt = (int)Math.Round(nUDLatency.Value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Class to store autoprofile path and title data. Path and Title are pre-stored as lowercase versions (case insensitive search) to speed up IsMatch method in autoprofile timer calls.
|
||||
// AutoProfile thread monitors active processes and windows. Autoprofile search rule can define just a process path or both path and window title search keywords.
|
||||
// Keyword syntax: xxxx = exact matach, ^xxxx = match to beginning of path or title string. xxxx$ = match to end of string. *xxxx = contains in a string search
|
||||
//
|
||||
public class ProgramPathItem
|
||||
{
|
||||
public string path;
|
||||
public string title;
|
||||
private string path_lowercase;
|
||||
private string title_lowercase;
|
||||
|
||||
public ProgramPathItem(string pathStr, string titleStr)
|
||||
{
|
||||
// Initialize autoprofile search keywords (xxx_tolower). To improve performance the search keyword is pre-calculated in xxx_tolower variables,
|
||||
// so autoprofile timer thread doesn't have to create substrings/replace/tolower string instances every second over and over again.
|
||||
if (!string.IsNullOrEmpty(pathStr))
|
||||
{
|
||||
path = pathStr;
|
||||
path_lowercase = path.ToLower().Replace('/', '\\');
|
||||
|
||||
if (path.Length >= 2)
|
||||
{
|
||||
if (path[0] == '^') path_lowercase = path_lowercase.Substring(1);
|
||||
else if (path[path.Length - 1] == '$') path_lowercase = path_lowercase.Substring(0, path_lowercase.Length - 1);
|
||||
else if (path[0] == '*') path_lowercase = path_lowercase.Substring(1);
|
||||
}
|
||||
}
|
||||
else path = path_lowercase = String.Empty;
|
||||
|
||||
if (!string.IsNullOrEmpty(titleStr))
|
||||
{
|
||||
title = titleStr;
|
||||
title_lowercase = title.ToLower();
|
||||
|
||||
if (title.Length >= 2)
|
||||
{
|
||||
if (title[0] == '^') title_lowercase = title_lowercase.Substring(1);
|
||||
else if (title[title.Length - 1] == '$') title_lowercase = title_lowercase.Substring(0, title_lowercase.Length - 1);
|
||||
else if (title[0] == '*') title_lowercase = title_lowercase.Substring(1);
|
||||
}
|
||||
}
|
||||
else title = title_lowercase = String.Empty;
|
||||
}
|
||||
|
||||
public bool IsMatch(string searchPath, string searchTitle)
|
||||
{
|
||||
bool bPathMatched = true;
|
||||
bool bTitleMwatched = true;
|
||||
|
||||
if (!String.IsNullOrEmpty(path_lowercase))
|
||||
{
|
||||
bPathMatched = (path_lowercase == searchPath
|
||||
|| (path[0] == '^' && searchPath.StartsWith(path_lowercase))
|
||||
|| (path[path.Length - 1] == '$' && searchPath.EndsWith(path_lowercase))
|
||||
|| (path[0] == '*' && searchPath.Contains(path_lowercase))
|
||||
);
|
||||
}
|
||||
|
||||
if (bPathMatched && !String.IsNullOrEmpty(title_lowercase))
|
||||
{
|
||||
bTitleMwatched = (title_lowercase == searchTitle
|
||||
|| (title[0] == '^' && searchTitle.StartsWith(title_lowercase))
|
||||
|| (title[title.Length - 1] == '$' && searchTitle.EndsWith(title_lowercase))
|
||||
|| (title[0] == '*' && searchTitle.Contains(title_lowercase))
|
||||
);
|
||||
}
|
||||
|
||||
// If both path and title defined in autoprofile entry then do AND condition (ie. both path and title should match)
|
||||
return bPathMatched && bTitleMwatched;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
@ -631,4 +631,58 @@
|
||||
<data name="lbID.Text" xml:space="preserve">
|
||||
<value>ID</value>
|
||||
</data>
|
||||
<data name="lbPad2.Text" xml:space="preserve">
|
||||
<value>Ohjain 2</value>
|
||||
</data>
|
||||
<data name="lbPad3.Text" xml:space="preserve">
|
||||
<value>Ohjain 3</value>
|
||||
</data>
|
||||
<data name="lbPad4.Text" xml:space="preserve">
|
||||
<value>Ohjain 4</value>
|
||||
</data>
|
||||
<data name="discon1toolStripMenuItem.Text" xml:space="preserve">
|
||||
<value>Katkaise yhteys ohjain 1</value>
|
||||
</data>
|
||||
<data name="discon2ToolStripMenuItem.Text" xml:space="preserve">
|
||||
<value>Katkaise yhteys ohjain 2</value>
|
||||
</data>
|
||||
<data name="discon3ToolStripMenuItem.Text" xml:space="preserve">
|
||||
<value>Katkaise yhteys ohjain 3</value>
|
||||
</data>
|
||||
<data name="discon4ToolStripMenuItem.Text" xml:space="preserve">
|
||||
<value>Katkaise yhteys ohjain 4</value>
|
||||
</data>
|
||||
<data name="lbLinkProfile.Text" xml:space="preserve">
|
||||
<value>Linkitä profiili/ID</value>
|
||||
</data>
|
||||
<data name="mintoTaskCheckBox.Text" xml:space="preserve">
|
||||
<value>Minimoi tehtäväpalkkiin</value>
|
||||
</data>
|
||||
<data name="openProgramFolderToolStripMenuItem.Text" xml:space="preserve">
|
||||
<value>Avaa ohjelmakansio</value>
|
||||
</data>
|
||||
<data name="label2.Text" xml:space="preserve">
|
||||
<value>Portti</value>
|
||||
</data>
|
||||
<data name="runStartProgRadio.Text" xml:space="preserve">
|
||||
<value>Ohjelmana</value>
|
||||
</data>
|
||||
<data name="label1.Text" xml:space="preserve">
|
||||
<value>Avaustapa:</value>
|
||||
</data>
|
||||
<data name="ckUdpServ.Text" xml:space="preserve">
|
||||
<value>UDP palvelin</value>
|
||||
</data>
|
||||
<data name="runStartTaskRadio.Text" xml:space="preserve">
|
||||
<value>Ajoitettuna tehtävänä</value>
|
||||
</data>
|
||||
<data name="cBCustomSteam.Text" xml:space="preserve">
|
||||
<value>Käytä vaihtoehtoista Steam-kansiota</value>
|
||||
</data>
|
||||
<data name="cBUseWhiteIcon.Text" xml:space="preserve">
|
||||
<value>Valkoinen DS4Windows-kuvake</value>
|
||||
</data>
|
||||
<data name="disconToolStripMenuItem.Text" xml:space="preserve">
|
||||
<value>Yhteyskatkaisun menu</value>
|
||||
</data>
|
||||
</root>
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
@ -126,4 +126,7 @@
|
||||
<data name="tBProfile.Text" xml:space="preserve">
|
||||
<value><Uusi nimi tähän></value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>Kirjoita uuden profiilin nimi</value>
|
||||
</data>
|
||||
</root>
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
@ -640,4 +640,19 @@
|
||||
<data name="tPDeadzone.Text" xml:space="preserve">
|
||||
<value>Deadzone</value>
|
||||
</data>
|
||||
<data name="lblSteeringWheelEmulationRange.Text" xml:space="preserve">
|
||||
<value>Rattiohjaimen kääntösäde</value>
|
||||
</data>
|
||||
<data name="lblSteeringWheelEmulationAxis.Text" xml:space="preserve">
|
||||
<value>Rattiohjaimen akseli</value>
|
||||
</data>
|
||||
<data name="lbL2TrackS.Text" xml:space="preserve">
|
||||
<value>Ohjaimen lukemat</value>
|
||||
</data>
|
||||
<data name="btnSteeringWheelEmulationCalibrate.Text" xml:space="preserve">
|
||||
<value>Kalibroi...</value>
|
||||
</data>
|
||||
<data name="rBTPMouse.Text" xml:space="preserve">
|
||||
<value>Käytä hiirenä</value>
|
||||
</data>
|
||||
</root>
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
@ -201,4 +201,7 @@
|
||||
<data name="lbUnloadTipKey.Text" xml:space="preserve">
|
||||
<value>Kytke pois painamalla</value>
|
||||
</data>
|
||||
<data name="cbProfileAutoUntrigger.Text" xml:space="preserve">
|
||||
<value>Poiskytkentä liipaisimen vapautuksella</value>
|
||||
</data>
|
||||
</root>
|
58
DS4Windows/DS4Forms/WinProgs.Designer.cs
generated
58
DS4Windows/DS4Forms/WinProgs.Designer.cs
generated
@ -31,7 +31,6 @@
|
||||
this.components = new System.ComponentModel.Container();
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WinProgs));
|
||||
this.bnAddPrograms = new System.Windows.Forms.Button();
|
||||
this.lBProgramPath = new System.Windows.Forms.Label();
|
||||
this.cBProfile1 = new System.Windows.Forms.ComboBox();
|
||||
this.cBProfile2 = new System.Windows.Forms.ComboBox();
|
||||
this.cBProfile3 = new System.Windows.Forms.ComboBox();
|
||||
@ -47,6 +46,7 @@
|
||||
this.lVPrograms = new System.Windows.Forms.ListView();
|
||||
this.nameHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.PathHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.WndTitleHeader = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
this.pBProfilesTip = new System.Windows.Forms.Label();
|
||||
this.bnHideUnchecked = new System.Windows.Forms.Button();
|
||||
this.cMSPrograms = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
@ -56,6 +56,10 @@
|
||||
this.addDirectoryToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.browseForOtherProgramsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.cBTurnOffDS4W = new System.Windows.Forms.CheckBox();
|
||||
this.cBAutoProfileDebugLog = new System.Windows.Forms.CheckBox();
|
||||
this.tBPath = new System.Windows.Forms.TextBox();
|
||||
this.tBWndTitle = new System.Windows.Forms.TextBox();
|
||||
this.lBDividerLine1 = new System.Windows.Forms.Label();
|
||||
this.cMSPrograms.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
@ -66,12 +70,6 @@
|
||||
this.bnAddPrograms.UseVisualStyleBackColor = true;
|
||||
this.bnAddPrograms.Click += new System.EventHandler(this.bnAddPrograms_Click);
|
||||
//
|
||||
// lBProgramPath
|
||||
//
|
||||
resources.ApplyResources(this.lBProgramPath, "lBProgramPath");
|
||||
this.lBProgramPath.Name = "lBProgramPath";
|
||||
this.lBProgramPath.TextChanged += new System.EventHandler(this.lBProgramPath_TextChanged);
|
||||
//
|
||||
// cBProfile1
|
||||
//
|
||||
resources.ApplyResources(this.cBProfile1, "cBProfile1");
|
||||
@ -154,7 +152,8 @@
|
||||
this.lVPrograms.CheckBoxes = true;
|
||||
this.lVPrograms.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
|
||||
this.nameHeader,
|
||||
this.PathHeader});
|
||||
this.PathHeader,
|
||||
this.WndTitleHeader});
|
||||
this.lVPrograms.FullRowSelect = true;
|
||||
this.lVPrograms.HideSelection = false;
|
||||
this.lVPrograms.LargeImageList = this.iLIcons;
|
||||
@ -164,7 +163,6 @@
|
||||
this.lVPrograms.SmallImageList = this.iLIcons;
|
||||
this.lVPrograms.UseCompatibleStateImageBehavior = false;
|
||||
this.lVPrograms.View = System.Windows.Forms.View.Details;
|
||||
this.lVPrograms.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.listView1_ItemCheck);
|
||||
this.lVPrograms.SelectedIndexChanged += new System.EventHandler(this.lBProgramPath_SelectedIndexChanged);
|
||||
//
|
||||
// nameHeader
|
||||
@ -175,6 +173,10 @@
|
||||
//
|
||||
resources.ApplyResources(this.PathHeader, "PathHeader");
|
||||
//
|
||||
// WndTitleHeader
|
||||
//
|
||||
resources.ApplyResources(this.WndTitleHeader, "WndTitleHeader");
|
||||
//
|
||||
// pBProfilesTip
|
||||
//
|
||||
resources.ApplyResources(this.pBProfilesTip, "pBProfilesTip");
|
||||
@ -239,13 +241,42 @@
|
||||
this.cBTurnOffDS4W.UseVisualStyleBackColor = true;
|
||||
this.cBTurnOffDS4W.CheckedChanged += new System.EventHandler(this.cBTurnOffDS4W_CheckedChanged);
|
||||
//
|
||||
// cBAutoProfileDebugLog
|
||||
//
|
||||
resources.ApplyResources(this.cBAutoProfileDebugLog, "cBAutoProfileDebugLog");
|
||||
this.cBAutoProfileDebugLog.Name = "cBAutoProfileDebugLog";
|
||||
this.cBAutoProfileDebugLog.UseVisualStyleBackColor = true;
|
||||
this.cBAutoProfileDebugLog.CheckedChanged += new System.EventHandler(this.cBAutoProfileDebugLog_CheckedChanged);
|
||||
//
|
||||
// tBPath
|
||||
//
|
||||
resources.ApplyResources(this.tBPath, "tBPath");
|
||||
this.tBPath.Name = "tBPath";
|
||||
this.tBPath.TextChanged += new System.EventHandler(this.tBPath_TextChanged);
|
||||
//
|
||||
// tBWndTitle
|
||||
//
|
||||
resources.ApplyResources(this.tBWndTitle, "tBWndTitle");
|
||||
this.tBWndTitle.Name = "tBWndTitle";
|
||||
this.tBWndTitle.TextChanged += new System.EventHandler(this.tBPath_TextChanged);
|
||||
//
|
||||
// lBDividerLine1
|
||||
//
|
||||
resources.ApplyResources(this.lBDividerLine1, "lBDividerLine1");
|
||||
this.lBDividerLine1.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
|
||||
this.lBDividerLine1.Name = "lBDividerLine1";
|
||||
//
|
||||
// WinProgs
|
||||
//
|
||||
resources.ApplyResources(this, "$this");
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.Controls.Add(this.cBTurnOffDS4W);
|
||||
this.Controls.Add(this.pBProfilesTip);
|
||||
this.Controls.Add(this.lBDividerLine1);
|
||||
this.Controls.Add(this.tBWndTitle);
|
||||
this.Controls.Add(this.tBPath);
|
||||
this.Controls.Add(this.cBAutoProfileDebugLog);
|
||||
this.Controls.Add(this.cBTurnOffDS4W);
|
||||
this.Controls.Add(this.bnHideUnchecked);
|
||||
this.Controls.Add(this.bnAddPrograms);
|
||||
this.Controls.Add(this.lVPrograms);
|
||||
@ -257,7 +288,6 @@
|
||||
this.Controls.Add(this.cBProfile3);
|
||||
this.Controls.Add(this.cBProfile2);
|
||||
this.Controls.Add(this.cBProfile1);
|
||||
this.Controls.Add(this.lBProgramPath);
|
||||
this.Controls.Add(this.bnDelete);
|
||||
this.Controls.Add(this.bnSave);
|
||||
this.Name = "WinProgs";
|
||||
@ -270,7 +300,6 @@
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Button bnAddPrograms;
|
||||
private System.Windows.Forms.Label lBProgramPath;
|
||||
private System.Windows.Forms.ComboBox cBProfile1;
|
||||
private System.Windows.Forms.ComboBox cBProfile2;
|
||||
private System.Windows.Forms.ComboBox cBProfile3;
|
||||
@ -295,5 +324,10 @@
|
||||
private System.Windows.Forms.ToolStripMenuItem browseForOtherProgramsToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem addDirectoryToolStripMenuItem;
|
||||
private System.Windows.Forms.CheckBox cBTurnOffDS4W;
|
||||
private System.Windows.Forms.CheckBox cBAutoProfileDebugLog;
|
||||
private System.Windows.Forms.ColumnHeader WndTitleHeader;
|
||||
private System.Windows.Forms.TextBox tBPath;
|
||||
private System.Windows.Forms.TextBox tBWndTitle;
|
||||
private System.Windows.Forms.Label lBDividerLine1;
|
||||
}
|
||||
}
|
@ -16,14 +16,13 @@ namespace DS4Windows.Forms
|
||||
{
|
||||
public partial class WinProgs : Form
|
||||
{
|
||||
ToolTip tp = new ToolTip();
|
||||
ComboBox[] cbs;
|
||||
public DS4Form form;
|
||||
//C:\ProgramData\Microsoft\Windows\Start Menu\Programs
|
||||
string steamgamesdir, origingamesdir;
|
||||
protected String m_Profile = Global.appdatapath + "\\Auto Profiles.xml";
|
||||
protected XmlDocument m_Xdoc = new XmlDocument();
|
||||
List<string> programpaths = new List<string>();
|
||||
|
||||
ProgramPathItem selectedProgramPathItem = null;
|
||||
List<string> lodsf = new List<string>();
|
||||
bool appsloaded = false;
|
||||
public const string steamCommx86Loc = @"C:\Program Files (x86)\Steam\steamapps\common";
|
||||
@ -33,7 +32,9 @@ namespace DS4Windows.Forms
|
||||
|
||||
public WinProgs(string[] oc, DS4Form main)
|
||||
{
|
||||
ToolTip tp = new ToolTip();
|
||||
InitializeComponent();
|
||||
|
||||
openProgram.Filter = Properties.Resources.Programs+"|*.exe|" + Properties.Resources.Shortcuts + "|*.lnk";
|
||||
form = main;
|
||||
cbs = new ComboBox[4] { cBProfile1, cBProfile2, cBProfile3, cBProfile4 };
|
||||
@ -44,6 +45,10 @@ namespace DS4Windows.Forms
|
||||
cbs[i].SelectedIndex = cbs[i].Items.Count - 1;
|
||||
}
|
||||
|
||||
tp.SetToolTip(cBAutoProfileDebugLog, Properties.Resources.ShowAutoProfileDebugLogTip);
|
||||
tp.SetToolTip(tBPath, Properties.Resources.AutoProfilePathAndWindowTitleEditTip);
|
||||
tp.SetToolTip(tBWndTitle, Properties.Resources.AutoProfilePathAndWindowTitleEditTip);
|
||||
|
||||
if (!File.Exists(Global.appdatapath + @"\Auto Profiles.xml"))
|
||||
Create();
|
||||
|
||||
@ -64,6 +69,10 @@ namespace DS4Windows.Forms
|
||||
origingamesdir = originLoc;
|
||||
else
|
||||
cMSPrograms.Items.Remove(addOriginGamesToolStripMenuItem);
|
||||
|
||||
cBAutoProfileDebugLog.Checked = (DS4Form.autoProfileDebugLogLevel > 0);
|
||||
selectedProgramPathItem = null;
|
||||
UpdateProfileComboListValues(null);
|
||||
}
|
||||
|
||||
public bool Create()
|
||||
@ -73,19 +82,20 @@ namespace DS4Windows.Forms
|
||||
try
|
||||
{
|
||||
XmlNode Node;
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
Node = m_Xdoc.CreateXmlDeclaration("1.0", "utf-8", String.Empty);
|
||||
m_Xdoc.AppendChild(Node);
|
||||
Node = doc.CreateXmlDeclaration("1.0", "utf-8", String.Empty);
|
||||
doc.AppendChild(Node);
|
||||
|
||||
Node = m_Xdoc.CreateComment(String.Format(" Auto-Profile Configuration Data. {0} ", DateTime.Now));
|
||||
m_Xdoc.AppendChild(Node);
|
||||
Node = doc.CreateComment(String.Format(" Auto-Profile Configuration Data. {0} ", DateTime.Now));
|
||||
doc.AppendChild(Node);
|
||||
|
||||
Node = m_Xdoc.CreateWhitespace("\r\n");
|
||||
m_Xdoc.AppendChild(Node);
|
||||
Node = doc.CreateWhitespace("\r\n");
|
||||
doc.AppendChild(Node);
|
||||
|
||||
Node = m_Xdoc.CreateNode(XmlNodeType.Element, "Programs", "");
|
||||
m_Xdoc.AppendChild(Node);
|
||||
m_Xdoc.Save(m_Profile);
|
||||
Node = doc.CreateNode(XmlNodeType.Element, "Programs", "");
|
||||
doc.AppendChild(Node);
|
||||
doc.Save(m_Profile);
|
||||
}
|
||||
catch { Saved = false; }
|
||||
|
||||
@ -101,38 +111,59 @@ namespace DS4Windows.Forms
|
||||
|
||||
public void LoadP()
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
programpaths.Clear();
|
||||
if (!File.Exists(Global.appdatapath + "\\Auto Profiles.xml"))
|
||||
return;
|
||||
|
||||
doc.Load(Global.appdatapath + "\\Auto Profiles.xml");
|
||||
XmlNodeList programslist = doc.SelectNodes("Programs/Program");
|
||||
foreach (XmlNode x in programslist)
|
||||
programpaths.Add(x.Attributes["path"].Value);
|
||||
|
||||
lVPrograms.BeginUpdate();
|
||||
int index = 0;
|
||||
foreach (string st in programpaths)
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrEmpty(st))
|
||||
XmlDocument doc = new XmlDocument();
|
||||
|
||||
iLIcons.Images.Clear();
|
||||
if (!File.Exists(Global.appdatapath + "\\Auto Profiles.xml"))
|
||||
return;
|
||||
|
||||
doc.Load(Global.appdatapath + "\\Auto Profiles.xml");
|
||||
XmlNodeList programslist = doc.SelectNodes("Programs/Program");
|
||||
|
||||
int index;
|
||||
ListViewItem lvi;
|
||||
string progPath, progTitle;
|
||||
|
||||
lVPrograms.BeginUpdate();
|
||||
foreach (XmlNode progNode in programslist)
|
||||
{
|
||||
if (File.Exists(st))
|
||||
progPath = progNode.Attributes["path"]?.Value;
|
||||
progTitle = progNode.Attributes["title"]?.Value;
|
||||
|
||||
if (!string.IsNullOrEmpty(progPath))
|
||||
{
|
||||
iLIcons.Images.Add(Icon.ExtractAssociatedIcon(st));
|
||||
index = iLIcons.Images.IndexOfKey(progPath);
|
||||
if (index < 0 && File.Exists(progPath))
|
||||
{
|
||||
iLIcons.Images.Add(progPath, Icon.ExtractAssociatedIcon(progPath));
|
||||
index = iLIcons.Images.Count - 1;
|
||||
}
|
||||
|
||||
if(index >= 0)
|
||||
lvi = new ListViewItem(Path.GetFileNameWithoutExtension(progPath), index);
|
||||
else
|
||||
lvi = new ListViewItem(Path.GetFileNameWithoutExtension(progPath));
|
||||
|
||||
lvi.Checked = true;
|
||||
lvi.SubItems.Add(progPath);
|
||||
if (!String.IsNullOrEmpty(progTitle))
|
||||
lvi.SubItems.Add(progTitle);
|
||||
|
||||
lVPrograms.Items.Add(lvi);
|
||||
}
|
||||
|
||||
ListViewItem lvi = new ListViewItem(Path.GetFileNameWithoutExtension(st), index);
|
||||
lvi.Checked = true;
|
||||
lvi.ToolTipText = st;
|
||||
lvi.SubItems.Add(st);
|
||||
lVPrograms.Items.Add(lvi);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
|
||||
lVPrograms.EndUpdate();
|
||||
catch (Exception e)
|
||||
{
|
||||
// Eat all exceptions while reading auto-profile file because we don't want to crash DS4Win app just because there are some permissions or other issues with the file
|
||||
AppLogger.LogToGui($"ERROR. Auto-profile XML file {Global.appdatapath}\\Auto Profiles.xml reading failed. {e.Message}", true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
lVPrograms.EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
private void GetApps(string path)
|
||||
@ -179,168 +210,314 @@ namespace DS4Windows.Forms
|
||||
appsloaded = true;
|
||||
}
|
||||
|
||||
void AddLoadedApps()
|
||||
int AddLoadedApps(bool autoremoveSetupApps = true)
|
||||
{
|
||||
int numOfAppsAdded = 0;
|
||||
|
||||
if (appsloaded)
|
||||
{
|
||||
bnAddPrograms.Text = Properties.Resources.AddingToList;
|
||||
for (int i = lodsf.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (lodsf[i].Contains("etup") || lodsf[i].Contains("dotnet") || lodsf[i].Contains("SETUP")
|
||||
|| lodsf[i].Contains("edist") || lodsf[i].Contains("nstall") || String.IsNullOrEmpty(lodsf[i]))
|
||||
lodsf.RemoveAt(i);
|
||||
}
|
||||
|
||||
for (int i = lodsf.Count - 1; i >= 0; i--)
|
||||
if (autoremoveSetupApps)
|
||||
{
|
||||
for (int j = programpaths.Count - 1; j >= 0; j--)
|
||||
for (int i = lodsf.Count - 1; i >= 0; i--)
|
||||
{
|
||||
if (lodsf[i].ToLower().Replace('/', '\\') == programpaths[j].ToLower().Replace('/', '\\'))
|
||||
if (lodsf[i].Contains("etup") || lodsf[i].Contains("dotnet") || lodsf[i].Contains("SETUP")
|
||||
|| lodsf[i].Contains("edist") || lodsf[i].Contains("nstall") || String.IsNullOrEmpty(lodsf[i]))
|
||||
lodsf.RemoveAt(i);
|
||||
}
|
||||
}
|
||||
|
||||
lVPrograms.BeginUpdate();
|
||||
foreach (string st in lodsf)
|
||||
{
|
||||
if (File.Exists(st))
|
||||
// Remove existing program entries from a list of new app paths (no need to add the same path twice)
|
||||
for (int i = lodsf.Count - 1; i >= 0; i--)
|
||||
{
|
||||
int index = programpaths.IndexOf(st);
|
||||
iLIcons.Images.Add(Icon.ExtractAssociatedIcon(st));
|
||||
ListViewItem lvi = new ListViewItem(Path.GetFileNameWithoutExtension(st), iLIcons.Images.Count + index);
|
||||
lvi.SubItems.Add(st);
|
||||
lvi.ToolTipText = st;
|
||||
lVPrograms.Items.Add(lvi);
|
||||
for (int j = 0; j < lVPrograms.Items.Count; j++)
|
||||
{
|
||||
if(string.Equals(lVPrograms.Items[j].SubItems[1].Text, lodsf[i], StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
lodsf.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
lVPrograms.EndUpdate();
|
||||
|
||||
bnAddPrograms.Text = Properties.Resources.AddPrograms;
|
||||
bnAddPrograms.Enabled = true;
|
||||
appsloaded = false;
|
||||
try
|
||||
{
|
||||
ListViewItem lvi;
|
||||
int index;
|
||||
|
||||
lVPrograms.BeginUpdate();
|
||||
foreach (string st in lodsf)
|
||||
{
|
||||
if (File.Exists(st))
|
||||
{
|
||||
index = iLIcons.Images.IndexOfKey(st);
|
||||
if (index < 0)
|
||||
{
|
||||
iLIcons.Images.Add(st, Icon.ExtractAssociatedIcon(st));
|
||||
index = iLIcons.Images.Count - 1;
|
||||
}
|
||||
|
||||
if(index >= 0)
|
||||
lvi = new ListViewItem(Path.GetFileNameWithoutExtension(st), index);
|
||||
else
|
||||
lvi = new ListViewItem(Path.GetFileNameWithoutExtension(st));
|
||||
|
||||
lvi.SubItems.Add(st);
|
||||
lvi.ToolTipText = st;
|
||||
lVPrograms.Items.Add(lvi);
|
||||
numOfAppsAdded++;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Eat all exceptions while processing added apps because we don't want to crash DS4Win app just because there are some permissions or other issues with the file
|
||||
AppLogger.LogToGui($"ERROR. Failed to add selected applications to an auto-profile list. {e.Message}", true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
lVPrograms.EndUpdate();
|
||||
|
||||
bnAddPrograms.Text = Properties.Resources.AddPrograms;
|
||||
bnAddPrograms.Enabled = true;
|
||||
appsloaded = false;
|
||||
}
|
||||
}
|
||||
|
||||
return numOfAppsAdded;
|
||||
}
|
||||
|
||||
public void Save(string name)
|
||||
private XmlNode FindProgramXMLItem(XmlDocument doc, string programPath, string windowTitle)
|
||||
{
|
||||
m_Xdoc.Load(m_Profile);
|
||||
// Try to find a specified programPath+windowTitle program entry from an autoprofile XML file list
|
||||
foreach (XmlNode item in doc.SelectNodes("/Programs/Program"))
|
||||
{
|
||||
XmlAttribute xmlAttrTitle = item.Attributes["title"];
|
||||
if(item.Attributes["path"].InnerText == programPath)
|
||||
{
|
||||
if (String.IsNullOrEmpty(windowTitle) && (xmlAttrTitle == null || String.IsNullOrEmpty(xmlAttrTitle.InnerText)))
|
||||
return item;
|
||||
else if (!String.IsNullOrEmpty(windowTitle) && xmlAttrTitle != null && xmlAttrTitle.InnerText == windowTitle)
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Save(ProgramPathItem progPathItem)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
XmlNode Node;
|
||||
string newPath, newTitle;
|
||||
|
||||
Node = m_Xdoc.CreateComment(String.Format(" Auto-Profile Configuration Data. {0} ", DateTime.Now));
|
||||
foreach (XmlNode node in m_Xdoc.SelectNodes("//comment()"))
|
||||
node.ParentNode.ReplaceChild(Node, node);
|
||||
newPath = tBPath.Text.Trim();
|
||||
newTitle = tBWndTitle.Text;
|
||||
|
||||
Node = m_Xdoc.SelectSingleNode("Programs");
|
||||
string programname;
|
||||
programname = Path.GetFileNameWithoutExtension(name);
|
||||
XmlElement el = m_Xdoc.CreateElement("Program");
|
||||
el.SetAttribute("path", name);
|
||||
el.AppendChild(m_Xdoc.CreateElement("Controller1")).InnerText = cBProfile1.Text;
|
||||
el.AppendChild(m_Xdoc.CreateElement("Controller2")).InnerText = cBProfile2.Text;
|
||||
el.AppendChild(m_Xdoc.CreateElement("Controller3")).InnerText = cBProfile3.Text;
|
||||
el.AppendChild(m_Xdoc.CreateElement("Controller4")).InnerText = cBProfile4.Text;
|
||||
el.AppendChild(m_Xdoc.CreateElement("TurnOff")).InnerText = cBTurnOffDS4W.Checked.ToString();
|
||||
if (progPathItem == null || String.IsNullOrEmpty(progPathItem.path) || String.IsNullOrEmpty(newPath))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
XmlNode oldxmlprocess = m_Xdoc.SelectSingleNode("/Programs/Program[@path=\"" + lBProgramPath.Text + "\"]");
|
||||
Node.ReplaceChild(el, oldxmlprocess);
|
||||
doc.Load(m_Profile);
|
||||
Node = doc.CreateComment(String.Format(" Auto-Profile Configuration Data. {0} ", DateTime.Now));
|
||||
foreach (XmlNode node in doc.SelectNodes("//comment()"))
|
||||
node.ParentNode.ReplaceChild(Node, node);
|
||||
|
||||
// Find the existing XML program entry using the old path and title value as a search key and replace it with new path and title values (or add a new entry if this was a new program path)
|
||||
XmlNode oldxmlprocess = FindProgramXMLItem(doc, progPathItem.path, progPathItem.title);
|
||||
Node = doc.SelectSingleNode("Programs");
|
||||
|
||||
XmlElement el = doc.CreateElement("Program");
|
||||
el.SetAttribute("path", newPath);
|
||||
if (!String.IsNullOrEmpty(newTitle))
|
||||
el.SetAttribute("title", newTitle);
|
||||
|
||||
el.AppendChild(doc.CreateElement("Controller1")).InnerText = cBProfile1.Text;
|
||||
el.AppendChild(doc.CreateElement("Controller2")).InnerText = cBProfile2.Text;
|
||||
el.AppendChild(doc.CreateElement("Controller3")).InnerText = cBProfile3.Text;
|
||||
el.AppendChild(doc.CreateElement("Controller4")).InnerText = cBProfile4.Text;
|
||||
el.AppendChild(doc.CreateElement("TurnOff")).InnerText = cBTurnOffDS4W.Checked.ToString();
|
||||
|
||||
if (oldxmlprocess != null)
|
||||
Node.ReplaceChild(el, oldxmlprocess);
|
||||
else
|
||||
Node.AppendChild(el);
|
||||
|
||||
doc.AppendChild(Node);
|
||||
doc.Save(m_Profile);
|
||||
|
||||
if(selectedProgramPathItem != null)
|
||||
{
|
||||
selectedProgramPathItem.path = newPath;
|
||||
selectedProgramPathItem.title = newTitle;
|
||||
}
|
||||
|
||||
if (lVPrograms.SelectedItems.Count > 0)
|
||||
{
|
||||
lVPrograms.SelectedItems[0].Checked = true;
|
||||
|
||||
lVPrograms.SelectedItems[0].SubItems[0].Text = Path.GetFileNameWithoutExtension(newPath);
|
||||
lVPrograms.SelectedItems[0].SubItems[1].Text = newPath;
|
||||
if (lVPrograms.SelectedItems[0].SubItems.Count < 3)
|
||||
if(!String.IsNullOrEmpty(newTitle))
|
||||
lVPrograms.SelectedItems[0].SubItems.Add(newTitle);
|
||||
else
|
||||
lVPrograms.SelectedItems[0].SubItems[2].Text = newTitle;
|
||||
|
||||
if (!String.IsNullOrEmpty(newTitle))
|
||||
lVPrograms.SelectedItems[0].ToolTipText = $"{newPath} [{newTitle}]";
|
||||
else
|
||||
lVPrograms.SelectedItems[0].ToolTipText = newPath;
|
||||
}
|
||||
|
||||
form.LoadP();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Eat all exceptions while writing auto-profile file because we don't want to crash DS4Win app just because there are some permissions or other issues with the file
|
||||
AppLogger.LogToGui($"ERROR. Auto-profile XML file {Global.appdatapath}\\Auto Profiles.xml writing failed. {e.Message}", true);
|
||||
}
|
||||
catch { Node.AppendChild(el); }
|
||||
|
||||
m_Xdoc.AppendChild(Node);
|
||||
m_Xdoc.Save(m_Profile);
|
||||
|
||||
if (lVPrograms.SelectedItems.Count > 0)
|
||||
lVPrograms.SelectedItems[0].Checked = true;
|
||||
|
||||
form.LoadP();
|
||||
}
|
||||
|
||||
public void LoadP(string name)
|
||||
public void LoadP(ProgramPathItem loadProgPathItem)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(m_Profile);
|
||||
XmlNodeList programs = doc.SelectNodes("Programs/Program");
|
||||
XmlNode Item = doc.SelectSingleNode("/Programs/Program[@path=\"" + name + "\"]");
|
||||
if (Item != null)
|
||||
if (loadProgPathItem == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(m_Profile);
|
||||
|
||||
XmlNode programItem = FindProgramXMLItem(doc, loadProgPathItem.path, loadProgPathItem.title);
|
||||
if (programItem != null)
|
||||
{
|
||||
Item = doc.SelectSingleNode("/Programs/Program[@path=\"" + name + "\"]" + "/Controller" + (i + 1));
|
||||
if (Item != null)
|
||||
XmlNode profileItem;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < cbs[i].Items.Count; j++)
|
||||
profileItem = programItem.SelectSingleNode($".//Controller{i + 1}");
|
||||
if (profileItem != null)
|
||||
{
|
||||
if (cbs[i].Items[j].ToString() == Item.InnerText)
|
||||
for (int j = 0; j < cbs[i].Items.Count; j++)
|
||||
{
|
||||
cbs[i].SelectedIndex = j;
|
||||
bnSave.Enabled = false;
|
||||
break;
|
||||
if (cbs[i].Items[j].ToString() == profileItem.InnerText)
|
||||
{
|
||||
cbs[i].SelectedIndex = j;
|
||||
break;
|
||||
}
|
||||
else
|
||||
cbs[i].SelectedIndex = cbs[i].Items.Count - 1;
|
||||
}
|
||||
else
|
||||
cbs[i].SelectedIndex = cbs[i].Items.Count - 1;
|
||||
}
|
||||
else
|
||||
cbs[i].SelectedIndex = cbs[i].Items.Count - 1;
|
||||
}
|
||||
|
||||
bool turnOff;
|
||||
profileItem = programItem.SelectSingleNode($".//TurnOff");
|
||||
if (profileItem != null && bool.TryParse(profileItem.InnerText, out turnOff))
|
||||
{
|
||||
cBTurnOffDS4W.Checked = turnOff;
|
||||
}
|
||||
else
|
||||
cbs[i].SelectedIndex = cbs[i].Items.Count - 1;
|
||||
cBTurnOffDS4W.Checked = false;
|
||||
}
|
||||
|
||||
Item = doc.SelectSingleNode("/Programs/Program[@path=\"" + name + "\"]" + "/TurnOff");
|
||||
bool turnOff;
|
||||
if (Item != null && bool.TryParse(Item.InnerText, out turnOff))
|
||||
tBPath.Text = loadProgPathItem.path;
|
||||
tBWndTitle.Text = loadProgPathItem.title;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Eat all exceptions while reading auto-profile file because we don't want to crash DS4Win app just because there are some permissions or other issues with the file
|
||||
AppLogger.LogToGui($"ERROR. Failed to read {loadProgPathItem.path} {loadProgPathItem.title} XML entry. {e.Message}", true);
|
||||
}
|
||||
bnSave.Enabled = false;
|
||||
}
|
||||
|
||||
public void RemoveP(ProgramPathItem removeProgPathItem, bool uncheck)
|
||||
{
|
||||
bnSave.Enabled = false;
|
||||
|
||||
if (removeProgPathItem == null)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(m_Profile);
|
||||
|
||||
XmlNode programItem = FindProgramXMLItem(doc, removeProgPathItem.path, removeProgPathItem.title);
|
||||
if (programItem != null)
|
||||
{
|
||||
cBTurnOffDS4W.Checked = turnOff;
|
||||
XmlNode parentNode = programItem.ParentNode;
|
||||
if (parentNode != null)
|
||||
{
|
||||
parentNode.RemoveChild(programItem);
|
||||
doc.AppendChild(parentNode);
|
||||
doc.Save(m_Profile);
|
||||
}
|
||||
}
|
||||
else
|
||||
cBTurnOffDS4W.Checked = false;
|
||||
if (lVPrograms.SelectedItems.Count > 0 && uncheck)
|
||||
lVPrograms.SelectedItems[0].Checked = false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// Eat all exceptions while updating auto-profile file because we don't want to crash DS4Win app just because there are some permissions or other issues with the file
|
||||
AppLogger.LogToGui($"ERROR. Failed to remove {removeProgPathItem.path} {removeProgPathItem.title} XML entry. {e.Message}", true);
|
||||
}
|
||||
|
||||
UpdateProfileComboListValues(null);
|
||||
}
|
||||
|
||||
private void UpdateProfileComboListValues(ProgramPathItem progItem)
|
||||
{
|
||||
if (progItem != null)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
cbs[i].Enabled = true;
|
||||
|
||||
tBPath.Enabled = tBWndTitle.Enabled = cBTurnOffDS4W.Enabled = true;
|
||||
LoadP(progItem);
|
||||
bnDelete.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
int last = cbs[0].Items.Count - 1;
|
||||
|
||||
// Set all profile combox values to "none" value (ie. the last item in a controller combobox list)
|
||||
for (int i = 0; i < 4; i++)
|
||||
cbs[i].SelectedIndex = cbs[i].Items.Count - 1;
|
||||
{
|
||||
cbs[i].Enabled = false;
|
||||
if (cbs[i].SelectedIndex != last)
|
||||
cbs[i].SelectedIndex = last;
|
||||
}
|
||||
|
||||
bnSave.Enabled = bnDelete.Enabled = false;
|
||||
tBPath.Enabled = tBWndTitle.Enabled = cBTurnOffDS4W.Enabled = false;
|
||||
tBPath.Text = tBWndTitle.Text = "";
|
||||
cBTurnOffDS4W.Checked = false;
|
||||
bnSave.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveP(string name, bool uncheck)
|
||||
{
|
||||
XmlDocument doc = new XmlDocument();
|
||||
doc.Load(m_Profile);
|
||||
XmlNode Node = doc.SelectSingleNode("Programs");
|
||||
XmlNode Item = doc.SelectSingleNode("/Programs/Program[@path=\"" + name + "\"]");
|
||||
if (Item != null)
|
||||
Node.RemoveChild(Item);
|
||||
|
||||
doc.AppendChild(Node);
|
||||
doc.Save(m_Profile);
|
||||
if (lVPrograms.SelectedItems.Count > 0 && uncheck)
|
||||
lVPrograms.SelectedItems[0].Checked = false;
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
cbs[i].SelectedIndex = cbs[i].Items.Count - 1;
|
||||
|
||||
bnSave.Enabled = false;
|
||||
}
|
||||
|
||||
private void CBProfile_IndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
int last = cbs[0].Items.Count - 1;
|
||||
if (lBProgramPath.Text != string.Empty)
|
||||
if (selectedProgramPathItem != null && lVPrograms.SelectedItems.Count > 0)
|
||||
bnSave.Enabled = true;
|
||||
|
||||
if (cbs[0].SelectedIndex == last && cbs[1].SelectedIndex == last &&
|
||||
cbs[2].SelectedIndex == last && cbs[3].SelectedIndex == last && !cBTurnOffDS4W.Checked)
|
||||
bnSave.Enabled = false;
|
||||
}
|
||||
|
||||
private void bnSave_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (lBProgramPath.Text != "")
|
||||
Save(lBProgramPath.Text);
|
||||
if (selectedProgramPathItem != null)
|
||||
{
|
||||
// Path cannot be empty. If user tried to clear it then re-use the original path value
|
||||
if (String.IsNullOrEmpty(tBPath.Text))
|
||||
tBPath.Text = selectedProgramPathItem.path;
|
||||
|
||||
Save(selectedProgramPathItem);
|
||||
}
|
||||
bnSave.Enabled = false;
|
||||
}
|
||||
|
||||
@ -349,41 +526,48 @@ namespace DS4Windows.Forms
|
||||
cMSPrograms.Show(bnAddPrograms, new Point(0, bnAddPrograms.Height));
|
||||
}
|
||||
|
||||
private void lBProgramPath_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lBProgramPath.Text != "")
|
||||
LoadP(lBProgramPath.Text);
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
cbs[i].SelectedIndex = cbs[i].Items.Count - 1;
|
||||
}
|
||||
}
|
||||
|
||||
private void bnDelete_Click(object sender, EventArgs e)
|
||||
{
|
||||
RemoveP(lBProgramPath.Text, true);
|
||||
RemoveP(selectedProgramPathItem, true);
|
||||
selectedProgramPathItem = null;
|
||||
bnSave.Enabled = bnDelete.Enabled = false;
|
||||
if (lVPrograms.SelectedItems.Count > 0)
|
||||
lVPrograms.SelectedItems[0].Selected = lVPrograms.SelectedItems[0].Focused = false;
|
||||
}
|
||||
|
||||
private void lBProgramPath_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (lVPrograms.SelectedItems.Count > 0)
|
||||
if (lVPrograms.SelectedItems.Count > 0 && lVPrograms.SelectedIndices[0] > -1)
|
||||
{
|
||||
if (lVPrograms.SelectedIndices[0] > -1)
|
||||
lBProgramPath.Text = lVPrograms.SelectedItems[0].SubItems[1].Text;
|
||||
if (selectedProgramPathItem == null) selectedProgramPathItem = new ProgramPathItem(String.Empty, String.Empty);
|
||||
|
||||
selectedProgramPathItem.path = lVPrograms.SelectedItems[0].SubItems[1].Text;
|
||||
if (lVPrograms.SelectedItems[0].SubItems.Count >= 3)
|
||||
selectedProgramPathItem.title = lVPrograms.SelectedItems[0].SubItems[2].Text;
|
||||
else
|
||||
selectedProgramPathItem.title = String.Empty;
|
||||
|
||||
UpdateProfileComboListValues(selectedProgramPathItem);
|
||||
}
|
||||
else
|
||||
lBProgramPath.Text = "";
|
||||
}
|
||||
|
||||
private void listView1_ItemCheck(object sender, ItemCheckEventArgs e)
|
||||
{
|
||||
if (lVPrograms.Items[e.Index].Checked)
|
||||
RemoveP(lVPrograms.Items[e.Index].SubItems[1].Text, false);
|
||||
{
|
||||
selectedProgramPathItem = null;
|
||||
UpdateProfileComboListValues(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void bnHideUnchecked_Click(object sender, EventArgs e)
|
||||
{
|
||||
// Remove all unchecked items from autoprofile XML file and listView list
|
||||
foreach (ListViewItem lvi in lVPrograms.Items)
|
||||
{
|
||||
if (!lvi.Checked)
|
||||
{
|
||||
RemoveP(new ProgramPathItem(lvi.SubItems[1]?.Text, (lvi.SubItems.Count >=3 ? lvi.SubItems[2]?.Text : null)), false);
|
||||
}
|
||||
}
|
||||
|
||||
selectedProgramPathItem = null;
|
||||
form.RefreshAutoProfilesPage();
|
||||
}
|
||||
|
||||
@ -418,11 +602,18 @@ namespace DS4Windows.Forms
|
||||
file = GetTargetPath(file);
|
||||
}
|
||||
|
||||
lBProgramPath.Text = file;
|
||||
iLIcons.Images.Add(Icon.ExtractAssociatedIcon(file));
|
||||
ListViewItem lvi = new ListViewItem(Path.GetFileNameWithoutExtension(file), lVPrograms.Items.Count);
|
||||
lvi.SubItems.Add(file);
|
||||
lVPrograms.Items.Insert(0, lvi);
|
||||
if (lVPrograms.SelectedItems.Count > 0)
|
||||
lVPrograms.SelectedItems[0].Selected = lVPrograms.SelectedItems[0].Focused = false;
|
||||
|
||||
lodsf.Clear();
|
||||
lodsf.Add(file);
|
||||
appsloaded = true;
|
||||
|
||||
if (AddLoadedApps(false) > 0 && lVPrograms.Items.Count > 0)
|
||||
{
|
||||
lVPrograms.Items[lVPrograms.Items.Count - 1].Focused = true;
|
||||
lVPrograms.Items[lVPrograms.Items.Count - 1].Selected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -534,6 +725,22 @@ namespace DS4Windows.Forms
|
||||
CBProfile_IndexChanged(sender, e);
|
||||
}
|
||||
|
||||
private void cBAutoProfileDebugLog_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
DS4Form.autoProfileDebugLogLevel = cBAutoProfileDebugLog.Checked ? 1 : 0;
|
||||
}
|
||||
|
||||
private void tBPath_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
int last = cbs[0].Items.Count - 1;
|
||||
if (cbs[0].SelectedIndex != last || cbs[1].SelectedIndex != last || cbs[2].SelectedIndex != last || cbs[3].SelectedIndex != last || !cBTurnOffDS4W.Checked)
|
||||
{
|
||||
// Content of path or wndTitle editbox changed. Enable SAVE button if it is disabled at the moment and there is an active selection in a listView
|
||||
if (selectedProgramPathItem != null && bnSave.Enabled == false && lVPrograms.SelectedItems.Count > 0)
|
||||
bnSave.Enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
public static string ResolveMsiShortcut(string file)
|
||||
{
|
||||
StringBuilder product = new StringBuilder(NativeMethods2.MaxGuidLength + 1);
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
@ -165,4 +165,16 @@
|
||||
<data name="pBProfilesTip.Text" xml:space="preserve">
|
||||
<value>Valitse profiilit tästä</value>
|
||||
</data>
|
||||
<data name="WndTitleHeader.Text" xml:space="preserve">
|
||||
<value>Ikkunan otsikko</value>
|
||||
</data>
|
||||
<data name="cBTurnOffDS4W.Text" xml:space="preserve">
|
||||
<value>Pysäytä DS4Windows väliaikaisesti</value>
|
||||
</data>
|
||||
<data name="cBAutoProfileDebugLog.Text" xml:space="preserve">
|
||||
<value>Näytä auto-profiilien virheseurannan viestit</value>
|
||||
</data>
|
||||
<data name="$this.Text" xml:space="preserve">
|
||||
<value>Auto-Profiilit</value>
|
||||
</data>
|
||||
</root>
|
@ -141,36 +141,9 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>bnAddPrograms.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
<value>8</value>
|
||||
</data>
|
||||
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
|
||||
<data name="lBProgramPath.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="lBProgramPath.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>519, 195</value>
|
||||
</data>
|
||||
<data name="lBProgramPath.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>205, 18</value>
|
||||
</data>
|
||||
<data name="lBProgramPath.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="lBProgramPath.Visible" type="System.Boolean, mscorlib">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name=">>lBProgramPath.Name" xml:space="preserve">
|
||||
<value>lBProgramPath</value>
|
||||
</data>
|
||||
<data name=">>lBProgramPath.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>lBProgramPath.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>lBProgramPath.ZOrder" xml:space="preserve">
|
||||
<value>14</value>
|
||||
</data>
|
||||
<data name="cBProfile1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
@ -193,7 +166,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>cBProfile1.ZOrder" xml:space="preserve">
|
||||
<value>13</value>
|
||||
<value>17</value>
|
||||
</data>
|
||||
<data name="cBProfile2.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
@ -217,7 +190,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>cBProfile2.ZOrder" xml:space="preserve">
|
||||
<value>12</value>
|
||||
<value>16</value>
|
||||
</data>
|
||||
<data name="cBProfile3.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
@ -241,7 +214,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>cBProfile3.ZOrder" xml:space="preserve">
|
||||
<value>11</value>
|
||||
<value>15</value>
|
||||
</data>
|
||||
<data name="cBProfile4.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
@ -265,7 +238,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>cBProfile4.ZOrder" xml:space="preserve">
|
||||
<value>10</value>
|
||||
<value>14</value>
|
||||
</data>
|
||||
<data name="bnSave.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
@ -295,7 +268,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>bnSave.ZOrder" xml:space="preserve">
|
||||
<value>16</value>
|
||||
<value>19</value>
|
||||
</data>
|
||||
<data name="lBController1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
@ -325,7 +298,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>lBController1.ZOrder" xml:space="preserve">
|
||||
<value>9</value>
|
||||
<value>13</value>
|
||||
</data>
|
||||
<data name="lBController2.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
@ -355,7 +328,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>lBController2.ZOrder" xml:space="preserve">
|
||||
<value>8</value>
|
||||
<value>12</value>
|
||||
</data>
|
||||
<data name="lBController3.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
@ -385,7 +358,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>lBController3.ZOrder" xml:space="preserve">
|
||||
<value>7</value>
|
||||
<value>11</value>
|
||||
</data>
|
||||
<data name="lBController4.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
@ -415,7 +388,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>lBController4.ZOrder" xml:space="preserve">
|
||||
<value>6</value>
|
||||
<value>10</value>
|
||||
</data>
|
||||
<metadata name="openProgram.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
@ -448,7 +421,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>bnDelete.ZOrder" xml:space="preserve">
|
||||
<value>15</value>
|
||||
<value>18</value>
|
||||
</data>
|
||||
<metadata name="iLIcons.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>143, 17</value>
|
||||
@ -469,13 +442,19 @@
|
||||
<value>Path</value>
|
||||
</data>
|
||||
<data name="PathHeader.Width" type="System.Int32, mscorlib">
|
||||
<value>358</value>
|
||||
<value>400</value>
|
||||
</data>
|
||||
<data name="WndTitleHeader.Text" xml:space="preserve">
|
||||
<value>Window Title</value>
|
||||
</data>
|
||||
<data name="WndTitleHeader.Width" type="System.Int32, mscorlib">
|
||||
<value>140</value>
|
||||
</data>
|
||||
<data name="lVPrograms.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>5, 28</value>
|
||||
</data>
|
||||
<data name="lVPrograms.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>505, 190</value>
|
||||
<value>505, 261</value>
|
||||
</data>
|
||||
<data name="lVPrograms.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>12</value>
|
||||
@ -490,7 +469,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>lVPrograms.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
<value>9</value>
|
||||
</data>
|
||||
<data name="pBProfilesTip.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
@ -520,7 +499,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>pBProfilesTip.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
<value>1</value>
|
||||
</data>
|
||||
<data name="bnHideUnchecked.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>99, 2</value>
|
||||
@ -544,7 +523,7 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>bnHideUnchecked.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
<value>7</value>
|
||||
</data>
|
||||
<metadata name="cMSPrograms.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>232, 17</value>
|
||||
@ -592,13 +571,13 @@
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="cBTurnOffDS4W.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>514, 152</value>
|
||||
<value>514, 151</value>
|
||||
</data>
|
||||
<data name="cBTurnOffDS4W.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="cBTurnOffDS4W.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>215, 41</value>
|
||||
<value>215, 24</value>
|
||||
</data>
|
||||
<data name="cBTurnOffDS4W.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>13</value>
|
||||
@ -616,7 +595,109 @@
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>cBTurnOffDS4W.ZOrder" xml:space="preserve">
|
||||
<value>1</value>
|
||||
<value>6</value>
|
||||
</data>
|
||||
<data name="cBAutoProfileDebugLog.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="cBAutoProfileDebugLog.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>514, 255</value>
|
||||
</data>
|
||||
<data name="cBAutoProfileDebugLog.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>2, 2, 2, 2</value>
|
||||
</data>
|
||||
<data name="cBAutoProfileDebugLog.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>215, 20</value>
|
||||
</data>
|
||||
<data name="cBAutoProfileDebugLog.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>14</value>
|
||||
</data>
|
||||
<data name="cBAutoProfileDebugLog.Text" xml:space="preserve">
|
||||
<value>Show auto-profile debug messages</value>
|
||||
</data>
|
||||
<data name=">>cBAutoProfileDebugLog.Name" xml:space="preserve">
|
||||
<value>cBAutoProfileDebugLog</value>
|
||||
</data>
|
||||
<data name=">>cBAutoProfileDebugLog.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>cBAutoProfileDebugLog.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>cBAutoProfileDebugLog.ZOrder" xml:space="preserve">
|
||||
<value>5</value>
|
||||
</data>
|
||||
<data name="tBPath.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="tBPath.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>514, 186</value>
|
||||
</data>
|
||||
<data name="tBPath.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>216, 20</value>
|
||||
</data>
|
||||
<data name="tBPath.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>15</value>
|
||||
</data>
|
||||
<data name=">>tBPath.Name" xml:space="preserve">
|
||||
<value>tBPath</value>
|
||||
</data>
|
||||
<data name=">>tBPath.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tBPath.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>tBPath.ZOrder" xml:space="preserve">
|
||||
<value>4</value>
|
||||
</data>
|
||||
<data name="tBWndTitle.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="tBWndTitle.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>514, 212</value>
|
||||
</data>
|
||||
<data name="tBWndTitle.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>215, 20</value>
|
||||
</data>
|
||||
<data name="tBWndTitle.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>16</value>
|
||||
</data>
|
||||
<data name=">>tBWndTitle.Name" xml:space="preserve">
|
||||
<value>tBWndTitle</value>
|
||||
</data>
|
||||
<data name=">>tBWndTitle.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.TextBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>tBWndTitle.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>tBWndTitle.ZOrder" xml:space="preserve">
|
||||
<value>3</value>
|
||||
</data>
|
||||
<data name="lBDividerLine1.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
|
||||
<value>Top, Right</value>
|
||||
</data>
|
||||
<data name="lBDividerLine1.Location" type="System.Drawing.Point, System.Drawing">
|
||||
<value>514, 248</value>
|
||||
</data>
|
||||
<data name="lBDividerLine1.Size" type="System.Drawing.Size, System.Drawing">
|
||||
<value>218, 5</value>
|
||||
</data>
|
||||
<data name="lBDividerLine1.TabIndex" type="System.Int32, mscorlib">
|
||||
<value>17</value>
|
||||
</data>
|
||||
<data name=">>lBDividerLine1.Name" xml:space="preserve">
|
||||
<value>lBDividerLine1</value>
|
||||
</data>
|
||||
<data name=">>lBDividerLine1.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>lBDividerLine1.Parent" xml:space="preserve">
|
||||
<value>$this</value>
|
||||
</data>
|
||||
<data name=">>lBDividerLine1.ZOrder" xml:space="preserve">
|
||||
<value>2</value>
|
||||
</data>
|
||||
<metadata name="$this.Localizable" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
@ -625,7 +706,7 @@
|
||||
<value>6, 13</value>
|
||||
</data>
|
||||
<data name="$this.ClientSize" type="System.Drawing.Size, System.Drawing">
|
||||
<value>736, 222</value>
|
||||
<value>736, 293</value>
|
||||
</data>
|
||||
<data name="$this.Margin" type="System.Windows.Forms.Padding, System.Windows.Forms">
|
||||
<value>4, 4, 4, 4</value>
|
||||
@ -657,6 +738,12 @@
|
||||
<data name=">>PathHeader.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>WndTitleHeader.Name" xml:space="preserve">
|
||||
<value>WndTitleHeader</value>
|
||||
</data>
|
||||
<data name=">>WndTitleHeader.Type" xml:space="preserve">
|
||||
<value>System.Windows.Forms.ColumnHeader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</data>
|
||||
<data name=">>addProgramsFromStartMenuToolStripMenuItem.Name" xml:space="preserve">
|
||||
<value>addProgramsFromStartMenuToolStripMenuItem</value>
|
||||
</data>
|
||||
|
18
DS4Windows/Properties/Resources.Designer.cs
generated
18
DS4Windows/Properties/Resources.Designer.cs
generated
@ -154,6 +154,15 @@ namespace DS4Windows.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to ^ABC = Match at the beginning of string (^) | ABC$ = Match at the end of string ($) | *ABC =Contains a string (*).
|
||||
/// </summary>
|
||||
public static string AutoProfilePathAndWindowTitleEditTip {
|
||||
get {
|
||||
return ResourceManager.GetString("AutoProfilePathAndWindowTitleEditTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized resource of type System.Drawing.Bitmap.
|
||||
/// </summary>
|
||||
@ -1800,6 +1809,15 @@ namespace DS4Windows.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to If enabled then Log tab page shows detailed messages of auto-profile events..
|
||||
/// </summary>
|
||||
public static string ShowAutoProfileDebugLogTip {
|
||||
get {
|
||||
return ResourceManager.GetString("ShowAutoProfileDebugLogTip", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Click for advanced Sixaxis reading.
|
||||
/// </summary>
|
||||
|
@ -603,4 +603,16 @@
|
||||
<data name="UdpServer" xml:space="preserve">
|
||||
<value>Aktivoi UDP palvelu. Palvelun osoite ja portti. Osoitevaihtoehdot: 127.0.0.1 paikallinen | 0.0.0.0 kaikki liittymät | Tietty palvelinnimi tai IP numero.</value>
|
||||
</data>
|
||||
<data name="AutoProfilePathAndWindowTitleEditTip" xml:space="preserve">
|
||||
<value>^ABC = Täsmää merkkijonon alusta (^) | ABC$ = Täsmää merkkijonon lopusta ($) | *ABC = Sisältää merkkijonon.</value>
|
||||
</data>
|
||||
<data name="ShowAutoProfileDebugLogTip" xml:space="preserve">
|
||||
<value>Näytä automaattiprofiilivalintojen tarkempia valvontaviestejä Loki-välilehdellä.</value>
|
||||
</data>
|
||||
<data name="OutContNotice" xml:space="preserve">
|
||||
<value>Valitse virtuaaliohjaimen tyyppi (muutos tulee voimaan profiilin tallennuksen jälkeen)</value>
|
||||
</data>
|
||||
<data name="EnableTouchToggle" xml:space="preserve">
|
||||
<value>Salli kosketuslevyhiiriohjaimen päälle-pois kytkentä PS + kosketuslevynapautuksella.</value>
|
||||
</data>
|
||||
</root>
|
@ -826,4 +826,10 @@
|
||||
<data name="UdpServer" xml:space="preserve">
|
||||
<value>Enable UDP server. Server listen address and port. Address value options: 127.0.0.1 localhost only | 0.0.0.0 all addresses | Specific host name or IP address.</value>
|
||||
</data>
|
||||
<data name="AutoProfilePathAndWindowTitleEditTip" xml:space="preserve">
|
||||
<value>^ABC = Match at the beginning of string (^) | ABC$ = Match at the end of string ($) | *ABC =Contains a string (*)</value>
|
||||
</data>
|
||||
<data name="ShowAutoProfileDebugLogTip" xml:space="preserve">
|
||||
<value>If enabled then Log tab page shows detailed messages of auto-profile events.</value>
|
||||
</data>
|
||||
</root>
|
Loading…
Reference in New Issue
Block a user