Lines 16-21
Link Here
|
16 |
import java.awt.Component; |
16 |
import java.awt.Component; |
17 |
import java.awt.Cursor; |
17 |
import java.awt.Cursor; |
18 |
import java.awt.event.ActionEvent; |
18 |
import java.awt.event.ActionEvent; |
|
|
19 |
import java.net.MalformedURLException; |
20 |
import java.net.URL; |
19 |
import java.util.*; |
21 |
import java.util.*; |
20 |
import java.io.File; |
22 |
import java.io.File; |
21 |
|
23 |
|
Lines 24-45
Link Here
|
24 |
import javax.swing.SwingUtilities; |
26 |
import javax.swing.SwingUtilities; |
25 |
import org.netbeans.api.project.FileOwnerQuery; |
27 |
import org.netbeans.api.project.FileOwnerQuery; |
26 |
import org.netbeans.api.project.Project; |
28 |
import org.netbeans.api.project.Project; |
|
|
29 |
import org.netbeans.spi.project.AuxiliaryConfiguration; |
27 |
import org.openide.ErrorManager; |
30 |
import org.openide.ErrorManager; |
|
|
31 |
import org.openide.cookies.EditCookie; |
32 |
import org.openide.cookies.OpenCookie; |
28 |
import org.openide.filesystems.FileObject; |
33 |
import org.openide.filesystems.FileObject; |
|
|
34 |
import org.openide.filesystems.FileStateInvalidException; |
29 |
import org.openide.filesystems.FileUtil; |
35 |
import org.openide.filesystems.FileUtil; |
|
|
36 |
import org.openide.filesystems.URLMapper; |
30 |
import org.openide.loaders.DataObject; |
37 |
import org.openide.loaders.DataObject; |
|
|
38 |
import org.openide.loaders.DataObjectNotFoundException; |
31 |
import org.openide.nodes.Node; |
39 |
import org.openide.nodes.Node; |
32 |
import org.openide.text.CloneableEditorSupport; |
40 |
import org.openide.text.CloneableEditorSupport; |
33 |
import org.openide.util.ContextAwareAction; |
41 |
import org.openide.util.ContextAwareAction; |
34 |
import org.openide.util.Mutex; |
42 |
import org.openide.util.Mutex; |
35 |
import org.openide.util.NbBundle; |
43 |
import org.openide.util.NbBundle; |
36 |
|
|
|
37 |
|
38 |
import org.openide.util.Utilities; |
39 |
import org.openide.windows.Mode; |
44 |
import org.openide.windows.Mode; |
40 |
import org.openide.windows.TopComponent; |
45 |
import org.openide.windows.TopComponent; |
41 |
import org.openide.windows.WindowManager; |
46 |
import org.openide.windows.WindowManager; |
42 |
|
47 |
import org.openide.xml.XMLUtil; |
|
|
48 |
import org.w3c.dom.Document; |
49 |
import org.w3c.dom.Element; |
50 |
import org.w3c.dom.NodeList; |
43 |
|
51 |
|
44 |
|
52 |
|
45 |
/** The util methods for projectui module. |
53 |
/** The util methods for projectui module. |
Lines 47-52
Link Here
|
47 |
* @author Jiri Rechtacek |
55 |
* @author Jiri Rechtacek |
48 |
*/ |
56 |
*/ |
49 |
public class ProjectUtilities { |
57 |
public class ProjectUtilities { |
|
|
58 |
static final String OPEN_FILES_NS = "http://www.netbeans.org/ns/projectui-open-files/1"; // NOI18N |
59 |
static final String OPEN_FILES_ELEMENT = "open-files"; // NOI18N |
60 |
static final String FILE_ELEMENT = "file"; // NOI18N |
50 |
|
61 |
|
51 |
/** Creates a new instance of CloseAllProjectDocuments */ |
62 |
/** Creates a new instance of CloseAllProjectDocuments */ |
52 |
private ProjectUtilities () { |
63 |
private ProjectUtilities () { |
Lines 59-105
Link Here
|
59 |
* @param p project to close |
70 |
* @param p project to close |
60 |
* @return false if an user cancel the Save/Discard/Cancel dialog, true otherwise |
71 |
* @return false if an user cancel the Save/Discard/Cancel dialog, true otherwise |
61 |
*/ |
72 |
*/ |
62 |
final public static boolean closeAllDocuments (Project[] projects) { |
73 |
public static boolean closeAllDocuments (Project[] projects) { |
63 |
if (projects == null) { |
74 |
return closeAllDocuments (projects, false); |
64 |
throw new IllegalArgumentException ("No proects are specified."); // NOI18N |
|
|
65 |
} |
66 |
|
67 |
if (projects.length == 0) { |
68 |
// no projects to close, no documents will be closed |
69 |
return true; |
70 |
} |
71 |
List/*Project*/ listOfProjects = Arrays.asList (projects); |
72 |
Set/*DataObject*/ modifiedFiles = new HashSet (); |
73 |
Set/*TopComponent*/ tc2close = new HashSet (); |
74 |
Mode editorMode = WindowManager.getDefault ().findMode (CloneableEditorSupport.EDITOR_MODE); |
75 |
TopComponent[] openTCs = editorMode.getTopComponents (); |
76 |
for (int i = 0; i < openTCs.length; i++) { |
77 |
DataObject dobj = (DataObject)openTCs[i].getLookup ().lookup (DataObject.class); |
78 |
if (dobj != null) { |
79 |
FileObject fobj = dobj.getPrimaryFile (); |
80 |
Project owner = FileOwnerQuery.getOwner (fobj); |
81 |
if (listOfProjects.contains (owner)) { |
82 |
modifiedFiles.add (dobj); |
83 |
tc2close.add (openTCs[i]); |
84 |
} |
85 |
} |
86 |
} |
87 |
|
88 |
if (modifiedFiles.isEmpty ()) { |
89 |
return true; |
90 |
} |
91 |
|
92 |
boolean result = ExitDialog.showDialog (modifiedFiles); |
93 |
|
94 |
if (result) { |
95 |
// close documents |
96 |
Iterator it = tc2close.iterator (); |
97 |
while (it.hasNext ()) { |
98 |
((TopComponent)it.next ()).close (); |
99 |
} |
100 |
} |
101 |
|
102 |
return result; |
103 |
} |
75 |
} |
104 |
|
76 |
|
105 |
/** Closes all documents of the given project in editor area. If some documents |
77 |
/** Closes all documents of the given project in editor area. If some documents |
Lines 108-114
Link Here
|
108 |
* @param p project to close |
80 |
* @param p project to close |
109 |
* @return false if an user cancel the Save/Discard/Cancel dialog, true otherwise |
81 |
* @return false if an user cancel the Save/Discard/Cancel dialog, true otherwise |
110 |
*/ |
82 |
*/ |
111 |
final public static boolean closeAllDocuments (Project p) { |
83 |
public static boolean closeAllDocuments (Project p) { |
112 |
if (p == null) { |
84 |
if (p == null) { |
113 |
throw new IllegalArgumentException ("No specified project."); // NOI18N |
85 |
throw new IllegalArgumentException ("No specified project."); // NOI18N |
114 |
} |
86 |
} |
Lines 123-136
Link Here
|
123 |
* |
95 |
* |
124 |
* @param newDo new data object |
96 |
* @param newDo new data object |
125 |
*/ |
97 |
*/ |
126 |
final public static void openAndSelectNewObject (final DataObject newDo) { |
98 |
public static void openAndSelectNewObject (final DataObject newDo) { |
127 |
// call the preferred action on main class |
99 |
// call the preferred action on main class |
128 |
Mutex.EVENT.writeAccess (new Runnable () { |
100 |
Mutex.EVENT.writeAccess (new Runnable () { |
129 |
public void run () { |
101 |
public void run () { |
130 |
final Node node = newDo.getNodeDelegate (); |
102 |
final Node node = newDo.getNodeDelegate (); |
131 |
Action a = node.getPreferredAction(); |
103 |
Action a = node.getPreferredAction(); |
132 |
if (a instanceof ContextAwareAction) { |
104 |
if (a instanceof ContextAwareAction) { |
133 |
a = ((ContextAwareAction)a).createContextAwareInstance(node.getLookup ()); |
105 |
a = ((ContextAwareAction) a).createContextAwareInstance(node.getLookup ()); |
134 |
} |
106 |
} |
135 |
if (a != null) { |
107 |
if (a != null) { |
136 |
a.actionPerformed(new ActionEvent(node, ActionEvent.ACTION_PERFORMED, "")); // NOI18N |
108 |
a.actionPerformed(new ActionEvent(node, ActionEvent.ACTION_PERFORMED, "")); // NOI18N |
Lines 161-167
Link Here
|
161 |
* @param extension extension of created file |
133 |
* @param extension extension of created file |
162 |
* @return localized error message or null if all right |
134 |
* @return localized error message or null if all right |
163 |
*/ |
135 |
*/ |
164 |
final public static String canUseFileName (FileObject targetFolder, String folderName, String newObjectName, String extension) { |
136 |
public static String canUseFileName (FileObject targetFolder, String folderName, String newObjectName, String extension) { |
165 |
if (extension != null && extension.length () > 0) { |
137 |
if (extension != null && extension.length () > 0) { |
166 |
StringBuffer sb = new StringBuffer (); |
138 |
StringBuffer sb = new StringBuffer (); |
167 |
sb.append (newObjectName); |
139 |
sb.append (newObjectName); |
Lines 238-243
Link Here
|
238 |
ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, npe); |
210 |
ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, npe); |
239 |
} |
211 |
} |
240 |
} |
212 |
} |
|
|
213 |
} |
214 |
|
215 |
/** Closes all documents in editor area which are owned by one of given projects. |
216 |
* If some documents are modified then an user is notified by Save/Discard/Cancel dialog. |
217 |
* Dialog is showed only once for all project's documents together. |
218 |
* If 'storeDocuments' is true then URLs of closed documents are store to private |
219 |
* <code>project.xml</code>. |
220 |
* |
221 |
* @param p project to close |
222 |
* @param storeDocuments will be documents stored to private |
223 |
* @return false if an user cancel the Save/Discard/Cancel dialog, true otherwise |
224 |
*/ |
225 |
public static boolean closeAllDocuments (Project[] projects, boolean storeDocuments) { |
226 |
if (projects == null) { |
227 |
throw new IllegalArgumentException ("No proects are specified."); // NOI18N |
228 |
} |
229 |
|
230 |
if (projects.length == 0) { |
231 |
// no projects to close, no documents will be closed |
232 |
return true; |
233 |
} |
234 |
|
235 |
List/*<Project>*/ listOfProjects = Arrays.asList (projects); |
236 |
Set/*<DataObject>*/ openFiles = new HashSet (); |
237 |
Set/*<TopComponent>*/ tc2close = new HashSet (); |
238 |
Map/*<Project, SortedSet<String>>*/ urls4project = new HashMap (); |
239 |
Mode editorMode = WindowManager.getDefault ().findMode (CloneableEditorSupport.EDITOR_MODE); |
240 |
TopComponent[] openTCs = editorMode.getTopComponents (); |
241 |
for (int i = 0; i < openTCs.length; i++) { |
242 |
DataObject dobj = (DataObject) openTCs[i].getLookup ().lookup (DataObject.class); |
243 |
if (dobj != null) { |
244 |
FileObject fobj = dobj.getPrimaryFile (); |
245 |
Project owner = FileOwnerQuery.getOwner (fobj); |
246 |
if (listOfProjects.contains (owner)) { |
247 |
openFiles.add (dobj); |
248 |
tc2close.add (openTCs[i]); |
249 |
if (!urls4project.containsKey (owner)) { |
250 |
// add project |
251 |
urls4project.put (owner, new TreeSet ()); |
252 |
} |
253 |
URL url = null; |
254 |
try { |
255 |
url = dobj.getPrimaryFile ().getURL (); |
256 |
((SortedSet)urls4project.get (owner)).add (url.toExternalForm ()); |
257 |
} catch (FileStateInvalidException fsie) { |
258 |
assert false : "FileStateInvalidException in " + dobj.getPrimaryFile (); |
259 |
} |
260 |
} |
261 |
} |
262 |
} |
263 |
|
264 |
if (openFiles.isEmpty ()) { |
265 |
return true; |
266 |
} |
267 |
|
268 |
boolean result = ExitDialog.showDialog (openFiles); |
269 |
|
270 |
if (result) { |
271 |
// store project's documents |
272 |
// loop all project being closed |
273 |
Iterator loop = urls4project.keySet ().iterator (); |
274 |
Project p; |
275 |
while (loop.hasNext ()) { |
276 |
p = (Project) loop.next (); |
277 |
storeProjectOpenFiles (p, (SortedSet)urls4project.get (p)); |
278 |
} |
279 |
|
280 |
// close documents |
281 |
Iterator it = tc2close.iterator (); |
282 |
while (it.hasNext ()) { |
283 |
((TopComponent)it.next ()).close (); |
284 |
} |
285 |
} |
286 |
|
287 |
return result; |
288 |
} |
289 |
|
290 |
static private void storeProjectOpenFiles (Project p, SortedSet/*<String>*/ urls) { |
291 |
AuxiliaryConfiguration aux = (AuxiliaryConfiguration) p.getLookup ().lookup (AuxiliaryConfiguration.class); |
292 |
if (aux != null) { |
293 |
|
294 |
// clean-up files before adding new one |
295 |
aux.removeConfigurationFragment (OPEN_FILES_ELEMENT, OPEN_FILES_NS, false); |
296 |
|
297 |
Document xml = XMLUtil.createDocument (OPEN_FILES_ELEMENT, OPEN_FILES_NS, null, null); |
298 |
Element fileEl; |
299 |
|
300 |
Element openFiles = xml.createElementNS (OPEN_FILES_NS, OPEN_FILES_ELEMENT); |
301 |
|
302 |
// loop all open files of given project |
303 |
Iterator it = urls.iterator (); |
304 |
while (it.hasNext ()) { |
305 |
fileEl = openFiles.getOwnerDocument ().createElement (FILE_ELEMENT); |
306 |
fileEl.appendChild (fileEl.getOwnerDocument ().createTextNode ((String)it.next ())); |
307 |
openFiles.appendChild (fileEl); |
308 |
} |
309 |
|
310 |
aux.putConfigurationFragment (openFiles, false); |
311 |
} |
312 |
} |
313 |
|
314 |
/** Opens the project's files read from the private <code>project.xml</code> file |
315 |
* |
316 |
* @param p project |
317 |
*/ |
318 |
public static void openProjectFiles (Project p) { |
319 |
AuxiliaryConfiguration aux = (AuxiliaryConfiguration) p.getLookup ().lookup (AuxiliaryConfiguration.class); |
320 |
|
321 |
if (aux == null) { |
322 |
return ; |
323 |
} |
324 |
|
325 |
Element openFiles = aux.getConfigurationFragment (OPEN_FILES_ELEMENT, OPEN_FILES_NS, false); |
326 |
if (openFiles == null) { |
327 |
return; |
328 |
} |
329 |
|
330 |
NodeList list = openFiles.getElementsByTagName (FILE_ELEMENT); |
331 |
if (list == null) { |
332 |
return ; |
333 |
} |
334 |
|
335 |
FileObject fo = null; |
336 |
DataObject dobj; |
337 |
String url; |
338 |
for (int i = 0; i < list.getLength (); i++) { |
339 |
url = list.item (i).getChildNodes ().item (0).getNodeValue (); |
340 |
try { |
341 |
fo = URLMapper.findFileObject (new URL (url)); |
342 |
if (fo == null) { |
343 |
continue; |
344 |
} |
345 |
dobj = DataObject.find (fo); |
346 |
EditCookie ec = (EditCookie) dobj.getCookie (EditCookie.class); |
347 |
OpenCookie oc = (OpenCookie) dobj.getCookie (OpenCookie.class); |
348 |
if (ec != null) { |
349 |
((EditCookie) ec).edit (); |
350 |
} else if (oc != null) { |
351 |
((OpenCookie) oc).open (); |
352 |
|
353 |
} |
354 |
} catch (MalformedURLException mue) { |
355 |
assert false : "MalformedURLException in " + url; |
356 |
} catch (DataObjectNotFoundException donfo) { |
357 |
assert false : "DataObject must exist for " + fo; |
358 |
} |
359 |
} |
360 |
|
361 |
// clean-up stored files |
362 |
aux.removeConfigurationFragment (OPEN_FILES_ELEMENT, OPEN_FILES_NS, false); |
241 |
} |
363 |
} |
242 |
|
364 |
|
243 |
} |
365 |
} |