View | Details | Raw Unified | Return to bug 315415 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/cdt/debug/internal/ui/views/executables/ExecutablesView.java (-24 / +5 lines)
Lines 279-312 Link Here
279
					{
279
					{
280
						// update the remove action
280
						// update the remove action
281
						removeAction.setEnabled(!newSelection.isEmpty());
281
						removeAction.setEnabled(!newSelection.isEmpty());
282
						
282
283
						// just immediately do this work: the source files content provider
284
						// will do the work in the background
283
						final Object firstElement = ((IStructuredSelection) newSelection).getFirstElement();
285
						final Object firstElement = ((IStructuredSelection) newSelection).getFirstElement();
284
						
285
						Job setectExeJob = new Job(Messages.ExecutablesView_Select_Executable) {
286
286
287
							@Override
287
						sourceFilesViewer.setInput(firstElement);
288
							protected IStatus run(IProgressMonitor monitor) {
288
						
289
								if (firstElement instanceof Executable) {
290
									Executable executable = (Executable)firstElement;
291
									this.setName(Messages.ExecutablesView_Finding_Sources_Job_Name + executable.getName());
292
									executable.getSourceFiles(monitor);
293
								}
294
								// selection could be empty, so do this no matter what to update the source
295
								// files viewer
296
								UIJob selectExeUIJob = new UIJob(Messages.ExecutablesView_Select_Executable){
297
									@Override
298
									public IStatus runInUIThread(IProgressMonitor monitor) {
299
										sourceFilesViewer.setInput(firstElement);
300
										sourceFilesViewer.packColumns();
301
										return Status.OK_STATUS;
302
									}};
303
								selectExeUIJob.schedule();								
304
								return Status.OK_STATUS;
305
							}};
306
						setectExeJob.schedule();
307
						oldSelection = (IStructuredSelection) newSelection;
289
						oldSelection = (IStructuredSelection) newSelection;
308
					}
290
					}
309
					
310
				}
291
				}
311
			}
292
			}
312
		});
293
		});
(-)src/org/eclipse/cdt/debug/internal/ui/views/executables/Messages.java (+1 lines)
Lines 52-57 Link Here
52
	public static String ExecutablesViewer_Size;
52
	public static String ExecutablesViewer_Size;
53
	public static String ExecutablesViewer_Type;
53
	public static String ExecutablesViewer_Type;
54
	public static String SourceFilesContentProvider_NoFilesFound;
54
	public static String SourceFilesContentProvider_NoFilesFound;
55
	public static String SourceFilesContentProvider_Refreshing;
55
	public static String SourceFilesViewer_RefreshSourceFiles;
56
	public static String SourceFilesViewer_RefreshSourceFiles;
56
	public static String SourceFilesViewer_Location;
57
	public static String SourceFilesViewer_Location;
57
	public static String SourceFilesViewer_Modified;
58
	public static String SourceFilesViewer_Modified;
(-)src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesContentProvider.java (-26 / +170 lines)
Lines 11-37 Link Here
11
11
12
package org.eclipse.cdt.debug.internal.ui.views.executables;
12
package org.eclipse.cdt.debug.internal.ui.views.executables;
13
13
14
import java.util.HashMap;
15
import java.util.List;
16
import java.util.Map;
17
14
import org.eclipse.cdt.core.model.ITranslationUnit;
18
import org.eclipse.cdt.core.model.ITranslationUnit;
15
import org.eclipse.cdt.debug.core.CDebugCorePlugin;
16
import org.eclipse.cdt.debug.core.executables.Executable;
19
import org.eclipse.cdt.debug.core.executables.Executable;
20
import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
21
import org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener;
22
import org.eclipse.cdt.debug.internal.ui.views.executables.SourceFilesViewer.TranslationUnitInfo;
17
import org.eclipse.cdt.ui.CElementContentProvider;
23
import org.eclipse.cdt.ui.CElementContentProvider;
18
import org.eclipse.core.runtime.IPath;
24
import org.eclipse.core.runtime.IPath;
19
import org.eclipse.core.runtime.IProgressMonitor;
25
import org.eclipse.core.runtime.IProgressMonitor;
20
import org.eclipse.core.runtime.IStatus;
26
import org.eclipse.core.runtime.IStatus;
21
import org.eclipse.core.runtime.Status;
27
import org.eclipse.core.runtime.Status;
28
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
22
import org.eclipse.core.runtime.jobs.Job;
29
import org.eclipse.core.runtime.jobs.Job;
30
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
31
import org.eclipse.jface.viewers.Viewer;
32
import org.eclipse.swt.widgets.Display;
33
34
public class SourceFilesContentProvider extends CElementContentProvider implements IExecutablesChangeListener {
35
36
	static class QuickParseJob extends Job {
37
		final Executable executable;
38
		ITranslationUnit[] tus;
39
		
40
		public QuickParseJob(Executable executable) {
41
			super ("Reading Debug Symbol Information: " + executable.getName());
42
			this.executable = executable;
43
			this.tus = null;
44
		}
45
		
46
		@Override
47
		protected IStatus run(IProgressMonitor monitor) {
48
			tus = executable.getSourceFiles(monitor);
49
			return Status.OK_STATUS;
50
		}
51
	}
52
	
53
	/** contains running jobs */ 
54
	private Map<IPath, QuickParseJob> pathToJobMap = new HashMap<IPath, SourceFilesContentProvider.QuickParseJob>();
55
	
56
	/** those executables for which we asked the question and got a result.
57
	 * NOTE: this contains a duplicate of into in Executable, because we can't
58
	 * guarantee or check whether Executable still has the info itself. */
59
	private Map<IPath, ITranslationUnit[]> fetchedExecutables = new HashMap<IPath, ITranslationUnit[]>();
23
60
24
public class SourceFilesContentProvider extends CElementContentProvider {
61
	private final SourceFilesViewer viewer;
25
62
	
26
	public SourceFilesContentProvider(SourceFilesViewer viewer) {
63
	public SourceFilesContentProvider(SourceFilesViewer viewer) {
27
		super(true, true);
64
		super(true, true);
65
		this.viewer = viewer;
66
		ExecutablesManager.getExecutablesManager().addExecutablesChangeListener(this);
28
	}
67
	}
29
68
69
	/* (non-Javadoc)
70
	 * @see org.eclipse.cdt.ui.CElementContentProvider#dispose()
71
	 */
72
	@Override
73
	public void dispose() {
74
		ExecutablesManager.getExecutablesManager().removeExecutablesChangeListener(this);
75
		synchronized (fetchedExecutables) {
76
			fetchedExecutables.clear();
77
		}
78
		synchronized (pathToJobMap) {
79
			pathToJobMap.clear();
80
		}
81
		super.dispose();
82
	}
83
	
30
	@Override
84
	@Override
31
	public boolean hasChildren(Object element) {
85
	public boolean hasChildren(Object element) {
32
		if (element instanceof ITranslationUnit) {
86
		if (element instanceof ITranslationUnit) {
33
			IPath path = ((ITranslationUnit) element).getLocation();
87
			TranslationUnitInfo info = SourceFilesViewer.fetchTranslationUnitInfo(
34
			if (path != null && !path.toFile().exists())
88
					(Executable) viewer.getInput(), element, System.currentTimeMillis());
89
			if (info != null && !info.exists)
35
				return false;
90
				return false;
36
		}
91
		}
37
		return super.hasChildren(element);
92
		return super.hasChildren(element);
Lines 40-70 Link Here
40
	public Object[] getElements(Object inputElement) {
95
	public Object[] getElements(Object inputElement) {
41
		if (inputElement instanceof Executable) {
96
		if (inputElement instanceof Executable) {
42
			final Executable executable = (Executable) inputElement;
97
			final Executable executable = (Executable) inputElement;
43
			final ITranslationUnit[][] resultHolder = new ITranslationUnit[1][];
98
			final IPath exePath = executable.getPath();
44
			Job quickParseJob = new Job("Reading Debug Symbol Information: " + executable.getName()) {
99
			
45
100
			// look for a job that is currently fetching this info
46
				@Override
101
			QuickParseJob job;
47
				protected IStatus run(IProgressMonitor monitor) {
102
			synchronized (pathToJobMap) {
48
					ITranslationUnit[] sourceFiles = executable.getSourceFiles(monitor);
103
				job = pathToJobMap.get(exePath);
49
					resultHolder[0] = sourceFiles;
104
			}
50
					return Status.OK_STATUS;
105
			if (job != null) {
51
				}
106
				// job is still running
52
			};
107
				return new String[] { Messages.SourceFilesContentProvider_Refreshing };
108
			}
53
			
109
			
54
			try {
110
			// see if we already checked
55
				quickParseJob.schedule();
111
			if (fetchedExecutables.containsKey(exePath)) {
56
				quickParseJob.join();
112
				return fetchedExecutables.get(exePath);
57
			} catch (InterruptedException e) {
58
				CDebugCorePlugin.log(e);
59
			}
113
			}
60
			
114
			
61
			ITranslationUnit[] sourceFiles = resultHolder[0];
115
			// start a background job to look for the sources
62
			if (sourceFiles.length == 0)
116
			job = new QuickParseJob(executable);
63
				return new String[] { Messages.SourceFilesContentProvider_NoFilesFound + executable.getName() };
117
			synchronized (pathToJobMap) {
64
			else
118
				pathToJobMap.put(exePath, job);
65
				return sourceFiles;
119
			}
120
			
121
			// once the job finishes, update the viewer
122
			final QuickParseJob theJob = job;
123
			job.addJobChangeListener(new JobChangeAdapter() {
124
				public void done(IJobChangeEvent event) {
125
					Display.getDefault().asyncExec(new Runnable() {
126
						public void run() {
127
							synchronized (pathToJobMap) {
128
								pathToJobMap.remove(exePath);
129
							}
130
							synchronized (fetchedExecutables) {
131
								fetchedExecutables.put(exePath, theJob.tus);
132
							}
133
							// update the viewer
134
							if (!viewer.getControl().isDisposed()) {
135
								viewer.getTree().setLayoutDeferred(true);
136
								viewer.refresh(executable);
137
								viewer.packColumns();
138
								viewer.getTree().setLayoutDeferred(false);
139
							}
140
						}
141
					});
142
				}
143
			});
144
			
145
			job.schedule();
146
			
147
			// while it's running...
148
			return new String[] { Messages.SourceFilesContentProvider_Refreshing };
66
		}
149
		}
67
		return new Object[] {};
150
		return new Object[] {};
68
	}
151
	}
69
152
70
}
153
154
	/* (non-Javadoc)
155
	 * @see org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener#executablesListChanged()
156
	 */
157
	public void executablesListChanged() {
158
		// Don't clear executables -- closing/opening project doesn't imply
159
		// the info is different.  But cancel any jobs that might be for closed projects.
160
		cancelQuickParseJobs();
161
	}
162
163
164
	/**
165
	 * 
166
	 */
167
	private void cancelQuickParseJobs() {
168
		synchronized (pathToJobMap) {
169
			for (QuickParseJob job : pathToJobMap.values()) {
170
				job.cancel();
171
			}
172
			pathToJobMap.clear();
173
		}
174
		
175
	}
176
177
	/* (non-Javadoc)
178
	 * @see org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener#executablesChanged(java.util.List)
179
	 */
180
	public void executablesChanged(List<Executable> executables) {
181
		for (Executable executable : executables) {
182
			IPath exePath = executable.getPath();
183
			synchronized (fetchedExecutables) {
184
				fetchedExecutables.remove(exePath);
185
			}
186
			synchronized (pathToJobMap) {
187
				QuickParseJob job = pathToJobMap.get(exePath);
188
				if (job != null) {
189
					job.cancel();
190
					pathToJobMap.remove(exePath);
191
				}
192
			}
193
		}
194
	}
195
	
196
	/* (non-Javadoc)
197
	 * @see org.eclipse.cdt.ui.CElementContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
198
	 */
199
	@Override
200
	public void inputChanged(Viewer viewer, Object oldInput, final Object newInput) {
201
		super.inputChanged(viewer, oldInput, newInput);
202
		cancelQuickParseJobs();
203
		
204
		Display.getDefault().asyncExec(new Runnable() {
205
			public void run() {
206
				// pack because the quick parse job won't run
207
				if (newInput instanceof Executable 
208
						&& fetchedExecutables.containsKey(((Executable) newInput).getPath()))
209
					SourceFilesContentProvider.this.viewer.packColumns();
210
			}
211
		});
212
	}
213
}
214
(-)src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesLabelProvider.java (-33 / +61 lines)
Lines 12-34 Link Here
12
package org.eclipse.cdt.debug.internal.ui.views.executables;
12
package org.eclipse.cdt.debug.internal.ui.views.executables;
13
13
14
import com.ibm.icu.text.DateFormat;
14
import com.ibm.icu.text.DateFormat;
15
15
import java.util.Date;
16
import java.util.Date;
17
import java.util.List;
16
18
17
import org.eclipse.cdt.core.model.ITranslationUnit;
19
import org.eclipse.cdt.core.model.ITranslationUnit;
18
import org.eclipse.cdt.debug.core.executables.Executable;
20
import org.eclipse.cdt.debug.core.executables.Executable;
21
import org.eclipse.cdt.debug.core.executables.ExecutablesManager;
22
import org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener;
19
import org.eclipse.cdt.ui.CElementLabelProvider;
23
import org.eclipse.cdt.ui.CElementLabelProvider;
20
import org.eclipse.core.runtime.IPath;
21
import org.eclipse.core.runtime.Path;
22
import org.eclipse.jface.resource.FontDescriptor;
24
import org.eclipse.jface.resource.FontDescriptor;
23
import org.eclipse.jface.resource.JFaceResources;
25
import org.eclipse.jface.resource.JFaceResources;
24
import org.eclipse.jface.resource.LocalResourceManager;
26
import org.eclipse.jface.resource.LocalResourceManager;
25
import org.eclipse.jface.viewers.TreeColumnViewerLabelProvider;
27
import org.eclipse.jface.viewers.TreeColumnViewerLabelProvider;
26
import org.eclipse.jface.viewers.ViewerCell;
28
import org.eclipse.jface.viewers.ViewerCell;
27
import org.eclipse.swt.SWT;
29
import org.eclipse.swt.SWT;
30
import org.eclipse.swt.events.DisposeEvent;
31
import org.eclipse.swt.events.DisposeListener;
28
import org.eclipse.swt.graphics.Font;
32
import org.eclipse.swt.graphics.Font;
29
import org.eclipse.swt.widgets.Display;
33
import org.eclipse.swt.widgets.Display;
30
34
31
public class SourceFilesLabelProvider extends TreeColumnViewerLabelProvider {
35
public class SourceFilesLabelProvider extends TreeColumnViewerLabelProvider implements IExecutablesChangeListener {
32
36
33
	private SourceFilesViewer viewer;
37
	private SourceFilesViewer viewer;
34
38
Lines 37-64 Link Here
37
	public SourceFilesLabelProvider(SourceFilesViewer viewer) {
41
	public SourceFilesLabelProvider(SourceFilesViewer viewer) {
38
		super(new CElementLabelProvider());
42
		super(new CElementLabelProvider());
39
		this.viewer = viewer;
43
		this.viewer = viewer;
44
		
45
		// brute-force clear the cache when executables change
46
		ExecutablesManager.getExecutablesManager().addExecutablesChangeListener(this);
47
		viewer.getControl().addDisposeListener(new DisposeListener() {
48
			public void widgetDisposed(DisposeEvent e) {
49
				ExecutablesManager.getExecutablesManager().removeExecutablesChangeListener(SourceFilesLabelProvider.this);
50
			}
51
		});
40
	}
52
	}
41
53
42
	@Override
54
	@Override
43
	public void update(ViewerCell cell) {
55
	public void update(ViewerCell cell) {
44
		super.update(cell);
56
		super.update(cell);
45
57
58
		SourceFilesViewer.TranslationUnitInfo tuInfo = null;
59
		if (cell.getElement() instanceof ITranslationUnit) {
60
			long now = System.currentTimeMillis();
61
			tuInfo = SourceFilesViewer.fetchTranslationUnitInfo((Executable) viewer.getInput(), cell.getElement(), now);
62
		}
63
		
46
		int orgColumnIndex = cell.getColumnIndex();
64
		int orgColumnIndex = cell.getColumnIndex();
47
65
48
		if (orgColumnIndex == 0) {
66
		if (orgColumnIndex == 0) {
49
			if (cell.getElement() instanceof String) {
67
			if (cell.getElement() instanceof String) {
50
				cell.setText((String) cell.getElement());
68
				cell.setText((String) cell.getElement());
51
				Font boldFont = resourceManager.createFont(FontDescriptor.createFrom(viewer.getTree().getFont()).setStyle(SWT.BOLD));
69
				Font italicFont = resourceManager.createFont(FontDescriptor.createFrom(viewer.getTree().getFont()).setStyle(SWT.ITALIC));
52
				cell.setFont(boldFont);
70
				cell.setFont(italicFont);
71
			} else {
72
				cell.setFont(viewer.getTree().getFont());
53
			}
73
			}
54
		} else if (orgColumnIndex == 1) {
74
		} else if (orgColumnIndex == 1) {
55
			cell.setText(null);
75
			cell.setText(null);
56
			if (cell.getElement() instanceof ITranslationUnit) {
76
			if (tuInfo != null) {
57
				ITranslationUnit tu = (ITranslationUnit) cell.getElement();
77
				if (tuInfo.location != null) {
58
				IPath path = tu.getLocation();
78
					cell.setText(tuInfo.location.toOSString());
59
				if (path != null) {
79
					if (tuInfo.exists)
60
					cell.setText(path.toOSString());
61
					if (path.toFile().exists())
62
						cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
80
						cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
63
					else
81
					else
64
						cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY));
82
						cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY));
Lines 67-77 Link Here
67
			cell.setImage(null);
85
			cell.setImage(null);
68
		} else if (orgColumnIndex == 2) {
86
		} else if (orgColumnIndex == 2) {
69
			cell.setText(null);
87
			cell.setText(null);
70
			if (cell.getElement() instanceof ITranslationUnit) {
88
			if (tuInfo != null && tuInfo.originalLocation != null) {
71
				Executable executable = (Executable) viewer.getInput();
89
				cell.setText(tuInfo.originalLocation.toOSString());
72
				Path path = new Path(executable.getOriginalLocation((ITranslationUnit) cell.getElement()));
90
				if (tuInfo.originalExists)
73
				cell.setText(path.toOSString());
74
				if (path.toFile().exists())
75
					cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
91
					cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
76
				else
92
				else
77
					cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY));
93
					cell.setForeground(Display.getDefault().getSystemColor(SWT.COLOR_GRAY));
Lines 79-112 Link Here
79
			cell.setImage(null);
95
			cell.setImage(null);
80
		} else if (orgColumnIndex == 3) {
96
		} else if (orgColumnIndex == 3) {
81
			cell.setText(null);
97
			cell.setText(null);
82
			if (cell.getElement() instanceof ITranslationUnit) {
98
			if (tuInfo != null) {
83
				ITranslationUnit tu = (ITranslationUnit) cell.getElement();
99
				if (tuInfo.exists) {
84
				IPath path = tu.getLocation();
100
					cell.setText(Long.toString(tuInfo.fileLength));
85
				if (path != null && path.toFile().exists()) {
86
					long fileLength = path.toFile().length();
87
					cell.setText(Long.toString(fileLength));
88
				}
101
				}
89
			}
102
			}
90
			cell.setImage(null);
103
			cell.setImage(null);
91
		} else if (orgColumnIndex == 4) {
104
		} else if (orgColumnIndex == 4) {
92
			cell.setText(null);
105
			cell.setText(null);
93
			if (cell.getElement() instanceof ITranslationUnit) {
106
			if (tuInfo != null) {
94
				ITranslationUnit tu = (ITranslationUnit) cell.getElement();
107
				if (tuInfo.exists) {
95
				IPath path = tu.getLocation();
108
					String dateTimeString = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(
96
				if (path != null && path.toFile().exists()) {
109
							new Date(tuInfo.lastModified));
97
					long modified = path.toFile().lastModified();
98
					String dateTimeString = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(new Date(modified));
99
					cell.setText(dateTimeString);
110
					cell.setText(dateTimeString);
100
				}
111
				}
101
			}
112
			}
102
			cell.setImage(null);
113
			cell.setImage(null);
103
		} else if (orgColumnIndex == 5) {
114
		} else if (orgColumnIndex == 5) {
104
			cell.setText(null);
115
			cell.setText(null);
105
			if (cell.getElement() instanceof ITranslationUnit) {
116
			if (tuInfo != null) {
106
				ITranslationUnit tu = (ITranslationUnit) cell.getElement();
117
				if (tuInfo.location != null) {
107
				IPath path = tu.getLocation();
118
					String fileExtension = tuInfo.location.getFileExtension();
108
				if (path != null) {
109
					String fileExtension = path.getFileExtension();
110
					if (fileExtension != null)
119
					if (fileExtension != null)
111
						cell.setText(fileExtension.toLowerCase());
120
						cell.setText(fileExtension.toLowerCase());
112
				}
121
				}
Lines 115-118 Link Here
115
		}
124
		}
116
	}
125
	}
117
126
127
	/* (non-Javadoc)
128
	 * @see org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener#executablesListChanged()
129
	 */
130
	public void executablesListChanged() {
131
		synchronized (SourceFilesViewer.translationUnitInfoCache) {
132
			SourceFilesViewer.translationUnitInfoCache.flush();
133
		}
134
	}
135
136
	/* (non-Javadoc)
137
	 * @see org.eclipse.cdt.debug.core.executables.IExecutablesChangeListener#executablesChanged(java.util.List)
138
	 */
139
	public void executablesChanged(List<Executable> executables) {
140
		synchronized (SourceFilesViewer.translationUnitInfoCache) {
141
			SourceFilesViewer.translationUnitInfoCache.flush();
142
		}
143
	}
144
118
}
145
}
146
	
(-)src/org/eclipse/cdt/debug/internal/ui/views/executables/SourceFilesViewer.java (-5 / +76 lines)
Lines 10-15 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.cdt.debug.internal.ui.views.executables;
11
package org.eclipse.cdt.debug.internal.ui.views.executables;
12
12
13
import java.io.File;
14
13
import org.eclipse.cdt.core.model.ICElement;
15
import org.eclipse.cdt.core.model.ICElement;
14
import org.eclipse.cdt.core.model.ISourceReference;
16
import org.eclipse.cdt.core.model.ISourceReference;
15
import org.eclipse.cdt.core.model.ITranslationUnit;
17
import org.eclipse.cdt.core.model.ITranslationUnit;
Lines 17-29 Link Here
17
import org.eclipse.cdt.debug.core.executables.Executable;
19
import org.eclipse.cdt.debug.core.executables.Executable;
18
import org.eclipse.cdt.debug.internal.ui.sourcelookup.CSourceNotFoundEditorInput;
20
import org.eclipse.cdt.debug.internal.ui.sourcelookup.CSourceNotFoundEditorInput;
19
import org.eclipse.cdt.debug.ui.ICDebugUIConstants;
21
import org.eclipse.cdt.debug.ui.ICDebugUIConstants;
22
import org.eclipse.cdt.internal.core.util.LRUCache;
20
import org.eclipse.cdt.internal.ui.util.EditorUtility;
23
import org.eclipse.cdt.internal.ui.util.EditorUtility;
21
import org.eclipse.cdt.ui.CUIPlugin;
24
import org.eclipse.cdt.ui.CUIPlugin;
22
import org.eclipse.core.runtime.CoreException;
25
import org.eclipse.core.runtime.CoreException;
23
import org.eclipse.core.runtime.IPath;
26
import org.eclipse.core.runtime.IPath;
24
import org.eclipse.core.runtime.IProgressMonitor;
27
import org.eclipse.core.runtime.IProgressMonitor;
25
import org.eclipse.core.runtime.IStatus;
28
import org.eclipse.core.runtime.IStatus;
29
import org.eclipse.core.runtime.Path;
26
import org.eclipse.core.runtime.Status;
30
import org.eclipse.core.runtime.Status;
31
import org.eclipse.core.runtime.jobs.Job;
27
import org.eclipse.debug.core.DebugPlugin;
32
import org.eclipse.debug.core.DebugPlugin;
28
import org.eclipse.debug.core.ILaunchConfiguration;
33
import org.eclipse.debug.core.ILaunchConfiguration;
29
import org.eclipse.debug.core.ILaunchConfigurationListener;
34
import org.eclipse.debug.core.ILaunchConfigurationListener;
Lines 38-49 Link Here
38
import org.eclipse.swt.events.DisposeEvent;
43
import org.eclipse.swt.events.DisposeEvent;
39
import org.eclipse.swt.events.DisposeListener;
44
import org.eclipse.swt.events.DisposeListener;
40
import org.eclipse.swt.widgets.Composite;
45
import org.eclipse.swt.widgets.Composite;
46
import org.eclipse.swt.widgets.Display;
41
import org.eclipse.swt.widgets.Tree;
47
import org.eclipse.swt.widgets.Tree;
42
import org.eclipse.swt.widgets.TreeColumn;
48
import org.eclipse.swt.widgets.TreeColumn;
43
import org.eclipse.ui.IEditorPart;
49
import org.eclipse.ui.IEditorPart;
44
import org.eclipse.ui.IWorkbenchPage;
50
import org.eclipse.ui.IWorkbenchPage;
45
import org.eclipse.ui.PartInitException;
51
import org.eclipse.ui.PartInitException;
46
import org.eclipse.ui.progress.UIJob;
47
52
48
/**
53
/**
49
 * Displays the list of source files for the executable selected in the
54
 * Displays the list of source files for the executable selected in the
Lines 51-56 Link Here
51
 */
56
 */
52
public class SourceFilesViewer extends BaseViewer implements ISourceLookupParticipant, ILaunchConfigurationListener {
57
public class SourceFilesViewer extends BaseViewer implements ISourceLookupParticipant, ILaunchConfigurationListener {
53
58
59
	/** Information from an ITranslationUnit for the various displayed columns */
60
	static class TranslationUnitInfo {
61
		long nextCheckTimestamp;
62
		boolean isFile;
63
		boolean exists;
64
		boolean originalExists;
65
		long fileLength;
66
		long lastModified;
67
		IPath location;
68
		IPath originalLocation;
69
	}
70
54
	private static final String P_COLUMN_ORDER_KEY_SF = "columnOrderKeySF"; //$NON-NLS-1$
71
	private static final String P_COLUMN_ORDER_KEY_SF = "columnOrderKeySF"; //$NON-NLS-1$
55
	private static final String P_SORTED_COLUMN_INDEX_KEY_SF = "sortedColumnIndexKeySF"; //$NON-NLS-1$
72
	private static final String P_SORTED_COLUMN_INDEX_KEY_SF = "sortedColumnIndexKeySF"; //$NON-NLS-1$
56
	private static final String P_COLUMN_SORT_DIRECTION_KEY_SF = "columnSortDirectionKeySF"; //$NON-NLS-1$
73
	private static final String P_COLUMN_SORT_DIRECTION_KEY_SF = "columnSortDirectionKeySF"; //$NON-NLS-1$
Lines 59-64 Link Here
59
76
60
	TreeColumn originalLocationColumn;
77
	TreeColumn originalLocationColumn;
61
	private Tree sourceFilesTree;
78
	private Tree sourceFilesTree;
79
	/** Tradeoff expensiveness of checking filesystem against likelihood 
80
	 * that files will be added/removed/changed in the given time period */
81
	static final long FILE_CHECK_DELTA = 30 * 1000;
82
	static LRUCache<Object, TranslationUnitInfo> translationUnitInfoCache = new LRUCache<Object, TranslationUnitInfo>(1024);
62
83
63
	public SourceFilesViewer(ExecutablesView view, Composite parent, int style) {
84
	public SourceFilesViewer(ExecutablesView view, Composite parent, int style) {
64
		super(view, parent, style);
85
		super(view, parent, style);
Lines 90-95 Link Here
90
		sourceFilesTree.addDisposeListener(new DisposeListener() {
111
		sourceFilesTree.addDisposeListener(new DisposeListener() {
91
112
92
			public void widgetDisposed(DisposeEvent e) {
113
			public void widgetDisposed(DisposeEvent e) {
114
				DebugPlugin.getDefault().getLaunchManager().removeLaunchConfigurationListener(SourceFilesViewer.this);
115
				
93
				CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().removeParticipants(
116
				CDebugCorePlugin.getDefault().getCommonSourceLookupDirector().removeParticipants(
94
						new ISourceLookupParticipant[] { SourceFilesViewer.this });
117
						new ISourceLookupParticipant[] { SourceFilesViewer.this });
95
			}
118
			}
Lines 213-226 Link Here
213
	}
236
	}
214
237
215
	private void refreshContent() {
238
	private void refreshContent() {
216
		UIJob refreshJob = new UIJob(Messages.SourceFilesViewer_RefreshSourceFiles) {
239
		Job refreshJob = new Job(Messages.SourceFilesViewer_RefreshSourceFiles) {
217
240
218
			@Override
241
			@Override
219
			public IStatus runInUIThread(IProgressMonitor monitor) {
242
			public IStatus run(IProgressMonitor monitor) {
220
				Object input = getInput();
243
				Object input = getInput();
221
				if (input != null && input instanceof Executable) {
244
				if (input != null && input instanceof Executable) {
222
					((Executable)input).setRemapSourceFiles(true);
245
					((Executable)input).setRemapSourceFiles(true);
223
					refresh(true);
246
					Display.getDefault().asyncExec(new Runnable() {
247
						public void run() {
248
							refresh(true);
249
						}
250
					});
224
				}
251
				}
225
				return Status.OK_STATUS;
252
				return Status.OK_STATUS;
226
			}
253
			}
Lines 280-284 Link Here
280
			refreshContent();
307
			refreshContent();
281
		}
308
		}
282
	}
309
	}
283
	
310
311
312
	static SourceFilesViewer.TranslationUnitInfo fetchTranslationUnitInfo(Executable executable, Object element, long now) {
313
		SourceFilesViewer.TranslationUnitInfo info;
314
		synchronized (SourceFilesViewer.translationUnitInfoCache) {
315
			info = (SourceFilesViewer.TranslationUnitInfo) SourceFilesViewer.translationUnitInfoCache.get(element);
316
		}
317
		if (info == null || info.nextCheckTimestamp <= now) {
318
			if (info == null)
319
				info = new SourceFilesViewer.TranslationUnitInfo();
320
			
321
			if (element instanceof ITranslationUnit) {
322
				ITranslationUnit tu = (ITranslationUnit) element;
323
				info.location = tu.getLocation();
324
				if (info.location != null) {
325
					File file = info.location.toFile();
326
					info.exists = file.exists();
327
					info.fileLength = file.length();
328
					info.lastModified = file.lastModified();
329
					
330
					if (executable != null) {
331
						info.originalLocation = new Path(executable.getOriginalLocation(tu));
332
						info.originalExists = info.originalLocation.toFile().exists();
333
					} else {
334
						info.originalLocation = null;
335
						info.originalExists = false;
336
					}
337
				} else {
338
					info.exists = false;
339
					info.fileLength = 0;
340
					info.lastModified = 0;
341
					info.originalExists = false;
342
					info.originalLocation = null;
343
				}
344
			}
345
			
346
			info.nextCheckTimestamp = System.currentTimeMillis() + SourceFilesViewer.FILE_CHECK_DELTA;
347
			
348
			synchronized (SourceFilesViewer.translationUnitInfoCache) {
349
				SourceFilesViewer.translationUnitInfoCache.put(element, info);
350
			}
351
		}
352
		return info;
353
	}
354
284
}
355
}
(-)src/org/eclipse/cdt/debug/internal/ui/views/executables/messages.properties (+1 lines)
Lines 46-51 Link Here
46
ExecutablesViewer_Size=Size
46
ExecutablesViewer_Size=Size
47
ExecutablesViewer_Type=Type
47
ExecutablesViewer_Type=Type
48
SourceFilesContentProvider_NoFilesFound=No source files found in 
48
SourceFilesContentProvider_NoFilesFound=No source files found in 
49
SourceFilesContentProvider_Refreshing=Refreshing... 
49
SourceFilesViewer_RefreshSourceFiles=Refresh Source Files
50
SourceFilesViewer_RefreshSourceFiles=Refresh Source Files
50
SourceFilesViewer_Location=Location
51
SourceFilesViewer_Location=Location
51
SourceFilesViewer_Modified=Modified
52
SourceFilesViewer_Modified=Modified

Return to bug 315415