From 284458d6c7644159eb14479e9f41127fd400ffdb Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sat, 3 Dec 2011 21:05:17 +0300 Subject: Allow copy any line from chat log to clipboard by context menu item "Copy to clipboard". --- src/gui/chatwindow.cpp | 17 +++++++++++++- src/gui/chatwindow.h | 2 ++ src/gui/popupmenu.cpp | 51 +++++++++++++++++++++++++++++++++++++++++- src/gui/popupmenu.h | 2 ++ src/gui/widgets/browserbox.cpp | 29 ++++++++++++++++++++++++ src/gui/widgets/browserbox.h | 3 +++ 6 files changed, 102 insertions(+), 2 deletions(-) diff --git a/src/gui/chatwindow.cpp b/src/gui/chatwindow.cpp index 35b89b839..9ba54016e 100644 --- a/src/gui/chatwindow.cpp +++ b/src/gui/chatwindow.cpp @@ -55,6 +55,7 @@ #include "net/playerhandler.h" #include "net/net.h" +#include "utils/copynpaste.h" #include "utils/dtor.h" #include "utils/gettext.h" #include "utils/stringutils.h" @@ -1540,4 +1541,18 @@ void ChatWindow::parseHighlights() bool ChatWindow::findHighlight(std::string &str) { return findI(str, mHighlights) != std::string::npos; -} \ No newline at end of file +} + +void ChatWindow::copyToClipboard(int x, int y) +{ + ChatTab *tab = getFocused(); + if (!tab) + return; + + BrowserBox *text = tab->mTextOutput; + if (!text) + return; + + std::string str = text->getTextAtPos(x, y); + sendBuffer(str); +} diff --git a/src/gui/chatwindow.h b/src/gui/chatwindow.h index ad5229ffe..9d63ca402 100644 --- a/src/gui/chatwindow.h +++ b/src/gui/chatwindow.h @@ -258,6 +258,8 @@ class ChatWindow : public Window, bool findHighlight(std::string &str); + void copyToClipboard(int x, int y); + protected: friend class ChatTab; friend class WhisperTab; diff --git a/src/gui/popupmenu.cpp b/src/gui/popupmenu.cpp index b133f66fc..e49d5c451 100644 --- a/src/gui/popupmenu.cpp +++ b/src/gui/popupmenu.cpp @@ -95,7 +95,9 @@ PopupMenu::PopupMenu(): mDialog(nullptr), mButton(nullptr), mNick(""), - mType(Being::UNKNOWN) + mType(Being::UNKNOWN), + mX(0), + mY(0) { mBrowserBox = new BrowserBox; mBrowserBox->setPosition(4, 4); @@ -120,6 +122,8 @@ void PopupMenu::showPopup(int x, int y, Being *being) mNick = being->getName(); mType = being->getType(); mBrowserBox->clearRows(); + mX = x; + mY = y; const std::string &name = mNick; @@ -348,6 +352,8 @@ void PopupMenu::showPopup(int x, int y, Being *being) void PopupMenu::showPopup(int x, int y, std::vector &beings) { + mX = x; + mY = y; mBrowserBox->clearRows(); mBrowserBox->addRow("Players"); std::vector::const_iterator it, it_end; @@ -374,6 +380,8 @@ void PopupMenu::showPlayerPopup(int x, int y, std::string nick) mNick = nick; mBeingId = 0; mType = Being::PLAYER; + mX = x; + mY = y; mBrowserBox->clearRows(); const std::string &name = mNick; @@ -508,6 +516,8 @@ void PopupMenu::showPopup(int x, int y, FloorItem *floorItem) return; mFloorItem = floorItem; + mX = x; + mY = y; const ItemInfo &info = floorItem->getInfo(); mBrowserBox->clearRows(); std::string name; @@ -534,6 +544,8 @@ void PopupMenu::showPopup(int x, int y, MapItem *mapItem) return; mMapItem = mapItem; + mX = x; + mY = y; mBrowserBox->clearRows(); @@ -554,6 +566,9 @@ void PopupMenu::showPopup(int x, int y, MapItem *mapItem) void PopupMenu::showOutfitsPopup(int x, int y) { + mX = x; + mY = y; + mBrowserBox->clearRows(); mBrowserBox->addRow(_("Outfits")); @@ -573,6 +588,9 @@ void PopupMenu::showSpellPopup(int x, int y, TextCommand *cmd) mBrowserBox->clearRows(); mSpell = cmd; + mX = x; + mY = y; + mBrowserBox->addRow(_("Spells")); mBrowserBox->addRow("load old spells", _("Load old spells")); mBrowserBox->addRow("edit spell", _("Edit spell")); @@ -589,6 +607,8 @@ void PopupMenu::showChatPopup(int x, int y, ChatTab *tab) return; mTab = tab; + mX = x; + mY = y; mBrowserBox->clearRows(); @@ -617,6 +637,8 @@ void PopupMenu::showChatPopup(int x, int y, ChatTab *tab) mBrowserBox->addRow("leave party", _("Leave")); mBrowserBox->addRow("##3---"); } + mBrowserBox->addRow("chat clipboard", _("Copy to clipboard")); + mBrowserBox->addRow("##3---"); if (tab->getType() == ChatTab::TAB_WHISPER) { @@ -815,6 +837,8 @@ void PopupMenu::showChangePos(int x, int y) if (!player_node) return; + mX = x; + mY = y; const Guild *guild = player_node->getGuild(); if (guild) { @@ -838,6 +862,8 @@ void PopupMenu::showChangePos(int x, int y) mMapItem = nullptr; mNick = ""; mType = Being::UNKNOWN; + mX = 0; + mY = 0; setVisible(false); } } @@ -1404,6 +1430,11 @@ void PopupMenu::handleLink(const std::string &link, if (chatWindow) chatWindow->saveState(); } + else if (link == "chat clipboard" && mTab) + { + if (chatWindow) + chatWindow->copyToClipboard(mX, mY); + } else if (link == "remove attack" && being) { if (actorSpriteManager && being->getType() == Being::MONSTER) @@ -1690,6 +1721,8 @@ void PopupMenu::handleLink(const std::string &link, mMapItem = nullptr; mNick = ""; mType = Being::UNKNOWN; + mX = 0; + mY = 0; } void PopupMenu::showPopup(Window *parent, int x, int y, Item *item, @@ -1700,6 +1733,8 @@ void PopupMenu::showPopup(Window *parent, int x, int y, Item *item, mItem = item; mWindow = parent; + mX = x; + mY = y; mBrowserBox->clearRows(); int cnt = item->getQuantity(); @@ -1793,6 +1828,8 @@ void PopupMenu::showItemPopup(int x, int y, int itemId, unsigned char color) mItem = nullptr; mItemId = itemId; mItemColor = color; + mX = x; + mY = y; mBrowserBox->clearRows(); mBrowserBox->addRow("use", _("Use")); @@ -1809,6 +1846,8 @@ void PopupMenu::showItemPopup(int x, int y, int itemId, unsigned char color) void PopupMenu::showItemPopup(int x, int y, Item *item) { mItem = item; + mX = x; + mY = y; if (item) { mItemId = item->getId(); @@ -1864,6 +1903,8 @@ void PopupMenu::showItemPopup(int x, int y, Item *item) void PopupMenu::showDropPopup(int x, int y, Item *item) { mItem = item; + mX = x; + mY = y; mBrowserBox->clearRows(); if (item) @@ -1912,6 +1953,8 @@ void PopupMenu::showPopup(int x, int y, Button *button) return; mButton = button; + mX = x; + mY = y; mBrowserBox->clearRows(); std::vector names = windowMenu->getButtons(); @@ -1947,6 +1990,8 @@ void PopupMenu::showPopup(int x, int y, ProgressBar *b) return; mNick = b->text(); + mX = x; + mY = y; mBrowserBox->clearRows(); std::vector bars = miniStatusWindow->getBars(); @@ -1988,6 +2033,8 @@ void PopupMenu::showAttackMonsterPopup(int x, int y, std::string name, mNick = name; mType = Being::MONSTER; + mX = x; + mY = y; mBrowserBox->clearRows(); @@ -2041,6 +2088,8 @@ void PopupMenu::showUndressPopup(int x, int y, Being *being, Item *item) mItem = item; mItemId = item->getId(); mItemColor = item->getColor(); + mX = x; + mY = y; mBrowserBox->clearRows(); diff --git a/src/gui/popupmenu.h b/src/gui/popupmenu.h index 4bbe2c46c..6dc9a953a 100644 --- a/src/gui/popupmenu.h +++ b/src/gui/popupmenu.h @@ -172,6 +172,8 @@ class PopupMenu : public Popup, public LinkHandler Button *mButton; std::string mNick; int mType; + int mX; + int mY; /** * Shared code for the various showPopup functions. diff --git a/src/gui/widgets/browserbox.cpp b/src/gui/widgets/browserbox.cpp index 5ded29c55..4af38bf67 100644 --- a/src/gui/widgets/browserbox.cpp +++ b/src/gui/widgets/browserbox.cpp @@ -645,6 +645,35 @@ void BrowserBox::updateHeight() } } +std::string BrowserBox::getTextAtPos(const int x, const int y) +{ + int textX = 0; + int textY = 0; + + getAbsolutePosition(textX, textY); + if (x < textX || y < textY) + return ""; // mouse position ourside of correct widget (outside of tab) + + textX = x - textX; + textY = y - textY; + + std::string str = ""; + + for (LinePartIterator i = mLineParts.begin(); + i != mLineParts.end(); + ++i) + { + const LinePart &part = *i; + if (part.mY + 50 < mYStart) + continue; + if (part.mY > textY) + break; + str = part.mText; + } + + return str; +} + LinePart::~LinePart() { if (mImage) diff --git a/src/gui/widgets/browserbox.h b/src/gui/widgets/browserbox.h index 06609b318..e26ae32e0 100644 --- a/src/gui/widgets/browserbox.h +++ b/src/gui/widgets/browserbox.h @@ -137,6 +137,7 @@ class BrowserBox : public gcn::Widget, * Handles mouse actions. */ void mousePressed(gcn::MouseEvent &event); + void mouseMoved(gcn::MouseEvent &event); /** @@ -198,6 +199,8 @@ class BrowserBox : public gcn::Widget, void setEnableImages(bool n) { mEnableImages = n; } + std::string getTextAtPos(const int x, const int y); + private: int calcHeight(); -- cgit v1.2.3-70-g09d2