4 // Copyright (c) 2006 Novell, Inc.
8 using System
.Collections
;
20 public class MainWindow
: Window
{
22 private Gtk
.Button button
;
23 private Gtk
.Tooltips tips
;
24 private Gtk
.Notebook pages
;
26 private Search
.UIManager uim
;
27 private Search
.NotificationArea notification_area
;
28 private Search
.GroupView view
;
29 private Search
.Entry entry
;
30 private Search
.Spinner spinner
;
31 private Search
.Panes panes
;
32 private Search
.Tray
.TrayIcon tray
;
34 private Search
.Pages
.QuickTips quicktips
;
35 private Search
.Pages
.RootUser rootuser
;
36 private Search
.Pages
.StartDaemon startdaemon
;
37 private Search
.Pages
.NoMatch nomatch
;
41 private string query_text
;
42 private Beagle
.Query current_query
;
43 private Search
.ScopeType scope
= ScopeType
.Everything
;
44 private Search
.SortType sort
= SortType
.Modified
;
45 private Search
.TypeFilter filter
= null;
46 private bool show_details
= true;
48 private XKeybinder keybinder
= new XKeybinder ();
50 public static bool IconEnabled
= false;
52 public static void Main (string [] args
)
54 SystemInformation
.SetProcessName ("beagle-search");
56 Catalog
.Init ("beagle", ExternalStringsHack
.LocaleDir
);
58 string query
= ParseArgs (args
);
60 Gnome
.Program program
= new Gnome
.Program ("search", "0.0",
61 Gnome
.Modules
.UI
, args
);
63 MainWindow window
= new MainWindow ();
65 if (query
!= null && query
!= "" && !IconEnabled
) {
66 window
.entry
.Text
= query
;
73 private static string ParseArgs (String
[] args
)
78 while (i
< args
.Length
) {
90 if (! Conf
.Searching
.Autostart
) {
91 Console
.WriteLine ("beagle-search: Autostarting is disabled, not starting");
96 // Ignore session management
97 case "--sm-config-prefix":
98 case "--sm-client-id":
100 // These all take an argument, so
106 if (args
[i
].Length
< 2 || args
[i
].Substring (0, 2) != "--") {
107 if (query
.Length
!= 0)
120 public static void PrintUsageAndExit ()
123 "beagle-search: GUI interface to the Beagle search system.\n" +
124 "Web page: http://www.beagle-project.org/\n" +
125 "Copyright (C) 2005-2006 Novell, Inc.\n\n";
128 "Usage: beagle-search [OPTIONS] [<query string>]\n\n" +
130 " --help\t\t\tPrint this usage message.\n" +
131 " --icon\t\t\tAdd an icon to the notification area rather than opening a search window.\n";
133 Console
.WriteLine (usage
);
134 System
.Environment
.Exit (0);
137 public MainWindow () : base (WindowType
.Toplevel
)
139 Title
= Catalog
.GetString ("Desktop Search");
140 Icon
= Beagle
.Images
.GetPixbuf ("system-search.png");
144 DeleteEvent
+= OnWindowDelete
;
146 VBox vbox
= new VBox ();
149 uim
= new UIManager (this);
150 uim
.ScopeChanged
+= OnScopeChanged
;
151 uim
.SortChanged
+= OnSortChanged
;
152 uim
.ToggleDetails
+= OnToggleDetails
;
153 uim
.ShowQuickTips
+= OnShowQuickTips
;
154 vbox
.PackStart (uim
.MenuBar
, false, false, 0);
156 HBox hbox
= new HBox (false, 6);
158 Label label
= new Label (Catalog
.GetString ("_Find:"));
159 hbox
.PackStart (label
, false, false, 0);
161 entry
= new Entry ();
162 entry
.Activated
+= OnEntryActivated
;
163 hbox
.PackStart (entry
, true, true, 0);
165 label
.MnemonicWidget
= entry
;
166 uim
.FocusSearchEntry
+= delegate () { entry.GrabFocus (); }
;
168 // The auto search after timeout feauture is now optional
169 // and can be disabled.
170 if (Beagle
.Util
.Conf
.Searching
.BeagleSearchAutoSearch
) {
171 entry
.Changed
+= OnEntryChanged
;
172 entry
.MoveCursor
+= OnEntryMoveCursor
;
175 button
= new Gtk
.Button ();
176 Gtk
.HBox button_hbox
= new Gtk
.HBox (false, 2);
177 Gtk
.Image icon
= new Gtk
.Image (Gtk
.Stock
.Find
, Gtk
.IconSize
.Button
);
178 button_hbox
.PackStart (icon
, false, false, 0);
179 label
= new Gtk
.Label (Catalog
.GetString ("Find Now"));
180 button_hbox
.PackStart (label
, false, false, 0);
181 button
.Add (button_hbox
);
182 button
.Clicked
+= OnButtonClicked
;
184 Gtk
.VBox buttonVBox
= new Gtk
.VBox (false, 0);
185 buttonVBox
.PackStart (button
, true, false, 0);
186 hbox
.PackStart (buttonVBox
, false, false, 0);
188 spinner
= new Spinner ();
189 hbox
.PackStart (spinner
, false, false, 0);
191 HBox padding_hbox
= new HBox ();
192 padding_hbox
.PackStart (hbox
, true, true, 9);
193 vbox
.PackStart (padding_hbox
, false, true, 6);
195 VBox view_box
= new VBox (false, 3);
196 vbox
.PackStart (view_box
, true, true, 0);
198 HBox na_padding
= new HBox ();
199 view_box
.PackStart (na_padding
, false, true, 0);
201 notification_area
= new NotificationArea ();
202 na_padding
.PackStart (notification_area
, true, true, 3);
204 pages
= new Gtk
.Notebook ();
205 pages
.ShowTabs
= false;
206 pages
.ShowBorder
= false;
207 pages
.BorderWidth
= 3;
208 view_box
.PackStart (pages
, true, true, 0);
210 quicktips
= new Pages
.QuickTips ();
212 pages
.Add (quicktips
);
214 rootuser
= new Pages
.RootUser ();
216 pages
.Add (rootuser
);
218 startdaemon
= new Pages
.StartDaemon ();
219 startdaemon
.DaemonStarted
+= OnDaemonStarted
;
221 pages
.Add (startdaemon
);
223 panes
= new Search
.Panes ();
227 view
= new GroupView ();
228 view
.TileSelected
+= ShowInformation
;
229 view
.CategoryToggled
+= OnCategoryToggled
;
230 panes
.MainContents
= view
;
234 tips
= new Gtk
.Tooltips ();
235 tips
.SetTip (entry
, Catalog
.GetString ("Type in search terms"), "");
236 tips
.SetTip (button
, Catalog
.GetString ("Start searching"), "");
239 if (Environment
.UserName
== "root" && ! Conf
.Daemon
.AllowRoot
) {
240 pages
.CurrentPage
= pages
.PageNum (rootuser
);
241 entry
.Sensitive
= button
.Sensitive
= uim
.Sensitive
= false;
243 pages
.CurrentPage
= pages
.PageNum (quicktips
);
247 tray
= new Search
.Tray
.TrayIcon ();
248 tray
.Clicked
+= OnTrayActivated
;
249 tray
.Search
+= OnTraySearch
;
251 // Attach the hide/show keybinding
252 keybinder
.Bind (Conf
.Searching
.ShowSearchWindowBinding
.ToString (), OnTrayActivated
);
257 StartCheckingIndexingStatus ();
260 private void SetWindowTitle (string query
)
262 Title
= String
.Format ( Catalog
.GetString ("Desktop Search: {0}"), query
);
265 // Whether we should grab focus from the text entry
266 private bool grab_focus
;
268 private void Search (bool grab_focus
)
271 GLib
.Source
.Remove (timeout
);
275 string query
= query_text
= entry
.Text
;
276 if (query
== null || query
== "")
279 SetWindowTitle (query
);
280 ShowInformation (null);
283 tray
.AddSearch (query
);
286 filter
= TypeFilter
.MakeFilter (ref query
);
291 pages
.CurrentPage
= pages
.PageNum (panes
);
293 this.grab_focus
= grab_focus
;
296 if (current_query
!= null) {
297 current_query
.HitsAddedEvent
-= OnHitsAdded
;
298 current_query
.HitsSubtractedEvent
-= OnHitsSubtracted
;
299 current_query
.Close ();
302 current_query
= new Query ();
303 current_query
.AddDomain (QueryDomain
.Neighborhood
);
305 // Don't search documentation by default
306 QueryPart_Property part
= new QueryPart_Property ();
307 part
.Logic
= QueryPartLogic
.Prohibited
;
308 part
.Type
= PropertyType
.Keyword
;
309 part
.Key
= "beagle:Source";
310 part
.Value
= "documentation";
311 current_query
.AddPart (part
);
313 current_query
.AddText (query
);
314 current_query
.HitsAddedEvent
+= OnHitsAdded
;
315 current_query
.HitsSubtractedEvent
+= OnHitsSubtracted
;
316 current_query
.FinishedEvent
+= OnFinished
;
318 current_query
.SendAsync ();
320 } catch (Beagle
.ResponseMessageException
) {
321 pages
.CurrentPage
= pages
.PageNum (startdaemon
);
322 } catch (Exception e
) {
323 Console
.WriteLine ("Querying the Beagle daemon failed: {0}", e
.Message
);
327 private void OnEntryActivated (object obj
, EventArgs args
)
332 private void OnDaemonStarted ()
337 private void OnEntryChanged (object obj
, EventArgs args
)
340 GLib
.Source
.Remove (timeout
);
341 timeout
= GLib
.Timeout
.Add (1000, OnEntryTimeout
);
344 private void OnEntryMoveCursor (object obj
, EventArgs args
)
347 GLib
.Source
.Remove (timeout
);
348 timeout
= GLib
.Timeout
.Add (1000, OnEntryTimeout
);
351 private bool OnEntryTimeout ()
358 private void OnButtonClicked (object obj
, EventArgs args
)
363 private void OnWindowDelete (object o
, Gtk
.DeleteEventArgs args
)
369 Gtk
.Application
.Quit ();
373 private void OnScopeChanged (Search
.ScopeType toggled
, bool active
)
376 view
.Scope
= scope
= scope
| toggled
;
378 view
.Scope
= scope
= scope ^ toggled
;
383 private void OnCategoryToggled (ScopeType toggled
)
385 string name
= ScopeType
.GetName (typeof (ScopeType
), toggled
);
387 ToggleAction act
= (ToggleAction
) uim
.GetAction ("/ui/MenuBar/Search/Scope/" + name
);
388 act
.Active
= ! act
.Active
;
390 catch (Exception ex
) {
391 Console
.WriteLine("Exception caught when trying to deactivate menu entry {0}:",name
);
392 Console
.WriteLine(ex
);
398 private void OnSortChanged (Search
.SortType newSort
)
400 view
.Sort
= sort
= newSort
;
403 private void OnToggleDetails (bool active
)
405 show_details
= active
;
406 if (panes
.Details
!= null)
407 panes
.ToggleDetails (show_details
);
409 panes
.ToggleDetails (false);
412 private void OnShowQuickTips ()
414 if (current_query
!= null) {
415 current_query
.HitsAddedEvent
-= OnHitsAdded
;
416 current_query
.HitsSubtractedEvent
-= OnHitsSubtracted
;
417 current_query
.Close ();
418 current_query
= null;
421 pages
.CurrentPage
= pages
.PageNum (quicktips
);
424 private void ShowInformation (Tiles
.Tile tile
)
427 panes
.Details
= tile
.Details
;
428 if (tile
.Details
!= null)
429 panes
.ToggleDetails (show_details
);
431 panes
.ToggleDetails (false);
433 panes
.Details
= null;
434 panes
.ToggleDetails (false);
438 private void OnFinished (FinishedResponse response
)
441 view
.Finished (grab_focus
);
447 private void OnHitsAdded (HitsAddedResponse response
)
449 foreach (Hit hit
in response
.Hits
) {
450 Tile tile
= TileActivatorOrg
.MakeTile (hit
, current_query
);
454 if (filter
!= null && !filter
.Filter (tile
))
458 if (pages
.CurrentPageWidget
!= panes
)
459 pages
.CurrentPage
= pages
.PageNum (panes
);
463 private void OnHitsSubtracted (HitsSubtractedResponse response
)
465 foreach (Uri uri
in response
.Uris
)
466 view
.SubtractHit (uri
);
471 private void CheckNoMatch ()
473 MatchType matches
= view
.MatchState
;
474 if (matches
== MatchType
.Matched
) {
475 pages
.CurrentPage
= pages
.PageNum (panes
);
481 nomatch
= new Pages
.NoMatch (query_text
, matches
== MatchType
.NoneInScope
);
484 pages
.CurrentPage
= pages
.PageNum (nomatch
);
487 /////////////////////////////////////
489 private void OnTrayActivated (object o
, EventArgs args
)
500 private void OnTraySearch (string query
)
509 //////////////////////////////////////
511 private void StartCheckingIndexingStatus ()
513 InformationalMessagesRequest msg_request
= new InformationalMessagesRequest ();
514 msg_request
.IndexingStatusEvent
+= OnIndexingStatusEvent
;
515 msg_request
.SendAsync ();
518 private void OnIndexingStatusEvent (IndexingStatus status
)
520 if (status
== IndexingStatus
.Running
) {
521 NotificationMessage m
= new NotificationMessage ();
522 m
.Icon
= Gtk
.Stock
.DialogInfo
;
523 m
.Title
= Catalog
.GetString ("Beagle is indexing your data");
524 m
.Message
= Catalog
.GetString ("The Beagle service is in the process of indexing your data. Search results may be incomplete until indexing has finished.");
525 notification_area
.Display (m
);
527 notification_area
.Hide ();