1 /* 2 * Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE 3 */ 4 package de.ilias.services.filemanager.content; 5 6 import de.ilias.services.filemanager.FileManager; 7 import de.ilias.services.filemanager.events.ListItemContextMenuEventHandler; 8 import de.ilias.services.filemanager.utils.FileManagerUtils; 9 import java.util.ArrayList; 10 import java.util.Iterator; 11 import java.util.logging.Logger; 12 import javafx.collections.ObservableList; 13 import javafx.scene.Node; 14 import javafx.scene.control.ContextMenu; 15 import javafx.scene.control.ListView; 16 import javafx.scene.control.MenuItemBuilder; 17 import javafx.scene.control.SeparatorMenuItemBuilder; 18 import javafx.scene.image.ImageViewBuilder; 19 import javafx.scene.input.*; 20 21 /** 22 * Class ListItemActionContextMenu 23 * 24 * @author Stefan Meyer <smeyer.ilias@gmx.de> 25 */ 26 public class ListItemActionContextMenu extends ContextMenu { 27 28 private static final Logger logger = Logger.getLogger(ListItemActionContextMenu.class.getName()); 29 30 private ObservableList<Node> selected = null; 31 private Node source = null; 32 private ArrayList<ListItem> listItems = new ArrayList<ListItem>(); 33 34 private boolean allowOpen = false; 35 private boolean allowCopy = false; 36 private boolean allowPaste = false; 37 private boolean allowDelete = false; 38 private boolean allowRename = false; 39 private boolean allowCopyToClipboard = false; 40 41 private boolean allowCreate = false; 42 private boolean allowCourse = false; 43 private boolean allowFolder = false; 44 private boolean allowCategory = false; 45 private boolean allowGroup = false; 46 ListItemActionContextMenu(ObservableList<Node> sel, Node source)47 public ListItemActionContextMenu(ObservableList<Node> sel, Node source) { 48 49 selected = sel; 50 this.source = source; 51 parseSelected(); 52 populate(); 53 } 54 55 /** 56 * get selected nodes 57 * @return 58 */ getSelectedNodes()59 public ObservableList<Node> getSelectedNodes() { 60 return selected; 61 } 62 63 /** 64 * Get array list of list items 65 * @return 66 */ getSelectedItems()67 public ArrayList<ListItem> getSelectedItems() { 68 return listItems; 69 } 70 71 /** 72 * Get source 73 * @return 74 */ getSource()75 public Node getSource() { 76 return source; 77 } 78 parseSelected()79 protected void parseSelected() { 80 81 boolean multipleSelected; 82 83 if(getSelectedNodes().size() > 1) { 84 multipleSelected = true; 85 allowCreate = false; 86 allowOpen = false; 87 allowCopy = true; 88 allowCopyToClipboard = true; 89 allowPaste = false; 90 allowRename = false; 91 allowDelete = true; 92 } 93 else { 94 multipleSelected = false; 95 allowOpen = true; 96 allowCopy = true; 97 allowCopyToClipboard = true; 98 allowRename = true; 99 allowPaste = true; 100 allowDelete = true; 101 } 102 103 Iterator nodeIte = getSelectedNodes().iterator(); 104 105 while(nodeIte.hasNext()) { 106 Node node = (Node) nodeIte.next(); 107 ListItem listItem = (ListItem) node.getUserData(); 108 109 getSelectedItems().add(listItem); 110 111 if( 112 listItem instanceof RemoteListItem && 113 (getSelectedNodes().size() == 1) && 114 (listItem.getType().equals("crs") || 115 listItem.getType().equals("grp")) 116 ) { 117 allowCopyToClipboard = false; 118 } 119 120 // Currently no delete for local list 121 if(listItem instanceof RemoteListItem && listItem.isContainer()) { 122 //allowDelete = false; 123 } 124 if(!allowPaste(listItem)) { 125 allowPaste = false; 126 } 127 /* 128 if(listItem instanceof RemoteListItem && listItem.isContainer()) { 129 allowOpen = false; 130 } 131 */ 132 if(!listItem.isWritable()) { 133 allowPaste = false; 134 allowRename = false; 135 } 136 if(!listItem.isReadable()) { 137 allowCopy = false; 138 allowCopyToClipboard = false; 139 allowOpen = false; 140 allowPaste = false; 141 allowRename = false; 142 } 143 if(!listItem.isDeletable()) { 144 allowDelete = false; 145 } 146 if(listItem instanceof LocalListItem) { 147 allowCopyToClipboard = false; 148 } 149 if(listItem.isCourseAllowed() && !multipleSelected) { 150 allowCreate = true; 151 allowCourse = true; 152 } 153 if(listItem.isCategoryAllowed() && !multipleSelected) { 154 allowCreate = true; 155 allowCategory = true; 156 } 157 if(listItem.isGroupAllowed() && !multipleSelected) { 158 allowCreate = true; 159 allowGroup = true; 160 } 161 if(listItem.isFolderAllowed() && !multipleSelected) { 162 allowCreate = true; 163 allowFolder = true; 164 } 165 // restrictive for upper link 166 if(listItem.isUpperLink()) { 167 allowCreate = false; 168 allowOpen = false; 169 allowCopy = false; 170 allowCopyToClipboard = false; 171 allowRename = false; 172 allowPaste = false; 173 allowDelete = false; 174 } 175 } 176 177 /** 178 * Default action of list view 179 */ 180 if(getSource() instanceof ListView) { 181 allowOpen = false; 182 allowCopy = false; 183 allowCopyToClipboard = false; 184 allowRename = false; 185 allowDelete = false; 186 187 if(((ListItem)getSource().getUserData()).isCategoryAllowed()) { 188 allowCreate = true; 189 allowCategory = true; 190 } 191 if(((ListItem)getSource().getUserData()).isCourseAllowed()) { 192 allowCreate = true; 193 allowCourse = true; 194 } 195 if(((ListItem)getSource().getUserData()).isGroupAllowed()) { 196 allowCreate = true; 197 allowGroup = true; 198 } 199 if(((ListItem)getSource().getUserData()).isFolderAllowed()) { 200 allowCreate = true; 201 allowFolder = true; 202 } 203 204 logger.info("List view default id = " + String.valueOf(((ListItem)getSource().getUserData()).getRefId())); 205 } 206 207 // Hide paste if clipboard content id empty 208 Clipboard clip = Clipboard.getSystemClipboard(); 209 if(!clip.hasFiles()) { 210 allowPaste = false; 211 } 212 } 213 214 215 /** 216 * Populate action menu 217 */ populate()218 protected void populate() { 219 220 // Open 221 this.getItems().addAll( 222 MenuItemBuilder.create(). 223 text("Open"). 224 accelerator(new KeyCodeCombination(KeyCode.O,KeyCodeCombination.CONTROL_DOWN)). 225 graphic( 226 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("edit.png")).build()). 227 disable(!allowOpen). 228 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_OPEN)). 229 build() 230 ); 231 232 // Separator 233 this.getItems().addAll( 234 SeparatorMenuItemBuilder.create().build()); 235 236 // Copy disabled 237 /* 238 this.getItems().addAll( 239 MenuItemBuilder.create(). 240 text("Copy"). 241 graphic( 242 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("edit-copy.png")).build()). 243 disable(!allowCopy). 244 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_COPY)). 245 build() 246 ); 247 248 */ 249 250 // Copy to clipboard 251 this.getItems().addAll( 252 MenuItemBuilder.create(). 253 text("Copy to Clipboard"). 254 accelerator(new KeyCodeCombination(KeyCode.C,KeyCodeCombination.CONTROL_DOWN)). 255 graphic( 256 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("edit-copy.png")).build()). 257 disable(!allowCopyToClipboard). 258 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_COPY_TO_CLIPBOARD)). 259 build() 260 ); 261 262 // Paste 263 this.getItems().addAll( 264 MenuItemBuilder.create(). 265 text("Paste"). 266 accelerator(new KeyCodeCombination(KeyCode.V,KeyCodeCombination.CONTROL_DOWN)). 267 graphic( 268 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("edit-paste.png")).build()). 269 disable(!allowPaste). 270 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_PASTE)). 271 build() 272 ); 273 274 // Seperator 275 this.getItems().addAll( 276 SeparatorMenuItemBuilder.create().build()); 277 278 // Delete 279 this.getItems().addAll( 280 MenuItemBuilder.create(). 281 accelerator(new KeyCodeCombination(KeyCode.DELETE)). 282 text("Delete"). 283 graphic( 284 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("edit-delete.png")).build()). 285 disable(!allowDelete). 286 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_DELETE)). 287 build() 288 ); 289 290 // Rename 291 this.getItems().addAll( 292 MenuItemBuilder.create(). 293 text("Rename"). 294 accelerator(new KeyCodeCombination(KeyCode.R,KeyCodeCombination.CONTROL_DOWN)). 295 graphic( 296 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("edit-rename.png")).build()). 297 disable(!allowRename). 298 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_RENAME)). 299 build() 300 ); 301 302 // File lock for files 303 if(checkAllowLock()) { 304 this.getItems().addAll( 305 MenuItemBuilder.create(). 306 text("Edit Revision State"). 307 accelerator(new KeyCodeCombination(KeyCode.L,KeyCodeCombination.CONTROL_DOWN)). 308 graphic( 309 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("edit-revision.png")).build()). 310 disable(false). 311 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_EDIT_REVISION_STATE)). 312 build() 313 ); 314 } 315 316 317 if(allowCreate) { 318 // Seperator 319 this.getItems().addAll( 320 SeparatorMenuItemBuilder.create().build()); 321 322 // Category 323 if(allowCategory) { 324 this.getItems().addAll( 325 MenuItemBuilder.create(). 326 text("Create Category"). 327 graphic( 328 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("icon_cat_s.gif")).build()). 329 disable(false). 330 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_CREATE_CAT)). 331 build() 332 ); 333 } 334 // Folder 335 if(allowFolder) { 336 this.getItems().addAll( 337 MenuItemBuilder.create(). 338 text("Create Folder"). 339 graphic( 340 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("icon_fold_s.gif")).build()). 341 disable(false). 342 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_CREATE_FOLD)). 343 build() 344 ); 345 } 346 // Course 347 if(allowCourse) { 348 this.getItems().addAll( 349 MenuItemBuilder.create(). 350 text("Create Course"). 351 graphic( 352 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("icon_crs_s.gif")).build()). 353 disable(false). 354 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_CREATE_CRS)). 355 build() 356 ); 357 } 358 // Group 359 if(allowGroup) { 360 this.getItems().addAll( 361 MenuItemBuilder.create(). 362 text("Create Group"). 363 graphic( 364 ImageViewBuilder.create().image(FileManagerUtils.getImageByName("icon_grp_s.gif")).build()). 365 disable(false). 366 onAction(new ListItemContextMenuEventHandler((ListItem) getSource().getUserData(), ListItemContextMenuEventHandler.ACTION_CREATE_GRP)). 367 build() 368 ); 369 } 370 371 } 372 } 373 374 /** 375 * Check if lock action should be displayed. 376 * @return 377 */ checkAllowLock()378 protected boolean checkAllowLock() { 379 380 if(this.getSelectedNodes().size() != 1) { 381 return false; 382 } 383 384 Iterator nodeIte = getSelectedNodes().iterator(); 385 while(nodeIte.hasNext()) { 386 Node node = (Node) nodeIte.next(); 387 ListItem item = (ListItem) node.getUserData(); 388 389 if(item.getType().equals("file") && item.isWritable()) { 390 logger.info("Item allows file lock"); 391 return true; 392 } 393 } 394 return false; 395 } 396 397 /** 398 * Check if paste is allowed 399 * @param item 400 * @return 401 */ allowPaste(ListItem item)402 public static boolean allowPaste(ListItem item) { 403 404 if(item.isContainer() && item.isWritable()) { 405 return true; 406 } 407 if(item.getType().equalsIgnoreCase("file") && item.isWritable()) { 408 return true; 409 } 410 return false; 411 } 412 } 413