# File lib/vimmatelib/files_window.rb, line 59
    def initialize(exclude_file_list = [])
      @open_signal = Set.new
      @menu_signal = Set.new
      @expander_signal = Set.new

      @filter_string = ""
      
      # Tree Store: Filename, Full path, Icon, Sort, Type, Status
      @gtk_tree_store = Gtk::TreeStore.new(String,
                                           String,
                                           Gdk::Pixbuf,
                                           String,
                                           Fixnum,
                                           String,
                                           FalseClass)
      @gtk_tree_store.set_sort_column_id(SORT)

      # Filtered Tree Store
      @gtk_filtered_tree_model = Gtk::TreeModelFilter.new(@gtk_tree_store)
      @gtk_filtered_tree_model.set_visible_func do |model, iter|
        if @filter_string.nil? or @filter_string.empty?
          true
        else
          iter[VISIBLE]
        end
      end
      
      # Tree View
      @gtk_tree_view = Gtk::TreeView.new(@gtk_filtered_tree_model)
      @gtk_tree_view.selection.mode = Gtk::SELECTION_SINGLE
      @gtk_tree_view.headers_visible = Config[:file_headers_visible]
      @gtk_tree_view.hover_selection = Config[:file_hover_selection]

      # Double-click, Enter, Space: Signal to open the file
      @gtk_tree_view.signal_connect("row-activated") do |view, path, column|
        path = @gtk_filtered_tree_model.get_iter(path)[PATH]
        @open_signal.each do |signal|
          signal.call(path,
                      Config[:files_default_open_in_tabs] ? :tab_open : :open)
        end
      end

      # Left-click: Select and Signal to open the menu
      @gtk_tree_view.signal_connect("button_press_event") do |widget, event|
        if event.kind_of? Gdk::EventButton and event.button == 3
          path = @gtk_tree_view.get_path_at_pos(event.x, event.y)
          @gtk_tree_view.selection.select_path(path[0]) if path

          selected = @gtk_tree_view.selection.selected
          if selected
            @menu_signal.each do |signal|
              signal.call(selected[PATH])
            end
          end
        end
      end

      # Create a label to show the path of the file
      gtk_label = Gtk::Label.new
      gtk_label.ellipsize = Pango::Layout::EllipsizeMode::START

      # When a selection is changed in the tree view, we change the label
      # to show the path of the file
      @gtk_tree_view.selection.signal_connect("changed") do
        gtk_label.text = ""
        next if (selected_row = @gtk_tree_view.selection.selected).nil?
        gtk_label.text = File.join(File.dirname(selected_row[PATH]), selected_row[NAME])
      end
      
      # Same thing as Left-click, but with the keyboard
      @gtk_tree_view.signal_connect("popup_menu") do
        selected = @gtk_tree_view.selection.selected
        if selected
          @menu_signal.each do |signal|
            signal.call(selected[PATH])
          end
        end
      end

      # Separator between directories
      @gtk_tree_view.set_row_separator_func do |model, iter|
        iter[TYPE] == TYPE_SEPARATOR
      end

      # Add the columns
      column = Gtk::TreeViewColumn.new
      column.title = "Files"

      # Icon
      icon_cell_renderer = Gtk::CellRendererPixbuf.new
      column.pack_start(icon_cell_renderer, false)
      column.set_attributes(icon_cell_renderer, :pixbuf => ICON)

      # File name
      text_cell_renderer = Gtk::CellRendererText.new
      if Config[:files_use_ellipsis]
        text_cell_renderer.ellipsize = Pango::Layout::EllipsizeMode::MIDDLE
      end
      column.pack_start(text_cell_renderer, true)
      column.set_attributes(text_cell_renderer, :text => NAME)
      
      # Status
      if Config[:files_show_status]
        text_cell_renderer2 = Gtk::CellRendererText.new
        if Config[:files_use_ellipsis]
          text_cell_renderer2.ellipsize = Pango::Layout::EllipsizeMode::END
        end
        column.pack_start(text_cell_renderer2, true)
        column.set_attributes(text_cell_renderer2, :text => STATUS)
      end
      
      @gtk_tree_view.append_column(column)
      
      # Put the tree view in a scroll window
      @gtk_scrolled_window = Gtk::ScrolledWindow.new
      @gtk_scrolled_window.set_policy(Gtk::POLICY_AUTOMATIC,
                                      Gtk::POLICY_AUTOMATIC)
      @gtk_scrolled_window.add(@gtk_tree_view)
      
      # Set the default size for the file list
      @gtk_scrolled_window.set_size_request(Config[:files_opened_width], -1)

      # Create a box to filter the list
      gtk_filter_box = Gtk::HBox.new
      gtk_filter_box.pack_start(gtk_filter_button = Gtk::ToggleButton.new("Filter"), false, false)
      gtk_filter_box.pack_start(@gtk_file_filter_entry = Gtk::Entry.new, true, true)
      changed_lambda = lambda do
        if gtk_filter_button.active?
          self.filter = @gtk_file_filter_entry.text
        else
          self.clear_filter
        end
      end
      @gtk_file_filter_entry.signal_connect("changed", &changed_lambda)
      gtk_filter_button.signal_connect("toggled", &changed_lambda)
      gtk_filter_button.active = Config[:files_filter_active]
      gtk_filter_box.spacing = 10
      gtk_filter_box.border_width = 10

      # Create the file tree
      initialize_file_tree(exclude_file_list)
      
      gtk_top_box = Gtk::VBox.new
      gtk_top_box.pack_start(gtk_filter_box, false, false)
      gtk_top_box.pack_start(@gtk_scrolled_window, true, true)
      gtk_top_box.pack_start(gtk_label, false, false)

      # Create the search file list if it's enabled
      if Config[:files_use_search]
        @gtk_paned_box = Gtk::VPaned.new
        @gtk_paned_box.add(gtk_top_box)
        @gtk_paned_box.add((@search_window = SearchWindow.new(@file_tree)).gtk_window)
        @gtk_paned_box.position = Config[:files_search_separator_position]

        # Set the signals for the search window
        @search_window.add_open_signal do |path, kind|
          @open_signal.each do |signal|
            signal.call(path, kind)
          end
        end
        @search_window.add_menu_signal do |path|
          @menu_signal.each do |signal|
            signal.call(path)
          end
        end
      end

      
      @gtk_expander = Gtk::Expander.new("File list")
      @gtk_expander.expanded = Config[:files_expanded]
      if Config[:files_use_search]
        @gtk_expander.add(@gtk_paned_box)
      else
        @gtk_expander.add(gtk_top_box)
      end
      @gtk_expander.signal_connect("notify::expanded") do
        @expander_signal.each do |signal|
          signal.call(@gtk_expander.expanded?)
        end
      end

      gtk_window.border_width = 5

      @file_tree_mutex = Mutex.new
    end