<commit_before>////////////////////////////////////////////////////////////////////////////////
// Name:      frame.cpp
// Purpose:   Implementation of wxExFrame class
// Author:    Anton van Wezenbeek
// Created:   2010-03-26
// RCS-ID:    $Id$
// Copyright: (c) 2010 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/persist/toplevel.h>
#include <wx/extension/frame.h>
#include <wx/extension/frd.h>
#include <wx/extension/grid.h>
#include <wx/extension/lexers.h>
#include <wx/extension/listview.h>
#include <wx/extension/printing.h>
#include <wx/extension/stc.h>
#include <wx/extension/tool.h>
#include <wx/extension/util.h>

#if wxUSE_GUI

#if wxUSE_STATUSBAR
wxExStatusBar* wxExFrame::m_StatusBar = NULL;
#endif

#if wxUSE_DRAG_AND_DROP
class FileDropTarget : public wxFileDropTarget
{
public:
  FileDropTarget(wxExFrame* frame)
    : m_Frame(frame){;};
private:
  virtual bool OnDropFiles(
    wxCoord x,
    wxCoord y,
    const wxArrayString& filenames) {
    wxExOpenFiles(m_Frame, filenames);
    return true;}

  wxExFrame* m_Frame;
};
#endif

BEGIN_EVENT_TABLE(wxExFrame, wxFrame)
  EVT_FIND(wxID_ANY, wxExFrame::OnFindDialog)
  EVT_FIND_CLOSE(wxID_ANY, wxExFrame::OnFindDialog)
  EVT_FIND_NEXT(wxID_ANY, wxExFrame::OnFindDialog)
  EVT_FIND_REPLACE(wxID_ANY, wxExFrame::OnFindDialog)
  EVT_FIND_REPLACE_ALL(wxID_ANY, wxExFrame::OnFindDialog)
  EVT_MENU(wxID_FIND, wxExFrame::OnCommand)
  EVT_MENU(wxID_REPLACE, wxExFrame::OnCommand)
  EVT_MENU(ID_EDIT_FIND_NEXT, wxExFrame::OnCommand)
  EVT_MENU(ID_EDIT_FIND_PREVIOUS, wxExFrame::OnCommand)
  EVT_MENU(ID_FOCUS_GRID, wxExFrame::OnCommand)
  EVT_MENU(ID_FOCUS_LISTVIEW, wxExFrame::OnCommand)
  EVT_MENU(ID_FOCUS_STC, wxExFrame::OnCommand)
  EVT_MENU(ID_VIEW_MENUBAR, wxExFrame::OnCommand)
  EVT_MENU(ID_VIEW_STATUSBAR, wxExFrame::OnCommand)
  EVT_UPDATE_UI(ID_VIEW_MENUBAR, wxExFrame::OnUpdateUI)
  EVT_UPDATE_UI(ID_VIEW_STATUSBAR, wxExFrame::OnUpdateUI)
#if wxUSE_STATUSBAR
  EVT_UPDATE_UI(ID_EDIT_STATUS_BAR, wxExFrame::OnUpdateUI)
#endif
END_EVENT_TABLE()

wxExFrame::wxExFrame(wxWindow* parent,
  wxWindowID id,
  const wxString& title,
  long style)
  : wxFrame(parent, id, title, wxDefaultPosition, wxDefaultSize, style)
  , m_FindReplaceDialog(NULL)
  , m_FocusGrid(NULL)
  , m_FocusListView(NULL)
  , m_FocusSTC(NULL)
{
  Initialize();

  SetName("wxExFrame");
  wxPersistentRegisterAndRestore(this);

#if wxUSE_HTML & wxUSE_PRINTING_ARCHITECTURE
  wxExPrinting::Get()->GetHtmlPrinter()->SetParentWindow(this);
#endif
}

wxExFrame::~wxExFrame()
{
  if (m_FindReplaceDialog != NULL)
  {
    m_FindReplaceDialog->Destroy();
  }

  wxConfigBase::Get()->Write("ShowMenuBar",
    GetMenuBar() != NULL && GetMenuBar()->IsShown());

#if wxUSE_STATUSBAR
  delete m_StatusBar;
#endif
}

void wxExFrame::FindIn(wxFindDialogEvent& event, wxExGrid* grid)
{
  if (
    event.GetEventType() == wxEVT_COMMAND_FIND ||
    event.GetEventType() == wxEVT_COMMAND_FIND_NEXT)
  {
    grid->FindNext(
      wxExFindReplaceData::Get()->GetFindString(),
      wxExFindReplaceData::Get()->SearchDown());
  }
  else
  {
    wxFAIL;
  }
}

void wxExFrame::FindIn(wxFindDialogEvent& event, wxExListView* lv)
{
  if (
    event.GetEventType() == wxEVT_COMMAND_FIND ||
    event.GetEventType() == wxEVT_COMMAND_FIND_NEXT)
  {
    lv->FindNext(
      wxExFindReplaceData::Get()->GetFindString(),
      wxExFindReplaceData::Get()->SearchDown());
  }
  else
  {
    wxFAIL;
  }
}

void wxExFrame::FindIn(wxFindDialogEvent& event, wxExSTC* stc)
{
  auto* frd = wxExFindReplaceData::Get();

  // Match word and regular expression do not work together.
  if (frd->MatchWord())
  {
    frd->SetUseRegularExpression(false);
  }

  if (
    event.GetEventType() == wxEVT_COMMAND_FIND ||
    event.GetEventType() == wxEVT_COMMAND_FIND_NEXT)
  {
    stc->FindNext(frd->SearchDown());
  }
  else if (event.GetEventType() == wxEVT_COMMAND_FIND_REPLACE)
  {
    stc->ReplaceNext(frd->SearchDown());
  }
  else if (event.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL)
  {
    stc->ReplaceAll(
      frd->GetFindString(),
      frd->GetReplaceString());
  }
  else
  {
    wxFAIL;
  }
}

void wxExFrame::GetFindString()
{
  if (m_FocusSTC != NULL)
  {
    m_FocusSTC->GetFindString();
  }
  else if (m_FocusGrid != NULL)
  {
    m_FocusGrid->GetFindString();
  }
  else
  {
    auto* stc = GetSTC();

    if (stc != NULL && stc->IsShown())
    {
      stc->GetFindString();
    }
    else
    {
      wxExGrid* grid = GetGrid();

      if (grid != NULL && grid->IsShown() )
      {
        grid->GetFindString();
      }
    }
  }
}

void wxExFrame::Initialize()
{
#if wxUSE_DRAG_AND_DROP
  SetDropTarget(new FileDropTarget(this));
#endif

  wxAcceleratorEntry entries[5];
  entries[0].Set(wxACCEL_NORMAL, WXK_F3, ID_EDIT_FIND_NEXT);
  entries[1].Set(wxACCEL_NORMAL, WXK_F4, ID_EDIT_FIND_PREVIOUS);
  entries[2].Set(wxACCEL_NORMAL, WXK_F5, wxID_FIND);
  entries[3].Set(wxACCEL_NORMAL, WXK_F6, wxID_REPLACE);
  entries[4].Set(wxACCEL_CTRL, (int)'B', ID_VIEW_MENUBAR);

  wxAcceleratorTable accel(WXSIZEOF(entries), entries);
  SetAcceleratorTable(accel);
}

void wxExFrame::OnCommand(wxCommandEvent& command)
{
  switch (command.GetId())
  {
  case wxID_FIND:
    GetFindString();

    if (m_FindReplaceDialog != NULL)
    {
      if (m_FindReplaceDialog->GetWindowStyle() & wxFR_REPLACEDIALOG)
      {
        m_FindReplaceDialog->Destroy();
        m_FindReplaceDialog = NULL;
      }
    }

    if (m_FindReplaceDialog == NULL)
    {
      m_FindReplaceDialog = new wxFindReplaceDialog(
        this, wxExFindReplaceData::Get(), _("Find"));
    }

    m_FindReplaceDialog->Show();
    break;

  case wxID_REPLACE:
    GetFindString();

    if (m_FindReplaceDialog != NULL)
    {
      if (!(m_FindReplaceDialog->GetWindowStyle() & wxFR_REPLACEDIALOG))
      {
        m_FindReplaceDialog->Destroy();
        m_FindReplaceDialog = NULL;
      }
    }

    if (m_FindReplaceDialog == NULL)
    {
      m_FindReplaceDialog = new wxFindReplaceDialog(
        this,
        wxExFindReplaceData::Get(),
        _("Replace"),
        wxFR_REPLACEDIALOG);
    }

    m_FindReplaceDialog->Show();
    break;

  case ID_EDIT_FIND_NEXT:
  case ID_EDIT_FIND_PREVIOUS:
    if (m_FocusSTC != NULL)
    {
      m_FocusSTC->GetFindString();
      m_FocusSTC->FindNext(command.GetId() == ID_EDIT_FIND_NEXT);
    }
    else if (m_FocusListView != NULL)
    {
      m_FocusListView->FindNext(
        wxExFindReplaceData::Get()->GetFindString(),
        command.GetId() == ID_EDIT_FIND_NEXT);
    }
    else if (m_FocusGrid != NULL)
    {
      m_FocusGrid->GetFindString();
      m_FocusGrid->FindNext(
        wxExFindReplaceData::Get()->GetFindString(),
        command.GetId() == ID_EDIT_FIND_NEXT);
    }
    break;

  case ID_FOCUS_GRID:
    m_FocusGrid = (wxExGrid*)command.GetEventObject();
    break;

  case ID_FOCUS_LISTVIEW:
    m_FocusListView = (wxExListView*)command.GetEventObject();;
    break;

  case ID_FOCUS_STC:
    m_FocusSTC = (wxExSTC*)command.GetEventObject();;
    break;

  case ID_VIEW_MENUBAR:
    {
    static wxMenuBar* oldbar = NULL;

    if (GetMenuBar() != NULL)
    {
      oldbar = GetMenuBar();
      SetMenuBar(NULL);
    }
    else
    {
      SetMenuBar(oldbar);
    }

    }
    break;

  case ID_VIEW_STATUSBAR:
    if (GetStatusBar() != NULL)
    {
      GetStatusBar()->Show(!GetStatusBar()->IsShown());
      SendSizeEvent();
    }
    break;

  default: wxFAIL; break;
  }
}

#if wxUSE_STATUSBAR
wxStatusBar* wxExFrame::OnCreateStatusBar(
  int number,
  long style,
  wxWindowID id,
  const wxString& name)
{
  m_StatusBar = new wxExStatusBar(this, id, style, name);
  m_StatusBar->SetFieldsCount(number);
  return m_StatusBar;
}
#endif

void wxExFrame::OnFindDialog(wxFindDialogEvent& event)
{
  wxASSERT(m_FindReplaceDialog != NULL);

  if (event.GetEventType() == wxEVT_COMMAND_FIND_CLOSE)
  {
    // Hiding instead of destroying, does not
    // show the dialog next time.
    m_FindReplaceDialog->Destroy();
    m_FindReplaceDialog = NULL;
    return;
  }

  if (m_FocusSTC != NULL)
  {
    FindIn(event, m_FocusSTC);
  }
  else if (m_FocusListView != NULL)
  {
    FindIn(event, m_FocusListView);
  }
  else if (m_FocusGrid != NULL)
  {
    FindIn(event, m_FocusGrid);
  }
  else
  {
    auto* stc = GetSTC();
    auto* lv = GetListView();
    auto* grid = GetGrid();

    if (stc != NULL && stc->IsShown())
    {
      FindIn(event, stc);
    }
    else if (lv != NULL && lv->IsShown())
    {
      FindIn(event, lv);
    }
    else if (grid != NULL && grid->IsShown())
    {
      FindIn(event, grid);
    }
  }
}

void wxExFrame::OnUpdateUI(wxUpdateUIEvent& event)
{
  switch (event.GetId())
  {
    case ID_VIEW_MENUBAR:
      if (GetMenuBar() != NULL)
      {
        event.Check(GetMenuBar()->IsShown());
      }
      else
      {
        event.Check(false);
      }
    break;

    case ID_VIEW_STATUSBAR:
      if (GetStatusBar() != NULL)
      {
        event.Check(GetStatusBar()->IsShown());
      }
      else
      {
        event.Check(false);
      }
      break;

#if wxUSE_STATUSBAR
    case ID_EDIT_STATUS_BAR:
    {
    auto* stc = GetFocusedSTC();
    if (stc == NULL) return;
    stc->UpdateStatusBar("PaneLines");
    }
    break;
#endif

  default:
    wxFAIL;
    break;
  }
}

bool wxExFrame::OpenFile(
  const wxExFileName& filename,
  int line_number,
  const wxString& match,
  long flags)
{
  auto* stc = GetFocusedSTC();

  if (stc != NULL)
  {
    return stc->Open(filename, line_number, match, flags);
  }

  return false;
}

void wxExFrame::SetMenuBar(wxMenuBar* bar)
{
  if (bar != NULL)
  {
    m_MenuBar = bar;
  }

  if (!wxConfigBase::Get()->ReadBool("ShowMenuBar", true))
  {
    wxFrame::SetMenuBar(NULL);
  }
  else
  {
    wxASSERT(m_MenuBar != NULL);
    wxFrame::SetMenuBar(m_MenuBar);
  }
}

#if wxUSE_STATUSBAR
wxExStatusBar* wxExFrame::SetupStatusBar(
  const std::vector<wxExPane>& panes,
  long style,
  wxWindowID id,
  const wxString& name)
{
  if (wxFrame::CreateStatusBar(panes.size(), style, id, name) != NULL)
  {
    if (m_StatusBar->SetPanes(panes) != panes.size())
    {
      return NULL;
    }
  }

  return m_StatusBar;
}
#endif // wxUSE_STATUSBAR

#if wxUSE_STATUSBAR
void wxExFrame::StatusBarDoubleClicked(
  const wxString& pane)
{
  if (pane == "PaneLines")
  {
    auto* stc = GetSTC();
    if (stc != NULL) stc->GotoDialog();
  }
  else if (pane == "PaneLexer")
  {
    auto* stc = GetSTC();

    if (stc != NULL && wxExLexers::Get()->Count() > 0)
    {
      wxString lexer = stc->GetLexer().GetScintillaLexer();

      if (wxExLexers::Get()->ShowDialog(this, lexer))
      {
        stc->SetLexer(lexer);
      }
    }
  }
  else if (pane == "PaneFileType")
  {
    auto* stc = GetSTC();
    if (stc != NULL) stc->FileTypeMenu();
  }
  else if (pane == "PaneItems")
  {
    wxExListView* list = GetListView();
    if (list != NULL) list->GotoDialog();
  }
  else
  {
    // Clicking on another field, do nothing.
  }
}

// This is a static method, so you cannot call wxFrame::SetStatusText.
void wxExFrame::StatusText(const wxString& text, const wxString& pane)
{
  if (m_StatusBar != NULL)
  {
    m_StatusBar->SetStatusText(text, pane);
  }
}

void wxExFrame::StatusText(const wxExFileName& filename, long flags)
{
  // Clear status bar for empty or not existing or not initialized file names.
  wxString text;

  if (filename.IsOk())
  {
    const wxString path = (flags & STAT_FULLPATH
      ? filename.GetFullPath(): filename.GetFullName());

    text += path;

    if (filename.GetStat().IsOk())
    {
      const wxString what = (flags & STAT_SYNC
        ? _("Synchronized"): _("Modified"));
      const wxString time = (flags & STAT_SYNC
        ? wxDateTime::Now().Format(): filename.GetStat().GetModificationTime());
      text += " " + what + " " + time;
    }
  }

  StatusText(text);
}

#endif // wxUSE_STATUSBAR
#endif // wxUSE_GUI
<commit_msg>menubar code simpler<commit_after>////////////////////////////////////////////////////////////////////////////////
// Name:      frame.cpp
// Purpose:   Implementation of wxExFrame class
// Author:    Anton van Wezenbeek
// Created:   2010-03-26
// RCS-ID:    $Id$
// Copyright: (c) 2010 Anton van Wezenbeek
////////////////////////////////////////////////////////////////////////////////

#include <wx/wxprec.h>
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif
#include <wx/persist/toplevel.h>
#include <wx/extension/frame.h>
#include <wx/extension/frd.h>
#include <wx/extension/grid.h>
#include <wx/extension/lexers.h>
#include <wx/extension/listview.h>
#include <wx/extension/printing.h>
#include <wx/extension/stc.h>
#include <wx/extension/tool.h>
#include <wx/extension/util.h>

#if wxUSE_GUI

#if wxUSE_STATUSBAR
wxExStatusBar* wxExFrame::m_StatusBar = NULL;
#endif

#if wxUSE_DRAG_AND_DROP
class FileDropTarget : public wxFileDropTarget
{
public:
  FileDropTarget(wxExFrame* frame)
    : m_Frame(frame){;};
private:
  virtual bool OnDropFiles(
    wxCoord x,
    wxCoord y,
    const wxArrayString& filenames) {
    wxExOpenFiles(m_Frame, filenames);
    return true;}

  wxExFrame* m_Frame;
};
#endif

BEGIN_EVENT_TABLE(wxExFrame, wxFrame)
  EVT_FIND(wxID_ANY, wxExFrame::OnFindDialog)
  EVT_FIND_CLOSE(wxID_ANY, wxExFrame::OnFindDialog)
  EVT_FIND_NEXT(wxID_ANY, wxExFrame::OnFindDialog)
  EVT_FIND_REPLACE(wxID_ANY, wxExFrame::OnFindDialog)
  EVT_FIND_REPLACE_ALL(wxID_ANY, wxExFrame::OnFindDialog)
  EVT_MENU(wxID_FIND, wxExFrame::OnCommand)
  EVT_MENU(wxID_REPLACE, wxExFrame::OnCommand)
  EVT_MENU(ID_EDIT_FIND_NEXT, wxExFrame::OnCommand)
  EVT_MENU(ID_EDIT_FIND_PREVIOUS, wxExFrame::OnCommand)
  EVT_MENU(ID_FOCUS_GRID, wxExFrame::OnCommand)
  EVT_MENU(ID_FOCUS_LISTVIEW, wxExFrame::OnCommand)
  EVT_MENU(ID_FOCUS_STC, wxExFrame::OnCommand)
  EVT_MENU(ID_VIEW_MENUBAR, wxExFrame::OnCommand)
  EVT_MENU(ID_VIEW_STATUSBAR, wxExFrame::OnCommand)
  EVT_UPDATE_UI(ID_VIEW_MENUBAR, wxExFrame::OnUpdateUI)
  EVT_UPDATE_UI(ID_VIEW_STATUSBAR, wxExFrame::OnUpdateUI)
#if wxUSE_STATUSBAR
  EVT_UPDATE_UI(ID_EDIT_STATUS_BAR, wxExFrame::OnUpdateUI)
#endif
END_EVENT_TABLE()

wxExFrame::wxExFrame(wxWindow* parent,
  wxWindowID id,
  const wxString& title,
  long style)
  : wxFrame(parent, id, title, wxDefaultPosition, wxDefaultSize, style)
  , m_FindReplaceDialog(NULL)
  , m_FocusGrid(NULL)
  , m_FocusListView(NULL)
  , m_FocusSTC(NULL)
{
  Initialize();

  SetName("wxExFrame");
  wxPersistentRegisterAndRestore(this);

#if wxUSE_HTML & wxUSE_PRINTING_ARCHITECTURE
  wxExPrinting::Get()->GetHtmlPrinter()->SetParentWindow(this);
#endif
}

wxExFrame::~wxExFrame()
{
  if (m_FindReplaceDialog != NULL)
  {
    m_FindReplaceDialog->Destroy();
  }

  wxConfigBase::Get()->Write("ShowMenuBar",
    GetMenuBar() != NULL && GetMenuBar()->IsShown());

#if wxUSE_STATUSBAR
  delete m_StatusBar;
#endif
}

void wxExFrame::FindIn(wxFindDialogEvent& event, wxExGrid* grid)
{
  if (
    event.GetEventType() == wxEVT_COMMAND_FIND ||
    event.GetEventType() == wxEVT_COMMAND_FIND_NEXT)
  {
    grid->FindNext(
      wxExFindReplaceData::Get()->GetFindString(),
      wxExFindReplaceData::Get()->SearchDown());
  }
  else
  {
    wxFAIL;
  }
}

void wxExFrame::FindIn(wxFindDialogEvent& event, wxExListView* lv)
{
  if (
    event.GetEventType() == wxEVT_COMMAND_FIND ||
    event.GetEventType() == wxEVT_COMMAND_FIND_NEXT)
  {
    lv->FindNext(
      wxExFindReplaceData::Get()->GetFindString(),
      wxExFindReplaceData::Get()->SearchDown());
  }
  else
  {
    wxFAIL;
  }
}

void wxExFrame::FindIn(wxFindDialogEvent& event, wxExSTC* stc)
{
  auto* frd = wxExFindReplaceData::Get();

  // Match word and regular expression do not work together.
  if (frd->MatchWord())
  {
    frd->SetUseRegularExpression(false);
  }

  if (
    event.GetEventType() == wxEVT_COMMAND_FIND ||
    event.GetEventType() == wxEVT_COMMAND_FIND_NEXT)
  {
    stc->FindNext(frd->SearchDown());
  }
  else if (event.GetEventType() == wxEVT_COMMAND_FIND_REPLACE)
  {
    stc->ReplaceNext(frd->SearchDown());
  }
  else if (event.GetEventType() == wxEVT_COMMAND_FIND_REPLACE_ALL)
  {
    stc->ReplaceAll(
      frd->GetFindString(),
      frd->GetReplaceString());
  }
  else
  {
    wxFAIL;
  }
}

void wxExFrame::GetFindString()
{
  if (m_FocusSTC != NULL)
  {
    m_FocusSTC->GetFindString();
  }
  else if (m_FocusGrid != NULL)
  {
    m_FocusGrid->GetFindString();
  }
  else
  {
    auto* stc = GetSTC();

    if (stc != NULL && stc->IsShown())
    {
      stc->GetFindString();
    }
    else
    {
      wxExGrid* grid = GetGrid();

      if (grid != NULL && grid->IsShown() )
      {
        grid->GetFindString();
      }
    }
  }
}

void wxExFrame::Initialize()
{
#if wxUSE_DRAG_AND_DROP
  SetDropTarget(new FileDropTarget(this));
#endif

  wxAcceleratorEntry entries[5];
  entries[0].Set(wxACCEL_NORMAL, WXK_F3, ID_EDIT_FIND_NEXT);
  entries[1].Set(wxACCEL_NORMAL, WXK_F4, ID_EDIT_FIND_PREVIOUS);
  entries[2].Set(wxACCEL_NORMAL, WXK_F5, wxID_FIND);
  entries[3].Set(wxACCEL_NORMAL, WXK_F6, wxID_REPLACE);
  entries[4].Set(wxACCEL_CTRL, (int)'B', ID_VIEW_MENUBAR);

  wxAcceleratorTable accel(WXSIZEOF(entries), entries);
  SetAcceleratorTable(accel);
}

void wxExFrame::OnCommand(wxCommandEvent& command)
{
  switch (command.GetId())
  {
  case wxID_FIND:
    GetFindString();

    if (m_FindReplaceDialog != NULL)
    {
      if (m_FindReplaceDialog->GetWindowStyle() & wxFR_REPLACEDIALOG)
      {
        m_FindReplaceDialog->Destroy();
        m_FindReplaceDialog = NULL;
      }
    }

    if (m_FindReplaceDialog == NULL)
    {
      m_FindReplaceDialog = new wxFindReplaceDialog(
        this, wxExFindReplaceData::Get(), _("Find"));
    }

    m_FindReplaceDialog->Show();
    break;

  case wxID_REPLACE:
    GetFindString();

    if (m_FindReplaceDialog != NULL)
    {
      if (!(m_FindReplaceDialog->GetWindowStyle() & wxFR_REPLACEDIALOG))
      {
        m_FindReplaceDialog->Destroy();
        m_FindReplaceDialog = NULL;
      }
    }

    if (m_FindReplaceDialog == NULL)
    {
      m_FindReplaceDialog = new wxFindReplaceDialog(
        this,
        wxExFindReplaceData::Get(),
        _("Replace"),
        wxFR_REPLACEDIALOG);
    }

    m_FindReplaceDialog->Show();
    break;

  case ID_EDIT_FIND_NEXT:
  case ID_EDIT_FIND_PREVIOUS:
    if (m_FocusSTC != NULL)
    {
      m_FocusSTC->GetFindString();
      m_FocusSTC->FindNext(command.GetId() == ID_EDIT_FIND_NEXT);
    }
    else if (m_FocusListView != NULL)
    {
      m_FocusListView->FindNext(
        wxExFindReplaceData::Get()->GetFindString(),
        command.GetId() == ID_EDIT_FIND_NEXT);
    }
    else if (m_FocusGrid != NULL)
    {
      m_FocusGrid->GetFindString();
      m_FocusGrid->FindNext(
        wxExFindReplaceData::Get()->GetFindString(),
        command.GetId() == ID_EDIT_FIND_NEXT);
    }
    break;

  case ID_FOCUS_GRID:
    m_FocusGrid = (wxExGrid*)command.GetEventObject();
    break;

  case ID_FOCUS_LISTVIEW:
    m_FocusListView = (wxExListView*)command.GetEventObject();;
    break;

  case ID_FOCUS_STC:
    m_FocusSTC = (wxExSTC*)command.GetEventObject();;
    break;

  case ID_VIEW_MENUBAR:
    if (GetMenuBar() != NULL)
    {
      SetMenuBar(NULL);
    }
    else
    {
      SetMenuBar(m_MenuBar);
    }
    break;

  case ID_VIEW_STATUSBAR:
    if (GetStatusBar() != NULL)
    {
      GetStatusBar()->Show(!GetStatusBar()->IsShown());
      SendSizeEvent();
    }
    break;

  default: wxFAIL; break;
  }
}

#if wxUSE_STATUSBAR
wxStatusBar* wxExFrame::OnCreateStatusBar(
  int number,
  long style,
  wxWindowID id,
  const wxString& name)
{
  m_StatusBar = new wxExStatusBar(this, id, style, name);
  m_StatusBar->SetFieldsCount(number);
  return m_StatusBar;
}
#endif

void wxExFrame::OnFindDialog(wxFindDialogEvent& event)
{
  wxASSERT(m_FindReplaceDialog != NULL);

  if (event.GetEventType() == wxEVT_COMMAND_FIND_CLOSE)
  {
    // Hiding instead of destroying, does not
    // show the dialog next time.
    m_FindReplaceDialog->Destroy();
    m_FindReplaceDialog = NULL;
    return;
  }

  if (m_FocusSTC != NULL)
  {
    FindIn(event, m_FocusSTC);
  }
  else if (m_FocusListView != NULL)
  {
    FindIn(event, m_FocusListView);
  }
  else if (m_FocusGrid != NULL)
  {
    FindIn(event, m_FocusGrid);
  }
  else
  {
    auto* stc = GetSTC();
    auto* lv = GetListView();
    auto* grid = GetGrid();

    if (stc != NULL && stc->IsShown())
    {
      FindIn(event, stc);
    }
    else if (lv != NULL && lv->IsShown())
    {
      FindIn(event, lv);
    }
    else if (grid != NULL && grid->IsShown())
    {
      FindIn(event, grid);
    }
  }
}

void wxExFrame::OnUpdateUI(wxUpdateUIEvent& event)
{
  switch (event.GetId())
  {
    case ID_VIEW_MENUBAR:
      if (GetMenuBar() != NULL)
      {
        event.Check(GetMenuBar()->IsShown());
      }
      else
      {
        event.Check(false);
      }
    break;

    case ID_VIEW_STATUSBAR:
      if (GetStatusBar() != NULL)
      {
        event.Check(GetStatusBar()->IsShown());
      }
      else
      {
        event.Check(false);
      }
      break;

#if wxUSE_STATUSBAR
    case ID_EDIT_STATUS_BAR:
    {
    auto* stc = GetFocusedSTC();
    if (stc == NULL) return;
    stc->UpdateStatusBar("PaneLines");
    }
    break;
#endif

  default:
    wxFAIL;
    break;
  }
}

bool wxExFrame::OpenFile(
  const wxExFileName& filename,
  int line_number,
  const wxString& match,
  long flags)
{
  auto* stc = GetFocusedSTC();

  if (stc != NULL)
  {
    return stc->Open(filename, line_number, match, flags);
  }

  return false;
}

void wxExFrame::SetMenuBar(wxMenuBar* bar)
{
  if (bar != NULL)
  {
    m_MenuBar = bar;
  }

  if (!wxConfigBase::Get()->ReadBool("ShowMenuBar", true))
  {
    wxFrame::SetMenuBar(NULL);
  }
  else
  {
    wxASSERT(m_MenuBar != NULL);
    wxFrame::SetMenuBar(m_MenuBar);
  }
}

#if wxUSE_STATUSBAR
wxExStatusBar* wxExFrame::SetupStatusBar(
  const std::vector<wxExPane>& panes,
  long style,
  wxWindowID id,
  const wxString& name)
{
  if (wxFrame::CreateStatusBar(panes.size(), style, id, name) != NULL)
  {
    if (m_StatusBar->SetPanes(panes) != panes.size())
    {
      return NULL;
    }
  }

  return m_StatusBar;
}
#endif // wxUSE_STATUSBAR

#if wxUSE_STATUSBAR
void wxExFrame::StatusBarDoubleClicked(
  const wxString& pane)
{
  if (pane == "PaneLines")
  {
    auto* stc = GetSTC();
    if (stc != NULL) stc->GotoDialog();
  }
  else if (pane == "PaneLexer")
  {
    auto* stc = GetSTC();

    if (stc != NULL && wxExLexers::Get()->Count() > 0)
    {
      wxString lexer = stc->GetLexer().GetScintillaLexer();

      if (wxExLexers::Get()->ShowDialog(this, lexer))
      {
        stc->SetLexer(lexer);
      }
    }
  }
  else if (pane == "PaneFileType")
  {
    auto* stc = GetSTC();
    if (stc != NULL) stc->FileTypeMenu();
  }
  else if (pane == "PaneItems")
  {
    wxExListView* list = GetListView();
    if (list != NULL) list->GotoDialog();
  }
  else
  {
    // Clicking on another field, do nothing.
  }
}

// This is a static method, so you cannot call wxFrame::SetStatusText.
void wxExFrame::StatusText(const wxString& text, const wxString& pane)
{
  if (m_StatusBar != NULL)
  {
    m_StatusBar->SetStatusText(text, pane);
  }
}

void wxExFrame::StatusText(const wxExFileName& filename, long flags)
{
  // Clear status bar for empty or not existing or not initialized file names.
  wxString text;

  if (filename.IsOk())
  {
    const wxString path = (flags & STAT_FULLPATH
      ? filename.GetFullPath(): filename.GetFullName());

    text += path;

    if (filename.GetStat().IsOk())
    {
      const wxString what = (flags & STAT_SYNC
        ? _("Synchronized"): _("Modified"));
      const wxString time = (flags & STAT_SYNC
        ? wxDateTime::Now().Format(): filename.GetStat().GetModificationTime());
      text += " " + what + " " + time;
    }
  }

  StatusText(text);
}

#endif // wxUSE_STATUSBAR
#endif // wxUSE_GUI
<|endoftext|>


<commit_before>//
// precise-generator.cpp
//
//  Created by Peter Gusev on 19 March 2016.
//  Copyright 2013-2016 Regents of the University of California
//

// #define DEBUG_PG
#include "precise-generator.hpp"
#include <boost/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/atomic.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/lock_guard.hpp>

#define STEADY_TIMER

#ifdef STEADY_TIMER

#include <boost/asio/steady_timer.hpp>
typedef boost::asio::steady_timer timer_type;
typedef lib_chrono::milliseconds ms;
typedef lib_chrono::nanoseconds ns;
typedef lib_chrono::high_resolution_clock::time_point time_point_type;
typedef lib_chrono::high_resolution_clock::duration duration_type;
#define duration_cast_ms(a) (lib_chrono::duration_cast<ms>(a))
#define duration_cast_ns(a) (lib_chrono::duration_cast<ns>(a))
#define duration_cast_double_ns(a) double(lib_chrono::duration_cast<ns>(a).count())
#define duration_count(a) (a).count()
#define now_time() (lib_chrono::high_resolution_clock::now())
#define is_time_point_zero(pt) (pt.time_since_epoch() == lib_chrono::high_resolution_clock::duration::zero())
#define print_duration_ns(d) (d.count())

#else // deadline timer

// requires posix_time
#include <boost/asio/deadline_timer.hpp>
typedef boost::asio::deadline_timer timer_type;
typedef boost::posix_time::ptime time_point_type;
typedef boost::posix_time::milliseconds ms;
typedef boost::posix_time::nanoseconds ns;
typedef boost::posix_time::time_duration duration_type;
#define duration_cast_ms(a) ms((a).total_milliseconds())
#define duration_cast_ns(a) ns((a).total_nanoseconds())
#define duration_cast_double_ns(a) double((a).total_nanoseconds())
#define duration_count(a) (a).ticks()
#define now_time() (boost::posix_time::microsec_clock::local_time())
#define is_time_point_zero(pt) (pt == boost::posix_time::not_a_date_time)
#define print_duration_ns(d) (d.total_nanoseconds())

#endif

using namespace std;
using namespace std::placeholders;

class PreciseGeneratorImpl : public boost::enable_shared_from_this<PreciseGeneratorImpl>
{
public:
    PreciseGeneratorImpl(boost::asio::io_service& io, const double& ratePerSec,
                         const PreciseGenerator::Task& task);

    void start();
    void stop();
    bool isRunning(){ return isRunning_; }
    long long getFireCount() { return fireCount_; }
    double getMeanProcessingOverheadNs() { return (meanProcOverheadNs_); }// - meanTaskTimeNs_); }
    double getMeanTaskTimeNs() { return meanTaskTimeNs_; }

    boost::recursive_mutex setupMutex_;
    boost::atomic<bool> isRunning_;
    long long fireCount_;
    double meanProcOverheadNs_, meanTaskTimeNs_;
    double rate_;
    PreciseGenerator::Task task_;
    boost::asio::io_service& io_;
    timer_type timer_;

    time_point_type iterStart_;
    duration_type lagNs_, lastTaskDurationNs_;
    ms lastIterIntervalMs_;

    void setupTimer();
    void onFire(const boost::system::error_code& code);
    ms getAdjustedInterval(const time_point_type& lastIterStart,
                           const time_point_type& thisIterStart,
                           const ms lastIterIntervalMs,
                           const ns lastTaskDurationNs,
                           const double& rate);
};

//******************************************************************************
PreciseGenerator::PreciseGenerator(boost::asio::io_service& io, const double& ratePerSec,
                                   const Task& task):
pimpl_(boost::make_shared<PreciseGeneratorImpl>(io, ratePerSec, task)){}
PreciseGenerator::~PreciseGenerator(){ pimpl_->stop(); }

void PreciseGenerator::start(){ pimpl_->start(); }
void PreciseGenerator::stop(){ pimpl_->stop(); }
bool PreciseGenerator::isRunning(){ return pimpl_->isRunning(); }
long long PreciseGenerator::getFireCount(){ return pimpl_->getFireCount(); }
double PreciseGenerator::getMeanProcessingOverheadNs(){ return pimpl_->getMeanProcessingOverheadNs(); }
double PreciseGenerator::getMeanTaskTimeNs(){ return pimpl_->getMeanTaskTimeNs(); }

//******************************************************************************
PreciseGeneratorImpl::PreciseGeneratorImpl(boost::asio::io_service& io, const double& ratePerSec,
                                           const PreciseGenerator::Task& task):
io_(io), timer_(io), rate_(ratePerSec), task_(task),
lastIterIntervalMs_(0), meanProcOverheadNs_(0), meanTaskTimeNs_(0)
#ifdef STEADY_TIMER
, lagNs_(0), lastTaskDurationNs_(0)
#endif
{}

void PreciseGeneratorImpl::start()
{
	fireCount_ = 0;
	isRunning_ = true;
	setupTimer();
}

void PreciseGeneratorImpl::stop()
{
    if (isRunning_)
    {
        boost::lock_guard<boost::recursive_mutex> scopedLock(setupMutex_);
        isRunning_ = false;
        timer_.cancel();
    }
}

void PreciseGeneratorImpl::setupTimer()
{
	time_point_type lastIterStart = iterStart_;
	iterStart_ = now_time();
	ms interval = getAdjustedInterval(lastIterStart, iterStart_,
		lastIterIntervalMs_, lastTaskDurationNs_, rate_);
	timer_.expires_from_now(interval);
	timer_.async_wait(lib_bind::bind(&PreciseGeneratorImpl::onFire, shared_from_this(), _1));
	lastIterIntervalMs_ = interval;
}

void PreciseGeneratorImpl::onFire(const boost::system::error_code& code)
{
    if (!code)
    {
        boost::lock_guard<boost::recursive_mutex> scopedLock(setupMutex_);

        if (isRunning_)
        {
            time_point_type tstart = now_time();
            task_();
            time_point_type tend = now_time();
            fireCount_++;

            lastTaskDurationNs_ = duration_cast_ns((tend-tstart));
            meanTaskTimeNs_ += (double)(duration_cast_double_ns(lastTaskDurationNs_) - meanTaskTimeNs_)/(double)fireCount_;

            setupTimer();
        }
    }
}

ms PreciseGeneratorImpl::getAdjustedInterval(const time_point_type& lastIterStart,
	const time_point_type& thisIterStart,
	const ms lastIterIntervalMs,
	const ns lastTaskDurationNs,
	const double& rate)
{
	ns originalInterval = ns((int)(1000000000./rate));
	ms adjustedIntervalMs = duration_cast_ms(originalInterval);
	ms originalIntervalMs = duration_cast_ms(originalInterval);
	ns diff = duration_cast_ns(originalInterval - duration_cast_ns(duration_cast_ms((originalInterval))));

	lagNs_ -= diff;

	#ifdef DEBUG_PG
	cout << "remainder " << print_duration_ns(diff) << endl;
	#endif

	if (!is_time_point_zero(lastIterStart))
	{
		ns lastIterDurationNs = duration_cast_ns((thisIterStart-lastIterStart));
		ns iterLag = duration_cast_ns(lastIterDurationNs-lastIterIntervalMs);

		lagNs_ += iterLag;
		meanProcOverheadNs_ += (double)(duration_cast_double_ns(iterLag-lastTaskDurationNs) - meanProcOverheadNs_)/(double)fireCount_;

		#ifdef DEBUG_PG
		cout << "last iter time " << print_duration_ns(lastIterDurationNs)
			<< " (should " << print_duration_ns(lastIterIntervalMs) << ", "
			<< print_duration_ns(iterLag) << " lag, "
			<< print_duration_ns(lastTaskDurationNs) << " task)" << endl;
		cout << "accum lag " << print_duration_ns(lagNs_) << endl;
		#endif

		if (lagNs_ > originalIntervalMs)
		{
			lagNs_ -= originalIntervalMs;
			adjustedIntervalMs = ms(0);

		}
		else if (abs(duration_count(duration_cast_ms(lagNs_))) > 0)
		{
			adjustedIntervalMs = duration_cast_ms(originalIntervalMs - duration_cast_ms(lagNs_));
			lagNs_ -= duration_cast_ms(lagNs_);
		}
	}

	#ifdef DEBUG_PG
	cout << "interval " << print_duration_ns(adjustedIntervalMs) << endl;
	cout << "adjusted lag " << print_duration_ns(lagNs_) << endl << "-" << endl;
	#endif

	return adjustedIntervalMs;
}
<commit_msg>fixed ubuntu compatibility<commit_after>//
// precise-generator.cpp
//
//  Created by Peter Gusev on 19 March 2016.
//  Copyright 2013-2016 Regents of the University of California
//

// #define DEBUG_PG
#include "precise-generator.hpp"
#include <boost/make_shared.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/thread/mutex.hpp>
#include <boost/atomic.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <boost/thread/lock_guard.hpp>

#define STEADY_TIMER

#ifdef STEADY_TIMER

#include <boost/asio/steady_timer.hpp>
typedef boost::asio::steady_timer timer_type;
typedef lib_chrono::milliseconds ms;
typedef lib_chrono::nanoseconds ns;
typedef lib_chrono::high_resolution_clock::time_point time_point_type;
typedef lib_chrono::high_resolution_clock::duration duration_type;
#define duration_cast_ms(a) (lib_chrono::duration_cast<ms>(a))
#define duration_cast_ns(a) (lib_chrono::duration_cast<ns>(a))
#define duration_cast_double_ns(a) double(lib_chrono::duration_cast<ns>(a).count())
#define duration_count(a) (a).count()
#define now_time() (lib_chrono::high_resolution_clock::now())
#define is_time_point_zero(pt) (pt.time_since_epoch() == lib_chrono::high_resolution_clock::duration::zero())
#define print_duration_ns(d) (d.count())

#else // deadline timer

// requires posix_time
#include <boost/asio/deadline_timer.hpp>
typedef boost::asio::deadline_timer timer_type;
typedef boost::posix_time::ptime time_point_type;
typedef boost::posix_time::milliseconds ms;
typedef boost::posix_time::nanoseconds ns;
typedef boost::posix_time::time_duration duration_type;
#define duration_cast_ms(a) ms((a).total_milliseconds())
#define duration_cast_ns(a) ns((a).total_nanoseconds())
#define duration_cast_double_ns(a) double((a).total_nanoseconds())
#define duration_count(a) (a).ticks()
#define now_time() (boost::posix_time::microsec_clock::local_time())
#define is_time_point_zero(pt) (pt == boost::posix_time::not_a_date_time)
#define print_duration_ns(d) (d.total_nanoseconds())

#endif

using namespace std;
using namespace std::placeholders;

class PreciseGeneratorImpl : public boost::enable_shared_from_this<PreciseGeneratorImpl>
{
public:
    PreciseGeneratorImpl(boost::asio::io_service& io, const double& ratePerSec,
                         const PreciseGenerator::Task& task);

    void start();
    void stop();
    bool isRunning(){ return isRunning_; }
    long long getFireCount() { return fireCount_; }
    double getMeanProcessingOverheadNs() { return (meanProcOverheadNs_); }// - meanTaskTimeNs_); }
    double getMeanTaskTimeNs() { return meanTaskTimeNs_; }

    boost::recursive_mutex setupMutex_;
    boost::atomic<bool> isRunning_;
    long long fireCount_;
    double meanProcOverheadNs_, meanTaskTimeNs_;
    double rate_;
    PreciseGenerator::Task task_;
    boost::asio::io_service& io_;
    timer_type timer_;

    time_point_type iterStart_;
    duration_type lagNs_, lastTaskDurationNs_;
    ms lastIterIntervalMs_;

    void setupTimer();
    void onFire(const boost::system::error_code& code);
    ms getAdjustedInterval(const time_point_type& lastIterStart,
                           const time_point_type& thisIterStart,
                           const ms lastIterIntervalMs,
                           const ns lastTaskDurationNs,
                           const double& rate);
};

//******************************************************************************
PreciseGenerator::PreciseGenerator(boost::asio::io_service& io, const double& ratePerSec,
                                   const Task& task):
pimpl_(boost::make_shared<PreciseGeneratorImpl>(io, ratePerSec, task)){}
PreciseGenerator::~PreciseGenerator(){ pimpl_->stop(); }

void PreciseGenerator::start(){ pimpl_->start(); }
void PreciseGenerator::stop(){ pimpl_->stop(); }
bool PreciseGenerator::isRunning(){ return pimpl_->isRunning(); }
long long PreciseGenerator::getFireCount(){ return pimpl_->getFireCount(); }
double PreciseGenerator::getMeanProcessingOverheadNs(){ return pimpl_->getMeanProcessingOverheadNs(); }
double PreciseGenerator::getMeanTaskTimeNs(){ return pimpl_->getMeanTaskTimeNs(); }

//******************************************************************************
PreciseGeneratorImpl::PreciseGeneratorImpl(boost::asio::io_service& io, const double& ratePerSec,
                                           const PreciseGenerator::Task& task):
io_(io), timer_(io), rate_(ratePerSec), task_(task),
lastIterIntervalMs_(0), meanProcOverheadNs_(0), meanTaskTimeNs_(0)
#ifdef STEADY_TIMER
, lagNs_(0), lastTaskDurationNs_(0)
#endif
{}

void PreciseGeneratorImpl::start()
{
	fireCount_ = 0;
	isRunning_ = true;
	setupTimer();
}

void PreciseGeneratorImpl::stop()
{
    if (isRunning_)
    {
        boost::lock_guard<boost::recursive_mutex> scopedLock(setupMutex_);
        isRunning_ = false;
        timer_.cancel();
    }
}

void PreciseGeneratorImpl::setupTimer()
{
	time_point_type lastIterStart = iterStart_;
	iterStart_ = now_time();
	ms interval = getAdjustedInterval(lastIterStart, iterStart_,
		lastIterIntervalMs_, lastTaskDurationNs_, rate_);
	timer_.expires_from_now(interval);
#ifdef OS_DARWIN
	timer_.async_wait(lib_bind::bind(&PreciseGeneratorImpl::onFire, shared_from_this(), _1));
#else
	timer_.async_wait(lib_bind::bind(&PreciseGeneratorImpl::onFire, shared_from_this(), boost::arg<1>()));
#endif
	lastIterIntervalMs_ = interval;
}

void PreciseGeneratorImpl::onFire(const boost::system::error_code& code)
{
    if (!code)
    {
        boost::lock_guard<boost::recursive_mutex> scopedLock(setupMutex_);

        if (isRunning_)
        {
            time_point_type tstart = now_time();
            task_();
            time_point_type tend = now_time();
            fireCount_++;

            lastTaskDurationNs_ = duration_cast_ns((tend-tstart));
            meanTaskTimeNs_ += (double)(duration_cast_double_ns(lastTaskDurationNs_) - meanTaskTimeNs_)/(double)fireCount_;

            setupTimer();
        }
    }
}

ms PreciseGeneratorImpl::getAdjustedInterval(const time_point_type& lastIterStart,
	const time_point_type& thisIterStart,
	const ms lastIterIntervalMs,
	const ns lastTaskDurationNs,
	const double& rate)
{
	ns originalInterval = ns((int)(1000000000./rate));
	ms adjustedIntervalMs = duration_cast_ms(originalInterval);
	ms originalIntervalMs = duration_cast_ms(originalInterval);
	ns diff = duration_cast_ns(originalInterval - duration_cast_ns(duration_cast_ms((originalInterval))));

	lagNs_ -= diff;

	#ifdef DEBUG_PG
	cout << "remainder " << print_duration_ns(diff) << endl;
	#endif

	if (!is_time_point_zero(lastIterStart))
	{
		ns lastIterDurationNs = duration_cast_ns((thisIterStart-lastIterStart));
		ns iterLag = duration_cast_ns(lastIterDurationNs-lastIterIntervalMs);

		lagNs_ += iterLag;
		meanProcOverheadNs_ += (double)(duration_cast_double_ns(iterLag-lastTaskDurationNs) - meanProcOverheadNs_)/(double)fireCount_;

		#ifdef DEBUG_PG
		cout << "last iter time " << print_duration_ns(lastIterDurationNs)
			<< " (should " << print_duration_ns(lastIterIntervalMs) << ", "
			<< print_duration_ns(iterLag) << " lag, "
			<< print_duration_ns(lastTaskDurationNs) << " task)" << endl;
		cout << "accum lag " << print_duration_ns(lagNs_) << endl;
		#endif

		if (lagNs_ > originalIntervalMs)
		{
			lagNs_ -= originalIntervalMs;
			adjustedIntervalMs = ms(0);

		}
		else if (abs(duration_count(duration_cast_ms(lagNs_))) > 0)
		{
			adjustedIntervalMs = duration_cast_ms(originalIntervalMs - duration_cast_ms(lagNs_));
			lagNs_ -= duration_cast_ms(lagNs_);
		}
	}

	#ifdef DEBUG_PG
	cout << "interval " << print_duration_ns(adjustedIntervalMs) << endl;
	cout << "adjusted lag " << print_duration_ns(lagNs_) << endl << "-" << endl;
	#endif

	return adjustedIntervalMs;
}
<|endoftext|>


<commit_before>/******************************************************************************\
* File:          shell.cpp
* Purpose:       Implementation of class wxExSTCShell
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/tokenzr.h>
#include <wx/extension/shell.h>
#include <wx/extension/app.h>

#if wxUSE_GUI

using namespace std;

BEGIN_EVENT_TABLE(wxExSTCShell, wxExSTC)
  EVT_KEY_DOWN(wxExSTCShell::OnKey)
  EVT_MENU(wxID_PASTE, wxExSTCShell::OnCommand)
END_EVENT_TABLE()

wxExSTCShell::wxExSTCShell(
  wxWindow* parent,
  const wxString& prompt,
  const wxString& command_end,
  bool echo,
  int commands_save_in_config,
  long menu_flags)
  : wxExSTC(parent, menu_flags)
  , m_Command(wxEmptyString)
  , m_CommandEnd((command_end == wxEmptyString ? GetEOL(): command_end))
  , m_CommandStartPosition(0)
  , m_Echo(echo)
  // take a char that is not likely to appear inside commands
  , m_CommandsInConfigDelimiter(wxChar(0x03))
  , m_CommandsSaveInConfig(commands_save_in_config)
  , m_Prompt(prompt)
{
  // Override defaults from config.
  SetEdgeMode(wxSTC_EDGE_NONE);
  ResetMargins(false); // do not reset divider margin

  // Start with a prompt.
  Prompt();

  if (m_CommandsSaveInConfig == -1)
  {
    // Fill the list with an empty command.
    KeepCommand();
  }
  else
  {
    // Get all previous commands.
    wxStringTokenizer tkz(wxExApp::GetConfig("Shell"),
      m_CommandsInConfigDelimiter);

    while (tkz.HasMoreTokens())
    {
      const wxString val = tkz.GetNextToken();
      m_Commands.push_front(val);
    }

    // Take care that m_CommandsIterator is valid.
    if (!m_Commands.empty())
    {
      m_CommandsIterator = m_Commands.end();
    }
    else
    {
      KeepCommand();
    }
  }
}

wxExSTCShell::~wxExSTCShell()
{
  if (m_CommandsSaveInConfig > 0)
  {
    wxString values;
    int items = 0;

    for (
      list < wxString >::reverse_iterator it = m_Commands.rbegin();
      it != m_Commands.rend() && items < m_CommandsSaveInConfig;
      it++)
    {
      values += *it + m_CommandsInConfigDelimiter;
      items++;
    }

    wxExApp::SetConfig("Shell", values);
  }
}

const wxString wxExSTCShell::GetHistory() const
{
  wxString commands;

  for (
    list < wxString >::const_iterator it = m_Commands.begin();
    it != m_Commands.end();
    it++)
  {
    commands += *it + "\n";
  }

  return commands;
}

void wxExSTCShell::KeepCommand()
{
  m_Commands.remove(m_Command);
  m_Commands.push_back(m_Command);

  if (m_Commands.size() == 1)
  {
    m_CommandsIterator = m_Commands.end();
  }
}

void wxExSTCShell::OnCommand(wxCommandEvent& command)
{
  switch (command.GetId())
  {
    case wxID_PASTE:
      // Take care that we cannot paste somewhere inside.
      if (GetCurrentPos() < m_CommandStartPosition)
      {
        DocumentEnd();
      }

      Paste();
      break;

    default: command.Skip();
      break;
  }
}

void wxExSTCShell::OnKey(wxKeyEvent& event)
{
  const int key = event.GetKeyCode();

  // Enter key pressed, we might have entered a command.
  if (key == WXK_RETURN)
  {
    // First get the command.
    SetTargetStart(GetTextLength());
    SetTargetEnd(0);
    SetSearchFlags(wxSTC_FIND_REGEXP);

    if (SearchInTarget("^" + m_Prompt + ".*") != -1)
    {
      m_Command = GetText().substr(
        GetTargetStart() + m_Prompt.length(),
        GetTextLength() - 1);
      m_Command.Trim();
    }

    if (m_Command.empty())
    {
      Prompt();
    }
    else if (
      m_CommandEnd == GetEOL() ||
      m_Command.EndsWith(m_CommandEnd))
    {
      // We have a command.
      EmptyUndoBuffer();

      // History command.
      if (m_Command == wxString("history") +
         (m_CommandEnd == GetEOL() ? wxString(wxEmptyString): m_CommandEnd))
      {
        KeepCommand();
        ShowHistory();
        Prompt();
      }
      // !.. command, get it from history.
      else if (m_Command.StartsWith("!"))
      {
        if (SetCommandFromHistory(m_Command.substr(1)))
        {
          AppendText(m_Command);
          KeepCommand();
          wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND);
          event.SetString(m_Command);
          wxPostEvent(GetParent(), event);
        }
        else
        {
          Prompt(m_Command + ": " + _("event not found"));
        }
      }
      // Other command, send to parent.
      else
      {
        KeepCommand();
        wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND);
        event.SetString(m_Command);
        wxPostEvent(GetParent(), event);
      }

      m_Command.clear();
    }
    else
    {
      if (m_Echo) event.Skip();
    }

    if (m_Commands.size() > 1)
    {
      m_CommandsIterator = m_Commands.end();
    }
  }
  // Up or down key pressed, and at the end of document.
  else if ((key == WXK_UP || key == WXK_DOWN) &&
            GetCurrentPos() == GetTextLength())
  {
    // There is always an empty command in the list.
    if (m_Commands.size() > 1)
    {
      ShowCommand(key);
    }
  }
  // Home key pressed.
  else if (key == WXK_HOME)
  {
    Home();

    const wxString line = GetLine(GetCurrentLine());

    if (line.StartsWith(m_Prompt))
    {
      GotoPos(GetCurrentPos() + m_Prompt.length());
    }
  }
  // Ctrl-Q pressed, used to stop processing.
  else if (event.GetModifiers() == wxMOD_CONTROL && key == 'Q')
  {
    wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND_STOP);
    wxPostEvent(GetParent(), event);
  }
  // Ctrl-V pressed, used for pasting as well.
  else if (event.GetModifiers() == wxMOD_CONTROL && key == 'V')
  {
    if (GetCurrentPos() < m_CommandStartPosition) DocumentEnd();
    if (m_Echo) event.Skip();
  }
  // Backspace or delete key pressed.
  else if (key == WXK_BACK || key == WXK_DELETE)
  {
    if (GetCurrentPos() <= m_CommandStartPosition)
    {
      // Ignore, so do nothing.
    }
    else
    {
      // Allow.
      if (m_Echo) event.Skip();
    }
  }
  // The rest.
  else
  {
    // If we enter regular text and not already building a command, first goto end.
    if (event.GetModifiers() == wxMOD_NONE &&
        key < WXK_START &&
        GetCurrentPos() < m_CommandStartPosition)
    {
      DocumentEnd();
    }

    if (m_Commands.size() > 1)
    {
      m_CommandsIterator = m_Commands.end();
    }

    if (m_Echo) event.Skip();
  }
}

void wxExSTCShell::Prompt(const wxString& text, bool add_eol)
{
  if (!text.empty())
  {
    AppendText(text);
  }

  if (GetTextLength() > 0 && add_eol)
  {
    AppendText(GetEOL());
  }

  AppendText(m_Prompt);

  DocumentEnd();

  m_CommandStartPosition = GetCurrentPos();

  EmptyUndoBuffer();
}

bool wxExSTCShell::SetCommandFromHistory(const wxString& short_command)
{
  const int no_asked_for = atoi(short_command.c_str());

  if (no_asked_for > 0)
  {
    int no = 1;

    for (
      list < wxString >::const_iterator it = m_Commands.begin();
      it != m_Commands.end();
      it++)
    {
      if (no == no_asked_for)
      {
        m_Command = *it;
        return true;
      }

      no++;
    }
  }
  else
  {
    wxString short_command_check;

    if (m_CommandEnd == GetEOL())
    {
      short_command_check = short_command;
    }
    else
    {
      short_command_check =
        short_command.substr(
          0,
          short_command.length() - m_CommandEnd.length());
    }

    // using a const_reverse_iterator here does not compile under MSW
    for (
      list < wxString >::reverse_iterator it = m_Commands.rbegin();
      it != m_Commands.rend();
      it++)
    {
      const wxString command = *it;

      if (command.StartsWith(short_command_check))
      {
        m_Command = command;
        return true;
      }
    }
  }

  return false;
}

void wxExSTCShell::ShowCommand(int key)
{
  SetTargetStart(GetTextLength());
  SetTargetEnd(0);
  SetSearchFlags(wxSTC_FIND_REGEXP);

  if (SearchInTarget("^" + m_Prompt + ".*") != -1)
  {
    SetTargetEnd(GetTextLength());

    if (key == WXK_UP)
    {
      if (m_CommandsIterator != m_Commands.begin())
      {
        m_CommandsIterator--;
      }
    }
    else
    {
      if (m_CommandsIterator != m_Commands.end())
      {
        m_CommandsIterator++;
      }
    }

    if (m_CommandsIterator != m_Commands.end())
    {
      ReplaceTarget(m_Prompt + *m_CommandsIterator);
    }
    else
    {
      ReplaceTarget(m_Prompt);
    }

    DocumentEnd();
  }
}

void wxExSTCShell::ShowHistory()
{
  int command_no = 1;

  for (
    list < wxString >::iterator it = m_Commands.begin();
    it != m_Commands.end();
    it++)
  {
    const wxString command = *it;

    if (!command.empty())
    {
      AppendText(wxString::Format("\n%d %s",
        command_no++,
        command.c_str()));
    }
  }
}

#endif // wxUSE_GUI
<commit_msg>wxExSTCShell now works more similar to bash shell<commit_after>/******************************************************************************\
* File:          shell.cpp
* Purpose:       Implementation of class wxExSTCShell
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/tokenzr.h>
#include <wx/extension/shell.h>
#include <wx/extension/app.h>

#if wxUSE_GUI

using namespace std;

BEGIN_EVENT_TABLE(wxExSTCShell, wxExSTC)
  EVT_KEY_DOWN(wxExSTCShell::OnKey)
  EVT_MENU(wxID_PASTE, wxExSTCShell::OnCommand)
END_EVENT_TABLE()

wxExSTCShell::wxExSTCShell(
  wxWindow* parent,
  const wxString& prompt,
  const wxString& command_end,
  bool echo,
  int commands_save_in_config,
  long menu_flags)
  : wxExSTC(parent, menu_flags)
  , m_Command(wxEmptyString)
  , m_CommandEnd((command_end == wxEmptyString ? GetEOL(): command_end))
  , m_CommandStartPosition(0)
  , m_Echo(echo)
  // take a char that is not likely to appear inside commands
  , m_CommandsInConfigDelimiter(wxChar(0x03))
  , m_CommandsSaveInConfig(commands_save_in_config)
  , m_Prompt(prompt)
{
  // Override defaults from config.
  SetEdgeMode(wxSTC_EDGE_NONE);
  ResetMargins(false); // do not reset divider margin

  // Start with a prompt.
  Prompt();

  if (m_CommandsSaveInConfig == -1)
  {
    // Fill the list with an empty command.
    KeepCommand();
  }
  else
  {
    // Get all previous commands.
    wxStringTokenizer tkz(wxExApp::GetConfig("Shell"),
      m_CommandsInConfigDelimiter);

    while (tkz.HasMoreTokens())
    {
      const wxString val = tkz.GetNextToken();
      m_Commands.push_front(val);
    }

    // Take care that m_CommandsIterator is valid.
    if (!m_Commands.empty())
    {
      m_CommandsIterator = m_Commands.end();
    }
    else
    {
      KeepCommand();
    }
  }
}

wxExSTCShell::~wxExSTCShell()
{
  if (m_CommandsSaveInConfig > 0)
  {
    wxString values;
    int items = 0;

    for (
      list < wxString >::reverse_iterator it = m_Commands.rbegin();
      it != m_Commands.rend() && items < m_CommandsSaveInConfig;
      it++)
    {
      values += *it + m_CommandsInConfigDelimiter;
      items++;
    }

    wxExApp::SetConfig("Shell", values);
  }
}

const wxString wxExSTCShell::GetHistory() const
{
  wxString commands;

  for (
    list < wxString >::const_iterator it = m_Commands.begin();
    it != m_Commands.end();
    it++)
  {
    commands += *it + "\n";
  }

  return commands;
}

void wxExSTCShell::KeepCommand()
{
  m_Commands.remove(m_Command);
  m_Commands.push_back(m_Command);

  if (m_Commands.size() == 1)
  {
    m_CommandsIterator = m_Commands.end();
  }
}

void wxExSTCShell::OnCommand(wxCommandEvent& command)
{
  switch (command.GetId())
  {
    case wxID_PASTE:
      // Take care that we cannot paste somewhere inside.
      if (GetCurrentPos() < m_CommandStartPosition)
      {
        DocumentEnd();
      }

      Paste();
      break;

    default: command.Skip();
      break;
  }
}

void wxExSTCShell::OnKey(wxKeyEvent& event)
{
  const int key = event.GetKeyCode();

  // Enter key pressed, we might have entered a command.
  if (key == WXK_RETURN)
  {
    // First get the command.
    SetTargetStart(GetTextLength());
    SetTargetEnd(0);
    SetSearchFlags(wxSTC_FIND_REGEXP);

    if (SearchInTarget("^" + m_Prompt + ".*") != -1)
    {
      m_Command = GetText().substr(
        GetTargetStart() + m_Prompt.length(),
        GetTextLength() - 1);
      m_Command.Trim();
    }

    if (m_Command.empty())
    {
      Prompt();
    }
    else if (
      m_CommandEnd == GetEOL() ||
      m_Command.EndsWith(m_CommandEnd))
    {
      // We have a command.
      EmptyUndoBuffer();

      // History command.
      if (m_Command == wxString("history") +
         (m_CommandEnd == GetEOL() ? wxString(wxEmptyString): m_CommandEnd))
      {
        KeepCommand();
        ShowHistory();
        Prompt();
      }
      // !.. command, get it from history.
      else if (m_Command.StartsWith("!"))
      {
        if (SetCommandFromHistory(m_Command.substr(1)))
        {
          AppendText(GetEOL() + m_Command);

          // We don't keep the command, so commands are not rearranged and
          // repeatingly calling !5 always gives the same command, just as bash does.

          wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND);
          event.SetString(m_Command);
          wxPostEvent(GetParent(), event);
        }
        else
        {
          Prompt(m_Command + ": " + _("event not found"));
        }
      }
      // Other command, send to parent.
      else
      {
        KeepCommand();
        wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND);
        event.SetString(m_Command);
        wxPostEvent(GetParent(), event);
      }

      m_Command.clear();
    }
    else
    {
      if (m_Echo) event.Skip();
    }

    if (m_Commands.size() > 1)
    {
      m_CommandsIterator = m_Commands.end();
    }
  }
  // Up or down key pressed, and at the end of document.
  else if ((key == WXK_UP || key == WXK_DOWN) &&
            GetCurrentPos() == GetTextLength())
  {
    // There is always an empty command in the list.
    if (m_Commands.size() > 1)
    {
      ShowCommand(key);
    }
  }
  // Home key pressed.
  else if (key == WXK_HOME)
  {
    Home();

    const wxString line = GetLine(GetCurrentLine());

    if (line.StartsWith(m_Prompt))
    {
      GotoPos(GetCurrentPos() + m_Prompt.length());
    }
  }
  // Ctrl-Q pressed, used to stop processing.
  else if (event.GetModifiers() == wxMOD_CONTROL && key == 'Q')
  {
    wxCommandEvent event(wxEVT_COMMAND_MENU_SELECTED, ID_SHELL_COMMAND_STOP);
    wxPostEvent(GetParent(), event);
  }
  // Ctrl-V pressed, used for pasting as well.
  else if (event.GetModifiers() == wxMOD_CONTROL && key == 'V')
  {
    if (GetCurrentPos() < m_CommandStartPosition) DocumentEnd();
    if (m_Echo) event.Skip();
  }
  // Backspace or delete key pressed.
  else if (key == WXK_BACK || key == WXK_DELETE)
  {
    if (GetCurrentPos() <= m_CommandStartPosition)
    {
      // Ignore, so do nothing.
    }
    else
    {
      // Allow.
      if (m_Echo) event.Skip();
    }
  }
  // The rest.
  else
  {
    // If we enter regular text and not already building a command, first goto end.
    if (event.GetModifiers() == wxMOD_NONE &&
        key < WXK_START &&
        GetCurrentPos() < m_CommandStartPosition)
    {
      DocumentEnd();
    }

    if (m_Commands.size() > 1)
    {
      m_CommandsIterator = m_Commands.end();
    }

    if (m_Echo) event.Skip();
  }
}

void wxExSTCShell::Prompt(const wxString& text, bool add_eol)
{
  if (!text.empty())
  {
    AppendText(text);
  }

  if (GetTextLength() > 0 && add_eol)
  {
    AppendText(GetEOL());
  }

  AppendText(m_Prompt);

  DocumentEnd();

  m_CommandStartPosition = GetCurrentPos();

  EmptyUndoBuffer();
}

bool wxExSTCShell::SetCommandFromHistory(const wxString& short_command)
{
  const int no_asked_for = atoi(short_command.c_str());

  if (no_asked_for > 0)
  {
    int no = 0;

    for (
      list < wxString >::const_iterator it = m_Commands.begin();
      it != m_Commands.end();
      it++)
    {
      if (no == no_asked_for)
      {
        m_Command = *it;
        return true;
      }

      no++;
    }
  }
  else
  {
    wxString short_command_check;

    if (m_CommandEnd == GetEOL())
    {
      short_command_check = short_command;
    }
    else
    {
      short_command_check =
        short_command.substr(
          0,
          short_command.length() - m_CommandEnd.length());
    }

    // using a const_reverse_iterator here does not compile under MSW
    for (
      list < wxString >::reverse_iterator it = m_Commands.rbegin();
      it != m_Commands.rend();
      it++)
    {
      const wxString command = *it;

      if (command.StartsWith(short_command_check))
      {
        m_Command = command;
        return true;
      }
    }
  }

  return false;
}

void wxExSTCShell::ShowCommand(int key)
{
  SetTargetStart(GetTextLength());
  SetTargetEnd(0);
  SetSearchFlags(wxSTC_FIND_REGEXP);

  if (SearchInTarget("^" + m_Prompt + ".*") != -1)
  {
    SetTargetEnd(GetTextLength());

    if (key == WXK_UP)
    {
      if (m_CommandsIterator != m_Commands.begin())
      {
        m_CommandsIterator--;
      }
    }
    else
    {
      if (m_CommandsIterator != m_Commands.end())
      {
        m_CommandsIterator++;
      }
    }

    if (m_CommandsIterator != m_Commands.end())
    {
      ReplaceTarget(m_Prompt + *m_CommandsIterator);
    }
    else
    {
      ReplaceTarget(m_Prompt);
    }

    DocumentEnd();
  }
}

void wxExSTCShell::ShowHistory()
{
  int command_no = 1;

  for (
    list < wxString >::iterator it = m_Commands.begin();
    it != m_Commands.end();
    it++)
  {
    const wxString command = *it;

    if (!command.empty())
    {
      AppendText(wxString::Format("\n%d %s",
        command_no++,
        command.c_str()));
    }
  }
}

#endif // wxUSE_GUI
<|endoftext|>


<commit_before>/******************************************************************************\
* File:          test.cpp
* Purpose:       Implementation for wxextension cpp unit testing
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
* Created:       za 17 jan 2009 11:51:20 CET
*
* Copyright (c) 2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <TestCaller.h>
#include "test.h"

void exTestFixture::setUp()
{
  m_Config = new exConfig("test.cfg", wxCONFIG_USE_LOCAL_FILE);
  m_File = new exFile("test.h");
  m_FileName = new exFileName("test.h");
  m_FileNameStatistics = new exFileNameStatistics("test.h");
  m_Lexer = new exLexer();
  m_Lexers = new exLexers(exFileName("../data/lexers.xml"));
  m_RCS = new exRCS();
  m_Stat = new exStat("test.h");
  m_Statistics = new exStatistics<long>();
  m_TextFile = new exTextFile(exFileName("test.h"), m_Config, m_Lexers);
  m_Tool = new exTool(ID_TOOL_REPORT_COUNT);
}

void exTestFixture::testConstructors()
{
  CPPUNIT_ASSERT(m_File != NULL);
}

void exTestFixture::testMethods()
{
  // test exConfig
  CPPUNIT_ASSERT(m_Config->Get("keystring", "val") == "val");
  CPPUNIT_ASSERT(m_Config->Get("keylong", 12) == 12);
  CPPUNIT_ASSERT(m_Config->GetBool("keybool", true));
  CPPUNIT_ASSERT(m_Config->GetFindReplaceData() != NULL);
  m_Config->Set("keystring", "val2");
  CPPUNIT_ASSERT(m_Config->Get("keystring", "val") == "val2");
  m_Config->Set("keylong", 15);
  CPPUNIT_ASSERT(m_Config->Get("keylong", 7) == 15);
  m_Config->SetBool("keybool", false);
  CPPUNIT_ASSERT(m_Config->GetBool("keybool", true) == false);
  m_Config->Toggle("keybool");
  CPPUNIT_ASSERT(m_Config->GetBool("keybool", false));

  // test exFile
  CPPUNIT_ASSERT(m_File->GetStat().IsOk());
  CPPUNIT_ASSERT(m_File->GetStat().GetFullPath() == m_File->GetFileName().GetFullPath());
  // The fullpath should be normalized, test it.
  CPPUNIT_ASSERT(m_File->GetFileName().GetFullPath() != "test.h");

  // test exFileName
  CPPUNIT_ASSERT(m_FileName->GetLexer().GetScintillaLexer().empty());
  CPPUNIT_ASSERT(m_FileName->GetStat().IsOk());
  m_FileName->Assign("xxx");
  m_FileName->GetStat().Update("xxx");
  CPPUNIT_ASSERT(!m_FileName->GetStat().IsOk());

  // test exFileNameStatistics
  CPPUNIT_ASSERT(m_FileNameStatistics->Get().empty());
  CPPUNIT_ASSERT(m_FileNameStatistics->Get("xx") == 0);

  // test exLexer
  *m_Lexer = m_Lexers->FindByText("// this is a cpp comment text");
  CPPUNIT_ASSERT(m_Lexer->GetScintillaLexer().empty()); // we have no lexers
  m_Lexer->SetKeywords("test11 test21:1 test31:1 test12:2 test22:2");
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("test11"));
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("test21"));
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("test12"));
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("test22"));
  CPPUNIT_ASSERT(m_Lexer->KeywordStartsWith("te"));
  CPPUNIT_ASSERT(!m_Lexer->KeywordStartsWith("xx"));
  CPPUNIT_ASSERT(!m_Lexer->GetKeywords().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetKeywordsSet().empty());

  // test exLexers
  CPPUNIT_ASSERT(m_Lexers->Read());
  *m_Lexer = m_Lexers->FindByText("// this is a cpp comment text");
  CPPUNIT_ASSERT(m_Lexer->GetScintillaLexer() == "cpp");
  CPPUNIT_ASSERT(m_Lexers->FindByFileName(wxFileName("test.h")).GetScintillaLexer() == "cpp");
  CPPUNIT_ASSERT(m_Lexers->FindByName("cpp").GetScintillaLexer() == "cpp");
  CPPUNIT_ASSERT(m_Lexers->Count() > 0);
  CPPUNIT_ASSERT(!m_Lexers->BuildWildCards(wxFileName("test.h")).empty());
  CPPUNIT_ASSERT(!m_Lexers->GetIndicators().empty());
  CPPUNIT_ASSERT(!m_Lexers->GetMarkers().empty());
  CPPUNIT_ASSERT(!m_Lexers->GetStyles().empty());
  CPPUNIT_ASSERT(!m_Lexers->GetStylesHex().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetAssociations().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetColourings().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetCommentBegin().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetCommentBegin2().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetCommentEnd().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetCommentEnd2().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetKeywords().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetKeywordsSet().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetKeywordsString().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetProperties().empty());
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("class"));
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("const"));
  CPPUNIT_ASSERT(m_Lexer->KeywordStartsWith("cla"));
  CPPUNIT_ASSERT(!m_Lexer->KeywordStartsWith("xxx"));
  CPPUNIT_ASSERT(!m_Lexer->MakeComment("test", true).empty());
  CPPUNIT_ASSERT(m_Lexer->UsableCharactersPerLine() == 74); // 80 - 4 (comments) - 2 (spaces)

  // test exRCS
  CPPUNIT_ASSERT(m_RCS->GetAuthor().empty());
  CPPUNIT_ASSERT(m_RCS->GetDescription().empty());
  CPPUNIT_ASSERT(m_RCS->GetUser().empty());

  // test exStat
  CPPUNIT_ASSERT(!m_Stat->IsLink());
  CPPUNIT_ASSERT(m_Stat->IsOk());
  CPPUNIT_ASSERT(!m_Stat->IsReadOnly());
  CPPUNIT_ASSERT(m_Stat->Update("testlink"));
//  CPPUNIT_ASSERT(m_Stat->IsLink());

  // test exStatistics
  m_Statistics->Inc("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 1);
  m_Statistics->Inc("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 2);
  m_Statistics->Set("test", 13);
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 13);
  m_Statistics->Dec("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 12);
  m_Statistics->Inc("test2");
  CPPUNIT_ASSERT(m_Statistics->Get("test2") == 1);
  m_Statistics->Clear();
  CPPUNIT_ASSERT(m_Statistics->GetItems().empty());

  // test exTextFile
  CPPUNIT_ASSERT(m_TextFile->RunTool(ID_TOOL_REPORT_COUNT));
  CPPUNIT_ASSERT(!m_TextFile->GetStatistics().GetElements().GetItems().empty());
  CPPUNIT_ASSERT(!m_TextFile->IsOpened()); // file should be closed after running tool

  CPPUNIT_ASSERT(m_TextFile->RunTool(ID_TOOL_REPORT_COUNT)); // do the same test
  CPPUNIT_ASSERT(!m_TextFile->GetStatistics().GetElements().GetItems().empty());
  CPPUNIT_ASSERT(!m_TextFile->IsOpened()); // file should be closed after running tool

  CPPUNIT_ASSERT(m_TextFile->RunTool(ID_TOOL_REPORT_HEADER));
  CPPUNIT_ASSERT(m_TextFile->GetTool().GetId() == ID_TOOL_REPORT_HEADER);
//wxLogMessage(m_TextFile->GetStatistics().Get() + m_TextFile->GetRCS().GetDescription());
//  CPPUNIT_ASSERT(m_TextFile->GetRCS().GetDescription() ==
//    "Declaration of classes for wxextension cpp unit testing");

  CPPUNIT_ASSERT(m_TextFile->RunTool(ID_TOOL_REPORT_KEYWORD));
//  CPPUNIT_ASSERT(!m_TextFile->GetStatistics().GetKeywords().GetItems().empty());

  // test exTool
  CPPUNIT_ASSERT(m_Tool->IsStatisticsType() > 0);
}

void exTestFixture::testTiming()
{
  exFile file("test.h");

  CPPUNIT_ASSERT(file.IsOpened());

  wxStopWatch sw;

  const int max = 10000;

  for (int i = 0; i < max; i++)
  {
    wxString* buffer = file.Read();
    CPPUNIT_ASSERT(buffer != NULL);
    delete buffer;
  }

  const long exfile_read = sw.Time();

  sw.Start();

  wxFile wxfile("test.h");

  for (int j = 0; j < max; j++)
  {
    char* charbuffer = new char[wxfile.Length()];
    wxfile.Read(charbuffer, wxfile.Length());
    wxString* buffer = new wxString(charbuffer, wxfile.Length());
    delete charbuffer;
    delete buffer;
  }

  const long file_read = sw.Time();

  printf(
    "exFile::Read:%ld wxFile::Read:%ld\n",
    exfile_read,
    file_read);
}

void exTestFixture::testTimingAttrib()
{
  const int max = 1000;

  wxStopWatch sw;

  const exFileName exfile("test.h");

  int checked = 0;

  for (int i = 0; i < max; i++)
  {
    checked += exfile.GetStat().IsReadOnly();
  }

  const long exfile_time = sw.Time();

  sw.Start();

  const wxFileName file("test.h");

  for (int j = 0; j < max; j++)
  {
    checked += file.IsFileWritable();
  }

  const long file_time = sw.Time();

  printf(
    "exFileName::IsReadOnly:%ld wxFileName::IsFileWritable:%ld\n",
    exfile_time,
    file_time);
}

void exTestFixture::testTimingConfig()
{
  const int max = 100000;

  wxStopWatch sw;

  for (int i = 0; i < max; i++)
  {
    m_Config->Get("test", 0);
  }

  const long exconfig = sw.Time();

  sw.Start();

  for (int j = 0; j < max; j++)
  {
    m_Config->Read("test", 0l);
  }

  const long config = sw.Time();

  printf(
    "exConfig::Get:%ld wxConfig::Read:%ld\n",
    exconfig,
    config);
}

void exTestFixture::tearDown()
{
}

void exAppTestFixture::setUp()
{
  m_Dir = new exDir("./");
  m_Grid = new exGrid(wxTheApp->GetTopWindow());
  m_ListView = new exListView(wxTheApp->GetTopWindow());
  m_STC = new exSTC(wxTheApp->GetTopWindow(), exFileName("test.h"));
  m_STCShell = new exSTCShell(wxTheApp->GetTopWindow());
  m_SVN = new exSVN(SVN_STAT, "test.h");
}

void exAppTestFixture::testConstructors()
{
}

void exAppTestFixture::testMethods()
{
  // test exApp
  CPPUNIT_ASSERT(exApp::GetConfig() != NULL);
  CPPUNIT_ASSERT(exApp::GetLexers() != NULL);
  CPPUNIT_ASSERT(exApp::GetPrinter() != NULL);

  // test exDir
  CPPUNIT_ASSERT(m_Dir->FindFiles() > 0);
  CPPUNIT_ASSERT(m_Dir->GetFiles().GetCount() > 0);

  // test exGrid
  CPPUNIT_ASSERT(m_Grid->CreateGrid(5, 5));
  m_Grid->SelectAll();
  m_Grid->SetGridCellValue(wxGridCellCoords(0, 0), "test");
  CPPUNIT_ASSERT(m_Grid->GetCellValue(0, 0) == "test");
  m_Grid->SetCellsValue(wxGridCellCoords(0, 0), "test1\ttest2\ntest3\ttest4\n");
  CPPUNIT_ASSERT(m_Grid->GetCellValue(0, 0) == "test1");

  // test exListView
  m_ListView->SetSingleStyle(wxLC_REPORT); // wxLC_ICON);
  m_ListView->InsertColumn("String", exColumn::COL_STRING);
  m_ListView->InsertColumn("Number", exColumn::COL_INT);
  CPPUNIT_ASSERT(m_ListView->FindColumn("String") == 0);
  CPPUNIT_ASSERT(m_ListView->FindColumn("Number") == 1);

  // test exSTC
  CPPUNIT_ASSERT(m_STC->GetFileName().GetFullName() == "test.h");

  // test exSTCShell
  m_STCShell->Prompt("test1");
  m_STCShell->Prompt("test2");
  m_STCShell->Prompt("test3");
  m_STCShell->Prompt("test4");
  // Prompting does not add a command to history...
  // TODO: Make a better test.
  CPPUNIT_ASSERT(!m_STCShell->GetHistory().Contains("test4"));

  // test exSVN
  CPPUNIT_ASSERT(m_SVN->GetInfo(false) == 0); // do not use a dialog
  // The contents depends on the svn stat, of course,
  // so do not assert on it.
  m_SVN->GetContents();

  // test util
  CPPUNIT_ASSERT(exClipboardAdd("test"));
  CPPUNIT_ASSERT(exClipboardGet() == "test");
  CPPUNIT_ASSERT(exGetNumberOfLines("test\ntest\n") == 3);
  CPPUNIT_ASSERT(exGetLineNumberFromText("test on line: 1200") == 1200);
  CPPUNIT_ASSERT(exLog("hello from wxextension test"));
  CPPUNIT_ASSERT(!exMatchesOneOf(wxFileName("test.txt"), "*.cpp"));
  CPPUNIT_ASSERT(exMatchesOneOf(wxFileName("test.txt"), "*.cpp;*.txt"));
  CPPUNIT_ASSERT(exSkipWhiteSpace("t     es   t") == "t es t");
}

void exAppTestFixture::tearDown()
{
}

exTestSuite::exTestSuite()
  : CppUnit::TestSuite("wxextension test suite")
{
#ifndef APP_TEST
  // Add the tests.
  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testConstructors",
    &exTestFixture::testConstructors));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testMethods",
    &exTestFixture::testMethods));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testTiming",
    &exTestFixture::testTiming));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testTimingAttrib",
    &exTestFixture::testTimingAttrib));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testTimingConfig",
    &exTestFixture::testTimingConfig));
#else
  addTest(new CppUnit::TestCaller<exAppTestFixture>(
    "testConstructors",
    &exAppTestFixture::testConstructors));

  addTest(new CppUnit::TestCaller<exAppTestFixture>(
    "testMethods",
    &exAppTestFixture::testMethods));
#endif
}
<commit_msg>added tests for syncing<commit_after>/******************************************************************************\
* File:          test.cpp
* Purpose:       Implementation for wxextension cpp unit testing
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
* Created:       za 17 jan 2009 11:51:20 CET
*
* Copyright (c) 2009 Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <TestCaller.h>
#include "test.h"

void exTestFixture::setUp()
{
  m_Config = new exConfig("test.cfg", wxCONFIG_USE_LOCAL_FILE);
  m_File = new exFile("test.h");
  m_FileName = new exFileName("test.h");
  m_FileNameStatistics = new exFileNameStatistics("test.h");
  m_Lexer = new exLexer();
  m_Lexers = new exLexers(exFileName("../data/lexers.xml"));
  m_RCS = new exRCS();
  m_Stat = new exStat("test.h");
  m_Statistics = new exStatistics<long>();
  m_TextFile = new exTextFile(exFileName("test.h"), m_Config, m_Lexers);
  m_Tool = new exTool(ID_TOOL_REPORT_COUNT);
}

void exTestFixture::testConstructors()
{
  CPPUNIT_ASSERT(m_File != NULL);
}

void exTestFixture::testMethods()
{
  // test exConfig
  CPPUNIT_ASSERT(m_Config->Get("keystring", "val") == "val");
  CPPUNIT_ASSERT(m_Config->Get("keylong", 12) == 12);
  CPPUNIT_ASSERT(m_Config->GetBool("keybool", true));
  CPPUNIT_ASSERT(m_Config->GetFindReplaceData() != NULL);
  m_Config->Set("keystring", "val2");
  CPPUNIT_ASSERT(m_Config->Get("keystring", "val") == "val2");
  m_Config->Set("keylong", 15);
  CPPUNIT_ASSERT(m_Config->Get("keylong", 7) == 15);
  m_Config->SetBool("keybool", false);
  CPPUNIT_ASSERT(m_Config->GetBool("keybool", true) == false);
  m_Config->Toggle("keybool");
  CPPUNIT_ASSERT(m_Config->GetBool("keybool", false));

  // test exFile
  CPPUNIT_ASSERT(m_File->GetStat().IsOk());
  CPPUNIT_ASSERT(m_File->GetStat().GetFullPath() == m_File->GetFileName().GetFullPath());
  // The fullpath should be normalized, test it.
  CPPUNIT_ASSERT(m_File->GetFileName().GetFullPath() != "test.h");
  CPPUNIT_ASSERT(!m_File->GetStat().IsReadOnly());
  CPPUNIT_ASSERT(!m_File->CheckSyncNeeded());
  CPPUNIT_ASSERT(!m_File->GetStat().IsReadOnly());

  // test exFileName
  CPPUNIT_ASSERT(m_FileName->GetLexer().GetScintillaLexer().empty());
  CPPUNIT_ASSERT(m_FileName->GetStat().IsOk());
  m_FileName->Assign("xxx");
  m_FileName->GetStat().Update("xxx");
  CPPUNIT_ASSERT(!m_FileName->GetStat().IsOk());

  // test exFileNameStatistics
  CPPUNIT_ASSERT(m_FileNameStatistics->Get().empty());
  CPPUNIT_ASSERT(m_FileNameStatistics->Get("xx") == 0);

  // test exLexer
  *m_Lexer = m_Lexers->FindByText("// this is a cpp comment text");
  CPPUNIT_ASSERT(m_Lexer->GetScintillaLexer().empty()); // we have no lexers
  m_Lexer->SetKeywords("test11 test21:1 test31:1 test12:2 test22:2");
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("test11"));
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("test21"));
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("test12"));
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("test22"));
  CPPUNIT_ASSERT(m_Lexer->KeywordStartsWith("te"));
  CPPUNIT_ASSERT(!m_Lexer->KeywordStartsWith("xx"));
  CPPUNIT_ASSERT(!m_Lexer->GetKeywords().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetKeywordsSet().empty());

  // test exLexers
  CPPUNIT_ASSERT(m_Lexers->Read());
  *m_Lexer = m_Lexers->FindByText("// this is a cpp comment text");
  CPPUNIT_ASSERT(m_Lexer->GetScintillaLexer() == "cpp");
  CPPUNIT_ASSERT(m_Lexers->FindByFileName(wxFileName("test.h")).GetScintillaLexer() == "cpp");
  CPPUNIT_ASSERT(m_Lexers->FindByName("cpp").GetScintillaLexer() == "cpp");
  CPPUNIT_ASSERT(m_Lexers->Count() > 0);
  CPPUNIT_ASSERT(!m_Lexers->BuildWildCards(wxFileName("test.h")).empty());
  CPPUNIT_ASSERT(!m_Lexers->GetIndicators().empty());
  CPPUNIT_ASSERT(!m_Lexers->GetMarkers().empty());
  CPPUNIT_ASSERT(!m_Lexers->GetStyles().empty());
  CPPUNIT_ASSERT(!m_Lexers->GetStylesHex().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetAssociations().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetColourings().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetCommentBegin().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetCommentBegin2().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetCommentEnd().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetCommentEnd2().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetKeywords().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetKeywordsSet().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetKeywordsString().empty());
  CPPUNIT_ASSERT(!m_Lexer->GetProperties().empty());
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("class"));
  CPPUNIT_ASSERT(m_Lexer->IsKeyword("const"));
  CPPUNIT_ASSERT(m_Lexer->KeywordStartsWith("cla"));
  CPPUNIT_ASSERT(!m_Lexer->KeywordStartsWith("xxx"));
  CPPUNIT_ASSERT(!m_Lexer->MakeComment("test", true).empty());
  CPPUNIT_ASSERT(m_Lexer->UsableCharactersPerLine() == 74); // 80 - 4 (comments) - 2 (spaces)

  // test exRCS
  CPPUNIT_ASSERT(m_RCS->GetAuthor().empty());
  CPPUNIT_ASSERT(m_RCS->GetDescription().empty());
  CPPUNIT_ASSERT(m_RCS->GetUser().empty());

  // test exStat
  CPPUNIT_ASSERT(!m_Stat->IsLink());
  CPPUNIT_ASSERT(m_Stat->IsOk());
  CPPUNIT_ASSERT(!m_Stat->IsReadOnly());
  CPPUNIT_ASSERT(m_Stat->Update("testlink"));
//  CPPUNIT_ASSERT(m_Stat->IsLink());

  // test exStatistics
  m_Statistics->Inc("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 1);
  m_Statistics->Inc("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 2);
  m_Statistics->Set("test", 13);
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 13);
  m_Statistics->Dec("test");
  CPPUNIT_ASSERT(m_Statistics->Get("test") == 12);
  m_Statistics->Inc("test2");
  CPPUNIT_ASSERT(m_Statistics->Get("test2") == 1);
  m_Statistics->Clear();
  CPPUNIT_ASSERT(m_Statistics->GetItems().empty());

  // test exTextFile
  CPPUNIT_ASSERT(m_TextFile->RunTool(ID_TOOL_REPORT_COUNT));
  CPPUNIT_ASSERT(!m_TextFile->GetStatistics().GetElements().GetItems().empty());
  CPPUNIT_ASSERT(!m_TextFile->IsOpened()); // file should be closed after running tool

  CPPUNIT_ASSERT(m_TextFile->RunTool(ID_TOOL_REPORT_COUNT)); // do the same test
  CPPUNIT_ASSERT(!m_TextFile->GetStatistics().GetElements().GetItems().empty());
  CPPUNIT_ASSERT(!m_TextFile->IsOpened()); // file should be closed after running tool

  CPPUNIT_ASSERT(m_TextFile->RunTool(ID_TOOL_REPORT_HEADER));
  CPPUNIT_ASSERT(m_TextFile->GetTool().GetId() == ID_TOOL_REPORT_HEADER);
//wxLogMessage(m_TextFile->GetStatistics().Get() + m_TextFile->GetRCS().GetDescription());
//  CPPUNIT_ASSERT(m_TextFile->GetRCS().GetDescription() ==
//    "Declaration of classes for wxextension cpp unit testing");

  CPPUNIT_ASSERT(m_TextFile->RunTool(ID_TOOL_REPORT_KEYWORD));
//  CPPUNIT_ASSERT(!m_TextFile->GetStatistics().GetKeywords().GetItems().empty());

  // test exTool
  CPPUNIT_ASSERT(m_Tool->IsStatisticsType() > 0);
}

void exTestFixture::testTiming()
{
  exFile file("test.h");

  CPPUNIT_ASSERT(file.IsOpened());

  wxStopWatch sw;

  const int max = 10000;

  for (int i = 0; i < max; i++)
  {
    wxString* buffer = file.Read();
    CPPUNIT_ASSERT(buffer != NULL);
    delete buffer;
  }

  const long exfile_read = sw.Time();

  sw.Start();

  wxFile wxfile("test.h");

  for (int j = 0; j < max; j++)
  {
    char* charbuffer = new char[wxfile.Length()];
    wxfile.Read(charbuffer, wxfile.Length());
    wxString* buffer = new wxString(charbuffer, wxfile.Length());
    delete charbuffer;
    delete buffer;
  }

  const long file_read = sw.Time();

  printf(
    "exFile::Read:%ld wxFile::Read:%ld\n",
    exfile_read,
    file_read);
}

void exTestFixture::testTimingAttrib()
{
  const int max = 1000;

  wxStopWatch sw;

  const exFileName exfile("test.h");

  int checked = 0;

  for (int i = 0; i < max; i++)
  {
    checked += exfile.GetStat().IsReadOnly();
  }

  const long exfile_time = sw.Time();

  sw.Start();

  const wxFileName file("test.h");

  for (int j = 0; j < max; j++)
  {
    checked += file.IsFileWritable();
  }

  const long file_time = sw.Time();

  printf(
    "exFileName::IsReadOnly:%ld wxFileName::IsFileWritable:%ld\n",
    exfile_time,
    file_time);
}

void exTestFixture::testTimingConfig()
{
  const int max = 100000;

  wxStopWatch sw;

  for (int i = 0; i < max; i++)
  {
    m_Config->Get("test", 0);
  }

  const long exconfig = sw.Time();

  sw.Start();

  for (int j = 0; j < max; j++)
  {
    m_Config->Read("test", 0l);
  }

  const long config = sw.Time();

  printf(
    "exConfig::Get:%ld wxConfig::Read:%ld\n",
    exconfig,
    config);
}

void exTestFixture::tearDown()
{
}

void exAppTestFixture::setUp()
{
  m_Dir = new exDir("./");
  m_Grid = new exGrid(wxTheApp->GetTopWindow());
  m_ListView = new exListView(wxTheApp->GetTopWindow());
  m_STC = new exSTC(wxTheApp->GetTopWindow(), exFileName("test.h"));
  m_STCShell = new exSTCShell(wxTheApp->GetTopWindow());
  m_SVN = new exSVN(SVN_STAT, "test.h");
}

void exAppTestFixture::testConstructors()
{
}

void exAppTestFixture::testMethods()
{
  // test exApp
  CPPUNIT_ASSERT(exApp::GetConfig() != NULL);
  CPPUNIT_ASSERT(exApp::GetLexers() != NULL);
  CPPUNIT_ASSERT(exApp::GetPrinter() != NULL);

  // test exDir
  CPPUNIT_ASSERT(m_Dir->FindFiles() > 0);
  CPPUNIT_ASSERT(m_Dir->GetFiles().GetCount() > 0);

  // test exGrid
  CPPUNIT_ASSERT(m_Grid->CreateGrid(5, 5));
  m_Grid->SelectAll();
  m_Grid->SetGridCellValue(wxGridCellCoords(0, 0), "test");
  CPPUNIT_ASSERT(m_Grid->GetCellValue(0, 0) == "test");
  m_Grid->SetCellsValue(wxGridCellCoords(0, 0), "test1\ttest2\ntest3\ttest4\n");
  CPPUNIT_ASSERT(m_Grid->GetCellValue(0, 0) == "test1");

  // test exListView
  m_ListView->SetSingleStyle(wxLC_REPORT); // wxLC_ICON);
  m_ListView->InsertColumn("String", exColumn::COL_STRING);
  m_ListView->InsertColumn("Number", exColumn::COL_INT);
  CPPUNIT_ASSERT(m_ListView->FindColumn("String") == 0);
  CPPUNIT_ASSERT(m_ListView->FindColumn("Number") == 1);

  // test exSTC
  CPPUNIT_ASSERT(m_STC->GetFileName().GetFullName() == "test.h");

  // test exSTCShell
  m_STCShell->Prompt("test1");
  m_STCShell->Prompt("test2");
  m_STCShell->Prompt("test3");
  m_STCShell->Prompt("test4");
  // Prompting does not add a command to history...
  // TODO: Make a better test.
  CPPUNIT_ASSERT(!m_STCShell->GetHistory().Contains("test4"));

  // test exSVN
  CPPUNIT_ASSERT(m_SVN->GetInfo(false) == 0); // do not use a dialog
  // The contents depends on the svn stat, of course,
  // so do not assert on it.
  m_SVN->GetContents();

  // test util
  CPPUNIT_ASSERT(exClipboardAdd("test"));
  CPPUNIT_ASSERT(exClipboardGet() == "test");
  CPPUNIT_ASSERT(exGetNumberOfLines("test\ntest\n") == 3);
  CPPUNIT_ASSERT(exGetLineNumberFromText("test on line: 1200") == 1200);
  CPPUNIT_ASSERT(exLog("hello from wxextension test"));
  CPPUNIT_ASSERT(!exMatchesOneOf(wxFileName("test.txt"), "*.cpp"));
  CPPUNIT_ASSERT(exMatchesOneOf(wxFileName("test.txt"), "*.cpp;*.txt"));
  CPPUNIT_ASSERT(exSkipWhiteSpace("t     es   t") == "t es t");
}

void exAppTestFixture::tearDown()
{
}

exTestSuite::exTestSuite()
  : CppUnit::TestSuite("wxextension test suite")
{
#ifndef APP_TEST
  // Add the tests.
  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testConstructors",
    &exTestFixture::testConstructors));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testMethods",
    &exTestFixture::testMethods));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testTiming",
    &exTestFixture::testTiming));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testTimingAttrib",
    &exTestFixture::testTimingAttrib));

  addTest(new CppUnit::TestCaller<exTestFixture>(
    "testTimingConfig",
    &exTestFixture::testTimingConfig));
#else
  addTest(new CppUnit::TestCaller<exAppTestFixture>(
    "testConstructors",
    &exAppTestFixture::testConstructors));

  addTest(new CppUnit::TestCaller<exAppTestFixture>(
    "testMethods",
    &exAppTestFixture::testMethods));
#endif
}
<|endoftext|>