summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2020-01-22 01:40:56 -0500
committerisanae <14251494+isanae@users.noreply.github.com>2020-02-04 03:33:21 -0500
commit6005da618775d545c664371f53571a75eacab7f2 (patch)
treec5cba8758389a557f64c5af0dd8731f042ccbdb6
parenta7a406e5538b343d87b3221b13b7bf3503bbfd70 (diff)
ShellMenuCollection, events not processed yet
-rw-r--r--src/envshell.cpp89
-rw-r--r--src/envshell.h26
-rw-r--r--src/filetree.cpp12
3 files changed, 109 insertions, 18 deletions
diff --git a/src/envshell.cpp b/src/envshell.cpp
index 992ce1ef..58948d31 100644
--- a/src/envshell.cpp
+++ b/src/envshell.cpp
@@ -237,6 +237,30 @@ private:
};
+QMainWindow* getMainWindow(QWidget* w)
+{
+ QWidget* p = w;
+
+ while (p) {
+ if (auto* mw=dynamic_cast<QMainWindow*>(p)) {
+ return mw;
+ }
+
+ p = p->parentWidget();
+ }
+
+ return nullptr;
+}
+
+HWND getHWND(QMainWindow* mw)
+{
+ if (mw) {
+ return (HWND)mw->winId();
+ } else {
+ return 0;
+ }
+}
+
void ShellMenu::addFile(QFileInfo fi)
{
@@ -351,21 +375,6 @@ HMenuPtr ShellMenu::createDummyMenu(const QString& what)
}
}
-QMainWindow* ShellMenu::getMainWindow(QWidget* w)
-{
- QWidget* p = w;
-
- while (p) {
- if (auto* mw=dynamic_cast<QMainWindow*>(p)) {
- return mw;
- }
-
- p = p->parentWidget();
- }
-
- return nullptr;
-}
-
COMPtr<IShellItem> ShellMenu::createShellItem(const std::wstring& path)
{
IShellItem* item = nullptr;
@@ -481,7 +490,7 @@ HMenuPtr ShellMenu::createMenu(IContextMenu* cm)
int ShellMenu::runMenu(
QMainWindow* mw, IContextMenu* cm, HMENU menu, const QPoint& p)
{
- const auto hwnd = (HWND)mw->winId();
+ const auto hwnd = getHWND(mw);
auto filter = std::make_unique<WndProcFilter>(mw, cm);
QCoreApplication::instance()->installNativeEventFilter(filter.get());
@@ -492,7 +501,7 @@ int ShellMenu::runMenu(
void ShellMenu::invoke(
QMainWindow* mw, const QPoint& p, int cmd, IContextMenu* cm)
{
- const auto hwnd = (HWND)mw->winId();
+ const auto hwnd = getHWND(mw);
CMINVOKECOMMANDINFOEX info = {};
@@ -523,4 +532,50 @@ void ShellMenu::invoke(
}
}
+
+void ShellMenuCollection::add(QString name, ShellMenu m)
+{
+ m_menus.push_back({name, std::move(m)});
+}
+
+void ShellMenuCollection::exec(QWidget* parent, const QPoint& pos)
+{
+ HMENU menu = ::CreatePopupMenu();
+ if (!menu) {
+ const auto e = GetLastError();
+
+ log::error(
+ "CreatePopupMenu for merged menus failed, {}",
+ formatSystemMessage(e));
+
+ return;
+ }
+
+ for (auto&& m : m_menus) {
+ auto hmenu = m.menu.getMenu();
+ if (!hmenu) {
+ continue;
+ }
+
+ const auto r = AppendMenuW(
+ menu, MF_POPUP | MF_STRING,
+ reinterpret_cast<UINT_PTR>(hmenu), m.name.toStdWString().c_str());
+
+ if (!r) {
+ const auto e = GetLastError();
+
+ log::error(
+ "AppendMenuW failed for merged menu {}, {}",
+ m.name, formatSystemMessage(e));
+
+ continue;
+ }
+ }
+
+ auto* mw = getMainWindow(parent);
+ auto hwnd = getHWND(mw);
+
+ TrackPopupMenuEx(menu, TPM_RETURNCMD, pos.x(), pos.y(), hwnd, nullptr);
+}
+
} // namespace
diff --git a/src/envshell.h b/src/envshell.h
index f25aeda7..79dce552 100644
--- a/src/envshell.h
+++ b/src/envshell.h
@@ -11,6 +11,14 @@ namespace env
class ShellMenu
{
public:
+ ShellMenu() = default;
+
+ // noncopyable
+ ShellMenu(const ShellMenu&) = delete;
+ ShellMenu& operator=(const ShellMenu&) = delete;
+ ShellMenu(ShellMenu&&) = default;
+ ShellMenu& operator=(ShellMenu&&) = default;
+
void addFile(QFileInfo fi);
void exec(QWidget* parent, const QPoint& pos);
@@ -23,7 +31,6 @@ private:
void createMenu();
- QMainWindow* getMainWindow(QWidget* w);
COMPtr<IShellItem> createShellItem(const std::wstring& path);
COMPtr<IPersistIDList> getPersistIDList(IShellItem* item);
CoTaskMemPtr<LPITEMIDLIST> getIDList(IPersistIDList* pidlist);
@@ -37,6 +44,23 @@ private:
void invoke(QMainWindow* mw, const QPoint& p, int cmd, IContextMenu* cm);
};
+
+class ShellMenuCollection
+{
+public:
+ void add(QString name, ShellMenu m);
+ void exec(QWidget* parent, const QPoint& pos);
+
+private:
+ struct MenuInfo
+ {
+ QString name;
+ ShellMenu menu;
+ };
+
+ std::vector<MenuInfo> m_menus;
+};
+
} // namespace
#endif // ENV_SHELL_H
diff --git a/src/filetree.cpp b/src/filetree.cpp
index 7128665d..543be82b 100644
--- a/src/filetree.cpp
+++ b/src/filetree.cpp
@@ -540,7 +540,19 @@ void FileTree::showShellMenu(QPoint pos)
auto& menu = menus.begin()->second;
menu.exec(m_tree, m_tree->viewport()->mapToGlobal(pos));
} else {
+ env::ShellMenuCollection mc;
+ for (auto&& m : menus) {
+ const auto* origin = m_core.directoryStructure()->findOriginByID(m.first);
+ if (!origin) {
+ log::error("origin {} not found for merged menus", m.first);
+ continue;
+ }
+
+ mc.add(QString::fromStdWString(origin->getName()), std::move(m.second));
+ }
+
+ mc.exec(m_tree, m_tree->viewport()->mapToGlobal(pos));
}
}