Skip to content

Commit

Permalink
Add 'Replace on Selected Area' menu, some cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
Mignari committed May 21, 2020
1 parent 792396c commit c6eb001
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 37 deletions.
1 change: 1 addition & 0 deletions data/menubar.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<separator/>
<item name="Find $Item..." hotkey="Ctrl+F" action="FIND_ITEM" help="Find all instances of an item type the map."/>
<item name="R$eplace Item..." hotkey="Ctrl+Shift+F" action="REPLACE_ITEM" help="Replaces all occurances of one item with another."/>
<item name="Replace on Selected Area" action="REPLACE_ON_SELECTION_ITEM" help="Replace item on selected area."/>
<menu name="$Find on Map">
<item name="Find $Everything" action="SEARCH_ON_MAP_EVERYTHING" help="Find all unique/action/text/container items."/>
<separator/>
Expand Down
105 changes: 68 additions & 37 deletions source/main_menubar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ MainMenuBar::MainMenuBar(MainFrame *frame) : frame(frame)
MAKE_ACTION(SEARCH_ON_SELECTION_CONTAINER, wxITEM_NORMAL, OnSearchForContainerOnSelection);
MAKE_ACTION(SEARCH_ON_SELECTION_WRITEABLE, wxITEM_NORMAL, OnSearchForWriteableOnSelection);
MAKE_ACTION(SEARCH_ON_SELECTION_ITEM, wxITEM_NORMAL, OnSearchForItemOnSelection);
MAKE_ACTION(REPLACE_ON_SELECTION_ITEM, wxITEM_NORMAL, OnReplaceItemOnSelection);
MAKE_ACTION(SELECT_MODE_COMPENSATE, wxITEM_RADIO, OnSelectionTypeChange);
MAKE_ACTION(SELECT_MODE_LOWER, wxITEM_RADIO, OnSelectionTypeChange);
MAKE_ACTION(SELECT_MODE_CURRENT, wxITEM_RADIO, OnSelectionTypeChange);
Expand Down Expand Up @@ -311,6 +312,7 @@ void MainMenuBar::Update()
EnableItem(SEARCH_ON_SELECTION_CONTAINER, has_selection && is_host);
EnableItem(SEARCH_ON_SELECTION_WRITEABLE, has_selection && is_host);
EnableItem(SEARCH_ON_SELECTION_ITEM, has_selection && is_host);
EnableItem(REPLACE_ON_SELECTION_ITEM, has_selection && is_host);

EnableItem(CUT, has_map);
EnableItem(COPY, has_map);
Expand Down Expand Up @@ -805,23 +807,25 @@ namespace OnSearchForItem
{
struct Finder
{
Finder(uint16_t itemid) : more_than_value(false), itemid(itemid) {}
bool more_than_value;
uint16_t itemid;
std::vector<std::pair<Tile*, Item*> > found;
Finder(uint16_t itemId, uint32_t maxCount) :
itemId(itemId), maxCount(maxCount) {}

uint16_t itemId;
uint32_t maxCount;
std::vector< std::pair<Tile*, Item*> > result;

bool limitReached() const { return result.size() >= (size_t)maxCount; }

void operator()(Map& map, Tile* tile, Item* item, long long done)
{
if(more_than_value) return;
if(done % 0x8000 == 0) {
if(result.size() >= (size_t)maxCount)
return;

if(done % 0x8000 == 0)
g_gui.SetLoadDone((unsigned int)(100 * done / map.getTileCount()));
}

if(item->getID() == itemid) {
found.push_back(std::make_pair(tile, item));
if(found.size() >= size_t(g_settings.getInteger(Config::REPLACE_SIZE)))
more_than_value = true;
}
if(item->getID() == itemId)
result.push_back(std::make_pair(tile, item));
}
};
}
Expand All @@ -834,32 +838,33 @@ void MainMenuBar::OnSearchForItem(wxCommandEvent& WXUNUSED(event))
FindItemDialog dialog(frame, "Search for Item");
dialog.setSearchMode((FindItemDialog::SearchMode)g_settings.getInteger(Config::FIND_ITEM_MODE));
if(dialog.ShowModal() == wxID_OK) {
OnSearchForItem::Finder finder(dialog.getResultID());
OnSearchForItem::Finder finder(dialog.getResultID(), (uint32_t)g_settings.getInteger(Config::REPLACE_SIZE));
g_gui.CreateLoadBar("Searching map...");

foreach_ItemOnMap(g_gui.GetCurrentMap(), finder, false);
std::vector<std::pair<Tile*, Item*> >& found = finder.found;
std::vector< std::pair<Tile*, Item*> >& result = finder.result;

g_gui.DestroyLoadBar();

if(finder.more_than_value) {
if(finder.limitReached()) {
wxString msg;
msg << "Only the first " << size_t(g_settings.getInteger(Config::REPLACE_SIZE)) << " results will be displayed.";
msg << "Only the first " << finder.maxCount << " results will be displayed.";
g_gui.PopupDialog("Notice", msg, wxOK);
}

SearchResultWindow* result = g_gui.ShowSearchWindow();
result->Clear();
for(std::vector<std::pair<Tile*, Item*> >::const_iterator iter = found.begin(); iter != found.end(); ++iter) {
SearchResultWindow* window = g_gui.ShowSearchWindow();
window->Clear();
for(std::vector<std::pair<Tile*, Item*> >::const_iterator iter = result.begin(); iter != result.end(); ++iter) {
Tile* tile = iter->first;
Item* item = iter->second;
result->AddPosition(wxstr(item->getName()), tile->getPosition());
window->AddPosition(wxstr(item->getName()), tile->getPosition());
}

g_settings.setInteger(Config::FIND_ITEM_MODE, (int)dialog.getSearchMode());
}
dialog.Destroy();
}

void MainMenuBar::OnReplaceItem(wxCommandEvent& WXUNUSED(event))
{
if(!g_gui.IsEditorOpen())
Expand All @@ -873,26 +878,22 @@ void MainMenuBar::OnReplaceItem(wxCommandEvent& WXUNUSED(event))
if(find_id == 0 || with_id == 0 || find_id == with_id)
return;

OnSearchForItem::Finder finder(find_id);
g_gui.GetCurrentEditor()->actionQueue->clear();
g_gui.CreateLoadBar("Searching & replacing item...");

// Search the map
OnSearchForItem::Finder finder(find_id, (uint32_t)g_settings.getInteger(Config::REPLACE_SIZE));
foreach_ItemOnMap(g_gui.GetCurrentMap(), finder, false);

// Replace the items in a second step (can't replace while iterating)
for(auto it = finder.found.begin(); it != finder.found.end(); ++it) {
std::vector< std::pair<Tile*, Item*> >& result = finder.result;
for(auto it = result.begin(); it != result.end(); ++it)
transformItem(it->second, with_id, it->first);
}

wxString msg;
msg << "Replaced " << finder.found.size() << " items.";
msg << "Replaced " << result.size() << " items.";
g_gui.SetStatusText(msg);

g_gui.DestroyLoadBar();
g_gui.RefreshView();
}

g_gui.RefreshView();
}

namespace OnSearchForStuff
Expand Down Expand Up @@ -1024,26 +1025,26 @@ void MainMenuBar::OnSearchForItemOnSelection(wxCommandEvent& WXUNUSED(event))
FindItemDialog dialog(frame, "Search on Selection");
dialog.setSearchMode((FindItemDialog::SearchMode)g_settings.getInteger(Config::FIND_ITEM_MODE));
if(dialog.ShowModal() == wxID_OK) {
OnSearchForItem::Finder finder(dialog.getResultID());
OnSearchForItem::Finder finder(dialog.getResultID(), (uint32_t)g_settings.getInteger(Config::REPLACE_SIZE));
g_gui.CreateLoadBar("Searching on selected area...");

foreach_ItemOnMap(g_gui.GetCurrentMap(), finder, true);
std::vector<std::pair<Tile*, Item*> >& found = finder.found;
std::vector<std::pair<Tile*, Item*> >& result = finder.result;

g_gui.DestroyLoadBar();

if(finder.more_than_value) {
if(finder.limitReached()) {
wxString msg;
msg << "Only the first " << size_t(g_settings.getInteger(Config::REPLACE_SIZE)) << " results will be displayed.";
msg << "Only the first " << finder.maxCount << " results will be displayed.";
g_gui.PopupDialog("Notice", msg, wxOK);
}

SearchResultWindow* result = g_gui.ShowSearchWindow();
result->Clear();
for(std::vector<std::pair<Tile*, Item*> >::const_iterator iter = found.begin(); iter != found.end(); ++iter) {
SearchResultWindow* window = g_gui.ShowSearchWindow();
window->Clear();
for(std::vector<std::pair<Tile*, Item*> >::const_iterator iter = result.begin(); iter != result.end(); ++iter) {
Tile* tile = iter->first;
Item* item = iter->second;
result->AddPosition(wxstr(item->getName()), tile->getPosition());
window->AddPosition(wxstr(item->getName()), tile->getPosition());
}

g_settings.setInteger(Config::FIND_ITEM_MODE, (int)dialog.getSearchMode());
Expand All @@ -1052,6 +1053,36 @@ void MainMenuBar::OnSearchForItemOnSelection(wxCommandEvent& WXUNUSED(event))
dialog.Destroy();
}

void MainMenuBar::OnReplaceItemOnSelection(wxCommandEvent& WXUNUSED(event))
{
if(!g_gui.IsEditorOpen())
return;

ReplaceItemDialog dialog(frame);

if(dialog.ShowModal() == wxID_OK) {
uint16_t find_id = dialog.GetResultFindID();
uint16_t with_id = dialog.GetResultWithID();
if(find_id == 0 || with_id == 0 || find_id == with_id)
return;

g_gui.CreateLoadBar("Searching & replacing item...");

OnSearchForItem::Finder finder(find_id, (uint32_t)g_settings.getInteger(Config::REPLACE_SIZE));
foreach_ItemOnMap(g_gui.GetCurrentMap(), finder, true);

std::vector< std::pair<Tile*, Item*> >& result = finder.result;
for(auto it = result.begin(); it != result.end(); ++it)
transformItem(it->second, with_id, it->first);

wxString msg;
msg << "Replaced " << result.size() << " items.";
g_gui.SetStatusText(msg);
g_gui.DestroyLoadBar();
g_gui.RefreshView();
}
}

void MainMenuBar::OnSelectionTypeChange(wxCommandEvent& WXUNUSED(event))
{
g_settings.setInteger(Config::COMPENSATED_SELECT, IsItemChecked(MenuBar::SELECT_MODE_COMPENSATE));
Expand Down
2 changes: 2 additions & 0 deletions source/main_menubar.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ namespace MenuBar
SEARCH_ON_SELECTION_CONTAINER,
SEARCH_ON_SELECTION_WRITEABLE,
SEARCH_ON_SELECTION_ITEM,
REPLACE_ON_SELECTION_ITEM,
SELECT_MODE_COMPENSATE,
SELECT_MODE_CURRENT,
SELECT_MODE_LOWER,
Expand Down Expand Up @@ -228,6 +229,7 @@ class MainMenuBar : wxEvtHandler
void OnSearchForContainerOnSelection(wxCommandEvent& event);
void OnSearchForWriteableOnSelection(wxCommandEvent& event);
void OnSearchForItemOnSelection(wxCommandEvent& event);
void OnReplaceItemOnSelection(wxCommandEvent& event);

// Map menu
void OnMapEditTowns(wxCommandEvent& event);
Expand Down

0 comments on commit c6eb001

Please sign in to comment.