allow "copy file" which sets the text/uri-list with the file path
This commit is contained in:
parent
e8eaa7a232
commit
5aac3422aa
@ -17,10 +17,8 @@
|
|||||||
|
|
||||||
#include "./media_meta_info_loader.hpp"
|
#include "./media_meta_info_loader.hpp"
|
||||||
#include "./sdl_clipboard_utils.hpp"
|
#include "./sdl_clipboard_utils.hpp"
|
||||||
#include "SDL_clipboard.h"
|
|
||||||
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cstdint>
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
@ -28,10 +26,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
|
||||||
namespace Components {
|
namespace Components {
|
||||||
|
|
||||||
@ -72,6 +67,48 @@ static std::string file_path_url_escape(const std::string&& value) {
|
|||||||
return escaped.str();
|
return escaped.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const void* clipboard_callback(void* userdata, const char* mime_type, size_t* size) {
|
||||||
|
if (mime_type == nullptr) {
|
||||||
|
// cleared or new data is set
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userdata == nullptr) {
|
||||||
|
// error
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* cg = static_cast<ChatGui4*>(userdata);
|
||||||
|
std::lock_guard lg{cg->_set_clipboard_data_mutex};
|
||||||
|
if (!cg->_set_clipboard_data.count(mime_type)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& sh_vec = cg->_set_clipboard_data.at(mime_type);
|
||||||
|
if (!static_cast<bool>(sh_vec)) {
|
||||||
|
// error, empty shared pointer
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
*size = sh_vec->size();
|
||||||
|
|
||||||
|
return sh_vec->data();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatGui4::setClipboardData(std::vector<std::string> mime_types, std::shared_ptr<std::vector<uint8_t>>&& data) {
|
||||||
|
std::vector<const char*> tmp_mimetype_list;
|
||||||
|
for (const auto& mime_type : mime_types) {
|
||||||
|
tmp_mimetype_list.push_back(mime_type.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard lg{_set_clipboard_data_mutex};
|
||||||
|
for (const auto& mime_type : mime_types) {
|
||||||
|
_set_clipboard_data[mime_type] = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_SetClipboardData(clipboard_callback, nullptr, this, tmp_mimetype_list.data(), tmp_mimetype_list.size());
|
||||||
|
}
|
||||||
|
|
||||||
ChatGui4::ChatGui4(
|
ChatGui4::ChatGui4(
|
||||||
ConfigModelI& conf,
|
ConfigModelI& conf,
|
||||||
RegistryMessageModel& rmm,
|
RegistryMessageModel& rmm,
|
||||||
@ -80,6 +117,17 @@ ChatGui4::ChatGui4(
|
|||||||
) : _conf(conf), _rmm(rmm), _cr(cr), _tal(_cr), _contact_tc(_tal, tu), _msg_tc(_mil, tu), _sip(tu) {
|
) : _conf(conf), _rmm(rmm), _cr(cr), _tal(_cr), _contact_tc(_tal, tu), _msg_tc(_mil, tu), _sip(tu) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ChatGui4::~ChatGui4(void) {
|
||||||
|
// TODO: this is bs
|
||||||
|
SDL_ClearClipboardData();
|
||||||
|
|
||||||
|
// this might be better, need to see if this works (docs needs improving)
|
||||||
|
//for (const auto& [k, _] : _set_clipboard_data) {
|
||||||
|
//const auto* tmp_mime_type = k.c_str();
|
||||||
|
//SDL_SetClipboardData(nullptr, nullptr, nullptr, &tmp_mime_type, 1);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
void ChatGui4::render(float time_delta) {
|
void ChatGui4::render(float time_delta) {
|
||||||
if (!_cr.storage<Contact::Components::TagAvatarInvalidate>().empty()) { // handle force-reloads for avatars
|
if (!_cr.storage<Contact::Components::TagAvatarInvalidate>().empty()) { // handle force-reloads for avatars
|
||||||
std::vector<Contact3> to_purge;
|
std::vector<Contact3> to_purge;
|
||||||
@ -761,10 +809,19 @@ void ChatGui4::renderMessageBodyFile(Message3Registry& reg, const Message3 e) {
|
|||||||
const auto& local_info = reg.get<Message::Components::Transfer::FileInfoLocal>(e);
|
const auto& local_info = reg.get<Message::Components::Transfer::FileInfoLocal>(e);
|
||||||
if (local_info.file_list.size() > i && ImGui::BeginPopupContextItem("##file_c")) {
|
if (local_info.file_list.size() > i && ImGui::BeginPopupContextItem("##file_c")) {
|
||||||
if (ImGui::MenuItem("open")) {
|
if (ImGui::MenuItem("open")) {
|
||||||
std::string url{"file://" + file_path_url_escape(std::filesystem::canonical(local_info.file_list.at(i)).u8string())};
|
const std::string url{"file://" + file_path_url_escape(std::filesystem::canonical(local_info.file_list.at(i)).u8string())};
|
||||||
std::cout << "opening file '" << url << "'\n";
|
std::cout << "opening file '" << url << "'\n";
|
||||||
SDL_OpenURL(url.c_str());
|
SDL_OpenURL(url.c_str());
|
||||||
}
|
}
|
||||||
|
if (ImGui::MenuItem("copy file")) {
|
||||||
|
const std::string url{"file://" + file_path_url_escape(std::filesystem::canonical(local_info.file_list.at(i)).u8string())};
|
||||||
|
//ImGui::SetClipboardText(url.c_str());
|
||||||
|
setClipboardData({"text/uri-list", "text/x-moz-url"}, std::make_shared<std::vector<uint8_t>>(url.begin(), url.end()));
|
||||||
|
}
|
||||||
|
if (ImGui::MenuItem("copy filepath")) {
|
||||||
|
const auto file_path = std::filesystem::canonical(local_info.file_list.at(i)).u8string();
|
||||||
|
ImGui::SetClipboardText(file_path.c_str());
|
||||||
|
}
|
||||||
ImGui::EndPopup();
|
ImGui::EndPopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,13 @@
|
|||||||
#include "./message_image_loader.hpp"
|
#include "./message_image_loader.hpp"
|
||||||
#include "./file_selector.hpp"
|
#include "./file_selector.hpp"
|
||||||
#include "./send_image_popup.hpp"
|
#include "./send_image_popup.hpp"
|
||||||
|
#include "entt/container/dense_map.hpp"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <string>
|
||||||
|
#include <mutex>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
class ChatGui4 {
|
class ChatGui4 {
|
||||||
ConfigModelI& _conf;
|
ConfigModelI& _conf;
|
||||||
@ -37,6 +41,12 @@ class ChatGui4 {
|
|||||||
float TEXT_BASE_WIDTH {1};
|
float TEXT_BASE_WIDTH {1};
|
||||||
float TEXT_BASE_HEIGHT {1};
|
float TEXT_BASE_HEIGHT {1};
|
||||||
|
|
||||||
|
// mimetype -> data
|
||||||
|
entt::dense_map<std::string, std::shared_ptr<std::vector<uint8_t>>> _set_clipboard_data;
|
||||||
|
std::mutex _set_clipboard_data_mutex; // might be called out of order
|
||||||
|
friend const void* clipboard_callback(void* userdata, const char* mime_type, size_t* size);
|
||||||
|
void setClipboardData(std::vector<std::string> mime_types, std::shared_ptr<std::vector<uint8_t>>&& data);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChatGui4(
|
ChatGui4(
|
||||||
ConfigModelI& conf,
|
ConfigModelI& conf,
|
||||||
@ -44,6 +54,7 @@ class ChatGui4 {
|
|||||||
Contact3Registry& cr,
|
Contact3Registry& cr,
|
||||||
TextureUploaderI& tu
|
TextureUploaderI& tu
|
||||||
);
|
);
|
||||||
|
~ChatGui4(void);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void render(float time_delta);
|
void render(float time_delta);
|
||||||
|
Loading…
Reference in New Issue
Block a user