Daenyth/Cockatrice — pull request #47 by sylvan-basilisk (2014-01-29 08:25:14+00:00)
Title: addition of advanced filtering features in deck editor

Hello, these commits enable advanced filtering in the deck editor mode. In order to fit in the filter UI components some parts of the editor layout had to be moved and/or made smaller.

The toolbar for "add/remove/increment/etc..." was made smaller with only the icons (no labels) and also moved above the card database. The text portion of the card info window was removed by replacing the CardInfoWIdget class with the CardFrame, CardInfoPicture, and CardInfoText classes. The new CardFrame class presents only the card picture by default, but switches to text mode if the picture can't be loaded. There is also an option for text only viewing in the database menu.

On to the filtering... The filter UI components were added underneath the card info panel. There are some components for selecting the type of filter logic and filter attribute, a text box for specifying the filter term and a button for adding the new filter. A tree view was added below this to display the filters organized by attribute, then logic.

The filter tree is represented by the FilterTree class and modeled by the FilterTreeModel class. The filter tree is organized with attributes at depth 1, logic operators (**and**, **and not**, **or**, **or not**) at depth 2 and finally terms at depth 3. The logic is applied in the following way to a given card X to determine if it is filtered out: attributes are iterated in the order they were added. For each attribute, we iterate over its operators: **and**, **and not**, **or**, **or not**. If an operator has an empty list of terms, the card is not filtered out by that operator. If the operator has terms, we combine the terms using the operator logic. The **and**s are run first, then 'and'ed with the **or**s.

For example, suppose the 'name' attribute had a non-empty list of terms for each operator:
* and: X1, X2, X3
* and not: x1, x2, x3
* or: Y1, Y2
* or not: y1, y2, y3, y4
then the logic would look like:
```
(X1 && X2 && X3 && (!x1) && (!x2) && (!x3)) && (Y1 || Y2 || (!y1) || (!y2) || (!y3) || (!y4))
```
in otherwords the **or** section filters whatever cards are not rejected by the **and**s.

I hope you like these additions and will pull these commits :D
If you see anything you don't like point it out and Ill fix it.