Patch #3283 2012-04-28 02:57
alpha0010
Context menu: Open link in browser- Download
- 3283-Context_menu_O.patch (3.9 KB)
Index: src/sdk/cbeditor.cpp
===================================================================
--- src/sdk/cbeditor.cpp (revision 8021)
+++ src/sdk/cbeditor.cpp (working copy)
@@ -552,6 +552,66 @@
}
}
+ wxString GetUrl()
+ {
+ cbStyledTextCtrl* control = m_pOwner->GetControl();
+ if (!control)
+ return wxEmptyString;
+
+ wxRegEx reUrl(wxT("***:(((ht|f)tp(s?)\\:\\/\\/)|(www\\.))(([a-zA-Z0-9\\-\\._]+(\\.[a-zA-Z0-9\\-\\._]+)+)|localhost)(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\'\\/\\\\\\+&%\\$#_]*)?([\\d\\w\\.\\/\\%\\+\\-\\=\\&\\?\\:\\\\\\"\\'\\,\\|\\~\\;]*)"));
+ wxString url = control->GetSelectedText();
+ // Is the URL selected?
+ if (reUrl.Matches(url))
+ return reUrl.GetMatch(url);
+ // else is there a URL near the cursor?
+
+ // Find out start position
+ int startPos = control->GetCurrentPos();
+ const wxString space = wxT(" \n\r\t{}");
+ wxChar curCh = control->GetCharAt(startPos);
+ while ( (startPos > 0) && (space.Find(curCh) == -1) )
+ {
+ startPos--;
+ curCh = control->GetCharAt(startPos);
+ }
+
+ // Find out end position
+ int endPos = control->GetCurrentPos();
+ int maxPos = control->GetLineEndPosition(control->GetLineCount());
+ curCh = control->GetCharAt(endPos);
+ while ( (endPos < maxPos) && (space.Find(curCh) == -1) )
+ {
+ endPos++;
+ curCh = control->GetCharAt(endPos);
+ }
+
+ url = control->GetTextRange(startPos, endPos);
+ if ( (control->GetLexer() == wxSCI_LEX_CPP)
+ && ( (control->GetStyleAt(control->GetCurrentPos()) == wxSCI_C_STRING)
+ || (control->GetStyleAt(control->GetCurrentPos()) == wxSCI_C_STRINGEOL) ) )
+ {
+ url.Replace(wxT("\\n"), wxT("\n"));
+ url.Replace(wxT("\\r"), wxT("\r"));
+ url.Replace(wxT("\\t"), wxT("\t"));
+ }
+
+ if (reUrl.Matches(url))
+ {
+ wxString match = reUrl.GetMatch(url);
+ if ( (url.Find(match) + startPos < control->GetCurrentPos())
+ && (url.Find(match) + startPos + (int)match.Length() > control->GetCurrentPos()) )
+ {
+ url = match;
+ }
+ else
+ url = wxEmptyString; // nope, too far from cursor, return invalid (empty)
+ }
+ else
+ url = wxEmptyString; // nope, return invalid (empty)
+
+ return url;
+ }
+
//vars
bool m_strip_trailing_spaces;
bool m_ensure_final_line_end;
@@ -609,6 +669,7 @@
const int idAddFileToProject = wxNewId();
const int idRemoveFileFromProject = wxNewId();
const int idShowFileInProject = wxNewId();
+const int idOpenUrl = wxNewId();
const int idBookmarkAdd = wxNewId();
const int idBookmarkRemove = wxNewId();
@@ -661,6 +722,7 @@
EVT_MENU(idSplitHorz, cbEditor::OnContextMenuEntry)
EVT_MENU(idSplitVert, cbEditor::OnContextMenuEntry)
EVT_MENU(idUnsplit, cbEditor::OnContextMenuEntry)
+ EVT_MENU(idOpenUrl, cbEditor::OnContextMenuEntry)
EVT_SCI_ZOOM(-1, cbEditor::OnZoom)
EVT_SCI_ZOOM(-1, cbEditor::OnZoom)
@@ -2673,6 +2735,12 @@
}
else
{
+ if(!noeditor && !m_pData->GetUrl().IsEmpty())
+ {
+ popup->InsertSeparator(0);
+ popup->Insert(0, idOpenUrl, _("Open link in browser"));
+ }
+
wxMenu* splitMenu = new wxMenu;
splitMenu->Append(idSplitHorz, _("Horizontally"));
splitMenu->Append(idSplitVert, _("Vertically"));
@@ -2933,6 +3001,8 @@
UnfoldBlockFromLine();
else if (id == idFoldingToggleCurrent)
ToggleFoldBlockFromLine();
+ else if (id == idOpenUrl)
+ wxLaunchDefaultBrowser(m_pData->GetUrl());
else if (id == idSplitHorz)
Split(stHorizontal);
else if (id == idSplitVert)
History
Very nice feature, I would like to apply in the near future.
Improve detection accuracy on escape sequences in strings.
Agreed from my side. Its like in Eclipse or other editors...
Just do a tiny clean-up of the code, for example: if you checked that url.IsEmpty() you don't need the last else- clause where you set url to "empty" explicitly again...
Another one: It does not compile under wxWidgets 2.9.x. I've an updated function here, that works (and is cleaned-up): wxString GetUrl() { cbStyledTextCtrl* control = m_pOwner->GetControl(); if (!control) return wxEmptyString; wxRegEx reUrl(wxT("***:(((ht|f)tp(s?)\\:\\/\\/)|(www\\.))(([a-zA-Z0-9\\-\\._]+(\\.[a-zA-Z0-9\\-\\._]+)+)|localhost)(\\/?)([a-zA-Z0-9\\-\\.\\?\\,\\'\\/\\\\\\+&%\\$#_]*)?([\\d\\w\\.\\/\\%\\+\\-\\=\\&\\?\\:\\\\\\"\\'\\,\\|\\~\\;]*)")); wxString url = control->GetSelectedText(); url.Trim(true).Trim(false); if (url.IsEmpty()) return wxEmptyString; if (reUrl.Matches(url)) return reUrl.GetMatch(url); // Find out start position int startPos = control->GetCurrentPos(); const wxString space = wxT(" \n\r\t{}"); wxChar startCh = control->GetCharAt(startPos); while ( (startPos > 0) && (space.Find(startCh) == -1) ) startPos--; // Find out end position int endPos = control->GetCurrentPos(); int maxPos = control->GetLineEndPosition(control->GetLineCount()); wxChar endCh = control->GetCharAt(endPos); while ( (endPos < maxPos) && (space.Find(endCh) == -1) ) endPos++; url = control->GetTextRange(startPos, endPos); if ( (control->GetLexer() == wxSCI_LEX_CPP) && ( (control->GetStyleAt(control->GetCurrentPos()) == wxSCI_C_STRING) || (control->GetStyleAt(control->GetCurrentPos()) == wxSCI_C_STRINGEOL) ) ) { url.Replace(wxT("\\n"), wxT("\n")); url.Replace(wxT("\\r"), wxT("\r")); url.Replace(wxT("\\t"), wxT("\t")); } if (reUrl.Matches(url)) { wxString match = reUrl.GetMatch(url); if ( (url.Find(match) + startPos < control->GetCurrentPos()) && (url.Find(match) + startPos + (int)match.Length() > control->GetCurrentPos()) ) { url = match; } else url = wxEmptyString; // nope, return invalid (empty) } else url = wxEmptyString; // nope, return invalid (empty) return url; }
Updated to the cleaned-up function with the following modifications:
* removed Trim() - had no purpose
* removed several optimizations - these caused it to only work if the URL was already selected (GetUrl() first checks if a URL is selected, then checks if there is a URL near the cursor - so one can simply right-click on a link, without needing to actually select it)
This part: while ( (startPos > 0) && (space.Find(control->GetCharAt(startPos)) == -1) ) does NOT work with wx2.9.x. I changed that on purpose to: wxChar startCh = control->GetCharAt(startPos); while ( (startPos > 0) && (space.Find(startCh) == -1) ) startPos--; ...(at two positions) in my other comment. Please leave it like that.
Apologies; I had reverted that because it broke the range finding logic (wxChar must update each iteration).
Does this revision compile with wx2.9.x?
Ok, this one is fine.
@ollydbg: Should I commit / will you? (I have it aligned a little bit more, but the content is the same and working in this version.)
@morten: please commit it.
PS: I see there are some parenthesis in "if" or "while" condition which can be removed, right?
Applied in SVN head (on behalf of ollydbg). Thanks!