Minor reorganization of html filter code.
[beagle.git] / search / Search.cs
blobeac13b9eabaec4094af01e7efe9fed5205cf0443
1 using System;
2 using System.Collections;
4 using Gtk;
5 using Beagle;
6 using Beagle.Util;
7 using Mono.Unix;
9 using Search.Tiles;
10 using Search.Tray;
12 namespace Search {
14 public class MainWindow : Window {
16 Search.GroupView view;
17 Search.Entry entry;
18 Gtk.Button button;
19 Search.Spinner spinner;
20 Gtk.Tooltips tips;
21 Gtk.Notebook pages;
22 Search.Pages.QuickTips quicktips;
23 Search.Pages.RootUser rootuser;
24 Search.Pages.StartDaemon startdaemon;
25 Search.Pages.NoMatch nomatch;
26 Search.Panes panes;
27 Search.Tray.TrayIcon tray;
29 uint timeout;
31 string queryText;
32 Beagle.Query currentQuery;
33 Search.ScopeType scope = ScopeType.Everywhere;
34 Search.SortType sort = SortType.Modified;
35 Search.TypeFilter filter = null;
37 XKeybinder keybinder = new XKeybinder ();
39 public static bool IconEnabled = false;
41 public static void Main (string [] args)
43 SystemInformation.SetProcessName ("beagle-search");
45 Catalog.Init ("beagle", ExternalStringsHack.LocaleDir);
47 string query = ParseArgs (args);
49 Gnome.Program program = new Gnome.Program ("search", "0.0",
50 Gnome.Modules.UI, args);
52 MainWindow window = new MainWindow ();
54 if (query != null && query != "" && !IconEnabled) {
55 window.entry.Text = query;
56 window.Search (true);
59 program.Run ();
62 private static string ParseArgs (String[] args)
64 string query = "";
65 int i = 0;
67 while (i < args.Length) {
68 switch (args [i]) {
69 case "--help":
70 case "--usage":
71 PrintUsageAndExit ();
72 return null;
74 case "--icon":
75 IconEnabled = true;
76 break;
78 case "--autostarted":
79 if (! Conf.Searching.Autostart) {
80 Console.WriteLine ("beagle-search: Autostarting is disabled, not starting");
81 Environment.Exit (0);
83 break;
85 // Ignore session management
86 case "--sm-config-prefix":
87 case "--sm-client-id":
88 case "--screen":
89 // These all take an argument, so
90 // increment i
91 i++;
92 break;
94 default:
95 if (args [i].Length < 2 || args [i].Substring (0, 2) != "--") {
96 if (query.Length != 0)
97 query += " ";
98 query += args [i];
100 break;
103 i++;
106 return query;
109 public static void PrintUsageAndExit ()
111 string usage =
112 "beagle-search: GUI interface to the Beagle search system.\n" +
113 "Web page: http://www.beagle-project.org/\n" +
114 "Copyright (C) 2005-2006 Novell, Inc.\n\n";
116 usage +=
117 "Usage: beagle-search [OPTIONS] [<query string>]\n\n" +
118 "Options:\n" +
119 " --help\t\t\tPrint this usage message.\n" +
120 " --icon\t\t\tAdd an icon to the notification area rather than opening a search window.\n";
122 Console.WriteLine (usage);
123 System.Environment.Exit (0);
126 public MainWindow () : base (WindowType.Toplevel)
128 Title = "Desktop Search";
129 Icon = Beagle.Images.GetPixbuf ("system-search.png");
131 BorderWidth = 3;
132 DefaultWidth = 700;
133 DefaultHeight = 550;
134 DeleteEvent += OnWindowDelete;
136 VBox vbox = new VBox ();
137 vbox.Spacing = 3;
139 UIManager uim = new UIManager (this);
140 uim.ScopeChanged += OnScopeChanged;
141 uim.SortChanged += OnSortChanged;
142 uim.ShowQuickTips += OnShowQuickTips;
143 vbox.PackStart (uim.MenuBar, false, false, 0);
145 HBox padding_hbox = new HBox ();
147 HBox hbox = new HBox (false, 6);
149 Label label = new Label (Catalog.GetString ("_Find:"));
150 hbox.PackStart (label, false, false, 0);
152 entry = new Entry ();
153 label.MnemonicWidget = entry;
154 uim.FocusSearchEntry += delegate () { entry.GrabFocus (); };
155 entry.Activated += OnEntryActivated;
156 entry.Changed += OnEntryChanged;
157 entry.MoveCursor += OnEntryMoveCursor;
158 hbox.PackStart (entry, true, true, 0);
160 button = new Gtk.Button ();
161 Gtk.HBox button_hbox = new Gtk.HBox (false, 2);
162 Gtk.Image icon = new Gtk.Image (Gtk.Stock.Find, Gtk.IconSize.Button);
163 button_hbox.PackStart (icon, false, false, 0);
164 label = new Gtk.Label (Catalog.GetString ("Find Now"));
165 button_hbox.PackStart (label, false, false, 0);
166 button.Add (button_hbox);
167 button.Clicked += OnButtonClicked;
169 Gtk.VBox buttonVBox = new Gtk.VBox (false, 0);
170 buttonVBox.PackStart (button, true, false, 0);
171 hbox.PackStart (buttonVBox, false, false, 0);
173 spinner = new Spinner ();
175 hbox.PackStart (spinner, false, false, 0);
177 padding_hbox.PackStart (hbox, true, true, 9);
179 vbox.PackStart (padding_hbox, false, true, 6);
181 pages = new Gtk.Notebook ();
182 pages.ShowTabs = false;
183 pages.ShowBorder = false;
184 vbox.PackStart (pages, true, true, 0);
186 quicktips = new Pages.QuickTips ();
187 quicktips.Show ();
188 pages.Add (quicktips);
190 rootuser = new Pages.RootUser ();
191 rootuser.Show ();
192 pages.Add (rootuser);
194 startdaemon = new Pages.StartDaemon ();
195 startdaemon.DaemonStarted += OnDaemonStarted;
196 startdaemon.Show ();
197 pages.Add (startdaemon);
199 panes = new Search.Panes ();
200 panes.Show ();
201 pages.Add (panes);
203 view = new GroupView ();
204 view.TileSelected += ShowInformation;
205 panes.MainContents = view;
207 Add (vbox);
209 tips = new Gtk.Tooltips ();
210 tips.SetTip (entry, Catalog.GetString ("Type in search terms"), "");
211 tips.SetTip (button, Catalog.GetString ("Start searching"), "");
212 tips.Enable ();
214 if (Environment.UserName == "root" && ! Conf.Daemon.AllowRoot) {
215 pages.CurrentPage = pages.PageNum (rootuser);
216 entry.Sensitive = button.Sensitive = uim.Sensitive = false;
217 } else {
218 pages.CurrentPage = pages.PageNum (quicktips);
221 if (IconEnabled) {
222 tray = new Search.Tray.TrayIcon ();
223 tray.Clicked += OnTrayActivated;
224 tray.Search += OnTraySearch;
226 // Attach the hide/show keybinding
227 keybinder.Bind (Conf.Searching.ShowSearchWindowBinding.ToString (), OnTrayActivated);
228 } else {
229 ShowAll ();
233 private void SetWindowTitle (string query)
235 Title = String.Format ("Desktop Search: {0}", query);
238 // Whether we should grab focus from the text entry
239 private bool grab_focus;
241 private void Search (bool grab_focus)
243 if (timeout != 0) {
244 GLib.Source.Remove (timeout);
245 timeout = 0;
248 string query = queryText = entry.Text;
249 if (query == null || query == "")
250 return;
252 SetWindowTitle (query);
253 ShowInformation (null);
255 if (tray != null) {
256 tray.AddSearch (query);
259 filter = TypeFilter.MakeFilter (ref query);
261 view.Clear ();
262 view.Scope = scope;
263 view.Sort = sort;
264 pages.CurrentPage = pages.PageNum (panes);
266 this.grab_focus = grab_focus;
268 try {
269 if (currentQuery != null) {
270 currentQuery.HitsAddedEvent -= OnHitsAdded;
271 currentQuery.HitsSubtractedEvent -= OnHitsSubtracted;
272 currentQuery.Close ();
275 currentQuery = new Query ();
276 currentQuery.AddDomain (QueryDomain.Neighborhood);
278 // Don't search documentation by default
279 QueryPart_Property part = new QueryPart_Property ();
280 part.Logic = QueryPartLogic.Prohibited;
281 part.Type = PropertyType.Keyword;
282 part.Key = "beagle:Source";
283 part.Value = "documentation";
284 currentQuery.AddPart (part);
286 currentQuery.AddText (query);
287 currentQuery.HitsAddedEvent += OnHitsAdded;
288 currentQuery.HitsSubtractedEvent += OnHitsSubtracted;
289 currentQuery.FinishedEvent += OnFinished;
291 currentQuery.SendAsync ();
292 spinner.Start ();
293 } catch (Beagle.ResponseMessageException e){
294 pages.CurrentPage = pages.PageNum (startdaemon);
295 } catch (Exception e) {
296 Console.WriteLine ("Querying the Beagle daemon failed: {0}", e.Message);
300 private void OnEntryActivated (object obj, EventArgs args)
302 Search (true);
305 private void OnDaemonStarted ()
307 Search (true);
310 private void OnEntryChanged (object obj, EventArgs args)
312 if (timeout != 0)
313 GLib.Source.Remove (timeout);
314 timeout = GLib.Timeout.Add (1000, OnEntryTimeout);
317 private void OnEntryMoveCursor (object obj, EventArgs args)
319 if (timeout != 0)
320 GLib.Source.Remove (timeout);
321 timeout = GLib.Timeout.Add (1000, OnEntryTimeout);
324 private bool OnEntryTimeout ()
326 timeout = 0;
327 Search (false);
328 return false;
331 private void OnButtonClicked (object obj, EventArgs args)
333 Search (true);
336 private void OnWindowDelete (object o, Gtk.DeleteEventArgs args)
338 if (IconEnabled) {
339 Hide ();
340 args.RetVal = true;
341 } else {
342 Gtk.Application.Quit ();
346 private void OnScopeChanged (Search.ScopeType newScope)
348 view.Scope = scope = newScope;
349 CheckNoMatch ();
352 private void OnSortChanged (Search.SortType newSort)
354 view.Sort = sort = newSort;
357 private void OnShowQuickTips ()
359 if (currentQuery != null) {
360 currentQuery.HitsAddedEvent -= OnHitsAdded;
361 currentQuery.HitsSubtractedEvent -= OnHitsSubtracted;
362 currentQuery.Close ();
363 currentQuery = null;
366 pages.CurrentPage = pages.PageNum (quicktips);
369 private void ShowInformation (Tiles.Tile tile)
371 if (tile != null)
372 panes.Details = tile.Details;
373 else
374 panes.Details = null;
377 private void OnFinished (FinishedResponse response)
379 spinner.Stop ();
380 view.Finished (grab_focus);
381 grab_focus = false;
383 CheckNoMatch ();
386 private void OnHitsAdded (HitsAddedResponse response)
388 foreach (Hit hit in response.Hits) {
389 Tile tile = TileActivatorOrg.MakeTile (hit, currentQuery);
390 if (tile == null)
391 continue;
393 if (filter != null && !filter.Filter (tile))
394 continue;
396 view.AddHit (tile);
397 if (pages.CurrentPageWidget != panes)
398 pages.CurrentPage = pages.PageNum (panes);
402 private void OnHitsSubtracted (HitsSubtractedResponse response)
404 foreach (Uri uri in response.Uris)
405 view.SubtractHit (uri);
407 CheckNoMatch ();
410 private void CheckNoMatch ()
412 MatchType matches = view.MatchState;
413 if (matches == MatchType.Matched) {
414 pages.CurrentPage = pages.PageNum (panes);
415 return;
418 if (nomatch != null)
419 nomatch.Destroy ();
420 nomatch = new Pages.NoMatch (queryText, matches == MatchType.NoneInScope);
421 nomatch.Show ();
422 pages.Add (nomatch);
423 pages.CurrentPage = pages.PageNum (nomatch);
426 /////////////////////////////////////
428 private void OnTrayActivated (object o, EventArgs args)
430 if (! Visible) {
431 base.ShowAll ();
432 base.Present ();
433 entry.GrabFocus ();
434 } else {
435 base.Hide ();
439 private void OnTraySearch (string query)
441 if (!Visible)
442 ShowAll ();
444 entry.Text = query;
445 Search (true);