1 19 20 package org.openide.actions; 21 22 23 import java.awt.event.ActionEvent ; 24 import java.beans.*; 25 import java.util.*; 26 import javax.swing.*; 27 import org.openide.awt.JInlineMenu; 28 import org.openide.filesystems.*; 29 import org.openide.loaders.*; 30 import org.openide.nodes.Node; 31 import org.openide.util.*; 32 import org.openide.util.actions.*; 33 import org.openide.util.lookup.*; 34 import org.openide.windows.TopComponent; 35 import org.openide.windows.WindowManager; 36 37 44 public class FileSystemAction extends SystemAction 45 implements ContextAwareAction, Presenter.Menu, Presenter.Popup { 46 47 static JMenuItem[] NONE = new JMenuItem[] {}; 48 49 51 private static Node[] nodes (Lookup lookup) { 52 Collection<? extends Node> c; 53 54 if (lookup != null) { 55 c = lookup.lookupAll(Node.class); 56 } else { 57 c = Collections.emptyList(); 58 } 59 return c.toArray(new Node[c.size()]); 60 } 61 62 66 static JMenuItem[] createMenu (boolean popUp, Lookup lookup) { 67 Node[] n = nodes (lookup); 68 69 if (n == null) { 70 n = WindowManager.getDefault ().getRegistry ().getActivatedNodes (); 71 } 72 73 74 Map<FileSystem,Set<FileObject>> fsSet = new HashMap<FileSystem,Set<FileObject>>(); 75 76 if (n != null) { 77 for (Node node : n) { 78 DataObject obj = node.getCookie(DataObject.class); 79 while (obj instanceof DataShadow) 80 obj = ((DataShadow) obj).getOriginal(); 81 if (obj != null) { 82 try { 83 FileSystem fs = obj.getPrimaryFile ().getFileSystem (); 84 Set<FileObject> foSet = fsSet.get(fs); 85 if (foSet == null ) { 86 fsSet.put(fs, foSet = new LinkedHashSet<FileObject>()); 87 } 88 foSet.addAll(obj.files ()); 89 } catch (FileStateInvalidException ex) {continue;} 90 } 91 } 92 95 if (fsSet.size () == 0 || fsSet.size() > 1) { 96 return createMenu(Enumerations.<Action>empty(), popUp, lookup); 97 } 98 99 List<SystemAction> result = new LinkedList<SystemAction>(); 100 Set<FileObject> backSet = new LinkedHashSet<FileObject>(); 101 for (Map.Entry<FileSystem,Set<FileObject>> entry : fsSet.entrySet()) { 102 103 FileSystem fs = entry.getKey(); 104 Set<FileObject> foSet = entry.getValue(); 105 List<FileObject> backupList = new LinkedList<FileObject>(foSet); 106 Iterator<FileObject> it = backupList.iterator (); 107 while (it.hasNext ()) { 108 FileObject fo = it.next (); 109 try { 110 if (fo.getFileSystem () != fs) { 111 it.remove (); 112 } 113 } catch (FileStateInvalidException ex) { 114 it.remove (); 115 } 116 } 117 backSet.addAll(backupList); 118 result.addAll(Arrays.asList(fs.getActions (backSet))); 119 } 120 121 122 return createMenu (Collections.enumeration (result), popUp, createProxyLookup(lookup, backSet)); 123 } 124 return NONE; 125 } 126 127 private static ProxyLookup createProxyLookup(final Lookup lookup, final Set<FileObject> backSet) { 128 return new ProxyLookup(lookup, Lookups.fixed((Object [])backSet.toArray(new FileObject [backSet.size()]))); 129 } 130 131 136 static JMenuItem[] createMenu(Enumeration<? extends Action> en, boolean popUp, Lookup lookup) { 137 en = Enumerations.removeDuplicates (en); 138 139 List<JMenuItem> items = new ArrayList<JMenuItem>(); 140 while (en.hasMoreElements ()) { 141 Action a = en.nextElement(); 142 143 if(lookup != null && a instanceof ContextAwareAction) { 145 a = ((ContextAwareAction)a).createContextAwareInstance(lookup); 146 } 147 148 boolean enabled = false; 149 try { 150 enabled = a.isEnabled(); 151 } catch (RuntimeException e) { 152 Exceptions.attachMessage(e, 153 "Guilty action: " + 154 a.getClass().getName()); Exceptions.printStackTrace(e); 156 } 157 if (enabled) { 158 JMenuItem item = null; 159 if (popUp) { 160 if (a instanceof Presenter.Popup) { 161 item = ((Presenter.Popup)a).getPopupPresenter (); 162 } 163 } else { 164 if (a instanceof Presenter.Menu) { 165 item = ((Presenter.Menu)a).getMenuPresenter (); 166 } 167 } 168 if (item != null) { 170 items.add (item); 171 } 172 } 173 } 174 JMenuItem[] array = new JMenuItem [items.size ()]; 175 items.toArray (array); 176 return array; 177 } 178 179 public JMenuItem getMenuPresenter () { 180 return new Menu (false, null); 181 } 182 183 public JMenuItem getPopupPresenter () { 184 return new Menu (true, null); 185 } 186 187 public String getName () { 188 return NbBundle.getMessage(DataObject.class, "ACT_FileSystemAction"); 189 } 190 191 public HelpCtx getHelpCtx () { 192 return new HelpCtx (FileSystemAction.class); 193 } 194 195 199 public void actionPerformed(ActionEvent e) { 200 assert false : "ActionEvt: " + e; 201 } 202 203 204 public Action createContextAwareInstance(Lookup actionContext) { 205 return new DelegateAction(actionContext); 206 } 207 208 209 211 private static class Menu extends JInlineMenu implements PropertyChangeListener { 212 213 private boolean popup; 214 215 private JMenuItem[] last = NONE; 216 217 private Lookup lookup; 218 219 static final long serialVersionUID =2650151487189209766L; 220 221 225 Menu (boolean popup, Lookup lookup) { 226 this.popup = popup; 227 this.lookup = lookup; 228 229 changeMenuItems (createMenu (popup, lookup)); 230 231 if (lookup == null) { 232 TopComponent.Registry r = WindowManager.getDefault ().getRegistry (); 234 235 r.addPropertyChangeListener ( 236 WeakListeners.propertyChange (this, r) 237 ); 238 } 239 } 240 241 244 synchronized void changeMenuItems (JMenuItem[] items) { 245 removeListeners (last); 246 addListeners (items); 247 last = items; 248 setMenuItems (items); 249 } 250 251 252 255 private void addListeners (JMenuItem[] items) { 256 int len = items.length; 257 for (int i = 0; i < len; i++) { 258 items[i].addPropertyChangeListener (this); 259 } 260 } 261 262 265 private void removeListeners (JMenuItem[] items) { 266 int len = items.length; 267 for (int i = 0; i < len; i++) { 268 items[i].removePropertyChangeListener (this); 269 } 270 } 271 272 boolean needsChange = false; 273 274 public void addNotify() { 275 if (needsChange) { 276 changeMenuItems (createMenu (popup, lookup)); 277 needsChange = false; 278 } 279 super.addNotify(); 280 } 281 282 public void removeNotify() { 283 removeListeners (last); 284 last = NONE; 285 } 286 287 public void propertyChange (PropertyChangeEvent ev) { 288 String name = ev.getPropertyName (); 289 if ( 290 name == null || 291 name.equals (SystemAction.PROP_ENABLED) || 292 name.equals (TopComponent.Registry.PROP_ACTIVATED_NODES) 293 ) { 294 needsChange = true; 296 } 297 } 298 } 299 300 301 private static final class DelegateAction extends AbstractAction 302 implements Presenter.Menu, Presenter.Popup { 303 304 private Lookup lookup; 305 306 public DelegateAction(Lookup lookup) { 307 this.lookup = lookup; 308 } 309 310 311 312 public JMenuItem getMenuPresenter () { 313 return new FileSystemAction.Menu (false, lookup); 314 } 315 316 317 public JMenuItem getPopupPresenter () { 318 return new FileSystemAction.Menu (true, lookup); 319 } 320 321 public void actionPerformed(ActionEvent e) { 322 assert false : e; 323 } 324 325 } 327 } 328 | Popular Tags |