2
// Author: John Luke <jluke@cfl.rr.com>
3
// Author: Inigo Illan <kodeport@terra.es>
6
// Copyright 2004 John Luke
10
using System.Collections;
11
using System.Diagnostics;
15
using MonoDevelop.Core.Properties;
16
using MonoDevelop.Core.Services;
17
using MonoDevelop.Gui.Utils;
18
using MonoDevelop.Services;
20
namespace MonoDevelop.Gui.Widgets
22
public delegate void DirectoryChangedEventHandler (string path);
24
private enum PerformingTask
31
public class FileBrowser : VBox
33
public DirectoryChangedEventHandler DirectoryChangedEvent;
34
private static GLib.GType gtype;
36
private Gtk.TreeView tv;
37
private Gtk.ScrolledWindow scrolledwindow;
38
private Gtk.Button upbutton, homebutton;
39
private Gtk.Entry entry;
40
private IMessageService messageService;
41
private Gtk.CellRendererText text_render;
42
private ListStore store;
43
private string currentDir;
44
private bool ignoreHidden = true;
45
private bool init = false;
47
private PerformingTask performingtask = PerformingTask.None;
48
private ArrayList files = new ArrayList ();
49
private Hashtable hiddenfolders = new Hashtable ();
51
PropertyService PropertyService = (PropertyService) ServiceManager.GetService (typeof (PropertyService));
53
public FileBrowser () : base (GType)
55
if (!Vfs.Initialized) {
59
messageService = (IMessageService) ServiceManager.GetService (typeof (IMessageService));
61
scrolledwindow = new ScrolledWindow ();
62
scrolledwindow.VscrollbarPolicy = PolicyType.Automatic;
63
scrolledwindow.HscrollbarPolicy = PolicyType.Automatic;
65
homebutton = new Button ();
66
homebutton.Add (new Image (Stock.Home, IconSize.SmallToolbar));
67
homebutton.Relief = ReliefStyle.None;
68
homebutton.Clicked += new EventHandler (OnHomeClicked);
70
upbutton = new Button ();
71
upbutton.Add (new Image (Stock.GoUp, IconSize.SmallToolbar));
72
upbutton.Relief = ReliefStyle.None;
73
upbutton.Clicked += new EventHandler (OnUpClicked);
76
entry.Activated += new EventHandler (OnEntryActivated);
78
Toolbar toolbar = new Toolbar ();
79
toolbar.AppendWidget (upbutton, GettextCatalog.GetString ("Up one level"), GettextCatalog.GetString ("Up one level"));
80
toolbar.AppendWidget (homebutton, GettextCatalog.GetString ("Home"), GettextCatalog.GetString ("Home"));
81
toolbar.AppendWidget (entry, GettextCatalog.GetString ("Location"), GettextCatalog.GetString ("Location"));
83
IProperties p = (IProperties) PropertyService.GetProperty ("SharpDevelop.UI.SelectStyleOptions", new DefaultProperties ());
84
ignoreHidden = !p.GetProperty ("MonoDevelop.Gui.FileScout.ShowHidden", false);
86
tv = new Gtk.TreeView ();
89
TreeViewColumn directorycolumn = new TreeViewColumn ();
90
directorycolumn.Title = "Directories";
92
CellRendererPixbuf pix_render = new CellRendererPixbuf ();
93
directorycolumn.PackStart (pix_render, false);
94
directorycolumn.AddAttribute (pix_render, "pixbuf", 0);
96
text_render = new CellRendererText ();
97
text_render.Edited += new EditedHandler (OnDirEdited);
98
directorycolumn.PackStart (text_render, false);
99
directorycolumn.AddAttribute (text_render, "text", 1);
101
tv.AppendColumn (directorycolumn);
103
store = new ListStore (typeof (Gdk.Pixbuf), typeof (string));
104
CurrentDir = Environment.GetEnvironmentVariable ("HOME");
107
tv.RowActivated += new RowActivatedHandler (OnRowActivated);
108
tv.ButtonReleaseEvent += new ButtonReleaseEventHandler (OnButtonRelease);
109
tv.PopupMenu += new PopupMenuHandler (OnPopupMenu);
111
scrolledwindow.Add (tv);
112
this.Homogeneous = false;
113
this.PackStart (toolbar, false, false, 0);
114
this.PackStart (scrolledwindow);
119
// FIXME: we should watch the PropertyChanged event instead
120
// of exposing the set part
121
public bool IgnoreHidden
123
get { return ignoreHidden; }
125
/* for some reasont his code crashes (NullReferenceException on the Populate() call
126
if (ignoreHidden != value) {
127
ignoreHidden = value;
128
// redraw folder list
129
System.Console.WriteLine("before poplate call");
134
ignoreHidden = value;
139
public string CurrentDir
141
get { return currentDir; }
143
currentDir = System.IO.Path.GetFullPath (value);
144
GetListOfHiddenFolders ();
147
if (DirectoryChangedEvent != null) {
148
DirectoryChangedEvent (CurrentDir);
153
public string[] Files
156
return (string[]) files.ToArray (typeof (string));
160
public static new GLib.GType GType
164
if (gtype == GLib.GType.Invalid)
165
gtype = RegisterGType (typeof (FileBrowser));
170
public void SelectFirst ()
172
tv.Selection.SelectPath (new TreePath ("0"));
179
// FIXME: never turns back on
180
if (System.IO.Path.GetPathRoot (CurrentDir) == CurrentDir)
181
upbutton.Sensitive = false;
182
else if (upbutton.Sensitive == false)
183
upbutton.Sensitive = true;
185
DirectoryInfo di = new DirectoryInfo (CurrentDir);
186
DirectoryInfo[] dirs = di.GetDirectories ();
188
foreach (DirectoryInfo d in dirs)
192
if (!d.Name.StartsWith (".") && NotHidden(d.Name))
193
store.AppendValues (FileIconLoader.GetPixbufForFile (System.IO.Path.Combine (CurrentDir, d.Name), 24, 24), d.Name);
197
store.AppendValues (FileIconLoader.GetPixbufForFile (System.IO.Path.Combine (CurrentDir, d.Name), 24, 24), d.Name);
202
tv.Selection.SelectPath (new Gtk.TreePath ("0"));
204
entry.Text = CurrentDir;
205
string[] filesaux = Directory.GetFiles (CurrentDir);
208
for (int cont = 0; cont < filesaux.Length; cont++)
212
if (NotHidden (System.IO.Path.GetFileName(filesaux[cont])))
214
files.Add (filesaux[cont]);
219
files.Add (filesaux[cont]);
224
private void OnRowActivated (object o, RowActivatedArgs args)
227
store.GetIter (out iter, args.Path);
228
string file = (string) store.GetValue (iter, 1);
229
string newDir = System.IO.Path.Combine (currentDir, file);
231
if (Directory.Exists (newDir))
237
private void OnButtonRelease (object o, ButtonReleaseEventArgs args)
239
if (args.Event.Button == 3)
245
private void OnPopupMenu (object o, PopupMenuArgs args)
250
private void ShowPopup ()
252
Menu menu = new Menu ();
253
MenuItem openfilebrowser = new MenuItem (GettextCatalog.GetString ("Open with file browser"));
254
openfilebrowser.Activated += new EventHandler (OpenFileBrowser);
256
MenuItem openterminal = new MenuItem (GettextCatalog.GetString ("Open with terminal"));
257
openterminal.Activated += new EventHandler (OpenTerminal);
259
MenuItem rename = new MenuItem (GettextCatalog.GetString ("Rename"));
260
rename.Activated += new EventHandler (OnDirRename);
262
MenuItem delete = new MenuItem (GettextCatalog.GetString ("Delete"));
263
delete.Activated += new EventHandler (OnDirDelete);
265
MenuItem newfolder = new MenuItem (GettextCatalog.GetString ("Create new folder"));
266
newfolder.Activated += new EventHandler (OnNewDir);
268
menu.Append (newfolder);
269
menu.Append (new MenuItem ());
270
menu.Append (delete);
271
menu.Append (rename);
272
menu.Append (new MenuItem ());
273
menu.Append (openterminal);
274
menu.Append (openfilebrowser);
275
menu.Popup (null, null, null, IntPtr.Zero, 3, Global.CurrentEventTime);
279
private void OpenFileBrowser (object o, EventArgs args)
283
// FIXME: look in GConf for the settings
284
// but strangely there is not one
285
string commandline = "nautilus \"";
287
if (tv.Selection.GetSelected (out model, out iter))
289
string selection = (string) store.GetValue (iter, 1);
290
commandline += System.IO.Path.Combine (currentDir, selection) + "\"";
291
Process.Start (commandline);
295
private void OpenTerminal (object o, EventArgs args)
299
// FIXME: look in GConf for the settings
300
// but the args will be terminal dependent
301
// leaving as hardcoded for now
302
string commandline = "gnome-terminal --working-directory=\"";
303
if (tv.Selection.GetSelected (out model, out iter))
305
string selection = (string) store.GetValue (iter, 1);
306
commandline += System.IO.Path.Combine (currentDir, selection) + "\"";
307
Process.Start (commandline);
311
private void OnUpClicked (object o, EventArgs args)
313
if (System.IO.Path.GetPathRoot (CurrentDir) != CurrentDir)
314
CurrentDir = System.IO.Path.Combine (CurrentDir, "..");
317
private void OnHomeClicked (object o, EventArgs args)
319
CurrentDir = Environment.GetEnvironmentVariable ("HOME");
322
private void OnEntryActivated (object sender, EventArgs args)
324
if (Directory.Exists (entry.Text.Trim ()))
325
CurrentDir = entry.Text;
328
messageService.ShowError (null, String.Format (GettextCatalog.GetString ("Cannot enter '{0}' folder"), entry.Text));
332
private void OnDirRename (object o, EventArgs args)
335
TreeViewColumn column;
337
performingtask = PerformingTask.Renaming;
338
text_render.Editable = true;
340
tv.GetCursor (out treepath, out column);
342
tv.SetCursor (treepath, column, true);
345
private void OnDirEdited (object o, EditedArgs args)
347
text_render.Editable = false;
349
switch (performingtask)
351
case PerformingTask.Renaming:
353
tv.Model.IterNthChild (out iter, Int32.Parse (args.Path));
354
string oldpath = (string) store.GetValue (iter, 1);
356
if (oldpath != args.NewText)
360
System.IO.Directory.Move (System.IO.Path.Combine(CurrentDir, oldpath), System.IO.Path.Combine(CurrentDir, args.NewText));
364
messageService.ShowError (ex, String.Format (GettextCatalog.GetString ("Could not rename folder '{0}' to '{1}'"), oldpath, args.NewText));
374
case PerformingTask.CreatingNew:
375
System.IO.DirectoryInfo dirinfo = new DirectoryInfo (CurrentDir);
378
dirinfo.CreateSubdirectory(args.NewText);
382
messageService.ShowError (ex, String.Format (GettextCatalog.GetString ("Could not create new folder '{0}'"), args.NewText));
392
Console.WriteLine ("This should not be happening");
396
performingtask = PerformingTask.None;
399
private void OnDirDelete (object o, EventArgs args)
404
if (messageService.AskQuestion (GettextCatalog.GetString ("Are you sure you want to delete this folder?"), GettextCatalog.GetString ("Delete folder")))
406
if (tv.Selection.GetSelected (out model, out iter))
410
Directory.Delete (System.IO.Path.Combine (CurrentDir, (string) store.GetValue (iter, 1)), true);
414
messageService.ShowError (ex, String.Format (GettextCatalog.GetString ("Could not delete folder '{0}'"), System.IO.Path.Combine (CurrentDir, (string) store.GetValue (iter, 1))));
424
// FIXME: When the scrollbars of the directory list
425
// are shown, and we perform a new dir action
426
// the column is never edited, but Populate is called
427
private void OnNewDir (object o, EventArgs args)
431
TreeViewColumn column;
433
performingtask = PerformingTask.CreatingNew;
434
text_render.Editable = true;
436
tv.Reorderable = false;
437
iter = store.AppendValues (FileIconLoader.GetPixbufForFile (CurrentDir, 24, 24), "folder name");
438
treepath = tv.Model.GetPath(iter);
440
column = tv.GetColumn (0);
441
tv.SetCursor (treepath, column, true);
444
private void GetListOfHiddenFolders ()
446
hiddenfolders.Clear ();
448
if (System.IO.File.Exists (CurrentDir + System.IO.Path.DirectorySeparatorChar + ".hidden"))
450
StreamReader stream = new StreamReader (CurrentDir + System.IO.Path.DirectorySeparatorChar + ".hidden");
451
string foldertohide = stream.ReadLine ();
453
while (foldertohide != null)
455
hiddenfolders.Add (foldertohide, foldertohide);
456
foldertohide = stream.ReadLine ();
463
private Boolean NotHidden (string folder)
465
return !hiddenfolders.Contains (folder);