From 0e05afdac5c8864080748f2c2c30b0743fd80d1a Mon Sep 17 00:00:00 2001 From: Richard Nelson Date: Wed, 6 Oct 2010 19:41:55 -0700 Subject: allow passing LLSD arguments on command line --- indra/llxml/llcontrol.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index f9a39826f5..2822b767e5 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -170,6 +170,19 @@ LLSD LLControlVariable::getComparableValue(const LLSD& value) storable_value = false; } } + else if (TYPE_LLSD == type() && value.isString()) + { + LLPointer parser = new LLSDNotationParser; + LLSD result; + if (parser->parse(std::stringstream(value.asString()), result, LLSDSerialize::SIZE_UNLIMITED) != LLSDParser::PARSE_FAILURE) + { + storable_value = result; + } + else + { + storable_value = value; + } + } else { storable_value = value; -- cgit v1.3 From 0fa63baf3781430d835b859094b7d2b35ae3b32b Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Thu, 7 Oct 2010 11:30:55 -0700 Subject: fix for gcc --- indra/llxml/llcontrol.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 2822b767e5..85d369b8cd 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -174,7 +174,8 @@ LLSD LLControlVariable::getComparableValue(const LLSD& value) { LLPointer parser = new LLSDNotationParser; LLSD result; - if (parser->parse(std::stringstream(value.asString()), result, LLSDSerialize::SIZE_UNLIMITED) != LLSDParser::PARSE_FAILURE) + std::stringstream value_stream(value.asString()); + if (parser->parse(value_stream, result, LLSDSerialize::SIZE_UNLIMITED) != LLSDParser::PARSE_FAILURE) { storable_value = result; } -- cgit v1.3 From 656b936915d5fd29f213f8eb7cd3873baed19109 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Tue, 9 Nov 2010 14:40:32 -0500 Subject: Add name, value info to convert_from_llsd<> specialization LL_ERRS. Prior to this, you could get a viewer crash whose ERROR: message said only: convert_from_llsd: Invalid string value This gave no hint as to *which value* was wrong, or where to go fix it. Ironically, each convert_from_llsd<> specialization already has the control_name and LLSD value in hand; added these to each such LL_ERRS message. --- indra/llxml/llcontrol.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index f9a39826f5..27c694dde9 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -1107,7 +1107,7 @@ bool convert_from_llsd(const LLSD& sd, eControlType type, const std::strin return sd.asBoolean(); else { - CONTROL_ERRS << "Invalid BOOL value" << llendl; + CONTROL_ERRS << "Invalid BOOL value for " << control_name << ": " << sd << llendl; return FALSE; } } @@ -1119,7 +1119,7 @@ S32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& return sd.asInteger(); else { - CONTROL_ERRS << "Invalid S32 value" << llendl; + CONTROL_ERRS << "Invalid S32 value for " << control_name << ": " << sd << llendl; return 0; } } @@ -1131,7 +1131,7 @@ U32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& return sd.asInteger(); else { - CONTROL_ERRS << "Invalid U32 value" << llendl; + CONTROL_ERRS << "Invalid U32 value for " << control_name << ": " << sd << llendl; return 0; } } @@ -1143,7 +1143,7 @@ F32 convert_from_llsd(const LLSD& sd, eControlType type, const std::string& return (F32) sd.asReal(); else { - CONTROL_ERRS << "Invalid F32 value" << llendl; + CONTROL_ERRS << "Invalid F32 value for " << control_name << ": " << sd << llendl; return 0.0f; } } @@ -1155,7 +1155,7 @@ std::string convert_from_llsd(const LLSD& sd, eControlType type, co return sd.asString(); else { - CONTROL_ERRS << "Invalid string value" << llendl; + CONTROL_ERRS << "Invalid string value for " << control_name << ": " << sd << llendl; return LLStringUtil::null; } } @@ -1173,7 +1173,7 @@ LLVector3 convert_from_llsd(const LLSD& sd, eControlType type, const return (LLVector3)sd; else { - CONTROL_ERRS << "Invalid LLVector3 value" << llendl; + CONTROL_ERRS << "Invalid LLVector3 value for " << control_name << ": " << sd << llendl; return LLVector3::zero; } } @@ -1185,7 +1185,7 @@ LLVector3d convert_from_llsd(const LLSD& sd, eControlType type, cons return (LLVector3d)sd; else { - CONTROL_ERRS << "Invalid LLVector3d value" << llendl; + CONTROL_ERRS << "Invalid LLVector3d value for " << control_name << ": " << sd << llendl; return LLVector3d::zero; } } @@ -1197,7 +1197,7 @@ LLRect convert_from_llsd(const LLSD& sd, eControlType type, const std::s return LLRect(sd); else { - CONTROL_ERRS << "Invalid rect value" << llendl; + CONTROL_ERRS << "Invalid rect value for " << control_name << ": " << sd << llendl; return LLRect::null; } } @@ -1211,19 +1211,19 @@ LLColor4 convert_from_llsd(const LLSD& sd, eControlType type, const st LLColor4 color(sd); if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f) { - llwarns << "Color " << control_name << " value out of range " << llendl; + llwarns << "Color " << control_name << " red value out of range: " << color << llendl; } else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f) { - llwarns << "Color " << control_name << " value out of range " << llendl; + llwarns << "Color " << control_name << " green value out of range: " << color << llendl; } else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f) { - llwarns << "Color " << control_name << " value out of range " << llendl; + llwarns << "Color " << control_name << " blue value out of range: " << color << llendl; } else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f) { - llwarns << "Color " << control_name << " value out of range " << llendl; + llwarns << "Color " << control_name << " alpha value out of range: " << color << llendl; } return LLColor4(sd); @@ -1242,7 +1242,7 @@ LLColor3 convert_from_llsd(const LLSD& sd, eControlType type, const st return sd; else { - CONTROL_ERRS << "Invalid LLColor3 value" << llendl; + CONTROL_ERRS << "Invalid LLColor3 value for " << control_name << ": " << sd << llendl; return LLColor3::white; } } -- cgit v1.3 From 5aa43e4f3e30d81fb518783189b3258e67b4620a Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Tue, 22 Feb 2011 19:30:50 -0800 Subject: SOCIAL-545 WIP Figure out how to configure skylight-specific settings while retaining relevant user settings (login account name, etc.) converted settings_file.xml to use param block descriptions for easier modification added session settings file and user session settings file for per-session config overrides --- indra/llxml/llcontrol.cpp | 5 +- indra/llxml/llcontrol.h | 2 +- indra/newview/app_settings/cmd_line.xml | 18 +++ indra/newview/app_settings/settings.xml | 26 ++- indra/newview/app_settings/settings_files.xml | 212 ++++++++----------------- indra/newview/llappviewer.cpp | 219 +++++++++++++++++--------- indra/newview/llappviewer.h | 2 +- 7 files changed, 257 insertions(+), 227 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp index 6c72609122..6e4364a20d 100644 --- a/indra/llxml/llcontrol.cpp +++ b/indra/llxml/llcontrol.cpp @@ -835,7 +835,7 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only return num_saved; } -U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values) +U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_values, bool save_values) { std::string name; LLSD settings; @@ -908,8 +908,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v } else if(existing_control->isPersisted()) { - - existing_control->setValue(control_map["Value"]); + existing_control->setValue(control_map["Value"], save_values); } // *NOTE: If not persisted and not setting defaults, // the value should not get loaded. diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h index 93975579cc..e402061e1f 100644 --- a/indra/llxml/llcontrol.h +++ b/indra/llxml/llcontrol.h @@ -289,7 +289,7 @@ public: // as the given type. U32 loadFromFileLegacy(const std::string& filename, BOOL require_declaration = TRUE, eControlType declare_as = TYPE_STRING); U32 saveToFile(const std::string& filename, BOOL nondefault_only); - U32 loadFromFile(const std::string& filename, bool default_values = false); + U32 loadFromFile(const std::string& filename, bool default_values = false, bool save_values = true); void resetToDefaults(); }; diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml index e4ac455e7c..89e5949fbe 100644 --- a/indra/newview/app_settings/cmd_line.xml +++ b/indra/newview/app_settings/cmd_line.xml @@ -261,6 +261,24 @@ + sessionsettings + + desc + Specify the filename of a configuration file that contains temporary per-session configuration overrides. + count + 1 + + + + usersessionsettings + + desc + Specify the filename of a configuration file that contains temporary per-session configuration user overrides. + count + 1 + + + login desc diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6630d8f400..1bcc988e5c 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11473,7 +11473,7 @@ Type F32 Value - 3.0 + 3 InterpolationPhaseOut @@ -11484,7 +11484,7 @@ Type F32 Value - 1.0 + 1 VerboseLogs @@ -12366,5 +12366,27 @@ Value name + SessionSettingsFile + + Comment + Settings that are a applied per session (not saved). + Persist + 0 + Type + String + Value + + + UserSessionSettingsFile + + Comment + User settings that are a applied per session (not saved). + Persist + 0 + Type + String + Value + + diff --git a/indra/newview/app_settings/settings_files.xml b/indra/newview/app_settings/settings_files.xml index aa5b301959..079a54f957 100644 --- a/indra/newview/app_settings/settings_files.xml +++ b/indra/newview/app_settings/settings_files.xml @@ -1,148 +1,64 @@ - - - Locations - - - Comment - List location from which to load files, and the rules about loading those files. - Persist - 0 - Type - LLSD - Value - - Default - - PathIndex - 2 - Files - - Global - - Name - settings.xml - Requirement - 1 - - PerAccount - - Name - settings_per_account.xml - Requirement - 1 - - CrashSettings - - Name - settings_crash_behavior.xml - Requirement - 1 - - Warnings - - Name - ignorable_dialogs.xml - Requirement - 1 - - - - User - - PathIndex - 1 - Files - - Global - - Name - settings.xml - NameFromSetting - ClientSettingsFile - - CrashSettings - - Name - settings_crash_behavior.xml - - Warnings - - Name - ignorable_dialogs.xml - NameFromSetting - WarningSettingsFile - - - - Account - - PathIndex - 3 - Files - - PerAccount - - Name - settings_per_account.xml - NameFromSetting - PerAccountSettingsFile - - - - DefaultSkin - - PathIndex - 17 - Files - - Skinning - - Name - colors.xml - - - - CurrentSkin - - PathIndex - 10 - Files - - Skinning - - Name - colors.xml - - - - UserSkin - - PathIndex - 14 - Files - - Skinning - - Name - colors.xml - NameFromSetting - SkinningSettingsFile - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index a23f809b71..c285ddc2f6 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -337,6 +337,46 @@ void init_default_trans_args() const char *VFS_DATA_FILE_BASE = "data.db2.x."; const char *VFS_INDEX_FILE_BASE = "index.db2.x."; + +struct SettingsFile : public LLInitParam::Block +{ + Mandatory name; + Optional file_name; + Optional required, + persistent; + Optional file_name_setting; + + SettingsFile() + : name("name"), + file_name("file_name"), + required("required", false), + persistent("persistent", true), + file_name_setting("file_name_setting") + {} +}; + +struct SettingsGroup : public LLInitParam::Block +{ + Mandatory name; + Mandatory path_index; + Multiple files; + + SettingsGroup() + : name("name"), + path_index("path_index"), + files("file") + {} +}; + +struct SettingsFiles : public LLInitParam::Block +{ + Multiple groups; + + SettingsFiles() + : groups("group") + {} +}; + static std::string gWindowTitle; LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ; @@ -594,7 +634,8 @@ LLAppViewer::LLAppViewer() : mRandomizeFramerate(LLCachedControl(gSavedSettings,"Randomize Framerate", FALSE)), mPeriodicSlowFrame(LLCachedControl(gSavedSettings,"Periodic Slow Frame", FALSE)), mFastTimerLogThread(NULL), - mUpdater(new LLUpdaterService()) + mUpdater(new LLUpdaterService()), + mSettingsLocationList(NULL) { if(NULL != sInstance) { @@ -610,6 +651,8 @@ LLAppViewer::LLAppViewer() : LLAppViewer::~LLAppViewer() { + delete mSettingsLocationList; + LLLoginInstance::instance().setUpdaterService(0); destroyMainloopTimeout(); @@ -1879,85 +1922,72 @@ bool LLAppViewer::initLogging() bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, bool set_defaults) { - // Find and vet the location key. - if(!mSettingsLocationList.has(location_key)) + if (!mSettingsLocationList) { - llerrs << "Requested unknown location: " << location_key << llendl; - return false; + llerrs << "Invalid settings location list" << llendl; } - LLSD location = mSettingsLocationList.get(location_key); - - if(!location.has("PathIndex")) - { - llerrs << "Settings location is missing PathIndex value. Settings cannot be loaded." << llendl; - return false; - } - ELLPath path_index = (ELLPath)(location.get("PathIndex").asInteger()); - if(path_index <= LL_PATH_NONE || path_index >= LL_PATH_LAST) + LLControlGroup* global_settings = LLControlGroup::getInstance(sGlobalSettingsName); + for(LLInitParam::ParamIterator::const_iterator it = mSettingsLocationList->groups.begin(), end_it = mSettingsLocationList->groups.end(); + it != end_it; + ++it) { - llerrs << "Out of range path index in app_settings/settings_files.xml" << llendl; - return false; - } - - // Iterate through the locations list of files. - LLSD files = location.get("Files"); - for(LLSD::map_iterator itr = files.beginMap(); itr != files.endMap(); ++itr) - { - std::string settings_group = (*itr).first; - llinfos << "Attempting to load settings for the group " << settings_group - << " - from location " << location_key << llendl; + if (it->name() != location_key) continue; - if(!LLControlGroup::getInstance(settings_group)) + ELLPath path_index = (ELLPath)it->path_index(); + if(path_index <= LL_PATH_NONE || path_index >= LL_PATH_LAST) { - llwarns << "No matching settings group for name " << settings_group << llendl; - continue; + llerrs << "Out of range path index in app_settings/settings_files.xml" << llendl; + return false; } - LLSD file = (*itr).second; - - std::string full_settings_path; - if(file.has("NameFromSetting")) + LLInitParam::ParamIterator::const_iterator file_it, end_file_it; + for (file_it = it->files.begin(), end_file_it = it->files.end(); + file_it != end_file_it; + ++file_it) { - std::string custom_name_setting = file.get("NameFromSetting"); - // *NOTE: Regardless of the group currently being lodaed, - // this setting is always read from the Global settings. - if(LLControlGroup::getInstance(sGlobalSettingsName)->controlExists(custom_name_setting)) + llinfos << "Attempting to load settings for the group " << file_it->name() + << " - from location " << location_key << llendl; + + LLControlGroup* settings_group = LLControlGroup::getInstance(file_it->name); + if(!settings_group) { - std::string file_name = - LLControlGroup::getInstance(sGlobalSettingsName)->getString(custom_name_setting); - full_settings_path = file_name; + llwarns << "No matching settings group for name " << file_it->name() << llendl; + continue; } - } - if(full_settings_path.empty()) - { - std::string file_name = file.get("Name"); - full_settings_path = gDirUtilp->getExpandedFilename(path_index, file_name); - } + std::string full_settings_path; - int requirement = 0; - if(file.has("Requirement")) - { - requirement = file.get("Requirement").asInteger(); - } - - if(!LLControlGroup::getInstance(settings_group)->loadFromFile(full_settings_path, set_defaults)) - { - if(requirement == 1) + if (file_it->file_name_setting.isProvided() + && global_settings->controlExists(file_it->file_name_setting)) { - llwarns << "Error: Cannot load required settings file from: " - << full_settings_path << llendl; - return false; + full_settings_path = global_settings->getString(file_it->file_name_setting); } else { - llinfos << "Cannot load " << full_settings_path << " - No settings found." << llendl; + full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, file_it->file_name()); + } + + if(!settings_group->loadFromFile(full_settings_path, set_defaults, file_it->persistent)) + { + if(file_it->required) + { + llwarns << "Error: Cannot load required settings file from: " + << full_settings_path << llendl; + return false; + } + else + { + if (!full_settings_path.empty()) + { + llinfos << "Cannot load " << full_settings_path << " - No settings found." << llendl; + } + } + } + else + { + llinfos << "Loaded settings file " << full_settings_path << llendl; } - } - else - { - llinfos << "Loaded settings file " << full_settings_path << llendl; } } @@ -1967,18 +1997,25 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key, std::string LLAppViewer::getSettingsFilename(const std::string& location_key, const std::string& file) { - if(mSettingsLocationList.has(location_key)) + for(LLInitParam::ParamIterator::const_iterator it = mSettingsLocationList->groups.begin(), end_it = mSettingsLocationList->groups.end(); + it != end_it; + ++it) { - LLSD location = mSettingsLocationList.get(location_key); - if(location.has("Files")) + if (it->name() == location_key) { - LLSD files = location.get("Files"); - if(files.has(file) && files[file].has("Name")) + LLInitParam::ParamIterator::const_iterator file_it, end_file_it; + for (file_it = it->files.begin(), end_file_it = it->files.end(); + file_it != end_file_it; + ++file_it) { - return files.get(file).get("Name").asString(); + if (file_it->name() == file) + { + return file_it->file_name; + } } } } + return std::string(); } @@ -1991,14 +2028,29 @@ bool LLAppViewer::initConfiguration() { //Load settings files list std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml"); - LLControlGroup settings_control("SettingsFiles"); - llinfos << "Loading settings file list " << settings_file_list << llendl; - if (0 == settings_control.loadFromFile(settings_file_list)) + //LLControlGroup settings_control("SettingsFiles"); + //llinfos << "Loading settings file list " << settings_file_list << llendl; + //if (0 == settings_control.loadFromFile(settings_file_list)) + //{ + // llerrs << "Cannot load default configuration file " << settings_file_list << llendl; + //} + + LLXMLNodePtr root; + BOOL success = LLXMLNode::parseFile(settings_file_list, root, NULL); + if (!success) { llerrs << "Cannot load default configuration file " << settings_file_list << llendl; } - mSettingsLocationList = settings_control.getLLSD("Locations"); + mSettingsLocationList = new SettingsFiles(); + + LLXUIParser parser; + parser.readXUI(root, *mSettingsLocationList, settings_file_list); + + if (!mSettingsLocationList->validateBlock()) + { + llerrs << "Invalid settings file list " << settings_file_list << llendl; + } // The settings and command line parsing have a fragile // order-of-operation: @@ -2105,6 +2157,29 @@ bool LLAppViewer::initConfiguration() << user_settings_filename << llendl; } + if (clp.hasOption("sessionsettings")) + { + std::string session_settings_filename = + gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, + clp.getOption("sessionsettings")[0]); + gSavedSettings.setString("SessionSettingsFile", session_settings_filename); + llinfos << "Using session settings filename: " + << session_settings_filename << llendl; + } + loadSettingsFromDirectory("Session"); + + if (clp.hasOption("usersessionsettings")) + { + std::string user_session_settings_filename = + gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, + clp.getOption("usersessionsettings")[0]); + gSavedSettings.setString("UserSessionSettingsFile", user_session_settings_filename); + llinfos << "Using user session settings filename: " + << user_session_settings_filename << llendl; + + } + loadSettingsFromDirectory("UserSession"); + // - load overrides from user_settings loadSettingsFromDirectory("User"); // - apply command line settings diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h index a18e6cbb02..0226211735 100644 --- a/indra/newview/llappviewer.h +++ b/indra/newview/llappviewer.h @@ -253,7 +253,7 @@ private: bool mQuitRequested; // User wants to quit, may have modified documents open. bool mLogoutRequestSent; // Disconnect message sent to simulator, no longer safe to send messages to the sim. S32 mYieldTime; - LLSD mSettingsLocationList; + struct SettingsFiles* mSettingsLocationList; LLWatchdogTimeout* mMainloopTimeout; -- cgit v1.3 From 8886460a22a6cc6307dd0909219b4dd442c55f8d Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Wed, 9 Mar 2011 00:21:57 -0800 Subject: SOCIAL-654 WIP Items purchased on Marketplace.secondlife.com while logged into Minimal skin are declined and not present in inventory made notification text skinnable --- indra/llui/llnotifications.cpp | 44 ++++++++++++++++++++++++------------------ indra/llui/llnotifications.h | 11 +++++------ indra/llui/lluictrlfactory.cpp | 22 ++++++++++++++++++++- indra/llvfs/lldir.cpp | 6 +++++- indra/llxml/llxmlnode.cpp | 24 +++++++++++------------ indra/llxml/llxmlnode.h | 3 +-- 6 files changed, 68 insertions(+), 42 deletions(-) (limited to 'indra/llxml') diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp index 89614e6d12..578de4376c 100644 --- a/indra/llui/llnotifications.cpp +++ b/indra/llui/llnotifications.cpp @@ -1266,7 +1266,6 @@ LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelN void LLNotifications::initSingleton() { loadTemplates(); - loadVisibilityRules(); createDefaultChannels(); } @@ -1310,17 +1309,6 @@ void LLNotifications::createDefaultChannels() connectFailedFilter(&visibilityRuleMached); } -bool LLNotifications::addTemplate(const std::string &name, - LLNotificationTemplatePtr theTemplate) -{ - if (mTemplates.count(name)) - { - llwarns << "LLNotifications -- attempted to add template '" << name << "' twice." << llendl; - return false; - } - mTemplates[name] = theTemplate; - return true; -} LLNotificationTemplatePtr LLNotifications::getTemplate(const std::string& name) { @@ -1417,27 +1405,45 @@ void replaceFormText(LLNotificationForm::Params& form, const std::string& patter } } +void addPathIfExists(std::string& new_path, std::vector& paths) +{ + if (gDirUtilp->fileExists(new_path)) + { + paths.push_back(new_path); + } +} + bool LLNotifications::loadTemplates() { - const std::string xml_filename = "notifications.xml"; - std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename); + std::vector search_paths; + + std::string skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml"; + std::string localized_skin_relative_path = gDirUtilp->getDirDelimiter() + LLUI::getLocalizedSkinPath() + gDirUtilp->getDirDelimiter() + "notifications.xml"; + + addPathIfExists(gDirUtilp->getDefaultSkinDir() + skin_relative_path, search_paths); + addPathIfExists(gDirUtilp->getDefaultSkinDir() + localized_skin_relative_path, search_paths); + addPathIfExists(gDirUtilp->getSkinDir() + skin_relative_path, search_paths); + addPathIfExists(gDirUtilp->getSkinDir() + localized_skin_relative_path, search_paths); + addPathIfExists(gDirUtilp->getUserSkinDir() + skin_relative_path, search_paths); + addPathIfExists(gDirUtilp->getUserSkinDir() + localized_skin_relative_path, search_paths); + std::string base_filename = search_paths.front(); LLXMLNodePtr root; - BOOL success = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root); + BOOL success = LLXMLNode::getLayeredXMLNode(root, search_paths); if (!success || root.isNull() || !root->hasName( "notifications" )) { - llerrs << "Problem reading UI Notifications file: " << full_filename << llendl; + llerrs << "Problem reading UI Notifications file: " << base_filename << llendl; return false; } LLNotificationTemplate::Notifications params; LLXUIParser parser; - parser.readXUI(root, params, full_filename); + parser.readXUI(root, params, base_filename); if(!params.validateBlock()) { - llerrs << "Problem reading UI Notifications file: " << full_filename << llendl; + llerrs << "Problem reading UI Notifications file: " << base_filename << llendl; return false; } @@ -1484,7 +1490,7 @@ bool LLNotifications::loadTemplates() replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text); } } - addTemplate(it->name, LLNotificationTemplatePtr(new LLNotificationTemplate(*it))); + mTemplates[it->name] = LLNotificationTemplatePtr(new LLNotificationTemplate(*it)); } return true; diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h index 34d3537781..0c4d4fc897 100644 --- a/indra/llui/llnotifications.h +++ b/indra/llui/llnotifications.h @@ -863,10 +863,11 @@ class LLNotifications : friend class LLSingleton; public: - // load notification descriptions from file; - // OK to call more than once because it will reload - bool loadTemplates(); - + // load all notification descriptions from file + // calling more than once will overwrite existing templates + // but never delete a template + bool loadTemplates(); + // load visibility rules from file; // OK to call more than once because it will reload bool loadVisibilityRules(); @@ -950,8 +951,6 @@ private: LLNotificationChannelPtr pHistoryChannel; LLNotificationChannelPtr pExpirationChannel; - // put your template in - bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate); TemplateMap mTemplates; VisibilityRuleList mVisibilityRules; diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp index 55b32fc8b1..25e7a31e90 100644 --- a/indra/llui/lluictrlfactory.cpp +++ b/indra/llui/lluictrlfactory.cpp @@ -152,7 +152,27 @@ static LLFastTimer::DeclareTimer FTM_XML_PARSE("XML Reading/Parsing"); bool LLUICtrlFactory::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root) { LLFastTimer timer(FTM_XML_PARSE); - return LLXMLNode::getLayeredXMLNode(xui_filename, root, LLUI::getXUIPaths()); + + std::vector paths; + std::string path = gDirUtilp->findSkinnedFilename(LLUI::getSkinPath(), xui_filename); + if (!path.empty()) + { + paths.push_back(path); + } + + std::string localize_path = gDirUtilp->findSkinnedFilename(LLUI::getLocalizedSkinPath(), xui_filename); + if (!localize_path.empty() && localize_path != path) + { + paths.push_back(localize_path); + } + + if (paths.empty()) + { + // sometimes whole path is passed in as filename + paths.push_back(xui_filename); + } + + return LLXMLNode::getLayeredXMLNode(root, paths); } diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp index cb898e385f..341c96f6ea 100644 --- a/indra/llvfs/lldir.cpp +++ b/indra/llvfs/lldir.cpp @@ -149,7 +149,11 @@ const std::string LLDir::findFile(const std::string& filename, const std::vector { if (!search_path_iter->empty()) { - std::string filename_and_path = (*search_path_iter) + getDirDelimiter() + filename; + std::string filename_and_path = (*search_path_iter); + if (!filename.empty()) + { + filename_and_path += getDirDelimiter() + filename; + } if (fileExists(filename_and_path)) { return filename_and_path; diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp index 8168f968cd..9f1e249ddd 100644 --- a/indra/llxml/llxmlnode.cpp +++ b/indra/llxml/llxmlnode.cpp @@ -859,23 +859,21 @@ BOOL LLXMLNode::isFullyDefault() } // static -bool LLXMLNode::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root, +bool LLXMLNode::getLayeredXMLNode(LLXMLNodePtr& root, const std::vector& paths) { - std::string full_filename = gDirUtilp->findSkinnedFilename(paths.front(), xui_filename); - if (full_filename.empty()) + if (paths.empty()) return false; + + std::string filename = paths.front(); + if (filename.empty()) { return false; } - - if (!LLXMLNode::parseFile(full_filename, root, NULL)) + + if (!LLXMLNode::parseFile(filename, root, NULL)) { - // try filename as passed in since sometimes we load an xml file from a user-supplied path - if (!LLXMLNode::parseFile(xui_filename, root, NULL)) - { - llwarns << "Problem reading UI description file: " << xui_filename << llendl; - return false; - } + llwarns << "Problem reading UI description file: " << filename << llendl; + return false; } LLXMLNodePtr updateRoot; @@ -887,7 +885,7 @@ bool LLXMLNode::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& std::string nodeName; std::string updateName; - std::string layer_filename = gDirUtilp->findSkinnedFilename((*itor), xui_filename); + std::string layer_filename = *itor; if(layer_filename.empty()) { // no localized version of this file, that's ok, keep looking @@ -896,7 +894,7 @@ bool LLXMLNode::getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& if (!LLXMLNode::parseFile(layer_filename, updateRoot, NULL)) { - llwarns << "Problem reading localized UI description file: " << (*itor) + gDirUtilp->getDirDelimiter() + xui_filename << llendl; + llwarns << "Problem reading localized UI description file: " << layer_filename << llendl; return false; } diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h index 9df37ccb6f..e3da7169e7 100644 --- a/indra/llxml/llxmlnode.h +++ b/indra/llxml/llxmlnode.h @@ -149,8 +149,7 @@ public: LLXMLNodePtr& update_node); static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node); - static bool getLayeredXMLNode(const std::string &xui_filename, LLXMLNodePtr& root, - const std::vector& paths); + static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector& paths); // Write standard XML file header: -- cgit v1.3