001 // This file is part of the Attempto Java Packages. 002 // Copyright 2008-2009, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch). 003 // 004 // The Attempto Java Packages is free software: you can redistribute it and/or modify it under the 005 // terms of the GNU Lesser General Public License as published by the Free Software Foundation, 006 // either version 3 of the License, or (at your option) any later version. 007 // 008 // The Attempto Java Packages is distributed in the hope that it will be useful, but WITHOUT ANY 009 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 010 // PURPOSE. See the GNU Lesser General Public License for more details. 011 // 012 // You should have received a copy of the GNU Lesser General Public License along with the Attempto 013 // Java Packages. If not, see http://www.gnu.org/licenses/. 014 015 package ch.uzh.ifi.attempto.preditor; 016 017 import java.util.ArrayList; 018 import java.util.HashMap; 019 import java.util.List; 020 021 import ch.uzh.ifi.attempto.chartparser.ChartParser; 022 import ch.uzh.ifi.attempto.chartparser.Restriction; 023 import ch.uzh.ifi.attempto.chartparser.Terminal; 024 import ch.uzh.ifi.attempto.preditor.text.TextElement; 025 026 /** 027 * This abstract class is used for the predictive editor to create menus on the basis of categories of the grammar. 028 * 029 * @author Tobias Kuhn 030 */ 031 public abstract class MenuCreator { 032 033 private HashMap<String, MenuBlockContent> contentsMap = new HashMap<String, MenuBlockContent>(); 034 private List<MenuBlockContent> contentsList = new ArrayList<MenuBlockContent>(); 035 private Restriction restriction; 036 private int id; 037 038 /** 039 * Initializes a new menu creator object. 040 */ 041 public MenuCreator() { 042 } 043 044 /** 045 * An implementation of this abstract method should add menu items that comply with the given restriction. 046 * This should be done by calling {@link #addMenuItem addMenuItem} and/or {@link #addMenuEntry addMenuEntry}. 047 * 048 * @param restriction The restriction for the menu items. 049 */ 050 protected abstract void addMenuItems(Restriction restriction); 051 052 /** 053 * This abstract method is called when the predictive editor is refreshed (before the first call of 054 * {@link #addMenuItems addMenuItems}). This is a good place for calling {@link #prepareMenuBlock(String) prepareMenuBlock}. 055 */ 056 public abstract void initMenuCreation(); 057 058 /** 059 * Prepares a new menu block (if there is no such menu block already with the same name). The menu blocks are 060 * shown in the predictive editor in the same order as they have been prepared. 061 * 062 * @param menuBlockName The name of the menu block. 063 */ 064 public void prepareMenuBlock(String menuBlockName) { 065 prepareMenuBlock(menuBlockName, false); 066 } 067 068 /** 069 * Prepares a new menu block (if there is no such menu block already with the same name). The second parameter 070 * defines whether the items of the menu block should be sorted. The menu blocks are 071 * shown in the predictive editor in the same order as they have been prepared. 072 * 073 * @param menuBlockName The name of the menu block. 074 * @param doSort true if the items should be sorted. 075 */ 076 public void prepareMenuBlock(String menuBlockName, boolean doSort) { 077 if (contentsMap.containsKey(menuBlockName)) { 078 return; 079 } 080 MenuBlockContent menuBlockContent = new MenuBlockContent(menuBlockName, doSort); 081 contentsMap.put(menuBlockName, menuBlockContent); 082 contentsList.add(menuBlockContent); 083 } 084 085 /** 086 * Adds the menu item to the given menu block. If no menu block of this name has been prepared at this point then 087 * the preparation is done first. 088 * 089 * @param menuBlockName The name of the menu block. 090 * @param menuItem The menu item to be added to the menu block. 091 */ 092 public void addMenuItem(String menuBlockName, MenuItem menuItem) { 093 if (menuItem instanceof MenuEntry) { 094 MenuEntry me = (MenuEntry) menuItem; 095 me.getTextElement().setID(id); 096 boolean restrFulfilled = me.getTextElement().applyRestriction(restriction); 097 if (!restrFulfilled) return; 098 } 099 if (!contentsMap.containsKey(menuBlockName)) { 100 prepareMenuBlock(menuBlockName); 101 } 102 contentsMap.get(menuBlockName).addItem(menuItem); 103 } 104 105 /** 106 * Adds a new menu entry containing the text element to the menu block. If no menu block of this name has been 107 * prepared at this point then the preparation is done first. 108 * 109 * @param menuBlockName The name of the menu block. 110 * @param textElement The text element of the menu entry that is created and then added to the menu block. 111 */ 112 public void addMenuEntry(String menuBlockName, TextElement textElement) { 113 textElement.setID(id); 114 boolean restrFulfilled = textElement.applyRestriction(restriction); 115 if (!restrFulfilled) return; 116 if (!contentsMap.containsKey(menuBlockName)) { 117 prepareMenuBlock(menuBlockName); 118 } 119 contentsMap.get(menuBlockName).addEntry(textElement); 120 } 121 122 synchronized List<MenuBlockContent> createMenu(ChartParser parser) { 123 contentsMap.clear(); 124 contentsList.clear(); 125 126 initMenuCreation(); 127 128 for (Restriction r : parser.getNextTokenRestrictions()) { 129 restriction = r; 130 id = parser.getTokens().size(); 131 addMenuItems(r); 132 } 133 134 return new ArrayList<MenuBlockContent>(contentsList); 135 } 136 137 /** 138 * Adds menu entries that stand for variables in the form of "X", "Y", "Z", "X1", "Y1", and so on. 139 * 140 * @param menuBlockName The name of the menu block into which the entries should be added. 141 * @param num The number upto which the variables should be enumerated. 142 * @param categoryName The category name of the entries. 143 */ 144 public void addVariableEntries(String menuBlockName, int num, String categoryName) { 145 ArrayList<String> varNames = new ArrayList<String>(); 146 varNames.add("X"); 147 varNames.add("Y"); 148 varNames.add("Z"); 149 for (int i=1; i<=num; i++) { 150 varNames.add("X" + i); 151 varNames.add("Y" + i); 152 varNames.add("Z" + i); 153 } 154 for (String s : varNames) { 155 Terminal t = new Terminal(categoryName); 156 t.setFeature("text", s); 157 addMenuEntry(menuBlockName, new TextElement(s, t)); 158 } 159 } 160 161 }