This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 44319
Collapse All | Expand All

(-)projects/projectui/arch.xml (+3 lines)
Lines 685-690 Link Here
685
   details given in the particular interfaces. E.g.
685
   details given in the particular interfaces. E.g.
686
   <code>LogicalViewProvider</code> is sought out in project lookups when
686
   <code>LogicalViewProvider</code> is sought out in project lookups when
687
   displaying the logical view.
687
   displaying the logical view.
688
   The UI uses <code>AuxiliaryConfiguration</code> to store list of files opened
689
   in the project in an instant closing the project. Will be used for reopen these
690
   files when this project opens.
688
  </p>
691
  </p>
689
 </answer>
692
 </answer>
690
693
(-)projects/projectui/src/org/netbeans/modules/project/ui/ProjectUtilities.java (-49 / +171 lines)
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
}
(-)projects/projectui/src/org/netbeans/modules/project/ui/actions/OpenProject.java (+4 lines)
Lines 24-29 Link Here
24
import org.netbeans.modules.project.ui.OpenProjectListSettings;
24
import org.netbeans.modules.project.ui.OpenProjectListSettings;
25
import org.netbeans.modules.project.ui.ProjectChooserAccessory;
25
import org.netbeans.modules.project.ui.ProjectChooserAccessory;
26
import org.netbeans.modules.project.ui.ProjectTab;
26
import org.netbeans.modules.project.ui.ProjectTab;
27
import org.netbeans.modules.project.ui.ProjectUtilities;
27
import org.openide.DialogDisplayer;
28
import org.openide.DialogDisplayer;
28
import org.openide.NotifyDescriptor;
29
import org.openide.NotifyDescriptor;
29
import org.openide.filesystems.FileUtil;
30
import org.openide.filesystems.FileUtil;
Lines 73-78 Link Here
73
                        OpenProjectList.getDefault().setMainProject( project );
74
                        OpenProjectList.getDefault().setMainProject( project );
74
                    }
75
                    }
75
                    final ProjectTab ptLogial  = ProjectTab.findDefault (ProjectTab.ID_LOGICAL);
76
                    final ProjectTab ptLogial  = ProjectTab.findDefault (ProjectTab.ID_LOGICAL);
77
                    
78
                    // open project files
79
                    ProjectUtilities.openProjectFiles (project);
76
                    
80
                    
77
                    // invoke later to select the being opened project if the focus is outside ProjectTab
81
                    // invoke later to select the being opened project if the focus is outside ProjectTab
78
                    SwingUtilities.invokeLater (new Runnable () {
82
                    SwingUtilities.invokeLater (new Runnable () {
(-)projects/projectui/src/org/netbeans/modules/project/ui/resources/projectui-open-files.xsd (+28 lines)
Added Link Here
1
<?xml version="1.0" encoding="UTF-8"?>
2
<!--
3
                Sun Public License Notice
4
5
The contents of this file are subject to the Sun Public License
6
Version 1.0 (the "License"). You may not use this file except in
7
compliance with the License. A copy of the License is available at
8
http://www.sun.com/
9
10
The Original Code is NetBeans. The Initial Developer of the Original
11
Code is Sun Microsystems, Inc. Portions Copyright 1997-2004 Sun
12
Microsystems, Inc. All Rights Reserved.
13
-->
14
15
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
16
            targetNamespace="http://www.netbeans.org/ns/projectui-open-files/1"
17
            xmlns="http://www.netbeans.org/ns/projectui-open-files/1"
18
            elementFormDefault="qualified">
19
20
    <xsd:element name="open-files">
21
        <xsd:complexType>
22
            <xsd:sequence>
23
                <xsd:element name="file" minOccurs="0" maxOccurs="unbounded" type="xsd:anyURI"/>
24
            </xsd:sequence>
25
        </xsd:complexType>
26
    </xsd:element>
27
    
28
</xsd:schema>

Return to bug 44319