1 /*
   2  * Copyright (c) 2012, 2014, Oracle and/or its affiliates.
   3  * All rights reserved. Use is subject to license terms.
   4  *
   5  * This file is available and licensed under the following license:
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  *
  11  *  - Redistributions of source code must retain the above copyright
  12  *    notice, this list of conditions and the following disclaimer.
  13  *  - Redistributions in binary form must reproduce the above copyright
  14  *    notice, this list of conditions and the following disclaimer in
  15  *    the documentation and/or other materials provided with the distribution.
  16  *  - Neither the name of Oracle Corporation nor the names of its
  17  *    contributors may be used to endorse or promote products derived
  18  *    from this software without specific prior written permission.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  */
  32 
  33 package com.oracle.javafx.scenebuilder.kit.editor.job;
  34 
  35 import com.oracle.javafx.scenebuilder.kit.editor.EditorController;
  36 import com.oracle.javafx.scenebuilder.kit.editor.i18n.I18N;
  37 import com.oracle.javafx.scenebuilder.kit.editor.selection.AbstractSelectionGroup;
  38 import com.oracle.javafx.scenebuilder.kit.editor.selection.ObjectSelectionGroup;
  39 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument;
  40 import com.oracle.javafx.scenebuilder.kit.fxom.FXOMObject;
  41 import com.oracle.javafx.scenebuilder.kit.library.BuiltinLibrary;
  42 import com.oracle.javafx.scenebuilder.kit.library.Library;
  43 import com.oracle.javafx.scenebuilder.kit.metadata.util.DesignHierarchyMask;
  44 import java.io.IOException;
  45 import java.net.URL;
  46 import java.util.Collection;
  47 import java.util.LinkedHashMap;
  48 import java.util.LinkedList;
  49 import java.util.List;
  50 import java.util.Map;
  51 
  52 /**
  53  *
  54  */
  55 public class AddContextMenuToSelectionJob extends BatchSelectionJob {
  56 
  57     private Map<FXOMObject, FXOMObject> contextMenuMap; // Initialized lazily
  58 
  59     public AddContextMenuToSelectionJob(EditorController editorController) {
  60         super(editorController);
  61     }
  62 
  63     public Collection<FXOMObject> getContextMenus() {
  64         constructContextMenuMap();
  65         return contextMenuMap.values();
  66     }
  67 
  68     /*
  69      * BatchSelectionJob
  70      */
  71 
  72     @Override
  73     protected List<Job> makeSubJobs() {
  74 
  75         constructContextMenuMap();
  76 
  77         final List<Job> result = new LinkedList<>();
  78         for (Map.Entry<FXOMObject, FXOMObject> e : contextMenuMap.entrySet()) {
  79             final FXOMObject fxomObject = e.getKey();
  80             final FXOMObject contextMenuObject = e.getValue();
  81             final Job insertJob = new InsertAsAccessoryJob(
  82                     contextMenuObject, fxomObject,
  83                     DesignHierarchyMask.Accessory.CONTEXT_MENU,
  84                     getEditorController());
  85             result.add(insertJob);
  86         }
  87 
  88         return result;
  89     }
  90 
  91     @Override
  92     protected AbstractSelectionGroup getNewSelectionGroup() {
  93         final Collection<FXOMObject> contextMenus = contextMenuMap.values();
  94         assert contextMenus.isEmpty() == false;
  95         final FXOMObject hitMenu = contextMenus.iterator().next();
  96 
  97         return new ObjectSelectionGroup(contextMenus, hitMenu, null);
  98     }
  99 
 100     /*
 101      * CompositeJob
 102      */
 103 
 104     @Override
 105     protected String makeDescription() {
 106         return I18N.getString("label.action.edit.add.context.menu");
 107     }
 108 
 109 
 110     /*
 111      * Private
 112      */
 113 
 114     private void constructContextMenuMap() {
 115         if (contextMenuMap == null) {
 116             contextMenuMap = new LinkedHashMap<>();
 117 
 118             // Build the ContextMenu item from the library builtin items
 119             final String contextMenuFxmlPath = "builtin/ContextMenu.fxml"; //NOI18N
 120             final URL contextMenuFxmlURL
 121                     = BuiltinLibrary.class.getResource(contextMenuFxmlPath);
 122             assert contextMenuFxmlURL != null;
 123 
 124             final AbstractSelectionGroup asg = getEditorController().getSelection().getGroup();
 125             assert asg instanceof ObjectSelectionGroup; // Because of (1)
 126             final ObjectSelectionGroup osg = (ObjectSelectionGroup) asg;
 127 
 128             try {
 129                 final String contextMenuFxmlText
 130                         = FXOMDocument.readContentFromURL(contextMenuFxmlURL);
 131 
 132                 final FXOMDocument fxomDocument = getEditorController().getFxomDocument();
 133                 final Library library = getEditorController().getLibrary();
 134                 for (FXOMObject fxomObject : osg.getItems()) {
 135                     final FXOMDocument contextMenuDocument = new FXOMDocument(
 136                             contextMenuFxmlText,
 137                             contextMenuFxmlURL, library.getClassLoader(), null);
 138 
 139                     assert contextMenuDocument != null;
 140                     final FXOMObject contextMenuObject = contextMenuDocument.getFxomRoot();
 141                     assert contextMenuObject != null;
 142                     contextMenuObject.moveToFxomDocument(fxomDocument);
 143                     assert contextMenuDocument.getFxomRoot() == null;
 144 
 145                     contextMenuMap.put(fxomObject, contextMenuObject);
 146                 }
 147             } catch(IOException x) {
 148                 throw new IllegalStateException("Bug in " + getClass().getSimpleName(), x); //NOI18N
 149             }
 150         }
 151     }
 152 }