public int subfilesCount() {
   int c = 0;
   for (DirectoryAdapter.Node n : this.children) {
     if (n.isFile() == true) c++;
   }
   return c;
 }
 public int subfolderCount() {
   int c = 0;
   for (DirectoryAdapter.Node n : this.children) {
     if (n.isFile() == false && n.name != "..") c++;
   }
   return c;
 }
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
    DirectoryAdapter.Node selectedNode = mCurrentNode.children.get(position);
    DirectoryViewHolder holder;
    View v = convertView;

    Context context = VLCApplication.getAppContext();

    /* If view not created */
    if (v == null) {
      v = mInflater.inflate(R.layout.directory_view_item, parent, false);
      holder = new DirectoryViewHolder();
      holder.layout = v.findViewById(R.id.layout_item);
      holder.title = (TextView) v.findViewById(R.id.title);
      holder.text = (TextView) v.findViewById(R.id.text);
      holder.icon = (ImageView) v.findViewById(R.id.dvi_icon);
      v.setTag(holder);
    } else holder = (DirectoryViewHolder) v.getTag();

    Util.setItemBackground(holder.layout, position);

    String holderText = "";
    if (selectedNode.isFile()) {
      Log.d(TAG, "Loading media " + selectedNode.name);
      Media m = new Media(getMediaLocation(position), false);
      holder.title.setText(m.getTitle());
      holderText = m.getSubtitle();
    } else holder.title.setText(selectedNode.getVisibleName());

    if (selectedNode.name == "..") holderText = context.getString(R.string.parent_folder);
    else if (!selectedNode.isFile()) {
      int folderCount = selectedNode.subfolderCount();
      int mediaFileCount = selectedNode.subfilesCount();
      holderText = "";

      if (folderCount > 0)
        holderText +=
            context
                .getResources()
                .getQuantityString(R.plurals.subfolders_quantity, folderCount, folderCount);
      if (folderCount > 0 && mediaFileCount > 0) holderText += ", ";
      if (mediaFileCount > 0)
        holderText +=
            context
                .getResources()
                .getQuantityString(R.plurals.mediafiles_quantity, mediaFileCount, mediaFileCount);
    }
    holder.text.setText(holderText);
    if (selectedNode.isFile()) holder.icon.setImageResource(R.drawable.icon);
    else holder.icon.setImageResource(R.drawable.ic_folder);

    return v;
  }
  public boolean browse(String directoryName) {
    if (this.mCurrentDir == null) {
      // We're on the storage list
      String storages[] = Util.getMediaDirectories();
      for (String storage : storages) {
        storage = Util.stripTrailingSlash(storage);
        if (storage.endsWith(directoryName)) {
          this.mCurrentRoot = storage;
          this.mCurrentDir = storage;
          this.mCurrentDir = Util.stripTrailingSlash(this.mCurrentDir);
          break;
        }
      }
    } else {
      try {
        this.mCurrentDir =
            new URI(Util.PathToURI(this.mCurrentDir + "/" + directoryName)).normalize().getPath();
        this.mCurrentDir = Util.stripTrailingSlash(this.mCurrentDir);

        if (this.mCurrentDir.equals(getParentDir(this.mCurrentRoot))) {
          // Returning on the storage list
          this.mCurrentDir = null;
          this.mCurrentRoot = null;
        }
      } catch (URISyntaxException e) {
        Log.e(TAG, "URISyntaxException in browse()", e);
        return false;
      } catch (NullPointerException e) {
        Log.e(TAG, "NullPointerException in browse()", e);
        return false;
      }
    }

    Log.d(TAG, "Browsing to " + this.mCurrentDir);

    if (directoryName.equals("..")) this.mCurrentNode = this.mCurrentNode.parent;
    else {
      this.mCurrentNode = this.mCurrentNode.getChildNode(directoryName);
      if (mCurrentNode.subfolderCount() < 1) {
        // Clear the ".." entry
        this.mCurrentNode.children.clear();
        this.populateNode(mCurrentNode, mCurrentDir);
      }
    }

    this.notifyDataSetChanged();
    return true;
  }
 public void addChildNode(DirectoryAdapter.Node n) {
   n.parent = this;
   this.children.add(n);
 }
 public boolean isChildFile(int position) {
   DirectoryAdapter.Node selectedNode = mCurrentNode.children.get(position);
   return selectedNode.isFile();
 }
 public boolean browse(int position) {
   DirectoryAdapter.Node selectedNode = mCurrentNode.children.get(position);
   if (selectedNode.isFile()) return false;
   return browse(selectedNode.name);
 }
  /**
   * @param n Node to populate
   * @param path Path to populate
   * @param depth Depth of iteration (0 = 1st level of nesting, 1 = 2 level of nesting, etc)
   */
  private void populateNode(DirectoryAdapter.Node n, String path, int depth) {
    if (path == null) {
      // We're on the storage list
      String storages[] = Util.getMediaDirectories();
      for (String storage : storages) {
        File f = new File(storage);
        DirectoryAdapter.Node child = new DirectoryAdapter.Node(f.getName(), getVisibleName(f));
        child.isFile = false;
        this.populateNode(child, storage, 0);
        n.addChildNode(child);
      }
      return;
    }

    File file = new File(path);
    if (!file.exists() || !file.isDirectory()) return;

    ArrayList<String> files = new ArrayList<String>();
    LibVLC.nativeReadDirectory(path, files);
    StringBuilder sb = new StringBuilder(100);
    /* If no sub-directories or I/O error don't crash */
    if (files == null || files.size() < 1) {
      // return
    } else {
      for (int i = 0; i < files.size(); i++) {
        String filename = files.get(i);
        /* Avoid infinite loop */
        if (filename.equals(".") || filename.equals("..") || filename.startsWith(".")) continue;

        DirectoryAdapter.Node nss = new DirectoryAdapter.Node(filename);
        nss.isFile = false;
        sb.append(path);
        sb.append("/");
        sb.append(filename);
        String newPath = sb.toString();
        sb.setLength(0);

        // Don't try to go beyond depth 10 as a safety measure.
        if (LibVLC.nativeIsPathDirectory(newPath) && depth < 10) {
          ArrayList<String> files_int = new ArrayList<String>();
          LibVLC.nativeReadDirectory(newPath, files_int);
          if (files_int.size() < 8) {
              /* Optimisation: If there are more than 8
              sub-folders, don't scan each one, otherwise
              when scaled it is very slow to load */
            String mCurrentDir_old = mCurrentDir;
            mCurrentDir = path;
            this.populateNode(nss, newPath, depth + 1);
            mCurrentDir = mCurrentDir_old;
          }
        } else {
          if (acceptedPath(newPath)) nss.setIsFile();
          else continue;
        }

        n.addChildNode(nss);
      }
      Collections.sort(n.children);
    }

    DirectoryAdapter.Node up = new DirectoryAdapter.Node("..");
    n.children.add(0, up);
  }