1
0
Fork 0

DBG+BRIDGE+GUI: plugin hotkeys

This commit is contained in:
mrexodia 2017-04-14 08:03:52 +02:00
parent d5e224a7a5
commit 7a52b28c55
No known key found for this signature in database
GPG Key ID: FC89E0AAA0C1AAD8
26 changed files with 186 additions and 16 deletions

View File

@ -1441,6 +1441,11 @@ BRIDGE_IMPEXP void GuiMenuSetEntryName(int hEntry, const char* name)
_gui_sendmessage(GUI_MENU_SET_VISIBLE, (void*)hEntry, (void*)name);
}
BRIDGE_IMPEXP void GuiMenuSetEntryHotkey(int hEntry, const char* hack)
{
_gui_sendmessage(GUI_MENU_SET_ENTRY_HOTKEY, (void*)hEntry, (void*)hack);
}
BRIDGE_IMPEXP void GuiShowCpu()
{
_gui_sendmessage(GUI_SHOW_CPU, 0, 0);

View File

@ -999,6 +999,7 @@ typedef enum
GUI_MENU_SET_NAME, // param1=int hMenu, param2=const char* name
GUI_MENU_SET_ENTRY_NAME, // param1=int hEntry, param2=const char* name
GUI_FLUSH_LOG, // param1=unused, param2=unused
GUI_MENU_SET_ENTRY_HOTKEY, // param1=int hEntry, param2=const char* hack
} GUIMSG;
//GUI Typedefs
@ -1130,6 +1131,7 @@ BRIDGE_IMPEXP void GuiMenuSetVisible(int hMenu, bool visible);
BRIDGE_IMPEXP void GuiMenuSetEntryVisible(int hEntry, bool visible);
BRIDGE_IMPEXP void GuiMenuSetName(int hMenu, const char* name);
BRIDGE_IMPEXP void GuiMenuSetEntryName(int hEntry, const char* name);
BRIDGE_IMPEXP void GuiMenuSetEntryHotkey(int hEntry, const char* hack);
BRIDGE_IMPEXP void GuiShowCpu();
BRIDGE_IMPEXP void GuiAddQWidgetTab(void* qWidget);
BRIDGE_IMPEXP void GuiShowQWidgetTab(void* qWidget);

View File

@ -123,6 +123,11 @@ PLUG_IMPEXP void _plugin_menuentrysetname(int pluginHandle, int hEntry, const ch
pluginmenuentrysetname(pluginHandle, hEntry, name);
}
PLUG_IMPEXP void _plugin_menuentrysethotkey(int pluginHandle, int hEntry, const char* hotkey)
{
pluginmenuentrysethotkey(pluginHandle, hEntry, hotkey);
}
PLUG_IMPEXP void _plugin_startscript(CBPLUGINSCRIPT cbScript)
{
dbgstartscriptthread(cbScript);

View File

@ -273,6 +273,7 @@ typedef bool (*CBPLUGINCOMMAND)(int argc, char** argv);
typedef void (*CBPLUGINSCRIPT)();
typedef duint(*CBPLUGINEXPRFUNCTION)(int argc, duint* argv, void* userdata);
typedef FORMATRESULT(*CBPLUGINFORMATFUNCTION)(char* dest, size_t destCount, int argc, char* argv[], duint value, void* userdata);
typedef bool (*CBPLUGINPREDICATE)(void* userdata);
//exports
#ifdef __cplusplus
@ -300,6 +301,7 @@ PLUG_IMPEXP void _plugin_menusetvisible(int pluginHandle, int hMenu, bool visibl
PLUG_IMPEXP void _plugin_menuentrysetvisible(int pluginHandle, int hEntry, bool visible);
PLUG_IMPEXP void _plugin_menusetname(int pluginHandle, int hMenu, const char* name);
PLUG_IMPEXP void _plugin_menuentrysetname(int pluginHandle, int hEntry, const char* name);
PLUG_IMPEXP void _plugin_menuentrysethotkey(int pluginHandle, int hEntry, const char* hotkey);
PLUG_IMPEXP void _plugin_startscript(CBPLUGINSCRIPT cbScript);
PLUG_IMPEXP bool _plugin_waituntilpaused();
PLUG_IMPEXP bool _plugin_registerexprfunction(int pluginHandle, const char* name, int argc, CBPLUGINEXPRFUNCTION cbFunction, void* userdata);

View File

@ -867,6 +867,32 @@ void pluginmenuentrysetname(int pluginHandle, int hEntry, const char* name)
}
}
void pluginmenuentrysethotkey(int pluginHandle, int hEntry, const char* hotkey)
{
if(hEntry == -1 || !hotkey)
return;
SHARED_ACQUIRE(LockPluginMenuList);
for(const auto & currentMenu : pluginMenuList)
{
if(currentMenu.pluginHandle == pluginHandle && currentMenu.hEntryPlugin == hEntry)
{
for(const auto & plugin : pluginList)
{
if(plugin.initStruct.pluginHandle == pluginHandle)
{
char name[MAX_PATH] = "";
strcpy_s(name, plugin.plugname);
*strrchr(name, '.') = '\0';
auto hack = StringUtils::sprintf("%s\1%s_%d", hotkey, name, hEntry);
GuiMenuSetEntryHotkey(currentMenu.hEntryMenu, hack.c_str());
break;
}
}
break;
}
}
}
bool pluginexprfuncregister(int pluginHandle, const char* name, int argc, CBPLUGINEXPRFUNCTION cbFunction, void* userdata)
{
PLUG_EXPRFUNCTION plugExprfunction;

View File

@ -85,6 +85,7 @@ void pluginmenusetvisible(int pluginHandle, int hMenu, bool visible);
void pluginmenuentrysetvisible(int pluginHandle, int hEntry, bool visible);
void pluginmenusetname(int pluginHandle, int hMenu, const char* name);
void pluginmenuentrysetname(int pluginHandle, int hEntry, const char* name);
void pluginmenuentrysethotkey(int pluginHandle, int hEntry, const char* hotkey);
bool pluginexprfuncregister(int pluginHandle, const char* name, int argc, CBPLUGINEXPRFUNCTION cbFunction, void* userdata);
bool pluginexprfuncunregister(int pluginHandle, const char* name);
bool pluginformatfuncregister(int pluginHandle, const char* type, CBPLUGINFORMATFUNCTION cbFunction, void* userdata);

View File

@ -782,6 +782,18 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
case GUI_FLUSH_LOG:
emit flushLog();
break;
case GUI_MENU_SET_ENTRY_HOTKEY:
{
BridgeResult result;
auto params = QString((const char*)param2).split('\1');
if(params.length() == 2)
{
emit setHotkeyMenuEntry(int(param1), params[0], params[1]);
result.Wait();
}
}
break;
}
return nullptr;

View File

@ -117,6 +117,7 @@ signals:
void setVisibleMenu(int hMenu, bool visible);
void setNameMenuEntry(int hEntry, QString name);
void setNameMenu(int hMenu, QString name);
void setHotkeyMenuEntry(int hEntry, QString hotkey, QString id);
void showCpu();
void addQWidgetTab(QWidget* qWidget);
void showQWidgetTab(QWidget* qWidget);

View File

@ -917,9 +917,21 @@ void CPUDisassembly::setCommentSlot()
mLineEdit.setWindowTitle(tr("Add comment at ") + addr_text);
if(mLineEdit.exec() != QDialog::Accepted)
return;
if(!DbgSetCommentAt(wVA, mLineEdit.editText.replace('\r', "").replace('\n', "").toUtf8().constData()))
QString comment = mLineEdit.editText.replace('\r', "").replace('\n', "");
if(!DbgSetCommentAt(wVA, comment.toUtf8().constData()))
SimpleErrorBox(this, tr("Error!"), tr("DbgSetCommentAt failed!"));
static bool easter = isEaster();
if(easter && comment.toLower() == "oep")
{
QFile file(":/icons/images/egg.wav");
if(file.open(QIODevice::ReadOnly))
{
QByteArray egg = file.readAll();
PlaySoundA(egg.data(), 0, SND_MEMORY | SND_ASYNC | SND_NODEFAULT);
}
}
GuiUpdateAllViews();
}

View File

@ -79,6 +79,7 @@ MainWindow::MainWindow(QWidget* parent)
connect(Bridge::getBridge(), SIGNAL(setIconMenu(int, QIcon)), this, SLOT(setIconMenu(int, QIcon)));
connect(Bridge::getBridge(), SIGNAL(setIconMenuEntry(int, QIcon)), this, SLOT(setIconMenuEntry(int, QIcon)));
connect(Bridge::getBridge(), SIGNAL(setCheckedMenuEntry(int, bool)), this, SLOT(setCheckedMenuEntry(int, bool)));
connect(Bridge::getBridge(), SIGNAL(setHotkeyMenuEntry(int, QString, QString)), this, SLOT(setHotkeyMenuEntry(int, QString, QString)));
connect(Bridge::getBridge(), SIGNAL(showCpu()), this, SLOT(displayCpuWidget()));
connect(Bridge::getBridge(), SIGNAL(addQWidgetTab(QWidget*)), this, SLOT(addQWidgetTab(QWidget*)));
connect(Bridge::getBridge(), SIGNAL(showQWidgetTab(QWidget*)), this, SLOT(showQWidgetTab(QWidget*)));
@ -708,6 +709,10 @@ void MainWindow::refreshShortcuts()
setGlobalShortcut(ui->actionStrings, ConfigShortcut("ActionFindStrings"));
setGlobalShortcut(ui->actionCalls, ConfigShortcut("ActionFindIntermodularCalls"));
for(const MenuEntryInfo & entry : mEntryList)
if(!entry.hotkeyId.isEmpty())
entry.mAction->setShortcut(ConfigShortcut(entry.hotkeyId));
}
void MainWindow::updateMRUMenu()
@ -1014,7 +1019,7 @@ const MainWindow::MenuInfo* MainWindow::findMenu(int hMenu)
void MainWindow::addMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu)
{
if(!findMenu(hMenu))
mMenuList.push_back(MenuInfo(parent, menu, hMenu, hParentMenu));
mMenuList.push_back(MenuInfo(parent, menu, hMenu, hParentMenu, hMenu == GUI_PLUGIN_MENU));
Bridge::getBridge()->setResult();
}
@ -1030,7 +1035,7 @@ void MainWindow::addMenu(int hMenu, QString title)
QWidget* parent = hMenu == -1 ? this : menu->parent;
QMenu* wMenu = new QMenu(title, parent);
wMenu->menuAction()->setVisible(false);
mMenuList.push_back(MenuInfo(parent, wMenu, hMenuNew, hMenu));
mMenuList.push_back(MenuInfo(parent, wMenu, hMenuNew, hMenu, menu->globalMenu));
if(hMenu == -1) //top-level
ui->menuBar->addMenu(wMenu);
else //deeper level
@ -1056,6 +1061,7 @@ void MainWindow::addMenuEntry(int hMenu, QString title)
QWidget* parent = hMenu == -1 ? this : menu->parent;
QAction* wAction = new QAction(title, parent);
wAction->setObjectName(QString().sprintf("ENTRY|%d", hEntryNew));
wAction->setShortcutContext(menu->globalMenu ? Qt::ApplicationShortcut : Qt::WidgetShortcut);
parent->addAction(wAction);
connect(wAction, SIGNAL(triggered()), this, SLOT(menuEntrySlot()));
newInfo.mAction = wAction;
@ -1199,6 +1205,55 @@ void MainWindow::setCheckedMenuEntry(int hEntry, bool checked)
Bridge::getBridge()->setResult();
}
QString MainWindow::nestedMenuDescription(const MenuInfo* menu)
{
auto found = findMenu(menu->hParentMenu);
if(!found)
return menu->mMenu->title();
auto nest = nestedMenuDescription(found);
if(nest.isEmpty())
{
switch(menu->hParentMenu)
{
case GUI_DISASM_MENU:
nest = tr("&Plugins") + " -> " + tr("Disassembly");
break;
case GUI_DUMP_MENU:
nest = tr("&Plugins") + " -> " + tr("Dump");
break;
case GUI_STACK_MENU:
nest = tr("&Plugins") + " -> " + tr("Stack");
break;
}
}
nest += " -> ";
return nest + menu->mMenu->title();
}
QString MainWindow::nestedMenuEntryDescription(const MenuEntryInfo & entry)
{
return QString(nestedMenuDescription(findMenu(entry.hParentMenu)) + " -> " + entry.mAction->text()).replace("&", "");
}
void MainWindow::setHotkeyMenuEntry(int hEntry, QString hotkey, QString id)
{
for(int i = 0; i < mEntryList.size(); i++)
{
if(mEntryList.at(i).hEntry == hEntry)
{
MenuEntryInfo & entry = mEntryList[i];
entry.hotkeyId = QString("Plugin_") + id;
id.truncate(id.lastIndexOf('_'));
entry.hotkey = hotkey;
entry.hotkeyGlobal = entry.mAction->shortcutContext() == Qt::ApplicationShortcut;
Config()->setPluginShortcut(entry.hotkeyId, nestedMenuEntryDescription(entry), hotkey, entry.hotkeyGlobal);
refreshShortcuts();
break;
}
}
Bridge::getBridge()->setResult();
}
void MainWindow::setVisibleMenuEntry(int hEntry, bool visible)
{
for(int i = 0; i < mEntryList.size(); i++)
@ -1234,6 +1289,7 @@ void MainWindow::setNameMenuEntry(int hEntry, QString name)
{
const MenuEntryInfo & entry = mEntryList.at(i);
entry.mAction->setText(name);
Config()->setPluginShortcut(entry.hotkeyId, nestedMenuEntryDescription(entry), entry.hotkey, entry.hotkeyGlobal);
break;
}
}

View File

@ -108,6 +108,7 @@ public slots:
void setIconMenuEntry(int hEntry, QIcon icon);
void setIconMenu(int hMenu, QIcon icon);
void setCheckedMenuEntry(int hEntry, bool checked);
void setHotkeyMenuEntry(int hEntry, QString hotkey, QString id);
void setVisibleMenuEntry(int hEntry, bool visible);
void setVisibleMenu(int hMenu, bool visible);
void setNameMenuEntry(int hEntry, QString name);
@ -212,23 +213,24 @@ private:
QAction* mAction;
int hEntry;
int hParentMenu;
QString hotkey;
QString hotkeyId;
bool hotkeyGlobal;
};
struct MenuInfo
{
public:
MenuInfo(QWidget* parent, QMenu* mMenu, int hMenu, int hParentMenu)
MenuInfo(QWidget* parent, QMenu* mMenu, int hMenu, int hParentMenu, bool globalMenu)
: parent(parent), mMenu(mMenu), hMenu(hMenu), hParentMenu(hParentMenu), globalMenu(globalMenu)
{
this->parent = parent;
this->mMenu = mMenu;
this->hMenu = hMenu;
this->hParentMenu = hParentMenu;
}
QWidget* parent;
QMenu* mMenu;
int hMenu;
int hParentMenu;
bool globalMenu;
};
QList<MenuEntryInfo> mEntryList;
@ -238,6 +240,8 @@ private:
void initMenuApi();
const MenuInfo* findMenu(int hMenu);
QString nestedMenuDescription(const MenuInfo* menu);
QString nestedMenuEntryDescription(const MenuEntryInfo & entry);
bool bCanClose;
MainWindowCloseThread* mCloseThread;

View File

@ -921,6 +921,12 @@ void Configuration::setShortcut(const QString key_id, const QKeySequence key_seq
noMoreMsgbox = true;
}
void Configuration::setPluginShortcut(const QString key_id, QString description, QString defaultShortcut, bool global)
{
defaultShortcuts[key_id] = Shortcut(description, defaultShortcut, global);
readShortcuts();
}
QColor Configuration::colorFromConfig(const QString id)
{
char setting[MAX_SETTING_SIZE] = "";

View File

@ -66,6 +66,7 @@ public:
const QFont getFont(const QString id) const;
const Shortcut getShortcut(const QString key_id) const;
void setShortcut(const QString key_id, const QKeySequence key_sequence);
void setPluginShortcut(const QString key_id, QString description, QString defaultShortcut, bool global);
//default setting maps
QMap<QString, QColor> defaultColors;

View File

@ -76,18 +76,45 @@ QString getSymbolicName(duint addr)
return addrText;
}
static bool isChristmas()
static bool allowSeasons()
{
srand(GetTickCount());
duint setting = 0;
if(BridgeSettingGetUint("Misc", "NoChristmas", &setting) && setting)
return false;
return !BridgeSettingGetUint("Misc", "NoSeasons", &setting) || !setting;
}
static bool isChristmas()
{
auto date = QDateTime::currentDateTime().date();
return date.month() == 12 && date.day() >= 23 && date.day() <= 26;
}
QString couldItBeChristmas(QString icon)
//https://www.daniweb.com/programming/software-development/threads/463261/c-easter-day-calculation
bool isEaster()
{
auto date = QDateTime::currentDateTime().date();
int K, M, S, A, D, R, OG, SZ, OE, X = date.year();
K = X / 100; // Secular number
M = 15 + (3 * K + 3) / 4 - (8 * K + 13) / 25; // Secular Moon shift
S = 2 - (3 * K + 3) / 4; // Secular sun shift
A = X % 19; // Moon parameter
D = (19 * A + M) % 30; // Seed for 1st full Moon in spring
R = D / 29 + (D / 28 - D / 29) * (A / 11); // Calendarian correction quantity
OG = 21 + D - R; // Easter limit
SZ = 7 - (X + X / 4 + S) % 7; // 1st sunday in March
OE = 7 - (OG - SZ) % 7; // Distance Easter sunday from Easter limit in days
int MM = ((OG + OE) > 31) ? 4 : 3;
int DD = (((OG + OE) % 31) == 0) ? 31 : ((OG + OE) % 31);
return date.month() == MM && date.day() >= DD - 2 && date.day() <= DD + 1;
}
QString couldItBeSeasonal(QString icon)
{
static bool christmas = isChristmas();
return christmas ? QString("christmas%0.png").arg(rand() % 8 + 1) : icon;
static bool easter = isEaster();
if(christmas)
return QString("christmas%1.png").arg(rand() % 8 + 1);
else if(easter)
return QString("easter%1.png").arg(rand() % 8 + 1);
return icon;
}

View File

@ -13,7 +13,8 @@ bool SimpleInputBox(QWidget* parent, const QString & title, QString defaultValue
void SimpleErrorBox(QWidget* parent, const QString & title, const QString & text);
void SimpleWarningBox(QWidget* parent, const QString & title, const QString & text);
QString getSymbolicName(duint addr);
QString couldItBeChristmas(QString icon);
bool isEaster();
QString couldItBeSeasonal(QString icon);
#define DIcon(file) QIcon(QString(":/icons/images/").append(couldItBeChristmas(file)))
#define DIcon(file) QIcon(QString(":/icons/images/").append(couldItBeSeasonal(file)))
#endif // MISCUTIL_H

BIN
src/gui/images/easter1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 B

BIN
src/gui/images/easter2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 B

BIN
src/gui/images/easter3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

BIN
src/gui/images/easter4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 777 B

BIN
src/gui/images/easter5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

BIN
src/gui/images/easter6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 B

BIN
src/gui/images/easter7.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

BIN
src/gui/images/easter8.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 756 B

BIN
src/gui/images/egg.wav Normal file

Binary file not shown.

View File

@ -297,5 +297,14 @@
<file>images/edit-script.png</file>
<file>images/load-script.png</file>
<file>images/import.png</file>
<file>images/easter1.png</file>
<file>images/easter2.png</file>
<file>images/easter3.png</file>
<file>images/easter4.png</file>
<file>images/easter5.png</file>
<file>images/easter6.png</file>
<file>images/easter7.png</file>
<file>images/easter8.png</file>
<file>images/egg.wav</file>
</qresource>
</RCC>

View File

@ -333,7 +333,7 @@ FORMS += \
##
## Libraries
##
LIBS += -luser32 -ladvapi32
LIBS += -luser32 -ladvapi32 -lwinmm
!contains(QMAKE_HOST.arch, x86_64) {
# Windows x86 (32bit) specific build