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 "../config.h"
#include "libaegisub/mru.h"
#include "libaegisub/cajun/writer.h" #include "libaegisub/cajun/writer.h"
#include "libaegisub/io.h" #include "libaegisub/io.h"
#include "libaegisub/json.h" #include "libaegisub/json.h"
#include "libaegisub/log.h" #include "libaegisub/log.h"
#include "libaegisub/mru.h" #include "libaegisub/option.h"
#include "libaegisub/option_value.h"
namespace agi { 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"; LOG_D("agi/mru") << "Loading MRU List";
json::Object root(json_util::file(config, default_config)); 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); Load(it->first, it->second);
} }
MRUManager::~MRUManager() { MRUManager::~MRUManager() {
} }
@ -48,30 +62,27 @@ MRUManager::MRUListMap &MRUManager::Find(std::string const& key) {
return index->second; return index->second;
} }
void MRUManager::Add(std::string const& key, std::string const& entry) {
void MRUManager::Add(const std::string &key, const std::string &entry) {
MRUListMap &map = Find(key); MRUListMap &map = Find(key);
map.remove(entry); map.remove(entry);
map.push_front(entry); map.push_front(entry);
Prune(map); Prune(key, map);
Flush(); Flush();
} }
void MRUManager::Remove(std::string const& key, std::string const& entry) {
void MRUManager::Remove(const std::string &key, const std::string &entry) {
Find(key).remove(entry); Find(key).remove(entry);
Flush(); Flush();
} }
const MRUManager::MRUListMap* MRUManager::Get(std::string const& key) {
const MRUManager::MRUListMap* MRUManager::Get(const std::string &key) {
return &Find(key); return &Find(key);
} }
std::string const& MRUManager::GetEntry(const std::string &key, size_t entry) { std::string const& MRUManager::GetEntry(std::string const& key, const size_t entry) {
const MRUManager::MRUListMap *map = Get(key); const MRUManager::MRUListMap *const map = Get(key);
if (entry >= map->size()) if (entry >= map->size())
throw MRUErrorIndexOutOfRange("Requested element index is out of range."); 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; return *index;
} }
void MRUManager::Flush() { void MRUManager::Flush() {
json::Object out; json::Object out;
@ -93,24 +103,29 @@ void MRUManager::Flush() {
json::Writer::Write(out, io::Save(config_name).Get()); json::Writer::Write(out, io::Save(config_name).Get());
} }
/// @brief Prune MRUListMap to the desired length. /// @brief Prune MRUListMap to the desired length.
/// This uses the user-set values for MRU list length. /// This uses the user-set values for MRU list length.
inline void MRUManager::Prune(MRUListMap& map) { void MRUManager::Prune(std::string const& key, MRUListMap& map) const {
map.resize(std::min<size_t>(16, map.size())); 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. /// @brief Load MRU Lists.
/// @param key List name. /// @param key List name.
/// @param array json::Array of values. /// @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 { try {
copy(array.begin(), array.end(), back_inserter(mru[key])); copy(array.begin(), array.end(), back_inserter(mru[key]));
} }
catch (json::Exception const&) { catch (json::Exception const&) {
// Out of date MRU file; just discard the data and skip it // 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; typedef std::deque<UnknownElement> Array;
} }
namespace agi {
class Options;
}
namespace agi { namespace agi {
DEFINE_BASE_EXCEPTION_NOINNER(MRUError,Exception) 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. /// If a file fails to open, Remove() should be called.
/// ///
class MRUManager { class MRUManager {
public: public:
/// @brief Map for time->value pairs. /// @brief Map for time->value pairs.
typedef std::list<std::string> MRUListMap; typedef std::list<const std::string> MRUListMap;
/// @brief Constructor /// @brief Constructor
/// @param config File to load MRU values from /// @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 /// Destructor
~MRUManager(); ~MRUManager();
@ -63,33 +66,35 @@ public:
/// @param key List name /// @param key List name
/// @param entry Entry to add /// @param entry Entry to add
/// @exception MRUErrorInvalidKey thrown when an invalid key is used. /// @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. /// @brief Remove entry from the list.
/// @param key List name /// @param key List name
/// @param entry Entry to add /// @param entry Entry to add
/// @exception MRUErrorInvalidKey thrown when an invalid key is used. /// @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 /// @brief Return list
/// @param key List name /// @param key List name
/// @exception MRUErrorInvalidKey thrown when an invalid key is used. /// @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. /// @brief Return A single entry in a list.
/// @param key List name /// @param key List name
/// @param entry 0-base position of entry /// @param entry 0-base position of entry
/// @exception MRUErrorInvalidKey thrown when an invalid key is used. /// @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. /// Write MRU lists to disk.
void Flush(); void Flush();
private: private:
/// Internal name of the config file, set during object construction. /// Internal name of the config file, set during object construction.
const std::string config_name; const std::string config_name;
/// User preferences object for maximum number of items to list
agi::Options *const options;
/// @brief Map for MRUListMap values. /// @brief Map for MRUListMap values.
/// @param std::string Name /// @param std::string Name
/// @param MRUListMap instance. /// @param MRUListMap instance.
@ -98,8 +103,11 @@ private:
/// Internal MRUMap values. /// Internal MRUMap values.
MRUMap mru; MRUMap mru;
void Load(const std::string &key, const ::json::Array& array); /// Map from MRU name to option name
inline void Prune(MRUListMap& map); 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); MRUListMap &Find(std::string const& key);
}; };

View File

@ -203,7 +203,7 @@ bool AegisubApp::OnInit() {
icon::icon_init(); icon::icon_init();
StartupLog("Load MRU"); 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__ #ifdef __VISUALC__
SetThreadName((DWORD) -1,"AegiMain"); 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); OptionAdd(general, _("Undo Levels"), "Limits/Undo Levels", 2);
wxFlexGridSizer *recent = PageSizer(_("Recently Used Lists")); 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"); OptionAdd(recent, _("Find/Replace"), "Limits/Find Replace");
SetSizerAndFit(sizer); SetSizerAndFit(sizer);