1Record Filters
2##############
3
4Filters are a key element of the OpenMW CS user interface, they allow rapid and
5easy access to records presented in all tables. In order to use this
6application effectively you need to familiarise yourself with all the concepts
7and instructions explained in this chapter. The filter system is somewhat
8unusual at first glance, but once you understand the basics it will be fairly
9intuitive and easy to use
10
11Filters are a key element to using the OpenMW CS efficiently by allowing you to
12narrow down the table entries very quickly and find what you are looking for.
13The filter system might appear unusual at first, you don't just type in a word
14and get all instances where it occurs, instead filters are first-class objects
15in the CS with their own table. This allows you to define very specific filters
16for your project and store them on disc to use in the next session. The CS
17allows you fine-grained control, you can choose whether to make a filter
18persistent between session, only for one session or use a one-off filter by
19typing it directly into the filter field.
20
21
22
23Terms used
24**********
25
26Filter
27   A Filter is generally speaking a tool able to filter the elements of a
28   table, that is select some elements while discarding others, according to
29   some criteria. These criteria are written using their own syntax.
30
31Criterion
32   A criterion describes some condition a record needs to satisfy in order to
33   be selected. They are written using a special syntax which is explained
34   below. We can logically combine multiple criteria in a filter for finer
35   control.
36
37Expression
38   Expressions are how we perform filtering. They look like functions in a
39   programming language: they have a name and accept a number of arguments.
40   The expression evaluates to either ``true`` or ``false`` for every record in
41   the table. The arguments are expressions themselves.
42
43Arity
44   The arity of an expression tells us how many arguments it takes. Expressions
45   taking no arguments are called *nullary*, those taking one argument are
46   known as *unary* expressions and those taking two arguments are called
47   *binary*.
48
49
50
51Interface
52*********
53
54Above each table there is a text field which is used to enter a filter: either
55one predefined by the OpenMW CS developers or one  made by you. Another
56important element is the filter table found under *View* → *Filters*. You
57should see the default filters made by the OpenMW team in the table. The table
58has the columns *Filter*, *Description* and *Modified*.
59
60ID
61   A unique name used to refer to this filter. Note that every ID has a
62   scope prefix, we will explain these soon.
63
64Modified
65   This is the same as for all the other records, it tells us whether the
66   filter is *added* or *removed*. Filters are specific to a project instead of
67   a content file, they have no effect on the game itself.
68
69Filter
70   The actual contents of the filter are given here using the filter syntax.
71   Change the expressions to modify what the filter returns.
72
73Description
74   A textual description of what the filter does.
75
76
77
78Using predefined filters
79************************
80
81To use a filter you have to type its ID into the filter field above a table.
82
83For instance, try to opening the objects table (under the world menu) and type
84into the filters field ``project::weapons``. As soon as you complete the text
85the table will show only the weapons. The string ``project::weapons`` is the ID
86of one of the predefined filters. This means that in order to use the filter
87inside the table you type its name inside the filter field.
88
89Filter IDs follow these general conventions:
90
91- IDs of filters for a specific record type contain usually the name of a
92  specific group. For instance the ``project::weapons`` filter contains the
93  term ``weapons``. Plural form is always used.
94
95- When filtering a specific subgroup the ID is prefixed with the name of the
96  more general filter. For instance ``project::weaponssilver`` will filter only
97  silver weapons and ``project::weaponsmagical`` will filter only magical
98  weapons.
99
100- There are few exceptions from the above rule. For instance there are
101  ``project::added``, ``project::removed``, ``project::modified`` and
102  ``project::base``. You might except something more like
103  ``project::statusadded`` but in this case requiring these extra characters
104  would not improve readability.
105
106We strongly recommend you take a look at the filters table right now to see
107what you can filter with the defaults. Try using the default filters first
108before writing you own.
109
110
111
112Writing your own filters
113************************
114
115As mentioned before, filters are just another type of record in the OpenMW CS.
116To create a new filter you will have to add a new record to the *Filters* table
117and set its properties to your liking. Filters are created by combining
118existing filters into more complex ones.
119
120
121Scopes
122======
123
124Every default filter has the prefix ``project``. This is a *scope*, a mechanism
125that determines the lifetime of the filter. These are the supported scopes:
126
127``project::``
128   Indicates that the filter is to be used throughout the project in multiple
129   sessions. You can restart the CS and the filter will still be there.
130
131``session::``
132   Indicates that the filter is not stored between multiple sessions and once
133   you quit the OpenMW CS application the filter will be gone. Until then it
134   can be found inside the filters table.
135
136Project-filters are stored in an internal project file, not final content file
137meant for the player. Keep in mind when collaborating with other modders that
138you need to share the same project file.
139
140
141
142Writing expressions
143===================
144
145The syntax for expressions is as follows:
146
147.. code::
148
149   <name>
150   <name>(<arg1>)
151   <name>(<arg1>, <arg2>, ..., <argn>)
152
153Where ``<name>`` is the name of the expression, such as ``string`` and the
154``<arg>`` are expressions themselves. A nullary expression consists only of its
155name. A unary expression contains its argument within a pair of parentheses
156following the name. If there is more than one argument they are separated by
157commas inside the parentheses.
158
159An example of a binary expression is ``string("Record Type", weapon)``; the
160name is ``string``, and it takes two arguments which are strings of string
161type. The meaning of arguments depends on the expression itself. In this case
162the first argument is the name of a record column and the second field is the
163values we want to test it against.
164
165Strings are sequences of characters and are case-insensitive. If a string
166contains spaces it must be quoted, otherwise the quotes are optional and
167ignored.
168
169
170Constant Expressions
171--------------------
172
173These expressions take no arguments and always return the same result.
174
175``true``
176   Always evaluates to ``true``.
177
178``false``
179   Always evaluates to ``false``.
180
181
182Comparison Expressions
183----------------------
184
185``string(<column>, <value>)``
186   The ``<value>`` is a regular expression pattern. The expressions evaluates
187   to ``true`` when the value of a record in ``<column>`` matches the pattern.
188   Since the majority of the columns contain string values, ``string`` is among
189   the most often used expressions. Examples:
190
191   ``string("Record Type", "Weapon")``
192      Will evaluate to ``true`` for all records containing ``Weapon`` in the
193      *Record Type* column cell.
194
195   ``string("Portable", "true")``
196      Will evaluate to ``true`` [#]_ for all records containing word ``true`` inside
197      *Portable* column cell.
198
199.. [#] There is no Boolean (``true`` or ``false``) value in the OpenMW CS. You
200       should use a string for those.
201
202
203``value(<value>, (<lower>, <upper>))``
204   Match a value type, such as a number, with a range of possible values. The
205   argument ``<value>`` is the string name of the value we want to compare, the
206   second argument is a pair of lower and upper bounds for the range interval.
207
208   One can use either parentheses ``()`` or brackets ``[]`` to surround the
209   pair. Brackets are inclusive and parentheses are exclusive. We can also mix
210   both styles:
211
212   .. code::
213
214      value("Weight", [20, 50))
215
216   This will match any objects with a weight greater or equal to 20 and
217   strictly less than 50.
218
219
220Logical Expressions
221-------------------
222
223``not <expression>``
224   Logically negates the result of an expression. If ``<expression>`` evaluates
225   to ``true`` the negation is ``false``, and if ``<expression>`` evaluates to
226   ``false`` the negation is ``true``. Note that there are no parentheses
227   around the argument.
228
229``or(<expr1>, <expr2>, ..., <exprN>)``
230   Logical disjunction, evaluates to ``true`` if at least one argument
231   evaluates to ``true`` as well, otherwise the expression evaluates to
232   ``false``.
233
234   As an example assume we want to filter for both NPCs and creatures; the
235   expression for that use-case is
236
237   .. code::
238
239      or(string("record type", "npc"), string("record type", "creature"))
240
241   In this particular case only one argument can evaluate to ``true``, but one
242   can write expressions where multiple arguments can be ``true`` at a time.
243
244``or(<expr1>, <expr2>, ..., <exprN>)``
245   Logical conjunction, evaluates to ``true`` if and only if all arguments
246   evaluate to ``true`` as well, otherwise the expression evaluates to
247   ``false``.
248
249   As an example assume we want to filter for weapons weighting less than a hundred
250   units The expression for that use-case is
251
252   .. code::
253
254      and(string("record type", "weapon"), value("weight", (0, 100)))
255
256
257Anonymous filters
258=================
259
260Creating a whole new filter when you only intend to use it once can be
261cumbersome. For that reason the OpenMW CS supports *anonymous* filters which
262can be typed directly into the filters field of a table. They are not stored
263anywhere, when you clear the field the filter is gone forever.
264
265In order to define an anonymous filter you type an exclamation mark as the
266first character into the field followed by the filter definition (e.g.
267``!string("Record Type", weapon)`` to filter only for weapons).
268
269
270
271Creating and saving filters
272***************************
273
274Filters are managed the same way as other records: go to the filters table,
275right click and select the option *Add Record* from the context menu. You are
276given a choice between project- or session scope. Choose the scope from the
277dropdown and type in your desired ID for the filter. A newly created filter
278does nothing since it still lacks expressions. In order to add your queries you
279have to edit the filter record.
280
281
282Replacing the default filters set
283=================================
284
285OpenMW CS allows you to substitute the default filter set for the entire
286application. This will affect the default filters for all content files that
287have not been edited on this computer and user account.
288
289Create a new content file, add the desired filters, remove the undesired ones
290and save. Now rename the *project* file to ``defaultfilters`` and make sure the
291``.omwaddon.project`` file extension is removed. This file will act as a
292template for all new files from now on. If you wish to go back to the
293old default set rename or remove this custom file.
294