Forgot to bump FSQ version. Weekend syndrome.
[beagle.git] / search / Search.cs
blob7279fd4b11dd1c2f438d3d89ccfcaf498a9c6cbf
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 private static bool icon_enabled = 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 != "" && !icon_enabled) {
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 icon_enabled = 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 hbox.PackStart (entry, true, true, 0);
159 button = new Gtk.Button ();
160 Gtk.HBox button_hbox = new Gtk.HBox (false, 2);
161 Gtk.Image icon = new Gtk.Image (Gtk.Stock.Find, Gtk.IconSize.Button);
162 button_hbox.PackStart (icon, false, false, 0);
163 label = new Gtk.Label (Catalog.GetString ("Find Now"));
164 button_hbox.PackStart (label, false, false, 0);
165 button.Add (button_hbox);
166 button.Clicked += OnButtonClicked;
168 Gtk.VBox buttonVBox = new Gtk.VBox (false, 0);
169 buttonVBox.PackStart (button, true, false, 0);
170 hbox.PackStart (buttonVBox, false, false, 0);
172 spinner = new Spinner ();
174 hbox.PackStart (spinner, false, false, 0);
176 padding_hbox.PackStart (hbox, true, true, 9);
178 vbox.PackStart (padding_hbox, false, true, 6);
180 pages = new Gtk.Notebook ();
181 pages.ShowTabs = false;
182 pages.ShowBorder = false;
183 vbox.PackStart (pages, true, true, 0);
185 quicktips = new Pages.QuickTips ();
186 quicktips.Show ();
187 pages.Add (quicktips);
189 rootuser = new Pages.RootUser ();
190 rootuser.Show ();
191 pages.Add (rootuser);
193 startdaemon = new Pages.StartDaemon ();
194 startdaemon.DaemonStarted += OnDaemonStarted;
195 startdaemon.Show ();
196 pages.Add (startdaemon);
198 panes = new Search.Panes ();
199 panes.Show ();
200 pages.Add (panes);
202 view = new GroupView ();
203 view.TileSelected += ShowInformation;
204 panes.MainContents = view;
206 Add (vbox);
208 tips = new Gtk.Tooltips ();
209 tips.SetTip (entry, Catalog.GetString ("Type in search terms"), "");
210 tips.SetTip (button, Catalog.GetString ("Start searching"), "");
211 tips.Enable ();
213 if (Environment.UserName == "root" && ! Conf.Daemon.AllowRoot) {
214 pages.CurrentPage = pages.PageNum (rootuser);
215 entry.Sensitive = button.Sensitive = uim.Sensitive = false;
216 } else {
217 pages.CurrentPage = pages.PageNum (quicktips);
220 if (icon_enabled) {
221 tray = new TrayIcon ();
222 tray.Clicked += OnTrayActivated;
223 tray.Search += OnTraySearch;
225 // Attach the hide/show keybinding
226 keybinder.Bind (Conf.Searching.ShowSearchWindowBinding.ToString (), OnTrayActivated);
227 } else {
228 ShowAll ();
232 Gtk.Widget oldFocus;
234 private void SetWindowTitle (string query)
236 Title = String.Format ("Desktop Search: {0}", query);
239 private void Search (bool grabFocus)
241 if (timeout != 0) {
242 GLib.Source.Remove (timeout);
243 timeout = 0;
246 string query = queryText = entry.Text;
247 if (query == null || query == "")
248 return;
250 SetWindowTitle (query);
251 ShowInformation (null);
253 if (tray != null) {
254 tray.AddSearch (query);
257 filter = TypeFilter.MakeFilter (ref query);
259 view.Clear ();
260 view.Scope = scope;
261 view.Sort = sort;
262 pages.CurrentPage = pages.PageNum (panes);
264 if (grabFocus)
265 oldFocus = Focus;
267 try {
268 if (currentQuery != null) {
269 currentQuery.HitsAddedEvent -= OnHitsAdded;
270 currentQuery.HitsSubtractedEvent -= OnHitsSubtracted;
271 currentQuery.Close ();
274 currentQuery = new Query ();
275 currentQuery.AddDomain (QueryDomain.Neighborhood);
277 // Don't search documentation by default
278 QueryPart_Property part = new QueryPart_Property ();
279 part.Logic = QueryPartLogic.Prohibited;
280 part.Type = PropertyType.Keyword;
281 part.Key = "beagle:Source";
282 part.Value = "documentation";
283 currentQuery.AddPart (part);
285 currentQuery.AddText (query);
286 currentQuery.HitsAddedEvent += OnHitsAdded;
287 currentQuery.HitsSubtractedEvent += OnHitsSubtracted;
288 currentQuery.FinishedEvent += OnFinished;
290 currentQuery.SendAsync ();
291 spinner.Start ();
292 } catch (Beagle.ResponseMessageException e){
293 pages.CurrentPage = pages.PageNum (startdaemon);
294 } catch (Exception e) {
295 Console.WriteLine ("Querying the Beagle daemon failed: {0}", e.Message);
299 private void OnEntryActivated (object obj, EventArgs args)
301 Search (true);
304 private void OnDaemonStarted ()
306 Search (true);
309 private void OnEntryChanged (object obj, EventArgs args)
311 if (timeout != 0)
312 GLib.Source.Remove (timeout);
313 timeout = GLib.Timeout.Add (1000, OnEntryTimeout);
316 private bool OnEntryTimeout ()
318 timeout = 0;
319 Search (false);
320 return false;
323 private void OnButtonClicked (object obj, EventArgs args)
325 Search (true);
328 private void OnWindowDelete (object o, Gtk.DeleteEventArgs args)
330 if (icon_enabled) {
331 Hide ();
332 args.RetVal = true;
333 } else {
334 Gtk.Application.Quit ();
338 private void OnScopeChanged (Search.ScopeType newScope)
340 view.Scope = scope = newScope;
341 CheckNoMatch ();
344 private void OnSortChanged (Search.SortType newSort)
346 view.Sort = sort = newSort;
349 private void OnShowQuickTips ()
351 pages.CurrentPage = pages.PageNum (quicktips);
354 private void ShowInformation (Tiles.Tile tile)
356 if (tile != null)
357 panes.Details = tile.Details;
358 else
359 panes.Details = null;
362 private void OnFinished (FinishedResponse response)
364 spinner.Stop ();
365 view.Finished (oldFocus == Focus);
367 CheckNoMatch ();
370 private void OnHitsAdded (HitsAddedResponse response)
372 foreach (Hit hit in response.Hits) {
373 Tile tile = TileActivatorOrg.MakeTile (hit, currentQuery);
374 if (tile == null)
375 continue;
377 if (filter != null && !filter.Filter (tile))
378 continue;
380 view.AddHit (tile);
381 if (pages.CurrentPageWidget != panes)
382 pages.CurrentPage = pages.PageNum (panes);
386 private void OnHitsSubtracted (HitsSubtractedResponse response)
388 foreach (Uri uri in response.Uris)
389 view.SubtractHit (uri);
391 CheckNoMatch ();
394 private void CheckNoMatch ()
396 MatchType matches = view.MatchState;
397 if (matches == MatchType.Matched) {
398 pages.CurrentPage = pages.PageNum (panes);
399 return;
402 if (nomatch != null)
403 nomatch.Destroy ();
404 nomatch = new Pages.NoMatch (queryText, matches == MatchType.NoneInScope);
405 nomatch.Show ();
406 pages.Add (nomatch);
407 pages.CurrentPage = pages.PageNum (nomatch);
410 /////////////////////////////////////
412 private void OnTrayActivated (object o, EventArgs args)
414 if (! Visible) {
415 ShowAll ();
416 entry.GrabFocus ();
417 } else {
418 base.Hide ();
422 private void OnTraySearch (string query)
424 if (!Visible)
425 ShowAll ();
427 entry.Text = query;
428 Search (true);