📄 testbrowserdialog.cpp
字号:
/////////////////////////////////////////////////////////////////////////////// Name: TestBrowserDialog.cpp// Purpose: Implementation for class TestBrowserDialog.cpp// Author: Baptiste Lepilleur// Modified by: Anthon Pang// Created: 2003.09.11// RCS-ID:// Copyright: (C) 2003 by Anthon Pang and Baptiste Lepilleur// Licence: LGPL// Reference: cppunit/src/qttestrunner/TestBrowserDlgImpl.cpp// cppunit/src/msvc6/testrunner/TreeHierarchyDlg.cpp// wxWidgets/samples/treectrl/treetest.cpp/////////////////////////////////////////////////////////////////////////////// ============================================================================// declarations// ============================================================================// ----------------------------------------------------------------------------// headers// ----------------------------------------------------------------------------// For compilers that support precompilation, includes "wx/wx.h".#include <wx/wxprec.h>#ifdef __BORLANDC__# pragma hdrstop#endif// for all others, include the necessary headers (this file is usually all you// need because it includes almost all "standard" wxWidgets headers)#ifndef WX_PRECOMP# include <wx/wx.h>#endif#include "TestBrowserDialog.h"#include <wx/treectrl.h>#include <wx/image.h>#include <wx/imaglist.h>#include "res/icon1.xpm"#include "res/icon2.xpm"#include "res/icon3.xpm"#include "res/icon4.xpm"#include "res/icon5.xpm"#include "res/icon6.xpm"// ----------------------------------------------------------------------------// private classes// ----------------------------------------------------------------------------class MyTreeItemData : public wxTreeItemData{private: CPPUNIT_NS::Test *m_test;public: MyTreeItemData(CPPUNIT_NS::Test *test) : m_test(test) { } CPPUNIT_NS::Test *getTest() const { return m_test; }};class MyTreeCtrl : public wxTreeCtrl{DECLARE_EVENT_TABLE() typedef bool (*ExamineFunc)( const wxTreeItemId& tid, const MyTreeItemData& data );public: enum { TREE_CTRL_ICON_FILE = 0, TREE_CTRL_ICON_FILE_SELECTED, TREE_CTRL_ICON_FOLDER, TREE_CTRL_ICON_FOLDER_SELECTED, TREE_CTRL_ICON_FOLDER_OPENED, TREE_CTRL_ICON_FOLDER_OPENED_SELECTED }; MyTreeCtrl() { } MyTreeCtrl(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style); virtual ~MyTreeCtrl(); void createImageList(int size = 16); bool getBoundingSize(wxSize &size); bool traverseTree(ExamineFunc f); bool traverseTreeRecursively(const wxTreeItemId& idParent, long cookie, ExamineFunc f);private: int m_imageSize; // current size of images};// ----------------------------------------------------------------------------// constants// ----------------------------------------------------------------------------enum{ BUTTON_SELECT = wxID_OK, BUTTON_CANCEL = wxID_CANCEL, TREECTRL_TESTS = wxID_HIGHEST};enum{// FIXME: arbitrarily picked VGA dimensions;// see getBoundingSize() and addTestsToTree() MAX_TREE_WIDTH = 640, MAX_TREE_HEIGHT = 480};// ----------------------------------------------------------------------------// event tables and other macros for wxWidgets// ----------------------------------------------------------------------------BEGIN_EVENT_TABLE(MyTreeCtrl, wxTreeCtrl)END_EVENT_TABLE()BEGIN_EVENT_TABLE(TestBrowserDialog, wxDialog) EVT_TREE_SEL_CHANGED(TREECTRL_TESTS, TestBrowserDialog::OnItemSelected) EVT_TREE_ITEM_ACTIVATED(TREECTRL_TESTS, TestBrowserDialog::OnItemActivated) EVT_TREE_KEY_DOWN(TREECTRL_TESTS, TestBrowserDialog::OnKeyDown)END_EVENT_TABLE()// ============================================================================// implementation// ============================================================================// ----------------------------------------------------------------------------// utility functions// ----------------------------------------------------------------------------static bool isSuite( CPPUNIT_NS::Test *test ){ return ( test->getChildTestCount() > 0 || // suite with test test->countTestCases() == 0 ); // empty suite}// ----------------------------------------------------------------------------// the tree control// ----------------------------------------------------------------------------MyTreeCtrl::MyTreeCtrl(wxWindow *parent, const wxWindowID id, const wxPoint& pos, const wxSize& size, long style) : wxTreeCtrl(parent, id, pos, size, style){ createImageList();}MyTreeCtrl::~MyTreeCtrl(){}void MyTreeCtrl::createImageList(int size){ wxBusyCursor wait; if ( size == -1 ) { SetImageList(NULL); return; } if ( size == 0 ) size = m_imageSize; else m_imageSize = size; // Make an image list containing small icons wxImageList *images = new wxImageList(size, size, TRUE); // should correspond to TREE_CTRL_ICON_xxx enum wxIcon icons[6]; icons[TREE_CTRL_ICON_FILE] = wxIcon(icon1_xpm); icons[TREE_CTRL_ICON_FILE_SELECTED] = wxIcon(icon2_xpm); icons[TREE_CTRL_ICON_FOLDER] = wxIcon(icon3_xpm); icons[TREE_CTRL_ICON_FOLDER_SELECTED] = wxIcon(icon4_xpm); icons[TREE_CTRL_ICON_FOLDER_OPENED] = wxIcon(icon5_xpm); icons[TREE_CTRL_ICON_FOLDER_OPENED_SELECTED] = wxIcon(icon6_xpm); int sizeOrig = icons[0].GetWidth(); for ( size_t i = 0; i < WXSIZEOF(icons); i++ ) { if ( size == sizeOrig ) { images->Add(icons[i]); } else { images->Add(wxBitmap(wxBitmap(icons[i]).ConvertToImage().Rescale(size, size))); } } AssignImageList(images);}bool MyTreeCtrl::getBoundingSize(wxSize& size){// Why? Because:// - wxWindow.GetBestSize() doesn't work here// - wxTreeCtrl.GetBoundingRect() is limited to a single node wxTreeItemId rootTid = GetRootItem(); wxRect rect; if (!GetBoundingRect( rootTid, rect, false )) return false; // add one to include the root itself size_t count = 1 + GetChildrenCount( rootTid, true ); // add one to account for vertical spacing between nodes size.SetHeight( count * (rect.GetHeight() + 1) );// FIXME: computing the width of the largest bounding rectangle is harder,// i.e., need to account for depth (indentation), image size, lines,// and that a parent node might be wider than a descendant size.SetWidth( 500 ); return true;}// TODO: create a friend iteratorbool MyTreeCtrl::traverseTree(ExamineFunc f){ wxTreeItemId rootTid = GetRootItem(); if (f && !(*f)( rootTid, *(MyTreeItemData *)GetItemData( rootTid ) )) return false; return traverseTreeRecursively( rootTid, -1, f );}bool MyTreeCtrl::traverseTreeRecursively(const wxTreeItemId& idParent, long cookie, ExamineFunc f){ bool shouldContinue = true; wxTreeItemId id; do { // walk through siblings if ( cookie == -1 ) id = GetFirstChild(idParent, cookie); else id = GetNextChild(idParent, cookie); // leaf if (id <= 0) break; // examine tree item (data) if (f) shouldContinue = (*f)( id, *(MyTreeItemData *)GetItemData( id ) ); if (shouldContinue && ItemHasChildren(id)) shouldContinue = traverseTreeRecursively(id, -1, f); } while (shouldContinue); return shouldContinue;}// ----------------------------------------------------------------------------// the dialog window// ----------------------------------------------------------------------------TestBrowserDialog::TestBrowserDialog( wxWindow *parent, CPPUNIT_NS::Test *test ) : wxDialog(parent, -1, wxString(_T("Test Hierarchy")), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ), m_rootTest( test ), m_selectedTest( 0 ){ wxBusyCursor wait; initializeLayout(); addTestsToTree();}TestBrowserDialog::~TestBrowserDialog(){}void TestBrowserDialog::OnItemSelected(wxTreeEvent& event){ wxTreeItemId tid = event.GetItem(); MyTreeItemData *item = (MyTreeItemData *) m_treeTests->GetItemData(tid); if (item) m_selectedTest = item->getTest(); else m_selectedTest = 0;}void TestBrowserDialog::OnItemActivated(wxTreeEvent& event){ OnItemSelected(event); // double-clicked on a leaf node (i.e., test fixture) if (m_selectedTest && !isSuite(m_selectedTest)) EndModal( wxID_OK );}void TestBrowserDialog::OnKeyDown(wxTreeEvent& event){ wxKeyEvent keyEvent = event.GetKeyEvent(); long keycode = keyEvent.GetKeyCode(); if ( keycode == WXK_RETURN ) { if (m_selectedTest) { EndModal( wxID_OK ); return; } } event.Skip();}void TestBrowserDialog::initializeLayout(){ // create controls wxBoxSizer *topSizer = new wxBoxSizer( wxHORIZONTAL ); m_treeTests = new MyTreeCtrl(this, TREECTRL_TESTS, wxDefaultPosition, wxDefaultSize, wxTR_DEFAULT_STYLE ); wxBoxSizer *vSizer = new wxBoxSizer( wxVERTICAL ); wxButton *m_btnOk = new wxButton( this, BUTTON_SELECT, _("&Select") ); m_btnOk->SetDefault(); wxButton *m_btnCancel = new wxButton( this, BUTTON_CANCEL, _("&Close") ); // layout controls SetSizer( topSizer ); topSizer->Add( m_treeTests, 1, wxGROW | wxALL, 5 ); vSizer->Add( m_btnOk, 0, wxALL, 5 ); vSizer->Add( m_btnCancel, 0, wxALL, 5 ); topSizer->Add( vSizer ); topSizer->SetSizeHints( this ); topSizer->Fit( this );}void TestBrowserDialog::addTestsToTree(){ wxTreeItemId rootTid; rootTid = addTestTo( m_rootTest, rootTid ); wxSize size; if (m_treeTests->getBoundingSize(size)) {// FIXME: use screen boundaries taking into account the// window's own ornamentation (e.g., title bar, controls, etc.) if (size.GetHeight() > MAX_TREE_HEIGHT) size.SetHeight(MAX_TREE_HEIGHT); if (size.GetWidth() > MAX_TREE_WIDTH) size.SetWidth(MAX_TREE_WIDTH); } GetSizer()->SetMinSize( size ); GetSizer()->Fit( this ); CentreOnParent();}void TestBrowserDialog::deleteTestsFromTree(){ m_treeTests->DeleteAllItems();}wxTreeItemId TestBrowserDialog::addTestTo( CPPUNIT_NS::Test *test, wxTreeItemId& parentTid ){ wxTreeItemId tid; if (test) { int testType = isSuite( test ) ? MyTreeCtrl::TREE_CTRL_ICON_FOLDER : MyTreeCtrl::TREE_CTRL_ICON_FILE; tid = m_treeTests->AppendItem( parentTid, test->getName().c_str(), testType, testType+1, new MyTreeItemData( test )); if (test->getChildTestCount() > 0) { m_treeTests->SetItemImage(tid, MyTreeCtrl::TREE_CTRL_ICON_FOLDER_OPENED, wxTreeItemIcon_Expanded); m_treeTests->SetItemImage(tid, MyTreeCtrl::TREE_CTRL_ICON_FOLDER_OPENED_SELECTED, wxTreeItemIcon_SelectedExpanded); addTestSuiteChildrenTo( test, tid ); m_treeTests->Expand( tid ); } } return tid;}void TestBrowserDialog::addTestSuiteChildrenTo( CPPUNIT_NS::Test *suite, wxTreeItemId& tidSuite ){ for (int childIndex = 0; childIndex < suite->getChildTestCount(); ++childIndex) { addTestTo( suite->getChildTestAt( childIndex ), tidSuite ); }}void TestBrowserDialog::goSelectTest( CPPUNIT_NS::Test *test ){ wxTreeItemId tid; if (findTest( test, tid )) { m_treeTests->ScrollTo( tid ); m_treeTests->SelectItem( tid ); }}void TestBrowserDialog::setRootTest( CPPUNIT_NS::Test *test ){ wxBusyCursor wait; deleteTestsFromTree(); m_rootTest = test; addTestsToTree();}static CPPUNIT_NS::Test *s_searchTest;static wxTreeItemId s_foundTid;bool matchSearch( const wxTreeItemId& tid, const MyTreeItemData& data ){ if (s_searchTest == data.getTest()) { s_foundTid = tid; return false; } // continue searching return true;}bool TestBrowserDialog::findTest( CPPUNIT_NS::Test *test, wxTreeItemId& foundTid ) const{ bool rc; s_searchTest = test; s_foundTid = 0L; m_treeTests->traverseTree( &matchSearch ); if ((rc = (s_foundTid > 0)) != false) foundTid = s_foundTid; return rc;}CPPUNIT_NS::Test *TestBrowserDialog::getSelectedTest() const{ return m_selectedTest;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -