diff --git a/abaddon.cpp b/abaddon.cpp index 6955ac8..18990e5 100644 --- a/abaddon.cpp +++ b/abaddon.cpp @@ -197,6 +197,10 @@ void Abaddon::ActionChatInputSubmit(std::string msg, Snowflake channel) { m_discord.SendChatMessage(msg, channel); } +void Abaddon::ActionChatDeleteMessage(Snowflake channel_id, Snowflake id) { + m_discord.DeleteMessage(channel_id, id); +} + int main(int argc, char **argv) { Gtk::Main::init_gtkmm_internals(); // why??? Abaddon abaddon; diff --git a/abaddon.hpp b/abaddon.hpp index 0d508c0..8fad286 100644 --- a/abaddon.hpp +++ b/abaddon.hpp @@ -27,6 +27,7 @@ public: void ActionListChannelItemClick(Snowflake id); void ActionChatInputSubmit(std::string msg, Snowflake channel); void ActionChatLoadHistory(Snowflake id); + void ActionChatDeleteMessage(Snowflake channel_id, Snowflake id); std::string GetDiscordToken() const; bool IsDiscordActive() const; diff --git a/components/chatmessage.cpp b/components/chatmessage.cpp index 29b2ac6..6ac4a99 100644 --- a/components/chatmessage.cpp +++ b/components/chatmessage.cpp @@ -1,4 +1,5 @@ #include "chatmessage.hpp" +#include "../abaddon.hpp" ChatMessageContainer::ChatMessageContainer(const MessageData *data) { UserID = data->Author.ID; @@ -52,6 +53,56 @@ void ChatMessageContainer::AddNewContent(Gtk::Widget *widget, bool prepend) { m_content_box->pack_start(*widget); } +ChatMessageItem::ChatMessageItem() { + m_menu_copy_id = Gtk::manage(new Gtk::MenuItem("_Copy ID", true)); + m_menu_copy_id->signal_activate().connect(sigc::mem_fun(*this, &ChatMessageItem::on_menu_copy_id)); + m_menu.append(*m_menu_copy_id); + + m_menu_delete_message = Gtk::manage(new Gtk::MenuItem("_Delete Message", true)); + m_menu_delete_message->signal_activate().connect(sigc::mem_fun(*this, &ChatMessageItem::on_menu_message_delete)); + m_menu.append(*m_menu_delete_message); + + m_menu.show_all(); +} + +void ChatMessageItem::SetAbaddon(Abaddon *ptr) { + m_abaddon = ptr; +} + +void ChatMessageItem::on_menu_message_delete() { + m_abaddon->ActionChatDeleteMessage(ChannelID, ID); +} + +void ChatMessageItem::on_menu_copy_id() { + Gtk::Clipboard::get()->set_text(std::to_string(ID)); +} + +// broken format v +// clang-format off +void ChatMessageItem::AttachMenuHandler(Gtk::Widget *widget) { + widget->signal_button_press_event().connect([this](GdkEventButton *event) -> bool { + if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_SECONDARY) { + ShowMenu(reinterpret_cast(event)); + return true; + } + + return false; + }, false); +} +// clang-format on + +void ChatMessageItem::ShowMenu(const GdkEvent *event) { + auto &client = m_abaddon->GetDiscordClient(); + auto *data = client.GetMessage(ID); + m_menu_delete_message->set_sensitive(client.GetUserData().ID == data->Author.ID); + m_menu.popup_at_pointer(event); +} + +void ChatMessageItem::AddMenuItem(Gtk::MenuItem *item) { + item->show(); + m_menu.append(*item); +} + ChatMessageTextItem::ChatMessageTextItem(const MessageData *data) { set_can_focus(false); set_editable(false); @@ -60,6 +111,16 @@ ChatMessageTextItem::ChatMessageTextItem(const MessageData *data) { set_hexpand(true); get_buffer()->set_text(data->Content); show(); + + AttachMenuHandler(this); + m_menu_copy_content = Gtk::manage(new Gtk::MenuItem("Copy _Message", true)); + AddMenuItem(m_menu_copy_content); + m_menu_copy_content->signal_activate().connect(sigc::mem_fun(*this, &ChatMessageTextItem::on_menu_copy_content)); +} + +void ChatMessageTextItem::on_menu_copy_content() { + auto *data = m_abaddon->GetDiscordClient().GetMessage(ID); + Gtk::Clipboard::get()->set_text(data->Content); } void ChatMessageTextItem::MarkAsDeleted() { diff --git a/components/chatmessage.hpp b/components/chatmessage.hpp index 181ffcd..dc967af 100644 --- a/components/chatmessage.hpp +++ b/components/chatmessage.hpp @@ -7,6 +7,8 @@ enum class ChatDisplayType { Text, }; +class Abaddon; + // contains the username and timestamp, chat items get stuck into its box class ChatMessageContainer : public Gtk::ListBoxRow { public: @@ -25,10 +27,27 @@ protected: class ChatMessageItem { public: - Snowflake ID; - ChatDisplayType MessageType; + ChatMessageItem(); + void SetAbaddon(Abaddon *ptr); + Snowflake ChannelID; + Snowflake ID; + ChatDisplayType MessageType = ChatDisplayType::Unknown; + + virtual void ShowMenu(const GdkEvent *event); + void AddMenuItem(Gtk::MenuItem *item); virtual void MarkAsDeleted() = 0; + +protected: + void AttachMenuHandler(Gtk::Widget *widget); + void on_menu_copy_id(); + void on_menu_message_delete(); + + Gtk::Menu m_menu; + Gtk::MenuItem *m_menu_copy_id; + Gtk::MenuItem *m_menu_delete_message; + + Abaddon *m_abaddon = nullptr; }; class ChatMessageTextItem @@ -37,4 +56,9 @@ class ChatMessageTextItem public: ChatMessageTextItem(const MessageData *data); virtual void MarkAsDeleted(); + +protected: + void on_menu_copy_content(); + Gtk::MenuItem *m_menu_copy_content; + Gtk::MenuItem *m_menu_delete_message; }; diff --git a/components/chatwindow.cpp b/components/chatwindow.cpp index 8b477e0..647d5b2 100644 --- a/components/chatwindow.cpp +++ b/components/chatwindow.cpp @@ -115,6 +115,9 @@ void ChatWindow::ProcessMessage(const MessageData *data, bool prepend) { // actual content if (type == ChatDisplayType::Text) { auto *text = Gtk::manage(new ChatMessageTextItem(data)); + text->ID = data->ID; + text->ChannelID = m_active_channel; + text->SetAbaddon(m_abaddon); container->AddNewContent(text, prepend); m_id_to_widget[data->ID] = text; }