I just uploaded patch 2405 to BerliOS. This patch adds features to the AStyle plugin.
Comments, questions and complaints from anyone are welcome.
Index: astyleplugin.cpp
===================================================================
--- astyleplugin.cpp (revision 4944)
+++ astyleplugin.cpp (working copy)
@@ -24,12 +24,25 @@
#include <wx/xrc/xmlres.h>
#include <wx/fs_zip.h>
#include <wx/strconv.h>
+#include <wx/progdlg.h>
#include "asstreamiterator.h"
#include "cbstyledtextctrl.h"
using std::istringstream;
using std::string;
+namespace
+{
+ const int idCodeFormatterFile = wxNewId();
+ const int idCodeFormatterActiveFile = wxNewId();
+ const int idCodeFormatterProject = wxNewId();
+}
+
+BEGIN_EVENT_TABLE( AStylePlugin, cbPlugin )
+ EVT_MENU( idCodeFormatterActiveFile, AStylePlugin::OnFormatActiveFile )
+ EVT_MENU( idCodeFormatterProject, AStylePlugin::OnFormatProject )
+END_EVENT_TABLE()
+
// this auto-registers the plugin
namespace
@@ -78,6 +91,97 @@
return dlg;
}
+void AStylePlugin::BuildModuleMenu( const ModuleType type, wxMenu* menu, const FileTreeData* data )
+{
+ if ( !menu || !IsAttached() )
+ return;
+
+ switch ( type )
+ {
+ case mtEditorManager:
+ menu->AppendSeparator();
+ menu->Append( idCodeFormatterActiveFile, _( "Format This File (AStyle)" ), _( "Format the source code in the current file" ) );
+ break;
+
+ case mtProjectManager:
+ if ( data ) switch ( data->GetKind() )
+ {
+ case FileTreeData::ftdkProject:
+ menu->AppendSeparator();
+ menu->Append( idCodeFormatterProject, _( "Format This Project (AStyle)" ), _( "Format the source code in this project" ) );
+ break;
+
+ case FileTreeData::ftdkFile:
+ menu->AppendSeparator();
+ menu->Append( idCodeFormatterProject, _( "Format This File (AStyle)" ), _( "Format the source code in this file" ) );
+ break;
+
+ default:
+ // Do nothing.
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void AStylePlugin::OnFormatProject( wxCommandEvent& event )
+{
+ wxTreeCtrl *tree = Manager::Get()->GetProjectManager()->GetTree();
+
+ if ( NULL == tree )
+ return;
+
+ wxTreeItemId treeItem = tree->GetSelection();
+
+ if ( false == treeItem.IsOk() )
+ return;
+
+ const FileTreeData *data = static_cast<FileTreeData*>( tree->GetItemData( treeItem ) );
+
+ if ( NULL == data )
+ return;
+
+ switch ( data->GetKind() )
+ {
+ case FileTreeData::ftdkProject:
+ {
+ cbProject* prj = data->GetProject();
+ wxProgressDialog progressDlg(_("Please wait"), _("Formatting..."), prj->GetFilesCount(), NULL, wxPD_CAN_ABORT|wxPD_AUTO_HIDE|wxPD_SMOOTH );
+ progressDlg.Show();
+ for ( int i = 0; i < prj->GetFilesCount(); ++i )
+ {
+ ProjectFile* pf = prj->GetFile( i );
+ wxString filename = pf->file.GetFullPath();
+
+ FileType fileType = FileTypeOf( filename );
+ if ( fileType == ftSource || fileType == ftHeader )
+ {
+ FormatFile( filename );
+ if ( false == progressDlg.Update( i, wxString("Formatting ") + pf->relativeFilename ) )
+ break;
+ }
+ }
+ }
+ break;
+
+ case FileTreeData::ftdkFile:
+ {
+ ProjectFile* f = data->GetProject()->GetFile( data->GetFileIndex() );
+ if ( f )
+ FormatFile( f->file.GetFullPath() );
+ }
+ break;
+ }
+}
+
+void AStylePlugin::OnFormatActiveFile( wxCommandEvent& event )
+{
+ Execute();
+}
+
int AStylePlugin::Execute()
{
if (!IsAttached())
@@ -92,10 +196,96 @@
return 0;
}
+ FormatEditor( ed );
+}
+
+void AStylePlugin::FormatFile( const wxString &filename )
+{
+ cbEditor* ed = Manager::Get()->GetEditorManager()->IsBuiltinOpen( filename );
+
+ if ( ed )
+ {
+ // File is already open
+ FormatEditor( ed );
+ }
+ else
+ {
+ // File is not open. We must open it.
+ ed = Manager::Get()->GetEditorManager()->Open( filename );
+
+ if ( ed )
+ {
+ bool changed = FormatEditor( ed );
+
+ if ( !changed )
+ {
+ // We opened a file and it didn't change. Close it.
+ Manager::Get()->GetEditorManager()->Close( filename );
+ }
+ }
+ }
+}
+
+// Special code to compare strings which doesn't care
+// about spaces leading up to the EOL.
+static bool BuffersDiffer( const wxString &a, const wxString &b )
+{
+ const wxChar *aCurrent = a.c_str();
+ const wxChar *bCurrent = b.c_str();
+ const wxChar * const aEnd = aCurrent + a.Len();
+ const wxChar * const bEnd = bCurrent + b.Len();
+
+ while ( aCurrent != aEnd && bCurrent != bEnd )
+ {
+ if ( *aCurrent != *bCurrent )
+ {
+ // Check for varying space at EOL
+ while ( *aCurrent == ' ' || *aCurrent == '\t' )
+ {
+ if ( ++aCurrent == aEnd )
+ break;
+ }
+ while ( *bCurrent == ' ' || *bCurrent == '\t' )
+ {
+ if ( ++bCurrent == bEnd )
+ break;
+ }
+
+ // Make sure it was at EOL
+ if ( ( *aCurrent != '\r' && *aCurrent != '\n' ) || ( *bCurrent != '\r' && *bCurrent != '\n' ) )
+ return true;
+ }
+
+ ++aCurrent;
+ ++bCurrent;
+ }
+
+ while ( aCurrent != aEnd )
+ {
+ if ( *aCurrent != ' ' && *aCurrent != '\t' )
+ {
+ return true;
+ }
+
+ }
+
+ while ( bCurrent != bEnd )
+ {
+ if ( *bCurrent != ' ' && *bCurrent != '\t' )
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool AStylePlugin::FormatEditor( cbEditor *ed )
+{
if (ed->GetControl()->GetReadOnly())
{
cbMessageBox(_("The file is read-only"), _("Error"), wxICON_ERROR);
- return 0;
+ return false;
}
wxString edText(ed->GetControl()->GetText());
@@ -167,20 +357,24 @@
int pos = ed->GetControl()->GetCurrentPos();
- ed->GetControl()->BeginUndoAction();
- ed->GetControl()->SetText(formattedText);
+ bool changed = BuffersDiffer( formattedText, edText );
- for (std::vector<int>::const_iterator i = new_bookmark.begin(); i != new_bookmark.end(); ++i)
- {
- ed->ToggleBookmark(*i);
- }
+ if ( changed )
+ {
+ ed->GetControl()->BeginUndoAction();
+ ed->GetControl()->SetText(formattedText);
- ed->GetControl()->EndUndoAction();
+ for (std::vector<int>::const_iterator i = new_bookmark.begin(); i != new_bookmark.end(); ++i)
+ {
+ ed->ToggleBookmark(*i);
+ }
- ed->GetControl()->GotoPos(pos);
- ed->SetModified(true);
+ ed->GetControl()->EndUndoAction();
+ ed->GetControl()->GotoPos(pos);
+ ed->SetModified(true);
+ }
wxSetCursor(wxNullCursor);
- return 0;
+ return changed;
}
Index: astyleplugin.h
===================================================================
--- astyleplugin.h (revision 4944)
+++ astyleplugin.h (working copy)
@@ -28,9 +28,18 @@
int Configure();
int GetConfigurationGroup() const { return cgEditor; }
cbConfigurationPanel* GetConfigurationPanel(wxWindow* parent);
+ void BuildModuleMenu( const ModuleType type, wxMenu* menu, const FileTreeData* data = 0 );
int Execute();
+
+ void OnFormatActiveFile( wxCommandEvent& event );
+ void OnFormatProject( wxCommandEvent& event );
+ void FormatFile( const wxString &filename );
+ bool FormatEditor( cbEditor *ed );
+
void OnAttach(); // fires when the plugin is attached to the application
void OnRelease(bool appShutDown); // fires when the plugin is released from the application
+
+ DECLARE_EVENT_TABLE()
};
#endif // ASTYLEPLUGIN_H