001 /**
002 * Copyright 2010 The Kuali Foundation Licensed under the
003 * Educational Community License, Version 2.0 (the "License"); you may
004 * not use this file except in compliance with the License. You may
005 * obtain a copy of the License at
006 *
007 * http://www.osedu.org/licenses/ECL-2.0
008 *
009 * Unless required by applicable law or agreed to in writing,
010 * software distributed under the License is distributed on an "AS IS"
011 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
012 * or implied. See the License for the specific language governing
013 * permissions and limitations under the License.
014 */
015
016 package org.kuali.student.lum.common.client.lo;
017
018 import java.util.ArrayList;
019 import java.util.HashMap;
020 import java.util.Map;
021
022 import org.kuali.student.common.assembly.data.QueryPath;
023 import org.kuali.student.common.ui.client.configurable.mvc.FieldDescriptor;
024 import org.kuali.student.common.ui.client.configurable.mvc.sections.VerticalSection;
025 import org.kuali.student.common.ui.client.theme.Theme;
026 import org.kuali.student.common.ui.client.widgets.field.layout.element.MessageKeyInfo;
027
028 import com.google.gwt.event.dom.client.MouseMoveHandler;
029 import com.google.gwt.event.logical.shared.ValueChangeEvent;
030 import com.google.gwt.event.logical.shared.ValueChangeHandler;
031 import com.google.gwt.event.shared.HandlerRegistration;
032 import com.google.gwt.user.client.DOM;
033 import com.google.gwt.user.client.Event;
034 import com.google.gwt.user.client.ui.HasValue;
035 import com.google.gwt.user.client.ui.HorizontalPanel;
036 import com.google.gwt.user.client.ui.Image;
037 import com.google.gwt.user.client.ui.Label;
038 import com.google.gwt.user.client.ui.VerticalPanel;
039 import com.google.gwt.user.client.ui.Widget;
040
041
042 public class OutlineManager extends VerticalSection implements HasValue<OutlineNodeModel> {
043 OutlineNodeModel<?> outlineModel;
044 String startOfPath;
045 String endOfPath;
046 String middleOfPath;
047
048 public OutlineManager(String pathStart, String pathMiddle, String pathEnd) {
049 startOfPath = pathStart;
050 middleOfPath = pathMiddle;
051 endOfPath = pathEnd;
052 }
053
054 public void render() {
055 Map<Integer, Integer> levelIndexes = new HashMap<Integer, Integer>();
056 int currIndent = 0;
057
058 levelIndexes.put(0, -1); // first node increments the 0'th indent's index
059 OutlineNode[] outlineNodes = outlineModel.toOutlineNodes();
060 for (final OutlineNode aNode : outlineNodes) {
061 NodePanel nodePanel = new NodePanel();
062 nodePanel.setStyleName("KS-LONodePanel");
063 nodePanel.setOutlineNode(aNode);
064 if (aNode.getIndentLevel() > currIndent) {
065 currIndent = aNode.getIndentLevel();
066 levelIndexes.put(currIndent, 0);
067 } else if (aNode.getIndentLevel() < currIndent) {
068 currIndent = aNode.getIndentLevel();
069 levelIndexes.put(currIndent, levelIndexes.get(currIndent) + 1);
070 } else {
071 levelIndexes.put(currIndent, levelIndexes.get(currIndent) + 1);
072 }
073
074 addField(getFieldKey(currIndent, levelIndexes), null, nodePanel, null);
075
076 showAllToolbar();
077 }
078 }
079
080 private String getFieldKey(int currIndent, Map<Integer, Integer> levelIndexes) {
081 StringBuilder keyBuilder = new StringBuilder(startOfPath);
082
083 keyBuilder.append("/").append(levelIndexes.get(0)).append("/");
084 for (int idx = 1; idx <= currIndent; idx++) {
085 keyBuilder.append(middleOfPath).append("/").append(levelIndexes.get(idx)).append("/");
086 }
087 keyBuilder.append(endOfPath);
088
089 return keyBuilder.toString();
090 }
091
092 private FieldDescriptor addField(String fieldKey, MessageKeyInfo messageKey, Widget widget, String parentPath) {
093 QueryPath path = QueryPath.concat(parentPath, fieldKey);
094
095 FieldDescriptor fd = new FieldDescriptor(path.toString(), messageKey, null);
096 if (widget != null) {
097 fd.setFieldWidget(widget);
098 fd.setHasHadFocus(true);
099 }
100 this.addField(fd);
101 return fd;
102 }
103
104 public void closeAllToolbar(){
105 for (FieldDescriptor fd : this.getFields()) {
106 if (fd.getFieldWidget() instanceof NodePanel) {
107 ((NodePanel) fd.getFieldWidget()).hideToolbar();
108 }
109 }
110 }
111
112 public void showAllToolbar(){
113 for (FieldDescriptor fd : this.getFields()) {
114 if (fd.getFieldWidget() instanceof NodePanel) {
115 ((NodePanel) fd.getFieldWidget()).showToolbar();
116 }
117 }
118 }
119
120 class NodePanel extends VerticalPanel{
121 OutlineManagerToolbar toolbar = new OutlineManagerToolbar();
122 HorizontalPanel emptySpacePanel = new HorizontalPanel();
123 ArrayList<MouseMoveHandler> mouseMoveHandlerList = new ArrayList<MouseMoveHandler>();
124 HorizontalPanel horitonalPanel = new HorizontalPanel();
125 OutlineNode currentNode;
126 NodePanel() {
127 toolbar.setModel(outlineModel);
128 horitonalPanel.setStyleName("KS-LOHNodePanel");
129 super.sinkEvents(Event.ONMOUSEMOVE);
130 super.sinkEvents(Event.ONMOUSEOUT);
131 emptySpacePanel.setStyleName("KS-LOOutlineManagerToolbar");
132 Image ieHack = Theme.INSTANCE.getCommonImages().getSpacer();
133 emptySpacePanel.add(ieHack);
134 super.insert(emptySpacePanel,0);
135 }
136
137 public void setOutlineNode(OutlineNode aNode) {
138 currentNode = aNode;
139 for (int i = 0; i < aNode.getIndentLevel(); i++) {
140 Label label = new Label();
141 label.setStyleName("KS-LONodeIndent");
142 horitonalPanel.add(label);
143
144 // space for toolbar
145 label = new Label();
146 label.setStyleName("KS-LONodeIndentToolbar");
147 toolbar.insert(label, 0);
148 }
149 Widget userWidget = (Widget) aNode.getUserObject();
150 userWidget.setStyleName("KS-LOaNode");
151 horitonalPanel.add(userWidget);
152
153 add(horitonalPanel);
154 }
155
156 public void addMouseMoveHandler(MouseMoveHandler handler) {
157 mouseMoveHandlerList.add(handler);
158 }
159
160 public void setToolbar(OutlineManagerToolbar t) {
161 toolbar = t;
162 }
163 public void showToolbar(){
164 super.remove(emptySpacePanel);
165 super.insert(toolbar, 0);
166 }
167 public void hideToolbar(){
168 super.remove(toolbar);
169 super.insert(emptySpacePanel,0);
170 }
171 @Override
172 public void onBrowserEvent(Event event) {
173 switch (DOM.eventGetType(event)) {
174 case Event.ONMOUSEMOVE: {
175 outlineModel.setCurrentNode(currentNode);
176 break;
177 }
178 case Event.ONMOUSEOUT:
179 break;
180 }
181 super.onBrowserEvent(event);
182 }
183
184 @Override
185 protected void onEnsureDebugId(String baseID) {
186 super.onEnsureDebugId(baseID);
187 toolbar.ensureDebugId(baseID);
188 if (currentNode != null) {
189 Object userObject = currentNode.getUserObject();
190 if (userObject instanceof Widget) {
191 ((Widget) userObject).ensureDebugId(baseID);
192 }
193 }
194 }
195
196
197 }
198
199 @Override
200 public OutlineNodeModel getValue() {
201 return outlineModel;
202 }
203
204 @Override
205 public void setValue(OutlineNodeModel value) {
206 outlineModel = value;
207 }
208
209 @Override
210 public void setValue(OutlineNodeModel value, boolean fireEvents) {
211 setValue(value);
212 }
213
214 @Override
215 public HandlerRegistration addValueChangeHandler(ValueChangeHandler<OutlineNodeModel> handler) {
216 return addHandler(handler, ValueChangeEvent.getType());
217 }
218 }