001/* 002 * ModeShape (http://www.modeshape.org) 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.modeshape.web.client.contents; 017 018import com.google.gwt.user.client.rpc.AsyncCallback; 019import com.smartgwt.client.types.Alignment; 020import com.smartgwt.client.types.VerticalAlignment; 021import com.smartgwt.client.util.BooleanCallback; 022import com.smartgwt.client.util.SC; 023import com.smartgwt.client.widgets.Label; 024import com.smartgwt.client.widgets.events.ClickEvent; 025import com.smartgwt.client.widgets.events.ClickHandler; 026import com.smartgwt.client.widgets.layout.HLayout; 027import java.util.Collection; 028import org.modeshape.web.client.contents.ChildrenEditor.NodeRecord; 029import org.modeshape.web.client.grid.Grid; 030import org.modeshape.web.client.grid.Pager; 031import org.modeshape.web.shared.Align; 032import org.modeshape.web.shared.Columns; 033import org.modeshape.web.shared.JcrNode; 034 035/** 036 * 037 * @author kulikov 038 */ 039public class ChildrenEditor extends Grid<NodeRecord, JcrNode> { 040 041 private JcrNode node; 042 private final Contents contents; 043 private final RenameNodeDialog renameNodeDialog; 044 private final ChildNodesPager pager = new ChildNodesPager(); 045 046 047 private Label hint; 048 049 public ChildrenEditor(Contents contents) { 050 super("Child nodes"); 051 this.contents = contents; 052 this.setFooterContent(pager); 053 renameNodeDialog = new RenameNodeDialog(contents); 054 } 055 056 public void show(JcrNode node) { 057 this.node = node; 058 059 pager.setRecordsAmount((int)node.getChildCount()); 060 pager.fetch(0); 061 062 String hintText = node.hasBinaryContent() ? 063 "This node has binary content attached. See bellow" : 064 "This node has no binary content attached"; 065 hint.setContents(hintText); 066 } 067 068 @Override 069 protected HLayout tableHeader() { 070 HLayout header = new HLayout(); 071 header.setHeight(30); 072 header.setBackgroundColor("#e6f1f6"); 073 074 Label name = new Label("<b>Name</b>"); 075 name.setWidth(150); 076 name.setIcon("icons/view_tree_modernist.png"); 077 078 Label type = new Label("<b>Primary Type</b>"); 079 type.setWidth(150); 080 type.setIcon("icons/documents.png"); 081 082 Label path = new Label("<b>Path</b>"); 083 path.setWidth100(); 084 path.setIcon("icons/view_table.png"); 085 086 087 header.addMember(name); 088 header.addMember(type); 089 header.addMember(path); 090 091 return header; 092 } 093 094 @SuppressWarnings("synthetic-access") 095 @Override 096 protected HLayout toolBar() { 097 hint = new Label(); 098 hint.setWidth100(); 099 100 Label hint2 = new Label(); 101 hint2.setContents("Enable/Disbale properties"); 102 hint2.setWidth(250); 103 hint2.setAlign(Alignment.RIGHT); 104 105 Label detailsButton = new Label(); 106 detailsButton.setTooltip("Show details"); 107 detailsButton.setStyleName("button-label"); 108 detailsButton.setWidth(16); 109 detailsButton.setIcon("icons/view_table.png"); 110 detailsButton.addClickHandler(new ClickHandler() { 111 @Override 112 public void onClick(ClickEvent event) { 113 contents.toggleDetails(); 114 } 115 }); 116 117 Columns col = new Columns(Align.LEFT, Align.CENTER); 118 col.setBackgroundColor("#ffffff"); 119 120 col.setHeight(30); 121 col.addMember(hint); 122 col.addMember(hint2); 123 col.addMember(detailsButton); 124 125 return col; 126 } 127 128 @Override 129 protected NodeRecord[] records() { 130 NodeRecord[] recs = new NodeRecord[100]; 131 for (int i = 0; i < recs.length; i++) { 132 recs[i] = new NodeRecord(); 133 } 134 return recs; 135 } 136 137 @SuppressWarnings("synthetic-access") 138 @Override 139 protected void updateRecord(int pos, NodeRecord record, JcrNode value) { 140 if (pos <= 0) { 141 record.setNodeAsParent(ChildrenEditor.this.node); 142 record.setVisible(!node.getPath().equals("/")); 143 } else { 144 record.setNode(value); 145 } 146 } 147 148 public class NodeRecord extends HLayout { 149 150 private Label name = new Label(); 151 private Label path = new Label(); 152 private Label primaryType = new Label(); 153 private Buttons buttons = new Buttons(); 154 private JcrNode node; 155 156 public NodeRecord() { 157 super(); 158 setStyleName("grid"); 159 setHeight(30); 160 161 setDefaultLayoutAlign(VerticalAlignment.CENTER); 162 setDefaultLayoutAlign(Alignment.LEFT); 163 164 setLayoutAlign(VerticalAlignment.CENTER); 165 setLayoutAlign(Alignment.CENTER); 166 167 setAlign(VerticalAlignment.CENTER); 168 setAlign(Alignment.LEFT); 169 170 name.setStyleName("node-name"); 171 name.setIcon("icons/folder.png"); 172 name.addClickHandler(new ClickHandler() { 173 @SuppressWarnings("synthetic-access") 174 @Override 175 public void onClick(ClickEvent event) { 176 contents.getAndDisplayNode(path(), true); 177 } 178 }); 179 180 name.setWidth(150); 181 primaryType.setWidth(150); 182 primaryType.setStyleName("text"); 183 184 path.setWidth100(); 185 path.setStyleName("text"); 186 187 188 addMember(name); 189 addMember(primaryType); 190 addMember(path); 191 addMember(buttons); 192 } 193 194 private String path() { 195 return node == null ? "/" : path.getContents(); 196 } 197 198 private void setNode(JcrNode node) { 199 this.node = node; 200 this.name.setContents(node.getName()); 201 this.path.setContents(node.getPath()); 202 this.path.setVisible(true); 203 this.buttons.setVisible(true); 204 this.buttons.setNode(node); 205 this.primaryType.setContents(node.getPrimaryType()); 206 } 207 208 private void setNodeAsParent(JcrNode node) { 209 this.node = node; 210 this.name.setContents("<b>../</b>"); 211 this.path.setContents(parent(node.getPath())); 212 this.path.setVisible(false); 213 this.buttons.setVisible(false); 214 this.buttons.setNode(node); 215 this.primaryType.setContents(""); 216 } 217 218 private String parent(String path) { 219 if (path == null) { 220 return "/"; 221 } 222 223 path = path.substring(0, path.lastIndexOf('/')); 224 if (path.length() == 0) { 225 return "/"; 226 } 227 228 return path; 229 } 230 } 231 232 private class Buttons extends HLayout { 233 234 private Label editButton = new Label(); 235 private Label remButton = new Label(); 236 private JcrNode node; 237 238 public Buttons() { 239 this.setWidth(36); 240 241 this.setDefaultLayoutAlign(Alignment.RIGHT); 242 this.setLayoutAlign(Alignment.RIGHT); 243 this.setAlign(Alignment.RIGHT); 244 this.setDefaultLayoutAlign(VerticalAlignment.CENTER); 245 this.setLayoutAlign(VerticalAlignment.CENTER); 246 this.setAlign(VerticalAlignment.CENTER); 247 248 editButton.setWidth(16); 249 editButton.setHeight(16); 250 editButton.setIcon("icons/pencil.png"); 251 editButton.setStyleName("button-label"); 252 editButton.addClickHandler(new ClickHandler() { 253 @Override 254 public void onClick(ClickEvent event) { 255 renameNodeDialog.showModal(node); 256 } 257 }); 258 259 remButton.setWidth(16); 260 remButton.setHeight(16); 261 remButton.setIcon("icons/cross.png"); 262 remButton.setStyleName("button-label"); 263 remButton.addClickHandler(new ClickHandler() { 264 @Override 265 public void onClick(ClickEvent event) { 266 SC.ask("Remove node", "Do you want to remove node?", new BooleanCallback() { 267 @Override 268 public void execute(Boolean confirmed) { 269 if (confirmed) { 270 contents.removeNode(node); 271 } 272 } 273 }); 274 } 275 }); 276 277 addMember(editButton); 278 addMember(remButton); 279 } 280 281 protected void setNode(JcrNode node) { 282 this.node = node; 283 } 284 } 285 286 private class ChildNodesPager extends Pager { 287 288 @Override 289 public void fetch(int index) { 290 contents.jcrService().childNodes(contents.repository(), 291 contents.workspace(), contents.path(), 292 index * pager.getRecordsPerPage(), 293 pager.getRecordsPerPage(), new AsyncCallback<Collection<JcrNode>>() { 294 @Override 295 public void onFailure(Throwable caught) { 296 SC.say(caught.getMessage()); 297 } 298 299 @Override 300 public void onSuccess(Collection<JcrNode> nodes) { 301 setValues(nodes); 302 } 303 }); 304 } 305 306 } 307}