Improvements to omnifilter

master
Ansariel 2025-12-11 14:59:52 +01:00
parent 5179d987e1
commit c6cdaf705d
13 changed files with 723 additions and 313 deletions

View File

@ -723,6 +723,9 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
*/
// <FS:Zi> Omnifilter support
static LLCachedControl<bool> use_omnifilter(gSavedSettings, "OmnifilterEnabled");
if (use_omnifilter)
{
OmnifilterEngine::Haystack haystack;
haystack.mContent = message;
haystack.mSenderName = agentName;
@ -814,6 +817,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
message = needle->mChatReplace;
}
}
// </FS:Zi>
std::string notice_name;

View File

@ -475,6 +475,9 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
LLUUID object_id = notification_id_to_object_id(notification_id);
// <FS:Zi> Omnifilter support
static LLCachedControl<bool> use_omnifilter(gSavedSettings, "OmnifilterEnabled");
if (use_omnifilter)
{
LLNotificationPtr notification = LLNotifications::instance().find(notification_id);
OmnifilterEngine::Haystack haystack;
@ -540,6 +543,7 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
notification->respond(response);
return;
}
}
// </FS:Zi>
// Need to indicate of "new message" for object chiclets according to requirements

View File

@ -3253,6 +3253,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
}
// <FS:Zi> Omnifilter support
static LLCachedControl<bool> use_omnifilter(gSavedSettings, "OmnifilterEnabled");
if (use_omnifilter)
{
OmnifilterEngine::Haystack haystack;
haystack.mContent = chat.mText;
haystack.mSenderName = from_name; // we don't use chat.mFromName here because that will include display names etc.
@ -3313,6 +3316,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
break;
}
}
}
// </FS:Zi>
// We have a real utterance now, so can stop showing "..." and proceed.

View File

@ -29,7 +29,6 @@
#include "llcombobox.h"
#include "lllineeditor.h"
#include "lltexteditor.h"
#include "lltrans.h"
#include "fsscrolllistctrl.h"
@ -44,10 +43,6 @@ Omnifilter::Omnifilter(const LLSD& key) :
{
}
Omnifilter::~Omnifilter()
{
}
LLScrollListItem* Omnifilter::addNeedle(const std::string& needle_name, const OmnifilterEngine::Needle& needle)
{
LLSD row;
@ -194,7 +189,7 @@ void Omnifilter::onNeedleChanged()
void Omnifilter::onAddNeedleClicked()
{
std::string new_needle_string = LLTrans::getString("OmnifilterNewNeedle");
std::string new_needle_string = getString("OmnifilterNewNeedle");
if (!mNeedleListCtrl->selectItemByLabel(new_needle_string, true, NEEDLE_NAME_COLUMN))
{
OmnifilterEngine::Needle& new_needle = OmnifilterEngine::getInstance()->newNeedle(new_needle_string);
@ -336,19 +331,18 @@ bool Omnifilter::postBuild()
mFilterLogCtrl->deleteAllItems();
for (auto const& needle_entry : OmnifilterEngine::getInstance()->getNeedleList())
auto& instance = OmnifilterEngine::instance();
for (const auto& [needle_name, needle] : instance.getNeedleList())
{
const std::string& needle_name = needle_entry.first;
const OmnifilterEngine::Needle& needle = needle_entry.second;
addNeedle(needle_name, needle);
}
for (auto logLine : OmnifilterEngine::getInstance()->mLog)
for (const auto& [log_time, log_message] : instance.mLog)
{
onLogLine(logLine.first, logLine.second);
onLogLine(log_time, log_message);
}
OmnifilterEngine::getInstance()->mLogSignal.connect(boost::bind(&Omnifilter::onLogLine, this, _1, _2));
instance.mLogSignal.connect(boost::bind(&Omnifilter::onLogLine, this, _1, _2));
if (mNeedleListCtrl->getItemCount())
{

View File

@ -44,7 +44,6 @@ class Omnifilter
private:
Omnifilter(const LLSD& key);
~Omnifilter();
public:
bool postBuild() override final;
@ -62,38 +61,38 @@ class Omnifilter
void onLogLine(time_t time, const std::string& logLine);
FSScrollListCtrl* mNeedleListCtrl;
LLButton* mAddNeedleBtn;
LLButton* mRemoveNeedleBtn;
FSScrollListCtrl* mFilterLogCtrl;
LLPanel* mPanelDetails;
LLLineEditor* mNeedleNameCtrl;
LLLineEditor* mSenderNameCtrl;
LLCheckBoxCtrl* mSenderCaseSensitiveCheck;
LLComboBox* mSenderMatchTypeCombo;
LLTextEditor* mContentCtrl;
LLCheckBoxCtrl* mContentCaseSensitiveCheck;
LLComboBox* mContentMatchTypeCombo;
LLLineEditor* mRegionNameCtrl;
LLLineEditor* mOwnerCtrl;
FSScrollListCtrl* mNeedleListCtrl{ nullptr };
LLButton* mAddNeedleBtn{ nullptr };
LLButton* mRemoveNeedleBtn{ nullptr };
FSScrollListCtrl* mFilterLogCtrl{ nullptr };
LLPanel* mPanelDetails{ nullptr };
LLLineEditor* mNeedleNameCtrl{ nullptr };
LLLineEditor* mSenderNameCtrl{ nullptr };
LLCheckBoxCtrl* mSenderCaseSensitiveCheck{ nullptr };
LLComboBox* mSenderMatchTypeCombo{ nullptr };
LLTextEditor* mContentCtrl{ nullptr };
LLCheckBoxCtrl* mContentCaseSensitiveCheck{ nullptr };
LLComboBox* mContentMatchTypeCombo{ nullptr };
LLLineEditor* mRegionNameCtrl{ nullptr };
LLLineEditor* mOwnerCtrl{ nullptr };
LLButton* mTypeNearbyBtn;
LLButton* mTypeIMBtn;
LLButton* mTypeGroupIMBtn;
LLButton* mTypeObjectChatBtn;
LLButton* mTypeObjectIMBtn;
LLButton* mTypeScriptErrorBtn;
LLButton* mTypeDialogBtn;
LLButton* mTypeOfferBtn;
LLButton* mTypeInviteBtn;
LLButton* mTypeLureBtn;
LLButton* mTypeLoadURLBtn;
LLButton* mTypeFriendshipOfferBtn;
LLButton* mTypeTeleportRequestBtn;
LLButton* mTypeGroupNoticeBtn;
LLButton* mTypeNearbyBtn{ nullptr };
LLButton* mTypeIMBtn{ nullptr };
LLButton* mTypeGroupIMBtn{ nullptr };
LLButton* mTypeObjectChatBtn{ nullptr };
LLButton* mTypeObjectIMBtn{ nullptr };
LLButton* mTypeScriptErrorBtn{ nullptr };
LLButton* mTypeDialogBtn{ nullptr };
LLButton* mTypeOfferBtn{ nullptr };
LLButton* mTypeInviteBtn{ nullptr };
LLButton* mTypeLureBtn{ nullptr };
LLButton* mTypeLoadURLBtn{ nullptr };
LLButton* mTypeFriendshipOfferBtn{ nullptr };
LLButton* mTypeTeleportRequestBtn{ nullptr };
LLButton* mTypeGroupNoticeBtn{ nullptr };
LLLineEditor* mChatReplaceCtrl;
LLLineEditor* mButtonReplyCtrl;
LLTextEditor* mTextBoxReplyCtrl;
LLLineEditor* mChatReplaceCtrl{ nullptr };
LLLineEditor* mButtonReplyCtrl{ nullptr };
LLTextEditor* mTextBoxReplyCtrl{ nullptr };
};
#endif // OMNIFILTER_H

View File

@ -28,6 +28,7 @@
#include "llnotificationsutil.h"
#include "llsdserialize.h"
#include "llviewercontrol.h"
#include <fstream>
#include <filesystem>
@ -59,15 +60,15 @@ void OmnifilterEngine::init()
const OmnifilterEngine::Needle* OmnifilterEngine::logMatch(const std::string& needle_name, const Needle& needle)
{
time_t now = (time_t)LLDate::now().secondsSinceEpoch();
mLog.push_back(std::make_pair(now, needle_name));
mLog.emplace_back(now, needle_name);
mLogSignal(now, needle_name);
return &needle;
}
bool OmnifilterEngine::matchStrings(const std::string& needle_string, const std::string& haystack_string, eMatchType match_type, bool case_insensitive)
bool OmnifilterEngine::matchStrings(std::string_view needle_string, std::string_view haystack_string, eMatchType match_type, bool case_insensitive)
{
static LLCachedControl<bool> use_omnifilter(*LLControlGroup::getInstance("Global"), "OmnifilterEnabled");
static LLCachedControl<bool> use_omnifilter(gSavedSettings, "OmnifilterEnabled");
if (!use_omnifilter)
{
return false;
@ -98,8 +99,8 @@ bool OmnifilterEngine::matchStrings(const std::string& needle_string, const std:
{
re_flags |= boost::regex::icase;
}
boost::regex re(needle_string, re_flags);
if (boost::regex_match(haystack_string, re))
boost::regex re(std::string(needle_string), re_flags);
if (boost::regex_match(std::string(haystack_string), re))
{
return true;
}
@ -132,11 +133,8 @@ bool OmnifilterEngine::matchStrings(const std::string& needle_string, const std:
const OmnifilterEngine::Needle* OmnifilterEngine::match(const Haystack& haystack)
{
for (auto const& needle_entry : mNeedles)
for (const auto& [needle_name, needle]: mNeedles)
{
const Needle& needle = needle_entry.second;
const std::string& needle_name = needle_entry.first;
if (!needle.mEnabled)
{
continue;
@ -166,7 +164,7 @@ const OmnifilterEngine::Needle* OmnifilterEngine::match(const Haystack& haystack
}
}
if (!needle.mTypes.empty() && needle.mTypes.find(haystack.mType) == needle.mTypes.end())
if (!needle.mTypes.empty() && !needle.mTypes.contains(haystack.mType))
{
continue;
}
@ -182,7 +180,7 @@ const OmnifilterEngine::Needle* OmnifilterEngine::match(const Haystack& haystack
OmnifilterEngine::Needle& OmnifilterEngine::newNeedle(const std::string& needle_name)
{
if (mNeedles.find(needle_name) != mNeedles.end())
if (mNeedles.contains(needle_name))
{
Needle new_needle;
new_needle.mEnabled = false;
@ -263,8 +261,7 @@ void OmnifilterEngine::loadNeedles()
LL_DEBUGS("Omnifilter") << "Loading needles" << mNeedlesXMLPath << LL_ENDL;
std::ifstream file;
file.open(mNeedlesXMLPath.c_str());
llifstream file(mNeedlesXMLPath.c_str());
if (file.fail())
{
LL_DEBUGS("Omnifilter") << "Unable to open Omnifilter storage at '" << mNeedlesXMLPath << "' for reading." << LL_ENDL;
@ -294,11 +291,8 @@ void OmnifilterEngine::loadNeedles()
return;
}
for (LLSD::map_iterator iter = needles_llsd.beginMap(); iter != needles_llsd.endMap(); ++iter)
for (const auto& [new_needle_name, needle_data] : llsd::inMap(needles_llsd))
{
const std::string& new_needle_name = (*iter).first;
LLSD needle_data = (*iter).second;
Needle new_needle;
new_needle.mSenderName = needle_data["sender_name"].asString();
new_needle.mContent = needle_data["content"].asString();
@ -311,9 +305,9 @@ void OmnifilterEngine::loadNeedles()
LLSD types_llsd = needle_data["types"];
for (LLSD::array_iterator aiter = types_llsd.beginArray(); aiter != types_llsd.endArray(); ++aiter)
for (const auto& needle_type : llsd::inArray(types_llsd))
{
new_needle.mTypes.insert(static_cast<OmnifilterEngine::eType>((*aiter).asInteger()));
new_needle.mTypes.insert(static_cast<OmnifilterEngine::eType>(needle_type.asInteger()));
}
new_needle.mEnabled = needle_data["enabled"].asBoolean();
@ -333,9 +327,7 @@ void OmnifilterEngine::saveNeedles()
LL_DEBUGS("Omnifilter") << "Saving needles" << mNeedlesXMLPath << LL_ENDL;
std::ofstream file;
file.open(mNeedlesXMLPath.c_str());
llofstream file(mNeedlesXMLPath.c_str());
if (file.fail())
{
LL_DEBUGS("Omnifilter") << "Unable to open Omnifilter storage at '" << mNeedlesXMLPath << "' for writing." << LL_ENDL;
@ -349,11 +341,8 @@ void OmnifilterEngine::saveNeedles()
LLSD needles_llsd;
for (auto const& needle_entry : mNeedles)
for (const auto& [needle_name, needle] : mNeedles)
{
const std::string& needle_name = needle_entry.first;
const Needle& needle = needle_entry.second;
needles_llsd[needle_name]["sender_name"] = needle.mSenderName;
needles_llsd[needle_name]["content"] = needle.mContent;
needles_llsd[needle_name]["region_name"] = needle.mRegionName;

View File

@ -101,7 +101,7 @@ class OmnifilterEngine
bool mContentCaseInsensitive = false;
};
typedef std::map<std::string, OmnifilterEngine::OmnifilterEngine::Needle> needle_list_t;
typedef std::map<std::string, OmnifilterEngine::OmnifilterEngine::Needle, std::less<>> needle_list_t;
needle_list_t& getNeedleList();
Needle& newNeedle(const std::string& needle_name);
@ -116,11 +116,11 @@ class OmnifilterEngine
typedef boost::signals2::signal<void(time_t, const std::string&)> log_signal_t;
log_signal_t mLogSignal;
std::list<std::pair<time_t, std::string>> mLog;
std::vector<std::pair<time_t, std::string>> mLog;
protected:
const Needle* logMatch(const std::string& needle_name, const Needle& needle);
bool matchStrings(const std::string& needle_string, const std::string& haystack_string, eMatchType match_type, bool case_insensitive);
bool matchStrings(std::string_view needle_string, std::string_view haystack_string, eMatchType match_type, bool case_insensitive);
void loadNeedles();
void saveNeedles();

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="omnifilter" title="Omni-Filter Regel-Editor">
<floater.string name="OmnifilterNewNeedle">
NEUE REGEL
</floater.string>
<layout_stack name="needle_list_stack">
<layout_panel name="needle_list_layout">
<check_box name="enable_omnifilter" label="Omnifilter aktivieren"/>

View File

@ -7327,7 +7327,4 @@ Ihre aktuelle Position: [AVATAR_POS]
<string name="Maximum">
Maximum
</string>
<string name="OmnifilterNewNeedle">
NEUE REGEL
</string>
</strings>

View File

@ -16,153 +16,571 @@
reuse_instance="true"
title="Omnifilter Rules Editor"
width="700">
<floater.string name="OmnifilterNewNeedle">
NEW RULE
</floater.string>
<layout_stack name="needle_list_stack" layout="topleft" follows="left|top|bottom" height="374" top="20" left="8" width="190" orientation="vertical" show_drag_handle="true">
<layout_panel name="needle_list_layout" layout="topleft" height="150" min_height="94" user_resize="true">
<check_box name="enable_omnifilter" layout="topleft" follows="left|top" height="20" top="0" right="-1" label="Enable Omnifilter" control_name="OmnifilterEnabled" />
<fs_scroll_list name="needle_list" layout="topleft" follows="all" height="100" top_pad="4" draw_heading="true" draw_stripes="true" desired_line_height="18">
<fs_scroll_list.columns name="enabled" label="On" width="24" />
<fs_scroll_list.columns name="needle_name" label="Rule" width="175" />
<layout_stack
name="needle_list_stack"
layout="topleft"
follows="left|top|bottom"
height="374"
top="20"
left="8"
width="190"
orientation="vertical"
show_drag_handle="true">
<layout_panel
name="needle_list_layout"
layout="topleft"
height="150"
min_height="94"
user_resize="true">
<check_box
name="enable_omnifilter"
layout="topleft"
follows="left|top"
height="20"
top="0"
right="-1"
label="Enable Omnifilter"
control_name="OmnifilterEnabled"/>
<fs_scroll_list
name="needle_list"
layout="topleft"
follows="all"
height="100"
top_pad="4"
draw_heading="true"
draw_stripes="true"
desired_line_height="18">
<fs_scroll_list.columns
name="enabled"
label="On"
width="24"/>
<fs_scroll_list.columns
name="needle_name"
label="Rule"
width="175"/>
<!-- example entries for UI editing -->
<row>
<column name="enabled" column="enabled" type="checkbox" value="true" />
<column name="needle_name" column="needle_name">Example Rule 1</column>
<column
name="enabled"
column="enabled"
type="checkbox"
value="true"/>
<column
name="needle_name"
column="needle_name">
Example Rule 1
</column>
</row>
<row>
<column name="enabled" column="enabled" type="checkbox" />
<column name="needle_name" column="needle_name">Example Rule 2</column>
<column
name="enabled"
column="enabled"
type="checkbox"/>
<column
name="needle_name"
column="needle_name">
Example Rule 2
</column>
</row>
</fs_scroll_list>
<button name="add_needle" layout="topleft" follows="left|bottom" height="20" top_pad="4" width="96" label="Add" />
<button name="remove_needle" layout="topleft" follows="right|bottom" height="20" left_pad="0" width="96" label="Remove" />
<button
name="add_needle"
layout="topleft"
follows="left|bottom"
height="20"
top_pad="4"
width="96"
label="Add"/>
<button
name="remove_needle"
layout="topleft"
follows="right|bottom"
height="20"
left_pad="0"
width="96"
label="Remove"/>
</layout_panel>
<layout_panel name="filter_log_layout" layout="topleft" height="130" min_height="50">
<fs_scroll_list name="filter_log" layout="topleft" follows="all" height="150" top="0" draw_heading="true" draw_stripes="true" can_sort="false">
<fs_scroll_list.columns name="timestamp" label="Time (SLT)" width="64" />
<fs_scroll_list.columns name="log_entry" label="Rule" />
<layout_panel
name="filter_log_layout"
layout="topleft"
height="130"
min_height="50">
<fs_scroll_list
name="filter_log"
layout="topleft"
follows="all"
height="150"
top="0"
draw_heading="true"
draw_stripes="true"
can_sort="false">
<fs_scroll_list.columns
name="timestamp"
label="Time (SLT)"
width="64"/>
<fs_scroll_list.columns
name="log_entry"
label="Rule"/>
<!-- example entries for UI editing -->
<row>
<column name="timestamp" column="timestamp" tool_tip="2015-11-24 00:01:02">00:01:02</column>
<column name="log_entry" column="log_entry">Example Rule 1</column>
<column
name="timestamp"
column="timestamp"
tool_tip="2015-11-24 00:01:02">
00:01:02
</column>
<column
name="log_entry"
column="log_entry">
Example Rule 1
</column>
</row>
<row>
<column name="timestamp" column="timestamp" tool_tip="2015-11-24 01:02:03">01:02:03</column>
<column name="log_entry" column="log_entry">Example Rule 2</column>
<column
name="timestamp"
column="timestamp"
tool_tip="2015-11-24 01:02:03">
01:02:03
</column>
<column
name="log_entry"
column="log_entry">
Example Rule 2
</column>
</row>
</fs_scroll_list>
</layout_panel>
</layout_stack>
<panel name="panel_details" layout="topleft" follows="all" height="374" left_pad="4" right="-4">
<text name="needle_name_label" layout="topleft" follows="left|top" height="20" width="100" left="0" top_pad="0" valign="center" value="Rule Name:" />
<line_editor name="needle_name" layout="topleft" follows="left|right|top" height="20" left_pad="4" right="-4" />
<text name="sender_name_label" layout="topleft" follows="left|top" height="20" width="100" left="0" top_pad="2" valign="center" value="Sender Name:" />
<line_editor name="sender_name" layout="topleft" follows="left|right|top" height="20" left_pad="4" right="-110" />
<check_box name="sender_case" layout="topleft" follows="right|top" height="20" left_pad="4" width="30" label="Aa" />
<combo_box name="sender_match_type" layout="topleft" follows="right|top" height="20" left_pad="8" right="-4" >
<combo_item name="sender_exact" value="0">
<column width="40" name="label" label="|Abc|" />
<column name="longtext" label="Match full text" />
<panel
name="panel_details"
layout="topleft"
follows="all"
height="374"
left_pad="4"
right="-4">
<text
name="needle_name_label"
layout="topleft"
follows="left|top"
height="20"
width="100"
left="0"
top_pad="0"
valign="center"
value="Rule Name:"/>
<line_editor
name="needle_name"
layout="topleft"
follows="left|right|top"
height="20"
left_pad="4"
right="-4"/>
<text
name="sender_name_label"
layout="topleft"
follows="left|top"
height="20"
width="100"
left="0"
top_pad="2"
valign="center"
value="Sender Name:"/>
<line_editor
name="sender_name"
layout="topleft"
follows="left|right|top"
height="20"
left_pad="4"
right="-110"/>
<check_box
name="sender_case"
layout="topleft"
follows="right|top"
height="20"
left_pad="4"
width="30"
label="Aa"/>
<combo_box
name="sender_match_type"
layout="topleft"
follows="right|top"
height="20"
left_pad="8"
right="-4">
<combo_item
name="sender_exact"
value="0">
<column
width="40"
name="label"
label="|Abc|"/>
<column
name="longtext"
label="Match full text"/>
</combo_item>
<combo_item name="sender_substring" value="1">
<column name="label" label="*Abc*" />
<column name="longtext" label="Match substring" />
<combo_item
name="sender_substring"
value="1">
<column
name="label"
label="*Abc*"/>
<column
name="longtext"
label="Match substring"/>
</combo_item>
<combo_item name="sender_regex" value="2">
<column name="label" label="/ *. /" />
<column name="longtext" label="Match regular expression" width.width="400" width.pixel_width="300" />
<combo_item
name="sender_regex"
value="2">
<column
name="label"
label="/ *. /"/>
<column
name="longtext"
label="Match regular expression"
width.width="400"
width.pixel_width="300"/>
</combo_item>
</combo_box>
<text
name="content_label"
layout="topleft"
follows="left|top"
height="20"
left="0"
width="100"
top_pad="3"
valign="center"
value="Content:"/>
<text_editor
name="content"
layout="topleft"
follows="all"
height="74"
left_pad="4"
right="-4"
top_delta="0"/>
<check_box
name="content_case"
layout="topleft"
follows="right|bottom"
height="20"
width="30"
right="-76"
top_pad="4"
label="Aa"/>
<combo_box
name="content_match_type"
layout="topleft"
follows="right|bottom"
height="20"
left_pad="8"
right="-4">
<combo_item
name="content_exact"
value="0">
<column
width="40"
name="label"
label="|Abc|"/>
<column
name="longtext"
label="Match full text"/>
</combo_item>
<combo_item
name="content_substring"
value="1">
<column
name="label"
label="*Abc*"/>
<column
name="longtext"
label="Match substring"/>
</combo_item>
<combo_item
name="content_regex"
value="2">
<column
name="label"
label="/ *. /"/>
<column
name="longtext"
label="Match regular expression"/>
</combo_item>
</combo_box>
<text name="content_label" layout="topleft" follows="left|top" height="20" left="0" width="100" top_pad="3" valign="center" value="Content:" />
<text_editor name="content" layout="topleft" follows="all" height="74" left_pad="4" right="-4" top_delta="0" />
<check_box name="content_case" layout="topleft" follows="right|bottom" height="20" width="30" right="-76" top_pad="4" label="Aa" />
<combo_box name="content_match_type" layout="topleft" follows="right|bottom" height="20" left_pad="8" right="-4" >
<combo_item name="content_exact" value="0">
<column width="40" name="label" label="|Abc|" />
<column name="longtext" label="Match full text" />
</combo_item>
<combo_item name="content_substring" value="1">
<column name="label" label="*Abc*" />
<column name="longtext" label="Match substring" />
</combo_item>
<combo_item name="content_regex" value="2">
<column name="label" label="/ *. /" />
<column name="longtext" label="Match regular expression" />
</combo_item>
</combo_box>
<text name="region_name_label" layout="topleft" follows="left|bottom" height="20" width="100" left="0" top_pad="2" valign="center" value="Region Name:" />
<line_editor name="region_name" layout="topleft" follows="left|right|bottom" height="20" left_pad="4" right="-4" />
<text name="owner_label" layout="topleft" follows="left|bottom" height="20" width="100" left="0" top_pad="2" valign="center" value="Owner:" />
<line_editor name="owner_uuid" layout="topleft" follows="left|right|bottom" height="20" left_pad="4" right="-4" />
<text name="match_source_label" layout="topleft" follows="left|bottom" width="100" height="20" top_pad="4" left="0" valign="center" value="Match Source:" />
<layout_stack name="buttons_stack" orientation="horizontal" left="104" top_delta="0" right="-4" height="68" follows="left|right|bottom" layout="topleft">
<layout_panel width="72" layout="topleft" follows="all" name="buttons_group_1">
<button name="type_nearby" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="0" label="Nearby Chat" tool_tip="Regular public avatar chat nearby." />
<button name="type_im" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="IM" tool_tip="Instant messages from users." />
<button name="type_group_im" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Group Chat" tool_tip="Group chat from users." />
<text
name="region_name_label"
layout="topleft"
follows="left|bottom"
height="20"
width="100"
left="0"
top_pad="2"
valign="center"
value="Region Name:"/>
<line_editor
name="region_name"
layout="topleft"
follows="left|right|bottom"
height="20"
left_pad="4"
right="-4"/>
<text
name="owner_label"
layout="topleft"
follows="left|bottom"
height="20"
width="100"
left="0"
top_pad="2"
valign="center"
value="Owner:"/>
<line_editor
name="owner_uuid"
layout="topleft"
follows="left|right|bottom"
height="20"
left_pad="4"
right="-4"/>
<text
name="match_source_label"
layout="topleft"
follows="left|bottom"
width="100"
height="20"
top_pad="4"
left="0"
valign="center"
value="Match Source:"/>
<layout_stack
name="buttons_stack"
orientation="horizontal"
left="104"
top_delta="0"
right="-4"
height="68"
follows="left|right|bottom"
layout="topleft">
<layout_panel
width="72"
layout="topleft"
follows="all"
name="buttons_group_1">
<button
name="type_nearby"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top_pad="0"
label="Local Chat"
tool_tip="Regular public avatar chat nearby."/>
<button
name="type_im"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top_pad="4"
label="IM"
tool_tip="Instant messages from residents."/>
<button
name="type_group_im"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top_pad="4"
label="Group Chat"
tool_tip="Group chat from residents."/>
</layout_panel>
<layout_panel name="buttons_group_2">
<button name="type_group_notice" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top="0" label="Notice" tool_tip="Group notices." />
<button name="type_invite" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Invite" tool_tip="Group invitations." />
<button name="type_object_chat" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Object Chat" tool_tip="Nearby chat from objects." />
<button
name="type_group_notice"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top="0"
label="Notice"
tool_tip="Group notices."/>
<button
name="type_invite"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top_pad="4"
label="Invite"
tool_tip="Group invitations."/>
<button
name="type_object_chat"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top_pad="4"
label="Object Chat"
tool_tip="Nearby chat from objects."/>
</layout_panel>
<layout_panel name="buttons_group_3">
<button name="type_object_im" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top="0" label="Object IM" tool_tip="Instant messages from objects." />
<button name="type_script_error" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Error" tool_tip="Debug chat coming from scripts." />
<button name="type_dialog" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Dialog" tool_tip="Matches fields in script dialogs." />
<button
name="type_object_im"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top="0"
label="Object IM"
tool_tip="Instant messages from objects."/>
<button
name="type_script_error"
layout="topleft"
follows="left|right|top"
width= "72" height="20"
is_toggle="true"
top_pad="4"
label="Error"
tool_tip="Debug chat coming from scripts."/>
<button
name="type_dialog"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top_pad="4"
label="Dialog"
tool_tip="Matches fields in script dialogs."/>
</layout_panel>
<layout_panel name="buttons_group_4">
<button name="type_inventory_offer" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top="0" label="Offer" tool_tip="Matches fields in inventory offers." />
<button name="type_friendship" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Friendship" tool_tip="Friend requests from users." />
<button name="type_lure" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="TP Lure" tool_tip="Teleport offers from users." />
<button
name="type_inventory_offer"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top="0"
label="Offer"
tool_tip="Matches fields in inventory offers."/>
<button
name="type_friendship"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top_pad="4"
label="Friendship"
tool_tip="Friend requests from residents."/>
<button
name="type_lure"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top_pad="4"
label="TP Lure"
tool_tip="Teleport offers from residents."/>
</layout_panel>
<layout_panel name="buttons_group_5">
<button name="type_tp_request" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top="0" label="TP Request" tool_tip="Requests from users to send them a teleport offer." />
<button name="type_load_url" layout="topleft" follows="left|right|top" width= "72" height="20" is_toggle="true" top_pad="4" label="Load URL" tool_tip="Scripted requests to visit a website." />
<button
name="type_tp_request"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top="0"
label="TP Request"
tool_tip="Requests from residents to send them a teleport offer."/>
<button
name="type_load_url"
layout="topleft"
follows="left|right|top"
width= "72"
height="20"
is_toggle="true"
top_pad="4"
label="Load URL"
tool_tip="Scripted requests to visit a website."/>
</layout_panel>
</layout_stack>
<view_border layout="topleft" right="-4" follows="left|bottom|right" left="0" height="1" top_pad="4" />
<text name="chat_replace_label" layout="topleft" follows="left|bottom" left="0" height="20" width="100" top_pad="2" value="Chat Replace:" valign="center" />
<line_editor name="chat_replace" layout="topleft" follows="left|right|bottom" left_pad="4" height="20" right="-4" />
<text name="button_reply_label" layout="topleft" follows="left|bottom" left="0" height="20" width="100" top_pad="2" value="Button Reply:" valign="center" />
<line_editor name="button_reply" layout="topleft" follows="left|right|bottom" left_pad="4" height="20" right="-4" />
<text name="text_box_reply_label" layout="topleft" follows="left|bottom" left="0" height="20" width="100" top_pad="3" value="Text Box Reply:" valign="center" />
<text_editor name="text_box_reply" layout="topleft" follows="left|right|bottom" left_pad="4" height="60" right="-4" top_delta="0" />
<view_border
layout="topleft"
right="-4"
follows="left|bottom|right"
left="0"
height="1"
top_pad="4"/>
<text
name="chat_replace_label"
layout="topleft"
follows="left|bottom"
left="0"
height="20"
width="100"
top_pad="2"
value="Chat Replace:"
valign="center"/>
<line_editor
name="chat_replace"
layout="topleft"
follows="left|right|bottom"
left_pad="4"
height="20"
right="-4"/>
<text
name="button_reply_label"
layout="topleft"
follows="left|bottom"
left="0"
height="20"
width="100"
top_pad="2"
value="Button Reply:"
valign="center"/>
<line_editor
name="button_reply"
layout="topleft"
follows="left|right|bottom"
left_pad="4"
height="20"
right="-4"/>
<text
name="text_box_reply_label"
layout="topleft"
follows="left|bottom"
left="0"
height="20"
width="100"
top_pad="3"
value="Text Box Reply:"
valign="center"/>
<text_editor
name="text_box_reply"
layout="topleft"
follows="left|right|bottom"
left_pad="4"
height="60"
right="-4"
top_delta="0"/>
</panel>
</floater>

View File

@ -3341,6 +3341,4 @@ Your current position: [AVATAR_POS]
<string name="Very High">Very High</string>
<string name="Ultra">Ultra</string>
<string name="Maximum">Maximum</string>
<string name="OmnifilterNewNeedle">NEW RULE</string> <!-- <FS:Zi> Omnifilter -->
</strings>

View File

@ -1,5 +1,8 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="omnifilter" title="Edytor reguł Omnifiltra">
<floater.string name="OmnifilterNewNeedle">
NOWA REGUŁA
</floater.string>
<layout_stack name="needle_list_stack">
<layout_panel name="needle_list_layout">
<check_box name="enable_omnifilter" label="Włącz Wszystkofiltr" />

View File

@ -6700,7 +6700,4 @@ Twoja aktualna pozycja: [AVATAR_POS]
<string name="Maximum">
Maksymalnie
</string>
<string name="OmnifilterNewNeedle">
NOWA REGUŁA
</string>
</strings>