Honor the configured MRU limits

Actually use the limits set in the preferences dialog rather than always
limiting the MRU lists to 16.

Currently only the Find and Replace limits can be set to above 16 due to
how the open recent items commands are implemented.

Closes #1528.
This commit is contained in:
Thomas Goyne 2012-10-11 09:19:16 -07:00
parent e5251544ea
commit 863e041d4d
4 changed files with 53 additions and 30 deletions

View File

@ -20,16 +20,31 @@
#include "../config.h"
#include "libaegisub/mru.h"
#include "libaegisub/cajun/writer.h"
#include "libaegisub/io.h"
#include "libaegisub/json.h"
#include "libaegisub/log.h"
#include "libaegisub/mru.h"
#include "libaegisub/option.h"
#include "libaegisub/option_value.h"
namespace agi {
MRUManager::MRUManager(const std::string &config, const std::string &default_config): config_name(config) {
MRUManager::MRUManager(std::string const& config, std::string const& default_config, agi::Options *options)
: config_name(config)
, options(options)
{
option_names["Audio"] = "Limits/MRU";
option_names["Keyframes"] = "Limits/MRU";
option_names["Subtitles"] = "Limits/MRU";
option_names["Timecodes"] = "Limits/MRU";
option_names["Video"] = "Limits/MRU";
option_names["Find"] = "Limits/Find Replace";
option_names["Replace"] = "Limits/Find Replace";
LOG_D("agi/mru") << "Loading MRU List";
json::Object root(json_util::file(config, default_config));
@ -37,7 +52,6 @@ MRUManager::MRUManager(const std::string &config, const std::string &default_con
Load(it->first, it->second);
}
MRUManager::~MRUManager() {
}
@ -48,30 +62,27 @@ MRUManager::MRUListMap &MRUManager::Find(std::string const& key) {
return index->second;
}
void MRUManager::Add(const std::string &key, const std::string &entry) {
void MRUManager::Add(std::string const& key, std::string const& entry) {
MRUListMap &map = Find(key);
map.remove(entry);
map.push_front(entry);
Prune(map);
Prune(key, map);
Flush();
}
void MRUManager::Remove(const std::string &key, const std::string &entry) {
void MRUManager::Remove(std::string const& key, std::string const& entry) {
Find(key).remove(entry);
Flush();
}
const MRUManager::MRUListMap* MRUManager::Get(const std::string &key) {
const MRUManager::MRUListMap* MRUManager::Get(std::string const& key) {
return &Find(key);
}
std::string const& MRUManager::GetEntry(const std::string &key, size_t entry) {
const MRUManager::MRUListMap *map = Get(key);
std::string const& MRUManager::GetEntry(std::string const& key, const size_t entry) {
const MRUManager::MRUListMap *const map = Get(key);
if (entry >= map->size())
throw MRUErrorIndexOutOfRange("Requested element index is out of range.");
@ -81,7 +92,6 @@ std::string const& MRUManager::GetEntry(const std::string &key, size_t entry) {
return *index;
}
void MRUManager::Flush() {
json::Object out;
@ -93,24 +103,29 @@ void MRUManager::Flush() {
json::Writer::Write(out, io::Save(config_name).Get());
}
/// @brief Prune MRUListMap to the desired length.
/// This uses the user-set values for MRU list length.
inline void MRUManager::Prune(MRUListMap& map) {
map.resize(std::min<size_t>(16, map.size()));
void MRUManager::Prune(std::string const& key, MRUListMap& map) const {
size_t limit = 16u;
if (options) {
std::map<const std::string, std::string>::const_iterator it = option_names.find(key);
if (it != option_names.end())
limit = (size_t)options->Get(it->second)->GetInt();
}
map.resize(std::min(limit, map.size()));
}
/// @brief Load MRU Lists.
/// @param key List name.
/// @param array json::Array of values.
void MRUManager::Load(const std::string &key, const json::Array& array) {
void MRUManager::Load(std::string const& key, const json::Array& array) {
try {
copy(array.begin(), array.end(), back_inserter(mru[key]));
}
catch (json::Exception const&) {
// Out of date MRU file; just discard the data and skip it
}
Prune(mru[key]);
Prune(key, mru[key]);
}
}

View File

@ -32,6 +32,10 @@ namespace json {
typedef std::deque<UnknownElement> Array;
}
namespace agi {
class Options;
}
namespace agi {
DEFINE_BASE_EXCEPTION_NOINNER(MRUError,Exception)
@ -47,14 +51,13 @@ DEFINE_SIMPLE_EXCEPTION_NOINNER(MRUErrorIndexOutOfRange, MRUError, "mru/invalid"
/// If a file fails to open, Remove() should be called.
///
class MRUManager {
public:
/// @brief Map for time->value pairs.
typedef std::list<std::string> MRUListMap;
typedef std::list<const std::string> MRUListMap;
/// @brief Constructor
/// @param config File to load MRU values from
MRUManager(const std::string &config, const std::string &default_config);
MRUManager(std::string const& config, std::string const& default_config, agi::Options *options = 0);
/// Destructor
~MRUManager();
@ -63,33 +66,35 @@ public:
/// @param key List name
/// @param entry Entry to add
/// @exception MRUErrorInvalidKey thrown when an invalid key is used.
void Add(const std::string &key, const std::string &entry);
void Add(std::string const& key, std::string const& entry);
/// @brief Remove entry from the list.
/// @param key List name
/// @param entry Entry to add
/// @exception MRUErrorInvalidKey thrown when an invalid key is used.
void Remove(const std::string &key, const std::string &entry);
void Remove(std::string const& key, std::string const& entry);
/// @brief Return list
/// @param key List name
/// @exception MRUErrorInvalidKey thrown when an invalid key is used.
const MRUListMap* Get(const std::string &key);
const MRUListMap* Get(std::string const& key);
/// @brief Return A single entry in a list.
/// @param key List name
/// @param entry 0-base position of entry
/// @exception MRUErrorInvalidKey thrown when an invalid key is used.
std::string const& GetEntry(const std::string &key, size_t entry);
std::string const& GetEntry(std::string const& key, const size_t entry);
/// Write MRU lists to disk.
void Flush();
private:
/// Internal name of the config file, set during object construction.
const std::string config_name;
/// User preferences object for maximum number of items to list
agi::Options *const options;
/// @brief Map for MRUListMap values.
/// @param std::string Name
/// @param MRUListMap instance.
@ -98,8 +103,11 @@ private:
/// Internal MRUMap values.
MRUMap mru;
void Load(const std::string &key, const ::json::Array& array);
inline void Prune(MRUListMap& map);
/// Map from MRU name to option name
std::map<const std::string, std::string> option_names;
void Load(std::string const& key, ::json::Array const& array);
void Prune(std::string const& key, MRUListMap& map) const;
MRUListMap &Find(std::string const& key);
};

View File

@ -203,7 +203,7 @@ bool AegisubApp::OnInit() {
icon::icon_init();
StartupLog("Load MRU");
config::mru = new agi::MRUManager(STD_STR(StandardPaths::DecodePath("?user/mru.json")), GET_DEFAULT_CONFIG(default_mru));
config::mru = new agi::MRUManager(STD_STR(StandardPaths::DecodePath("?user/mru.json")), GET_DEFAULT_CONFIG(default_mru), config::opt);
#ifdef __VISUALC__
SetThreadName((DWORD) -1,"AegiMain");

View File

@ -116,7 +116,7 @@ General::General(wxTreebook *book, Preferences *parent): OptionPage(book, parent
OptionAdd(general, _("Undo Levels"), "Limits/Undo Levels", 2);
wxFlexGridSizer *recent = PageSizer(_("Recently Used Lists"));
OptionAdd(recent, _("Files"), "Limits/MRU");
OptionAdd(recent, _("Files"), "Limits/MRU", 0, 16);
OptionAdd(recent, _("Find/Replace"), "Limits/Find Replace");
SetSizerAndFit(sizer);