git-tfs-id: [http://tfs.userrendszerhaz.hu:8080/tfs/DefaultCollection]$/MediaCube...
authorvasary.daniel <TFS\vasary.daniel>
Mon, 13 Dec 2021 13:25:12 +0000 (13:25 +0000)
committervasary.daniel <TFS\vasary.daniel>
Mon, 13 Dec 2021 13:25:12 +0000 (13:25 +0000)
server/user.mediacube.gui/pages/searchitems/results.zul
server/user.mediacube.gui/src/user/jobengine/zk/model/GridSearchModel.java [new file with mode: 0644]

index 3cb307bb6e12bf461127b51646827ca011bdd602..e0713f92f6f43349754b0cfbbe95212db4842492 100644 (file)
                        </listitem>\r
                </template>\r
        </listbox>\r
-</zk>
\ No newline at end of file
+</zk>\r
+\r
+<!-- <zk xmlns:w="http://www.zkoss.org/2005/zk/client" xmlns:c="client" height="100%" width="100%"> -->\r
+<!--   <grid id="itemsGrid" sizedByContent="false" span="true" vflex="true" hflex="true" mold="paging"  -->\r
+<!--           autopaging="false" model="@load(vm.searchResult)" -->\r
+<!--           emptyMessage="Nincs találat!" pageSize="50"  -->\r
+<!--           onAfterRender="@command('onAfterRenderGrid')"  -->\r
+<!--           style="border: none; background: white !important;" -->\r
+<!--           oddRowSclass="listbox-odd-style"> -->\r
+<!--           <attribute name="onAfterRender"> -->\r
+<!--                   Clients.evalJavaScript("clearSelection();"); -->\r
+<!--           </attribute> -->\r
+<!--           <columns id="orderColumns"> -->\r
+\r
+<!--                   <column hflex="min"> -->\r
+<!--                           <checkbox checked="@bind(vm.rowsExpanded)" /> -->\r
+<!--                   </column> -->\r
+<!--                   <column hflex="min"> -->\r
+<!--                           <checkbox checked="@bind(vm.allSelected)" /> -->\r
+<!--                   </column> -->\r
+                       \r
+<!--                   <column label="ID" sort="auto" hflex="1" align="left" /> -->\r
+<!--                   <column label="Cím" sort="auto" hflex="2" align="left" /> -->\r
+<!--                   <column label="Fájlnév" sort="auto" hflex="5" align="left" /> -->\r
+<!--                   <column label="Archiválva" sort="auto" hflex="1" align="left" /> -->\r
+<!--                   <column label="Hossz" sort="auto" hflex="2" align="right" /> -->\r
+<!--           </columns> -->\r
+<!--           <rows id="rows" style="cursor: pointer;"> -->\r
+<!--                   <template name="model"> -->\r
+<!--                           <row onClick="@command('select', selectedObject=each)" onMouseOver="@Command('rowMouseOver', evt=event)" -->\r
+<!--                                   onMouseOut="@Command('rowMouseOut', evt=event)" style="background: none;"> -->\r
+<!--                                   <detail open="@load(vm.rowsExpanded)"> -->\r
+<!--                                           <hlayout style="border-bottom: 1px solid #ebebeb; width: 100%;"> -->\r
+<!--                                                   <image tooltiptext="Kattints a lejátszáshoz!" width="140px" height="90px" sclass="myimg" -->\r
+<!--                                                           content="@load(each.media.poster) @converter('user.jobengine.zk.model.ByToImageConverter')" -->\r
+<!--                                                           onClick="@command('select', selectedObject=each)" /> -->\r
+<!--                                                   <div sclass="details"> -->\r
+<!--                                                           <hlayout> -->\r
+<!--                                                                   <div class="${c:cat(vm.typeFilters[each.media.itemType.name].color,' type-inlist')}"> -->\r
+<!--                                                                           <label style="font-size: 10px;" value="@load(each.media.itemType.name)" /> -->\r
+<!--                                                                   </div> -->\r
+<!--                                                                   <label style="font:20px Century Gothic; color:#008AC8;" value="@load(each.item.title)" /> -->\r
+<!--                                                           </hlayout> -->\r
+<!--                                                           <html sclass="relevant"> -->\r
+<!--                                                                   <![CDATA[ <div style='width: 90%'>${each.relevant}</div> ]]> -->\r
+<!--                                                           </html> -->\r
+<!--                                                   </div> -->\r
+<!--                                           </hlayout> -->\r
+<!--                                   </detail> -->\r
+<!--                                   <checkbox checked="@save(vm.itemSelected) @validator(vm.itemSelectedValidator, arg=each)" /> -->\r
+<!--                                   <label value="@load(each.media.houseId)" /> -->\r
+<!--                                   <label value="@load(each.media.title)" /> -->\r
+<!--                                   <label value="@load(each.media.mediaFileRealName)" /> -->\r
+<!--                                   <label style="font-size: 10px;" value="@load(each.media.archived) @converter('user.jobengine.zk.model.ShortDateConverter')" /> -->\r
+<!--                                   <cell> -->\r
+<!--                                           <vlayout> -->\r
+<!--                                                   <hlayout> -->\r
+<!--                                                           <label style="font-size:14px" -->\r
+<!--                                                                   value="@load(each.media.length) @converter('user.jobengine.zk.model.TCConverter')" /> -->\r
+<!--                                                           <image src="/img/ic_visibility_black_18dp.png" style="margin-left:4px;margin-top:2px;vertical-align:top;"> -->\r
+<!--                                                                   <attribute name="visible" if="${each.media.mediaFilesCount lt 2}">false</attribute> -->\r
+<!--                                                           </image> -->\r
+<!--                                                           <image src="/img/ic_visibility_off_black_18dp.png" -->\r
+<!--                                                                   style="margin-left:4px;margin-top:2px;vertical-align:top;"> -->\r
+<!--                                                                   <attribute name="visible" if="${each.media.mediaFilesCount gt 1}">false</attribute> -->\r
+<!--                                                           </image> -->\r
+<!--                                                           <image src="/img/baseline_arrow_back_black_18dp.png" -->\r
+<!--                                                                   style="margin-left:4px;margin-top:2px;vertical-align:top;" -->\r
+<!--                                                                   visible="@load(!each.media.created.equals(each.media.modified))"> -->\r
+<!--                                                           </image> -->\r
+<!--                                                   </hlayout> -->\r
+<!--                                           </vlayout> -->\r
+<!--                                   </cell> -->\r
+<!--                           </row> -->\r
+<!--                   </template> -->\r
+<!--           </rows> -->\r
+<!--   </grid> -->\r
+<!-- </zk> -->
\ No newline at end of file
diff --git a/server/user.mediacube.gui/src/user/jobengine/zk/model/GridSearchModel.java b/server/user.mediacube.gui/src/user/jobengine/zk/model/GridSearchModel.java
new file mode 100644 (file)
index 0000000..b44d8b3
--- /dev/null
@@ -0,0 +1,1175 @@
+package user.jobengine.zk.model;\r
+\r
+import static java.time.temporal.TemporalAdjusters.firstDayOfMonth;\r
+import static java.time.temporal.TemporalAdjusters.firstDayOfNextMonth;\r
+import static java.time.temporal.TemporalAdjusters.firstDayOfNextYear;\r
+import static java.time.temporal.TemporalAdjusters.firstDayOfYear;\r
+\r
+import java.nio.file.Paths;\r
+import java.time.LocalDate;\r
+import java.time.ZoneId;\r
+import java.time.ZonedDateTime;\r
+import java.time.temporal.ChronoField;\r
+import java.util.ArrayList;\r
+import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.LinkedHashMap;\r
+import java.util.List;\r
+import java.util.Map;\r
+\r
+import org.apache.commons.lang.StringUtils;\r
+import org.apache.logging.log4j.LogManager;\r
+import org.apache.logging.log4j.Logger;\r
+import org.zkoss.bind.BindContext;\r
+import org.zkoss.bind.ValidationContext;\r
+import org.zkoss.bind.Validator;\r
+import org.zkoss.bind.annotation.AfterCompose;\r
+import org.zkoss.bind.annotation.BindingParam;\r
+import org.zkoss.bind.annotation.Command;\r
+import org.zkoss.bind.annotation.ContextParam;\r
+import org.zkoss.bind.annotation.ContextType;\r
+import org.zkoss.bind.annotation.NotifyChange;\r
+import org.zkoss.json.JSONObject;\r
+import org.zkoss.zk.ui.Component;\r
+import org.zkoss.zk.ui.Executions;\r
+import org.zkoss.zk.ui.event.Event;\r
+import org.zkoss.zk.ui.event.EventListener;\r
+import org.zkoss.zk.ui.event.Events;\r
+import org.zkoss.zk.ui.event.KeyEvent;\r
+import org.zkoss.zk.ui.event.MouseEvent;\r
+import org.zkoss.zk.ui.event.SortEvent;\r
+import org.zkoss.zk.ui.select.Selectors;\r
+import org.zkoss.zk.ui.select.annotation.Wire;\r
+import org.zkoss.zk.ui.util.Clients;\r
+import org.zkoss.zul.Button;\r
+import org.zkoss.zul.Checkbox;\r
+import org.zkoss.zul.Column;\r
+import org.zkoss.zul.Combobox;\r
+import org.zkoss.zul.Detail;\r
+import org.zkoss.zul.Grid;\r
+import org.zkoss.zul.Hbox;\r
+import org.zkoss.zul.Hlayout;\r
+import org.zkoss.zul.ListModelList;\r
+import org.zkoss.zul.Menuitem;\r
+import org.zkoss.zul.Menupopup;\r
+import org.zkoss.zul.Messagebox;\r
+import org.zkoss.zul.Paging;\r
+import org.zkoss.zul.Panel;\r
+import org.zkoss.zul.Row;\r
+import org.zkoss.zul.Timer;\r
+import org.zkoss.zul.Toolbar;\r
+import org.zkoss.zul.Toolbarbutton;\r
+import org.zkoss.zul.Vlayout;\r
+import org.zkoss.zul.West;\r
+import org.zkoss.zul.Window;\r
+\r
+import user.commons.ListUtils;\r
+import user.commons.StoreUri;\r
+import user.commons.remotestore.RemoteStoreProtocol;\r
+import user.jobengine.db.ArchivedMedia;\r
+import user.jobengine.db.IItemManager;\r
+import user.jobengine.db.ItemManager;\r
+import user.jobengine.db.ItemType;\r
+import user.jobengine.db.MediaFile;\r
+import user.jobengine.db.SearchOptions;\r
+import user.jobengine.db.Store;\r
+import user.jobengine.gui.ComponentBinder;\r
+import user.jobengine.server.IJobEngine;\r
+import user.jobengine.server.JobEngineException;\r
+import user.jobengine.server.scheduler.ScheduledJob;\r
+import user.jobengine.zk.util.SessionUtil;\r
+\r
+public class GridSearchModel extends AsyncBaseModel {\r
+       private static final String TAGTYPE_REMOVE = "remove";\r
+       private static final String TAGTYPE_ADD = "add";\r
+       private static final String TAGEVT_TAGTEXT = "tagtext";\r
+       private static final String TAGEVT_TYPE = "type";\r
+       private static final String TAGSRC_FILTER = "filter";\r
+       private static final String TAGSRC_MEDIA = "media";\r
+       private static final String TAGEVT_SOURCE = "source";\r
+       private static final String CREATE_LOWRES_TEMPLATE = "create-lowres-ondemand.xml";\r
+       private static final String ARG = "arg";\r
+       private static final String MEDIA_ID = "showMediaID";\r
+       private static final Logger logger = LogManager.getLogger();\r
+       private List<TypeFilter> topTypeFilters;\r
+       private List<TypeFilter> bottomTypeFilters;\r
+       private Map<String, TypeFilter> typeFilters;\r
+       private Map<String, String> columnHeaders;\r
+       private CachedListModel searchResult = null;\r
+       private ArchivedMedia selectedObject = null;\r
+       private Validator allFilterCheckedValidator;\r
+       private Validator itemSelectedValidator;\r
+       private boolean allChecked = true;\r
+       private boolean rowsExpanded = true;\r
+       private boolean allSelected;\r
+       private boolean itemSelected;\r
+       private int descLength;\r
+       private Map<String, Long> tags = null;\r
+       private List<Long> searchTags = new ArrayList<>();\r
+       protected IItemManager itemManager = null;\r
+\r
+       @Wire\r
+       Timer timer;\r
+       @Wire\r
+       Grid itemsGrid;\r
+       @Wire\r
+       Button backToVideoButton;\r
+       @Wire\r
+       Combobox search;\r
+       @Wire\r
+       Toolbar tagsToolbar;\r
+       @Wire\r
+       Button btnSearch;\r
+       @Wire\r
+       Hbox searchFiltersMenu;\r
+       @Wire\r
+       Toolbarbutton toggleShowTypeFilters;\r
+       @Wire\r
+       Panel serachDetails;\r
+       @Wire\r
+       Toolbar filterToolbar;\r
+\r
+       @Wire\r
+       Menupopup searchSettings;\r
+       @Wire\r
+       Vlayout mediaDetails;\r
+       @Wire\r
+       West searchWest;\r
+\r
+       private String orderBy;\r
+\r
+       private boolean orderAscending;\r
+       private Map<String, String> topColorClasses;\r
+       private int selectedRowIndex = -1;\r
+       private volatile boolean preventAfterRender;\r
+       private int positionToScroll = -1;\r
+       private ListModelList<String> searchHistory;\r
+       private Map<String, String> columnOrder;\r
+       private Date searchFrom;\r
+       private Date searchTo;\r
+       private boolean missingProxy;\r
+       private int selectedDateOption;\r
+       private Window metaWindow;\r
+\r
+       public GridSearchModel() {\r
+               this.itemManager = ItemManager.getInstance();\r
+\r
+               typeFilters = new LinkedHashMap<>();\r
+               MediaCubeConfig mediaCubeConfig = SessionUtil.getMediaCubeConfig();\r
+               setTopTypeFilters(mediaCubeConfig.getTopTypeFilters());\r
+               setBottomTypeFilters(mediaCubeConfig.getBottomTypeFilters());\r
+\r
+               columnHeaders = new LinkedHashMap<>();\r
+               columnHeaders.put("ID", "mediahouseid");\r
+               columnHeaders.put("Cím", "mediatitle");\r
+               columnHeaders.put("Hossz", "length");\r
+               columnHeaders.put("Fájlnév", "mediafilehouseid");\r
+               columnHeaders.put("Archiválva", "archived");\r
+\r
+               allFilterCheckedValidator = new Validator() {\r
+                       @Override\r
+                       public void validate(ValidationContext ctx) {\r
+                               try {\r
+\r
+                                       TypeFilter typeFilter = (TypeFilter) ctx.getProperty().getBase();\r
+                                       boolean isChecked = (boolean) ctx.getProperty().getValue();\r
+                                       typeFilter.setChecked(isChecked);\r
+                                       // logger.info("{} {}", label, isChecked);\r
+                               } catch (Exception e) {\r
+\r
+                               }\r
+                               updateAllChecked();\r
+                       }\r
+               };\r
+\r
+               itemSelectedValidator = new Validator() {\r
+                       @Override\r
+                       public void validate(ValidationContext ctx) {\r
+                               try {\r
+\r
+                                       ArchivedMedia item = (ArchivedMedia) ctx.getValidatorArg(ARG);\r
+                                       boolean select = (boolean) ctx.getProperty().getValue();\r
+                                       MenuModel model = (MenuModel) SessionUtil.getAttribute(SessionUtil.MENUMODEL);\r
+                                       model.selectArchivedMedia(item, select);\r
+                               } catch (Exception e) {\r
+\r
+                               }\r
+                       }\r
+               };\r
+\r
+               // searchHistory = new ListModelList<>(SessionUtil.getUserSearchHistory());\r
+               // setColumnOrder();\r
+               // setUserSelectedFilters();\r
+       }\r
+\r
+       private void addTypeFilters(List<TypeFilter> filters) {\r
+               for (TypeFilter typeFilter : filters)\r
+                       typeFilters.put(typeFilter.getName(), typeFilter);\r
+       }\r
+\r
+       @AfterCompose\r
+       public void afterCompose(@ContextParam(ContextType.VIEW) Component view) {\r
+               // A MediaFileServlet a services/proxy alatt szolgal ki\r
+               // Clients.evalJavaScript("setSource('http://localhost:9080/services/proxy/20209535_1-20205617.mp4',\r
+               // 'video/mp4')");\r
+\r
+               try {\r
+\r
+                       Selectors.wireComponents(view, this, false);\r
+                       Selectors.wireEventListeners(view, this);\r
+\r
+                       boolean typeFiltersVisible = SessionUtil.getTypeFiltersVisibility();\r
+                       if (typeFiltersVisible) {\r
+                               toggleShowTypeFilters.setChecked(true);\r
+                               toggleTypeFiltersCheck();\r
+                               search.setFocus(true);\r
+                       }\r
+\r
+                       configureSearchResultGrid();\r
+                       showExternalMediaID();\r
+\r
+                       searchHistory = new ListModelList<>(SessionUtil.getUserSearchHistory());\r
+                       setColumnOrder();\r
+                       setUserSelectedFilters();\r
+\r
+                       if (SessionUtil.getUserPageSize() != 0)\r
+                               itemsGrid.setPageSize(SessionUtil.getUserPageSize());\r
+                       setSettingsPageSize(itemsGrid.getPageSize());\r
+                       if (!allChecked)\r
+                               showSearchTypeWarning();\r
+\r
+                       tags = itemManager.getAllTags();\r
+                       // lekerdezesi hiba\r
+                       if (tags == null)\r
+                               Clients.showNotification("A cimkék inicializálása sikertelen!", "error", tagsToolbar, "start_center",\r
+                                               3000);\r
+                       else\r
+                               setSearchTags();\r
+\r
+               } catch (Exception e) {\r
+                       handleSearchError(e);\r
+               }\r
+\r
+       }\r
+\r
+       private void clearAllFilters() {\r
+               for (String filter : typeFilters.keySet()) {\r
+                       typeFilters.get(filter).setChecked(false);\r
+               }\r
+       }\r
+\r
+       @Command\r
+       @NotifyChange("searchHistory")\r
+       public void clearHistory() {\r
+               setSearchHistory(new ListModelList<>());\r
+               SessionUtil.putUserSearchHistory(searchHistory);\r
+       }\r
+\r
+       private void configureSearchResultGrid() {\r
+               Paging paging = itemsGrid.getPagingChild();\r
+               paging.setAutohide(false);\r
+\r
+               for (Component child : itemsGrid.getColumns().getChildren()) {\r
+                       Column column = (Column) child;\r
+                       if (columnOrder != null)\r
+                               if (column.getLabel().equals(columnOrder.entrySet().iterator().next().getKey()))\r
+                                       column.setSortDirection(columnOrder.entrySet().iterator().next().getValue());\r
+                       column.addEventListener("onSort", evt -> doSort(evt));\r
+               }\r
+       }\r
+\r
+       @Command\r
+       public void copyMediaIdToClipboard() {\r
+               String port = (Executions.getCurrent().getServerPort() == 80) ? ""\r
+                               : (":" + Executions.getCurrent().getServerPort());\r
+               String baseURL = Executions.getCurrent().getScheme() + "://" + Executions.getCurrent().getServerName() + port\r
+                               + Executions.getCurrent().getContextPath();\r
+               String url = String.format("%s/?%s=%d", baseURL, MEDIA_ID, selectedObject.getMedia().getId());\r
+               String email = String.format("mailto:?subject=Média címe: %s &body=A média itt tekinthető meg: %s",\r
+                               selectedObject.getMedia().getTitle(), url);\r
+               Executions.getCurrent().sendRedirect(email);\r
+       }\r
+\r
+       @Command\r
+       public void createLowres() {\r
+               IJobEngine jobEngine = ComponentBinder.getJobEngine();\r
+\r
+               ScheduledJob scheduledJob = jobEngine.getScheduledJob(CREATE_LOWRES_TEMPLATE);\r
+               Map<String, Object> parameters = scheduledJob.getJobParameters();\r
+               parameters.put("mediaCubeMedia", selectedObject.getMedia());\r
+               parameters.put("deleteSource", true);\r
+               parameters.put("killDateDays", 0);\r
+               parameters.put("targetNamePattern", "%s");\r
+               parameters.put("successRecipient", SessionUtil.getUserPrincipal().getEmail());\r
+\r
+               try {\r
+                       jobEngine.submit(CREATE_LOWRES_TEMPLATE, scheduledJob.getJobName(), parameters,\r
+                                       SessionUtil.getUserPrincipal().getDisplayName());\r
+                       Messagebox.show("A proxy pótlása elindult, emailben értesíti a rendszer a folyamat végeztével.",\r
+                                       "Információ", Messagebox.OK, Messagebox.INFORMATION);\r
+               } catch (JobEngineException e) {\r
+                       logger.info("Hiba a feladat indításakor", e);\r
+                       Messagebox.show("Hiba a feladat indításakor. A rendszer üzenete: " + e.getMessage(), "Hiba", Messagebox.OK,\r
+                                       Messagebox.ERROR);\r
+               }\r
+       }\r
+\r
+       @Command\r
+       @NotifyChange({ "searchResult", "selectedObject", "hasTSMMediaFile", "hasLowresMediaFile", "lowresMediaFilePath" })\r
+       public void doSearch() {\r
+               try {\r
+                       search.close();\r
+                       search.select();\r
+                       searchResult = null;\r
+                       itemsGrid.setActivePage(0);\r
+                       setSelectedObject(null);\r
+                       String searchValue = search.getText();\r
+\r
+                       if (StringUtils.isNotBlank(searchValue) && !searchHistory.contains(searchValue)) {\r
+                               searchHistory.add(0, searchValue);\r
+                               SessionUtil.putUserSearchHistory(searchHistory);\r
+                       }\r
+\r
+                       List<String> searchFilters = getSelectedFilters();\r
+                       SessionUtil.putUserSearchFilter(searchFilters);\r
+\r
+                       if (SessionUtil.getUserColumnOrder() != null) {\r
+                               orderBy = columnHeaders.get(columnOrder.entrySet().iterator().next().getKey());\r
+                               orderAscending = columnOrder.entrySet().iterator().next().getValue().equals("ascending");\r
+                       }\r
+\r
+                       if (searchFilters == null || searchFilters.size() == 0)\r
+                               throw new Exception("Anyag típus kiválasztása kötelező!");\r
+\r
+                       List<Long> selectedTypeIds = getTypeIDs(searchFilters);\r
+\r
+                       SearchOptions options = SearchOptions.create().setText(searchValue).setTypes(selectedTypeIds)\r
+                                       .setTags(searchTags).setFrom(searchFrom).setTo(searchTo).setMissingProxy(missingProxy)\r
+                                       .setDescLength(descLength).setOrder(orderBy, orderAscending);\r
+\r
+                       if (!options.isValid())\r
+                               throw new Exception(\r
+                                               "Legalább egy keresési opció használata kötelező: 3 karakter, hiányzó proxy, dátum, típus, cimke!");\r
+                       searchResult = new CachedListModel(options);\r
+                       searchResult.addEventListener(e -> {\r
+                               if (e.getName().equals(Events.ON_ERROR)) {\r
+                                       Exception ex = (Exception) e.getData();\r
+                                       handleSearchError(ex);\r
+                               }\r
+                       });\r
+\r
+                       if (!allChecked)\r
+                               showSearchTypeWarning();\r
+\r
+               } catch (Exception e) {\r
+                       handleSearchError(e);\r
+               }\r
+       }\r
+\r
+       public void doSort(Event event) throws Exception {\r
+               itemsGrid.getColumns().getChildren().forEach(c -> ((Column) c).setSortDirection("natural"));\r
+               SortEvent evt = (SortEvent) event;\r
+               Column column = (Column) evt.getTarget();\r
+               column.setSortDirection(evt.isAscending() ? "ascending" : "descending");\r
+               logger.info("{} {}", column.getLabel(), evt.isAscending());\r
+\r
+               columnOrder = new HashMap<>();\r
+               columnOrder.put(column.getLabel(), column.getSortDirection());\r
+               SessionUtil.putUserColumnOrder(columnOrder);\r
+\r
+               orderBy = columnHeaders.get(column.getLabel());\r
+               orderAscending = evt.isAscending();\r
+               doSearch();\r
+               notifyChange("searchResult", "selectedObject", "hasLowresMediaFile", "lowresMediaFilePath");\r
+               evt.stopPropagation();\r
+       }\r
+\r
+       @Command\r
+       public void downloadMedia() {\r
+               if (!getHasTSMMediaFile())\r
+                       return;\r
+               // Map<String, Object> arguments = new HashMap<String, Object>();\r
+               // arguments.put(MEDIACUBEMEDIA, this.selectedObject.getMedia());\r
+               // Window window = (Window)\r
+               // Executions.createComponents(PAGES_RETRIEVESELECTOR_ZUL, null,\r
+               // arguments);\r
+               // window.doModal();\r
+\r
+               MenuModel model = (MenuModel) SessionUtil.getAttribute(SessionUtil.MENUMODEL);\r
+               model.selectArchivedMedia(this.selectedObject, true);\r
+       }\r
+\r
+       void ensureVisible(int pos) {\r
+\r
+               registerTask(() -> {\r
+                       logger.info("Scrolling to pos {} begin", pos);\r
+                       List<Component> children = itemsGrid.getRows().getChildren();\r
+                       if (children.size() > 0) {\r
+                               Component top = children.get(pos);\r
+                               Clients.scrollIntoView(top);\r
+                               logger.info("Scrolled into the {}. row on the page.", pos);\r
+                       }\r
+\r
+                       if (positionToScroll > -1) {\r
+                               highlight(selectedObject, true);\r
+                               positionToScroll = -1;\r
+                       }\r
+\r
+                       logger.info("Scrolling to pos {} end", pos);\r
+                       preventAfterRender = false;\r
+               });\r
+               timer.start();\r
+       }\r
+\r
+       public Validator getAllFilterCheckedValidator() {\r
+               return allFilterCheckedValidator;\r
+       }\r
+\r
+       public List<TypeFilter> getBottomTypeFilters() {\r
+               return bottomTypeFilters;\r
+       }\r
+\r
+       public int getDescLength() {\r
+               return descLength;\r
+       }\r
+\r
+       public boolean getHasLowresMediaFile() {\r
+               boolean ret = false;\r
+               if (selectedObject != null) {\r
+                       List<MediaFile> mediaFiles = selectedObject.getMedia().getMediaFiles();\r
+                       if (mediaFiles != null) {\r
+                               for (MediaFile mf : mediaFiles) {\r
+                                       if (mf.getStore().isLowres()) {\r
+                                               return true;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               return ret;\r
+       }\r
+\r
+       public boolean getHasTSMMediaFile() {\r
+               return selectedObject != null;\r
+       }\r
+\r
+       public Validator getItemSelectedValidator() {\r
+               return itemSelectedValidator;\r
+       }\r
+\r
+       public String getLowresMediaFilePath() throws Exception {\r
+               String ret = null;\r
+               if (selectedObject != null) {\r
+                       List<MediaFile> mediaFiles = selectedObject.getMedia().getMediaFiles();\r
+                       if (mediaFiles != null) {\r
+                               for (MediaFile mf : mediaFiles) {\r
+                                       Store store = mf.getStore();\r
+                                       if (store == null)\r
+                                               continue;\r
+                                       // TODO a tartalek nem tud lowres lenni, de a TSM-nek nincs HTTP bejegyzese\r
+                                       // if (store.isLowres()) {\r
+                                       // StoreUri sourceStoreUri = store.getSourceStoreUri(RemoteStoreProtocol.HTTP);\r
+                                       // URL base = new URL(sourceStoreUri.toString());\r
+                                       // String relative = mf.getRelativePath().replace("\\", "/");\r
+                                       // ret = new URL(base, relative).toString();\r
+                                       // break;\r
+                                       // }\r
+\r
+                                       // relative cim a sajat kiszolgalo miatt\r
+                                       StoreUri sourceStoreUri = store.getSourceStoreUri(RemoteStoreProtocol.HTTP);\r
+\r
+                                       if (sourceStoreUri != null && sourceStoreUri.isStream()) {\r
+\r
+                                               String noProtocolUri = sourceStoreUri.toString(true);\r
+                                               String base = noProtocolUri.startsWith("/") ? noProtocolUri : sourceStoreUri.toString(false);\r
+                                               if (!base.endsWith("/"))\r
+                                                       base += "/";\r
+                                               String relative = mf.getRelativePath().replace("\\", "/");\r
+                                               ret = base + relative;\r
+                                               logger.info("Found lowres on store {}, url is {}", store.getName(), ret);\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               return ret;\r
+       }\r
+\r
+       public Date getSearchFrom() {\r
+               return searchFrom;\r
+       }\r
+\r
+       public ListModelList<String> getSearchHistory() {\r
+               return searchHistory;\r
+       }\r
+\r
+       public ListModelList<ArchivedMedia> getSearchResult() {\r
+               return searchResult;\r
+       }\r
+\r
+       public Date getSearchTo() {\r
+               return searchTo;\r
+       }\r
+\r
+       public int getSelectedDateOption() {\r
+               return selectedDateOption;\r
+       }\r
+\r
+       private List<String> getSelectedFilters() {\r
+               List<String> result = null;\r
+               for (String label : typeFilters.keySet()) {\r
+                       boolean isChecked = typeFilters.get(label).isChecked();\r
+                       if (!isChecked)\r
+                               continue;\r
+                       if (result == null)\r
+                               result = new ArrayList<>();\r
+                       result.add(label);\r
+               }\r
+               return result;\r
+       }\r
+\r
+       public ArchivedMedia getSelectedObject() {\r
+               return selectedObject;\r
+       }\r
+\r
+       public Map<String, String> getTopColorClasses() {\r
+               return topColorClasses;\r
+       }\r
+\r
+       public List<TypeFilter> getTopTypeFilters() {\r
+               return topTypeFilters;\r
+       }\r
+\r
+       public String getTSMMediaFilePath() throws Exception {\r
+               String ret = "";\r
+               if (selectedObject != null) {\r
+                       List<MediaFile> mediaFiles = selectedObject.getMedia().getMediaFiles();\r
+                       for (MediaFile mf : mediaFiles) {\r
+                               Store store = mf.getStore();\r
+                               if (mf.getStore().isSystem())\r
+                                       ret = Paths.get(store.getStoreUris().get(0).toString(false), mf.getRelativePath()).toString();\r
+                       }\r
+               }\r
+               return ret;\r
+       }\r
+\r
+       public Map<String, TypeFilter> getTypeFilters() {\r
+               return typeFilters;\r
+       }\r
+\r
+       private List<Long> getTypeIDs(List<String> searchFilters) {\r
+               if (allChecked)\r
+                       return null;\r
+               List<Long> result = null;\r
+               if (searchFilters != null) {\r
+                       for (String typeName : searchFilters) {\r
+                               ItemType itemType = itemManager.getItemType(typeName);\r
+                               if (itemType == null)\r
+                                       continue;\r
+                               if (result == null)\r
+                                       result = new ArrayList<>();\r
+                               result.add(itemType.getId());\r
+                       }\r
+               }\r
+               return result;\r
+       }\r
+\r
+       private void handleSearchError(Exception e) {\r
+               if (e instanceof NullPointerException)\r
+                       Clients.showNotification("Database query error!", "error", btnSearch, "start_center", 3000);\r
+               else\r
+                       Clients.showNotification(e.getMessage(), "error", btnSearch, "start_center", 3000);\r
+               logger.error(e);\r
+       }\r
+\r
+       private void highlight(ArchivedMedia am, boolean highlight) {\r
+               if (am == null)\r
+                       return;\r
+               List<Component> components = itemsGrid.getRows().getChildren();\r
+               for (int i = 0; i < components.size(); i++) {\r
+                       Row row = (Row) components.get(i);\r
+                       ArchivedMedia archivedMedia = (ArchivedMedia) row.getValue();\r
+                       if (archivedMedia != null && am.getMedia().getId() == archivedMedia.getMedia().getId()) {\r
+                               Detail detail = (Detail) row.getChildren().get(0);\r
+                               Hlayout hlayout = (Hlayout) detail.getChildren().get(0);\r
+                               if (highlight) {\r
+                                       selectedRowIndex = i;\r
+                                       row.setStyle("background: #F1F8E9;");\r
+                                       hlayout.setStyle("border-bottom: 1px solid #C5E1A5; background: #F1F8E9;");\r
+                               } else {\r
+                                       row.setStyle("background: none;");\r
+                                       hlayout.setStyle("border-bottom: 1px solid #ebebeb; background: none;");\r
+                               }\r
+                               break;\r
+\r
+                       }\r
+               }\r
+       }\r
+\r
+       public boolean isAllChecked() {\r
+               return allChecked;\r
+       }\r
+\r
+       public boolean isAllSelected() {\r
+               return allSelected;\r
+       }\r
+\r
+       public boolean isItemSelected() {\r
+               return itemSelected;\r
+       }\r
+\r
+       public boolean isMissingProxy() {\r
+               return missingProxy;\r
+       }\r
+\r
+       public boolean isRowsExpanded() {\r
+               return rowsExpanded;\r
+       }\r
+\r
+       @Command\r
+       public void onAfterRenderGrid() {\r
+               logger.info("onAfterRenderGrid begin");\r
+               // aszinkron fut le, kulon kezelendo a hiba\r
+               try {\r
+\r
+                       if (searchResult != null)\r
+                               logger.info("isempty {}", searchResult.isEmpty());\r
+\r
+                       String mediaID = SessionUtil.getQueryParameter(MEDIA_ID);\r
+                       if (mediaID != null) {\r
+                               selectedObject = searchResult.getElementAt(0);\r
+                               highlight(selectedObject, true);\r
+                               notifyChange("selectedObject", "hasLowresMediaFile", "hasTSMMediaFile", "lowresMediaFilePath");\r
+                               logger.info("onAfterRenderGrid end");\r
+                               return;\r
+                       }\r
+\r
+                       if (preventAfterRender) {\r
+                               logger.info("onAfterRenderGrid end");\r
+                               return;\r
+                       }\r
+                       preventAfterRender = true;\r
+\r
+                       if (positionToScroll != -1) {\r
+                               ensureVisible(positionToScroll);\r
+                       }\r
+               } catch (Exception e) {\r
+                       handleSearchError(e);\r
+               }\r
+               logger.info("onAfterRenderGrid end");\r
+       }\r
+\r
+       @Command\r
+       public void onChangingCombo(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {\r
+               logger.info(((KeyEvent) ctx.getTriggerEvent()).getKeyCode());\r
+               logger.info("onChanging");\r
+       }\r
+\r
+       @Command\r
+       public void onPaging() {\r
+               logger.info("onPaging");\r
+       }\r
+\r
+       @Command\r
+       public void onTagChanged(@ContextParam(ContextType.TRIGGER_EVENT) Event event) {\r
+               // source: filter | media,\r
+               // type : add | remove,\r
+               // tagtext: e.detail.data.value,\r
+               // index: e.detail.index\r
+\r
+               JSONObject jsObject = (JSONObject) event.getData();\r
+               if (!jsObject.containsKey(TAGEVT_SOURCE))\r
+                       return;\r
+               String source = String.valueOf(jsObject.get(TAGEVT_SOURCE));\r
+\r
+               if (TAGSRC_MEDIA.equals(source))\r
+                       processMediaTagChanged(jsObject);\r
+\r
+               if (TAGSRC_FILTER.equals(source))\r
+                       processFilterTagChanged(jsObject);\r
+\r
+               logger.info(event);\r
+       }\r
+\r
+       @Command\r
+       public void onTcIn(@ContextParam(ContextType.TRIGGER_EVENT) Event event) throws Exception {\r
+               JSONObject jsObject = (JSONObject) event.getData();\r
+               Double doubleVar = 0.0;\r
+               if (!jsObject.get("meta").equals(0)) {\r
+                       doubleVar = (Double) jsObject.get("meta");\r
+               }\r
+\r
+               if (doubleVar.floatValue() >= ((selectedObject.getTcOut() == null) ? 9999999999999999999999.9\r
+                               : selectedObject.getTcOut())) {\r
+                       throw new Exception("A kilépés időpontjának későbbinek kell lennie mint a belépés időpontja!");\r
+               } else {\r
+                       selectedObject.setTcIn(new Float(doubleVar.floatValue()));\r
+               }\r
+       }\r
+\r
+       @Command\r
+       public void onTcOut(@ContextParam(ContextType.TRIGGER_EVENT) Event event) throws Exception {\r
+               JSONObject jsObject = (JSONObject) event.getData();\r
+               Double doubleVar = 0.0;\r
+               if (!jsObject.get("meta").equals(0)) {\r
+                       doubleVar = (Double) jsObject.get("meta");\r
+               }\r
+\r
+               if (doubleVar.floatValue() <= ((selectedObject.getTcIn() == null) ? 0.0 : selectedObject.getTcIn())) {\r
+                       throw new Exception("A kilépés időpontjának későbbinek kell lennie mint a belépés időpontja!");\r
+               } else {\r
+                       selectedObject.setTcOut(new Float(doubleVar.floatValue()));\r
+               }\r
+       }\r
+\r
+       @Command\r
+       public void onWestResize() {\r
+               filterToolbar.invalidate();\r
+       }\r
+\r
+       @Command\r
+       public void openMetaDataDialog() {\r
+               if (metaWindow != null)\r
+                       return;\r
+\r
+               // EventListener<Event> eventListener = e -> {\r
+               // EventQueues.lookup("my super queue", EventQueues.APPLICATION,\r
+               // true).unsubscribe(this);\r
+               // };\r
+               // EventQueues.lookup("my super queue", EventQueues.APPLICATION,\r
+               // true).subscribe(eventListener);\r
+               String template = "/pages/metadatadetails.zul";\r
+               EventListener<?> listener = e -> {\r
+                       logger.info("Meta window closed");\r
+\r
+                       notifyChange("selectedObject", "itemsGrid");\r
+\r
+                       metaWindow = null;\r
+               };\r
+\r
+               metaWindow = (Window) Executions.createComponents(template, null,\r
+                               ListUtils.asMap("selectedObject", selectedObject, "listener", listener));\r
+               metaWindow.doOverlapped();\r
+               metaWindow.addEventListener("onClose", listener);\r
+       }\r
+\r
+       private void processFilterTagChanged(JSONObject jsObject) {\r
+               if (tags == null)\r
+                       return;\r
+\r
+               if (!jsObject.containsKey(TAGEVT_TYPE))\r
+                       return;\r
+               String type = String.valueOf(jsObject.get(TAGEVT_TYPE));\r
+\r
+               if (!jsObject.containsKey(TAGEVT_TAGTEXT))\r
+                       return;\r
+               String tagText = String.valueOf(jsObject.get(TAGEVT_TAGTEXT));\r
+\r
+               long id = tags.get(tagText);\r
+\r
+               switch (type) {\r
+               case TAGTYPE_ADD:\r
+                       searchTags.add(id);\r
+                       break;\r
+               case TAGTYPE_REMOVE:\r
+                       searchTags.remove(id);\r
+                       break;\r
+               }\r
+       }\r
+\r
+       private void processMediaTagChanged(JSONObject jsObject) {\r
+               if (selectedObject == null || !SessionUtil.isEditor() || tags == null) {\r
+                       setMediaTags(0);\r
+                       return;\r
+               }\r
+\r
+               if (!jsObject.containsKey(TAGEVT_TYPE))\r
+                       return;\r
+               String type = String.valueOf(jsObject.get(TAGEVT_TYPE));\r
+\r
+               if (!jsObject.containsKey(TAGEVT_TAGTEXT))\r
+                       return;\r
+               String tagText = String.valueOf(jsObject.get(TAGEVT_TAGTEXT));\r
+\r
+               long id = 0;\r
+               if (tags.containsKey(tagText))\r
+                       id = tags.get(tagText);\r
+\r
+               List<String> mediaTags = selectedObject.getTags();\r
+               switch (type) {\r
+               case TAGTYPE_ADD:\r
+                       if (mediaTags.contains(tagText.toLowerCase()))\r
+                               return;\r
+                       if (id == 0) {\r
+                               id = itemManager.addMediaTag(tagText, selectedObject.getMedia().getId());\r
+                               // frissitjuk az osszes Tagify control whitelist-jet\r
+                               tags.put(tagText, id);\r
+                               setSearchTags();\r
+                       } else\r
+                               itemManager.addMediaTag(id, selectedObject.getMedia().getId());\r
+\r
+                       mediaTags.add(tagText);\r
+                       break;\r
+               case TAGTYPE_REMOVE:\r
+                       mediaTags.remove(tagText.toLowerCase());\r
+                       if (id == 0) {\r
+                               Messagebox.show("A cimke már nem található az adatbázisban: " + tagText, "Belső hiba!", Messagebox.OK,\r
+                                               Messagebox.EXCLAMATION);\r
+                               return;\r
+                       }\r
+                       itemManager.removeMediaTag(id, selectedObject.getMedia().getId());\r
+                       break;\r
+               }\r
+       }\r
+\r
+       @Command\r
+       public void rowMouseOut(@BindingParam("evt") MouseEvent event) {\r
+               logger.info(event);\r
+       }\r
+\r
+       // public void rowSelected(@BindingParam("item") Object media,\r
+       // @BindingParam("isChecked") boolean isChecked) {\r
+       @Command\r
+       public void rowMouseOver(@BindingParam("evt") MouseEvent event) {\r
+               logger.info(event);\r
+       }\r
+\r
+       @Command\r
+       @NotifyChange({ "selectedObject", "hasLowresMediaFile", "hasTSMMediaFile", "lowresMediaFilePath" })\r
+       public void select(@BindingParam("selectedObject") ArchivedMedia selectedObject,\r
+                       @ContextParam(ContextType.BIND_CONTEXT) BindContext ctx) {\r
+               Event event = ctx.getTriggerEvent();\r
+               // Nem mindig a row a target, ha a kepre kattintunk akkor az image\r
+               // selectedRowIndex = ((Row) event.getTarget()).getIndex();\r
+               highlight(this.selectedObject, false);\r
+               setSelectedObject(selectedObject);\r
+               highlight(this.selectedObject, true);\r
+               Clients.scrollIntoView(mediaDetails.getFirstChild());\r
+               logger.info("Media was selected. Selected media archive:{}", selectedObject.getMedia().getId());\r
+       }\r
+\r
+       @NotifyChange({ "typeFilters", "topTypeFilters", "bottomTypeFilters" })\r
+       public void setAllChecked(boolean allChecked) {\r
+               this.allChecked = allChecked;\r
+               for (String key : typeFilters.keySet())\r
+                       typeFilters.get(key).setChecked(allChecked);\r
+               for (TypeFilter topTypeFilter : topTypeFilters)\r
+                       topTypeFilter.setChecked(allChecked);\r
+               for (TypeFilter bottomTypeFilter : bottomTypeFilters)\r
+                       bottomTypeFilter.setChecked(allChecked);\r
+       }\r
+\r
+       public void setAllFilterCheckedValidator(Validator allFilterCheckedValidator) {\r
+               this.allFilterCheckedValidator = allFilterCheckedValidator;\r
+       }\r
+\r
+       public void setAllSelected(boolean allSelected) {\r
+               this.allSelected = allSelected;\r
+               // itemsGrid.renderAll();\r
+               List<Component> components = itemsGrid.getRows().getChildren();\r
+               for (Component obj : components) {\r
+                       Row row = (Row) obj;\r
+                       List<Component> children = row.getChildren();\r
+                       if (children.size() < 2)\r
+                               continue;\r
+                       Component component = children.get(1);\r
+                       if (!(component instanceof Checkbox))\r
+                               continue;\r
+                       Checkbox ck = (Checkbox) component;\r
+                       ck.setChecked(allSelected);\r
+                       MenuModel model = (MenuModel) SessionUtil.getAttribute(SessionUtil.MENUMODEL);\r
+                       model.selectArchivedMedia(row.getValue(), allSelected);\r
+               }\r
+\r
+       }\r
+\r
+       public void setBottomTypeFilters(List<TypeFilter> bottomTypeFilters) {\r
+               this.bottomTypeFilters = bottomTypeFilters;\r
+               addTypeFilters(bottomTypeFilters);\r
+\r
+       }\r
+\r
+       @Command\r
+       @NotifyChange({ "searchFrom", "searchTo", "selectedDateOption" })\r
+       public void setCalendar(@BindingParam(TAGEVT_SOURCE) Menuitem source) {\r
+               int value = Integer.parseInt(source.getValue());\r
+               LocalDate now = LocalDate.now();\r
+               ZoneId zoneId = ZoneId.systemDefault();\r
+               // az elozo, kovetkezo lepteteshez kell\r
+               selectedDateOption = value;\r
+               switch (value) {\r
+               // nap\r
+               case 1:\r
+                       searchFrom = Date.from(now.atStartOfDay(zoneId).toInstant());\r
+                       searchTo = Date.from(now.plusDays(1).atStartOfDay(zoneId).toInstant());\r
+                       break;\r
+               // het\r
+               case 2:\r
+                       ZonedDateTime zdt = now.atStartOfDay(zoneId);\r
+                       // ISO 8601, Monday is first day of week\r
+                       ZonedDateTime firstOfWeek = zdt.with(ChronoField.DAY_OF_WEEK, 1);\r
+                       searchFrom = Date.from(firstOfWeek.toInstant());\r
+                       ZonedDateTime firstOfNextWeek = firstOfWeek.plusWeeks(1);\r
+                       searchTo = Date.from(firstOfNextWeek.toInstant());\r
+                       break;\r
+               // honap\r
+               case 3:\r
+                       searchFrom = Date.from(now.with(firstDayOfMonth()).atStartOfDay(zoneId).toInstant());\r
+                       searchTo = Date.from(now.with(firstDayOfNextMonth()).atStartOfDay(zoneId).toInstant());\r
+                       break;\r
+               // ev\r
+               case 4:\r
+                       searchFrom = Date.from(now.with(firstDayOfYear()).atStartOfDay(zoneId).toInstant());\r
+                       searchTo = Date.from(now.with(firstDayOfNextYear()).atStartOfDay(zoneId).toInstant());\r
+                       break;\r
+               // elozo\r
+               case 100:\r
+                       break;\r
+               // kovetkezo\r
+               case 200:\r
+                       break;\r
+               case 300:\r
+                       searchFrom = null;\r
+                       searchTo = null;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       private void setColumnOrder() {\r
+               if (SessionUtil.getUserColumnOrder() != null) {\r
+                       columnOrder = new HashMap<>();\r
+                       columnOrder.put(SessionUtil.getUserColumnOrder().entrySet().iterator().next().getKey(),\r
+                                       (String) SessionUtil.getUserColumnOrder().entrySet().iterator().next().getValue());\r
+               }\r
+       }\r
+\r
+       public void setDescLength(int descLength) {\r
+               this.descLength = descLength;\r
+       }\r
+\r
+       public void setItemSelected(boolean itemSelected) {\r
+               this.itemSelected = itemSelected;\r
+       }\r
+\r
+       public void setItemSelectedValidator(Validator itemSelectedValidator) {\r
+               this.itemSelectedValidator = itemSelectedValidator;\r
+       }\r
+\r
+       private void setMediaTags(long mediaId) {\r
+               // JavaScript : addMediaTags(['aaa']);\r
+\r
+               List<String> mediaTags = null;\r
+\r
+               if (mediaId > 0)\r
+                       mediaTags = itemManager.getMediaTags(mediaId);\r
+\r
+               // inicializaljuk, hogy az addTag event ezeket mar ne akarja meg 1x hozzadni\r
+               StringBuilder sb = new StringBuilder();\r
+               if (mediaTags != null) {\r
+                       for (String tag : mediaTags) {\r
+                               selectedObject.getTags().add(tag.toLowerCase());\r
+                               if (tag.contains("'"))\r
+                                       continue;\r
+                               if (sb.length() > 0)\r
+                                       sb.append(",");\r
+                               sb.append(String.format("'%s'", tag));\r
+                       }\r
+               }\r
+               sb.insert(0, "addMediaTags([");\r
+               sb.append("]);");\r
+\r
+               String js = sb.toString();\r
+               logger.info(js);\r
+               Clients.evalJavaScript(js);\r
+       }\r
+\r
+       public void setMissingProxy(boolean missingProxy) {\r
+               this.missingProxy = missingProxy;\r
+       }\r
+\r
+       @Command\r
+       public void setPageSize(@BindingParam(TAGEVT_SOURCE) Menuitem source) {\r
+               if (source.isChecked())\r
+                       return;\r
+               int pageSize = Integer.parseInt(source.getValue());\r
+               setSettingsPageSize(pageSize);\r
+               itemsGrid.setPageSize(pageSize);\r
+               itemsGrid.setActivePage(0);\r
+               SessionUtil.putUserPageSize(pageSize);\r
+       }\r
+\r
+       public void setRowsExpanded(boolean rowsExpanded) {\r
+               this.rowsExpanded = rowsExpanded;\r
+       }\r
+\r
+       public void setSearchFrom(Date searchFrom) {\r
+               this.searchFrom = searchFrom;\r
+       }\r
+\r
+       public void setSearchHistory(ListModelList<String> searchHistory) {\r
+               this.searchHistory = searchHistory;\r
+       }\r
+\r
+       private void setSearchTags() {\r
+               // JavaScript : addAllTags(['aaa', 'bbb', 'ccc']);\r
+               if (tags == null)\r
+                       return;\r
+\r
+               StringBuilder sb = new StringBuilder();\r
+               for (String tag : tags.keySet()) {\r
+                       if (tag.contains("'"))\r
+                               continue;\r
+                       if (sb.length() > 0)\r
+                               sb.append(",");\r
+                       sb.append(String.format("'%s'", StringUtils.escape(tag)));\r
+               }\r
+               if (sb.length() > 0) {\r
+                       sb.insert(0, "addAllTags([");\r
+                       sb.append("]);");\r
+\r
+                       String js = sb.toString();\r
+                       logger.info(js);\r
+                       Clients.evalJavaScript(js);\r
+               }\r
+       }\r
+\r
+       public void setSearchTo(Date searchTo) {\r
+               this.searchTo = searchTo;\r
+       }\r
+\r
+       public void setSelectedDateOption(int selectedDateOption) {\r
+               this.selectedDateOption = selectedDateOption;\r
+       }\r
+\r
+       @NotifyChange({ "selectedObject", "hasLowresMediaFile", "hasTSMMediaFile", "lowresMediaFilePath" })\r
+       public void setSelectedObject(ArchivedMedia selectedObject) {\r
+               this.selectedObject = selectedObject;\r
+               if (selectedObject != null) {\r
+                       long mediaId = selectedObject.getMedia().getId();\r
+                       selectedObject.setMedia(itemManager.getMedia(mediaId));\r
+                       selectedObject.setItem(itemManager.getItem(selectedObject.getMedia().getItemId()));\r
+\r
+                       // tags\r
+                       setMediaTags(mediaId);\r
+\r
+                       try {\r
+                               // proxy\r
+                               String video = getLowresMediaFilePath();\r
+                               if (video == null) {\r
+                                       Clients.evalJavaScript("setSource(null, null)");\r
+                               } else {\r
+                                       String srcType = null;\r
+                                       if (video.endsWith(".m3u8"))\r
+                                               srcType = "application/x-mpegURL";\r
+                                       else\r
+                                               srcType = "video/mp4";\r
+\r
+                                       Clients.evalJavaScript(String.format("setSource('%s', '%s')", video, srcType));\r
+                               }\r
+\r
+                       } catch (Exception e) {\r
+                               logger.error(e);\r
+                       }\r
+\r
+               } else\r
+                       Clients.evalJavaScript("addMediaTags([]);");\r
+\r
+       }\r
+\r
+       private void setSettingsPageSize(int pageSize) {\r
+               List<Component> searchSettingItems = searchSettings.getChildren();\r
+               for (Component c : searchSettingItems) {\r
+                       if (!(c instanceof Menuitem))\r
+                               continue;\r
+                       Menuitem menuItem = (Menuitem) c;\r
+                       String value = menuItem.getValue();\r
+                       if (String.valueOf(pageSize).equals(value))\r
+                               menuItem.setChecked(true);\r
+                       else\r
+                               menuItem.setChecked(false);\r
+               }\r
+       }\r
+\r
+       public void setTopTypeFilters(List<TypeFilter> topTypeFilters) {\r
+               this.topTypeFilters = topTypeFilters;\r
+               addTypeFilters(topTypeFilters);\r
+       }\r
+\r
+       private void setUserSelectedFilters() {\r
+               List<String> selectedFilters = SessionUtil.getUserSearchFilter();\r
+               if (selectedFilters != null) {\r
+                       clearAllFilters();\r
+                       for (String filter : selectedFilters) {\r
+                               if (typeFilters.containsKey(filter)) {\r
+                                       TypeFilter typeFilter = typeFilters.get(filter);\r
+                                       typeFilter.setChecked(true);\r
+                                       typeFilters.put(filter, typeFilter);\r
+                               }\r
+                       }\r
+                       if (typeFilters.size() != selectedFilters.size())\r
+                               allChecked = false;\r
+               }\r
+       }\r
+\r
+       private void showExternalMediaID() {\r
+               String mediaId = SessionUtil.getQueryParameter(MEDIA_ID);\r
+               if (mediaId == null)\r
+                       return;\r
+               try {\r
+                       SearchOptions options = SearchOptions.create().setMediaId(Long.parseLong(mediaId));\r
+                       searchResult = new InitializedCachedListModel(options);\r
+               } catch (Exception e) {\r
+                       Messagebox.show(e.getMessage(), "Hiba!", Messagebox.OK, Messagebox.ERROR);\r
+               }\r
+       }\r
+\r
+       @Command\r
+       @NotifyChange("itemsGrid")\r
+       public void showInResults() {\r
+               if (selectedObject == null)\r
+                       return;\r
+               int activePageIndex = selectedRowIndex / itemsGrid.getPageSize();\r
+               positionToScroll = selectedRowIndex - itemsGrid.getPageSize() * activePageIndex;\r
+               // preventAfterRender = true;\r
+               if (activePageIndex != itemsGrid.getActivePage()) {\r
+                       itemsGrid.setActivePage(activePageIndex);\r
+                       logger.info(\r
+                                       "Selected media is shown in the results, which can be found on {} page and also it will be highlighted.",\r
+                                       activePageIndex + 1);\r
+               } else {\r
+                       // TODO for debug purposes\r
+                       // onAfterRenderGrid();\r
+                       logger.info("Selected media is shown in the results, which can be found on opened page.");\r
+               }\r
+       }\r
+\r
+       private void showSearchTypeWarning() {\r
+               Clients.showNotification(String.format(\r
+                               "Figyelem!<br><br><span style='white-space:nowrap'> A keresés eredménye nem tartalmazza az összes típust.</span>"),\r
+                               "warning", toggleShowTypeFilters, "end_center", 3000);\r
+       }\r
+\r
+       @Command\r
+       public void toggleTypeFiltersCheck() {\r
+               boolean visible = toggleShowTypeFilters.isChecked();\r
+               toggleShowTypeFilters.setIconSclass(visible ? "z-icon-caret-up" : "z-icon-caret-down");\r
+               serachDetails.setOpen(visible);\r
+               SessionUtil.putUserTypeFiltersVisibility(visible);\r
+       }\r
+\r
+       public void updateAllChecked() {\r
+               final boolean[] check = { true };\r
+               for (String key : typeFilters.keySet()) {\r
+                       if (!typeFilters.get(key).isChecked()) {\r
+                               check[0] = false;\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               registerTask(() -> {\r
+                       allChecked = check[0];\r
+                       notifyChange("allChecked");\r
+               });\r
+               timer.start();\r
+       }\r
+\r
+}\r