001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.ui.apps.modules; 029 030import org.opencms.main.OpenCms; 031import org.opencms.module.CmsModule; 032import org.opencms.ui.A_CmsUI; 033import org.opencms.ui.CmsVaadinUtils; 034import org.opencms.ui.FontOpenCms; 035import org.opencms.ui.apps.A_CmsAttributeAwareApp; 036import org.opencms.ui.apps.Messages; 037import org.opencms.ui.components.CmsBasicDialog; 038import org.opencms.ui.components.CmsBasicDialog.DialogWidth; 039import org.opencms.ui.components.CmsInfoButton; 040import org.opencms.ui.components.CmsToolBar; 041import org.opencms.ui.contextmenu.CmsContextMenu; 042import org.opencms.ui.util.table.CmsBeanTableBuilder; 043 044import java.util.Collections; 045import java.util.LinkedHashSet; 046import java.util.List; 047import java.util.Map; 048import java.util.Set; 049 050import com.google.common.collect.Lists; 051import com.google.common.collect.Maps; 052import com.vaadin.shared.MouseEventDetails.MouseButton; 053import com.vaadin.ui.Button; 054import com.vaadin.ui.Button.ClickEvent; 055import com.vaadin.ui.Button.ClickListener; 056import com.vaadin.ui.Component; 057import com.vaadin.ui.UI; 058import com.vaadin.ui.Window; 059import com.vaadin.ui.themes.ValoTheme; 060import com.vaadin.v7.data.Container; 061import com.vaadin.v7.data.util.BeanItemContainer; 062import com.vaadin.v7.event.FieldEvents.TextChangeEvent; 063import com.vaadin.v7.event.FieldEvents.TextChangeListener; 064import com.vaadin.v7.event.ItemClickEvent; 065import com.vaadin.v7.event.ItemClickEvent.ItemClickListener; 066import com.vaadin.v7.ui.HorizontalLayout; 067import com.vaadin.v7.ui.Table; 068import com.vaadin.v7.ui.TextField; 069 070/** 071 * Overview list for module information.<p> 072 * 073 * @param <T> the row type 074 */ 075public class CmsModuleTable<T> extends Table { 076 077 /** The serial version id. */ 078 private static final long serialVersionUID = 1L; 079 080 /** The module manager app instance. */ 081 protected CmsModuleApp m_app; 082 083 /** The table builder. */ 084 protected CmsBeanTableBuilder<T> m_tableBuilder; 085 086 /** The row counter label. */ 087 private CmsInfoButton m_counter; 088 089 /** The context menu. */ 090 protected CmsContextMenu m_menu = new CmsContextMenu(); 091 092 /** The search box. */ 093 private TextField m_searchBox = new TextField(); 094 095 /** 096 * Creates a new instance.<p> 097 * 098 * @param app the module manager app instance.<p> 099 * @param rowType the row type 100 * @param rows the module rows 101 */ 102 public CmsModuleTable(CmsModuleApp app, Class<T> rowType, List<T> rows) { 103 104 m_menu.setAsTableContextMenu(this); 105 m_app = app; 106 addItemClickListener(new ItemClickListener() { 107 108 private static final long serialVersionUID = 1L; 109 110 @Override 111 public void itemClick(ItemClickEvent event) { 112 113 CmsModuleTable.this.onItemClick(event); 114 } 115 }); 116 m_searchBox.addTextChangeListener(new TextChangeListener() { 117 118 private static final long serialVersionUID = 1L; 119 120 @Override 121 public void textChange(TextChangeEvent event) { 122 123 String filterString = event.getText(); 124 filter(filterString); 125 } 126 127 }); 128 m_searchBox.setIcon(FontOpenCms.FILTER); 129 m_searchBox.setInputPrompt( 130 Messages.get().getBundle(UI.getCurrent().getLocale()).key(Messages.GUI_EXPLORER_FILTER_0)); 131 m_searchBox.addStyleName(ValoTheme.TEXTFIELD_INLINE_ICON); 132 m_searchBox.setWidth("200px"); 133 134 Map<String, Object> attributes = Maps.newHashMap(); 135 136 HorizontalLayout hl = new HorizontalLayout(); 137 hl.setSpacing(true); 138 139 hl.addComponent(m_searchBox); 140 // hl.setComponentAlignment(m_counter, Alignment.MIDDLE_LEFT); 141 attributes.put(A_CmsAttributeAwareApp.ATTR_INFO_COMPONENT, hl); 142 attributes.put(A_CmsAttributeAwareApp.ATTR_MAIN_HEIGHT_FULL, Boolean.TRUE); 143 List<Component> buttons = Lists.newArrayList(); 144 Button addModule = CmsToolBar.createButton( 145 FontOpenCms.WAND, 146 CmsVaadinUtils.getMessageText(Messages.GUI_MODULES_BUTTON_NEW_MODULE_0)); 147 addModule.addClickListener(new ClickListener() { 148 149 private static final long serialVersionUID = 1L; 150 151 @Override 152 public void buttonClick(ClickEvent event) { 153 154 m_app.editNewModule(CmsModuleTable.this::reload); 155 } 156 }); 157 buttons.add(addModule); 158 159 Button importButton = CmsToolBar.createButton( 160 CmsModuleApp.Icons.IMPORT, 161 CmsVaadinUtils.getMessageText(Messages.GUI_MODULES_BUTTON_IMPORT_0)); 162 importButton.addClickListener(new ClickListener() { 163 164 private static final long serialVersionUID = 1L; 165 166 @Override 167 public void buttonClick(ClickEvent event) { 168 169 importModule(); 170 } 171 }); 172 173 buttons.add(importButton); 174 m_counter = new CmsInfoButton(); 175 m_counter.setWindowCaption(CmsVaadinUtils.getMessageText(Messages.GUI_MODULES_STATISTICS_0)); 176 m_counter.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_MODULES_STATISTICS_0)); 177 buttons.add(m_counter); 178 attributes.put(CmsModuleApp.Attributes.BUTTONS, buttons); 179 setData(attributes); 180 CmsBeanTableBuilder<T> builder = CmsBeanTableBuilder.newInstance(rowType); 181 m_tableBuilder = builder; 182 builder.buildTable(this, rows); 183 setCellStyleGenerator(builder.getDefaultCellStyleGenerator()); 184 setItemIconPropertyId("icon"); 185 setRowHeaderMode(RowHeaderMode.ICON_ONLY); 186 setSelectable(true); 187 setMultiSelect(false); 188 sort(new Object[] {"name"}, new boolean[] {true}); 189 updateCounter(); 190 } 191 192 /** 193 * Applies the given filter. 194 * 195 * @param filterString a filter string 196 */ 197 public void filter(String filterString) { 198 199 m_searchBox.setValue(filterString); 200 Container.Filterable container = (Container.Filterable)getContainerDataSource(); 201 container.removeAllContainerFilters(); 202 container.addContainerFilter(m_tableBuilder.getDefaultFilter(filterString)); 203 if ((getValue() != null)) { 204 setCurrentPageFirstItemId(getValue()); 205 } 206 } 207 208 /** 209 * Gets the search field. 210 * 211 * @return the search field 212 */ 213 public TextField getSearchBox() { 214 215 return m_searchBox; 216 } 217 218 /** 219 * Opens the import module dialog.<p> 220 */ 221 public void importModule() { 222 223 Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide); 224 CmsImportTabForm form = new CmsImportTabForm(m_app, this::reload); 225 window.setContent(form); 226 window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_MODULES_IMPORT_TITLE_0)); 227 A_CmsUI.get().addWindow(window); 228 window.center(); 229 } 230 231 /** 232 * Reloads the table data.<p> 233 */ 234 public void reload() { 235 236 List<CmsModule> modules = OpenCms.getModuleManager().getAllInstalledModules(); 237 @SuppressWarnings("unchecked") 238 BeanItemContainer<CmsModuleRow> container = (BeanItemContainer<CmsModuleRow>)getContainerDataSource(); 239 container.removeAllItems(); 240 List<CmsModuleRow> newRows = Lists.newArrayList(); 241 for (CmsModule module : modules) { 242 CmsModuleRow row = new CmsModuleRow(module); 243 newRows.add(row); 244 } 245 container.addAll(newRows); 246 sort(); 247 updateCounter(); 248 } 249 250 /** 251 * Handles the table item clicks.<p> 252 * 253 * @param event the click event 254 */ 255 protected void onItemClick(ItemClickEvent event) { 256 257 if (!event.isCtrlKey() && !event.isShiftKey()) { 258 259 Set<String> nameSet = new LinkedHashSet<String>(); 260 261 CmsModuleRow moduleRow = (CmsModuleRow)(event.getItemId()); 262 select(moduleRow); 263 nameSet.add(moduleRow.getModule().getName()); 264 if (event.getButton().equals(MouseButton.RIGHT) || (event.getPropertyId() == null)) { 265 select(moduleRow); 266 m_menu.setEntries(m_app.getMenuEntries(), nameSet); 267 m_menu.openForTable(event, this); 268 } else if (event.getButton().equals(MouseButton.LEFT) && "name".equals(event.getPropertyId())) { 269 270 m_app.openModuleInfo(nameSet); 271 } 272 273 } 274 } 275 276 /** 277 * Updates the row counter.<p> 278 */ 279 private void updateCounter() { 280 281 m_counter.replaceData( 282 Collections.singletonMap( 283 CmsVaadinUtils.getMessageText(Messages.GUI_MODULES_STATISTICS_ROW_COUNT_0), 284 String.valueOf(getContainerDataSource().size()))); 285 } 286 287}