public Term (Term parent, Literal after)
		{
			this.parent = parent;

			if (parent != null) {
				if (after == null)
					parent.Add (this);
				else
					parent.SubTerms.Insert (parent.SubTerms.IndexOf (after) + 1, this);
			}
		}
Beispiel #2
0
        protected Term(Term parent, Literal after)
        {
            this.parent = parent;
            SubTerms = new List<Term> ();

            if (parent != null)
                if (after == null) {
                    parent.Add (this);
                } else {
                    parent.SubTerms.Insert (parent.SubTerms.IndexOf (after) + 1, this);
                }
        }
Beispiel #3
0
 public void Add(Term term)
 {
     SubTerms.Add (term);
 }
Beispiel #4
0
        public static Term TermFromOperator(string op, Term parent, Literal after)
        {
            //Console.WriteLine ("finding type for operator {0}", op);
            //op = op.Trim ();
            op = op.ToLower ();

            if (AndTerm.Operators.Contains (op))
                return new AndTerm (parent, after);

            if (OrTerm.Operators.Contains (op))
                return new OrTerm (parent, after);

            Log.DebugFormat ("Do not have Term for operator {0}", op);
            return null;
        }
Beispiel #5
0
        private void Update()
        {
            // Clear the last root term
            root_term = null;

            if (ParensValid () && ConstructQuery (null, 0, entry.Text)) {
                if (RootTerm != null) {
                    //Log.DebugFormat("rootTerm = {0}", RootTerm);
                    if (!(RootTerm is AndTerm)) {
                        // A little hacky, here to make sure the root term is a AndTerm which will
                        // ensure we handle the Hidden tag properly
                        AndTerm root_parent = new AndTerm(null, null);
                        RootTerm.Parent = root_parent;
                        root_term = root_parent;
                    }

                    //Log.DebugFormat("rootTerm = {0}", RootTerm);
                    if (!(RootTerm is AndTerm)) {
                        // A little hacky, here to make sure the root term is a AndTerm which will
                        // ensure we handle the Hidden tag properly
                        AndTerm root_parent = new AndTerm(null, null);
                        RootTerm.Parent = root_parent;
                        root_term = root_parent;
                    }
                    //Log.DebugFormat ("condition = {0}", RootTerm.SqlCondition ());
                    query.TagTerm = new ConditionWrapper (RootTerm.SqlCondition ());
                } else {
                    query.TagTerm = null;
                    //Log.Debug ("root term is null");
                }
            }
        }
		public AbstractLiteral(Term parent, Literal after) : base (parent, after) {}
Beispiel #7
0
 void HandleTagsAdded(Tag[] tags, Term parent, Literal after)
 {
     InsertTerm (tags, parent, after);
 }
Beispiel #8
0
 void HandleAttachTag(Tag tag, Term parent, Literal after)
 {
     InsertTerm (new Tag [] {tag}, parent, after);
 }
		private static bool AppendTerm (ArrayList parts, Term term, Tag single_tag)
		{
			bool tag_matches = false;
			if (term != null) {
				Literal literal = term as Literal;
				if (literal != null) {
					if (literal.Tag == single_tag)
						tag_matches = true;

					if (literal.IsNegated)
						parts.Add (String.Format (Catalog.GetString ("Not {0}"), literal.Tag.Name));
					else
						parts.Add (literal.Tag.Name);
				} else {
					foreach (Term subterm in term.SubTerms) {
						tag_matches |= AppendTerm (parts, subterm, single_tag);
					}
				}
			}

			return tag_matches;
		}
Beispiel #10
0
 public Literal(Term parent, Tag tag, Literal after)
     : base(parent, after)
 {
     Tag = tag;
 }
Beispiel #11
0
 public OrTerm(Term parent, Literal after)
     : base(parent, after)
 {
 }
        public ArrayList InsertTerm(Tag [] tags, Term parent, Literal after)
        {
            int position;

            if (after != null)
            {
                position = WidgetPosition(after.Widget) + 1;
            }
            else
            {
                position = Children.Length - 1;
            }

            ArrayList added = new ArrayList();

            foreach (Tag tag in tags)
            {
                //Console.WriteLine ("Adding tag {0}", tag.Name);

                // Don't put a tag into a Term twice
                if (parent != Root && (parent.FindByTag(tag, true)).Count > 0)
                {
                    continue;
                }

                if (parent.Count > 0)
                {
                    Widget sep = parent.SeparatorWidget();

                    InsertWidget(position, sep);
                    position++;
                }

                // Encapsulate new OR terms within a new AND term of which they are the
                // only member, so later other terms can be AND'd with them
                //
                // TODO should really see what type of term the parent is, and
                // encapsulate this term in a term of the opposite type. This will
                // allow the query system to be expanded to work for multiple levels much easier.
                if (parent == rootTerm)
                {
                    parent = new AndTerm(rootTerm, after);
                    after  = null;
                }

                Literal term = new Literal(parent, tag, after);
                term.TermAdded      += HandleTermAdded;
                term.LiteralsMoved  += HandleLiteralsMoved;
                term.AttachTag      += HandleAttachTag;
                term.NegatedToggled += HandleNegated;
                term.Removing       += HandleRemoving;
                term.Removed        += HandleRemoved;
                term.RequireTag     += Require;
                term.UnRequireTag   += UnRequire;

                added.Add(term);

                // Insert this widget into the appropriate place in the hbox
                InsertWidget(position, term.Widget);
            }

            UpdateQuery();

            return(added);
        }
 private void HandleAttachTag(Tag tag, Term parent, Literal after)
 {
     InsertTerm(new Tag [] { tag }, parent, after);
 }
 private void HandleTermAdded(Term parent, Literal after)
 {
     InsertTerm(parent, after);
 }
Beispiel #15
0
		public TextLiteral (Term parent, string text) : base (parent, null)
		{
			this.text = text;
		}
Beispiel #16
0
        public void CopyAndInvertSubTermsFrom(Term term, bool recurse)
        {
            is_negated = true;
            var termsToMove = new List<Term> (term.SubTerms);

            foreach (Term subterm in termsToMove) {
                if (recurse)
                    subterm.Invert (true).Parent = this;
                else
                    subterm.Parent = this;
            }
        }
Beispiel #17
0
        public void Remove(Term term)
        {
            SubTerms.Remove (term);

            // Remove ourselves if we're now empty
            if (SubTerms.Count == 0 && Parent != null)
                Parent.Remove (this);
        }
		private void HandleTermAdded (Term parent, Literal after)
		{
			InsertTerm (parent, after);
		}
Beispiel #19
0
        public List<Literal> InsertTerm(Tag [] tags, Term parent, Literal after)
        {
            int position;
            if (after != null)
                position = WidgetPosition (after.Widget) + 1;
            else
                position = Children.Length - 1;

            var added = new List<Literal>();

            foreach (Tag tag in tags) {
                //Console.WriteLine ("Adding tag {0}", tag.Name);

                // Don't put a tag into a Term twice
                if (parent != Root && (parent.FindByTag (tag, true)).Count > 0)
                    continue;

                if (parent.Count > 0) {
                    Widget sep = parent.SeparatorWidget ();

                    InsertWidget (position, sep);
                    position++;
                }

                // Encapsulate new OR terms within a new AND term of which they are the
                // only member, so later other terms can be AND'd with them
                //
                // TODO should really see what type of term the parent is, and
                // encapsulate this term in a term of the opposite type. This will
                // allow the query system to be expanded to work for multiple levels much easier.
                if (parent == rootTerm) {
                    parent = new AndTerm (rootTerm, after);
                    after = null;
                }

                Literal term  = new Literal (parent, tag, after);
                term.TagsAdded  += HandleTagsAdded;
                term.LiteralsMoved += HandleLiteralsMoved;
                term.AttachTag  += HandleAttachTag;
                term.NegatedToggled += HandleNegated;
                term.Removing  += HandleRemoving;
                term.Removed  += HandleRemoved;
                term.RequireTag  += Require;
                term.UnRequireTag += UnRequire;

                added.Add (term);

                // Insert this widget into the appropriate place in the hbox
                InsertWidget (position, term.Widget);
            }

            UpdateQuery ();

            return added;
        }
		private void InsertTerm (Term parent, Literal after)
		{
			if (Literal.FocusedLiterals.Count != 0) {
				HandleLiteralsMoved (Literal.FocusedLiterals, parent, after);

				// Prevent them from being removed again
				Literal.FocusedLiterals = null;
			}
			else
				InsertTerm (tag_selection_widget.TagHighlight, parent, after);
		}
Beispiel #21
0
        void HandleLiteralsMoved(List<Literal> literals, Term parent, Literal after)
        {
            preventUpdate = true;
            foreach (Literal term in literals) {
                Tag tag = term.Tag;

                // Don't listen for it to be removed since we are
                // moving it. We will update when we're done.
                term.Removed -= HandleRemoved;
                term.RemoveSelf ();

                // Add it to where it was dropped
                List<Literal> groups = InsertTerm (new [] {tag}, parent, after);

                if (term.IsNegated)
                    foreach (Literal group in groups)
                        group.IsNegated = true;
            }
            preventUpdate = false;
            UpdateQuery ();
        }
Beispiel #22
0
 // Breaking the query the user typed into something useful involves running
 // it through the above regular expression recursively until it is broken down
 // into literals and operators that we can use to generate SQL queries.
 private bool ConstructQuery(Term parent, int depth, string txt)
 {
     return ConstructQuery(parent, depth, txt, false);
 }
Beispiel #23
0
        void Init()
        {
            sepBox = null;
            preview = false;

            rootAdd = new Gtk.EventBox ();
            rootAdd.VisibleWindow = false;
            rootAdd.CanFocus = true;
            rootAdd.DragMotion  += HandleDragMotion;
            rootAdd.DragDataReceived += HandleDragDataReceived;
            rootAdd.DragLeave  += HandleDragLeave;

            help = new Gtk.Label ("<i>" + Catalog.GetString ("Drag tags here to search for them") + "</i>");
            help.UseMarkup = true;
            help.Visible = true;

            rootBox = new HBox();
            rootBox.Add (help);
            rootBox.Show ();

            rootAdd.Child = rootBox;
            rootAdd.Show ();

            Gtk.Drag.DestSet (rootAdd, DestDefaults.All, tag_dest_target_table,
                      DragAction.Copy | DragAction.Move );

            PackEnd (rootAdd, true, true, 0);

            rootTerm = new OrTerm (null, null);
        }
Beispiel #24
0
        private bool ConstructQuery(Term parent, int depth, string txt, bool negated)
        {
            if (string.IsNullOrEmpty(txt))
                return true;

            string indent = String.Format ("{0," + depth*2 + "}", " ");

            //Log.DebugFormat (indent + "Have text: {0}", txt);

            // Match the query the user typed against our regular expression
            Match match = term_regex.Match (txt);

            if (!match.Success) {
                //Log.Debug (indent + "Failed to match.");
                return false;
            }

            bool op_valid = true;
            string op = String.Empty;

            // For the moment at least we don't support operator precedence, so we require
            // that only a single operator is used for any given term unless it is made unambiguous
            // by using parenthesis.
            foreach (Capture capture in match.Groups ["Ops"].Captures) {
                if (op == String.Empty)
                    op = capture.Value;
                else if (op != capture.Value) {
                    op_valid = false;
                    break;
                }
            }

            if (!op_valid) {
                Log.Information (indent + "Ambiguous operator sequence.  Use parenthesis to explicitly define evaluation order.");
                return false;
            }

            if (match.Groups ["Terms"].Captures.Count == 1 && match.Groups["NotTerm"].Captures.Count != 1) {
                //Log.DebugFormat (indent + "Unbreakable term: {0}", match.Groups ["Terms"].Captures [0]);
                string literal;
                bool is_negated = false;
                Tag tag = null;

                if (match.Groups ["NotTag"].Captures.Count == 1) {
                    literal = match.Groups ["NotTag"].Captures [0].Value;
                    is_negated = true;
                } else {
                    literal = match.Groups ["Terms"].Captures [0].Value;
                }

                is_negated = is_negated || negated;

                tag = App.Instance.Database.Tags.GetTagByName (literal);

                // New OR term so we can match against both tag and text search
                parent = new OrTerm(parent, null);

                // If the literal is the name of a tag, include it in the OR
                //AbstractLiteral term = null;
                if (tag != null) {
                    new Literal (parent, tag, null);
                }

                // Always include the literal text in the search (path, comment, etc)
                new TextLiteral (parent, literal);

                // If the term was negated, negate the OR parent term
                if (is_negated) {
                    parent = parent.Invert(true);
                }

                if (RootTerm == null)
                    root_term = parent;

                return true;
            } else {
                Term us = null;
                if (op != null && op != String.Empty) {
                    us = Term.TermFromOperator (op, parent, null);
                    if (RootTerm == null)
                        root_term = us;
                }

                foreach (Capture capture in match.Groups ["Term"].Captures) {
                    string subterm = capture.Value.Trim ();

                    if (subterm == null || subterm.Length == 0)
                        continue;

                    // Strip leading/trailing parens
                    if (subterm [0] == '(' && subterm [subterm.Length - 1] == ')') {
                        subterm = subterm.Remove (subterm.Length - 1, 1);
                        subterm = subterm.Remove (0, 1);
                    }

                    //Log.DebugFormat (indent + "Breaking subterm apart: {0}", subterm);

                    if (!ConstructQuery (us, depth + 1, subterm, negated))
                        return false;
                }

                foreach (Capture capture in match.Groups ["NotTerm"].Captures) {
                    string subterm = capture.Value.Trim ();

                    if (subterm == null || subterm.Length == 0)
                        continue;

                    // Strip leading/trailing parens
                    if (subterm [0] == '(' && subterm [subterm.Length - 1] == ')') {
                        subterm = subterm.Remove (subterm.Length - 1, 1);
                        subterm = subterm.Remove (0, 1);
                    }

                    //Log.DebugFormat (indent + "Breaking not subterm apart: {0}", subterm);

                    if (!ConstructQuery (us, depth + 1, subterm, true))
                        return false;
                }

                if (negated && us != null) {
                    if (us == RootTerm)
                        root_term = us.Invert(false);
                    else
                        us.Invert(false);
                }

                return true;
            }
        }