Jakub Niedermertl has uploaded a new change for review.

Change subject: userportal: Vm Icons - userportal part
......................................................................

userportal: Vm Icons - userportal part

http://www.ovirt.org/Features/VM_Icons

* Customizable icons rendered in Extended VMs list, Extended Templates
  list, Basic list and Basic details view
* Icons are downloaded before the lists are rendered

Change-Id: I5d1b2e313aac9640950919e4c4cb41eb247913a3
Signed-off-by: Jakub Niedermertl <jnied...@redhat.com>
Bug-Url: https://bugzilla.redhat.com/1103175
---
A 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/AbstractImageCell.java
A 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/DataurlImageCell.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/ImageResourceCell.java
A 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/AbstractDataurlImageColumn.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/IconUtils.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/PoolItemBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalBasicListModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalItemModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalListModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalTemplateListModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/VmItemBehavior.java
M 
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicDetailsView.java
M 
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicDetailsView.ui.xml
M 
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicListItemView.java
M 
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicListItemView.ui.xml
M 
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/extended/SideTabExtendedTemplateView.java
M 
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/extended/SideTabExtendedVirtualMachineView.java
A 
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/basic/IconImage.java
D 
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/basic/OsTypeImage.java
M 
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/table/column/AbstractMaskedVmImageColumn.java
A 
frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/table/column/AbstractUserportalMaskedDataurlImageColumn.java
22 files changed, 413 insertions(+), 140 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/20/40320/3

diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/AbstractImageCell.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/AbstractImageCell.java
new file mode 100644
index 0000000..cf969ee
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/AbstractImageCell.java
@@ -0,0 +1,45 @@
+package org.ovirt.engine.ui.common.widget.table.cell;
+
+import org.ovirt.engine.ui.common.widget.table.HasStyleClass;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.safehtml.client.SafeHtmlTemplates;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+
+public abstract class AbstractImageCell<T> extends AbstractCell<T> implements 
HasStyleClass {
+
+    interface CellTemplate extends SafeHtmlTemplates {
+        @Template("<div id=\"{0}\" style=\"{1}\" class=\"{2}\">{3}</div>")
+        SafeHtml imageContainerWithStyleClass(String id, String style, String 
styleClass, SafeHtml imageHtml);
+    }
+
+    private String style = "line-height: 100%; text-align: center; 
vertical-align: middle;"; //$NON-NLS-1$
+    private String styleClass = ""; //$NON-NLS-1$
+
+    private CellTemplate template = GWT.create(CellTemplate.class);
+
+    protected abstract SafeHtml getRenderedImage(T value);
+
+    @Override
+    public void render(Context context, T value, SafeHtmlBuilder sb, String 
id) {
+        if (value != null) {
+            final SafeHtml renderedImage = getRenderedImage(value);
+            sb.append(template.imageContainerWithStyleClass(
+                    id,
+                    style,
+                    styleClass,
+                    renderedImage));
+        }
+    }
+
+    public void setStyle(String style) {
+        this.style = style;
+    }
+
+    @Override
+    public void setStyleClass(String styleClass) {
+        this.styleClass = styleClass == null ? "" : styleClass; //$NON-NLS-1$
+    }
+
+}
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/DataurlImageCell.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/DataurlImageCell.java
new file mode 100644
index 0000000..4377f6b
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/DataurlImageCell.java
@@ -0,0 +1,22 @@
+package org.ovirt.engine.ui.common.widget.table.cell;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.safehtml.client.SafeHtmlTemplates;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeUri;
+import com.google.gwt.safehtml.shared.UriUtils;
+
+public class DataurlImageCell extends AbstractImageCell<String> {
+
+    interface ImageTemplate extends SafeHtmlTemplates {
+        @Template("<img src='{0}' />")
+        SafeHtml image(SafeUri dataurl);
+    }
+
+    private ImageTemplate template = GWT.create(ImageTemplate.class);
+
+    @Override
+    protected SafeHtml getRenderedImage(String imageDataurl) {
+        return template.image(UriUtils.fromTrustedString(imageDataurl));
+    }
+}
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/ImageResourceCell.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/ImageResourceCell.java
index e7a66f6..5db2919 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/ImageResourceCell.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/cell/ImageResourceCell.java
@@ -1,48 +1,16 @@
 package org.ovirt.engine.ui.common.widget.table.cell;
 
-import org.ovirt.engine.ui.common.widget.table.HasStyleClass;
-
-import com.google.gwt.core.client.GWT;
 import com.google.gwt.resources.client.ImageResource;
-import com.google.gwt.safehtml.client.SafeHtmlTemplates;
 import com.google.gwt.safehtml.shared.SafeHtml;
-import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
-import com.google.gwt.safehtml.shared.SafeHtmlUtils;
 import com.google.gwt.user.client.ui.AbstractImagePrototype;
 
 /**
  * Cell that renders an ImageResource. Supports setting a style / class. 
Supports tooltips.
  */
-public class ImageResourceCell extends AbstractCell<ImageResource> implements 
HasStyleClass {
-
-    interface CellTemplate extends SafeHtmlTemplates {
-        @Template("<div id=\"{0}\" style=\"{1}\" class=\"{2}\">{3}</div>")
-        SafeHtml imageContainerWithStyleClass(String id, String style, String 
styleClass, SafeHtml imageHtml);
-    }
-
-    private String style = "line-height: 100%; text-align: center; 
vertical-align: middle;"; //$NON-NLS-1$
-    private String styleClass = ""; //$NON-NLS-1$
-
-    private CellTemplate template = GWT.create(CellTemplate.class);
+public class ImageResourceCell extends AbstractImageCell<ImageResource>  {
 
     @Override
-    public void render(Context context, ImageResource value, SafeHtmlBuilder 
sb, String id) {
-        if (value != null) {
-            sb.append(template.imageContainerWithStyleClass(
-                    id,
-                    style,
-                    styleClass,
-                    
SafeHtmlUtils.fromTrustedString(AbstractImagePrototype.create(value).getHTML())));
-        }
+    protected SafeHtml getRenderedImage(ImageResource value) {
+        return AbstractImagePrototype.create(value).getSafeHtml();
     }
-
-    public void setStyle(String style) {
-        this.style = style;
-    }
-
-    @Override
-    public void setStyleClass(String styleClass) {
-        this.styleClass = styleClass == null ? "" : styleClass; //$NON-NLS-1$
-    }
-
 }
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/AbstractDataurlImageColumn.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/AbstractDataurlImageColumn.java
new file mode 100644
index 0000000..7d3d26d
--- /dev/null
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/table/column/AbstractDataurlImageColumn.java
@@ -0,0 +1,11 @@
+package org.ovirt.engine.ui.common.widget.table.column;
+
+
+import org.ovirt.engine.ui.common.widget.table.cell.DataurlImageCell;
+
+public abstract class AbstractDataurlImageColumn<T> extends AbstractColumn<T, 
String> {
+
+    public AbstractDataurlImageColumn() {
+        super(new DataurlImageCell());
+    }
+}
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/IconUtils.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/IconUtils.java
index a88c806..100d64c 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/IconUtils.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/IconUtils.java
@@ -1,8 +1,17 @@
 package org.ovirt.engine.ui.uicommonweb;
 
+import org.ovirt.engine.core.common.businessentities.Nameable;
+import org.ovirt.engine.core.common.businessentities.VM;
+import 
org.ovirt.engine.core.common.businessentities.comparators.NameableComparator;
+import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
 import org.ovirt.engine.ui.uicommonweb.models.vms.IconCache;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
 
 public class IconUtils {
 
@@ -26,4 +35,37 @@
                 ? icon
                 : null;
     }
+
+    public static void prefetchIcons(Collection<VM> vmsAndPoolRepresentants,
+            boolean smallIcons,
+            boolean largeIcons,
+            IconCache.IconsCallback callback) {
+        final List<Guid> iconIdsToPrefetch = 
extractSmallIconIds(vmsAndPoolRepresentants, smallIcons, largeIcons);
+        IconCache.getInstance().getOrFetchIcons(iconIdsToPrefetch, callback);
+    }
+
+    private static List<Guid> extractSmallIconIds(Collection<VM> vms, boolean 
smallIcons, boolean largeIcons) {
+        final List<Guid> result = new ArrayList<>();
+        for (VM vm: vms) {
+            if (smallIcons) {
+                result.add(vm.getStaticData().getSmallIconId());
+            }
+            if (largeIcons) {
+                result.add(vm.getStaticData().getLargeIconId());
+            }
+        }
+        return result;
+    }
+
+    public static Comparator<Pair<? extends Nameable, ?>> 
getFirstComponentNameableComparator() {
+        return new Comparator<Pair<? extends Nameable, ?>>() {
+
+            private final NameableComparator firstComponentComparator =  new 
NameableComparator();
+
+            @Override public int compare(Pair<? extends Nameable, ?> o1, 
Pair<? extends Nameable, ?> o2) {
+                return firstComponentComparator.compare(
+                        o1.getFirst(), o2.getFirst());
+            }
+        };
+    }
 }
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java
index c333265..f1ca6d0 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java
@@ -56,6 +56,7 @@
 import org.ovirt.engine.core.common.scheduling.PolicyUnit;
 import org.ovirt.engine.core.common.scheduling.PolicyUnitType;
 import org.ovirt.engine.core.common.utils.ObjectUtils;
+import org.ovirt.engine.core.common.utils.Pair;
 import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.core.compat.StringHelper;
 import org.ovirt.engine.core.compat.Version;
@@ -799,6 +800,7 @@
         return result;
     }
 
+    @SafeVarargs
     public static <T> List<T> concat(List<T>... lists) {
         return concatUnsafe(lists);
     }
@@ -829,6 +831,25 @@
         return result;
     }
 
+    public static <U, V> List<Pair<U, V>> zip(List<U> objects, List<V> vms) {
+        if (objects.size() != vms.size()) {
+            throw new RuntimeException("Zip called on lists of different 
lengths"); //$NON-NLS-1$
+        }
+        final List<Pair<U, V>> result = new ArrayList<>();
+        for (int i = 0; i < objects.size(); i++) {
+            result.add(new Pair<>(objects.get(i), vms.get(i)));
+        }
+        return result;
+    }
+
+    public static <U, V> List<Pair<U, V>> wrapAsFirst(List<U> list, Class<V> 
secondComponentClass) {
+        final List<Pair<U, V>> result = new ArrayList<>();
+        for (U object : list) {
+            result.add(new Pair<>(object, (V) null));
+        }
+        return result;
+    }
+
     public static StorageDomain getStorageById(Guid storageId, 
ArrayList<StorageDomain> storageDomains) {
         for (StorageDomain storage : storageDomains) {
             if (storage.getId().equals(storageId)) {
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/PoolItemBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/PoolItemBehavior.java
index edd4e7a..693b3bb 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/PoolItemBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/PoolItemBehavior.java
@@ -29,9 +29,15 @@
     // this has to be static because in every request a new instance of this 
class is created
     private static Map<Guid, Integer> poolToOsType = new HashMap<Guid, 
Integer>();
 
-    public PoolItemBehavior(UserPortalItemModel item)
+    private VM poolRepresentant;
+
+    /**
+     * @see UserPortalItemModel#UserPortalItemModel(Object, VmConsoles, VM)
+     */
+    public PoolItemBehavior(UserPortalItemModel item, VM poolRepresentant)
     {
         super(item);
+        this.poolRepresentant = poolRepresentant;
     }
 
     @Override
@@ -95,26 +101,34 @@
             getItem().setOsId(poolToOsType.get(entity.getVmPoolId()));
         }
 
-        Frontend.getInstance().runQuery(VdcQueryType.GetVmDataByPoolId,
-                new IdQueryParameters(entity.getVmPoolId()),
-                new AsyncQuery(this,
-                        new INewAsyncCallback() {
-                            @Override
-                            public void onSuccess(Object target, Object 
returnValue) {
+        if (poolRepresentant != null) {
+            updatePropertiesFromPoolRepresentant(poolRepresentant);
+            poolRepresentant = null;
+        } else {
+            Frontend.getInstance().runQuery(VdcQueryType.GetVmDataByPoolId,
+                    new IdQueryParameters(entity.getVmPoolId()),
+                    new AsyncQuery(this, new INewAsyncCallback() {
+                        @Override
+                        public void onSuccess(Object target, Object 
returnValue) {
 
-                                PoolItemBehavior behavior = (PoolItemBehavior) 
target;
-                                if (returnValue != null)
-                                {
-                                    VM vm = (VM) ((VdcQueryReturnValue) 
returnValue).getReturnValue();
-                                    if (vm == null) {
-                                        return;
-                                    }
-                                    UserPortalItemModel model = 
behavior.getItem();
-                                    model.setOsId(vm.getVmOsId());
-                                    poolToOsType.put(((VmPool) 
model.getEntity()).getVmPoolId(), vm.getVmOsId());
+                            if (returnValue != null) {
+                                VM vm = (VM) ((VdcQueryReturnValue) 
returnValue).getReturnValue();
+                                if (vm == null) {
+                                    return;
                                 }
+                                updatePropertiesFromPoolRepresentant(vm);
                             }
-                        }));
+                        }
+                    }));
+        }
+    }
+
+    private void updatePropertiesFromPoolRepresentant(VM poolRepresentant) {
+        UserPortalItemModel model = getItem();
+        model.setOsId(poolRepresentant.getVmOsId());
+        
model.setSmallIconId(poolRepresentant.getStaticData().getSmallIconId());
+        
model.setLargeIconId(poolRepresentant.getStaticData().getLargeIconId());
+        poolToOsType.put(((VmPool) model.getEntity()).getVmPoolId(), 
poolRepresentant.getVmOsId());
     }
 
     private void updateActionAvailability()
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalBasicListModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalBasicListModel.java
index e3686ff..69077c6 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalBasicListModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalBasicListModel.java
@@ -5,18 +5,21 @@
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import org.ovirt.engine.core.common.businessentities.VM;
 import org.ovirt.engine.core.common.businessentities.VmPool;
-import 
org.ovirt.engine.core.common.businessentities.comparators.NameableComparator;
 import org.ovirt.engine.core.common.queries.IdQueryParameters;
 import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
 import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
 import org.ovirt.engine.core.common.queries.VdcQueryType;
+import org.ovirt.engine.core.common.utils.Pair;
+import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.ui.frontend.AsyncQuery;
 import org.ovirt.engine.ui.frontend.Frontend;
 import org.ovirt.engine.ui.frontend.INewAsyncCallback;
 import 
org.ovirt.engine.ui.uicommonweb.ConsoleOptionsFrontendPersister.ConsoleContext;
+import org.ovirt.engine.ui.uicommonweb.IconUtils;
 import org.ovirt.engine.ui.uicommonweb.Linq;
 import org.ovirt.engine.ui.uicommonweb.UICommand;
 import org.ovirt.engine.ui.uicommonweb.models.ConsoleModelsCache;
@@ -24,6 +27,7 @@
 import org.ovirt.engine.ui.uicommonweb.models.HasEntity;
 import org.ovirt.engine.ui.uicommonweb.models.Model;
 import org.ovirt.engine.ui.uicommonweb.models.VmConsoles;
+import org.ovirt.engine.ui.uicommonweb.models.vms.IconCache;
 import org.ovirt.engine.ui.uicommonweb.place.UserPortalApplicationPlaces;
 import org.ovirt.engine.ui.uicompat.ConstantsManager;
 import org.ovirt.engine.ui.uicompat.Event;
@@ -261,7 +265,7 @@
         if (getvms() != null && getpools() != null) {
             // Complete search.
             // Remove pools that has provided VMs.
-            ArrayList<VmPool> filteredPools = new ArrayList<VmPool>();
+            final ArrayList<VmPool> filteredPools = new ArrayList<VmPool>();
 
             for (VmPool pool : getpools()) {
                 int attachedVmsCount = 0;
@@ -276,11 +280,16 @@
                 }
             }
 
-            // Merge VMs and Pools, and create item models.
-            final List all = Linq.concatUnsafe(getvms(), filteredPools);
+            final List<Object> vms = 
Collections.<Object>unmodifiableList(getvms());
+            final List<Pair<Object, VM>> vmPairs = Linq.wrapAsFirst(vms, 
VM.class);
 
             if (filteredPools.isEmpty()) {
-                finishSearch(all);
+                IconUtils.prefetchIcons(getvms(), true, true, new 
IconCache.IconsCallback() {
+                    @Override public void onSuccess(Map<Guid, String> 
idToIconMap) {
+                        finishSearch(vmPairs);
+                    }
+                });
+
             } else { // if we have pools we have to update their console cache 
and THEN finish search
                 List<VdcQueryType> poolQueryList = new 
ArrayList<VdcQueryType>();
                 List<VdcQueryParametersBase> poolParamList = new 
ArrayList<VdcQueryParametersBase>();
@@ -301,22 +310,38 @@
                                     poolRepresentants.add((VM) 
poolRepresentant.getReturnValue());
                                 }
                                 
consoleModelsCache.updatePoolCache(poolRepresentants);
-                                finishSearch(all);
+                                final List<Pair<Object, VM>> poolsPairs =
+                                        
Linq.zip(Collections.<Object>unmodifiableList(filteredPools), 
poolRepresentants);
+                                final List<Pair<Object, VM>> all = 
Linq.concat(vmPairs, poolsPairs);
+                                final List<VM> vmsAndPoolRepresentants = 
Linq.concat(getvms(), poolRepresentants);
+                                
IconUtils.prefetchIcons(vmsAndPoolRepresentants, true, true,
+                                        new IconCache.IconsCallback() {
+                                    @Override public void onSuccess(Map<Guid, 
String> idToIconMap) {
+                                        finishSearch(all);
+                                    }
+                                });
                             }});
             }
         }
     }
 
-    private void finishSearch(List vmsAndFilteredPools) {
+    /**
+     * @param vmOrPoolAndPoolRepresentants the pair can be
+     *                                     <ul>
+     *                                     <li>either ({@link VM}, null)</li>
+     *                                     <li>or ({@link VmPool} pool, {@link 
VM} resolved pool representant)</li>
+     *                                     </ul>
+     */
+    private void finishSearch(List<Pair<Object, VM>> 
vmOrPoolAndPoolRepresentants) {
         consoleModelsCache.updateVmCache(getvms());
 
-        Collections.sort(vmsAndFilteredPools, new NameableComparator());
+        Collections.sort((List) vmOrPoolAndPoolRepresentants, 
IconUtils.getFirstComponentNameableComparator());
 
         ArrayList<Model> items = new ArrayList<Model>();
-        for (Object item : vmsAndFilteredPools) {
-            VmConsoles consoles = 
consoleModelsCache.getVmConsolesForEntity(item);
-            UserPortalItemModel model = new UserPortalItemModel(item, 
consoles);
-            model.setEntity(item);
+        for (Pair<Object, VM> item : vmOrPoolAndPoolRepresentants) {
+            VmConsoles consoles = 
consoleModelsCache.getVmConsolesForEntity(item.getFirst());
+            UserPortalItemModel model = new 
UserPortalItemModel(item.getFirst(), consoles, item.getSecond());
+            model.setEntity(item.getFirst());
             items.add(model);
         }
 
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalItemModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalItemModel.java
index 6661615..31c6959 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalItemModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalItemModel.java
@@ -26,6 +26,7 @@
 public class UserPortalItemModel extends EntityModel {
     private UICommand runCommand;
     private final VmConsoles vmConsoles;
+    private VM poolRepresentant;
 
     public UICommand getRunCommand()
     {
@@ -262,9 +263,43 @@
         }
     }
 
+    private Guid smallIconId;
+
+    public Guid getSmallIconId() {
+        return smallIconId;
+    }
+
+    public void setSmallIconId(Guid smallIconId) {
+        if (!Objects.equals(this.smallIconId, smallIconId)) {
+            this.smallIconId = smallIconId;
+            onPropertyChanged(new PropertyChangedEventArgs("SmallIconId")); 
//$NON-NLS-1$
+        }
+    }
+
+    private Guid largeIconId;
+
+    public Guid getLargeIconId() {
+        return largeIconId;
+    }
+
+    public void setLargeIconId(Guid largeIconId) {
+        if (!Objects.equals(this.largeIconId, largeIconId)) {
+            this.largeIconId = largeIconId;
+            onPropertyChanged(new PropertyChangedEventArgs("LargeIconId")); 
//$NON-NLS-1$
+        }
+    }
+
+
     private ItemBehavior behavior;
 
-    public UserPortalItemModel(Object vmOrPool, VmConsoles consoles) {
+    /**
+     *
+     * @param vmOrPool instance of either {@link VM} or {@link VmPool} - the 
wrapped entity
+     * @param poolRepresentant used if {@code vmOrPool} argument is instance 
of {@link VmPool};
+     *                         a pre-resolved pool representant for one-time 
use. Introduced to reduce
+     *                         number of queries for pool representants.
+     */
+    public UserPortalItemModel(Object vmOrPool, VmConsoles consoles, VM 
poolRepresentant) {
         setRunCommand(new UICommand("Run", this)); //$NON-NLS-1$
         setPauseCommand(new UICommand("Pause", this)); //$NON-NLS-1$
         setStopCommand(new UICommand("Stop", this)); //$NON-NLS-1$
@@ -278,6 +313,7 @@
         setCdImages(new ArrayList<ChangeCDModel>(Arrays.asList(new 
ChangeCDModel[] { tempVar })));
 
         this.vmConsoles = consoles;
+        this.poolRepresentant = poolRepresentant;
 
         setEntity(vmOrPool);
     }
@@ -292,7 +328,8 @@
         }
         else if (getEntity() instanceof VmPool)
         {
-            behavior = new PoolItemBehavior(this);
+            behavior = new PoolItemBehavior(this, poolRepresentant);
+            poolRepresentant = null;
         }
         else
         {
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalListModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalListModel.java
index c6dd57a..0ff689c 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalListModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalListModel.java
@@ -7,6 +7,8 @@
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
+
 import org.ovirt.engine.core.common.VdcActionUtils;
 import org.ovirt.engine.core.common.action.AddVmParameters;
 import org.ovirt.engine.core.common.action.AddVmTemplateParameters;
@@ -26,7 +28,6 @@
 import org.ovirt.engine.core.common.businessentities.VmPool;
 import org.ovirt.engine.core.common.businessentities.VmStatic;
 import org.ovirt.engine.core.common.businessentities.VmType;
-import 
org.ovirt.engine.core.common.businessentities.comparators.NameableComparator;
 import org.ovirt.engine.core.common.queries.IdQueryParameters;
 import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
 import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
@@ -39,6 +40,7 @@
 import org.ovirt.engine.ui.frontend.INewAsyncCallback;
 import org.ovirt.engine.ui.uicommonweb.Cloner;
 import 
org.ovirt.engine.ui.uicommonweb.ConsoleOptionsFrontendPersister.ConsoleContext;
+import org.ovirt.engine.ui.uicommonweb.IconUtils;
 import org.ovirt.engine.ui.uicommonweb.Linq;
 import org.ovirt.engine.ui.uicommonweb.UICommand;
 import org.ovirt.engine.ui.uicommonweb.builders.BuilderExecutor;
@@ -65,6 +67,7 @@
 import org.ovirt.engine.ui.uicommonweb.models.vms.CloneVmModel;
 import org.ovirt.engine.ui.uicommonweb.models.vms.ConsoleModel;
 import org.ovirt.engine.ui.uicommonweb.models.vms.DataCenterWithCluster;
+import org.ovirt.engine.ui.uicommonweb.models.vms.IconCache;
 import org.ovirt.engine.ui.uicommonweb.models.vms.RunOnceModel;
 import org.ovirt.engine.ui.uicommonweb.models.vms.UnitVmModel;
 import 
org.ovirt.engine.ui.uicommonweb.models.vms.UnitVmModelNetworkAsyncCallback;
@@ -1344,7 +1347,7 @@
             // Complete search.
 
             // Remove pools that has provided VMs.
-            ArrayList<VmPool> filteredPools = new ArrayList<VmPool>();
+            final ArrayList<VmPool> filteredPools = new ArrayList<VmPool>();
             for (VmPool pool : getpools()) {
                 // Add pool to map.
 
@@ -1360,11 +1363,15 @@
                 }
             }
 
-            // Merge VMs and Pools, and create item models.
-            final List all = Linq.concatUnsafe(getvms(), filteredPools);
+            final List<Object> vms = 
Collections.<Object>unmodifiableList(getvms());
+            final List<Pair<Object, VM>> vmPairs = Linq.wrapAsFirst(vms, 
VM.class);
 
             if (filteredPools.isEmpty()) {
-                finishSearch(all);
+                IconUtils.prefetchIcons(getvms(), true, false, new 
IconCache.IconsCallback() {
+                    @Override public void onSuccess(Map<Guid, String> 
idToIconMap) {
+                        finishSearch(vmPairs);
+                    }
+                });
             } else { // if we have pools we have to update their console cache 
and THEN finish search
                 List<VdcQueryType> poolQueryList = new 
ArrayList<VdcQueryType>();
                 List<VdcQueryParametersBase> poolParamList = new 
ArrayList<VdcQueryParametersBase>();
@@ -1385,22 +1392,32 @@
                                     poolRepresentants.add((VM) 
poolRepresentant.getReturnValue());
                                 }
                                 
consoleModelsCache.updatePoolCache(poolRepresentants);
-                                finishSearch(all);
-                            }});
+                                final List<Pair<Object, VM>> poolsPairs =
+                                        
Linq.zip(Collections.<Object>unmodifiableList(filteredPools), 
poolRepresentants);
+                                final List<Pair<Object, VM>> all = 
Linq.concat(vmPairs, poolsPairs);
+                                final List<VM> vmsAndPoolRepresentants = 
Linq.concat(getvms(), poolRepresentants);
+                                
IconUtils.prefetchIcons(vmsAndPoolRepresentants, true, false,
+                                        new IconCache.IconsCallback() {
+                                    @Override public void onSuccess(Map<Guid, 
String> idToIconMap) {
+                                        finishSearch(all);
+                                    }
+                                });
+                            }
+                        });
             }
         }
     }
 
-    private void finishSearch(List vmsAndFilteredPools) {
+    private void finishSearch(List<Pair<Object, VM>> 
vmOrPoolAndPoolRepresentants) {
         consoleModelsCache.updateVmCache(getvms());
 
-        Collections.sort(vmsAndFilteredPools, new NameableComparator());
+        Collections.sort((List) vmOrPoolAndPoolRepresentants, 
IconUtils.getFirstComponentNameableComparator());
 
         ArrayList<Model> items = new ArrayList<Model>();
-        for (Object item : vmsAndFilteredPools) {
-            VmConsoles consoles = 
consoleModelsCache.getVmConsolesForEntity(item);
-            UserPortalItemModel model = new UserPortalItemModel(item, 
consoles);
-            model.setEntity(item);
+        for (Pair<Object, VM> item : vmOrPoolAndPoolRepresentants) {
+            VmConsoles consoles = 
consoleModelsCache.getVmConsolesForEntity(item.getFirst());
+            UserPortalItemModel model = new 
UserPortalItemModel(item.getFirst(), consoles, item.getSecond());
+            model.setEntity(item.getFirst());
             items.add(model);
         }
 
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalTemplateListModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalTemplateListModel.java
index 22a8366..950c6e6 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalTemplateListModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalTemplateListModel.java
@@ -6,11 +6,13 @@
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
+import java.util.Map;
 
 import org.ovirt.engine.core.common.VdcActionUtils;
 import org.ovirt.engine.core.common.action.VdcActionType;
 import org.ovirt.engine.core.common.businessentities.VmTemplate;
 import org.ovirt.engine.core.common.businessentities.VmTemplateStatus;
+import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.ui.frontend.AsyncQuery;
 import org.ovirt.engine.ui.frontend.INewAsyncCallback;
 import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
@@ -22,6 +24,7 @@
 import org.ovirt.engine.ui.uicommonweb.models.templates.TemplateVmListModel;
 import 
org.ovirt.engine.ui.uicommonweb.models.templates.UserPortalTemplateDiskListModel;
 import 
org.ovirt.engine.ui.uicommonweb.models.templates.UserPortalTemplateEventListModel;
+import org.ovirt.engine.ui.uicommonweb.models.vms.IconCache;
 import org.ovirt.engine.ui.uicommonweb.models.vms.TemplateVmModelBehavior;
 import 
org.ovirt.engine.ui.uicommonweb.models.vms.UserPortalTemplateVmModelBehavior;
 
@@ -53,11 +56,29 @@
         AsyncDataProvider.getInstance().getAllVmTemplates(new AsyncQuery(this, 
new INewAsyncCallback() {
             @Override
             public void onSuccess(Object model, Object returnValue) {
-                ((UserPortalTemplateListModel) model).setItems((Collection) 
returnValue);
+                Collection<VmTemplate> vmTemplates = (Collection<VmTemplate>) 
returnValue;
+                prefetchIcons(vmTemplates);
             }
         }), getIsQueryFirstTime());
     }
 
+    private void prefetchIcons(final Collection<VmTemplate> vmTemplates) {
+        final List<Guid> iconIds = extractSmallIconIds(vmTemplates);
+        IconCache.getInstance().getOrFetchIcons(iconIds, new 
IconCache.IconsCallback() {
+            @Override public void onSuccess(Map<Guid, String> idToIconMap) {
+                setItems(vmTemplates);
+            }
+        });
+    }
+
+    private List<Guid> extractSmallIconIds(Collection<VmTemplate> vmTemplates) 
{
+        final List<Guid> result = new ArrayList<>();
+        for (VmTemplate template: vmTemplates) {
+            result.add(template.getSmallIconId());
+        }
+        return result;
+    }
+
     @Override
     protected void updateActionsAvailability() {
         VmTemplate item = (VmTemplate) getSelectedItem();
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/VmItemBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/VmItemBehavior.java
index ab5efba..2f73391 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/VmItemBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/VmItemBehavior.java
@@ -145,6 +145,8 @@
         getItem().setIsServer(entity.getVmType() == VmType.Server);
         getItem().setOsId(entity.getVmOsId());
         getItem().setIsFromPool(entity.getVmPoolId() != null);
+        getItem().setSmallIconId(entity.getStaticData().getSmallIconId());
+        getItem().setLargeIconId(entity.getStaticData().getLargeIconId());
     }
 
     private void updateActionAvailability() {
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicDetailsView.java
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicDetailsView.java
index 4496b40..97d222e 100644
--- 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicDetailsView.java
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicDetailsView.java
@@ -10,7 +10,7 @@
 import 
org.ovirt.engine.ui.userportal.section.main.presenter.tab.basic.MainTabBasicDetailsPresenterWidget;
 import org.ovirt.engine.ui.userportal.widget.ToStringEntityModelLabel;
 import org.ovirt.engine.ui.userportal.widget.basic.DisksImageWidget;
-import org.ovirt.engine.ui.userportal.widget.basic.OsTypeImage;
+import org.ovirt.engine.ui.userportal.widget.basic.IconImage;
 import org.ovirt.engine.ui.userportal.widget.basic.VmTypeImage;
 
 import com.google.gwt.core.client.GWT;
@@ -47,8 +47,8 @@
     }
 
     @UiField
-    @Path("selectedItem.osId")
-    OsTypeImage osImage;
+    @Path("selectedItem.smallIconId")
+    IconImage smallIconImage;
 
     @UiField
     @Path("selectedItem")
@@ -165,7 +165,7 @@
 
     @Override
     public void displayVmOsImages(boolean dispaly) {
-        osImage.setVisible(dispaly);
+        smallIconImage.setVisible(dispaly);
         vmImage.setVisible(dispaly);
     }
 
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicDetailsView.ui.xml
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicDetailsView.ui.xml
index 00f1334..9571ae5 100644
--- 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicDetailsView.ui.xml
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicDetailsView.ui.xml
@@ -178,7 +178,7 @@
         <g:north size='80'>
             <g:SimpleLayoutPanel addStyleNames="{style.detailsHeaderPanel}">
                 <g:FlowPanel>
-                    <e:OsTypeImage ui:field="osImage" 
addStyleNames="{style.osImage}" nameUniquePart="Small" />
+                    <e:IconImage ui:field="smallIconImage" 
addStyleNames="{style.osImage}" />
                     <e:VmTypeImage ui:field="vmImage" 
addStyleNames="{style.vmImage}"/>
 
                     <g:FlowPanel>
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicListItemView.java
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicListItemView.java
index 97855fb..515d937 100644
--- 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicListItemView.java
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicListItemView.java
@@ -11,9 +11,9 @@
 import org.ovirt.engine.ui.userportal.ApplicationResources;
 import org.ovirt.engine.ui.userportal.gin.AssetProvider;
 import 
org.ovirt.engine.ui.userportal.section.main.presenter.tab.basic.MainTabBasicListItemPresenterWidget;
+import org.ovirt.engine.ui.userportal.widget.basic.IconImage;
 import 
org.ovirt.engine.ui.userportal.widget.basic.MainTabBasicListItemActionButton;
 import 
org.ovirt.engine.ui.userportal.widget.basic.MainTabBasicListItemMessagesTranslator;
-import org.ovirt.engine.ui.userportal.widget.basic.OsTypeImage;
 import org.ovirt.engine.ui.userportal.widget.basic.VmPausedImage;
 import org.ovirt.engine.ui.userportal.widget.basic.VmUpMaskImage;
 
@@ -82,8 +82,8 @@
     private final Driver driver = GWT.create(Driver.class);
 
     @UiField
-    @Path("osId")
-    OsTypeImage osTypeImage;
+    @Path("largeIconId")
+    IconImage largeIconImage;
 
     @UiField
     @Path("isVmUp")
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicListItemView.ui.xml
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicListItemView.ui.xml
index 6355141..74ef257 100644
--- 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicListItemView.ui.xml
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/basic/MainTabBasicListItemView.ui.xml
@@ -137,7 +137,7 @@
         <g:center>
             <g:LayoutPanel ui:field="mainContainer" 
addStyleNames="{style.basicVmViewBoxStyle}">
                 <g:layer>
-                    <i:OsTypeImage ui:field="osTypeImage" 
addStyleNames="{style.osTypeImage}" nameUniquePart="Large" />
+                    <i:IconImage ui:field="largeIconImage" 
addStyleNames="{style.osTypeImage}" />
                 </g:layer>
 
                 <g:layer top='5px' height='120px' left='5px' width='150px'>
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/extended/SideTabExtendedTemplateView.java
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/extended/SideTabExtendedTemplateView.java
index 3564818..02ab507 100644
--- 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/extended/SideTabExtendedTemplateView.java
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/extended/SideTabExtendedTemplateView.java
@@ -1,13 +1,16 @@
 package org.ovirt.engine.ui.userportal.section.main.view.tab.extended;
 
 import org.ovirt.engine.core.common.businessentities.VmTemplate;
+import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.ui.common.idhandler.ElementIdHandler;
 import org.ovirt.engine.ui.common.system.ClientStorage;
 import org.ovirt.engine.ui.common.utils.ElementIdUtils;
 import org.ovirt.engine.ui.common.widget.table.cell.TextCell;
+import 
org.ovirt.engine.ui.common.widget.table.column.AbstractDataurlImageColumn;
 import org.ovirt.engine.ui.common.widget.table.column.AbstractTextColumn;
 import org.ovirt.engine.ui.uicommonweb.UICommand;
 import 
org.ovirt.engine.ui.uicommonweb.models.userportal.UserPortalTemplateListModel;
+import org.ovirt.engine.ui.uicommonweb.models.vms.IconCache;
 import org.ovirt.engine.ui.userportal.ApplicationConstants;
 import org.ovirt.engine.ui.userportal.ApplicationMessages;
 import org.ovirt.engine.ui.userportal.ApplicationResources;
@@ -18,8 +21,6 @@
 import 
org.ovirt.engine.ui.userportal.section.main.view.AbstractSideTabWithDetailsView;
 import 
org.ovirt.engine.ui.userportal.uicommon.model.template.UserPortalTemplateListProvider;
 import org.ovirt.engine.ui.userportal.widget.action.UserPortalButtonDefinition;
-import org.ovirt.engine.ui.userportal.widget.table.column.VmImageColumn;
-import 
org.ovirt.engine.ui.userportal.widget.table.column.VmImageColumn.OsTypeExtractor;
 
 import com.google.gwt.cell.client.AbstractCell;
 import com.google.gwt.cell.client.Cell;
@@ -112,12 +113,12 @@
         getTable().enableColumnResizing();
         final String elementIdPrefix = getTable().getContentTableElementId();
 
-        getTable().addColumn(new VmImageColumn<VmTemplate>(new 
OsTypeExtractor<VmTemplate>() {
-            @Override
-            public int extractOsType(VmTemplate item) {
-                return item.getOsId();
+        getTable().addColumn(new AbstractDataurlImageColumn<VmTemplate>() {
+            @Override public String getValue(VmTemplate template) {
+                final Guid smallIconId = template.getSmallIconId();
+                return IconCache.getInstance().getIcon(smallIconId);
             }
-        }), "", "77px"); //$NON-NLS-1$ //$NON-NLS-2$
+        }, "", "77px"); //$NON-NLS-1$ //$NON-NLS-2$
 
         Cell<VmTemplate> nameCell = new AbstractCell<VmTemplate>() {
             @Override
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/extended/SideTabExtendedVirtualMachineView.java
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/extended/SideTabExtendedVirtualMachineView.java
index d47d6cf..cabec20 100644
--- 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/extended/SideTabExtendedVirtualMachineView.java
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/section/main/view/tab/extended/SideTabExtendedVirtualMachineView.java
@@ -3,6 +3,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import org.ovirt.engine.core.compat.Guid;
 import org.ovirt.engine.ui.common.idhandler.ElementIdHandler;
 import org.ovirt.engine.ui.common.system.ClientStorage;
 import org.ovirt.engine.ui.common.widget.table.SimpleActionTable;
@@ -12,7 +13,6 @@
 import org.ovirt.engine.ui.common.widget.table.column.EmptyColumn;
 import org.ovirt.engine.ui.uicommonweb.ErrorPopupManager;
 import org.ovirt.engine.ui.uicommonweb.UICommand;
-import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
 import org.ovirt.engine.ui.uicommonweb.models.VmConsoles;
 import org.ovirt.engine.ui.uicommonweb.models.userportal.UserPortalItemModel;
 import org.ovirt.engine.ui.uicommonweb.models.userportal.UserPortalListModel;
@@ -33,7 +33,7 @@
 import org.ovirt.engine.ui.userportal.widget.refresh.UserPortalRefreshManager;
 import org.ovirt.engine.ui.userportal.widget.table.UserPortalSimpleActionTable;
 import 
org.ovirt.engine.ui.userportal.widget.table.cell.VmButtonsImageButtonCell;
-import 
org.ovirt.engine.ui.userportal.widget.table.column.AbstractMaskedVmImageColumn;
+import 
org.ovirt.engine.ui.userportal.widget.table.column.AbstractUserportalMaskedDataurlImageColumn;
 import 
org.ovirt.engine.ui.userportal.widget.table.column.AbstractMaskedVmImageColumn.ShowMask;
 import org.ovirt.engine.ui.userportal.widget.table.column.OsTypeExtractor;
 import org.ovirt.engine.ui.userportal.widget.table.column.VmStatusColumn;
@@ -136,15 +136,14 @@
 
         ImageResource mask = resources.disabledSmallMask();
 
-        AbstractMaskedVmImageColumn<UserPortalItemModel> maskedVmImageColumn =
-                new 
AbstractMaskedVmImageColumn<UserPortalItemModel>(extractor, upMask, mask) {
+        AbstractUserportalMaskedDataurlImageColumn maskedVmImageColumn =
+                new AbstractUserportalMaskedDataurlImageColumn(mask) {
 
                     @Override
-                    public SafeHtml getTooltip(UserPortalItemModel object) {
-                        String osId = 
AsyncDataProvider.getInstance().getOsName(object.getOsId());
-                        return SafeHtmlUtils.fromString(osId);
+                    public Guid getIconId(UserPortalItemModel itemModel) {
+                        return itemModel.getSmallIconId();
                     }
-        };
+                };
 
         getTable().addColumn(maskedVmImageColumn, constants.empty(), "77px"); 
//$NON-NLS-1$
 
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/basic/IconImage.java
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/basic/IconImage.java
new file mode 100644
index 0000000..e8054ed
--- /dev/null
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/basic/IconImage.java
@@ -0,0 +1,32 @@
+package org.ovirt.engine.ui.userportal.widget.basic;
+
+import com.google.gwt.editor.client.IsEditor;
+import com.google.gwt.editor.client.adapters.TakesValueEditor;
+import com.google.gwt.safehtml.shared.SafeUri;
+import com.google.gwt.safehtml.shared.UriUtils;
+import com.google.gwt.user.client.TakesValue;
+import com.google.gwt.user.client.ui.Image;
+import org.ovirt.engine.core.compat.Guid;
+import org.ovirt.engine.ui.uicommonweb.models.vms.IconCache;
+
+public class IconImage extends Image implements 
IsEditor<TakesValueEditor<Guid>>, TakesValue<Guid> {
+
+    private Guid value;
+
+    @Override public TakesValueEditor<Guid> asEditor() {
+        return TakesValueEditor.of(this);
+    }
+
+    @Override public void setValue(Guid value) {
+        setUrl(toIconUrl(value));
+        this.value = value;
+    }
+
+    private SafeUri toIconUrl(Guid iconId) {
+        return 
UriUtils.fromTrustedString(IconCache.getInstance().getIcon(iconId));
+    }
+
+    @Override public Guid getValue() {
+        return value;
+    }
+}
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/basic/OsTypeImage.java
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/basic/OsTypeImage.java
deleted file mode 100644
index c3871fe..0000000
--- 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/basic/OsTypeImage.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.ovirt.engine.ui.userportal.widget.basic;
-
-import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
-
-import com.google.gwt.uibinder.client.UiConstructor;
-
-/**
- * OS Type such as Windows, Linux, RHEL etc...
- */
-public class OsTypeImage extends AbstractDynamicImage<Integer> {
-
-    private String nameUniquePart;
-
-    private static final String IMAGE = "Image"; //$NON-NLS-1$
-
-    @UiConstructor
-    public OsTypeImage(String nameUniquePart) {
-        this.nameUniquePart = nameUniquePart;
-    }
-
-    @Override
-    protected String imageName(Integer value) {
-        return AsyncDataProvider.getInstance().getOsUniqueOsNames().get(value) 
+ nameUniquePart + IMAGE;
-    }
-
-    @Override
-    protected String defaultImageName(Integer value) {
-        return "other" + nameUniquePart + IMAGE; //$NON-NLS-1$
-    }
-
-}
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/table/column/AbstractMaskedVmImageColumn.java
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/table/column/AbstractMaskedVmImageColumn.java
index 85a6c92..c419257 100644
--- 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/table/column/AbstractMaskedVmImageColumn.java
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/table/column/AbstractMaskedVmImageColumn.java
@@ -46,11 +46,15 @@
     @Override
     public void render(Context context, T object, SafeHtmlBuilder sb) {
         if (showMask.showMask(object)) {
-            // TODO why hardcode to 19px left here?
-            sb.appendHtmlConstant("<div style=\"position: absolute; left: 
19px\" >"); //$NON-NLS-1$
-            
sb.append(SafeHtmlUtils.fromTrustedString(AbstractImagePrototype.create(mask).getHTML()));
-            sb.appendHtmlConstant("</div>"); //$NON-NLS-1$
+            renderMask(mask, sb);
         }
         super.render(context, object, sb);
     }
+
+    public static void renderMask(ImageResource mask, SafeHtmlBuilder sb) {
+        // TODO why hardcode to 19px left here?
+        sb.appendHtmlConstant("<div style=\"position: absolute; left: 19px\" 
>"); //$NON-NLS-1$
+        
sb.append(SafeHtmlUtils.fromTrustedString(AbstractImagePrototype.create(mask).getHTML()));
+        sb.appendHtmlConstant("</div>"); //$NON-NLS-1$
+    }
 }
diff --git 
a/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/table/column/AbstractUserportalMaskedDataurlImageColumn.java
 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/table/column/AbstractUserportalMaskedDataurlImageColumn.java
new file mode 100644
index 0000000..52aa9c2
--- /dev/null
+++ 
b/frontend/webadmin/modules/userportal-gwtp/src/main/java/org/ovirt/engine/ui/userportal/widget/table/column/AbstractUserportalMaskedDataurlImageColumn.java
@@ -0,0 +1,43 @@
+package org.ovirt.engine.ui.userportal.widget.table.column;
+
+
+import com.google.gwt.cell.client.Cell;
+import com.google.gwt.resources.client.ImageResource;
+import com.google.gwt.safehtml.shared.SafeHtml;
+import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
+import com.google.gwt.safehtml.shared.SafeHtmlUtils;
+import org.ovirt.engine.core.compat.Guid;
+import 
org.ovirt.engine.ui.common.widget.table.column.AbstractDataurlImageColumn;
+import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
+import org.ovirt.engine.ui.uicommonweb.models.userportal.UserPortalItemModel;
+import org.ovirt.engine.ui.uicommonweb.models.vms.IconCache;
+
+public abstract class AbstractUserportalMaskedDataurlImageColumn extends 
AbstractDataurlImageColumn<UserPortalItemModel> {
+
+    private ImageResource mask;
+
+    public AbstractUserportalMaskedDataurlImageColumn(ImageResource mask) {
+        this.mask = mask;
+    }
+
+    @Override
+    public SafeHtml getTooltip(UserPortalItemModel itemModel) {
+        String osName = 
AsyncDataProvider.getInstance().getOsName(itemModel.getOsId());
+        return SafeHtmlUtils.fromString(osName);
+    }
+
+    @Override
+    public String getValue(UserPortalItemModel itemModel) {
+        return IconCache.getInstance().getIcon(getIconId(itemModel));
+    }
+
+    public abstract Guid getIconId(UserPortalItemModel itemModel);
+
+    @Override
+    public void render(Cell.Context context, UserPortalItemModel itemModel, 
SafeHtmlBuilder sb) {
+        if (!itemModel.isVmUp()) {
+            AbstractMaskedVmImageColumn.renderMask(mask, sb);
+        }
+        super.render(context, itemModel, sb);
+    }
+}


-- 
To view, visit https://gerrit.ovirt.org/40320
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I5d1b2e313aac9640950919e4c4cb41eb247913a3
Gerrit-PatchSet: 3
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Jakub Niedermertl <jnied...@redhat.com>
Gerrit-Reviewer: automat...@ovirt.org
Gerrit-Reviewer: oVirt Jenkins CI Server
_______________________________________________
Engine-patches mailing list
Engine-patches@ovirt.org
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to