diff --git a/x64_dbg_gui/Project/Src/Bridge/Bridge.cpp b/x64_dbg_gui/Project/Src/Bridge/Bridge.cpp index 0a30219c..f85ee53e 100644 --- a/x64_dbg_gui/Project/Src/Bridge/Bridge.cpp +++ b/x64_dbg_gui/Project/Src/Bridge/Bridge.cpp @@ -238,6 +238,11 @@ void Bridge::emitSetLastException(unsigned int exceptionCode) emit setLastException(exceptionCode); } +void Bridge::emitMenuAddToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu) +{ + emit menuAddMenuToList(parent, menu, hMenu, hParentMenu); +} + int Bridge::emitMenuAddMenu(int hMenu, QString title) { mBridgeMutex->lock(); diff --git a/x64_dbg_gui/Project/Src/Bridge/Bridge.h b/x64_dbg_gui/Project/Src/Bridge/Bridge.h index 33b56e2f..13752ee7 100644 --- a/x64_dbg_gui/Project/Src/Bridge/Bridge.h +++ b/x64_dbg_gui/Project/Src/Bridge/Bridge.h @@ -60,10 +60,12 @@ public: void emitUpdateMemory(); void emitAddRecentFile(QString file); void emitSetLastException(unsigned int exceptionCode); + void emitMenuAddToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu = -1); int emitMenuAddMenu(int hMenu, QString title); int emitMenuAddMenuEntry(int hMenu, QString title); void emitMenuAddSeparator(int hMenu); void emitMenuClearMenu(int hMenu); + void emitMenuRemoveEntry(int hEntry); bool emitSelectionGet(int hWindow, SELECTIONDATA* selection); bool emitSelectionSet(int hWindow, const SELECTIONDATA* selection); bool emitGetStrWindow(const QString title, QString* text); @@ -119,10 +121,12 @@ signals: void updateMemory(); void addRecentFile(QString file); void setLastException(unsigned int exceptionCode); + void menuAddMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu); void menuAddMenu(int hMenu, QString title); void menuAddMenuEntry(int hMenu, QString title); void menuAddSeparator(int hMenu); void menuClearMenu(int hMenu); + void menuRemoveMenuEntry(int hEntry); void selectionDisasmGet(SELECTIONDATA* selection); void selectionDisasmSet(const SELECTIONDATA* selection); void selectionDumpGet(SELECTIONDATA* selection); diff --git a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp index 00d9b4a5..1c7b4770 100644 --- a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp +++ b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp @@ -17,6 +17,22 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi { ui->setupUi(this); + //setup bridge signals + connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString))); + connect(Bridge::getBridge(), SIGNAL(addRecentFile(QString)), this, SLOT(addRecentFile(QString))); + connect(Bridge::getBridge(), SIGNAL(setLastException(uint)), this, SLOT(setLastException(uint))); + connect(Bridge::getBridge(), SIGNAL(menuAddMenuToList(QWidget*, QMenu*, int, int)), this, SLOT(addMenuToList(QWidget*, QMenu*, int, int))); + connect(Bridge::getBridge(), SIGNAL(menuAddMenu(int, QString)), this, SLOT(addMenu(int, QString))); + connect(Bridge::getBridge(), SIGNAL(menuAddMenuEntry(int, QString)), this, SLOT(addMenuEntry(int, QString))); + connect(Bridge::getBridge(), SIGNAL(menuAddSeparator(int)), this, SLOT(addSeparator(int))); + connect(Bridge::getBridge(), SIGNAL(menuClearMenu(int)), this, SLOT(clearMenu(int))); + connect(Bridge::getBridge(), SIGNAL(menuRemoveMenuEntry(int)), this, SLOT(removeMenuEntry(int))); + connect(Bridge::getBridge(), SIGNAL(getStrWindow(QString, QString*)), this, SLOT(getStrWindow(QString, QString*))); + + //setup menu api + initMenuApi(); + addMenuToList(this, ui->menuPlugins, GUI_PLUGIN_MENU); + this->showMaximized(); #ifdef _WIN64 @@ -173,18 +189,10 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi connect(ui->actionDetach, SIGNAL(triggered()), this, SLOT(detach())); connect(ui->actionChangeCommandLine, SIGNAL(triggered()), this, SLOT(changeCommandLine())); - connect(Bridge::getBridge(), SIGNAL(updateWindowTitle(QString)), this, SLOT(updateWindowTitleSlot(QString))); - connect(Bridge::getBridge(), SIGNAL(addRecentFile(QString)), this, SLOT(addRecentFile(QString))); - connect(Bridge::getBridge(), SIGNAL(setLastException(uint)), this, SLOT(setLastException(uint))); - connect(Bridge::getBridge(), SIGNAL(menuAddMenu(int, QString)), this, SLOT(addMenu(int, QString))); - connect(Bridge::getBridge(), SIGNAL(menuAddMenuEntry(int, QString)), this, SLOT(addMenuEntry(int, QString))); - connect(Bridge::getBridge(), SIGNAL(menuAddSeparator(int)), this, SLOT(addSeparator(int))); - connect(Bridge::getBridge(), SIGNAL(menuClearMenu(int)), this, SLOT(clearMenu(int))); connect(mCpuWidget->mDisas, SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget())); connect(mCpuWidget->mDisas, SIGNAL(showPatches()), this, SLOT(patchWindow())); connect(mCpuWidget->mDump, SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget())); connect(mCpuWidget->mStack, SIGNAL(displayReferencesWidget()), this, SLOT(displayReferencesWidget())); - connect(Bridge::getBridge(), SIGNAL(getStrWindow(QString, QString*)), this, SLOT(getStrWindow(QString, QString*))); connect(Config(), SIGNAL(shortcutsUpdated()), this, SLOT(refreshShortcuts())); //Set default setttings (when not set) @@ -195,9 +203,6 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWi //Create updatechecker mUpdateChecker = new UpdateChecker(this); - //setup menu api - initMenuApi(); - refreshShortcuts(); bClose = false; @@ -706,8 +711,10 @@ void MainWindow::findModularCalls() displayReferencesWidget(); } -void MainWindow::addMenu(int hMenu, QString title) +const MainWindow::MenuInfo* MainWindow::findMenu(int hMenu) { + if(hMenu == -1) + return 0; int nFound = -1; for(int i = 0; i < mMenuList.size(); i++) { @@ -717,77 +724,73 @@ void MainWindow::addMenu(int hMenu, QString title) break; } } - if(nFound == -1 && hMenu != -1) + return nFound == -1 ? 0 : &mMenuList.at(nFound); +} + +void MainWindow::addMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu) +{ + if(!findMenu(hMenu)) + mMenuList.push_back(MenuInfo(parent, menu, hMenu, hParentMenu)); +} + +void MainWindow::addMenu(int hMenu, QString title) +{ + const MenuInfo* menu = findMenu(hMenu); + if(!menu && hMenu != -1) { Bridge::getBridge()->BridgeSetResult(-1); return; } - MenuInfo newInfo; - int hMenuNew = hMenuNext; - hMenuNext++; - QMenu* wMenu = new QMenu(title, this); - newInfo.mMenu = wMenu; - newInfo.hMenu = hMenuNew; - newInfo.hParentMenu = hMenu; - mMenuList.push_back(newInfo); + int hMenuNew = hMenuNext++; + 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)); if(hMenu == -1) //top-level ui->menuBar->addMenu(wMenu); else //deeper level - mMenuList.at(nFound).mMenu->addMenu(wMenu); + menu->mMenu->addMenu(wMenu); Bridge::getBridge()->BridgeSetResult(hMenuNew); } void MainWindow::addMenuEntry(int hMenu, QString title) { - int nFound = -1; - for(int i = 0; i < mMenuList.size(); i++) - { - if(hMenu == mMenuList.at(i).hMenu) - { - nFound = i; - break; - } - } - if(nFound == -1 && hMenu != -1) + const MenuInfo* menu = findMenu(hMenu); + if(!menu && hMenu != -1) { Bridge::getBridge()->BridgeSetResult(-1); return; } MenuEntryInfo newInfo; - int hEntryNew = hEntryNext; - hEntryNext++; + int hEntryNew = hEntryNext++; newInfo.hEntry = hEntryNew; newInfo.hParentMenu = hMenu; - QAction* wAction = new QAction(title, this); + QWidget* parent = hMenu == -1 ? this : menu->parent; + QAction* wAction = new QAction(title, parent); wAction->setObjectName(QString().sprintf("ENTRY|%d", hEntryNew)); - this->addAction(wAction); + parent->addAction(wAction); connect(wAction, SIGNAL(triggered()), this, SLOT(menuEntrySlot())); newInfo.mAction = wAction; mEntryList.push_back(newInfo); if(hMenu == -1) //top level ui->menuBar->addAction(wAction); else //deeper level - mMenuList.at(nFound).mMenu->addAction(wAction); + { + menu->mMenu->addAction(wAction); + menu->mMenu->menuAction()->setVisible(true); + } Bridge::getBridge()->BridgeSetResult(hEntryNew); } void MainWindow::addSeparator(int hMenu) { - int nFound = -1; - for(int i = 0; i < mMenuList.size(); i++) - { - if(hMenu == mMenuList.at(i).hMenu) //we found a menu that has the menu as parent - { - nFound = i; - break; - } - } - if(nFound == -1) //not found + const MenuInfo* menu = findMenu(hMenu); + if(!menu) return; MenuEntryInfo newInfo; newInfo.hEntry = -1; newInfo.hParentMenu = hMenu; - newInfo.mAction = mMenuList.at(nFound).mMenu->addSeparator(); + newInfo.mAction = menu->mMenu->addSeparator(); mEntryList.push_back(newInfo); } @@ -795,12 +798,14 @@ void MainWindow::clearMenu(int hMenu) { if(!mMenuList.size() || hMenu == -1) return; + const MenuInfo* menu = findMenu(hMenu); //delete menu entries for(int i = mEntryList.size() - 1; i > -1; i--) { if(hMenu == mEntryList.at(i).hParentMenu) //we found an entry that has the menu as parent { - this->removeAction(mEntryList.at(i).mAction); + QWidget* parent = menu == 0 ? this : menu->parent; + parent->removeAction(mEntryList.at(i).mAction); delete mEntryList.at(i).mAction; //delete the entry object mEntryList.erase(mEntryList.begin() + i); } @@ -815,6 +820,9 @@ void MainWindow::clearMenu(int hMenu) mMenuList.erase(mMenuList.begin() + i); //delete the child entry } } + //hide the empty menu + if(menu) + menu->mMenu->menuAction()->setVisible(false); } void MainWindow::initMenuApi() @@ -824,12 +832,6 @@ void MainWindow::initMenuApi() hEntryNext = 256; mMenuList.clear(); hMenuNext = 256; - MenuInfo newInfo; - //add plugin menu - newInfo.mMenu = ui->menuPlugins; - newInfo.hMenu = GUI_PLUGIN_MENU; - newInfo.hParentMenu = -1; - mMenuList.push_back(newInfo); } void MainWindow::menuEntrySlot() @@ -843,6 +845,23 @@ void MainWindow::menuEntrySlot() } } +void MainWindow::removeMenuEntry(int hEntry) +{ + for(int i = 0; i < mEntryList.size(); i++) + { + if(mEntryList.at(i).hEntry == hEntry) + { + const MenuEntryInfo & entry = mEntryList.at(i); + const MenuInfo* menu = findMenu(entry.hParentMenu); + QWidget* parent = menu == 0 ? this : menu->parent; + parent->removeAction(entry.mAction); + delete entry.mAction; + mEntryList.erase(mEntryList.begin() + i); + break; + } + } +} + void MainWindow::runSelection() { if(!DbgIsDebugging()) diff --git a/x64_dbg_gui/Project/Src/Gui/MainWindow.h b/x64_dbg_gui/Project/Src/Gui/MainWindow.h index 75e33498..a73b5059 100644 --- a/x64_dbg_gui/Project/Src/Gui/MainWindow.h +++ b/x64_dbg_gui/Project/Src/Gui/MainWindow.h @@ -71,11 +71,13 @@ public slots: void setLastException(unsigned int exceptionCode); void findStrings(); void findModularCalls(); + void addMenuToList(QWidget* parent, QMenu* menu, int hMenu, int hParentMenu = -1); void addMenu(int hMenu, QString title); void addMenuEntry(int hMenu, QString title); void addSeparator(int hMenu); void clearMenu(int hMenu); void menuEntrySlot(); + void removeMenuEntry(int hEntry); void runSelection(); void getStrWindow(const QString title, QString* text); void patchWindow(); @@ -137,6 +139,16 @@ private: struct MenuInfo { + public: + MenuInfo(QWidget* parent, QMenu* mMenu, int hMenu, int hParentMenu) + { + this->parent = parent; + this->mMenu = mMenu; + this->hMenu = hMenu; + this->hParentMenu = hParentMenu; + } + + QWidget* parent; QMenu* mMenu; int hMenu; int hParentMenu; @@ -148,6 +160,7 @@ private: int hMenuNext; void initMenuApi(); + const MenuInfo* findMenu(int hMenu); protected: void dragEnterEvent(QDragEnterEvent* pEvent);