[EGIT PATCH] Showing commit info like the CVS plugin instead of tooltips.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Tooltips for the info were annoying, especially on MacOS where the tooltip center is your pointer location.
It is now possible to copy&paste data.
Like the CVS plugin, there's a menu to show/hide views. Thought it doesn't save in the preferences store for now.

Signed-off-by: Roger C. Soares <rogersoares@xxxxxxxxxxxxxxxx>
---
 .../src/org/spearce/egit/ui/GitHistoryPage.java    |  361 +++++++++++++++-----
 .../src/org/spearce/egit/ui/UIText.java            |    4 +
 .../src/org/spearce/egit/ui/uitext.properties      |    4 +
 3 files changed, 277 insertions(+), 92 deletions(-)

diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/GitHistoryPage.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/GitHistoryPage.java
index 3738dfd..ae404cf 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/GitHistoryPage.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/GitHistoryPage.java
@@ -17,6 +17,7 @@
 package org.spearce.egit.ui;
 
 import java.io.IOException;
+import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -37,10 +38,14 @@ import org.eclipse.core.runtime.IStatus;
 import org.eclipse.core.runtime.Status;
 import org.eclipse.core.runtime.jobs.Job;
 import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
 import org.eclipse.jface.action.IMenuListener;
 import org.eclipse.jface.action.IMenuManager;
 import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
 import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.text.Document;
+import org.eclipse.jface.text.TextViewer;
 import org.eclipse.jface.viewers.ColumnWeightData;
 import org.eclipse.jface.viewers.ILazyContentProvider;
 import org.eclipse.jface.viewers.StructuredSelection;
@@ -48,12 +53,11 @@ import org.eclipse.jface.viewers.TableLayout;
 import org.eclipse.jface.viewers.TableViewer;
 import org.eclipse.jface.viewers.Viewer;
 import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.SashForm;
 import org.eclipse.swt.events.MouseEvent;
 import org.eclipse.swt.events.MouseListener;
-import org.eclipse.swt.events.MouseMoveListener;
 import org.eclipse.swt.events.SelectionAdapter;
 import org.eclipse.swt.events.SelectionEvent;
-import org.eclipse.swt.graphics.Point;
 import org.eclipse.swt.layout.GridData;
 import org.eclipse.swt.layout.GridLayout;
 import org.eclipse.swt.widgets.Composite;
@@ -72,6 +76,8 @@ import org.eclipse.team.internal.ui.history.DialogHistoryPageSite;
 import org.eclipse.team.ui.history.HistoryPage;
 import org.eclipse.team.ui.history.IHistoryCompareAdapter;
 import org.eclipse.team.ui.history.IHistoryPageSite;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.part.IPageSite;
 import org.spearce.egit.core.GitProvider;
 import org.spearce.egit.core.internal.mapping.GitCommitFileRevision;
 import org.spearce.egit.core.internal.mapping.GitFileHistory;
@@ -92,16 +98,24 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 	private static final String PREF_SHOWALLREPOVERSIONS = "org.spearce.egit.ui.githistorypage.showallrepoversions";
 	private static final String PREF_SHOWALLPROJECTVERSIONS = "org.spearce.egit.ui.githistorypage.showallprojectversions";
 	private static final String PREF_SHOWALLFOLDERVERSIONS = "org.spearce.egit.ui.githistorypage.showallfolderversions";
+	/* private */static final SimpleDateFormat DATETIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");
+	/* private */static final SimpleDateFormat DATETIMETZ_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
 
-	private Composite localComposite;
+	private SashForm localComposite;
+	private SashForm revisionInfoComposite;
 
-	private TableViewer viewer;
+	/* private */TableViewer viewer;
+	/* private */TextViewer revDetailTextViewer;
+	/* private */TextViewer revCommentTextViewer;
+	/* private */IAction toggleCommentWrapAction;
+	/* private */IAction toggleRevDetailAction;
+	/* private */IAction toggleRevCommentAction;
 
-	private Table table;
+	/* private */Table table;
 
-	private List<IFileRevision> fileRevisions;
+	/* private */List<IFileRevision> fileRevisions;
 
-	protected boolean hintShowDiffNow;
+	/* private */boolean hintShowDiffNow;
 
 	private boolean showAllProjectVersions;
 
@@ -127,7 +141,8 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 	}
 
 	public void createControl(Composite parent) {
-		localComposite = new Composite(parent, SWT.NONE);
+		localComposite = new SashForm(parent, SWT.VERTICAL);
+
 		GridLayout layout = new GridLayout();
 		layout.marginHeight = 0;
 		layout.marginWidth = 0;
@@ -138,6 +153,10 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 
 		createTable(localComposite);
 
+		revisionInfoComposite = new SashForm(localComposite, SWT.HORIZONTAL);
+		createRevDetailTextViewer(revisionInfoComposite);
+		createRevCommentTextViewer(revisionInfoComposite);
+
 		IHistoryPageSite parentSite = getHistoryPageSite();
 		if (parentSite != null && parentSite instanceof DialogHistoryPageSite)
 			parentSite.setSelectionProvider(viewer);
@@ -149,6 +168,7 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		table.addMouseListener(new MouseListener() {
 		
 			public void mouseUp(MouseEvent e) {
+				return;
 			}
 		
 			public void mouseDown(MouseEvent e) {
@@ -156,25 +176,11 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 			}
 		
 			public void mouseDoubleClick(MouseEvent e) {
+				return;
 			}
 		
 		});
 
-		table.addMouseMoveListener(new MouseMoveListener() {
-			TableItem lastItem;
-			public void mouseMove(MouseEvent e) {
-				TableItem item = table.getItem(new Point(e.x,e.y));
-				if (item != null && item!=lastItem) {
-					IFileRevision rev = (IFileRevision) item.getData();
-					if (rev == null)
-						return;
-					String toolTipText = formatRevisionToolTipText(rev);
-					table.setToolTipText(toolTipText);
-				}
-				lastItem = item;
-			}
-		});
-
 		table.addSelectionListener(new SelectionAdapter() {
 			public void widgetSelected(SelectionEvent e) {
 				// update the current
@@ -184,6 +190,12 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 					selection2[i] = (IFileRevision) selection[i].getData();
 				}
 
+				// Updates the revision info text viewers
+				cleanRevisionInfoTextViewers();
+				if(selection2.length == 1) {
+					setRevisionInfoTextViewers(selection2[0]);
+				}
+
 				compareAction.setCurrentFileRevision(fileRevisions.get(0));
 				compareAction.selectionChanged(new StructuredSelection(
 						selection2));
@@ -280,33 +292,92 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		showAllFolderVersionsAction.setChecked(isShowAllFolderVersions());
 		getSite().getActionBars().getToolBarManager().add(
 				showAllFolderVersionsAction);
+
+		toggleCommentWrapAction = new Action(UIText.ResourceHistory_toggleCommentWrap) {
+			public void run() {
+				updateResourceHistoryComposites();
+			}
+		};
+		toggleCommentWrapAction.setChecked(true);
+
+		toggleRevDetailAction = new Action(UIText.ResourceHistory_toggleRevDetail) {
+			public void run() {
+				updateResourceHistoryComposites();
+			}
+		};
+		toggleRevDetailAction.setChecked(true);
+
+		toggleRevCommentAction = new Action(UIText.ResourceHistory_toggleRevComment) {
+			public void run() {
+				updateResourceHistoryComposites();
+			}
+		};
+		toggleRevCommentAction.setChecked(true);
+
+		IActionBars actionBars = getSite().getActionBars();
+		IMenuManager menuManager = actionBars.getMenuManager();
+		if (menuManager != null) {
+			menuManager.add(toggleCommentWrapAction);
+			menuManager.add(new Separator());
+			menuManager.add(toggleRevDetailAction);
+			menuManager.add(toggleRevCommentAction);
+			menuManager.add(new Separator());
+		}
+		actionBars.updateActionBars();
+		updateResourceHistoryComposites();
+
+		localComposite.setWeights(new int[] {65, 35});
+		revisionInfoComposite.setWeights(new int[] {40, 60});
+	}
+
+	/* private */void updateResourceHistoryComposites() {
+		boolean commentWrap = toggleCommentWrapAction.isChecked();
+		boolean showRevDetail = toggleRevDetailAction.isChecked();
+		boolean showRevComment = toggleRevCommentAction.isChecked();
+
+		revCommentTextViewer.getTextWidget().setWordWrap(commentWrap);
+
+		if(showRevDetail && showRevComment) {
+			localComposite.setMaximizedControl(null);
+			revisionInfoComposite.setMaximizedControl(null);
+		} else {
+			if(!(showRevDetail || showRevComment)) {
+				localComposite.setMaximizedControl(table);
+			} else if(showRevDetail) {
+				localComposite.setMaximizedControl(null);
+				revisionInfoComposite.setMaximizedControl(revDetailTextViewer.getControl());
+			} else {
+				localComposite.setMaximizedControl(null);
+				revisionInfoComposite.setMaximizedControl(revCommentTextViewer.getControl());
+			}
+		}
 	}
 
-	private boolean isShowAllRepoVersions() {
+	/* private */boolean isShowAllRepoVersions() {
 		return showAllRepoVersions;
 	}
 
-	protected void setShowAllRepoVersions(boolean showAllRepoVersions) {
+	/* private */void setShowAllRepoVersions(boolean showAllRepoVersions) {
 		this.showAllRepoVersions = showAllRepoVersions;
 		Activator.getDefault().getPreferenceStore().setValue(
 				PREF_SHOWALLREPOVERSIONS, showAllRepoVersions);
 	}
 
-	private boolean isShowAllProjectVersions() {
+	/* private */boolean isShowAllProjectVersions() {
 		return showAllProjectVersions;
 	}
 
-	protected void setShowAllProjectVersions(boolean showAllProjectVersions) {
+	/* private */void setShowAllProjectVersions(boolean showAllProjectVersions) {
 		this.showAllProjectVersions = showAllProjectVersions;
 		Activator.getDefault().getPreferenceStore().setValue(
 				PREF_SHOWALLPROJECTVERSIONS, showAllProjectVersions);
 	}
 
-	private boolean isShowAllFolderVersions() {
+	/* private */boolean isShowAllFolderVersions() {
 		return showAllFolderVersions;
 	}
 
-	protected void setShowAllFolderVersion(boolean showAllFolderVersions) {
+	/* private */void setShowAllFolderVersion(boolean showAllFolderVersions) {
 		this.showAllFolderVersions = showAllFolderVersions;
 		Activator.getDefault().getPreferenceStore().setValue(
 				PREF_SHOWALLFOLDERVERSIONS, showAllFolderVersions);
@@ -392,7 +463,7 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 				Date d = new Date(element.getTimestamp());
 				if (d.getTime() == -1)
 					return "";
-				return d.toString();
+				return DATETIME_FORMAT.format(d);
 			}
 			if (columnIndex == 4)
 				return element.getAuthor();
@@ -411,6 +482,166 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		}
 	}
 
+	private void createRevDetailTextViewer(SashForm composite) {
+		revDetailTextViewer = new TextViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY);
+	}
+
+	private void createRevCommentTextViewer(SashForm composite) {
+		revCommentTextViewer = new TextViewer(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY);
+	}
+
+	/* private */void setRevisionInfoTextViewers(IFileRevision rev) {
+		StringBuilder revisionInfo = new StringBuilder();
+		if (appliedPatches != null) {
+			String id = rev.getContentIdentifier();
+			if (!id.equals("Workspace") && !id.equals("Index")) {
+				StGitPatch patch = (StGitPatch) appliedPatches
+						.get(new ObjectId(id));
+				if (patch != null) {
+					revisionInfo.append("Patch: ");
+					revisionInfo.append(patch.getName());
+				}
+			} else {
+				revisionInfo.append(id.toString());
+			}
+		}
+		if (revisionInfo.length() == 0) {
+			revisionInfo.append("Commit: ");
+			revisionInfo.append(rev.getContentIdentifier());
+		}
+
+		// Gets the tags for this revision.
+		// TODO: Understand this better and see if there's a simpler/shared way to do it.
+		IProject project = ((IResource) getInput()).getProject();
+		RepositoryMapping repositoryMapping = RepositoryMapping.getMapping(project);
+		Map<ObjectId,Tag[]> newtags = new HashMap<ObjectId,Tag[]>();
+		try {
+			for (String name : repositoryMapping.getRepository().getTags()) {
+				Tag t = repositoryMapping.getRepository().mapTag(name);
+				Tag[] samecommit = newtags.get(t.getObjId());
+				if (samecommit==null) { 
+					samecommit = new Tag[] { t };
+				} else {
+					Tag[] n=new Tag[samecommit.length+1];
+					for (int j=0; j<samecommit.length; ++j)
+						n[j] = samecommit[j];
+					n[n.length-1] = t;
+					samecommit = n;
+				}
+				newtags.put(t.getObjId(), samecommit);
+			}
+
+			String id = rev.getContentIdentifier();
+			if (!id.equals("Workspace") && !id.equals("Index")) {
+				ObjectId oid = new ObjectId(id);
+				StringBuilder b=new StringBuilder();
+				if (tags != null) {
+					Tag[] matching = tags.get(oid);
+					if (matching != null) {
+						for (Tag t : matching) {
+							if (b.length() > 0)
+								b.append(", ");
+							String tag = t.getTag();
+							b.append(tag);
+						}
+					}
+				}
+				if(b.length() > 0) {
+					revisionInfo.append("\nTags: ");
+					revisionInfo.append(b);
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		// Gets the branches for this revision.
+		// TODO: Branches should always show all the branches from a commit.
+		Map<ObjectId, String[]> newBranches = new HashMap<ObjectId, String[]>();
+		try {
+			for (String branch : repositoryMapping.getRepository().getBranches()) {
+				ObjectId id = repositoryMapping.getRepository().resolve(branch);
+				String[] samecommit = newBranches.get(id);
+				if (samecommit == null) {
+					samecommit = new String[] { branch };
+				} else {
+					String[] n=new String[samecommit.length + 1];
+					for (int j=0; j<samecommit.length; ++j)
+						n[j] = samecommit[j];
+					n[n.length-1] = branch;
+					samecommit = n;
+				}
+				newBranches.put(id, samecommit);
+			}
+			String[] samecommit = newBranches.get(currentHead);
+			if (samecommit == null) {
+				samecommit = new String[] { "HEAD" };
+			} else {
+				String[] n=new String[samecommit.length + 1];
+				for (int j=0; j<samecommit.length; ++j)
+					n[j] = samecommit[j];
+				n[n.length-1] = "HEAD";
+				samecommit = n;
+			}
+			newBranches.put(currentHead, samecommit);
+			branches = newBranches;
+
+			String id = rev.getContentIdentifier();
+			if (branches != null) {
+				StringBuilder b=new StringBuilder();
+				ObjectId oid = new ObjectId(id);
+				String[] matching = branches.get(oid);
+				if (matching != null) {
+					for (String t : matching) {
+						if (b.length() > 0)
+							b.append(", ");
+						if (t.startsWith("refs/heads/"))
+							t = t.substring(11);
+						b.append(t);
+					}
+				}
+				if(b.length() > 0) {
+					revisionInfo.append("\nBranches: ");
+					revisionInfo.append(b);
+				}
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+
+		revisionInfo.append("\nAuthor: ");
+		revisionInfo.append(rev.getAuthor());
+		revisionInfo.append("\nDate: ");
+		revisionInfo.append(DATETIMETZ_FORMAT.format(new Date(rev.getTimestamp())));
+
+		String comment = rev.getComment();
+		revDetailTextViewer.setDocument(new Document(revisionInfo.toString()));
+		revCommentTextViewer.setDocument(new Document(comment));
+
+		// Adds the first comment line in the status line.
+		int enterIndex = comment.indexOf("\n");
+		if(enterIndex > 0) {
+			comment = comment.substring(0, enterIndex);
+		}
+		IPageSite workbenchPageSite = getHistoryPageSite().getWorkbenchPageSite();
+		if (workbenchPageSite != null) {
+			workbenchPageSite.getActionBars().getStatusLineManager().setMessage(comment);
+		}
+	}
+
+	/* private */void cleanRevisionInfoTextViewers() {
+		if(revDetailTextViewer != null && revCommentTextViewer != null) {
+			revDetailTextViewer.setDocument(new Document(""));
+			revCommentTextViewer.setDocument(new Document(""));
+
+			// Cleans the status line
+			IPageSite workbenchPageSite = getHistoryPageSite().getWorkbenchPageSite();
+			if (workbenchPageSite != null) {
+				workbenchPageSite.getActionBars().getStatusLineManager().setMessage(null);
+			}
+		}
+	}
+
 	private void createTable(Composite composite) {
 		table = new Table(composite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI
 				| SWT.FULL_SELECTION | SWT.VIRTUAL);
@@ -556,10 +787,10 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		viewer.setInput(getInput());
 	}
 
-	private Map appliedPatches;
+	/* private */Map appliedPatches;
 	ObjectId currentHead;
-	private Map<ObjectId,Tag[]> tags;
-	private Map<ObjectId, String[]> branches;
+	/* private */Map<ObjectId,Tag[]> tags;
+	/* private */Map<ObjectId, String[]> branches;
 	GitHistoryLabelProvider lp = new GitHistoryLabelProvider();
 
 	class HistoryRefreshJob extends Job {
@@ -662,6 +893,8 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 				table.getDisplay().asyncExec(new Runnable() {
 				
 					public void run() {
+						cleanRevisionInfoTextViewers();
+
 						table.removeAll();
 						table.setItemCount(fileRevisions.size());
 						table.setData("X");
@@ -720,6 +953,7 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		}
 
 		public void dispose() {
+			return;
 		}
 
 		public void updateElement(int index) {
@@ -757,7 +991,7 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		col.setResizable(true);
 		col.setText(TeamUIMessages.GenericHistoryTableProvider_RevisionTime);
 		// X col.addSelectionListener(headerListener);
-		((TableLayout) table.getLayout()).addColumnData(new ColumnWeightData(30,
+		((TableLayout) table.getLayout()).addColumnData(new ColumnWeightData(20,
 				true));
 
 		// author
@@ -773,7 +1007,7 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		col.setResizable(true);
 		col.setText(TeamUIMessages.GenericHistoryTableProvider_Comment);
 		// X col.addSelectionListener(headerListener);
-		((TableLayout) table.getLayout()).addColumnData(new ColumnWeightData(35,
+		((TableLayout) table.getLayout()).addColumnData(new ColumnWeightData(45,
 				true));
 	}
 
@@ -821,61 +1055,4 @@ public class GitHistoryPage extends HistoryPage implements IAdaptable,
 		// TODO Auto-generated method stub
 	}
 
-	/**
-	 * Formats the revision description to be displayed in the tooltip.
-	 *
-	 * @param rev
-	 *            the revision to be displayed
-	 * @return formatted description
-	 */
-	protected String formatRevisionToolTipText(IFileRevision rev) {
-		String commitStr = null;
-		if (appliedPatches != null) {
-			String id = rev.getContentIdentifier();
-			if (!id.equals("Workspace") && !id.equals("Index")) {
-				StGitPatch patch = (StGitPatch) appliedPatches
-						.get(new ObjectId(id));
-				if (patch != null)
-					commitStr = "Patch: " + patch.getName();
-			} else {
-				commitStr = id.toString();
-			}
-		}
-		if (commitStr == null)
-			commitStr = "Commit: " + rev.getContentIdentifier();
-
-		// The tooltip window is usually
-		// narrower
-		// than the comment. Remove soft returns
-		// to
-		// avoid short lines like in
-		// this
-		// example
-		String niceComment = unwrapComment(rev.getComment());
-		String toolTipText = commitStr + "\nAuthor: " + rev.getAuthor()
-				+ "\nDate: " + new Date(rev.getTimestamp()) + "\n\n"
-				+ niceComment;
-		return toolTipText;
-	}
-
-	/**
-	 * Remove soft returns (single \n) from the string. Keep hard returns
-	 * between paragraphs (two \n).
-	 *
-	 * @param origComment
-	 * @return reformated comment
-	 */
-	private static String unwrapComment(String origComment) {
-		if (origComment == null)
-			return null;
-		String paragraphs[] = origComment.split("\n\\s*\n");
-		StringBuffer result = new StringBuffer();
-		for (int i = 0; i < paragraphs.length; i++) {
-			result.append(paragraphs[i].replaceAll("\n", " "));
-			if (i < paragraphs.length - 1)
-				result.append("\n\n");
-		}
-		return result.toString();
-	}
-
 }
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
index cdbe8bb..b714c1d 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/UIText.java
@@ -39,6 +39,10 @@ public class UIText extends NLS {
 
 	public static String QuickDiff_failedLoading;
 
+	public static String ResourceHistory_toggleCommentWrap;
+	public static String ResourceHistory_toggleRevDetail;
+	public static String ResourceHistory_toggleRevComment;
+
 	static {
 		initializeMessages(UIText.class.getPackage().getName() + ".uitext",
 				UIText.class);
diff --git a/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties b/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties
index 75e975b..f45f4d2 100644
--- a/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties
+++ b/org.spearce.egit.ui/src/org/spearce/egit/ui/uitext.properties
@@ -28,3 +28,7 @@ ExistingOrNewPage_createNew=Create a new Git repository for this project
 
 Decorator_failedLazyLoading=Resource decorator failed to load tree contents on demand.
 QuickDiff_failedLoading=Quick diff failed to obtain file data.
+
+ResourceHistory_toggleCommentWrap=Wrap Comments
+ResourceHistory_toggleRevDetail=Show Revision Details
+ResourceHistory_toggleRevComment=Show Revision Comment
\ No newline at end of file
-- 
1.5.3.7

-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux