Show total number of results for google driver too. Helps to know if my query resulte...
[beagle.git] / search / Search.cs
bloba0178bea032914110a9320f5e1f2abe731cdf11b
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 UIManager uim;
17 Search.GroupView view;
18 Search.Entry entry;
19 Gtk.Button button;
20 Search.Spinner spinner;
21 Gtk.Tooltips tips;
22 Gtk.Notebook pages;
23 Search.Pages.QuickTips quicktips;
24 Search.Pages.RootUser rootuser;
25 Search.Pages.StartDaemon startdaemon;
26 Search.Pages.NoMatch nomatch;
27 Search.Panes panes;
28 Search.Tray.TrayIcon tray;
30 uint timeout;
32 string queryText;
33 Beagle.Query currentQuery;
34 Search.ScopeType scope = ScopeType.Everything;
35 Search.SortType sort = SortType.Modified;
36 Search.TypeFilter filter = null;
37 bool showDetails = true;
39 XKeybinder keybinder = new XKeybinder ();
41 public static bool IconEnabled = false;
43 public static void Main (string [] args)
45 SystemInformation.SetProcessName ("beagle-search");
47 Catalog.Init ("beagle", ExternalStringsHack.LocaleDir);
49 string query = ParseArgs (args);
51 Gnome.Program program = new Gnome.Program ("search", "0.0",
52 Gnome.Modules.UI, args);
54 MainWindow window = new MainWindow ();
56 if (query != null && query != "" && !IconEnabled) {
57 window.entry.Text = query;
58 window.Search (true);
61 program.Run ();
64 private static string ParseArgs (String[] args)
66 string query = "";
67 int i = 0;
69 while (i < args.Length) {
70 switch (args [i]) {
71 case "--help":
72 case "--usage":
73 PrintUsageAndExit ();
74 return null;
76 case "--icon":
77 IconEnabled = true;
78 break;
80 case "--autostarted":
81 if (! Conf.Searching.Autostart) {
82 Console.WriteLine ("beagle-search: Autostarting is disabled, not starting");
83 Environment.Exit (0);
85 break;
87 // Ignore session management
88 case "--sm-config-prefix":
89 case "--sm-client-id":
90 case "--screen":
91 // These all take an argument, so
92 // increment i
93 i++;
94 break;
96 default:
97 if (args [i].Length < 2 || args [i].Substring (0, 2) != "--") {
98 if (query.Length != 0)
99 query += " ";
100 query += args [i];
102 break;
105 i++;
108 return query;
111 public static void PrintUsageAndExit ()
113 string usage =
114 "beagle-search: GUI interface to the Beagle search system.\n" +
115 "Web page: http://www.beagle-project.org/\n" +
116 "Copyright (C) 2005-2006 Novell, Inc.\n\n";
118 usage +=
119 "Usage: beagle-search [OPTIONS] [<query string>]\n\n" +
120 "Options:\n" +
121 " --help\t\t\tPrint this usage message.\n" +
122 " --icon\t\t\tAdd an icon to the notification area rather than opening a search window.\n";
124 Console.WriteLine (usage);
125 System.Environment.Exit (0);
128 public MainWindow () : base (WindowType.Toplevel)
130 Title = "Desktop Search";
131 Icon = Beagle.Images.GetPixbuf ("system-search.png");
133 DefaultWidth = 700;
134 DefaultHeight = 550;
135 DeleteEvent += OnWindowDelete;
137 VBox vbox = new VBox ();
138 vbox.Spacing = 3;
140 uim = new UIManager (this);
141 uim.ScopeChanged += OnScopeChanged;
142 uim.SortChanged += OnSortChanged;
143 uim.ToggleDetails += OnToggleDetails;
144 uim.ShowQuickTips += OnShowQuickTips;
145 vbox.PackStart (uim.MenuBar, false, false, 0);
147 HBox padding_hbox = new HBox ();
149 HBox hbox = new HBox (false, 6);
151 Label label = new Label (Catalog.GetString ("_Find:"));
152 hbox.PackStart (label, false, false, 0);
154 entry = new Entry ();
155 label.MnemonicWidget = entry;
156 uim.FocusSearchEntry += delegate () { entry.GrabFocus (); };
157 entry.Activated += OnEntryActivated;
158 entry.Changed += OnEntryChanged;
159 entry.MoveCursor += OnEntryMoveCursor;
160 hbox.PackStart (entry, true, true, 0);
162 button = new Gtk.Button ();
163 Gtk.HBox button_hbox = new Gtk.HBox (false, 2);
164 Gtk.Image icon = new Gtk.Image (Gtk.Stock.Find, Gtk.IconSize.Button);
165 button_hbox.PackStart (icon, false, false, 0);
166 label = new Gtk.Label (Catalog.GetString ("Find Now"));
167 button_hbox.PackStart (label, false, false, 0);
168 button.Add (button_hbox);
169 button.Clicked += OnButtonClicked;
171 Gtk.VBox buttonVBox = new Gtk.VBox (false, 0);
172 buttonVBox.PackStart (button, true, false, 0);
173 hbox.PackStart (buttonVBox, false, false, 0);
175 spinner = new Spinner ();
177 hbox.PackStart (spinner, false, false, 0);
179 padding_hbox.PackStart (hbox, true, true, 9);
181 vbox.PackStart (padding_hbox, false, true, 6);
183 pages = new Gtk.Notebook ();
184 pages.ShowTabs = false;
185 pages.ShowBorder = false;
186 pages.BorderWidth = 3;
187 vbox.PackStart (pages, true, true, 0);
189 quicktips = new Pages.QuickTips ();
190 quicktips.Show ();
191 pages.Add (quicktips);
193 rootuser = new Pages.RootUser ();
194 rootuser.Show ();
195 pages.Add (rootuser);
197 startdaemon = new Pages.StartDaemon ();
198 startdaemon.DaemonStarted += OnDaemonStarted;
199 startdaemon.Show ();
200 pages.Add (startdaemon);
202 panes = new Search.Panes ();
203 panes.Show ();
204 pages.Add (panes);
206 view = new GroupView ();
207 view.TileSelected += ShowInformation;
208 view.CategoryToggled += OnCategoryToggled;
209 panes.MainContents = view;
211 Add (vbox);
213 tips = new Gtk.Tooltips ();
214 tips.SetTip (entry, Catalog.GetString ("Type in search terms"), "");
215 tips.SetTip (button, Catalog.GetString ("Start searching"), "");
216 tips.Enable ();
218 if (Environment.UserName == "root" && ! Conf.Daemon.AllowRoot) {
219 pages.CurrentPage = pages.PageNum (rootuser);
220 entry.Sensitive = button.Sensitive = uim.Sensitive = false;
221 } else {
222 pages.CurrentPage = pages.PageNum (quicktips);
225 if (IconEnabled) {
226 tray = new Search.Tray.TrayIcon ();
227 tray.Clicked += OnTrayActivated;
228 tray.Search += OnTraySearch;
230 // Attach the hide/show keybinding
231 keybinder.Bind (Conf.Searching.ShowSearchWindowBinding.ToString (), OnTrayActivated);
232 } else {
233 ShowAll ();
237 private void SetWindowTitle (string query)
239 Title = String.Format ("Desktop Search: {0}", query);
242 // Whether we should grab focus from the text entry
243 private bool grab_focus;
245 private void Search (bool grab_focus)
247 if (timeout != 0) {
248 GLib.Source.Remove (timeout);
249 timeout = 0;
252 string query = queryText = entry.Text;
253 if (query == null || query == "")
254 return;
256 SetWindowTitle (query);
257 ShowInformation (null);
259 if (tray != null) {
260 tray.AddSearch (query);
263 filter = TypeFilter.MakeFilter (ref query);
265 view.Clear ();
266 view.Scope = scope;
267 view.Sort = sort;
268 pages.CurrentPage = pages.PageNum (panes);
270 this.grab_focus = grab_focus;
272 try {
273 if (currentQuery != null) {
274 currentQuery.HitsAddedEvent -= OnHitsAdded;
275 currentQuery.HitsSubtractedEvent -= OnHitsSubtracted;
276 currentQuery.Close ();
279 currentQuery = new Query ();
280 currentQuery.AddDomain (QueryDomain.Neighborhood);
282 // Don't search documentation by default
283 QueryPart_Property part = new QueryPart_Property ();
284 part.Logic = QueryPartLogic.Prohibited;
285 part.Type = PropertyType.Keyword;
286 part.Key = "beagle:Source";
287 part.Value = "documentation";
288 currentQuery.AddPart (part);
290 currentQuery.AddText (query);
291 currentQuery.HitsAddedEvent += OnHitsAdded;
292 currentQuery.HitsSubtractedEvent += OnHitsSubtracted;
293 currentQuery.FinishedEvent += OnFinished;
295 currentQuery.SendAsync ();
296 spinner.Start ();
297 } catch (Beagle.ResponseMessageException){
298 pages.CurrentPage = pages.PageNum (startdaemon);
299 } catch (Exception e) {
300 Console.WriteLine ("Querying the Beagle daemon failed: {0}", e.Message);
304 private void OnEntryActivated (object obj, EventArgs args)
306 Search (true);
309 private void OnDaemonStarted ()
311 Search (true);
314 private void OnEntryChanged (object obj, EventArgs args)
316 if (timeout != 0)
317 GLib.Source.Remove (timeout);
318 timeout = GLib.Timeout.Add (1000, OnEntryTimeout);
321 private void OnEntryMoveCursor (object obj, EventArgs args)
323 if (timeout != 0)
324 GLib.Source.Remove (timeout);
325 timeout = GLib.Timeout.Add (1000, OnEntryTimeout);
328 private bool OnEntryTimeout ()
330 timeout = 0;
331 Search (false);
332 return false;
335 private void OnButtonClicked (object obj, EventArgs args)
337 Search (true);
340 private void OnWindowDelete (object o, Gtk.DeleteEventArgs args)
342 if (IconEnabled) {
343 Hide ();
344 args.RetVal = true;
345 } else {
346 Gtk.Application.Quit ();
350 private void OnScopeChanged (Search.ScopeType toggled, bool active)
352 if (active)
353 view.Scope = scope = scope | toggled;
354 else
355 view.Scope = scope = scope ^ toggled;
357 CheckNoMatch ();
360 private void OnCategoryToggled (ScopeType toggled)
362 string name = ScopeType.GetName (typeof (ScopeType), toggled);
363 try {
364 ToggleAction act = (ToggleAction) uim.GetAction ("/ui/MenuBar/Search/Scope/" + name);
365 act.Active = ! act.Active;
367 catch (Exception ex) {
368 Console.WriteLine("Exception caught when trying to deactivate menu entry {0}:",name);
369 Console.WriteLine(ex);
370 return;
375 private void OnSortChanged (Search.SortType newSort)
377 view.Sort = sort = newSort;
380 private void OnToggleDetails (bool active)
382 showDetails = active;
383 if (panes.Details != null)
384 panes.ToggleDetails (showDetails);
385 else
386 panes.ToggleDetails (false);
389 private void OnShowQuickTips ()
391 if (currentQuery != null) {
392 currentQuery.HitsAddedEvent -= OnHitsAdded;
393 currentQuery.HitsSubtractedEvent -= OnHitsSubtracted;
394 currentQuery.Close ();
395 currentQuery = null;
398 pages.CurrentPage = pages.PageNum (quicktips);
401 private void ShowInformation (Tiles.Tile tile)
403 if (tile != null) {
404 panes.Details = tile.Details;
405 if (tile.Details != null)
406 panes.ToggleDetails (showDetails);
407 else
408 panes.ToggleDetails (false);
409 } else {
410 panes.Details = null;
411 panes.ToggleDetails (false);
415 private void OnFinished (FinishedResponse response)
417 spinner.Stop ();
418 view.Finished (grab_focus);
419 grab_focus = false;
421 CheckNoMatch ();
424 private void OnHitsAdded (HitsAddedResponse response)
426 foreach (Hit hit in response.Hits) {
427 Tile tile = TileActivatorOrg.MakeTile (hit, currentQuery);
428 if (tile == null)
429 continue;
431 if (filter != null && !filter.Filter (tile))
432 continue;
434 view.AddHit (tile);
435 if (pages.CurrentPageWidget != panes)
436 pages.CurrentPage = pages.PageNum (panes);
440 private void OnHitsSubtracted (HitsSubtractedResponse response)
442 foreach (Uri uri in response.Uris)
443 view.SubtractHit (uri);
445 CheckNoMatch ();
448 private void CheckNoMatch ()
450 MatchType matches = view.MatchState;
451 if (matches == MatchType.Matched) {
452 pages.CurrentPage = pages.PageNum (panes);
453 return;
456 if (nomatch != null)
457 nomatch.Destroy ();
458 nomatch = new Pages.NoMatch (queryText, matches == MatchType.NoneInScope);
459 nomatch.Show ();
460 pages.Add (nomatch);
461 pages.CurrentPage = pages.PageNum (nomatch);
464 /////////////////////////////////////
466 private void OnTrayActivated (object o, EventArgs args)
468 if (! Visible) {
469 base.ShowAll ();
470 base.Present ();
471 entry.GrabFocus ();
472 } else {
473 base.Hide ();
477 private void OnTraySearch (string query)
479 if (!Visible)
480 ShowAll ();
482 entry.Text = query;
483 Search (true);