summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/envshell.cpp123
-rw-r--r--src/envshell.h26
-rw-r--r--src/filetree.cpp6
3 files changed, 85 insertions, 70 deletions
diff --git a/src/envshell.cpp b/src/envshell.cpp
index dcf337c5..1f9c4032 100644
--- a/src/envshell.cpp
+++ b/src/envshell.cpp
@@ -1,5 +1,4 @@
#include "envshell.h"
-#include "env.h"
#include <log.h>
#include <utility.h>
#include <windowsx.h>
@@ -209,7 +208,56 @@ private:
-QMainWindow* getMainWindow(QWidget* w)
+void ShellMenu::addFile(QFileInfo fi)
+{
+ m_files.emplace_back(std::move(fi));
+}
+
+void ShellMenu::exec(QWidget* parent, const QPoint& pos)
+{
+ if (m_files.empty()) {
+ log::warn("showShellMenu(): no files given");
+ return;
+ }
+
+ try
+ {
+ auto* mw = getMainWindow(parent);
+ auto idls = createIdls(m_files);
+
+ if (idls.empty()) {
+ log::error("no idls, can't create context menu");
+ return;
+ }
+
+ IdlsFreer freer(idls);
+
+ auto array = createItemArray(idls);
+ auto cm = createContextMenu(array.get());
+ auto hmenu = createMenu(cm.get());
+
+ const int cmd = runMenu(mw, cm.get(), hmenu.get(), pos);
+ if (cmd <= 0) {
+ return;
+ }
+
+ invoke(mw, pos, cmd - QCM_FIRST, cm.get());
+ }
+ catch(MenuFailed& e)
+ {
+ if (m_files.size() == 1) {
+ log::error(
+ "can't create shell menu for '{}': {}",
+ QDir::toNativeSeparators(m_files[0].absoluteFilePath()), e.what());
+ } else {
+ log::error(
+ "can't create shell menu for {} files: {}",
+ m_files.size(), e.what());
+ }
+ }
+}
+
+QMainWindow* ShellMenu::getMainWindow(QWidget* w)
{
QWidget* p = w;
@@ -224,7 +272,7 @@ QMainWindow* getMainWindow(QWidget* w)
return nullptr;
}
-COMPtr<IShellItem> createShellItem(const std::wstring& path)
+COMPtr<IShellItem> ShellMenu::createShellItem(const std::wstring& path)
{
IShellItem* item = nullptr;
@@ -238,7 +286,7 @@ COMPtr<IShellItem> createShellItem(const std::wstring& path)
return COMPtr<IShellItem>(item);
}
-COMPtr<IPersistIDList> getPersistIDList(IShellItem* item)
+COMPtr<IPersistIDList> ShellMenu::getPersistIDList(IShellItem* item)
{
IPersistIDList* idl = nullptr;
auto r = item->QueryInterface(IID_IPersistIDList, (void**)&idl);
@@ -250,7 +298,7 @@ COMPtr<IPersistIDList> getPersistIDList(IShellItem* item)
return COMPtr<IPersistIDList>(idl);
}
-CoTaskMemPtr<LPITEMIDLIST> getIDList(IPersistIDList* pidlist)
+CoTaskMemPtr<LPITEMIDLIST> ShellMenu::getIDList(IPersistIDList* pidlist)
{
LPITEMIDLIST absIdl = nullptr;
auto r = pidlist->GetIDList(&absIdl);
@@ -262,7 +310,7 @@ CoTaskMemPtr<LPITEMIDLIST> getIDList(IPersistIDList* pidlist)
return CoTaskMemPtr<LPITEMIDLIST>(absIdl);
}
-std::vector<LPCITEMIDLIST> createIdls(
+std::vector<LPCITEMIDLIST> ShellMenu::createIdls(
const std::vector<QFileInfo>& files)
{
std::vector<LPCITEMIDLIST> idls;
@@ -280,7 +328,7 @@ std::vector<LPCITEMIDLIST> createIdls(
return idls;
}
-COMPtr<IShellItemArray> createItemArray(
+COMPtr<IShellItemArray> ShellMenu::createItemArray(
std::vector<LPCITEMIDLIST>& idls)
{
IShellItemArray* array = nullptr;
@@ -294,7 +342,7 @@ COMPtr<IShellItemArray> createItemArray(
return COMPtr<IShellItemArray>(array);
}
-COMPtr<IContextMenu> createContextMenu(IShellItemArray* array)
+COMPtr<IContextMenu> ShellMenu::createContextMenu(IShellItemArray* array)
{
IContextMenu* cm = nullptr;
@@ -308,7 +356,7 @@ COMPtr<IContextMenu> createContextMenu(IShellItemArray* array)
return COMPtr<IContextMenu>(cm);
}
-HMenuPtr createMenu(IContextMenu* cm)
+HMenuPtr ShellMenu::createMenu(IContextMenu* cm)
{
HMENU hmenu = CreatePopupMenu();
if (!hmenu) {
@@ -326,7 +374,8 @@ HMenuPtr createMenu(IContextMenu* cm)
return HMenuPtr(hmenu);
}
-int runMenu(QMainWindow* mw, IContextMenu* cm, HMENU menu, const QPoint& p)
+int ShellMenu::runMenu(
+ QMainWindow* mw, IContextMenu* cm, HMENU menu, const QPoint& p)
{
const auto hwnd = (HWND)mw->winId();
@@ -336,7 +385,8 @@ int runMenu(QMainWindow* mw, IContextMenu* cm, HMENU menu, const QPoint& p)
return TrackPopupMenuEx(menu, TPM_RETURNCMD, p.x(), p.y(), hwnd, nullptr);
}
-void invoke(QMainWindow* mw, const QPoint& p, int cmd, IContextMenu* cm)
+void ShellMenu::invoke(
+ QMainWindow* mw, const QPoint& p, int cmd, IContextMenu* cm)
{
const auto hwnd = (HWND)mw->winId();
@@ -369,55 +419,4 @@ void invoke(QMainWindow* mw, const QPoint& p, int cmd, IContextMenu* cm)
}
}
-
-void showShellMenu(
- QWidget* parent, const std::vector<QFileInfo>& files, const QPoint& pos)
-{
- if (files.empty()) {
- log::warn("showShellMenu(): no files given");
- return;
- }
-
- try
- {
- auto* mw = getMainWindow(parent);
- auto idls = createIdls(files);
-
- if (idls.empty()) {
- log::error("no idls, can't create context menu");
- return;
- }
-
- IdlsFreer freer(idls);
-
- auto array = createItemArray(idls);
- auto cm = createContextMenu(array.get());
- auto hmenu = createMenu(cm.get());
-
- const int cmd = runMenu(mw, cm.get(), hmenu.get(), pos);
- if (cmd <= 0) {
- return;
- }
-
- invoke(mw, pos, cmd - QCM_FIRST, cm.get());
- }
- catch(MenuFailed& e)
- {
- if (files.size() == 1) {
- log::error(
- "can't create shell menu for '{}': {}",
- QDir::toNativeSeparators(files[0].absoluteFilePath()), e.what());
- } else {
- log::error(
- "can't create shell menu for {} files: {}",
- files.size(), e.what());
- }
- }
-}
-
-void showShellMenu(QWidget* parent, const QFileInfo& file, const QPoint& pos)
-{
- showShellMenu(parent, std::vector{file}, pos);
-}
-
} // namespace
diff --git a/src/envshell.h b/src/envshell.h
index 3be53841..3e694562 100644
--- a/src/envshell.h
+++ b/src/envshell.h
@@ -1,18 +1,34 @@
#ifndef ENV_SHELL_H
#define ENV_SHELL_H
+#include "env.h"
#include <QFileInfo>
#include <QPoint>
namespace env
{
-void showShellMenu(
- QWidget* parent, const QFileInfo& file, const QPoint& pos);
+class ShellMenu
+{
+public:
+ void addFile(QFileInfo fi);
+ void exec(QWidget* parent, const QPoint& pos);
+
+private:
+ std::vector<QFileInfo> m_files;
-void showShellMenu(
- QWidget* parent, const std::vector<QFileInfo>& files, const QPoint& pos);
+ QMainWindow* getMainWindow(QWidget* w);
+ COMPtr<IShellItem> createShellItem(const std::wstring& path);
+ COMPtr<IPersistIDList> getPersistIDList(IShellItem* item);
+ CoTaskMemPtr<LPITEMIDLIST> getIDList(IPersistIDList* pidlist);
+ std::vector<LPCITEMIDLIST> createIdls(const std::vector<QFileInfo>& files);
+ COMPtr<IShellItemArray> createItemArray(std::vector<LPCITEMIDLIST>& idls);
+ COMPtr<IContextMenu> createContextMenu(IShellItemArray* array);
+ HMenuPtr createMenu(IContextMenu* cm);
+ int runMenu(QMainWindow* mw, IContextMenu* cm, HMENU menu, const QPoint& p);
+ void invoke(QMainWindow* mw, const QPoint& p, int cmd, IContextMenu* cm);
+};
-}
+} // namespace
#endif // ENV_SHELL_H
diff --git a/src/filetree.cpp b/src/filetree.cpp
index d7dbc6e6..404c994b 100644
--- a/src/filetree.cpp
+++ b/src/filetree.cpp
@@ -468,7 +468,7 @@ void FileTree::onContextMenu(const QPoint &pos)
void FileTree::showShellMenu(QPoint pos)
{
- std::vector<QFileInfo> files;
+ env::ShellMenu menu;
for (auto&& index : m_tree->selectionModel()->selectedRows()) {
auto* item = m_model->itemFromIndex(index);
@@ -476,10 +476,10 @@ void FileTree::showShellMenu(QPoint pos)
continue;
}
- files.push_back(item->realPath());
+ menu.addFile(item->realPath());
}
- env::showShellMenu(m_tree, files, m_tree->viewport()->mapToGlobal(pos));
+ menu.exec(m_tree, m_tree->viewport()->mapToGlobal(pos));
}
void FileTree::addDirectoryMenus(QMenu&, FileTreeItem&)