#include "widgets/notification/copyNotification.hpp" #include #include #include "components/button/iconButton.hpp" #include "glibmm/datetime.h" #include "glibmm/fileutils.h" #include "glibmm/miscutils.h" #include "gtkmm/box.h" #include "gtkmm/button.h" #include "gtkmm/image.h" #include "gtkmm/label.h" // todo refactor out later void copyToClipboard(const std::string &text) { auto clipboard = Gdk::Display::get_default()->get_clipboard(); clipboard->set_text(text); } void copyToClipboard(const Glib::RefPtr &image) { auto clipboard = Gdk::Display::get_default()->get_clipboard(); // Wrap the pixbuf in a Value so GTK knows how to handle it Glib::Value> value; value.init(Glib::Value>::value_type()); value.set(image); // Create a content provider from the value auto provider = Gdk::ContentProvider::create(value); spdlog::info("Copying image to clipboard with content provider"); clipboard->set_content(provider); } void createDirectoryIfNotExists(const std::string &dirpath) { if (!Glib::file_test(dirpath, Glib::FileTest::IS_DIR)) { try { g_mkdir_with_parents(dirpath.c_str(), 0755); } catch (const Glib::Error &e) { spdlog::error("Failed to create directory {}: {}", dirpath, e.what()); } } } void saveImageToFile(const Glib::RefPtr &image, const std::string &filepath, const std::string &filename) { try { createDirectoryIfNotExists(filepath); std::string fullpath = filepath + "/" + filename; image->save(fullpath, "png"); } catch (const Glib::Error &e) { spdlog::error("Failed to save image to file {}: {}", filepath, e.what()); } } CopyNotification::CopyNotification(uint64_t id, std::shared_ptr monitor, NotifyMessage notify) : BaseNotification(id, monitor) { this->set_child(this->mainBox); this->mainBox.set_orientation(Gtk::Orientation::VERTICAL); if (notify.imageData) { this->createImageNotification(notify); } else if (!notify.body.empty()) { this->createTextNotification(notify); } else { spdlog::warn("CopyNotification created without valid image or text data."); } } void CopyNotification::createImageNotification(NotifyMessage notify) { this->setupTitle("image copied"); this->type = CopyType::IMAGE; this->copiedImage = notify.imageData.value(); auto contentBox = Gtk::make_managed(); contentBox->set_orientation(Gtk::Orientation::VERTICAL); auto imageWidget = Gtk::make_managed(this->copiedImage); contentBox->append(*imageWidget); imageWidget->set_pixel_size(300); auto buttonBox = Gtk::make_managed(); buttonBox->set_spacing(10); auto saveToClipboardButton = Gtk::make_managed(Icon::CONTENT_COPY); saveToClipboardButton->signal_clicked().connect([this]() { copyToClipboard(this->copiedImage); spdlog::info("Copied image to clipboard"); this->getSignalClose().emit(this->getNotificationId()); }); saveToClipboardButton->set_tooltip_text("Copy to Clipboard"); saveToClipboardButton->add_css_class("notification-button"); saveToClipboardButton->add_css_class("notification-icon-button"); auto saveToFileButton = Gtk::make_managed(Icon::SAVE); saveToFileButton->signal_clicked().connect([this]() { auto xdgPicturesDir = Glib::get_user_special_dir(Glib::UserDirectory::PICTURES); auto dateStamp = Glib::DateTime::create_now_local().format("%Y%m%d_%H%M%S"); auto filepath = xdgPicturesDir + "/screenshot"; auto filename = dateStamp + ".png"; saveImageToFile(this->copiedImage, filepath, filename); spdlog::info("Saved image to {}", filepath.c_str()); this->getSignalClose().emit(this->getNotificationId()); }); saveToFileButton->set_tooltip_text("Save to File"); saveToFileButton->add_css_class("notification-button"); saveToFileButton->add_css_class("notification-icon-button"); buttonBox->append(*saveToClipboardButton); buttonBox->append(*saveToFileButton); contentBox->append(*buttonBox); this->mainBox.append(*contentBox); } void CopyNotification::createTextNotification(NotifyMessage notify) { this->setupTitle("text copied"); this->type = CopyType::TEXT; this->copiedText = notify.body; auto contentBox = Gtk::make_managed(); contentBox->set_orientation(Gtk::Orientation::VERTICAL); auto textLabel = Gtk::make_managed(this->copiedText); textLabel->set_margin_bottom(10); contentBox->append(*textLabel); auto copyToClipboardButton = Gtk::make_managed(Icon::CONTENT_COPY); copyToClipboardButton->signal_clicked().connect([this]() { copyToClipboard(this->copiedText); this->getSignalClose().emit(this->getNotificationId()); }); copyToClipboardButton->set_tooltip_text("Copy to Clipboard"); copyToClipboardButton->add_css_class("notification-icon-button"); copyToClipboardButton->add_css_class("notification-button"); copyToClipboardButton->set_hexpand(false); copyToClipboardButton->set_halign(Gtk::Align::START); contentBox->append(*copyToClipboardButton); this->mainBox.append(*contentBox); } void CopyNotification::setupTitle(std::string title) { this->title = title; auto titleLabel = Gtk::make_managed(this->title); titleLabel->set_margin_bottom(8); this->mainBox.append(*titleLabel); }