Logo Search packages:      
Sourcecode: codeblocks version File versions  Download package

ThreadSearchLoggerTree.cpp

/***************************************************************
 * Name:      ThreadSearchLoggerTree
 * Purpose:   ThreadSearchLoggerTree implements the
 *            ThreadSearchLoggerBase interface with a wxTreeCtrl.
 * Author:    Jerome ANTOINE
 * Created:   2007-07-28
 * Copyright: Jerome ANTOINE
 * License:   GPL
 **************************************************************/

#include <sdk.h> // Code::Blocks SDK
#ifndef CB_PRECOMP
      // Required extra includes
#endif

#include "ThreadSearch.h"   //(pecan 2008/3/06)
#include "ThreadSearchLoggerTree.h"
#include "ThreadSearchEvent.h"
#include "ThreadSearchView.h"

00021 ThreadSearchLoggerTree::ThreadSearchLoggerTree(ThreadSearchView& threadSearchView,
                                                                     ThreadSearch& threadSearchPlugin,
                                                                     InsertIndexManager::eFileSorting fileSorting,
                                                                     wxPanel* pParent,
                                                                     long id)
                                 : ThreadSearchLoggerBase(threadSearchView, threadSearchPlugin, fileSorting)
                                 , m_pTreeLog(NULL)
                                 , m_FirstItemProcessed(false)
{
    m_pTreeLog = new wxTreeCtrl(pParent, id, wxDefaultPosition, wxSize(1,1), wxTR_HAS_BUTTONS|wxTR_LINES_AT_ROOT|wxTR_FULL_ROW_HIGHLIGHT|wxTR_HIDE_ROOT|wxTR_DEFAULT_STYLE|wxSUNKEN_BORDER);
    m_pTreeLog->SetMinSize(wxSize(100, 100));
    m_pTreeLog->AddRoot(wxEmptyString);

      // Events are managed dynamically to be able to stop/start management when required.
      ConnectEvents(pParent);
}


00039 ThreadSearchLoggerTree::~ThreadSearchLoggerTree()
{
      wxWindow* pParent = m_pTreeLog->GetParent();
      if ( pParent != NULL )
      {
            // Events are managed dynamically to be able to stop/start management when required.
            DisconnectEvents(pParent);
      }
      m_pTreeLog->Destroy();
      m_pTreeLog = NULL;
}


00052 wxWindow* ThreadSearchLoggerTree::GetWindow()
{
      return m_pTreeLog;
}
// ----------------------------------------------------------------------------
00057 void ThreadSearchLoggerTree::SetFocus()
// ----------------------------------------------------------------------------
{
      m_pTreeLog->SetFocus();
    SyncLoggerToPreview();
}
// ----------------------------------------------------------------------------
00064 void ThreadSearchLoggerTree::ConnectEvents(wxEvtHandler* pEvtHandler)
// ----------------------------------------------------------------------------
{
      // Dynamic event connections.
      int id = m_pTreeLog->GetId();
      pEvtHandler->Connect(id, wxEVT_COMMAND_TREE_SEL_CHANGED,
                  (wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)
                  &ThreadSearchLoggerTree::OnLoggerTreeClick, NULL, this);

      pEvtHandler->Connect(id, wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
                  (wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)
                  &ThreadSearchLoggerTree::OnLoggerTreeDoubleClick, NULL, this);

      m_pTreeLog->Connect(id, wxEVT_MOUSEWHEEL, //(pecan 2008/7/31)
                  (wxObjectEventFunction)(wxEventFunction)(wxMouseEventFunction)
                  &ThreadSearchLoggerTree::OnMouseWheelEvent, NULL, static_cast<wxEvtHandler*>(this));

}
// ----------------------------------------------------------------------------
00083 void ThreadSearchLoggerTree::DisconnectEvents(wxEvtHandler* pEvtHandler)
// ----------------------------------------------------------------------------
{
      // Dynamic event disconnections.
      int id = m_pTreeLog->GetId();
      pEvtHandler->Disconnect(id, wxEVT_COMMAND_TREE_SEL_CHANGED,
                  (wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)
                  &ThreadSearchLoggerTree::OnLoggerTreeClick, NULL, this);

      pEvtHandler->Disconnect(id, wxEVT_COMMAND_TREE_ITEM_ACTIVATED,
                  (wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)
                  &ThreadSearchLoggerTree::OnLoggerTreeDoubleClick, NULL, this);

      m_pTreeLog->Disconnect(id, wxEVT_MOUSEWHEEL, //(pecan 2008/7/31)
                  (wxObjectEventFunction)(wxEventFunction)(wxMouseEventFunction)
                  &ThreadSearchLoggerTree::OnMouseWheelEvent, NULL, static_cast<wxEvtHandler*>(this));
}
// ----------------------------------------------------------------------------
void ThreadSearchLoggerTree::OnMouseWheelEvent(wxMouseEvent& event)
// ----------------------------------------------------------------------------
{
    // Ctrl-MouseWheel rotation changes treeCtrl font

    //-wxWindow* pParent = m_pListLog->GetParent();
    wxWindow* pParent = (wxWindow*)event.GetEventObject();
    //-wxWindow* pParent = m_pListLog;
      if ( not pParent ) return;

    bool mouseCtrlKeyDown = event.ControlDown();
    #ifdef LOGGING
     //LOGIT(wxT("treeCtrl:OnMouseWheel[%s]"), m_MouseCtrlKeyDown?wxT("Down"):wxT("UP") );
    #endif
    if (not mouseCtrlKeyDown) {event.Skip(); return;}

    int nRotation = event.GetWheelRotation();
    wxFont ctrlFont = pParent->GetFont();

    if ( nRotation > 0)
        ctrlFont.SetPointSize( ctrlFont.GetPointSize()-1);
    else
        ctrlFont.SetPointSize( ctrlFont.GetPointSize()+1);

    pParent->SetFont(ctrlFont);
    pParent->Refresh();
    pParent->Update();
    return;
}

00131 void ThreadSearchLoggerTree::OnLoggerTreeClick(wxTreeEvent& event)
{
      // Manages list log left double click
    // Gets file path and line from list control
    wxString filepath(wxEmptyString);
    long line;
    if ( GetFileLineFromTreeEvent(event, filepath, line) == false )
    {
            cbMessageBox(wxT("Failed to retrieve file path and line number"), wxT("Error"), wxICON_ERROR);
      return;
    }
    m_ThreadSearchView.OnLoggerClick(filepath, line);
    event.Skip();
}


00147 void ThreadSearchLoggerTree::OnLoggerTreeDoubleClick(wxTreeEvent& event)
{
      // Manages list log left double click
    // Gets file path and line from list control
    wxString filepath(wxEmptyString);
    long line;
    if ( GetFileLineFromTreeEvent(event, filepath, line) == false )
    {
            cbMessageBox(wxT("Failed to retrieve file path and line number"), wxT("Error"), wxICON_ERROR);
      return;
    }
    m_ThreadSearchView.OnLoggerDoubleClick(filepath, line);

    event.Skip();
}


00164 bool ThreadSearchLoggerTree::GetFileLineFromTreeEvent(wxTreeEvent& event, wxString& filepath, long &line)
{
      wxTreeItemId lineItemId;
      wxTreeItemId fileItemId;
      wxTreeItemId rootItemId = m_pTreeLog->GetRootItem();
      wxTreeItemId eventItemId = event.GetItem();
      bool success(false);

      filepath = wxEmptyString;
      line = 0;

      do
      {
            // We test if we are on a file item or a line item.
            // As root is hidden, we have only file and line items on tree.
            if ( m_pTreeLog->GetItemParent(eventItemId) == rootItemId )
            {
                  fileItemId = eventItemId;
                  wxTreeItemIdValue cookie;
                  lineItemId = m_pTreeLog->GetFirstChild(eventItemId, cookie);
                  if ( lineItemId.IsOk() == false )
                        break;
            }
            else
            {
                  lineItemId = eventItemId;
                  fileItemId = m_pTreeLog->GetItemParent(lineItemId);
            }

            // We extract line and file path values
            // Look at ThreadSearchLoggerTree::OnThreadSearchEvent to have format

            // Line:
            const wxString& lineText = m_pTreeLog->GetItemText(lineItemId);
            int columnPos = lineText.Find(':');
            if ( columnPos == wxNOT_FOUND )
                  break;

            if ( lineText.Left(columnPos).ToLong(&line) == false )
                  break;

            // File:
            const wxString& fileText = m_pTreeLog->GetItemText(fileItemId);
            int fileLength = fileText.Find(wxT(" ("));
            if ( fileLength == wxNOT_FOUND )
                  break;

            int dirBegin   = fileLength + 2; // 2 for " ("
            int dirLength  = fileText.Length() - dirBegin - 1;
            if ( dirLength <= 0 )
                  break;

            wxFileName filename(fileText.Mid(dirBegin, dirLength), fileText.Left(fileLength));
            filepath = filename.GetFullPath();

            success = true;
      } while ( false );

      return success;
}


00226 void ThreadSearchLoggerTree::OnThreadSearchEvent(const ThreadSearchEvent& event)
{
      // A search event has been sent by the worker thread.
      // Tree log upddate
      const wxArrayString& words  = event.GetLineTextArray();
      const wxFileName&    filename(event.GetString());
      bool                 setFocus(false);
      wxTreeItemId         rootItemId(m_pTreeLog->GetRootItem());
      wxTreeItemId         fileItemId;
      long                 index    = m_IndexManager.GetInsertionIndex(filename.GetFullPath());
      long                 nb_items = m_pTreeLog->GetChildrenCount(rootItemId, false);

      wxASSERT(index != wxNOT_FOUND);
      wxASSERT((words.GetCount() % 2) == 0);

      // Use of Freeze Thaw to enhance speed and limit blink effect
      m_pTreeLog->Freeze();
      wxTreeItemId lineItemId;

      if ( index == nb_items )
      {
            fileItemId = m_pTreeLog->AppendItem(rootItemId,
                                                                               wxString::Format(wxT("%s (%s)"),
                                                                                                        filename.GetFullName().c_str(),
                                                                                                        filename.GetPath().c_str()));
      }
      else
      {
            fileItemId = m_pTreeLog->InsertItem(rootItemId, index,
                                                                  wxString::Format(wxT("%s (%s)"),
                                                                                           filename.GetFullName().c_str(),
                                                                                           filename.GetPath().c_str()));
      }

      for (size_t i = 0; i < words.GetCount(); i += 2)
      {
            lineItemId = m_pTreeLog->AppendItem(fileItemId, wxString::Format(wxT("%s: %s"),
                                                                                                             words[i].c_str(),     // Line index starting from 1
                                                                                                             words[i+1].c_str())); // File line matching search expression

        //(pecan 2008/7/31) Dont do the following, else Ctrl-MouseWheel cannot change fonts
            //-m_pTreeLog->SetItemFont(fileItemId, m_ThreadSearchPlugin.m_Conf_font);          //(pecan 2008/3/06)
            //-m_pTreeLog->SetItemFont(lineItemId, m_ThreadSearchPlugin.m_Conf_font);          //(pecan 2008/3/06)

            // We update preview log for first list item
            if ( (m_FirstItemProcessed == false)                        &&
                   (m_pTreeLog->GetChildrenCount(fileItemId, false) == 1) &&
                   (m_pTreeLog->GetChildrenCount(rootItemId, false) == 1) )
            {
                  // Expand first file item
                  m_pTreeLog->Expand(fileItemId);

                  // Select first item (generates selection event to update ThreadSearchView code preview)
                  m_pTreeLog->SelectItem(lineItemId);

                  // to avoid lots of preview that freezes app
                  m_FirstItemProcessed = true;

                  // It is useful to give focus to tree to navigate in results
                  // just after running a search
                  setFocus = true;
            }
      }
      m_pTreeLog->Thaw();

      if ( setFocus == true )
      {
            // On Linux, executing SetFocus just after SelectItem
            // does not work. Probbly because of Thaw...
            m_pTreeLog->SetFocus();
      }
}


00300 void ThreadSearchLoggerTree::Clear()
{
      // As wxTreeCtrl::DeleteChildren sends lots of selected events
      // and because we don't want any wxTreeCtrl event to be processed
      // during delete, we disable events management during tree cleaning
      // (DisconnectEvents then ConnectEvents).
      wxWindow* pParent = m_pTreeLog->GetParent();
      if ( pParent == NULL ) return;

      DisconnectEvents(pParent);

    m_pTreeLog->DeleteChildren(m_pTreeLog->GetRootItem());
    m_FirstItemProcessed = false;

    m_IndexManager.Reset();

    ConnectEvents(pParent);
}
// ----------------------------------------------------------------------------
void ThreadSearchLoggerTree::SyncLoggerToPreview()
// ----------------------------------------------------------------------------
{   //(pecan 2008/4/27)
    // We need to position the Logger window to the selection
    // in Preview cbEditor control
    // This routine must be called *after* the thread events have been
    // exhausted (in the timer event) and the window has already been redrawn.

    wxTreeCtrl* pTreeCtrl = (wxTreeCtrl*)GetWindow();
    wxTreeItemId setFocusItem = pTreeCtrl->GetSelection();

    if (not setFocusItem.IsOk())    //no selecction
        return;
    pTreeCtrl->EnsureVisible(setFocusItem);
    pTreeCtrl->SetFocus();
}

Generated by  Doxygen 1.6.0   Back to index