Merge branch 'feature/editor-mru-1.12' into 1.12

This commit is contained in:
Ignacio R. Morelle 2015-10-17 02:40:33 -03:00
commit f136c87210
11 changed files with 205 additions and 5 deletions

View file

@ -188,6 +188,17 @@
default=no
[/advanced_preference]
[advanced_preference]
field=editor_max_recent_files
name= _ "Editor recent files limit"
description= _ "The maximum number of items to display on the Recent Files menu in the editor"
type=int
default=10
min=1
max=64
step=1
[/advanced_preference]
#ifndef APPLE
[advanced_preference]
field=color_cursors

View file

@ -61,12 +61,20 @@
title= _ "File"
type=turbo
font_size=9
items=editor-scenario-edit,statustable,unitlist,editor-map-new,editor-scenario-new,editor-map-load,editor-map-revert,editor-map-save,editor-map-save-as,editor-scenario-save-as,editor-map-save-all,preferences,help,editor-close-map,quit-editor,editor-quit-to-desktop
items=editor-scenario-edit,statustable,unitlist,editor-map-new,editor-scenario-new,editor-map-load,menu-editor-recent,editor-map-revert,editor-map-save,editor-map-save-as,editor-scenario-save-as,editor-map-save-all,preferences,help,editor-close-map,quit-editor,editor-quit-to-desktop
ref=top-panel
rect="=+1,=+1,+100,+20"
xanchor=fixed
yanchor=fixed
[/menu]
[menu]
title= _ "Load Recent"
id=menu-editor-recent
button=false
items=EDITOR-LOAD-MRU-PLACEHOLDER
[/menu]
# [menu]
# id=menu-editor-edit
# title= _ "Edit"

View file

@ -246,6 +246,7 @@ bool editor_controller::can_execute_command(const hotkey::hotkey_command& cmd, i
return true;
}
return false;
case editor::LOAD_MRU:
case editor::PALETTE:
case editor::AREA:
case editor::SIDE:
@ -526,6 +527,8 @@ hotkey::ACTION_STATE editor_controller::get_action_state(hotkey::HOTKEY_COMMAND
case editor::MAP:
return index == context_manager_->current_context_index()
? ACTION_SELECTED : ACTION_DESELECTED;
case editor::LOAD_MRU:
return ACTION_STATELESS;
case editor::PALETTE:
return ACTION_STATELESS;
case editor::AREA:
@ -587,6 +590,11 @@ bool editor_controller::execute_command(const hotkey::hotkey_command& cmd, int i
}
}
return false;
case LOAD_MRU:
if (index >= 0) {
context_manager_->load_mru_item(static_cast<unsigned>(index));
}
return true;
case PALETTE:
toolkit_->get_palette_manager()->set_group(index);
return true;
@ -970,6 +978,10 @@ void editor_controller::show_menu(const std::vector<std::string>& items_arg, int
}
++i;
}
if (!items.empty() && items.front() == "EDITOR-LOAD-MRU-PLACEHOLDER") {
active_menu_ = editor::LOAD_MRU;
context_manager_->expand_load_mru_menu(items);
}
if (!items.empty() && items.front() == "editor-switch-map") {
active_menu_ = editor::MAP;
context_manager_->expand_open_maps_menu(items);

View file

@ -55,6 +55,7 @@ std::string get_left_button_function();
enum menu_type {
MAP,
LOAD_MRU,
PALETTE,
AREA,
SIDE,

View file

@ -13,10 +13,13 @@
*/
#include "editor/editor_preferences.hpp"
#include "config.hpp"
#include "game_preferences.hpp"
#include "serialization/string_utils.hpp"
#include "util.hpp"
#include <boost/foreach.hpp>
namespace preferences {
namespace editor {
@ -94,6 +97,100 @@ namespace editor {
return lexical_cast_in_range<int>(preferences::get("editor_b"), 0, -255, 255);
}
namespace {
size_t editor_mru_limit()
{
return std::max(size_t(1), lexical_cast_default<size_t>(
preferences::get("editor_max_recent_files"), 10));
}
//
// NOTE: The MRU read/save functions enforce the entry count limit in
// order to ensure the list on disk doesn't grow forever. Otherwise,
// normally this would be the UI's responsibility instead.
//
std::vector<std::string> do_read_editor_mru()
{
const config& cfg = preferences::get_child("editor_recent_files");
std::vector<std::string> mru;
if(!cfg) {
return mru;
}
BOOST_FOREACH(const config& child, cfg.child_range("entry"))
{
const std::string& entry = child["path"].str();
if(!entry.empty()) {
mru.push_back(entry);
}
}
mru.resize(std::min(editor_mru_limit(), mru.size()));
return mru;
}
void do_commit_editor_mru(const std::vector<std::string>& mru)
{
config cfg;
unsigned n = 0;
BOOST_FOREACH(const std::string& entry, mru)
{
if(entry.empty()) {
continue;
}
config& child = cfg.add_child("entry");
child["path"] = entry;
if(++n >= editor_mru_limit()) {
break;
}
}
preferences::set_child("editor_recent_files", cfg);
}
}
std::vector<std::string> recent_files()
{
return do_read_editor_mru();
}
void add_recent_files_entry(const std::string& path)
{
if(path.empty()) {
return;
}
std::vector<std::string> mru = do_read_editor_mru();
// Enforce uniqueness. Normally shouldn't do a thing unless somebody
// has been tampering with the preferences file.
mru.erase(std::remove(mru.begin(), mru.end(), path), mru.end());
mru.insert(mru.begin(), path);
mru.resize(std::min(editor_mru_limit(), mru.size()));
do_commit_editor_mru(mru);
}
void remove_recent_files_entry(const std::string& path)
{
if(path.empty()) {
return;
}
std::vector<std::string> mru = do_read_editor_mru();
mru.erase(std::remove(mru.begin(), mru.end(), path), mru.end());
do_commit_editor_mru(mru);
}
} //end namespace editor
} //end namespace preferences

View file

@ -16,6 +16,7 @@
#define EDITOR_PREFERENCES_HPP_INCLUDED
#include <string>
#include <vector>
namespace preferences {
@ -56,6 +57,13 @@ namespace editor {
/** Get editor blue tint level. */
int tod_b();
/** Retrieves the list of recently opened files. */
std::vector<std::string> recent_files();
/** Adds an entry to the recent files list. */
void add_recent_files_entry(const std::string& path);
/** Removes a single entry from the recent files list. */
void remove_recent_files_entry(const std::string& path);
} //end namespace editor
} //end namespace preferences

View file

@ -187,6 +187,17 @@ void context_manager::load_map_dialog(bool force_same_context /* = false */)
}
}
void context_manager::load_mru_item(unsigned int index, bool force_same_context /* = false */)
{
const std::vector<std::string>& mru = preferences::editor::recent_files();
if(mru.empty() || index >= mru.size()) {
return;
}
load_map(mru[index], !force_same_context);
}
void context_manager::edit_side_dialog(int side)
{
team& t = get_map_context().get_teams()[side];
@ -302,6 +313,36 @@ void context_manager::expand_open_maps_menu(std::vector<std::string>& items)
}
}
void context_manager::expand_load_mru_menu(std::vector<std::string>& items)
{
std::vector<std::string> mru = preferences::editor::recent_files();
for (unsigned int i = 0; i < items.size(); ++i) {
if (items[i] != "EDITOR-LOAD-MRU-PLACEHOLDER") {
continue;
}
items.erase(items.begin() + i);
if(mru.empty()) {
items.insert(items.begin() + i, _("No Recent Files"));
continue;
}
BOOST_FOREACH(std::string& path, mru)
{
// TODO: add proper leading ellipsization instead, since otherwise
// it'll be impossible to tell apart files with identical names and
// different parent paths.
path = filesystem::base_name(path);
}
items.insert(items.begin() + i, mru.begin(), mru.end());
break;
}
}
void context_manager::expand_areas_menu(std::vector<std::string>& items)
{
tod_manager* tod = get_map_context().get_time_manager();

View file

@ -111,6 +111,9 @@ public:
/** Menu expanding for open maps list */
void expand_open_maps_menu(std::vector<std::string>& items);
/** Menu expanding for most recent loaded list */
void expand_load_mru_menu(std::vector<std::string>& items);
/** Menu expanding for the map's player sides */
void expand_sides_menu(std::vector<std::string>& items);
@ -126,6 +129,9 @@ public:
/** Display a load map dialog and process user input. */
void load_map_dialog(bool force_same_context = false);
/** Open the specified entry from the recent files list. */
void load_mru_item(unsigned index, bool force_same_context = false);
/** Display a scenario edit dialog and process user input. */
void edit_scenario_dialog();

View file

@ -14,6 +14,7 @@
#define GETTEXT_DOMAIN "wesnoth-editor"
#include "editor/action/action.hpp"
#include "editor/editor_preferences.hpp"
#include "map_context.hpp"
#include "display.hpp"
@ -141,6 +142,8 @@ map_context::map_context(const config& game_config, const std::string& filename,
boost::regex_constants::match_not_dot_null)) {
map_ = editor_map::from_string(game_config, file_string); //throws on error
pure_map_ = true;
add_to_recent_files();
return;
}
@ -160,14 +163,15 @@ map_context::map_context(const config& game_config, const std::string& filename,
} catch (config::error & e) {
throw editor_map_load_exception("load_scenario", e.message); //we already caught and rethrew this exception in load_scenario
}
return;
} else {
LOG_ED << "Loading embedded map file" << std::endl;
embedded_ = true;
pure_map_ = true;
map_ = editor_map::from_string(game_config, map_data);
return;
}
add_to_recent_files();
return;
}
// 3.0 Macro referenced pure map
@ -186,6 +190,8 @@ map_context::map_context(const config& game_config, const std::string& filename,
file_string = filesystem::read_file(filename_);
map_ = editor_map::from_string(game_config, file_string);
pure_map_ = true;
add_to_recent_files();
}
void map_context::set_side_setup(int side, const std::string& team_name, const std::string& user_team_name,
@ -545,6 +551,7 @@ bool map_context::save_map()
throw editor_map_save_exception(_("Could not save into scenario"));
}
}
add_to_recent_files();
clear_modified();
} catch (filesystem::io_exception& e) {
utils::string_map symbols;
@ -610,6 +617,11 @@ void map_context::clear_modified()
actions_since_save_ = 0;
}
void map_context::add_to_recent_files()
{
preferences::editor::add_recent_files_entry(get_filename());
}
bool map_context::can_undo() const
{
return !undo_stack_.empty();

View file

@ -311,6 +311,9 @@ public:
/** Clear the modified state */
void clear_modified();
/** Adds the map to the editor's recent files list. */
void add_to_recent_files();
/** @return true when undo can be performed, false otherwise */
bool can_undo() const;

View file

@ -378,8 +378,9 @@ std::string command_executor::get_menu_image(display& disp, const std::string& c
const hotkey::ACTION_STATE state = get_action_state(hk, index);
const theme::menu* menu = disp.get_theme().get_menu_item(command);
if (menu)
return "buttons/fold-arrow.png"; // TODO should not be hardcoded
if (menu) {
return "icons/arrows/short_arrow_right_25.png~CROP(3,3,18,18)"; // TODO should not be hardcoded
}
if (filesystem::file_exists(game_config::path + "/images/" + base_image_name)) {
switch (state) {