use of com.android.ide.common.res2.ResourceItem in project android by JetBrains.
the class ThemeEditorStyle method setValue.
/**
* Sets the value of given attribute in all possible folders where this style is defined. If attribute or value can be used from certain API level,
* folders below that level won't be modified, instead new folder with certain API will be created.
* Note: {@link LocalResourceRepository}'s won't get updated immediately
*
* @param attribute the style attribute name
* @param value the style attribute value
*/
public void setValue(@NotNull final String attribute, @NotNull final String value) {
if (!isProjectStyle()) {
throw new UnsupportedOperationException("Non project styles can not be modified");
}
final Project project = myManager.getProject();
int maxApi = Math.max(ResolutionUtils.getOriginalApiLevel(value, myManager.getProject()), ResolutionUtils.getOriginalApiLevel(attribute, project));
int minSdk = ThemeEditorUtils.getMinApiLevel(myManager.getModule());
// When api level of both attribute and value is not greater that Minimum SDK,
// we should modify every FolderConfiguration, thus we set desiredApi to -1
final int desiredApi = (maxApi <= minSdk) ? -1 : maxApi;
new WriteCommandAction.Simple(project, "Setting value of " + attribute) {
@Override
protected void run() {
// Makes the command global even if only one xml file is modified
// That way, the Undo is always available from the theme editor
CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
Collection<FolderConfiguration> toBeCopied = findToBeCopied(desiredApi);
for (FolderConfiguration configuration : toBeCopied) {
XmlTag styleTag = findXmlTagFromConfiguration(configuration);
assert styleTag != null;
ThemeEditorUtils.copyTheme(desiredApi, styleTag);
}
if (!toBeCopied.isEmpty()) {
// We need to refreshResource, to get all copied styles
// Otherwise, LocalResourceRepositories won't get updated, so we won't get copied styles
AndroidFacet facet = AndroidFacet.getInstance(myManager.getModule());
if (facet != null) {
facet.refreshResources();
// This is because the ResourceFolderRepository may initialize through the file instead of Psi.
GradleBuildInvoker.saveAllFilesSafely();
}
}
Collection<ResourceItem> styleItems = getStyleResourceItems();
for (ResourceItem style : styleItems) {
FolderConfiguration configuration = style.getConfiguration();
int version = ThemeEditorUtils.getVersionFromConfiguration(configuration);
// it means than we can modify 'attribute' to value 'value'.
if (version >= desiredApi) {
setValue(configuration, attribute, value);
}
}
}
}.execute();
}
use of com.android.ide.common.res2.ResourceItem in project android by JetBrains.
the class ThemeEditorStyle method getParentName.
/**
* @param configuration FolderConfiguration of the style to lookup
* @return parent this style with a FolderConfiguration configuration
*/
@Nullable
public /*if there is no of this style*/
String getParentName(@NotNull FolderConfiguration configuration) {
if (isFramework()) {
IAndroidTarget target = myManager.getHighestApiTarget();
assert target != null;
com.android.ide.common.resources.ResourceItem styleItem = myManager.getResolverCache().getFrameworkResources(new FolderConfiguration(), target).getResourceItem(ResourceType.STYLE, getName());
for (ResourceFile file : styleItem.getSourceFileList()) {
if (file.getConfiguration().equals(configuration)) {
StyleResourceValue style = (StyleResourceValue) file.getValue(ResourceType.STYLE, getName());
return ResolutionUtils.getParentQualifiedName(style);
}
}
throw new IllegalArgumentException("bad folder config " + configuration);
}
for (final ResourceItem styleItem : getStyleResourceItems()) {
if (configuration.equals(styleItem.getConfiguration())) {
StyleResourceValue style = (StyleResourceValue) styleItem.getResourceValue(false);
assert style != null;
return ResolutionUtils.getParentQualifiedName(style);
}
}
throw new IllegalArgumentException("bad folder config " + configuration);
}
use of com.android.ide.common.res2.ResourceItem in project android by JetBrains.
the class ThemeEditorStyle method findToBeCopied.
/**
* Finds best to be copied {@link FolderConfiguration}s
* e.g if style is defined in "port-v8", "port-v18", "port-v22", "night-v20" and desiredApi = 21,
* then result is {"port-v18", "night-v20"}
*
* @param desiredApi new api level of {@link FolderConfiguration}s after being copied
* @return Collection of FolderConfigurations which are going to be copied to version desiredApi
*/
@NotNull
private ImmutableCollection<FolderConfiguration> findToBeCopied(int desiredApi) {
// Keeps closest VersionQualifier to 'desiredApi'
// e.g. desiredApi = 21, "en-port", "en-port-v18", "en-port-v19", "en-port-v22" then
// bestVersionCopyFrom will contain {"en-port" -> v19}, as it is closest one to v21
final HashMap<FolderConfiguration, VersionQualifier> bestVersionCopyFrom = Maps.newHashMap();
for (ResourceItem styleItem : getStyleResourceItems()) {
FolderConfiguration configuration = FolderConfiguration.copyOf(styleItem.getConfiguration());
int styleItemVersion = ThemeEditorUtils.getVersionFromConfiguration(configuration);
// We want to get the best from port-v19 port-v20 port-v23. so we need to remove the version qualifier to compare them
configuration.setVersionQualifier(null);
if (styleItemVersion > desiredApi) {
// Thus, we don't need to copy it, we are going to just modify it.
continue;
}
// If 'version' is closer to 'desiredApi' than we have found
if (!bestVersionCopyFrom.containsKey(configuration) || bestVersionCopyFrom.get(configuration).getVersion() < styleItemVersion) {
bestVersionCopyFrom.put(configuration, new VersionQualifier(styleItemVersion));
}
}
ImmutableList.Builder<FolderConfiguration> toBeCopied = ImmutableList.builder();
for (FolderConfiguration key : bestVersionCopyFrom.keySet()) {
FolderConfiguration configuration = FolderConfiguration.copyOf(key);
VersionQualifier version = bestVersionCopyFrom.get(key);
if (version.getVersion() != -1) {
configuration.setVersionQualifier(version);
}
// Version can't be bigger as we have filtered above
if (version.getVersion() < desiredApi) {
toBeCopied.add(configuration);
}
}
return toBeCopied.build();
}
use of com.android.ide.common.res2.ResourceItem in project android by JetBrains.
the class ThemeEditorStyle method removeAttribute.
/**
* Deletes an attribute of that particular style from all the relevant xml files
*/
public void removeAttribute(@NotNull final String attribute) {
if (!isProjectStyle()) {
throw new UnsupportedOperationException("Non project styles can not be modified");
}
final Project project = myManager.getProject();
Collection<PsiFile> toBeEdited = new HashSet<PsiFile>();
final Collection<XmlTag> toBeRemoved = new HashSet<XmlTag>();
for (ResourceItem resourceItem : getStyleResourceItems()) {
final XmlTag sourceXml = LocalResourceRepository.getItemTag(project, resourceItem);
assert sourceXml != null;
final XmlTag tag = getValueTag(sourceXml, attribute);
if (tag != null) {
toBeEdited.add(tag.getContainingFile());
toBeRemoved.add(tag);
}
}
new WriteCommandAction.Simple(project, "Removing " + attribute, toBeEdited.toArray(new PsiFile[toBeEdited.size()])) {
@Override
protected void run() {
// Makes the command global even if only one xml file is modified
// That way, the Undo is always available from the theme editor
CommandProcessor.getInstance().markCurrentCommandAsGlobal(project);
for (XmlTag tag : toBeRemoved) {
tag.delete();
}
}
}.execute();
}
use of com.android.ide.common.res2.ResourceItem in project android by JetBrains.
the class ThemeEditorStyle method getValues.
/**
* @param configuration FolderConfiguration of the style to lookup
* @return all values defined in this style with a FolderConfiguration configuration
*/
@NotNull
public Collection<ItemResourceValue> getValues(@NotNull FolderConfiguration configuration) {
if (isFramework()) {
IAndroidTarget target = myManager.getHighestApiTarget();
assert target != null;
com.android.ide.common.resources.ResourceItem styleItem = myManager.getResolverCache().getFrameworkResources(new FolderConfiguration(), target).getResourceItem(ResourceType.STYLE, getName());
for (ResourceFile file : styleItem.getSourceFileList()) {
if (file.getConfiguration().equals(configuration)) {
StyleResourceValue style = (StyleResourceValue) file.getValue(ResourceType.STYLE, getName());
return style.getValues();
}
}
throw new IllegalArgumentException("bad folder config " + configuration);
}
for (final ResourceItem styleItem : getStyleResourceItems()) {
if (configuration.equals(styleItem.getConfiguration())) {
StyleResourceValue style = (StyleResourceValue) styleItem.getResourceValue(false);
if (style == null) {
// style might be null if the value fails to parse
continue;
}
return style.getValues();
}
}
throw new IllegalArgumentException("bad folder config " + configuration);
}
Aggregations