mirror of
https://github.com/FirestormViewer/phoenix-firestorm.git
synced 2026-08-14 00:48:30 +00:00
FIRE-36763 - Add rule sets to Omnifilter
Added new UI elements to the Omnifilter to allow adding multiple rule sets to the Omnifilter and switching between each rule set with an drop down. There is an option to create a new empty rule set with a specified name, clone the current active rule set with a specified name, and remove the current rule set. This allows the user to have different rule sets configured and to be able to switch to the rule sets. Added new setting to keep track of the rule set selected so it can be restored after logging out. Also added a new notifications that either show errors to the user or prompt for new rule set names or ask the user if they really want to remove a rule set.
This commit is contained in:
@@ -27530,6 +27530,19 @@ Change of this parameter will affect the layout of buttons in notification toast
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<!-- <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter -->
|
||||
<key>OmnifilterRuleSetID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>The id of the current rule set for the Omnifilter.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>-1</integer>
|
||||
</map>
|
||||
<!-- </FS:minerjr> [FIRE-36763] -->
|
||||
<key>FSAutoOrderIMTabs</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
#include "llcombobox.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "lltexteditor.h"
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
#include "llviewercontrol.h" // Needed for gSavedSettings
|
||||
#include "llnotificationsutil.h" // Needed for Notifications
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
|
||||
#include "fsscrolllistctrl.h"
|
||||
|
||||
@@ -78,7 +82,11 @@ OmnifilterEngine::Needle* Omnifilter::getSelectedNeedle()
|
||||
if (needle_name_cell)
|
||||
{
|
||||
const std::string& needle_name = needle_name_cell->getValue().asString();
|
||||
if (!needle_name.empty())
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
//if (!needle_name.empty())
|
||||
// Only try to access the needle if the name is not empty and it is on the current needle list, otherwise it will cause an error
|
||||
if (!needle_name.empty() && OmnifilterEngine::getInstance()->getNeedleList().contains(needle_name))
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
{
|
||||
return &OmnifilterEngine::getInstance()->getNeedleList().at(needle_name);
|
||||
}
|
||||
@@ -277,6 +285,237 @@ void Omnifilter::onDownNeedleClicked()
|
||||
}
|
||||
// </FS:minerjr> [FIRE-36649]
|
||||
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
// Callback method for the New Rule Set button when clicked.
|
||||
// Creates an notification to the user to ask for the name of the new rule set.
|
||||
void Omnifilter::onNewRuleSetClicked()
|
||||
{
|
||||
LLSD args;
|
||||
// Default name of the new rule set
|
||||
args["RULESETNAME"] = "New Rule Set";
|
||||
// Display the new rule set notification and if the user presses the OK button, call the new rule set name selected callback method
|
||||
LLNotificationsUtil::add("OmniFilterNewRuleSet", args, LLSD(),
|
||||
boost::bind(&Omnifilter::onNewRuleSetNameSelectedCallback, this, _1, _2));
|
||||
}
|
||||
|
||||
// Callback method for the Clone Rule Set button when clicked.
|
||||
// Creates an notification to the user to ask for the name of the clone rule set.
|
||||
void Omnifilter::onCloneRuleSetClicked()
|
||||
{
|
||||
LLSD args;
|
||||
// Default name of the cloned rule set
|
||||
args["RULESETNAME"] = "Cloned Rule Set";
|
||||
// Display the new rule set notification and if the user presses the OK button, call the new rule set name selected callback method
|
||||
LLNotificationsUtil::add("OmniFilterCloneRuleSet", args, LLSD(),
|
||||
boost::bind(&Omnifilter::onCloneRuleSetNameSelectedCallback, this, _1, _2));
|
||||
}
|
||||
|
||||
// Callback method for the Remove Rule Set button when clicked.
|
||||
// Creates a notification to the user to ask if they are sure they want to remove the specified Rule Set.
|
||||
void Omnifilter::onRemoveRuleSetClicked()
|
||||
{
|
||||
static OmnifilterEngine* instance = OmnifilterEngine::getInstance();
|
||||
// IF the user tries to remove the Default rule set, send an error as that is not allowed.
|
||||
if (mRuleSetsCmb->getCurrentIndex() == 0)
|
||||
{
|
||||
LLNotificationsUtil::add("OmniFilterRemoveRuleSetDefault", LLSD(), LLSD());
|
||||
}
|
||||
// Else prompt the user with a confirmation notification if they really want to remove the
|
||||
else
|
||||
{
|
||||
LLSD args;
|
||||
args["RULESETNAME"] = instance->getCurrentSelectedRuleSet();
|
||||
// Display the remove rule set notification and if the user presses the OK button, call the remove rule set confirm callback method
|
||||
LLNotificationsUtil::add("OmniFilterRemoveRuleSet", args, LLSD(),
|
||||
boost::bind(&Omnifilter::onRemoveRuleSetConfirmedCallback, this, _1, _2));
|
||||
}
|
||||
}
|
||||
|
||||
// New Rule Set callback, which does the actual cloning.
|
||||
void Omnifilter::onNewRuleSetNameSelectedCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
static OmnifilterEngine* instance = OmnifilterEngine::getInstance();
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option == 0) // YES
|
||||
{
|
||||
std::string new_name = response["new_name"].asString();
|
||||
// Try to perform the actual creating a new rule set.
|
||||
S32 return_value = instance->addNewRuleSet(new_name);
|
||||
|
||||
if (return_value == 1)
|
||||
{
|
||||
S32 new_rule_index = gSavedSettings.getS32("OmnifilterRuleSetID");
|
||||
// Add the new rule set to the Rule Set Drop Down
|
||||
mRuleSetsCmb->add(new_name, LLSD(new_rule_index));
|
||||
// Select the new rule set
|
||||
mRuleSetsCmb->setCurrentByIndex(new_rule_index);
|
||||
|
||||
// Clear the Rule list
|
||||
mNeedleListCtrl->clear();
|
||||
mNeedleListCtrl->clearRows();
|
||||
|
||||
// Add the new item.
|
||||
onAddNeedleClicked();
|
||||
|
||||
// Save the state of the OmniFilter Window
|
||||
instance->setDirty(true);
|
||||
}
|
||||
// Else the user tried to create a new rule set with a blank name, so show an error.
|
||||
else if (return_value == -1)
|
||||
{
|
||||
LLNotificationsUtil::add("OmniFilterrNewRuleSetBlank", LLSD(), LLSD(), boost::bind(&Omnifilter::onNewRuleSetClicked, this));
|
||||
}
|
||||
// Else the user tried to create a new rule set with a duplicate name, so show an error.
|
||||
else if (return_value == 0)
|
||||
{
|
||||
LLNotificationsUtil::add("OmniFilterNewRuleSetDuplicate", LLSD(), LLSD(), boost::bind(&Omnifilter::onNewRuleSetClicked, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clone Rule Set callback, which does the actual cloning.
|
||||
void Omnifilter::onCloneRuleSetNameSelectedCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
static OmnifilterEngine* instance = OmnifilterEngine::getInstance();
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option == 0) // YES
|
||||
{
|
||||
std::string new_name = response["new_name"].asString();
|
||||
// Try to perform the actual cloning of the rule set.
|
||||
S32 return_value = instance->addClonedRuleSet(new_name);
|
||||
// If the cloning succeeded
|
||||
if (return_value == 1)
|
||||
{
|
||||
// Get the index of the added rule set.
|
||||
S32 new_rule_index = gSavedSettings.getS32("OmnifilterRuleSetID");
|
||||
// Add the new rule set to the Rule Set Drop Down
|
||||
mRuleSetsCmb->add(new_name, LLSD(new_rule_index));
|
||||
|
||||
// Select the new rule set
|
||||
mRuleSetsCmb->setCurrentByIndex(new_rule_index);
|
||||
|
||||
// Save the state of the OmniFilter Window
|
||||
instance->setDirty(true);
|
||||
}
|
||||
// Else the user tried to create a cloned rule set with a blank name, so show an error.
|
||||
else if (return_value == -1)
|
||||
{
|
||||
LLNotificationsUtil::add("OmniFilterCloneRuleSetBlank", LLSD(), LLSD(), boost::bind(&Omnifilter::onCloneRuleSetClicked, this));
|
||||
}
|
||||
// Else the user tried to create a cloned rule set with a duplicate name, so show an error.
|
||||
else if (return_value == 0)
|
||||
{
|
||||
LLNotificationsUtil::add("OmniFilterCloneRuleSetDuplicate", LLSD(), LLSD(), boost::bind(&Omnifilter::onCloneRuleSetClicked, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove Rule Set callback, which does the actual removal.
|
||||
void Omnifilter::onRemoveRuleSetConfirmedCallback(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
static OmnifilterEngine* instance = OmnifilterEngine::getInstance();
|
||||
// Get the user response
|
||||
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
||||
if (option == 0) // YES
|
||||
{
|
||||
std::string tooltip_msg;
|
||||
// Get the index of the current rule set being removed.
|
||||
S32 current_index = gSavedSettings.getS32("OmnifilterRuleSetID");
|
||||
// Try to perform the actual removal.
|
||||
S32 return_value = instance->removeCurrentRuleSet();
|
||||
// If the removal succeeded
|
||||
if (return_value == 1)
|
||||
{
|
||||
// Remove the rule set from the Rule Set Drop Down
|
||||
mRuleSetsCmb->remove(current_index);
|
||||
// Reload the current rule set and switch the UI over to the Default rule set.
|
||||
reloadRule();
|
||||
mRuleSetsCmb->setCurrentByIndex(0);
|
||||
|
||||
// Save the state of the OmniFilter Window
|
||||
instance->setDirty(true);
|
||||
}
|
||||
// Else the user tried to remove the default rule set, so show an error.
|
||||
else if (return_value == 0)
|
||||
{
|
||||
LLNotificationsUtil::add("OmniFilterRemoveRuleSetDefault", LLSD(), LLSD());
|
||||
}
|
||||
// Else the user tried to remove a rule set that index was out of bounds, so show an error.
|
||||
else if (return_value == -1)
|
||||
{
|
||||
LLSD args;
|
||||
args["OUTOFBOUNDS"] = current_index;
|
||||
LLNotificationsUtil::add("OmniFilterRemoveRuleSetOutofBounds", args, LLSD());
|
||||
}
|
||||
// Else the user tried to remove a rule set that had an name that does not exist in the map of rule sets, so show an error.
|
||||
else if (return_value == -2)
|
||||
{
|
||||
LLSD args;
|
||||
args["INVALIDNAME"] = instance->getCurrentSelectedRuleSet();
|
||||
LLNotificationsUtil::add("OmniFilterRemoveRuleSetInvalidName", args, LLSD());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Rule Set Drop Down on commit callback method
|
||||
void Omnifilter::onRuleSetChanged()
|
||||
{
|
||||
static OmnifilterEngine* instance = OmnifilterEngine::getInstance();
|
||||
|
||||
// Save the current
|
||||
// Write the current rule set back to the storeage
|
||||
instance->assignRuleSet(false);
|
||||
// Store the current combo box index as the Needle Preset Index
|
||||
gSavedSettings.setS32("OmnifilterRuleSetID", mRuleSetsCmb->getCurrentIndex());
|
||||
// Assign and reload the current rule
|
||||
instance->assignRuleSetNameFromSettings();
|
||||
|
||||
instance->assignRuleSet(true);
|
||||
reloadRule();
|
||||
}
|
||||
|
||||
// Reloads the full rule sets drop down widget (combobox)
|
||||
void Omnifilter::reloadRules()
|
||||
{
|
||||
static OmnifilterEngine* instance = OmnifilterEngine::getInstance();
|
||||
// Clear the current needles
|
||||
mRuleSetsCmb->clear();
|
||||
S32 current_rule_set_id = gSavedSettings.getS32("OmnifilterRuleSetID");
|
||||
for (S32 index = 0; index < instance->getOrderedRuleSetSize(); index++)
|
||||
{
|
||||
// Get the name from the ordered list of rule sets.
|
||||
const std::string needle_rule_set_name(instance->getOrderedRuleSetName(index));
|
||||
LLSD value(index);
|
||||
// And add to the UI element. The value is the value that is passed along with the commit callback method.
|
||||
mRuleSetsCmb->add(needle_rule_set_name, value);
|
||||
}
|
||||
// Finally, select the stored rule set
|
||||
mRuleSetsCmb->selectByValue(LLSD(current_rule_set_id));
|
||||
}
|
||||
|
||||
// Reloads the actual rule set UI elements, including the Rule scroll list and editor panel
|
||||
void Omnifilter::reloadRule()
|
||||
{
|
||||
// Use static pointer for the instance so that don't have to keep requesting every time this code is touched.
|
||||
static OmnifilterEngine* instance = OmnifilterEngine::getInstance();
|
||||
// Clear the current needles
|
||||
mNeedleListCtrl->clearRows();
|
||||
mNeedleListCtrl->clear();
|
||||
|
||||
// Loop over the ordered list
|
||||
for (const auto& needle_name : instance->getOrderedNeedleList())
|
||||
{
|
||||
// Get the current needle and use the addNeedle method to add the the UI.
|
||||
const auto& needle = instance->getNeedleList()[needle_name];
|
||||
addNeedle(needle_name, needle);
|
||||
}
|
||||
|
||||
mNeedleListCtrl->selectFirstItem();
|
||||
onSelectNeedle();
|
||||
}
|
||||
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
|
||||
void Omnifilter::onNeedleNameChanged()
|
||||
{
|
||||
const std::string& old_name = mNeedleListCtrl->getSelectedItemLabel(NEEDLE_NAME_COLUMN);
|
||||
@@ -381,6 +620,13 @@ bool Omnifilter::postBuild()
|
||||
mSenderCaseSensitiveCheck = getChild<LLCheckBoxCtrl>("sender_case");
|
||||
mSenderMatchTypeCombo = getChild<LLComboBox>("sender_match_type");
|
||||
mContentCtrl = getChild<LLTextEditor>("content");
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
// Add the preset controls
|
||||
mRuleSetsCmb = getChild<LLComboBox>("cmb_rule_sets"); // Rule Set Drop Down
|
||||
mNewRuleSetBtn = getChild<LLButton>("btn_rule_set_new"); // New Rule Set
|
||||
mCloneRuleSetBtn = getChild<LLButton>("btn_rule_set_clone"); // Clone Rule Set
|
||||
mRemoveRuleSetBtn = getChild<LLButton>("btn_rule_set_remove"); // Remove Rule Set
|
||||
// <//FS:minerjr> [FIRE-36763]
|
||||
mContentCaseSensitiveCheck = getChild<LLCheckBoxCtrl>("content_case");
|
||||
mContentMatchTypeCombo = getChild<LLComboBox>("content_match_type");
|
||||
mRegionNameCtrl = getChild<LLLineEditor>("region_name");
|
||||
@@ -412,6 +658,12 @@ bool Omnifilter::postBuild()
|
||||
mFilterLogCtrl->deleteAllItems();
|
||||
|
||||
auto& instance = OmnifilterEngine::instance();
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
// Reload the rules set UI elements, uses the settings stored rule set ID
|
||||
reloadRules();
|
||||
instance.assignRuleSetNameFromSettings();
|
||||
instance.assignRuleSet(true);
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
// <FS:minerjr> [FIRE-36649] - Add reordering to OmniFilter
|
||||
//for (const auto& [needle_name, needle] : instance.getNeedleList())
|
||||
// Loop over the ordered list
|
||||
@@ -446,6 +698,13 @@ bool Omnifilter::postBuild()
|
||||
mUpNeedleBtn->setCommitCallback(boost::bind(&Omnifilter::onUpNeedleClicked, this));
|
||||
mDownNeedleBtn->setCommitCallback(boost::bind(&Omnifilter::onDownNeedleClicked, this));
|
||||
// </FS:minerjr> [FIRE-36649]
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
// Add the Rule Set controls
|
||||
mRuleSetsCmb->setCommitCallback(boost::bind(&Omnifilter::onRuleSetChanged, this)); // Rule Set Drop Down
|
||||
mNewRuleSetBtn->setCommitCallback(boost::bind(&Omnifilter::onNewRuleSetClicked, this)); // New Rule Set
|
||||
mCloneRuleSetBtn->setCommitCallback(boost::bind(&Omnifilter::onCloneRuleSetClicked, this)); // Clone Rule Set
|
||||
mRemoveRuleSetBtn->setCommitCallback(boost::bind(&Omnifilter::onRemoveRuleSetClicked, this)); // Remove Rule Set
|
||||
// <//FS:minerjr> [FIRE-36763]
|
||||
mNeedleNameCtrl->setCommitCallback(boost::bind(&Omnifilter::onNeedleNameChanged, this));
|
||||
mSenderNameCtrl->setCommitCallback(boost::bind(&Omnifilter::onNeedleChanged, this));
|
||||
mSenderCaseSensitiveCheck->setCommitCallback(boost::bind(&Omnifilter::onNeedleChanged, this));
|
||||
|
||||
@@ -60,6 +60,17 @@ protected:
|
||||
void onUpNeedleClicked();
|
||||
void onDownNeedleClicked();
|
||||
// </FS:minerjr> [FIRE-36649]
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
void onNewRuleSetClicked();
|
||||
void onCloneRuleSetClicked();
|
||||
void onRemoveRuleSetClicked();
|
||||
void onNewRuleSetNameSelectedCallback(const LLSD& notification, const LLSD& response);
|
||||
void onCloneRuleSetNameSelectedCallback(const LLSD& notification, const LLSD& response);
|
||||
void onRemoveRuleSetConfirmedCallback(const LLSD& notification, const LLSD& response);
|
||||
void onRuleSetChanged();
|
||||
void reloadRules();
|
||||
void reloadRule();
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
void onNeedleNameChanged();
|
||||
void onNeedleCheckboxChanged(LLUICtrl* ctrl);
|
||||
void onOwnerChanged();
|
||||
@@ -73,6 +84,12 @@ protected:
|
||||
LLButton* mUpNeedleBtn{ nullptr };
|
||||
LLButton* mDownNeedleBtn{ nullptr };
|
||||
// </FS:minerjr> [FIRE-36649]
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
LLComboBox* mRuleSetsCmb{ nullptr };
|
||||
LLButton* mNewRuleSetBtn{ nullptr };
|
||||
LLButton* mCloneRuleSetBtn{ nullptr };
|
||||
LLButton* mRemoveRuleSetBtn{ nullptr };
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
FSScrollListCtrl* mFilterLogCtrl{ nullptr };
|
||||
LLPanel* mPanelDetails{ nullptr };
|
||||
LLLineEditor* mNeedleNameCtrl{ nullptr };
|
||||
|
||||
@@ -38,13 +38,18 @@ OmnifilterEngine::OmnifilterEngine()
|
||||
: LLSingleton<OmnifilterEngine>()
|
||||
, LLEventTimer(5.0f)
|
||||
, mDirty(false)
|
||||
, mCurrentSelectedRuleSet("Default") // <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
{
|
||||
mEventTimer.stop();
|
||||
}
|
||||
|
||||
OmnifilterEngine::~OmnifilterEngine()
|
||||
{
|
||||
// delete Xxx;
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
// If the user changed a setting and quickly closed the viewer, the changes would not be saved, but
|
||||
// the changes to the settings.xml would, which would cause issues. So save upon close just in case.
|
||||
saveNeedles();
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
}
|
||||
|
||||
void OmnifilterEngine::init()
|
||||
@@ -325,6 +330,363 @@ void OmnifilterEngine::setDirty(bool dirty)
|
||||
}
|
||||
}
|
||||
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
// Get the name from the vector of ordered rule sets at the specified index
|
||||
std::string_view OmnifilterEngine::getOrderedRuleSetName(const S32 index) const
|
||||
{
|
||||
// If the index is within the range of the vector, return the stored value
|
||||
if (index >= 0 && index < mOrderedRuleSets.size() && mOrderedRuleSets.size() > 0)
|
||||
{
|
||||
return mOrderedRuleSets[index];
|
||||
}
|
||||
|
||||
// Return an empty string if not found.
|
||||
return "";
|
||||
}
|
||||
|
||||
// Gets the ordered rule set index by looking up the name of a rule set.
|
||||
S32 OmnifilterEngine::getOrderedRuleSetIndex(std::string_view lookup_name)
|
||||
{
|
||||
for (S32 index = 0; index < mOrderedNeedles.size(); index++)
|
||||
{
|
||||
if (mOrderedNeedles[index] == lookup_name)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Parses a passed in LLSD as a Map of rule sets, which contain another map, which contains the actual rule set data and an order value
|
||||
// return false if the current LLSD is an older format, return true when finish importing the data.
|
||||
bool OmnifilterEngine::importFromLLSD(const LLSD& needle_rule_sets_llsd)
|
||||
{
|
||||
std::string preset_name = "Default";
|
||||
// If there is no default Rule Set return false
|
||||
if (!needle_rule_sets_llsd.has("Default"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Else there is a map named default, does it contain a variable of "order", if not, return false
|
||||
else if (!needle_rule_sets_llsd["Default"].has("order"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
mOrderedRuleSets.clear();
|
||||
// Use the number of rule sets to pre-allocate the ordered rule sets. So can use assignment operators without re-allocating.
|
||||
mOrderedRuleSets.resize(needle_rule_sets_llsd.size());
|
||||
// Loop over the outer Rule Set map
|
||||
S32 rule_set_index = 0;
|
||||
for (const auto&[new_rule_set_name, new_rule_set_llsd] : llsd::inMap(needle_rule_sets_llsd))
|
||||
{
|
||||
|
||||
// If there is an order tag, then
|
||||
if (new_rule_set_llsd.has("order"))
|
||||
{
|
||||
// Add the rule set name to the ordered list at the order position.
|
||||
mOrderedRuleSets[new_rule_set_llsd["order"].asInteger()] = new_rule_set_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Else if there is no order tag, then add add the rule set name to the ordered list in the order read in.
|
||||
// NOTE maps don't store data order added, but optimized order for storage.
|
||||
mOrderedRuleSets[rule_set_index++] = new_rule_set_name;
|
||||
}
|
||||
// Generate a new rule set
|
||||
rule_set_t new_rule_set = rule_set_t(needle_ordered_list_t(), needle_list_t());
|
||||
// Apply the size of the rule set (number of rules) to the ordered rule set set.
|
||||
// First = Ordered Rule Set Vector, Second = Actual Rule Set Map
|
||||
new_rule_set.first.resize(new_rule_set_llsd["rule_set"].size());
|
||||
// Set the current needles_llsd to the actual rule set stored.
|
||||
// keeps old code valid.
|
||||
LLSD needles_llsd = new_rule_set_llsd["rule_set"];
|
||||
S32 index = 0;
|
||||
// Now loop over the rule map stored in the rule set.
|
||||
for (const auto& [new_needle_name, needle_data] : llsd::inMap(needles_llsd))
|
||||
{
|
||||
Needle new_needle;
|
||||
// Perform checks on all input values from the data format and skip any that don't exist.
|
||||
if (needle_data.has("sender_name"))
|
||||
new_needle.mSenderName = needle_data["sender_name"].asString();
|
||||
if (needle_data.has("content"))
|
||||
new_needle.mContent = needle_data["content"].asString();
|
||||
if (needle_data.has("region_name"))
|
||||
new_needle.mRegionName = needle_data["region_name"].asString();
|
||||
if (needle_data.has("chat_replace"))
|
||||
new_needle.mChatReplace = needle_data["chat_replace"].asString();
|
||||
if (needle_data.has("button_reply"))
|
||||
new_needle.mButtonReply = needle_data["button_reply"].asString();
|
||||
if (needle_data.has("textbox_reply"))
|
||||
new_needle.mTextBoxReply = needle_data["textbox_reply"].asString();
|
||||
if (needle_data.has("sender_name_match_type"))
|
||||
new_needle.mSenderNameMatchType = static_cast<OmnifilterEngine::eMatchType>(needle_data["sender_name_match_type"].asInteger());
|
||||
if (needle_data.has("content_match_type"))
|
||||
new_needle.mContentMatchType = static_cast<OmnifilterEngine::eMatchType>(needle_data["content_match_type"].asInteger());
|
||||
|
||||
if (needle_data.has("types"))
|
||||
{
|
||||
LLSD types_llsd = needle_data["types"];
|
||||
|
||||
for (const auto& needle_type : llsd::inArray(types_llsd))
|
||||
{
|
||||
new_needle.mTypes.insert(static_cast<OmnifilterEngine::eType>(needle_type.asInteger()));
|
||||
}
|
||||
}
|
||||
if (needle_data.has("enabled"))
|
||||
new_needle.mEnabled = needle_data["enabled"].asBoolean();
|
||||
if (needle_data.has("sender_name_case_insensitive"))
|
||||
new_needle.mSenderNameCaseInsensitive = needle_data["sender_name_case_insensitive"].asBoolean();
|
||||
if (needle_data.has("content_case_insensitive"))
|
||||
new_needle.mContentCaseInsensitive = needle_data["content_case_insensitive"].asBoolean();
|
||||
|
||||
if (needle_data.has("enabled"))
|
||||
{
|
||||
const std::string owner_id_str = needle_data["owner_id"].asString();
|
||||
if (!owner_id_str.empty())
|
||||
{
|
||||
new_needle.mOwnerID.set(owner_id_str);
|
||||
}
|
||||
}
|
||||
// Assign the actuall new rule set to the parsed needle object
|
||||
new_rule_set.second[new_needle_name] = new_needle;
|
||||
// Add the loaded needle name to the ordered needle list
|
||||
// Needles are stored in order added to the map originally so use the
|
||||
// order value stored to restore the order back to the user
|
||||
// defined order.
|
||||
if (needle_data.has("order"))
|
||||
{
|
||||
new_rule_set.first[needle_data["order"].asInteger()] = new_needle_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
new_rule_set.first[index++] = new_needle_name;
|
||||
}
|
||||
}
|
||||
mNeedleRuleSets[new_rule_set_name] = new_rule_set;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Exports the current stored orered rules sets to an LLSD object and returns the object created.
|
||||
LLSD OmnifilterEngine::exportToLLSD()
|
||||
{
|
||||
LLSD output;
|
||||
// Loop over all the rulesets
|
||||
S32 rule_set_order = 0;
|
||||
// Loop over the ordered rule set names
|
||||
for (const auto& export_rule_set_name : mOrderedRuleSets)
|
||||
{
|
||||
LLSD needles_llsd;
|
||||
// Get the map of needles that have the name of the current ordered rule set
|
||||
const auto& export_rule_set = mNeedleRuleSets[export_rule_set_name];
|
||||
|
||||
// <FS:minerjr> [FIRE-36649] - Add reordering to OmniFilter
|
||||
// Use ordered needle list to get the names of the needles in specified order and not the order added to the map.
|
||||
// for (const auto& [needle_name, needle] : mNeedles)
|
||||
S32 order = 0;
|
||||
for (const auto& needle_name : export_rule_set.first)
|
||||
{
|
||||
const Needle &needle = export_rule_set.second.at(needle_name);
|
||||
// Store the order of the needle
|
||||
needles_llsd[needle_name]["order"] = order++;
|
||||
// </FS:minerjr> [FIRE-36649]
|
||||
needles_llsd[needle_name]["sender_name"] = needle.mSenderName;
|
||||
needles_llsd[needle_name]["content"] = needle.mContent;
|
||||
needles_llsd[needle_name]["region_name"] = needle.mRegionName;
|
||||
needles_llsd[needle_name]["chat_replace"] = needle.mChatReplace;
|
||||
needles_llsd[needle_name]["button_reply"] = needle.mButtonReply;
|
||||
needles_llsd[needle_name]["textbox_reply"] = needle.mTextBoxReply;
|
||||
needles_llsd[needle_name]["sender_name_match_type"] = needle.mSenderNameMatchType;
|
||||
needles_llsd[needle_name]["content_match_type"] = needle.mContentMatchType;
|
||||
needles_llsd[needle_name]["owner_id"] = needle.mOwnerID;
|
||||
|
||||
LLSD types_llsd;
|
||||
for (auto type : needle.mTypes)
|
||||
{
|
||||
types_llsd.append(static_cast<S32>(type));
|
||||
}
|
||||
|
||||
needles_llsd[needle_name]["types"] = types_llsd;
|
||||
needles_llsd[needle_name]["enabled"] = needle.mEnabled;
|
||||
needles_llsd[needle_name]["sender_name_case_insensitive"] = needle.mSenderNameCaseInsensitive;
|
||||
needles_llsd[needle_name]["content_case_insensitive"] = needle.mContentCaseInsensitive;
|
||||
}
|
||||
// Store the rule set into the otuput with the rule set store in the LLSD as well as the rule set order value
|
||||
output[export_rule_set_name]["rule_set"] = needles_llsd;
|
||||
output[export_rule_set_name]["order"] = rule_set_order++;
|
||||
}
|
||||
|
||||
// Return the final LLSD which contains all the Rule Sets
|
||||
return output;
|
||||
}
|
||||
|
||||
// Assignes a rule set to either fron the internal variable to the stored map of rule sets, or
|
||||
// copies the current selected rule set from storage to the internal variables.
|
||||
// This lets us keep all the original design and not require refactoring of code
|
||||
// in other classes that interact with the Omnifilter.
|
||||
bool OmnifilterEngine::assignRuleSet(const bool rule_set_to_internal)
|
||||
{
|
||||
// If there is no current selected rule set or the rule set name is not in the list of rule sets, return false
|
||||
if (mCurrentSelectedRuleSet.empty() || !mNeedleRuleSets.contains(mCurrentSelectedRuleSet))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If transfering data from the currently selected rule set to the internal variables
|
||||
if (rule_set_to_internal)
|
||||
{
|
||||
// Assign the needle map and vector of ordered neele names from the currently selected rule set.
|
||||
mNeedles = mNeedleRuleSets[mCurrentSelectedRuleSet].second;
|
||||
mOrderedNeedles = mNeedleRuleSets[mCurrentSelectedRuleSet].first;
|
||||
}
|
||||
// Else, want to move the data back the from the internal variables to selected data values
|
||||
else
|
||||
{
|
||||
mNeedleRuleSets[mCurrentSelectedRuleSet].second = mNeedles;
|
||||
mNeedleRuleSets[mCurrentSelectedRuleSet].first = mOrderedNeedles;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Assigns the current selected rule set string to the value passed in
|
||||
bool OmnifilterEngine::setCurrentRuleSet(std::string_view rule_set_name)
|
||||
{
|
||||
// If blank, return false as we should not have a blank name.
|
||||
if (rule_set_name.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// Store the pass in rule set name.
|
||||
mCurrentSelectedRuleSet = rule_set_name;
|
||||
|
||||
// Apply the rule set to the current variables
|
||||
assignRuleSet();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Performs the actual removal of the current rule set.
|
||||
S32 OmnifilterEngine::removeCurrentRuleSet()
|
||||
{
|
||||
// If the current rule set list contains the currently selceted rule set, then erase it.
|
||||
if (mNeedleRuleSets.contains(mCurrentSelectedRuleSet))
|
||||
{
|
||||
S32 current_index = gSavedSettings.getS32("OmnifilterRuleSetID");
|
||||
// If the current index is greater then the
|
||||
if (current_index == 0)
|
||||
{
|
||||
// Return 0 for unable to remove default
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If the index is within range of the needle rule sets, then
|
||||
if (current_index < mNeedleRuleSets.size() && current_index > 0)
|
||||
{
|
||||
// Erase both the the current rule set and the ordered rule set name
|
||||
mNeedleRuleSets.erase(mCurrentSelectedRuleSet);
|
||||
mOrderedRuleSets.erase(mOrderedRuleSets.begin() + current_index);
|
||||
// Reset the selected rule set ID back to 0, let the user pick the one to use next. 0 is also safe as it should never be removed.
|
||||
gSavedSettings.setS32("OmnifilterRuleSetID", 0);
|
||||
// Re-assign the current rule set name and reload the rule set from storage to the rule set
|
||||
assignRuleSetNameFromSettings();
|
||||
assignRuleSet();
|
||||
// Return 1 indicating that the removal worked correctly.
|
||||
return 1;
|
||||
}
|
||||
// Return -1 as the rule set index out of bounds
|
||||
return 0;
|
||||
}
|
||||
// Return -2 for rule set name does not exist
|
||||
return -2;
|
||||
}
|
||||
|
||||
// Add a new rule set based upon the name passed in
|
||||
S32 OmnifilterEngine::addNewRuleSet(std::string_view new_name)
|
||||
{
|
||||
// If the name is blank, return an error code, to then let the user know with a notification
|
||||
if (new_name.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string str_new_name(new_name);
|
||||
// If the name already exists, return an error to let the user know
|
||||
if (mNeedleRuleSets.contains(str_new_name))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We want to clear the current rule set and ordered rules as a new rule set has only a single template rule that is disabled.
|
||||
mNeedles.clear();
|
||||
mOrderedNeedles.clear();
|
||||
// Set the rule set in the map to a new rule set pair.
|
||||
mNeedleRuleSets[str_new_name] = rule_set_t(needle_ordered_list_t(), needle_list_t());
|
||||
// Update the OmnifilterRuleSetID saved setting to store the location of the new rule set.
|
||||
// We want to do this to support auto-selecting the new rule set.
|
||||
gSavedSettings.setS32("OmnifilterRuleSetID", static_cast<S32>(mNeedleRuleSets.size() - 1));
|
||||
// Set the current selcted rule set to the new rule set
|
||||
mCurrentSelectedRuleSet = str_new_name;
|
||||
// Add the rule set name to the list of ordered rule sets
|
||||
mOrderedRuleSets.push_back(mCurrentSelectedRuleSet);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Clone the current rule set based upon the name passed in
|
||||
S32 OmnifilterEngine::addClonedRuleSet(std::string_view new_name)
|
||||
{
|
||||
// If the name is blank, return an error code, to then let the user know with a notification
|
||||
if (new_name.empty())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string str_new_name(new_name);
|
||||
|
||||
// If the name already exists, return an error to let the user know
|
||||
if (mNeedleRuleSets.contains(str_new_name))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This method is different in the new rule set method by not clearing the current rules and ordered rules.
|
||||
|
||||
// Set the rule set in the map to a new rule set pair.
|
||||
mNeedleRuleSets[str_new_name] = rule_set_t(needle_ordered_list_t(), needle_list_t());
|
||||
// Update the OmnifilterRuleSetID saved setting to store the location of the new rule set.
|
||||
// We want to do this to support auto-selecting the new rule set.
|
||||
gSavedSettings.setS32("OmnifilterRuleSetID", static_cast<S32>(mNeedleRuleSets.size() - 1));
|
||||
// Set the current selcted rule set to the new rule set
|
||||
mCurrentSelectedRuleSet = str_new_name;
|
||||
// Add the rule set name to the list of ordered rule sets
|
||||
mOrderedRuleSets.push_back(mCurrentSelectedRuleSet);
|
||||
|
||||
// Copy the internal rule set to the stored rulset
|
||||
assignRuleSet(false);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Takes the stored setting OmnifilterRuleSetID and assigns the current
|
||||
// selected rule set to the ordered rule set at that location.
|
||||
bool OmnifilterEngine::assignRuleSetNameFromSettings()
|
||||
{
|
||||
// Get hte number of items to loop over
|
||||
S32 rule_set_id = gSavedSettings.getS32("OmnifilterRuleSetID");
|
||||
std::string found_rule_set(getOrderedRuleSetName(rule_set_id));
|
||||
|
||||
if (found_rule_set.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mCurrentSelectedRuleSet = found_rule_set;
|
||||
|
||||
return true;
|
||||
}
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
|
||||
void OmnifilterEngine::loadNeedles()
|
||||
{
|
||||
if (mNeedlesXMLPath.empty())
|
||||
@@ -391,6 +753,28 @@ void OmnifilterEngine::loadNeedles()
|
||||
return;
|
||||
}
|
||||
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
static LLCachedControl<S32> NeedlePresetIndex(gSavedSettings, "OmnifilterRuleSetID");
|
||||
|
||||
// If this is not the first time loading, based upon the preset index being set
|
||||
// to an invalid valid, after this there should always be atleast 1 rule set (default)
|
||||
if (NeedlePresetIndex > -1)
|
||||
{
|
||||
mNeedleRuleSets.clear();
|
||||
// If the importing works out correctly, then use the reloaded rulset set name from the settings and assign that rule set.
|
||||
if (importFromLLSD(needles_llsd))
|
||||
{
|
||||
assignRuleSetNameFromSettings();
|
||||
// Assign the rule set
|
||||
assignRuleSet();
|
||||
// Return as we can skip the rest of the old loading.
|
||||
return;
|
||||
}
|
||||
// Otherwise, the import failed as it may be an existing older rule set that has a vector of ordered rules.
|
||||
// If so, we still want to use the older load code to parse the older form and convert to the newer format.
|
||||
}
|
||||
// Load the file with the old code to get the old .xml file data loaded, to then be outputted in the new format
|
||||
// <F/S:minerjr> [FIRE-36763]
|
||||
// <FS:minerjr> [FIRE-36649] - Add reordering to OmniFilter
|
||||
// Clear the vector of filters
|
||||
mOrderedNeedles.clear();
|
||||
@@ -444,6 +828,19 @@ void OmnifilterEngine::loadNeedles()
|
||||
}
|
||||
// <FS:minerjr> [/FIRE-36649]
|
||||
}
|
||||
// <FS:minerjr> [FIRE-36649] - Add reordering to OmniFilter
|
||||
// Create a default from the current version
|
||||
gSavedSettings.setS32("OmnifilterRuleSetID", 0);
|
||||
// The first rule set is always called Default.
|
||||
mCurrentSelectedRuleSet = "Default";
|
||||
// Create a new rule set with the already parsed ordered ruules and map of rules.
|
||||
mNeedleRuleSets["Default"] = rule_set_t(mOrderedNeedles, mNeedles);
|
||||
mOrderedRuleSets.push_back(mCurrentSelectedRuleSet);
|
||||
// Save the ruleset to the storage rule set.
|
||||
assignRuleSet(false);
|
||||
// Save the changes back to the Omnifilter.xml file.
|
||||
saveNeedles();
|
||||
// </FS:minerjr> [FIRE-36649]
|
||||
}
|
||||
|
||||
void OmnifilterEngine::saveNeedles()
|
||||
@@ -469,6 +866,12 @@ void OmnifilterEngine::saveNeedles()
|
||||
|
||||
LLSD needles_llsd;
|
||||
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
// First assign the current rule set back to the currently selected rule set.
|
||||
assignRuleSet(false);
|
||||
// Export the needles to LLSD storage
|
||||
needles_llsd = exportToLLSD();
|
||||
/*
|
||||
// <FS:minerjr> [FIRE-36649] - Add reordering to OmniFilter
|
||||
// Use ordered needle list to get the names of the needles in specified order and not the order added to the map.
|
||||
//for (const auto& [needle_name, needle] : mNeedles)
|
||||
@@ -500,6 +903,8 @@ void OmnifilterEngine::saveNeedles()
|
||||
needles_llsd[needle_name]["sender_name_case_insensitive"] = needle.mSenderNameCaseInsensitive;
|
||||
needles_llsd[needle_name]["content_case_insensitive"] = needle.mContentCaseInsensitive;
|
||||
}
|
||||
*/
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
|
||||
LLSDSerialize::toXML(needles_llsd, file);
|
||||
|
||||
|
||||
@@ -125,21 +125,48 @@ class OmnifilterEngine
|
||||
|
||||
void init();
|
||||
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
bool setCurrentRuleSet(std::string_view rule_set_name);
|
||||
S32 removeCurrentRuleSet();
|
||||
S32 addNewRuleSet(std::string_view new_name);
|
||||
S32 addClonedRuleSet(std::string_view new_name);
|
||||
bool assignRuleSet(const bool rule_set_to_internal = true);
|
||||
bool assignRuleSetNameFromSettings();
|
||||
std::string getCurrentSelectedRuleSet() { return mCurrentSelectedRuleSet; }
|
||||
needle_ordered_list_t& getOrderedRuleSets() { return mOrderedRuleSets; }
|
||||
std::string_view getOrderedRuleSetName(const S32 index) const;
|
||||
S32 getOrderedRuleSetIndex(std::string_view lookup_name);
|
||||
S32 getOrderedRuleSetSize() { return static_cast<S32>(mOrderedRuleSets.size()); }
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
typedef boost::signals2::signal<void(time_t, const std::string&)> log_signal_t;
|
||||
log_signal_t mLogSignal;
|
||||
|
||||
std::vector<std::pair<time_t, std::string>> mLog;
|
||||
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
typedef std::pair<needle_ordered_list_t, needle_list_t> rule_set_t;
|
||||
typedef std::map<std::string, rule_set_t> rule_sets_t;
|
||||
rule_sets_t& getRuleSets() { return mNeedleRuleSets; }
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
protected:
|
||||
const Needle* logMatch(const std::string& needle_name, const Needle& needle);
|
||||
bool matchStrings(std::string_view needle_string, std::string_view haystack_string, eMatchType match_type, bool case_insensitive);
|
||||
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
bool importFromLLSD(const LLSD& data);
|
||||
LLSD exportToLLSD();
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
void loadNeedles();
|
||||
void saveNeedles();
|
||||
|
||||
bool tick() override;
|
||||
|
||||
protected:
|
||||
// <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter
|
||||
rule_sets_t mNeedleRuleSets;
|
||||
std::string mCurrentSelectedRuleSet;
|
||||
needle_ordered_list_t mOrderedRuleSets;
|
||||
// </FS:minerjr> [FIRE-36763]
|
||||
needle_list_t mNeedles;
|
||||
// <FS:minerjr> [FIRE-36649] - Add reordering to OmniFilter
|
||||
needle_ordered_list_t mOrderedNeedles;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
can_resize="true"
|
||||
can_minimize="true"
|
||||
can_close="true"
|
||||
height="400"
|
||||
height="425"
|
||||
min_height="348"
|
||||
min_width="668"
|
||||
layout="topleft"
|
||||
@@ -20,12 +20,71 @@
|
||||
NEW RULE
|
||||
</floater.string>
|
||||
|
||||
<!-- <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter --> <!-- <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter -->
|
||||
<panel
|
||||
name="needle_rule_set_controls"
|
||||
layout="topleft"
|
||||
follows="left|top|right"
|
||||
height="25"
|
||||
left="0"
|
||||
min_height="25"
|
||||
top="20"
|
||||
user_resize="false">
|
||||
<text
|
||||
name="lbl_ruleset"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
height="20"
|
||||
width="70"
|
||||
left="8"
|
||||
top="0"
|
||||
valign="center"
|
||||
value="Rule Sets:"/>
|
||||
<combo_box
|
||||
height="20"
|
||||
layout="topleft"
|
||||
left_pad="4"
|
||||
follows="left|top"
|
||||
name="cmb_rule_sets"
|
||||
tool_tip="Choose the Omnifilter Rule Set to use."
|
||||
width="150">
|
||||
</combo_box>
|
||||
<button
|
||||
name="btn_rule_set_new"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
width="150"
|
||||
height="20"
|
||||
left_pad="4"
|
||||
label="New Rule Set"
|
||||
tool_tip="Create a new blank Omnifilter Rule Set."/>
|
||||
<button
|
||||
name="btn_rule_set_clone"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
width= "150"
|
||||
height="20"
|
||||
left_pad="4"
|
||||
label="Clone Rule Set"
|
||||
tool_tip="Create a clone of the current Omnifilter Rule Set."/>
|
||||
<button
|
||||
name="btn_rule_set_remove"
|
||||
layout="topleft"
|
||||
follows="left|top"
|
||||
width= "150"
|
||||
height="20"
|
||||
left_pad="4"
|
||||
label="Remove Rule Set"
|
||||
tool_tip="Remove
|
||||
the current Omnifilter Rule Set."/>
|
||||
</panel>
|
||||
<!-- </FS:minerjr> [FIRE-36763] -->
|
||||
<layout_stack
|
||||
name="needle_list_stack"
|
||||
layout="topleft"
|
||||
follows="left|top|bottom"
|
||||
height="374"
|
||||
top="20"
|
||||
top="45"
|
||||
left="8"
|
||||
width="190"
|
||||
orientation="vertical"
|
||||
|
||||
@@ -15150,4 +15150,155 @@ You can enable saving transcripts under Preferences > Privacy > Logs &
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
<!-- </FS:TJ>-->
|
||||
<!-- <FS:minerjr> [FIRE-36763] - Add rule sets to Omnifilter -->
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
label="New Rule Set"
|
||||
name="OmniFilterNewRuleSet"
|
||||
type="alertmodal">
|
||||
Enter a name for the New Rule Set:
|
||||
<tag>confirm</tag>
|
||||
<form name="form">
|
||||
<input name="new_name" type="text" width="300" default="true">
|
||||
[RULESETNAME]
|
||||
</input>
|
||||
<button
|
||||
default="true"
|
||||
index="0"
|
||||
name="OK"
|
||||
text="OK"/>
|
||||
<button
|
||||
index="1"
|
||||
name="Cancel"
|
||||
text="Cancel"/>
|
||||
</form>
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="OmniFilterrNewRuleSetBlank"
|
||||
sound="UISndAlert"
|
||||
persist="true"
|
||||
type="alertmodal">
|
||||
Blank names are not allowed. Please try again with a name.
|
||||
<usetemplate
|
||||
ignoretext="Warn me again when trying to add a New Rule Set with no name."
|
||||
name="okignore"
|
||||
yestext="OK"/>
|
||||
<tag>voice</tag>
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="OmniFilterNewRuleSetDuplicate"
|
||||
sound="UISndAlert"
|
||||
persist="true"
|
||||
type="alertmodal">
|
||||
Duplicate names are not allowed. Please try again with a different name.
|
||||
<usetemplate
|
||||
ignoretext="Warn me again when trying to add a New Rule Set with a duplicate name."
|
||||
name="okignore"
|
||||
yestext="OK"/>
|
||||
<tag>voice</tag>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
label="Clone Rule Set"
|
||||
name="OmniFilterCloneRuleSet"
|
||||
type="alertmodal">
|
||||
Enter a name to the Cloned Rule Set:
|
||||
<tag>confirm</tag>
|
||||
<form name="form">
|
||||
<input name="new_name" type="text" width="300" default="true">
|
||||
[RULESETNAME]
|
||||
</input>
|
||||
<button
|
||||
default="true"
|
||||
index="0"
|
||||
name="OK"
|
||||
text="OK"/>
|
||||
<button
|
||||
index="1"
|
||||
name="Cancel"
|
||||
text="Cancel"/>
|
||||
</form>
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="OmniFilterCloneRuleSetBlank"
|
||||
sound="UISndAlert"
|
||||
persist="true"
|
||||
type="alertmodal">
|
||||
Blank names are not allowed. Please try again with a name.
|
||||
<usetemplate
|
||||
ignoretext="Warn me again when trying to add a Cloned Rule Set with no name."
|
||||
name="okignore"
|
||||
yestext="OK"/>
|
||||
<tag>voice</tag>
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="OmniFilterCloneRuleSetDuplicate"
|
||||
sound="UISndAlert"
|
||||
persist="true"
|
||||
type="alertmodal">
|
||||
Duplicate names are not allowed. Please try again with a different name.
|
||||
<usetemplate
|
||||
ignoretext="Warn me again when trying to add a Cloned Rule Set with a duplicate name."
|
||||
name="okignore"
|
||||
yestext="OK"/>
|
||||
<tag>voice</tag>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="OmniFilterRemoveRuleSet"
|
||||
type="alertmodal">
|
||||
Are you sure you want to remove [RULESETNAME]?
|
||||
<tag>confirm</tag>
|
||||
<usetemplate
|
||||
ignoretext="Confirm before I remove a Rule Set."
|
||||
name="okcancelignore"
|
||||
notext="Cancel"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="OmniFilterRemoveRuleSetDefault"
|
||||
sound="UISndAlert"
|
||||
persist="true"
|
||||
type="alertmodal">
|
||||
Unable to remove the Default Rule Set.
|
||||
<usetemplate
|
||||
ignoretext="Warn me again when trying to remove the Default Rule Set."
|
||||
name="okignore"
|
||||
yestext="OK"/>
|
||||
<tag>voice</tag>
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="OmniFilterRemoveRuleSetOutofBounds"
|
||||
sound="UISndAlert"
|
||||
persist="true"
|
||||
type="alertmodal">
|
||||
Unable to remove the Rule Set due to index out of bounds.
|
||||
<usetemplate
|
||||
ignoretext="Warn me again when trying to remove a Rule Set with an index [OUTOFBOUNDS] out of bounds."
|
||||
name="okignore"
|
||||
yestext="OK"/>
|
||||
<tag>voice</tag>
|
||||
</notification>
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="OmniFilterRemoveRuleSetInvalidName"
|
||||
sound="UISndAlert"
|
||||
persist="true"
|
||||
type="alertmodal">
|
||||
Unable to remove the Rule Set due to name not found.
|
||||
<usetemplate
|
||||
ignoretext="Warn me again when trying to remove a Rule Set with an invalid name '[INVALIDNAME]'."
|
||||
name="okignore"
|
||||
yestext="OK"/>
|
||||
<tag>voice</tag>
|
||||
</notification>
|
||||
<!-- </FS:minerjr> [FIRE-36763] -->
|
||||
</notifications>
|
||||
|
||||
Reference in New Issue
Block a user