All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.android.tools.idea.navigator.nodes.AndroidResGroupNode Maven / Gradle / Ivy

/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.tools.idea.navigator.nodes;

import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.google.common.collect.Lists;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.projectView.ProjectViewNode;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.fileEditor.OpenFileDescriptor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Queryable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiFile;
import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.PlatformIcons;
import org.jetbrains.android.facet.AndroidFacet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.List;

/** {@link AndroidResGroupNode} groups together all the configuration specific alternatives of a single resource. */
public class AndroidResGroupNode extends ProjectViewNode> implements DirectoryGroupNode, Comparable {
  @NotNull private final String myResName;
  @NotNull private final AndroidFacet myFacet;
  @NotNull private final List myFiles;

  public AndroidResGroupNode(@NotNull Project project,
                             @NotNull AndroidFacet facet,
                             @NotNull List files,
                             @NotNull String resName,
                             @NotNull ViewSettings settings) {
    super(project, files, settings);
    myResName = resName;
    myFacet = facet;
    myFiles = files;
  }

  @NotNull
  @Override
  public PsiDirectory[] getDirectories() {
    List psiFiles = getValue();
    PsiDirectory[] folders = new PsiDirectory[psiFiles.size()];
    for (int i = 0; i < psiFiles.size(); i++) {
      folders[i] = psiFiles.get(i).getParent();
    }
    return folders;
  }

  @Override
  public boolean contains(@NotNull VirtualFile file) {
    for (PsiFile psiFile : myFiles) {
      if (psiFile.getVirtualFile().equals(file)) {
        return true;
      }
    }

    return false;
  }

  @NotNull
  @Override
  public Collection getChildren() {
    List children = Lists.newArrayListWithExpectedSize(myFiles.size());
    for (PsiFile file : myFiles) {
      children.add(new AndroidResFileNode(myProject, file, getSettings(), myFacet));
    }
    return children;
  }

  @Override
  public int getWeight() {
    return 20; // same as PsiFileNode so that res group nodes are compared with resources only alphabetically
  }

  @Nullable
  @Override
  public Comparable getSortKey() {
    return this;
  }

  @Nullable
  @Override
  public Comparable getTypeSortKey() {
    return this;
  }

  @Override
  public int compareTo(@NotNull Object obj) {
    return AndroidResComparator.INSTANCE.compare(this, obj);
  }

  @NotNull
  public String getResName() {
    return myResName;
  }

  @Override
  public boolean expandOnDoubleClick() {
    return false;
  }

  @Override
  public boolean canNavigate() {
    return true;
  }

  @Override
  public void navigate(boolean requestFocus) {
    if (myFiles.isEmpty()) {
      return;
    }

    PsiFile fileToOpen = findFileToOpen(myFiles);
    if (fileToOpen == null) {
      return;
    }

    new OpenFileDescriptor(myProject, fileToOpen.getVirtualFile()).navigate(requestFocus);
  }

  /** Returns the best configuration of a particular resource given a set of multiple configurations of the same resource. */
  @Nullable
  private static PsiFile findFileToOpen(@NotNull List files) {
    PsiFile bestFile = null;
    FolderConfiguration bestConfig = null;

    for (PsiFile file : files) {
      PsiDirectory qualifiedDirectory = file.getParent();
      assert qualifiedDirectory != null : "Resource file's parent directory cannot be null";
      FolderConfiguration config = FolderConfiguration.getConfigForFolder(qualifiedDirectory.getName());

      if (bestConfig == null // first time through the loop
          || config == null  // FolderConfiguration is null for default configurations
          || config.compareTo(bestConfig) < 0) { // lower FolderConfiguration value than current best
        bestConfig = config;
        bestFile = file;
      }
    }

    return bestFile;
  }

  @Override
  protected void update(PresentationData presentation) {
    presentation.setPresentableText(myResName);
    presentation.addText(myResName, SimpleTextAttributes.REGULAR_ATTRIBUTES);
    if (myFiles.size() > 1) {
      presentation.addText(String.format(" (%1$d)", myFiles.size()), SimpleTextAttributes.GRAY_ATTRIBUTES);
    }
    presentation.setIcon(PlatformIcons.PACKAGE_ICON);
  }

  @Nullable
  @Override
  public String toTestString(@Nullable Queryable.PrintInfo printInfo) {
    StringBuilder sb = new StringBuilder(myResName);
    sb.append(" (");
    sb.append(myFiles.size());
    sb.append(")");
    return sb.toString();
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy