Developer forums (C::B DEVELOPMENT STRICTLY!) > Plugins development

Scripted Plugin: FindBrokenFiles

(1/6) > >>

MortenMacFly:
Some time back I had developed a scripted plugin just for my personal experience. Today I found this within the many folders on my HDD by accident and I think it's worth sharing for people that are interested in such kind of plugins. Take it as an excercise...

What does it do? It searches within a project for broken files - thus, files that are part of the project but do no longer exist on the drive. It shows a list of these files and offers to remove them from the project. Now what is so special about that? Nothing, except this is a scripted plugin. Never heard of such? C::B offers so much more that you can ever imagine... ;-) Scripted plugins use the scripting engine inside C::B and the exposed parts of the C::B SDK to be nearly as powerful as "binary" plugins but do require *no* compilation.

So what do you have to do? Read the documentation about scripting in the WiKi. Install the plugin as following:
- create a file named "find_broken_files.script"
- copy the content of the file (as shown below in the attachment) within this file
- put the file (which already is the ready-to-use plugin!) into: [C::B]\share\CodeBlocks\scripts
- open the startup.script file in the very same folder
- add the line: Include(_T("find_broken_files.script")); just where the comments state to do so
- restart C::B, open a project and right-click on it in the project tree
- notice the new menu entry "Find broken files in project"
- inspect the scripted plugin again to understand it's "magic" - it's very simple!

With regards, Morten.

Attachment (file "find_broken_files.script"):

--- Code: ---//
// Script that searches inside a project for invalid (broken) files
// Created by MortenMacFly for Code::Blocks IDE (www.codeblocks.org)
//

class FindBrokenFilesPlugin extends cbScriptPlugin
{
  // mandatory to setup the plugin's info
  constructor()
  {
    info.name = _T("Find Broken Files plugin");
    info.title = _T("Find Broken Files");
    info.version = _T("0.9");
    info.license = _T("GPL");
  }

  // create menubar items
  function GetMenu()
  {
    local entries = ::wxArrayString();
    entries.Add(_T("Project/-Find broken files in project"), 1);
    return entries;
  }

  // create context menu entries
  function GetModuleMenu(who, data)
  {
    local entries = ::wxArrayString();

    if (who == ::mtProjectManager)
      entries.Add(_T("Find broken files in project"), 1);

    return entries;
  }

  // support ExecutePlugin(pluginNameString)
  function Execute()
  {
    // try to open the project manager
    local pm = GetProjectManager();

    // display a message if project manager could not be located
    if (IsNull(pm))
    {
      ShowError(_T("Could not query the project manager. Cannot continue."));
      return 0;
    }

    // try to query the currently active project (which we will analyse)
    local p = pm.GetActiveProject();

    // display a message if there is no active project
    if (IsNull(p))
    {
      ShowError(_T("Currently no project is loaded/activated. Cannot continue."));
      return 0;
    }

    // verify that there are files in the project to analyse
    local files_count = p.GetFilesCount();

    // display a message if the project contains no files
    if (files_count<1)
    {
      ShowError(_T("The active project contains no files. Cannot continue."));
      return 0;
    }
    //else
    //  ShowInfo(_T("The active project has ") + files_count + _T(" files."));

    // search for broken files
    local broken_files = 0;
    local broken_files_str = _T("");
    for (local i=0; i<files_count; i++)
    {
      local pf = p.GetFile(i);
      if (IsNull(pf))
      {
        ShowError(_T("Could not access project file(s). Cannot continue."));
        return 0;
      }

      local full_path = pf.file.GetFullPath(::wxPATH_NATIVE);
      if (!IO.FileExists(full_path))
      {
        broken_files++;
        broken_files_str = broken_files_str + full_path + _T("\n");
      }
    }

    // operate broken files (if any)
    if (broken_files>0)
    {
      ShowInfo(_T("The project has ") + broken_files + _T(" broken files:\n") + broken_files_str);

      local msg   = _T("Do you want to remove them from the project now?");
      local remove_files = Message(msg, _T("Broken Files Plugin"), ::wxICON_QUESTION | ::wxYES_NO);
      if (remove_files==::wxID_YES)
      {
        // search for broken files again and remove them from the project
        local removed_files = 0;
        for (local i=0; i<files_count; i++)
        {
          local pf = p.GetFile(i-removed_files);
          if (IsNull(pf))
          {
            ShowError(_T("Could not access project file(s). Cannot continue."));
            return 0;
          }

          local full_path = pf.file.GetFullPath(::wxPATH_NATIVE);
          if (!IO.FileExists(full_path))
          {
            if (p.RemoveFile(i-removed_files))
            {
              removed_files++;
              files_count--;
            }
          }
        }
        pm.RebuildTree();
        ShowInfo(_T("Operation successfully completed.\n") + removed_files + _T(" files have been removed."));
      }
      else
        ShowInfo(_T("Operation cancelled."));
    }
    else
      ShowInfo(_T("In this project no broken files were found."));

    return 0;
  }

  // callback for menubar items clicking
  function OnMenuClicked(index)
  {
    local result = Execute();
  }

  // callback for context menu items clicking
  function OnModuleMenuClicked(index)
  {
    local result = Execute();
  }
}

// this call actually registers the script plugin with Code::Blocks
RegisterPlugin(FindBrokenFilesPlugin());

--- End code ---

Edit1: Fixed a little bug in the script on behalf of killerbot...
Edit2: Fixed another bug that wouldn't allow to remove the duplicate files

killerbot:
great :-)
Thumbs up !!!

MortenMacFly:

--- Quote from: killerbot on June 13, 2007, 11:21:51 pm ---great :-)

--- End quote ---
Hehe... this actually came into my mind when I saw your changes with r4093. This *could* have been done similarly by a script(ed plugin), too.  (Although it surely makes more sense in the SDK). ;-)

LETARTARE:
here is an adaptation for r7639


--- Code: ---local full_path = pf.file.GetFullPath(::wxPATH_NATIVE);
          if (!IO.FileExists(full_path))
          {
//-->  LETARTARE for r7639
          //  if (p.RemoveFile(i-removed_files))
       if (p.RemoveFile(pf))
//<-- LETARTARE
            {
              removed_files++;
              files_count--;
            }
          }

--- End code ---

oBFusCATed:
Morten: Have you thought of putting this in svn?
Also have you tried to put a menu entry in Plugins instead of the context menu of the project, something like "Plugins->Find broken files"?

Navigation

[0] Message Index

[#] Next page

Go to full version