From 5a597cd71a57cc99442c6b0a4342bc00969097b4 Mon Sep 17 00:00:00 2001 From: "Zane U. Ji" Date: Tue, 20 May 2014 22:36:03 +0800 Subject: [PATCH] Feature #69 Add "current XPath" shortcut --- ChangeLog | 1 + src/xmlcopyeditor.cpp | 49 +++++++++++++++++++++++++++++++++++++++++++ src/xmlcopyeditor.h | 3 +++ src/xmlctrl.cpp | 24 +++++++++++++++++++++ src/xmlctrl.h | 1 + 5 files changed, 78 insertions(+) diff --git a/ChangeLog b/ChangeLog index 555937d..9762e55 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,5 @@ 1.2.1.2 + + Feature #69 Add "current XPath" shortcut + Click on the error message to jump to the error location * Bug #99 fix desktop file (Marco Rodrigues) diff --git a/src/xmlcopyeditor.cpp b/src/xmlcopyeditor.cpp index f59cc94..3dec286 100644 --- a/src/xmlcopyeditor.cpp +++ b/src/xmlcopyeditor.cpp @@ -159,6 +159,7 @@ BEGIN_EVENT_TABLE ( MyFrame, wxFrame ) EVT_MENU ( ID_LOCATION_PANE_VISIBLE, MyFrame::OnLocationPaneVisible ) EVT_MENU ( ID_PROTECT_TAGS, MyFrame::OnProtectTags ) EVT_MENU ( ID_WRAP_WORDS, MyFrame::OnWrapWords ) + EVT_MENU ( ID_COPY_XPATH, MyFrame::OnCopyXPath ) EVT_MENU_RANGE ( ID_SHOW_TAGS, ID_HIDE_TAGS, MyFrame::OnVisibilityState ) EVT_MENU_RANGE ( ID_ASSOCIATE_DTD_PUBLIC, ID_ASSOCIATE_XSL, MyFrame::OnAssociate ) EVT_MENU_RANGE ( wxID_FILE1, wxID_FILE9, MyFrame::OnHistoryFile ) @@ -201,6 +202,7 @@ BEGIN_EVENT_TABLE ( MyFrame, wxFrame ) EVT_UPDATE_UI ( ID_CLOSE_FIND_REPLACE_PANE, MyFrame::OnUpdateCloseFindReplacePane ) EVT_UPDATE_UI ( ID_CLOSE_COMMAND_PANE, MyFrame::OnUpdateCloseCommandPane ) EVT_UPDATE_UI ( ID_RELOAD, MyFrame::OnUpdateReload ) + EVT_UPDATE_UI ( ID_COPY_XPATH, MyFrame::OnUpdateCopyXPath ) EVT_IDLE ( MyFrame::OnIdle ) EVT_AUINOTEBOOK_PAGE_CLOSE ( wxID_ANY, MyFrame::OnPageClosing ) #ifdef __WXMSW__ @@ -5194,6 +5196,10 @@ wxMenuBar *MyFrame::getMenuBar() ID_XPATH, _ ( "&Evaluate XPath...\tF9" ), _ ( "Evaluate XPath..." ) ); + xmlMenu->Append ( + ID_COPY_XPATH, + _ ( "Copy &The Current XPath" ), + _ ( "Copy The Current XPath" ) ); xmlMenu->AppendSeparator(); xmlMenu->Append ( @@ -6019,6 +6025,49 @@ void MyFrame::OnPromptGenerated ( wxNotifyEvent &event ) insertEntityPanel->update ( doc, wxEmptyString, wxEmptyString, true ); } +void MyFrame::OnCopyXPath ( wxCommandEvent &event ) +{ + XmlDoc *doc = getActiveDocument(); + if ( !doc ) + return; + + wxBusyCursor cursor; + + wxString xpath = doc->getCurrentXPath(); + // Write the XPath to the clipboard + if ( xpath.IsEmpty() ) + { + messagePane ( _("The current XPath is empty."), CONST_WARNING ); + } + else if ( wxTheClipboard->Open() ) + { + // This data objects are held by the clipboard, + // so do not delete them in the app. + wxTheClipboard->SetData ( new wxTextDataObject ( xpath ) ); + wxTheClipboard->Close(); + + wxString message = wxString::Format + ( _("The current XPath has been copied to the clipboard:[br][b]%s[/b]") + , xpath.c_str() + ); + messagePane ( message, CONST_INFO ); + } + else + { + wxString message = wxString::Format + ( _("Failed to copy the current XPath to the clipboard:[br][b]%s[/b]") + , xpath.c_str() + ); + messagePane ( message, CONST_STOP ); + htmlReport->SetFocus(); // This is needed to make Ctrl + C work + } +} + +void MyFrame::OnUpdateCopyXPath ( wxUpdateUIEvent& event ) +{ + event.Enable ( getActiveDocument() ); +} + wxString MyFrame::getAuxPath ( const wxString& fileName ) { if ( fileName.Find ( _T ( ".xsl" ) ) != wxNOT_FOUND || diff --git a/src/xmlcopyeditor.h b/src/xmlcopyeditor.h index 274602b..d4f9ce2 100644 --- a/src/xmlcopyeditor.h +++ b/src/xmlcopyeditor.h @@ -125,6 +125,7 @@ enum ID_CREATE_SCHEMA, ID_DTD_TO_SCHEMA, ID_XPATH, + ID_COPY_XPATH, ID_XSLT, ID_XSLT_TEI_FO, ID_XSLT_TEI_HTML, @@ -320,6 +321,8 @@ class MyFrame : public wxFrame void OnDropFiles ( wxDropFilesEvent& event ); #endif void OnPromptGenerated ( wxNotifyEvent &event ); + void OnCopyXPath ( wxCommandEvent &event ); + void OnUpdateCopyXPath ( wxUpdateUIEvent& event ); void setStrictScrolling ( bool b ); void validateRelaxNG ( XmlDoc *doc, diff --git a/src/xmlctrl.cpp b/src/xmlctrl.cpp index cb14782..185bcf2 100644 --- a/src/xmlctrl.cpp +++ b/src/xmlctrl.cpp @@ -2366,3 +2366,27 @@ void XmlCtrl::toggleComment() SetSelection ( pos, pos ); } } + +wxString XmlCtrl::getCurrentXPath() +{ + wxString xpath; + int pos = GetCurrentPos(); + for ( ; ; ) + { + pos = findPreviousStartTag ( pos, 1, '>' ); + if ( pos <= 0 ) + break; + + wxString name = getLastElementName ( pos ); + size_t pos = name.Index ( ':' ); + if ( pos != wxString::npos && pos < name.length() ) + { + ++pos; + name = _T("*[local-name()='") + + name.substr ( pos, name.length() - pos ) + _T("']"); + } + xpath = _T("/") + name + xpath; + } + + return xpath; +} diff --git a/src/xmlctrl.h b/src/xmlctrl.h index c1dc08a..480ec9c 100644 --- a/src/xmlctrl.h +++ b/src/xmlctrl.h @@ -160,6 +160,7 @@ class XmlCtrl: public wxStyledTextCtrl void setValidationRequired ( bool b ); bool selectCurrentElement(); void toggleComment(); + wxString getCurrentXPath(); private: ValidationThread *validationThread; // used for background validation XmlPromptGenerator *mPromptGeneratorThread;