/***************************************************************
* Name: todolist.cpp
* Purpose: Code::Blocks plugin
* Author: Yiannis Mandravellos <mandrav@codeblocks.org>
* Created: 11/21/03 14:01:50
* Copyright: (c) Yiannis Mandravellos
* License: GPL
**************************************************************/
#include <sdk.h>
#if defined(__GNUG__) && !defined(__APPLE__)
#pragma implementation "todolist.h"
#endif
#include <wx/intl.h>
#include <wx/textdlg.h>
#include <wx/xrc/xmlres.h>
#include <wx/fs_zip.h>
#include <manager.h>
#include <configmanager.h>
#include <editormanager.h>
#include <messagemanager.h>
#include <projectmanager.h>
#include <cbeditor.h>
#include <cbproject.h>
#include <licenses.h>
#include "todolist.h"
#include "addtododlg.h"
#include "todosettingsdlg.h"
#include <wx/arrimpl.cpp>
WX_DEFINE_OBJARRAY(ToDoItems);
CB_IMPLEMENT_PLUGIN(ToDoList);
const int idAddTodo = wxNewId();
BEGIN_EVENT_TABLE(ToDoList, cbPlugin)
EVT_MENU(idAddTodo, ToDoList::OnAddItem)
EVT_EDITOR_OPEN(ToDoList::OnReparse)
EVT_EDITOR_SAVE(ToDoList::OnReparse)
EVT_PROJECT_CLOSE(ToDoList::OnReparse)
EVT_PROJECT_ACTIVATE(ToDoList::OnReparse)
EVT_PROJECT_FILE_ADDED(ToDoList::OnReparse)
EVT_PROJECT_FILE_REMOVED(ToDoList::OnReparse)
END_EVENT_TABLE()
ToDoList::ToDoList()
{
//ctor
wxFileSystem::AddHandler(new wxZipFSHandler);
wxXmlResource::Get()->InitAllHandlers();
wxString resPath = ConfigManager::Get()->Read(_T("data_path"), wxEmptyString);
wxXmlResource::Get()->Load(resPath + _T("/todo.zip#zip:*.xrc"));
m_PluginInfo.name = _T("ToDoList");
m_PluginInfo.title = _("To-Do List");
m_PluginInfo.version = _T("0.1");
m_PluginInfo.description = _("Code::Blocks To-Do List plugin");
m_PluginInfo.author = _T("Yiannis An. Mandravellos");
m_PluginInfo.authorEmail = _T("info@codeblocks.org");
m_PluginInfo.authorWebsite = _T("www.codeblocks.org");
m_PluginInfo.thanksTo = _T("");
m_PluginInfo.license = LICENSE_GPL;
m_PluginInfo.hasConfigure = true;
ConfigManager::AddConfiguration(m_PluginInfo.title, _T("/todo_list"));
}
ToDoList::~ToDoList()
{
//dtor
}
void ToDoList::OnAttach()
{
// create ToDo in bottom view
wxArrayString titles;
int widths[6] = {64, 320, 64, 48, 48, 640};
titles.Add(_("Type"));
titles.Add(_("Text"));
titles.Add(_("User"));
titles.Add(_("Prio."));
titles.Add(_("Line"));
titles.Add(_("File"));
MessageManager* msgMan = Manager::Get()->GetMessageManager();
m_pListLog = new ToDoListView(msgMan, m_PluginInfo.title, 6, widths, titles, m_Types);
m_ListPageIndex = msgMan->AddLog(m_pListLog);
m_AutoRefresh = ConfigManager::Get()->Read(_T("todo_list/auto_refresh"), true);
LoadTypes();
}
void ToDoList::OnRelease(bool appShutDown)
{
if (Manager::Get()->GetMessageManager())
Manager::Get()->GetMessageManager()->DeletePage(m_ListPageIndex);
}
void ToDoList::BuildMenu(wxMenuBar* menuBar)
{
// nothing to be added in menu
}
void ToDoList::BuildModuleMenu(const ModuleType type, wxMenu* menu, const wxString& arg)
{
if (!menu || !m_IsAttached)
return;
if (type == mtEditorManager)
{
menu->AppendSeparator();
menu->Append(idAddTodo, _("Add To-Do item..."), _("Add new To-Do item..."));
}
}
bool ToDoList::BuildToolBar(wxToolBar* toolBar)
{
//NotImplemented("ToDoList::BuildToolBar()");
return false;
}
int ToDoList::Configure()
{
ToDoSettingsDlg dlg;
if (dlg.ShowModal() == wxID_OK)
m_AutoRefresh = ConfigManager::Get()->Read(_T("todo_list/auto_refresh"), true);
return 0;
}
void ToDoList::LoadTypes()
{
m_Types.Clear();
long cookie;
wxString entry;
wxConfigBase* conf = ConfigManager::Get();
wxString oldPath = conf->GetPath();
conf->SetPath(_T("/todo/types"));
bool cont = conf->GetFirstEntry(entry, cookie);
while (cont)
{
m_Types.Add(entry);
cont = conf->GetNextEntry(entry, cookie);
}
conf->SetPath(oldPath);
if(m_Types.GetCount()==0)
{
m_Types.Add(_T("TODO"));
m_Types.Add(_T("FIXME"));
m_Types.Add(_T("NOTE"));
}
SaveTypes();
}
void ToDoList::SaveTypes()
{
wxConfigBase* conf = ConfigManager::Get();
conf->DeleteGroup(_T("/todo/types"));
wxString oldPath = conf->GetPath();
conf->SetPath(_T("/todo/types"));
for (unsigned int i = 0; i < m_Types.GetCount(); ++i)
{
conf->Write(m_Types[i], wxEmptyString);
}
conf->SetPath(oldPath);
}
// events
void ToDoList::OnAddItem(wxCommandEvent& event)
{
cbEditor* ed = Manager::Get()->GetEditorManager()->GetBuiltinActiveEditor();
if (!ed)
return;
// display todo dialog
AddTodoDlg dlg(Manager::Get()->GetAppWindow(), m_Types);
if (dlg.ShowModal() != wxID_OK)
return;
SaveTypes();
cbStyledTextCtrl* control = ed->GetControl();
// calculate insertion point
int idx = 0;
int crlfLen = 0; // length of newline chars
int origPos = control->GetCurrentPos(); // keep current position in the document
int line = control->GetCurrentLine(); // current line
if (dlg.GetPosition() == tdpCurrent)
idx = control->GetCurrentPos(); // current position in the document
else
{
if (dlg.GetPosition() == tdpAbove)
idx = control->GetLineEndPosition(line - 1); // get previous line's end
else if (dlg.GetPosition() == tdpBelow)
idx = control->GetLineEndPosition(line); // get current line's end
// calculate insertion point by skipping next newline
switch (control->GetEOLMode())
{
case wxSCI_EOL_CR:
case wxSCI_EOL_LF: crlfLen = 1; break;
case wxSCI_EOL_CRLF: crlfLen = 2; break;
}
if (idx > 0)
idx += crlfLen;
}
// make sure insertion point is valid (bug #1300981)
if (idx > control->GetLength())
idx = control->GetLength();
// ok, construct todo line text like this:
// TODO (mandrav#0#): Implement code to do this and the other...
wxString buffer;
// start with the comment
if (dlg.GetCommentType() == tdctCpp && dlg.GetPosition() != tdpCurrent)
buffer << _T("// "); // if tdpCurrent we can't use this type of comment...
else
{
if (dlg.GetCommentType() == tdctWarning)
buffer << _T("#warning ");
else if (dlg.GetCommentType() == tdctError)
buffer << _T("#error ");
else
buffer << _T("/* ");
}
// continue with the type
buffer << dlg.GetType() << _T(" ");
// now do the () part
buffer << _T("(") << dlg.GetUser() << _T("#") << dlg.GetPriority() << _T("#): ");
wxString text = dlg.GetText();
if (dlg.GetCommentType() != tdctC)
{
// make sure that multi-line notes, don't break the to-do
if (text.Replace(_T("\r\n"), _T("\\\r\n")) == 0)
text.Replace(_T("\n"), _T("\\\n"));
// now see if there were already a backslash before newline
if (text.Replace(_T("\\\\\r\n"), _T("\\\r\n")) == 0)
text.Replace(_T("\\\\\n"), _T("\\\n"));
}
// add the actual text
buffer << text;
if (dlg.GetCommentType() == tdctWarning || dlg.GetCommentType() == tdctError)
buffer << _T("");
else if (dlg.GetCommentType() == tdctC || dlg.GetPosition() == tdpCurrent)
buffer << _T(" */");
// add newline char(s), only if dlg.GetPosition() != tdpCurrent
if (dlg.GetPosition() != tdpCurrent)
{
switch (control->GetEOLMode())
{
// NOTE: maybe this switch, should make it in the SDK (maybe as cbStyledTextCtrl::GetEOLString())???
case wxSCI_EOL_CR: buffer << _T("\n"); break;
case wxSCI_EOL_CRLF: buffer << _T("\r\n"); break;
case wxSCI_EOL_LF: buffer << _T("\r"); break;
}
}
// ok, insert the todo line text
control->InsertText(idx, buffer);
if (dlg.GetPosition() == tdpAbove)
origPos += buffer.Length() + crlfLen;
control->GotoPos(origPos);
control->EnsureCaretVisible();
m_pListLog->Parse();
}
void ToDoList::OnReparse(CodeBlocksEvent& event)
{
if (m_AutoRefresh)
m_pListLog->Parse();
event.Skip();
}
syntax highlighted by Code2HTML, v. 0.9.1