mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
clipboard functions for keywords
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@358 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -18,14 +18,14 @@ DECLARE_TYPEOF_COLLECTION(KeywordModeP);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Add Keyword
|
||||
|
||||
AddKeywordAction::AddKeywordAction(Adding, Set& set)
|
||||
: KeywordListAction(set), adding(true), keyword(new Keyword())
|
||||
AddKeywordAction::AddKeywordAction(Adding, Set& set, const KeywordP& keyword)
|
||||
: KeywordListAction(set), adding(true), keyword(keyword ? keyword : new_intrusive<Keyword>())
|
||||
, keyword_id(set.keywords.size())
|
||||
{
|
||||
// find default mode
|
||||
FOR_EACH(mode, set.game->keyword_modes) {
|
||||
if (mode->is_default) {
|
||||
keyword->mode = mode->name;
|
||||
this->keyword->mode = mode->name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ enum Removing {REMOVE};
|
||||
/// Adding or removing a keyword from a set
|
||||
class AddKeywordAction : public KeywordListAction {
|
||||
public:
|
||||
AddKeywordAction(Adding, Set& set);
|
||||
AddKeywordAction(Adding, Set& set, const KeywordP& keyword = KeywordP());
|
||||
AddKeywordAction(Removing, Set& set, const KeywordP& keyword);
|
||||
|
||||
virtual String getName(bool to_undo) const;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <data/card.hpp>
|
||||
#include <data/set.hpp>
|
||||
#include <data/game.hpp>
|
||||
#include <data/keyword.hpp>
|
||||
#include <util/io/package.hpp>
|
||||
#include <script/scriptable.hpp>
|
||||
#include <wx/sstream.h>
|
||||
@@ -74,6 +75,46 @@ CardP CardDataObject::getCard(const SetP& set) {
|
||||
else return card;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : KeywordDataObject
|
||||
|
||||
/// A wrapped keyword for storing on the clipboard
|
||||
struct WrappedKeyword {
|
||||
Game* expected_game;
|
||||
String game_name;
|
||||
KeywordP keyword;
|
||||
|
||||
DECLARE_REFLECTION();
|
||||
};
|
||||
|
||||
IMPLEMENT_REFLECTION(WrappedKeyword) {
|
||||
REFLECT(game_name);
|
||||
if (game_name == expected_game->name()) {
|
||||
WITH_DYNAMIC_ARG(game_for_reading, expected_game);
|
||||
REFLECT(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wxDataFormat KeywordDataObject::format = _("application/x-mse-keyword");
|
||||
|
||||
KeywordDataObject::KeywordDataObject(const SetP& set, const KeywordP& keyword) {
|
||||
WrappedKeyword data = { set->game.get(), set->game->name(), keyword };
|
||||
SetText(serialize_for_clipboard(*set, data));
|
||||
SetFormat(format);
|
||||
}
|
||||
|
||||
KeywordDataObject::KeywordDataObject() {
|
||||
SetFormat(format);
|
||||
}
|
||||
|
||||
KeywordP KeywordDataObject::getKeyword(const SetP& set) {
|
||||
KeywordP keyword(new Keyword());
|
||||
WrappedKeyword data = { set->game.get(), set->game->name(), keyword};
|
||||
deserialize_from_clipboard(data, *set, GetText());
|
||||
if (data.game_name != set->game->name()) return KeywordP(); // Keyword is from a different game
|
||||
else return keyword;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Card on clipboard
|
||||
|
||||
CardOnClipboard::CardOnClipboard(const SetP& set, const CardP& card) {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
DECLARE_POINTER_TYPE(Set);
|
||||
DECLARE_POINTER_TYPE(Card);
|
||||
DECLARE_POINTER_TYPE(Keyword);
|
||||
|
||||
// ----------------------------------------------------------------------------- : CardDataObject
|
||||
|
||||
@@ -31,6 +32,22 @@ class CardDataObject : public wxTextDataObject {
|
||||
CardP getCard(const SetP& set);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : KeywordDataObject
|
||||
|
||||
/// The data format for keywords on the clipboard
|
||||
class KeywordDataObject : public wxTextDataObject {
|
||||
public:
|
||||
/// Name of the format of MSE keywords
|
||||
static wxDataFormat format;
|
||||
|
||||
KeywordDataObject();
|
||||
/// Store a keyword
|
||||
KeywordDataObject(const SetP& set, const KeywordP& card);
|
||||
|
||||
/// Retrieve a keyword, only if it is made with the same game as set
|
||||
KeywordP getKeyword(const SetP& set);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Card on clipboard
|
||||
|
||||
/// A DataObject for putting a card on the clipboard, in multiple formats
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <data/stylesheet.hpp>
|
||||
#include <data/settings.hpp>
|
||||
#include <util/find_replace.hpp>
|
||||
#include <util/window_id.hpp>
|
||||
#include <wx/caret.h>
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(ValueViewerP);
|
||||
@@ -297,12 +298,12 @@ void DataEditor::onChar(wxKeyEvent& ev) {
|
||||
void DataEditor::onContextMenu(wxContextMenuEvent& ev) {
|
||||
if (current_editor) {
|
||||
IconMenu m;
|
||||
m.Append(wxID_CUT, _("cut"), _("Cu&t"), _("Move the selected text to the clipboard"));
|
||||
m.Append(wxID_COPY, _("copy"), _("&Copy"), _("Place the selected text on the clipboard"));
|
||||
m.Append(wxID_PASTE, _("paste"), _("&Paste"), _("Inserts the text from the clipboard"));
|
||||
m.Enable(wxID_CUT, canCut());
|
||||
m.Enable(wxID_COPY, canCopy());
|
||||
m.Enable(wxID_PASTE, canPaste());
|
||||
m.Append(ID_EDIT_CUT, _("cut"), _MENU_("cut"), _HELP_("cut"));
|
||||
m.Append(ID_EDIT_COPY, _("copy"), _MENU_("copy"), _HELP_("copy"));
|
||||
m.Append(ID_EDIT_PASTE, _("paste"), _MENU_("paste"), _HELP_("paste"));
|
||||
m.Enable(ID_EDIT_CUT, canCut());
|
||||
m.Enable(ID_EDIT_COPY, canCopy());
|
||||
m.Enable(ID_EDIT_PASTE, canPaste());
|
||||
if (current_editor->onContextMenu(m, ev)) {
|
||||
PopupMenu(&m);
|
||||
}
|
||||
|
||||
@@ -336,10 +336,8 @@ void CardListBase::onContextMenu(wxContextMenuEvent&) {
|
||||
|
||||
// ----------------------------------------------------------------------------- : CardListBase : Event table
|
||||
|
||||
BEGIN_EVENT_TABLE(CardListBase, wxListView)
|
||||
EVT_LIST_COL_CLICK (wxID_ANY, CardListBase::onColumnClick)
|
||||
BEGIN_EVENT_TABLE(CardListBase, ItemList)
|
||||
EVT_LIST_COL_RIGHT_CLICK (wxID_ANY, CardListBase::onColumnRightClick)
|
||||
EVT_LIST_ITEM_FOCUSED (wxID_ANY, CardListBase::onItemFocus)
|
||||
EVT_CHAR ( CardListBase::onChar)
|
||||
EVT_MOTION ( CardListBase::onDrag)
|
||||
EVT_MENU (ID_SELECT_COLUMNS, CardListBase::onSelectColumns)
|
||||
|
||||
@@ -37,6 +37,18 @@ class ItemList : public wxListView {
|
||||
/// Move the selection to the first item (if possible)
|
||||
void selectFirst();
|
||||
|
||||
// --------------------------------------------------- : Clipboard
|
||||
|
||||
virtual bool canCut() const { return canCopy() && canDelete(); }
|
||||
virtual bool canCopy() const { return false; }
|
||||
virtual bool canPaste() const { return false; }
|
||||
virtual bool canDelete() const { return false; }
|
||||
// Try to perform a clipboard operation, return success
|
||||
virtual bool doCut() { return false; }
|
||||
virtual bool doCopy() { return false; }
|
||||
virtual bool doPaste() { return false; }
|
||||
virtual bool doDelete() { return false; }
|
||||
|
||||
// --------------------------------------------------- : Virtual interface
|
||||
protected:
|
||||
/// Get a list of all items
|
||||
@@ -85,6 +97,7 @@ class ItemList : public wxListView {
|
||||
|
||||
void onColumnClick(wxListEvent& ev);
|
||||
void onItemFocus (wxListEvent& ev);
|
||||
void onContextMenu(wxContextMenuEvent&);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
|
||||
@@ -7,13 +7,17 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <gui/control/keyword_list.hpp>
|
||||
#include <gui/icon_menu.hpp>
|
||||
#include <data/set.hpp>
|
||||
#include <data/game.hpp>
|
||||
#include <data/keyword.hpp>
|
||||
#include <data/action/value.hpp>
|
||||
#include <data/action/keyword.hpp>
|
||||
#include <data/format/clipboard.hpp>
|
||||
#include <util/tagged_string.hpp>
|
||||
#include <util/window_id.hpp>
|
||||
#include <gfx/gfx.hpp>
|
||||
#include <wx/clipbrd.h>
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(KeywordP);
|
||||
|
||||
@@ -79,6 +83,46 @@ void KeywordList::onAction(const Action& action, bool undone) {
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Clipboard
|
||||
|
||||
bool KeywordList::canCopy() const { return !!selected_item; }
|
||||
bool KeywordList::canCut() const { return canCopy() && !getKeyword()->fixed; }
|
||||
bool KeywordList::canPaste() const {
|
||||
return wxTheClipboard->IsSupported(KeywordDataObject::format);
|
||||
}
|
||||
|
||||
bool KeywordList::doCopy() {
|
||||
if (!canCopy()) return false;
|
||||
if (!wxTheClipboard->Open()) return false;
|
||||
bool ok = wxTheClipboard->SetData(new KeywordDataObject(set, getKeyword())); // ignore result
|
||||
wxTheClipboard->Close();
|
||||
return ok;
|
||||
}
|
||||
bool KeywordList::doCut() {
|
||||
// cut = copy + delete
|
||||
if (!canCut()) return false;
|
||||
if (!doCopy()) return false;
|
||||
set->actions.add(new AddKeywordAction(REMOVE, *set, getKeyword()));
|
||||
return true;
|
||||
}
|
||||
bool KeywordList::doPaste() {
|
||||
// get data
|
||||
if (!canPaste()) return false;
|
||||
if (!wxTheClipboard->Open()) return false;
|
||||
KeywordDataObject data;
|
||||
bool ok = wxTheClipboard->GetData(data);
|
||||
wxTheClipboard->Close();
|
||||
if (!ok) return false;
|
||||
// add keyword to set
|
||||
KeywordP keyword = data.getKeyword(set);
|
||||
if (keyword) {
|
||||
set->actions.add(new AddKeywordAction(ADD, *set, keyword));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : KeywordListBase : for ItemList
|
||||
|
||||
String match_string(const Keyword& a) {
|
||||
@@ -117,7 +161,7 @@ bool KeywordList::compareItems(void* a, void* b) const {
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : KeywordListBase : Item text
|
||||
// ----------------------------------------------------------------------------- : KeywordList : Item text
|
||||
|
||||
String KeywordList::OnGetItemText (long pos, long col) const {
|
||||
const Keyword& kw = *getKeyword(pos);
|
||||
@@ -145,3 +189,20 @@ wxListItemAttr* KeywordList::OnGetItemAttr(long pos) const {
|
||||
}
|
||||
return &item_attr;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : KeywordList : Context menu
|
||||
|
||||
void KeywordList::onContextMenu(wxContextMenuEvent&) {
|
||||
IconMenu m;
|
||||
m.Append(ID_EDIT_CUT, _("cut"), _CONTEXT_MENU_("cut"), _HELP_("cut keyword"));
|
||||
m.Append(ID_EDIT_COPY, _("copy"), _CONTEXT_MENU_("copy"), _HELP_("copy keyword"));
|
||||
m.Append(ID_EDIT_PASTE, _("paste"), _CONTEXT_MENU_("paste"), _HELP_("paste keyword"));
|
||||
m.AppendSeparator();
|
||||
m.Append(ID_KEYWORD_ADD, _("keyword_add"), _CONTEXT_MENU_("add keyword"), _HELP_("add keyword"));
|
||||
m.Append(ID_KEYWORD_REMOVE, _("keyword_del"), _CONTEXT_MENU_("remove keyword"), _HELP_("remove keyword"));
|
||||
PopupMenu(&m);
|
||||
}
|
||||
|
||||
BEGIN_EVENT_TABLE(KeywordList, ItemList)
|
||||
EVT_CONTEXT_MENU(KeywordList::onContextMenu)
|
||||
END_EVENT_TABLE ()
|
||||
|
||||
@@ -50,6 +50,16 @@ class KeywordList : public ItemList, public SetView {
|
||||
inline KeywordP getKeyword() const { return static_pointer_cast<Keyword>(selected_item); }
|
||||
inline void setKeyword(const KeywordP& kw) { selectItem(kw, true, false); }
|
||||
|
||||
// --------------------------------------------------- : Clipboard
|
||||
|
||||
bool canCut() const;
|
||||
bool canCopy() const;
|
||||
bool canPaste() const;
|
||||
// Try to perform a clipboard operation, return success
|
||||
bool doCut();
|
||||
bool doCopy();
|
||||
bool doPaste();
|
||||
|
||||
// --------------------------------------------------- : The keywords
|
||||
protected:
|
||||
/// Get a list of all keywords
|
||||
@@ -75,6 +85,11 @@ class KeywordList : public ItemList, public SetView {
|
||||
void storeColumns();
|
||||
|
||||
mutable wxListItemAttr item_attr; // for OnGetItemAttr
|
||||
|
||||
// --------------------------------------------------- : Window events
|
||||
DECLARE_EVENT_TABLE();
|
||||
|
||||
void onContextMenu (wxContextMenuEvent&);
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
|
||||
@@ -138,8 +138,8 @@ void CardsPanel::destroyUI(wxToolBar* tb, wxMenuBar* mb) {
|
||||
tb->DeleteTool(ID_CARD_REMOVE);
|
||||
tb->DeleteTool(ID_CARD_ROTATE);
|
||||
// HACK: hardcoded size of rest of toolbar
|
||||
tb->DeleteToolByPos(10); // delete separator
|
||||
tb->DeleteToolByPos(10); // delete separator
|
||||
tb->DeleteToolByPos(12); // delete separator
|
||||
tb->DeleteToolByPos(12); // delete separator
|
||||
// Menus
|
||||
mb->Remove(3);
|
||||
mb->Remove(2);
|
||||
|
||||
@@ -33,7 +33,7 @@ KeywordsPanel::KeywordsPanel(Window* parent, int id)
|
||||
{
|
||||
// init controls
|
||||
splitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0);
|
||||
list = new KeywordList(splitter, wxID_ANY);
|
||||
list = new KeywordList(splitter, ID_KEYWORD_LIST);
|
||||
panel = new Panel(splitter, wxID_ANY, wxDefaultPosition, wxDefaultSize, 0 /* no tab traversal*/);
|
||||
keyword = new TextCtrl(panel, ID_KEYWORD, false);
|
||||
match = new TextCtrl(panel, ID_MATCH, false);
|
||||
@@ -225,24 +225,22 @@ String KeywordsPanel::runRefScript(int find_i) {
|
||||
// ----------------------------------------------------------------------------- : Clipboard
|
||||
|
||||
// determine what control to use for clipboard actions
|
||||
#define CUT_COPY_PASTE(op,return) \
|
||||
int id = focused_control(this); \
|
||||
if (id == ID_KEYWORD && keyword ->IsEnabled()) { return keyword ->op(); } \
|
||||
else if (id == ID_MATCH && match ->IsEnabled()) { return match ->op(); } \
|
||||
else if (id == ID_REMINDER && reminder->IsEnabled()) { return reminder->op(); } \
|
||||
else if (id == ID_RULES && rules ->IsEnabled()) { return rules ->op(); } \
|
||||
else { return false; }
|
||||
#define CUT_COPY_PASTE(op,return,check) \
|
||||
int id = focused_control(this); \
|
||||
if (id == ID_KEYWORD_LIST && keyword ->IsEnabled()) { return list ->op(); } \
|
||||
else if (check) { return false; } \
|
||||
else if (id == ID_KEYWORD && keyword ->IsEnabled()) { return keyword ->op(); } \
|
||||
else if (id == ID_MATCH && match ->IsEnabled()) { return match ->op(); } \
|
||||
else if (id == ID_REMINDER && reminder->IsEnabled()) { return reminder->op(); } \
|
||||
else if (id == ID_RULES && rules ->IsEnabled()) { return rules ->op(); } \
|
||||
else { return false; }
|
||||
|
||||
bool KeywordsPanel::canCopy() const { CUT_COPY_PASTE(canCopy, return) }
|
||||
bool KeywordsPanel::canCut() const { if (!list->getKeyword() || list->getKeyword()->fixed) return false;
|
||||
CUT_COPY_PASTE(canCut, return) }
|
||||
bool KeywordsPanel::canPaste() const { if (!list->getKeyword() || list->getKeyword()->fixed) return false;
|
||||
CUT_COPY_PASTE(canPaste, return) }
|
||||
void KeywordsPanel::doCopy() { CUT_COPY_PASTE(doCopy, ;) }
|
||||
void KeywordsPanel::doCut() { if (!list->getKeyword() || list->getKeyword()->fixed) return;
|
||||
CUT_COPY_PASTE(doCut, ;) }
|
||||
void KeywordsPanel::doPaste() { if (!list->getKeyword() || list->getKeyword()->fixed) return;
|
||||
CUT_COPY_PASTE(doPaste, ;) }
|
||||
bool KeywordsPanel::canCopy() const { CUT_COPY_PASTE(canCopy, return, false) }
|
||||
bool KeywordsPanel::canCut() const { CUT_COPY_PASTE(canCut, return, !list->getKeyword() || list->getKeyword()->fixed) }
|
||||
bool KeywordsPanel::canPaste() const { CUT_COPY_PASTE(canPaste, return, !list->getKeyword() || list->getKeyword()->fixed) }
|
||||
void KeywordsPanel::doCopy() { CUT_COPY_PASTE(doCopy, ;, false) }
|
||||
void KeywordsPanel::doCut() { CUT_COPY_PASTE(doCut, ;, !list->getKeyword() || list->getKeyword()->fixed) }
|
||||
void KeywordsPanel::doPaste() { CUT_COPY_PASTE(doPaste, ;, !list->getKeyword() || list->getKeyword()->fixed) }
|
||||
|
||||
// ----------------------------------------------------------------------------- : Events
|
||||
|
||||
|
||||
@@ -190,6 +190,7 @@ enum ControlID {
|
||||
, ID_PART_LIST
|
||||
, ID_GAME_LIST
|
||||
, ID_STYLESHEET_LIST
|
||||
, ID_KEYWORD_LIST
|
||||
, ID_NOTES
|
||||
, ID_KEYWORD
|
||||
, ID_MATCH
|
||||
|
||||
Reference in New Issue
Block a user