mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Refactor command and bang logic into new CCommandHandler class
This also improves bang log messages, which now include the bang name.
This commit is contained in:
parent
85b214de0e
commit
f8c3f11913
938
Library/CommandHandler.cpp
Normal file
938
Library/CommandHandler.cpp
Normal file
@ -0,0 +1,938 @@
|
||||
/*
|
||||
Copyright (C) 2013 Rainmeter Team
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "CommandHandler.h"
|
||||
#include "ConfigParser.h"
|
||||
#include "DialogAbout.h"
|
||||
#include "DialogManage.h"
|
||||
#include "Measure.h"
|
||||
#include "Logger.h"
|
||||
#include "Rainmeter.h"
|
||||
#include "System.h"
|
||||
#include "TrayWindow.h"
|
||||
#include "resource.h"
|
||||
|
||||
extern CRainmeter* Rainmeter;
|
||||
|
||||
namespace {
|
||||
|
||||
typedef void (* BangHandlerFunc)(std::vector<std::wstring>& args, CMeterWindow* skin);
|
||||
|
||||
struct BangInfo
|
||||
{
|
||||
Bang bang;
|
||||
WCHAR* name;
|
||||
uint8_t argCount;
|
||||
};
|
||||
|
||||
struct CustomBangInfo
|
||||
{
|
||||
Bang bang;
|
||||
WCHAR* name;
|
||||
BangHandlerFunc handlerFunc;
|
||||
};
|
||||
|
||||
// Bangs that are to be handled with DoBang().
|
||||
const BangInfo s_Bangs[] =
|
||||
{
|
||||
{ Bang::Refresh, L"Refresh", 0 },
|
||||
{ Bang::Redraw, L"Redraw", 0 },
|
||||
{ Bang::Update, L"Update", 0 },
|
||||
{ Bang::Hide, L"Hide", 0 },
|
||||
{ Bang::Show, L"Show", 0 },
|
||||
{ Bang::Toggle, L"Toggle", 0 },
|
||||
{ Bang::HideFade, L"HideFade", 0 },
|
||||
{ Bang::ShowFade, L"ShowFade", 0 },
|
||||
{ Bang::ToggleFade, L"ToggleFade", 0 },
|
||||
{ Bang::HideMeter, L"HideMeter", 1 },
|
||||
{ Bang::ShowMeter, L"ShowMeter", 1 },
|
||||
{ Bang::ToggleMeter, L"ToggleMeter", 1 },
|
||||
{ Bang::MoveMeter, L"MoveMeter", 3 },
|
||||
{ Bang::UpdateMeter, L"UpdateMeter", 1 },
|
||||
{ Bang::DisableMeasure, L"DisableMeasure", 1 },
|
||||
{ Bang::EnableMeasure, L"EnableMeasure", 1 },
|
||||
{ Bang::ToggleMeasure, L"ToggleMeasure", 1 },
|
||||
{ Bang::UpdateMeasure, L"UpdateMeasure", 1 },
|
||||
{ Bang::CommandMeasure, L"CommandMeasure", 2 },
|
||||
{ Bang::PluginBang, L"PluginBang", 1 },
|
||||
{ Bang::ShowBlur, L"ShowBlur", 0 },
|
||||
{ Bang::HideBlur, L"HideBlur", 0 },
|
||||
{ Bang::ToggleBlur, L"ToggleBlur", 0 },
|
||||
{ Bang::AddBlur, L"AddBlur", 1 },
|
||||
{ Bang::RemoveBlur, L"RemoveBlur", 1 },
|
||||
{ Bang::Move, L"Move", 2 },
|
||||
{ Bang::ZPos, L"ZPos", 1 },
|
||||
{ Bang::ZPos, L"ChangeZPos", 1 }, // For backwards compatibility.
|
||||
{ Bang::ChangeZPos, L"ChangeZPos", 1 },
|
||||
{ Bang::ClickThrough, L"ClickThrough", 1 },
|
||||
{ Bang::Draggable, L"Draggable", 1 },
|
||||
{ Bang::SnapEdges, L"SnapEdges", 1 },
|
||||
{ Bang::KeepOnScreen, L"KeepOnScreen", 1 },
|
||||
{ Bang::SetTransparency, L"SetTransparency", 1 },
|
||||
{ Bang::SetVariable, L"SetVariable", 2 },
|
||||
{ Bang::SetOption, L"SetOption", 3 },
|
||||
{ Bang::SetOptionGroup, L"SetOptionGroup", 3 },
|
||||
{ Bang::HideMeterGroup, L"HideMeterGroup", 1 },
|
||||
{ Bang::ShowMeterGroup, L"ShowMeterGroup", 1 },
|
||||
{ Bang::ToggleMeterGroup, L"ToggleMeterGroup", 1 },
|
||||
{ Bang::UpdateMeterGroup, L"UpdateMeterGroup", 1 },
|
||||
{ Bang::DisableMeasureGroup, L"DisableMeasureGroup", 1 },
|
||||
{ Bang::EnableMeasureGroup, L"EnableMeasureGroup", 1 },
|
||||
{ Bang::ToggleMeasureGroup, L"ToggleMeasureGroup", 1 },
|
||||
{ Bang::UpdateMeasureGroup, L"UpdateMeasureGroup", 1 }
|
||||
};
|
||||
|
||||
// Bangs that are to be handled with DoGroupBang().
|
||||
const BangInfo s_GroupBangs[] =
|
||||
{
|
||||
{ Bang::RefreshGroup, L"RefreshGroup", 0 },
|
||||
{ Bang::UpdateGroup, L"UpdateGroup", 0 },
|
||||
{ Bang::RedrawGroup, L"RedrawGroup", 0 },
|
||||
{ Bang::HideGroup, L"HideGroup", 0 },
|
||||
{ Bang::ShowGroup, L"ShowGroup", 0 },
|
||||
{ Bang::ToggleGroup, L"ToggleGroup", 0 },
|
||||
{ Bang::HideFadeGroup, L"HideFadeGroup", 0 },
|
||||
{ Bang::ShowFadeGroup, L"ShowFadeGroup", 0 },
|
||||
{ Bang::ToggleFadeGroup, L"ToggleFadeGroup", 0 },
|
||||
{ Bang::DeactivateConfigGroup, L"DeactivateConfigGroup" },
|
||||
{ Bang::ZPosGroup, L"ZPosGroup", 1 },
|
||||
{ Bang::ClickThroughGroup, L"ClickThroughGroup", 1 },
|
||||
{ Bang::DraggableGroup, L"DraggableGroup", 1 },
|
||||
{ Bang::SnapEdgesGroup, L"SnapEdgesGroup", 1 },
|
||||
{ Bang::KeepOnScreenGroup, L"KeepOnScreenGroup", 1 },
|
||||
{ Bang::SetTransparencyGroup, L"SetTransparencyGroup", 1 },
|
||||
{ Bang::SetVariableGroup, L"SetVariableGroup", 2 }
|
||||
};
|
||||
|
||||
// Bangs that are to be handled using a custom handler function.
|
||||
const CustomBangInfo s_CustomBangs[] =
|
||||
{
|
||||
{ Bang::ActivateConfig, L"ActivateConfig", CCommandHandler::DoActivateSkinBang },
|
||||
{ Bang::DeactivateConfig, L"DeactivateConfig", CCommandHandler::DoDeactivateSkinBang },
|
||||
{ Bang::ToggleConfig, L"ToggleConfig", CCommandHandler::DoToggleSkinBang },
|
||||
{ Bang::WriteKeyValue, L"WriteKeyValue", CCommandHandler::DoWriteKeyValueBang },
|
||||
{ Bang::LoadLayout, L"LoadLayout", CCommandHandler::DoLoadLayoutBang },
|
||||
{ Bang::SetClip, L"SetClip", CCommandHandler::DoSetClipBang },
|
||||
{ Bang::SetWallpaper, L"SetWallpaper", CCommandHandler::DoSetWallpaperBang },
|
||||
{ Bang::About, L"About", CCommandHandler::DoAboutBang },
|
||||
{ Bang::Manage, L"Manage", CCommandHandler::DoManageBang },
|
||||
{ Bang::SkinMenu, L"SkinMenu", CCommandHandler::DoSkinMenuBang },
|
||||
{ Bang::TrayMenu, L"TrayMenu", CCommandHandler::DoTrayMenuBang },
|
||||
{ Bang::ResetStats, L"ResetStats", CCommandHandler::DoResetStatsBang },
|
||||
{ Bang::Log, L"Log", CCommandHandler::DoLogBang },
|
||||
{ Bang::RefreshApp, L"RefreshApp", CCommandHandler::DoRefreshApp },
|
||||
{ Bang::Quit, L"Quit", CCommandHandler::DoQuitBang },
|
||||
{ Bang::LsBoxHook, L"LsBoxHook", CCommandHandler::DoLsBoxHookBang }
|
||||
};
|
||||
|
||||
void DoBang(const BangInfo& bangInfo, std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
const size_t argsCount = args.size();
|
||||
if (argsCount >= bangInfo.argCount)
|
||||
{
|
||||
if (argsCount == bangInfo.argCount && skin)
|
||||
{
|
||||
skin->DoBang(bangInfo.bang, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the specified window instead of skin parameter.
|
||||
if (argsCount > bangInfo.argCount)
|
||||
{
|
||||
const std::wstring& folderPath = args[bangInfo.argCount];
|
||||
if (!folderPath.empty() && (folderPath.length() != 1 || folderPath[0] != L'*'))
|
||||
{
|
||||
CMeterWindow* skin = Rainmeter->GetMeterWindow(folderPath);
|
||||
if (skin)
|
||||
{
|
||||
skin->DoBang(bangInfo.bang, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogErrorF(L"!%s: Skin \"%s\" not found", folderPath.c_str(), bangInfo.name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// No skin defined -> apply to all.
|
||||
for (const auto& ip : Rainmeter->GetAllMeterWindows())
|
||||
{
|
||||
ip.second->DoBang(bangInfo.bang, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// For backwards compatibility.
|
||||
if (bangInfo.bang == Bang::CommandMeasure && argsCount >= 1)
|
||||
{
|
||||
std::wstring& firstArg = args[0];
|
||||
std::wstring::size_type pos = firstArg.find_first_of(L' ');
|
||||
if (pos != std::wstring::npos)
|
||||
{
|
||||
std::wstring newArg = firstArg.substr(0, pos);
|
||||
firstArg.erase(0, pos + 1);
|
||||
args.insert(args.begin(), newArg);
|
||||
|
||||
LogWarningF(L"!%s: Two parameters required, only one given", bangInfo.name);
|
||||
DoBang(bangInfo, args, skin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LogErrorF(L"!%s: Incorrect number of arguments", bangInfo.name);
|
||||
}
|
||||
}
|
||||
|
||||
void DoGroupBang(const BangInfo& bangInfo, std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
if (args.size() > bangInfo.argCount)
|
||||
{
|
||||
std::multimap<int, CMeterWindow*> windows;
|
||||
Rainmeter->GetMeterWindowsByLoadOrder(windows, args[bangInfo.argCount]);
|
||||
|
||||
// Remove extra parameters (including group).
|
||||
args.resize(bangInfo.argCount);
|
||||
|
||||
std::multimap<int, CMeterWindow*>::const_iterator iter = windows.begin();
|
||||
for (const auto& ip : windows)
|
||||
{
|
||||
DoBang(bangInfo, args, ip.second);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogErrorF(L"!%s: Incorrect number of arguments", bangInfo.name);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
/*
|
||||
** Parses and executes the given command.
|
||||
**
|
||||
*/
|
||||
void CCommandHandler::ExecuteCommand(const WCHAR* command, CMeterWindow* skin, bool multi)
|
||||
{
|
||||
if (command[0] == L'!') // Bang
|
||||
{
|
||||
++command; // Skip "!"
|
||||
|
||||
if (_wcsnicmp(L"Execute", command, 7) == 0)
|
||||
{
|
||||
command += 7;
|
||||
command = wcschr(command, L'[');
|
||||
if (!command) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_wcsnicmp(command, L"Rainmeter", 9) == 0)
|
||||
{
|
||||
// Skip "Rainmeter" for backwards compatibility
|
||||
command += 9;
|
||||
}
|
||||
|
||||
std::wstring bang;
|
||||
std::vector<std::wstring> args;
|
||||
|
||||
// Find the first space
|
||||
const WCHAR* pos = wcschr(command, L' ');
|
||||
if (pos)
|
||||
{
|
||||
bang.assign(command, 0, pos - command);
|
||||
args = ParseString(pos + 1, skin ? &skin->GetParser() : NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
bang = command;
|
||||
}
|
||||
|
||||
ExecuteBang(bang.c_str(), args, skin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (multi && command[0] == L'[') // Multi-bang
|
||||
{
|
||||
std::wstring bangs = command;
|
||||
std::wstring::size_type start = std::wstring::npos;
|
||||
int count = 0;
|
||||
for (size_t i = 0, isize = bangs.size(); i < isize; ++i)
|
||||
{
|
||||
if (bangs[i] == L'[')
|
||||
{
|
||||
if (count == 0)
|
||||
{
|
||||
start = i;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
else if (bangs[i] == L']')
|
||||
{
|
||||
--count;
|
||||
|
||||
if (count == 0 && start != std::wstring::npos)
|
||||
{
|
||||
// Change ] to NULL
|
||||
bangs[i] = L'\0';
|
||||
|
||||
// Skip whitespace
|
||||
start = bangs.find_first_not_of(L" \t\r\n", start + 1, 4);
|
||||
|
||||
ExecuteCommand(bangs.c_str() + start, skin, false);
|
||||
}
|
||||
}
|
||||
else if (bangs[i] == L'"' && isize > (i + 2) && bangs[i + 1] == L'"' && bangs[i + 2] == L'"')
|
||||
{
|
||||
i += 3;
|
||||
|
||||
std::wstring::size_type pos = bangs.find(L"\"\"\"", i);
|
||||
if (pos != std::wstring::npos)
|
||||
{
|
||||
i = pos + 2; // Skip "", loop will skip last "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check for built-ins
|
||||
if (_wcsnicmp(L"PLAY", command, 4) == 0)
|
||||
{
|
||||
if (command[4] == L' ' || // PLAY
|
||||
_wcsnicmp(L"LOOP ", &command[4], 5) == 0) // PLAYLOOP
|
||||
{
|
||||
command += 4; // Skip PLAY
|
||||
|
||||
DWORD flags = SND_FILENAME | SND_ASYNC;
|
||||
|
||||
if (command[0] != L' ')
|
||||
{
|
||||
flags |= SND_LOOP | SND_NODEFAULT;
|
||||
command += 4; // Skip LOOP
|
||||
}
|
||||
|
||||
++command; // Skip the space
|
||||
if (command[0] != L'\0')
|
||||
{
|
||||
std::wstring sound = command;
|
||||
|
||||
// Strip the quotes
|
||||
std::wstring::size_type len = sound.length();
|
||||
if (len >= 2 && sound[0] == L'"' && sound[len - 1] == L'"')
|
||||
{
|
||||
len -= 2;
|
||||
sound.assign(sound, 1, len);
|
||||
}
|
||||
|
||||
if (skin)
|
||||
{
|
||||
skin->GetParser().ReplaceMeasures(sound);
|
||||
skin->MakePathAbsolute(sound);
|
||||
}
|
||||
|
||||
PlaySound(sound.c_str(), NULL, flags);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if (_wcsnicmp(L"STOP", &command[4], 4) == 0) // PLAYSTOP
|
||||
{
|
||||
PlaySound(NULL, NULL, SND_PURGE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Run command
|
||||
std::wstring tmpSz = command;
|
||||
if (skin)
|
||||
{
|
||||
skin->GetParser().ReplaceMeasures(tmpSz);
|
||||
}
|
||||
RunCommand(tmpSz);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Runs the given bang.
|
||||
**
|
||||
*/
|
||||
void CCommandHandler::ExecuteBang(const WCHAR* name, std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
for (const auto& bangInfo : s_Bangs)
|
||||
{
|
||||
if (_wcsicmp(bangInfo.name, name) == 0)
|
||||
{
|
||||
DoBang(bangInfo, args, skin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& bangInfo : s_GroupBangs)
|
||||
{
|
||||
if (_wcsicmp(bangInfo.name, name) == 0)
|
||||
{
|
||||
DoGroupBang(bangInfo, args, skin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& bangInfo : s_CustomBangs)
|
||||
{
|
||||
if (_wcsicmp(bangInfo.name, name) == 0)
|
||||
{
|
||||
bangInfo.handlerFunc(args, skin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LogErrorF(L"Invalid bang: !%s", name);
|
||||
}
|
||||
|
||||
/*
|
||||
** Parses and runs the given command.
|
||||
**
|
||||
*/
|
||||
void CCommandHandler::RunCommand(std::wstring command)
|
||||
{
|
||||
std::wstring args;
|
||||
|
||||
size_t notwhite = command.find_first_not_of(L" \t\r\n");
|
||||
command.erase(0, notwhite);
|
||||
|
||||
size_t quotePos = command.find(L'"');
|
||||
if (quotePos == 0)
|
||||
{
|
||||
size_t quotePos2 = command.find(L'"', quotePos + 1);
|
||||
if (quotePos2 != std::wstring::npos)
|
||||
{
|
||||
args.assign(command, quotePos2 + 1, command.length() - (quotePos2 + 1));
|
||||
command.assign(command, quotePos + 1, quotePos2 - quotePos - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
command.erase(0, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t spacePos = command.find(L' ');
|
||||
if (spacePos != std::wstring::npos)
|
||||
{
|
||||
args.assign(command, spacePos + 1, command.length() - (spacePos + 1));
|
||||
command.erase(spacePos);
|
||||
}
|
||||
}
|
||||
|
||||
if (!command.empty())
|
||||
{
|
||||
RunFile(command.c_str(), args.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Runs a file with the given arguments.
|
||||
**
|
||||
*/
|
||||
void CCommandHandler::RunFile(const WCHAR* file, const WCHAR* args)
|
||||
{
|
||||
SHELLEXECUTEINFO si = {sizeof(SHELLEXECUTEINFO)};
|
||||
si.lpVerb = L"open";
|
||||
si.lpFile = file;
|
||||
si.nShow = SW_SHOWNORMAL;
|
||||
|
||||
DWORD type = GetFileAttributes(si.lpFile);
|
||||
if (type & FILE_ATTRIBUTE_DIRECTORY && type != 0xFFFFFFFF)
|
||||
{
|
||||
ShellExecute(si.hwnd, si.lpVerb, si.lpFile, NULL, NULL, si.nShow);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring dir = CRainmeter::ExtractPath(file);
|
||||
si.lpDirectory = dir.c_str();
|
||||
si.lpParameters = args;
|
||||
si.fMask = SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI;
|
||||
ShellExecuteEx(&si);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Splits strings into parts.
|
||||
**
|
||||
*/
|
||||
std::vector<std::wstring> CCommandHandler::ParseString(LPCTSTR str, CConfigParser* parser)
|
||||
{
|
||||
std::vector<std::wstring> result;
|
||||
|
||||
if (str)
|
||||
{
|
||||
std::wstring arg = str;
|
||||
|
||||
// Split the argument between first space.
|
||||
// Or if string is in quotes, the after the second quote.
|
||||
|
||||
auto addResult = [&](std::wstring& string, bool stripQuotes)
|
||||
{
|
||||
if (stripQuotes)
|
||||
{
|
||||
size_t pos = 0;
|
||||
do
|
||||
{
|
||||
pos = string.find(L'"', pos);
|
||||
if (pos != std::wstring::npos)
|
||||
{
|
||||
string.erase(pos, 1);
|
||||
}
|
||||
}
|
||||
while (pos != std::wstring::npos);
|
||||
}
|
||||
|
||||
if (parser)
|
||||
{
|
||||
parser->ReplaceMeasures(string);
|
||||
}
|
||||
|
||||
result.push_back(string);
|
||||
};
|
||||
|
||||
size_t pos;
|
||||
std::wstring newStr;
|
||||
while ((pos = arg.find_first_not_of(L' ')) != std::wstring::npos)
|
||||
{
|
||||
size_t extra = 1;
|
||||
if (arg[pos] == L'"')
|
||||
{
|
||||
if (arg.size() > (pos + 2) &&
|
||||
arg[pos + 1] == L'"' && arg[pos + 2] == L'"')
|
||||
{
|
||||
// Eat found quotes and finding ending """
|
||||
arg.erase(0, pos + 3);
|
||||
|
||||
extra = 4;
|
||||
if ((pos = arg.find(L"\"\"\" ")) == std::wstring::npos)
|
||||
{
|
||||
extra = 3;
|
||||
pos = arg.rfind(L"\"\"\""); // search backward
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Eat found quote and find ending quote
|
||||
arg.erase(0, pos + 1);
|
||||
pos = arg.find_first_of(L'"');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pos > 0)
|
||||
{
|
||||
// Eat everything until non-space (and non-quote) char
|
||||
arg.erase(0, pos);
|
||||
}
|
||||
|
||||
// Find the second quote
|
||||
pos = arg.find_first_of(L' ');
|
||||
}
|
||||
|
||||
if (pos != std::wstring::npos)
|
||||
{
|
||||
newStr.assign(arg, 0, pos);
|
||||
arg.erase(0, pos + extra);
|
||||
|
||||
addResult(newStr, extra == 1);
|
||||
}
|
||||
else // quote or space not found
|
||||
{
|
||||
addResult(arg, extra == 1);
|
||||
arg.clear();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!arg.empty() && result.empty())
|
||||
{
|
||||
addResult(arg, true);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CCommandHandler::DoActivateSkinBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
if (args.size() == 1)
|
||||
{
|
||||
int index = Rainmeter->FindSkinFolderIndex(args[0]);
|
||||
if (index != -1)
|
||||
{
|
||||
const CRainmeter::SkinFolder& skinFolder = Rainmeter->m_SkinFolders[index];
|
||||
if (!(skinFolder.active == 1 && skinFolder.files.size() == 1))
|
||||
{
|
||||
// Activate the next index.
|
||||
Rainmeter->ActivateSkin(index, (skinFolder.active < skinFolder.files.size()) ? skinFolder.active : 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (args.size() > 1)
|
||||
{
|
||||
std::pair<int, int> indexes = Rainmeter->GetMeterWindowIndex(args[0], args[1]);
|
||||
if (indexes.first != -1 && indexes.second != -1)
|
||||
{
|
||||
Rainmeter->ActivateSkin(indexes.first, indexes.second);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LogError(L"!ActivateConfig: Invalid parameters");
|
||||
}
|
||||
|
||||
void CCommandHandler::DoDeactivateSkinBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
if (!args.empty())
|
||||
{
|
||||
skin = Rainmeter->GetMeterWindow(args[0]);
|
||||
if (!skin)
|
||||
{
|
||||
LogWarningF(L"!DeactivateConfig: \"%s\" not active", args[0].c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (skin)
|
||||
{
|
||||
Rainmeter->DeactivateSkin(skin, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError(L"!DeactivateConfig: Invalid parameters");
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandHandler::DoToggleSkinBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
if (args.size() >= 2)
|
||||
{
|
||||
CMeterWindow* skin = Rainmeter->GetMeterWindow(args[0]);
|
||||
if (skin)
|
||||
{
|
||||
Rainmeter->DeactivateSkin(skin, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
// If the skin wasn't active, activate it.
|
||||
DoActivateSkinBang(args, nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError(L"!ToggleConfig: Invalid parameters");
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandHandler::DoDeactivateSkinGroupBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
if (!args.empty())
|
||||
{
|
||||
std::multimap<int, CMeterWindow*> windows;
|
||||
Rainmeter->GetMeterWindowsByLoadOrder(windows, args[0]);
|
||||
for (const auto& ip : windows)
|
||||
{
|
||||
Rainmeter->DeactivateSkin(ip.second, -1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError(L"!DeactivateConfigGroup: Invalid parameters");
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandHandler::DoLoadLayoutBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
if (args.size() == 1)
|
||||
{
|
||||
if (skin)
|
||||
{
|
||||
// Delay to avoid loading theme in the middle of an update.
|
||||
std::wstring command = L"!LoadLayout \"";
|
||||
command += args[0];
|
||||
command += L'"';
|
||||
Rainmeter->DelayedExecuteCommand(command.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not called from a skin (or called with delay).
|
||||
Rainmeter->LoadLayout(args[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandHandler::DoSetClipBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
if (!args.empty())
|
||||
{
|
||||
CSystem::SetClipboardText(args[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError(L"!SetClip: Invalid parameter");
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandHandler::DoSetWallpaperBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
const size_t argsSize = args.size();
|
||||
if (argsSize >= 1 && argsSize <= 2)
|
||||
{
|
||||
std::wstring& file = args[0];
|
||||
const std::wstring& style = (argsSize == 2) ? args[1] : L"";
|
||||
|
||||
if (skin)
|
||||
{
|
||||
skin->MakePathAbsolute(file);
|
||||
}
|
||||
|
||||
CSystem::SetWallpaper(file, style);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError(L"!SetWallpaper: Invalid parameters");
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandHandler::DoAboutBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
||||
{
|
||||
CDialogAbout::Open(args.empty() ? L"" : args[0].c_str());
|
||||
}
|
||||
|
||||
void CCommandHandler::DoManageBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
||||
{
|
||||
CDialogManage::Open(args.empty() ? L"" : args[0].c_str());
|
||||
}
|
||||
|
||||
void CCommandHandler::DoSkinMenuBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
if (!args.empty())
|
||||
{
|
||||
skin = Rainmeter->GetMeterWindow(args[0]);
|
||||
if (!skin)
|
||||
{
|
||||
LogWarningF(L"!SkinMenu: \"%s\" not active", args[0].c_str());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (skin)
|
||||
{
|
||||
POINT pos = CSystem::GetCursorPosition();
|
||||
Rainmeter->ShowContextMenu(pos, skin);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError(L"!SkinMenu: Invalid parameter");
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandHandler::DoTrayMenuBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
POINT pos = CSystem::GetCursorPosition();
|
||||
Rainmeter->ShowContextMenu(pos, NULL);
|
||||
}
|
||||
|
||||
void CCommandHandler::DoResetStatsBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
||||
{
|
||||
Rainmeter->ResetStats();
|
||||
}
|
||||
|
||||
void CCommandHandler::DoWriteKeyValueBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
if (args.size() == 3 && skin)
|
||||
{
|
||||
// Add the skin file path to the args
|
||||
args.push_back(skin->GetFilePath());
|
||||
}
|
||||
else if (args.size() < 4)
|
||||
{
|
||||
LogError(L"!WriteKeyValue: Invalid parameters");
|
||||
return;
|
||||
}
|
||||
|
||||
std::wstring& strIniFile = args[3];
|
||||
if (skin)
|
||||
{
|
||||
skin->MakePathAbsolute(strIniFile);
|
||||
}
|
||||
|
||||
const WCHAR* iniFile = strIniFile.c_str();
|
||||
|
||||
if (strIniFile.find(L"..\\") != std::wstring::npos || strIniFile.find(L"../") != std::wstring::npos)
|
||||
{
|
||||
LogErrorF(L"!WriteKeyValue: Illegal path: %s", iniFile);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_wcsnicmp(iniFile, Rainmeter->m_SkinPath.c_str(), Rainmeter->m_SkinPath.size()) != 0 &&
|
||||
_wcsnicmp(iniFile, Rainmeter->m_SettingsPath.c_str(), Rainmeter->m_SettingsPath.size()) != 0)
|
||||
{
|
||||
LogErrorF(L"!WriteKeyValue: Illegal path: %s", iniFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify whether the file exists.
|
||||
if (_waccess(iniFile, 0) == -1)
|
||||
{
|
||||
LogErrorF(L"!WriteKeyValue: File not found: %s", iniFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// Verify whether the file is read-only.
|
||||
DWORD attr = GetFileAttributes(iniFile);
|
||||
if (attr == -1 || (attr & FILE_ATTRIBUTE_READONLY))
|
||||
{
|
||||
LogWarningF(L"!WriteKeyValue: File is read-only: %s", iniFile);
|
||||
return;
|
||||
}
|
||||
|
||||
// Avoid "IniFileMapping"
|
||||
CSystem::UpdateIniFileMappingList();
|
||||
std::wstring strIniWrite = CSystem::GetTemporaryFile(strIniFile);
|
||||
if (strIniWrite.size() == 1 && strIniWrite[0] == L'?') // error occurred
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bool temporary = !strIniWrite.empty();
|
||||
|
||||
if (temporary)
|
||||
{
|
||||
if (Rainmeter->GetDebug())
|
||||
{
|
||||
LogDebugF(L"!WriteKeyValue: Writing to: %s (Temp: %s)", iniFile, strIniWrite.c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Rainmeter->GetDebug())
|
||||
{
|
||||
LogDebugF(L"!WriteKeyValue: Writing to: %s", iniFile);
|
||||
}
|
||||
strIniWrite = strIniFile;
|
||||
}
|
||||
|
||||
const WCHAR* iniWrite = strIniWrite.c_str();
|
||||
const WCHAR* section = args[0].c_str();
|
||||
const WCHAR* key = args[1].c_str();
|
||||
const std::wstring& strValue = args[2];
|
||||
|
||||
bool formula = false;
|
||||
BOOL write = 0;
|
||||
|
||||
if (skin)
|
||||
{
|
||||
double value;
|
||||
if (skin->GetParser().ParseFormula(strValue, &value))
|
||||
{
|
||||
WCHAR buffer[256];
|
||||
int len = _snwprintf_s(buffer, _TRUNCATE, L"%.5f", value);
|
||||
CMeasure::RemoveTrailingZero(buffer, len);
|
||||
|
||||
write = WritePrivateProfileString(section, key, buffer, iniWrite);
|
||||
}
|
||||
}
|
||||
|
||||
if (!formula)
|
||||
{
|
||||
write = WritePrivateProfileString(section, key, strValue.c_str(), iniWrite);
|
||||
}
|
||||
|
||||
if (temporary)
|
||||
{
|
||||
if (write != 0)
|
||||
{
|
||||
WritePrivateProfileString(NULL, NULL, NULL, iniWrite); // FLUSH
|
||||
|
||||
// Copy the file back.
|
||||
if (!CSystem::CopyFiles(strIniWrite, strIniFile))
|
||||
{
|
||||
LogErrorF(L"!WriteKeyValue: Failed to copy temporary file to original filepath: %s (Temp: %s)", iniFile, iniWrite);
|
||||
}
|
||||
}
|
||||
else // failed
|
||||
{
|
||||
LogErrorF(L"!WriteKeyValue: Failed to write to: %s (Temp: %s)", iniFile, iniWrite);
|
||||
}
|
||||
|
||||
// Remove the temporary file.
|
||||
CSystem::RemoveFile(strIniWrite);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (write == 0) // failed
|
||||
{
|
||||
LogErrorF(L"!WriteKeyValue: Failed to write to: %s", iniFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandHandler::DoLogBang(std::vector<std::wstring>& args, CMeterWindow* skin)
|
||||
{
|
||||
if (!args.empty())
|
||||
{
|
||||
CLogger::Level level = CLogger::Level::Notice;
|
||||
if (args.size() > 1)
|
||||
{
|
||||
const WCHAR* type = args[1].c_str();
|
||||
if (_wcsicmp(type, L"ERROR") == 0)
|
||||
{
|
||||
level = CLogger::Level::Error;
|
||||
}
|
||||
else if (_wcsicmp(type, L"WARNING") == 0)
|
||||
{
|
||||
level = CLogger::Level::Warning;
|
||||
}
|
||||
else if (_wcsicmp(type, L"DEBUG") == 0)
|
||||
{
|
||||
level = CLogger::Level::Debug;
|
||||
}
|
||||
else if (_wcsicmp(type, L"NOTICE") != 0)
|
||||
{
|
||||
LogError(L"!Log: Invalid type");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CLogger::GetInstance().Log(level, args[0].c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void CCommandHandler::DoRefreshApp(std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
||||
{
|
||||
// Refresh needs to be delayed since it crashes if done during Update().
|
||||
PostMessage(Rainmeter->m_Window, WM_RAINMETER_DELAYED_REFRESH_ALL, NULL, NULL);
|
||||
}
|
||||
|
||||
void CCommandHandler::DoQuitBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
||||
{
|
||||
// Quit needs to be delayed since it crashes if done during Update().
|
||||
PostMessage(Rainmeter->GetTrayWindow()->GetWindow(), WM_COMMAND, MAKEWPARAM(IDM_QUIT, 0), NULL);
|
||||
}
|
||||
|
||||
void CCommandHandler::DoLsBoxHookBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow)
|
||||
{
|
||||
// Deprecated.
|
||||
}
|
141
Library/CommandHandler.h
Normal file
141
Library/CommandHandler.h
Normal file
@ -0,0 +1,141 @@
|
||||
/*
|
||||
Copyright (C) 2012 Rainmeter Team
|
||||
|
||||
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 Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef RM_LIBRARY_COMMANDHANDLER_H_
|
||||
#define RM_LIBRARY_COMMANDHANDLER_H_
|
||||
|
||||
#include <Windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class CConfigParser;
|
||||
class CMeterWindow;
|
||||
|
||||
enum class Bang
|
||||
{
|
||||
Refresh,
|
||||
RefreshApp,
|
||||
Redraw,
|
||||
Update,
|
||||
Hide,
|
||||
Show,
|
||||
Toggle,
|
||||
HideFade,
|
||||
ShowFade,
|
||||
ToggleFade,
|
||||
HideMeter,
|
||||
ShowMeter,
|
||||
ToggleMeter,
|
||||
MoveMeter,
|
||||
UpdateMeter,
|
||||
DisableMeasure,
|
||||
EnableMeasure,
|
||||
ToggleMeasure,
|
||||
UpdateMeasure,
|
||||
CommandMeasure,
|
||||
PluginBang,
|
||||
ShowBlur,
|
||||
HideBlur,
|
||||
ToggleBlur,
|
||||
AddBlur,
|
||||
RemoveBlur,
|
||||
ActivateConfig,
|
||||
DeactivateConfig,
|
||||
ToggleConfig,
|
||||
Move,
|
||||
ZPos,
|
||||
ChangeZPos,
|
||||
ClickThrough,
|
||||
Draggable,
|
||||
SnapEdges,
|
||||
KeepOnScreen,
|
||||
SetTransparency,
|
||||
SetVariable,
|
||||
SetOption,
|
||||
RefreshGroup,
|
||||
UpdateGroup,
|
||||
RedrawGroup,
|
||||
HideGroup,
|
||||
ShowGroup,
|
||||
ToggleGroup,
|
||||
HideFadeGroup,
|
||||
ShowFadeGroup,
|
||||
ToggleFadeGroup,
|
||||
HideMeterGroup,
|
||||
ShowMeterGroup,
|
||||
ToggleMeterGroup,
|
||||
UpdateMeterGroup,
|
||||
DisableMeasureGroup,
|
||||
EnableMeasureGroup,
|
||||
ToggleMeasureGroup,
|
||||
UpdateMeasureGroup,
|
||||
DeactivateConfigGroup,
|
||||
ZPosGroup,
|
||||
ClickThroughGroup,
|
||||
DraggableGroup,
|
||||
SnapEdgesGroup,
|
||||
KeepOnScreenGroup,
|
||||
SetTransparencyGroup,
|
||||
SetVariableGroup,
|
||||
SetOptionGroup,
|
||||
WriteKeyValue,
|
||||
LoadLayout,
|
||||
SetClip,
|
||||
SetWallpaper,
|
||||
About,
|
||||
Manage,
|
||||
SkinMenu,
|
||||
TrayMenu,
|
||||
ResetStats,
|
||||
Log,
|
||||
Quit,
|
||||
LsBoxHook
|
||||
};
|
||||
|
||||
// Parses and executes commands and bangs.
|
||||
class CCommandHandler
|
||||
{
|
||||
public:
|
||||
void ExecuteCommand(const WCHAR* command, CMeterWindow* skin, bool multi = true);
|
||||
void ExecuteBang(const WCHAR* name, std::vector<std::wstring>& args, CMeterWindow* skin);
|
||||
|
||||
static void RunCommand(std::wstring command);
|
||||
static void RunFile(const WCHAR* file, const WCHAR* args = NULL);
|
||||
|
||||
static std::vector<std::wstring> ParseString(const WCHAR* str, CConfigParser* parser = NULL);
|
||||
|
||||
static void DoActivateSkinBang(std::vector<std::wstring>& args, CMeterWindow* skin);
|
||||
static void DoDeactivateSkinBang(std::vector<std::wstring>& args, CMeterWindow* skin);
|
||||
static void DoToggleSkinBang(std::vector<std::wstring>& args, CMeterWindow* skin);
|
||||
static void DoDeactivateSkinGroupBang(std::vector<std::wstring>& args, CMeterWindow* skin);
|
||||
static void DoLoadLayoutBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
static void DoSetClipBang(std::vector<std::wstring>& args, CMeterWindow* skin);
|
||||
static void DoSetWallpaperBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
static void DoAboutBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
static void DoManageBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
static void DoSkinMenuBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
static void DoTrayMenuBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
static void DoResetStatsBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
static void DoWriteKeyValueBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
static void DoLogBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
static void DoRefreshApp(std::vector<std::wstring>& args, CMeterWindow* skin);
|
||||
static void DoQuitBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
static void DoLsBoxHookBang(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
};
|
||||
|
||||
#endif
|
@ -1252,11 +1252,11 @@ INT_PTR CDialogAbout::CTabVersion::OnNotify(WPARAM wParam, LPARAM lParam)
|
||||
case NM_CLICK:
|
||||
if (nm->idFrom == Id_HomeLink)
|
||||
{
|
||||
RunFile(L"http://rainmeter.net");
|
||||
CCommandHandler::RunFile(L"http://rainmeter.net");
|
||||
}
|
||||
else if (nm->idFrom == Id_HomeLink)
|
||||
{
|
||||
RunFile(L"http://gnu.org/licenses");
|
||||
CCommandHandler::RunFile(L"http://gnu.org/licenses");
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#define __DIALOGABOUT_H__
|
||||
|
||||
#include "../Common/Dialog.h"
|
||||
#include "Logger.h"
|
||||
#include "MeterWindow.h"
|
||||
|
||||
class CDialogAbout : public CDialog
|
||||
{
|
||||
|
@ -1041,7 +1041,7 @@ INT_PTR CDialogManage::CTabSkins::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
case Id_CreateSkinPackageButton:
|
||||
{
|
||||
std::wstring file = Rainmeter->GetPath() + L"SkinInstaller.exe";
|
||||
RunFile(file.c_str(), L"/Packager");
|
||||
CCommandHandler::RunFile(file.c_str(), L"/Packager");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1733,7 +1733,7 @@ INT_PTR CDialogManage::CTabLayouts::OnCommand(WPARAM wParam, LPARAM lParam)
|
||||
args += layouts[sel];
|
||||
args += L"\\Rainmeter.ini";
|
||||
args += L'"';
|
||||
RunFile(Rainmeter->GetSkinEditor().c_str(), args.c_str());
|
||||
CCommandHandler::RunFile(Rainmeter->GetSkinEditor().c_str(), args.c_str());
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -161,7 +161,7 @@ LPCWSTR PluginBridge(LPCWSTR command, LPCWSTR data)
|
||||
}
|
||||
else if (_wcsicmp(command, L"GetWindow") == 0)
|
||||
{
|
||||
std::vector<std::wstring> subStrings = CRainmeter::ParseString(data);
|
||||
std::vector<std::wstring> subStrings = CCommandHandler::ParseString(data);
|
||||
|
||||
if (subStrings.size() >= 1)
|
||||
{
|
||||
@ -181,7 +181,7 @@ LPCWSTR PluginBridge(LPCWSTR command, LPCWSTR data)
|
||||
}
|
||||
else if (_wcsicmp(command, L"GetVariable") == 0)
|
||||
{
|
||||
std::vector<std::wstring> subStrings = CRainmeter::ParseString(data);
|
||||
std::vector<std::wstring> subStrings = CCommandHandler::ParseString(data);
|
||||
|
||||
if (subStrings.size() >= 2)
|
||||
{
|
||||
@ -204,7 +204,7 @@ LPCWSTR PluginBridge(LPCWSTR command, LPCWSTR data)
|
||||
}
|
||||
else if (_wcsicmp(command, L"SetVariable") == 0)
|
||||
{
|
||||
std::vector<std::wstring> subStrings = CRainmeter::ParseString(data);
|
||||
std::vector<std::wstring> subStrings = CCommandHandler::ParseString(data);
|
||||
|
||||
if (subStrings.size() == 3)
|
||||
{
|
||||
|
@ -84,6 +84,9 @@
|
||||
<ClCompile Include="..\Common\MenuTemplate.cpp" />
|
||||
<ClCompile Include="..\Common\Platform.cpp" />
|
||||
<ClCompile Include="..\Common\StringUtil.cpp" />
|
||||
<ClCompile Include="CommandHandler.cpp">
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ConfigParser.cpp">
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
@ -312,6 +315,7 @@
|
||||
<ClInclude Include="..\Common\MenuTemplate.h" />
|
||||
<ClInclude Include="..\Common\Platform.h" />
|
||||
<ClInclude Include="..\Common\StringUtil.h" />
|
||||
<ClInclude Include="CommandHandler.h" />
|
||||
<ClInclude Include="ConfigParser.h" />
|
||||
<ClInclude Include="DialogAbout.h" />
|
||||
<ClInclude Include="DisableThreadLibraryCalls.h" />
|
||||
|
@ -393,6 +393,9 @@
|
||||
<ClCompile Include="Logger.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CommandHandler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ConfigParser.h">
|
||||
@ -686,6 +689,9 @@
|
||||
<ClInclude Include="Logger.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="CommandHandler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Library.rc">
|
||||
|
@ -30,65 +30,6 @@ UINT GetUniqueID()
|
||||
return id++;
|
||||
}
|
||||
|
||||
void RunCommand(std::wstring command)
|
||||
{
|
||||
std::wstring args;
|
||||
|
||||
size_t notwhite = command.find_first_not_of(L" \t\r\n");
|
||||
command.erase(0, notwhite);
|
||||
|
||||
size_t quotePos = command.find(L'"');
|
||||
if (quotePos == 0)
|
||||
{
|
||||
size_t quotePos2 = command.find(L'"', quotePos + 1);
|
||||
if (quotePos2 != std::wstring::npos)
|
||||
{
|
||||
args.assign(command, quotePos2 + 1, command.length() - (quotePos2 + 1));
|
||||
command.assign(command, quotePos + 1, quotePos2 - quotePos - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
command.erase(0, 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t spacePos = command.find(L' ');
|
||||
if (spacePos != std::wstring::npos)
|
||||
{
|
||||
args.assign(command, spacePos + 1, command.length() - (spacePos + 1));
|
||||
command.erase(spacePos);
|
||||
}
|
||||
}
|
||||
|
||||
if (!command.empty())
|
||||
{
|
||||
RunFile(command.c_str(), args.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void RunFile(const WCHAR* file, const WCHAR* args)
|
||||
{
|
||||
SHELLEXECUTEINFO si = {sizeof(SHELLEXECUTEINFO)};
|
||||
si.lpVerb = L"open";
|
||||
si.lpFile = file;
|
||||
si.nShow = SW_SHOWNORMAL;
|
||||
|
||||
DWORD type = GetFileAttributes(si.lpFile);
|
||||
if (type & FILE_ATTRIBUTE_DIRECTORY && type != 0xFFFFFFFF)
|
||||
{
|
||||
ShellExecute(si.hwnd, si.lpVerb, si.lpFile, NULL, NULL, si.nShow);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::wstring dir = CRainmeter::ExtractPath(file);
|
||||
si.lpDirectory = dir.c_str();
|
||||
si.lpParameters = args;
|
||||
si.fMask = SEE_MASK_DOENVSUBST | SEE_MASK_FLAG_NO_UI;
|
||||
ShellExecuteEx(&si);
|
||||
}
|
||||
}
|
||||
|
||||
WCHAR* GetString(UINT id)
|
||||
{
|
||||
LPWSTR pData;
|
||||
|
@ -30,9 +30,6 @@ UINT GetUniqueID();
|
||||
template <typename T>
|
||||
UINT TypeID() { static UINT id = GetUniqueID(); return id; }
|
||||
|
||||
void RunCommand(std::wstring command);
|
||||
void RunFile(const WCHAR* file, const WCHAR* args = NULL);
|
||||
|
||||
WCHAR* GetString(UINT id);
|
||||
std::wstring GetFormattedString(UINT id, ...);
|
||||
|
||||
|
@ -706,20 +706,20 @@ void CMeterWindow::ChangeSingleZPos(ZPOSITION zPos, bool all)
|
||||
** Runs the bang command with the given arguments.
|
||||
** Correct number of arguments must be passed (or use CRainmeter::ExecuteBang).
|
||||
*/
|
||||
void CMeterWindow::RunBang(BANGCOMMAND bang, const std::vector<std::wstring>& args)
|
||||
void CMeterWindow::DoBang(Bang bang, const std::vector<std::wstring>& args)
|
||||
{
|
||||
switch (bang)
|
||||
{
|
||||
case BANG_REFRESH:
|
||||
case Bang::Refresh:
|
||||
// Refresh needs to be delayed since it crashes if done during Update()
|
||||
PostMessage(m_Window, WM_METERWINDOW_DELAYED_REFRESH, (WPARAM)NULL, (LPARAM)NULL);
|
||||
break;
|
||||
|
||||
case BANG_REDRAW:
|
||||
case Bang::Redraw:
|
||||
Redraw();
|
||||
break;
|
||||
|
||||
case BANG_UPDATE:
|
||||
case Bang::Update:
|
||||
KillTimer(m_Window, TIMER_METER); // Kill timer temporarily
|
||||
Update(false);
|
||||
if (m_WindowUpdate >= 0)
|
||||
@ -728,122 +728,122 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const std::vector<std::wstring>& ar
|
||||
}
|
||||
break;
|
||||
|
||||
case BANG_SHOWBLUR:
|
||||
case Bang::ShowBlur:
|
||||
ShowBlur();
|
||||
break;
|
||||
|
||||
case BANG_HIDEBLUR:
|
||||
case Bang::HideBlur:
|
||||
HideBlur();
|
||||
break;
|
||||
|
||||
case BANG_TOGGLEBLUR:
|
||||
RunBang(IsBlur() ? BANG_HIDEBLUR : BANG_SHOWBLUR, args);
|
||||
case Bang::ToggleBlur:
|
||||
DoBang(IsBlur() ? Bang::HideBlur : Bang::ShowBlur, args);
|
||||
break;
|
||||
|
||||
case BANG_ADDBLUR:
|
||||
case Bang::AddBlur:
|
||||
ResizeBlur(args[0], RGN_OR);
|
||||
if (IsBlur()) ShowBlur();
|
||||
break;
|
||||
|
||||
case BANG_REMOVEBLUR:
|
||||
case Bang::RemoveBlur:
|
||||
ResizeBlur(args[0], RGN_DIFF);
|
||||
if (IsBlur()) ShowBlur();
|
||||
break;
|
||||
|
||||
case BANG_TOGGLEMETER:
|
||||
case Bang::ToggleMeter:
|
||||
ToggleMeter(args[0]);
|
||||
break;
|
||||
|
||||
case BANG_SHOWMETER:
|
||||
case Bang::ShowMeter:
|
||||
ShowMeter(args[0]);
|
||||
break;
|
||||
|
||||
case BANG_HIDEMETER:
|
||||
case Bang::HideMeter:
|
||||
HideMeter(args[0]);
|
||||
break;
|
||||
|
||||
case BANG_UPDATEMETER:
|
||||
case Bang::UpdateMeter:
|
||||
UpdateMeter(args[0]);
|
||||
break;
|
||||
|
||||
case BANG_TOGGLEMETERGROUP:
|
||||
case Bang::ToggleMeterGroup:
|
||||
ToggleMeter(args[0], true);
|
||||
break;
|
||||
|
||||
case BANG_SHOWMETERGROUP:
|
||||
case Bang::ShowMeterGroup:
|
||||
ShowMeter(args[0], true);
|
||||
break;
|
||||
|
||||
case BANG_HIDEMETERGROUP:
|
||||
case Bang::HideMeterGroup:
|
||||
HideMeter(args[0], true);
|
||||
break;
|
||||
|
||||
case BANG_UPDATEMETERGROUP:
|
||||
case Bang::UpdateMeterGroup:
|
||||
UpdateMeter(args[0], true);
|
||||
break;
|
||||
|
||||
case BANG_TOGGLEMEASURE:
|
||||
case Bang::ToggleMeasure:
|
||||
ToggleMeasure(args[0]);
|
||||
break;
|
||||
|
||||
case BANG_ENABLEMEASURE:
|
||||
case Bang::EnableMeasure:
|
||||
EnableMeasure(args[0]);
|
||||
break;
|
||||
|
||||
case BANG_DISABLEMEASURE:
|
||||
case Bang::DisableMeasure:
|
||||
DisableMeasure(args[0]);
|
||||
break;
|
||||
|
||||
case BANG_UPDATEMEASURE:
|
||||
case Bang::UpdateMeasure:
|
||||
UpdateMeasure(args[0]);
|
||||
CDialogAbout::UpdateMeasures(this);
|
||||
break;
|
||||
|
||||
case BANG_DISABLEMEASUREGROUP:
|
||||
case Bang::DisableMeasureGroup:
|
||||
DisableMeasure(args[0], true);
|
||||
break;
|
||||
|
||||
case BANG_TOGGLEMEASUREGROUP:
|
||||
case Bang::ToggleMeasureGroup:
|
||||
ToggleMeasure(args[0], true);
|
||||
break;
|
||||
|
||||
case BANG_ENABLEMEASUREGROUP:
|
||||
case Bang::EnableMeasureGroup:
|
||||
EnableMeasure(args[0], true);
|
||||
break;
|
||||
|
||||
case BANG_UPDATEMEASUREGROUP:
|
||||
case Bang::UpdateMeasureGroup:
|
||||
UpdateMeasure(args[0], true);
|
||||
CDialogAbout::UpdateMeasures(this);
|
||||
break;
|
||||
|
||||
case BANG_SHOW:
|
||||
case Bang::Show:
|
||||
m_Hidden = false;
|
||||
ShowWindow(m_Window, SW_SHOWNOACTIVATE);
|
||||
UpdateWindowTransparency((m_WindowHide == HIDEMODE_FADEOUT) ? 255 : m_AlphaValue);
|
||||
break;
|
||||
|
||||
case BANG_HIDE:
|
||||
case Bang::Hide:
|
||||
m_Hidden = true;
|
||||
ShowWindow(m_Window, SW_HIDE);
|
||||
break;
|
||||
|
||||
case BANG_TOGGLE:
|
||||
RunBang(m_Hidden ? BANG_SHOW : BANG_HIDE, args);
|
||||
case Bang::Toggle:
|
||||
DoBang(m_Hidden ? Bang::Show : Bang::Toggle, args);
|
||||
break;
|
||||
|
||||
case BANG_SHOWFADE:
|
||||
case Bang::ShowFade:
|
||||
ShowFade();
|
||||
break;
|
||||
|
||||
case BANG_HIDEFADE:
|
||||
case Bang::HideFade:
|
||||
HideFade();
|
||||
break;
|
||||
|
||||
case BANG_TOGGLEFADE:
|
||||
RunBang(m_Hidden ? BANG_SHOWFADE : BANG_HIDEFADE, args);
|
||||
case Bang::ToggleFade:
|
||||
DoBang(m_Hidden ? Bang::ShowFade : Bang::HideFade, args);
|
||||
break;
|
||||
|
||||
case BANG_MOVE:
|
||||
case Bang::Move:
|
||||
{
|
||||
int x = m_Parser.ParseInt(args[0].c_str(), 0);
|
||||
int y = m_Parser.ParseInt(args[1].c_str(), 0);
|
||||
@ -851,39 +851,39 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const std::vector<std::wstring>& ar
|
||||
}
|
||||
break;
|
||||
|
||||
case BANG_ZPOS:
|
||||
case Bang::ZPos:
|
||||
SetWindowZPosition((ZPOSITION)m_Parser.ParseInt(args[0].c_str(), 0));
|
||||
break;
|
||||
|
||||
case BANG_CLICKTHROUGH:
|
||||
case Bang::ClickThrough:
|
||||
{
|
||||
int f = m_Parser.ParseInt(args[0].c_str(), 0);
|
||||
SetClickThrough((f == -1) ? !m_ClickThrough : f);
|
||||
}
|
||||
break;
|
||||
|
||||
case BANG_DRAGGABLE:
|
||||
case Bang::Draggable:
|
||||
{
|
||||
int f = m_Parser.ParseInt(args[0].c_str(), 0);
|
||||
SetWindowDraggable((f == -1) ? !m_WindowDraggable : f);
|
||||
}
|
||||
break;
|
||||
|
||||
case BANG_SNAPEDGES:
|
||||
case Bang::SnapEdges:
|
||||
{
|
||||
int f = m_Parser.ParseInt(args[0].c_str(), 0);
|
||||
SetSnapEdges((f == -1) ? !m_SnapEdges : f);
|
||||
}
|
||||
break;
|
||||
|
||||
case BANG_KEEPONSCREEN:
|
||||
case Bang::KeepOnScreen:
|
||||
{
|
||||
int f = m_Parser.ParseInt(args[0].c_str(), 0);
|
||||
SetKeepOnScreen((f == -1) ? !m_KeepOnScreen : f);
|
||||
}
|
||||
break;
|
||||
|
||||
case BANG_SETTRANSPARENCY:
|
||||
case Bang::SetTransparency:
|
||||
{
|
||||
const std::wstring& arg = args[0];
|
||||
m_AlphaValue = CConfigParser::ParseInt(arg.c_str(), 255);
|
||||
@ -893,7 +893,7 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const std::vector<std::wstring>& ar
|
||||
}
|
||||
break;
|
||||
|
||||
case BANG_MOVEMETER:
|
||||
case Bang::MoveMeter:
|
||||
{
|
||||
int x = m_Parser.ParseInt(args[0].c_str(), 0);
|
||||
int y = m_Parser.ParseInt(args[1].c_str(), 0);
|
||||
@ -901,7 +901,7 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const std::vector<std::wstring>& ar
|
||||
}
|
||||
break;
|
||||
|
||||
case BANG_COMMANDMEASURE:
|
||||
case Bang::CommandMeasure:
|
||||
{
|
||||
const std::wstring& measure = args[0];
|
||||
CMeasure* m = GetMeasure(measure);
|
||||
@ -916,7 +916,7 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const std::vector<std::wstring>& ar
|
||||
}
|
||||
break;
|
||||
|
||||
case BANG_PLUGIN:
|
||||
case Bang::PluginBang:
|
||||
{
|
||||
std::wstring arg = args[0];
|
||||
std::wstring::size_type pos;
|
||||
@ -956,15 +956,15 @@ void CMeterWindow::RunBang(BANGCOMMAND bang, const std::vector<std::wstring>& ar
|
||||
}
|
||||
break;
|
||||
|
||||
case BANG_SETVARIABLE:
|
||||
case Bang::SetVariable:
|
||||
SetVariable(args[0], args[1]);
|
||||
break;
|
||||
|
||||
case BANG_SETOPTION:
|
||||
case Bang::SetOption:
|
||||
SetOption(args[0], args[1], args[2], false);
|
||||
break;
|
||||
|
||||
case BANG_SETOPTIONGROUP:
|
||||
case Bang::SetOptionGroup:
|
||||
SetOption(args[0], args[1], args[2], true);
|
||||
break;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <dwmapi.h>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include "CommandHandler.h"
|
||||
#include "ConfigParser.h"
|
||||
#include "Group.h"
|
||||
#include "Mouse.h"
|
||||
@ -91,55 +92,6 @@ enum BEVELTYPE
|
||||
BEVELTYPE_DOWN
|
||||
};
|
||||
|
||||
enum BANGCOMMAND
|
||||
{
|
||||
BANG_REFRESH,
|
||||
BANG_REDRAW,
|
||||
BANG_UPDATE,
|
||||
BANG_TOGGLEMETER,
|
||||
BANG_SHOWMETER,
|
||||
BANG_HIDEMETER,
|
||||
BANG_MOVEMETER,
|
||||
BANG_UPDATEMETER,
|
||||
BANG_TOGGLEMEASURE,
|
||||
BANG_ENABLEMEASURE,
|
||||
BANG_DISABLEMEASURE,
|
||||
BANG_UPDATEMEASURE,
|
||||
BANG_COMMANDMEASURE,
|
||||
BANG_SHOWBLUR,
|
||||
BANG_HIDEBLUR,
|
||||
BANG_TOGGLEBLUR,
|
||||
BANG_ADDBLUR,
|
||||
BANG_REMOVEBLUR,
|
||||
BANG_SHOW,
|
||||
BANG_HIDE,
|
||||
BANG_TOGGLE,
|
||||
BANG_SHOWFADE,
|
||||
BANG_HIDEFADE,
|
||||
BANG_TOGGLEFADE,
|
||||
BANG_MOVE,
|
||||
BANG_ZPOS,
|
||||
BANG_SETTRANSPARENCY,
|
||||
BANG_CLICKTHROUGH,
|
||||
BANG_DRAGGABLE,
|
||||
BANG_SNAPEDGES,
|
||||
BANG_KEEPONSCREEN,
|
||||
|
||||
BANG_TOGGLEMETERGROUP,
|
||||
BANG_SHOWMETERGROUP,
|
||||
BANG_HIDEMETERGROUP,
|
||||
BANG_UPDATEMETERGROUP,
|
||||
BANG_TOGGLEMEASUREGROUP,
|
||||
BANG_ENABLEMEASUREGROUP,
|
||||
BANG_DISABLEMEASUREGROUP,
|
||||
BANG_UPDATEMEASUREGROUP,
|
||||
|
||||
BANG_PLUGIN,
|
||||
BANG_SETVARIABLE,
|
||||
BANG_SETOPTION,
|
||||
BANG_SETOPTIONGROUP
|
||||
};
|
||||
|
||||
enum RESIZEMODE
|
||||
{
|
||||
RESIZEMODE_NONE = 0,
|
||||
@ -165,7 +117,7 @@ public:
|
||||
|
||||
void Initialize();
|
||||
|
||||
void RunBang(BANGCOMMAND bang, const std::vector<std::wstring>& args);
|
||||
void DoBang(Bang bang, const std::vector<std::wstring>& args);
|
||||
|
||||
void HideMeter(const std::wstring& name, bool group = false);
|
||||
void ShowMeter(const std::wstring& name, bool group = false);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,7 @@
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include "Litestep.h"
|
||||
#include "CommandHandler.h"
|
||||
#include "Logger.h"
|
||||
#include "MeterWindow.h"
|
||||
|
||||
@ -212,29 +212,15 @@ public:
|
||||
bool LoadLayout(const std::wstring& name);
|
||||
void PreserveSetting(const std::wstring& from, LPCTSTR key, bool replace = true);
|
||||
|
||||
static std::vector<std::wstring> ParseString(LPCTSTR str, CConfigParser* parser = NULL);
|
||||
static std::wstring ExtractPath(const std::wstring& strFilePath);
|
||||
static void ExpandEnvironmentVariables(std::wstring& strPath);
|
||||
|
||||
friend class CCommandHandler;
|
||||
friend class CDialogManage;
|
||||
|
||||
private:
|
||||
static LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
void BangWithArgs(BANGCOMMAND bang, std::vector<std::wstring>& args, size_t numOfArgs, CMeterWindow* meterWindow);
|
||||
void BangGroupWithArgs(BANGCOMMAND bang, std::vector<std::wstring>& args, size_t numOfArgs, CMeterWindow* meterWindow);
|
||||
void Bang_ActivateSkin(std::vector<std::wstring>& args);
|
||||
void Bang_DeactivateSkin(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
void Bang_ToggleSkin(std::vector<std::wstring>& args);
|
||||
void Bang_DeactivateSkinGroup(std::vector<std::wstring>& args);
|
||||
void Bang_LoadLayout(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
void Bang_SetClip(std::vector<std::wstring>& args);
|
||||
void Bang_SetWallpaper(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
void Bang_SkinMenu(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
void Bang_TrayMenu();
|
||||
void Bang_WriteKeyValue(std::vector<std::wstring>& args, CMeterWindow* meterWindow);
|
||||
void Bang_Log(std::vector<std::wstring>& args);
|
||||
|
||||
void ActivateActiveSkins();
|
||||
void CreateMeterWindow(const std::wstring& folderPath, const std::wstring& file);
|
||||
void DeleteAllMeterWindows();
|
||||
@ -306,6 +292,8 @@ private:
|
||||
|
||||
std::wstring m_SkinEditor;
|
||||
|
||||
CCommandHandler m_CommandHandler;
|
||||
|
||||
CConfigParser* m_CurrentParser;
|
||||
|
||||
HWND m_Window;
|
||||
|
@ -475,11 +475,11 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
break;
|
||||
|
||||
case IDM_SHOW_HELP:
|
||||
RunFile(RAINMETER_HELP);
|
||||
CCommandHandler::RunFile(RAINMETER_HELP);
|
||||
break;
|
||||
|
||||
case IDM_NEW_VERSION:
|
||||
RunFile(RAINMETER_OFFICIAL);
|
||||
CCommandHandler::RunFile(RAINMETER_OFFICIAL);
|
||||
break;
|
||||
|
||||
case IDM_REFRESH:
|
||||
@ -634,7 +634,7 @@ LRESULT CALLBACK CTrayWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA
|
||||
}
|
||||
else if (tray->m_Notification == TRAY_NOTIFICATION_UPDATE)
|
||||
{
|
||||
RunFile(RAINMETER_OFFICIAL);
|
||||
CCommandHandler::RunFile(RAINMETER_OFFICIAL);
|
||||
}
|
||||
tray->m_Notification = TRAY_NOTIFICATION_NONE;
|
||||
break;
|
||||
|
@ -17,8 +17,9 @@
|
||||
*/
|
||||
|
||||
#include "../StdAfx.h"
|
||||
#include "../../Common/StringUtil.h"
|
||||
#include "LuaManager.h"
|
||||
#include "../Rainmeter.h"
|
||||
#include "../Logger.h"
|
||||
|
||||
int LuaManager::c_RefCount = 0;
|
||||
lua_State* LuaManager::c_State = 0;
|
||||
|
@ -17,9 +17,9 @@
|
||||
*/
|
||||
|
||||
#include "../StdAfx.h"
|
||||
#include "../../Common/StringUtil.h"
|
||||
#include "LuaScript.h"
|
||||
#include "LuaManager.h"
|
||||
#include "../Rainmeter.h"
|
||||
|
||||
/*
|
||||
** The constructor
|
||||
|
Loading…
Reference in New Issue
Block a user