diff options
Diffstat (limited to 'Source/WXDialog/CMakeSetupFrame.cpp')
-rw-r--r-- | Source/WXDialog/CMakeSetupFrame.cpp | 1775 |
1 files changed, 1775 insertions, 0 deletions
diff --git a/Source/WXDialog/CMakeSetupFrame.cpp b/Source/WXDialog/CMakeSetupFrame.cpp new file mode 100644 index 0000000..c4072ca --- /dev/null +++ b/Source/WXDialog/CMakeSetupFrame.cpp @@ -0,0 +1,1775 @@ +/*========================================================================= + + Program: WXDialog - wxWidgets X-platform GUI Front-End for CMake + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Author: Jorgen Bodde + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#if defined(__GNUG__) && !defined(__APPLE__) +#pragma implementation "CMakeSetupFrame.h" +#endif + +// For compilers that support precompilation, includes "wx/wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include "wx/wx.h" +#endif + +////@begin includes +////@end includes + +#include <wx/dirdlg.h> +#include <wx/msgdlg.h> +#include <wx/filename.h> + +#include "CMakeSetupFrame.h" +#include "PropertyList.h" +#include "app_resources.h" +#include "CMakeIcon.xpm" +#include "aboutdlg.h" + +// cmake includes +#include "../cmListFileCache.h" +#include "../cmCacheManager.h" +#include "../cmGlobalGenerator.h" +#include "../cmDynamicLoader.h" + +////@begin XPM images +////@end XPM images + +/*! + * CMakeSetupFrm type definition + */ + +IMPLEMENT_CLASS( CMakeSetupFrm, wxFrame ) + +/*! + * CMakeSetupFrm event table definition + */ + +BEGIN_EVENT_TABLE( CMakeSetupFrm, wxFrame ) + +////@begin CMakeSetupFrm event table entries + EVT_CLOSE( CMakeSetupFrm::OnCloseWindow ) + + EVT_SPLITTER_SASH_POS_CHANGING( ID_SPLITTERWINDOW, CMakeSetupFrm::OnSplitterPosChanging ) + EVT_SPLITTER_DCLICK( ID_SPLITTERWINDOW, CMakeSetupFrm::OnSplitterwindowSashDClick ) + + EVT_BUTTON( ID_BROWSE_PROJECT, CMakeSetupFrm::OnButtonBrowseProject ) + + EVT_TEXT( ID_SOURCE_BUILD_PATH, CMakeSetupFrm::OnSourceBuildPathUpdated ) + EVT_TEXT_ENTER( ID_SOURCE_BUILD_PATH, CMakeSetupFrm::OnSourceBuildPathEnter ) + + EVT_BUTTON( ID_BROWSE_BUILD, CMakeSetupFrm::OnButtonBrowseBuild ) + + EVT_COMBOBOX( ID_SEARCHQUERY, CMakeSetupFrm::OnSearchquerySelected ) + EVT_TEXT( ID_SEARCHQUERY, CMakeSetupFrm::OnSearchqueryUpdated ) + + EVT_CHECKBOX( ID_SHOW_ADVANCED, CMakeSetupFrm::OnShowAdvancedValues ) + + EVT_GRID_CELL_CHANGE( CMakeSetupFrm::OnCellChange ) + EVT_GRID_SELECT_CELL( CMakeSetupFrm::OnGridSelectCell ) + EVT_MOTION( CMakeSetupFrm::OnPropertyMotion ) + + EVT_BUTTON( ID_DO_CONFIGURE, CMakeSetupFrm::OnButtonConfigure ) + + EVT_BUTTON( ID_DO_OK, CMakeSetupFrm::OnButtonOk ) + + EVT_BUTTON( ID_DO_CANCEL, CMakeSetupFrm::OnButtonCancel ) + + EVT_BUTTON( ID_DO_DELETE_CACHE, CMakeSetupFrm::OnButtonDeleteCache ) + + EVT_BUTTON( ID_CLEAR_LOG, CMakeSetupFrm::OnClearLogClick ) + + EVT_BUTTON( ID_BROWSE_GRID, CMakeSetupFrm::OnBrowseGridClick ) + + EVT_MENU( ID_MENU_RELOAD_CACHE, CMakeSetupFrm::OnMenuReloadCacheClick ) + + EVT_MENU( ID_MENU_DELETE_CACHE, CMakeSetupFrm::OnMenuDeleteCacheClick ) + + EVT_MENU( ID_MENU_QUIT, CMakeSetupFrm::OnMenuQuitClick ) + + EVT_MENU( ID_MENU_CONFIGURE, CMakeSetupFrm::OnMenuConfigureClick ) + + EVT_MENU( ID_MENU_EXITGENERATE, CMakeSetupFrm::OnMenuGenerateClick ) + + EVT_MENU( ID_MENU_TOGGLE_ADVANCED, CMakeSetupFrm::OnMenuToggleAdvancedClick ) + + EVT_MENU( ID_CMAKE_OPTIONS, CMakeSetupFrm::OnOptionsClick ) + + EVT_MENU( ID_ABOUTDLG, CMakeSetupFrm::OnAboutClick ) + +////@end CMakeSetupFrm event table entries + + EVT_MENU_RANGE(CM_RECENT_BUILD_ITEM, CM_RECENT_BUILD_ITEM + CM_MAX_RECENT_PATHS, CMakeSetupFrm::OnRecentFileMenu) + + EVT_TEXT_ENTER(ID_SEARCHQUERY, CMakeSetupFrm::OnAddQuery ) + +END_EVENT_TABLE() + +/** Callback function for CMake generator, to tell user how + far the generation actually is */ +void updateProgress(const char *msg, float prog, void *cd) +{ + // TODO: Make some kind of progress counter + + CMakeSetupFrm *fm = (CMakeSetupFrm *)cd; + + if(fm) + { + if(prog < 0) + fm->LogMessage(0, msg); + else + { + fm->UpdateProgress(prog); + fm->IssueUpdate(); + } + } +} + +/** Callback function for CMake generator, to tell user about stuff. This should be + logged in the m_log window */ +void MFCMessageCallback(const char* m, const char* title, bool& nomore, void *clientdata) +{ + CMakeSetupFrm *fm = (CMakeSetupFrm *)clientdata; + + if(fm) + { + wxString what = m, msg; + if(what.StartsWith("CMake Error: ")) + fm->LogMessage(-1, m); + else + fm->LogMessage(1, m); + } +} + +// Convert to Win32 path (slashes). This calls the system tools one and then +// removes the spaces. It is not in system tools because we don't want any +// generators accidentally use it +std::string ConvertToWindowsPath(const char* path) +{ + // Convert to output path. + // Remove the "" around it (if any) since it's an output path for + // the shell. If another shell-oriented feature is not designed + // for a GUI use, then we are in trouble. + // save the value of the force to unix path option + bool saveForce = cmSystemTools::GetForceUnixPaths(); + // make sure we get windows paths no matter what for the GUI + cmSystemTools::SetForceUnixPaths(false); + std::string s = cmSystemTools::ConvertToOutputPath(path); + // now restore the force unix path to its previous value + cmSystemTools::SetForceUnixPaths(saveForce); + if (s.size()) + { + std::string::iterator i = s.begin(); + if (*i == '\"') + { + s.erase(i, i + 1); + } + i = s.begin() + s.length() - 1; + if (*i == '\"') + { + s.erase(i, i + 1); + } + } + return s; +} + + +bool DnDFile::OnDropFiles(wxCoord, wxCoord, const wxArrayString& filenames) +{ + size_t nFiles = filenames.GetCount(); + + // only one item allowed + if(nFiles > 1) + return false; + + if(nFiles == 1) + { + // only one dir allowed + if(!wxDirExists(filenames[0])) + return false; + + // strip the seperator + wxFileName name; + name.AssignDir(filenames[0]); + + // issue a 'drop' by changing text ctrl + m_pOwner->SetValue(name.GetFullPath()); + + return true; + } + + return false; +} + +/*! + * CMakeSetupFrm constructors + */ + +CMakeSetupFrm::CMakeSetupFrm( ) + : m_cmake(0) +{ +} + +CMakeSetupFrm::CMakeSetupFrm( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) + : m_cmake(0) +{ + Create( parent, id, caption, pos, size, style ); +} + +/*! + * CMakeSetupFrm creator + */ + +bool CMakeSetupFrm::Create( wxWindow* parent, wxWindowID id, const wxString& caption, const wxPoint& pos, const wxSize& size, long style ) +{ +////@begin CMakeSetupFrm member initialisation + m_splitter = NULL; + m_cmProjectPath = NULL; + m_BrowseProjectPathButton = NULL; + m_cmBuildPath = NULL; + m_BrowseSourcePathButton = NULL; + m_cmGeneratorChoice = NULL; + m_cmSearchQuery = NULL; + m_cmShowAdvanced = NULL; + m_cmOptions = NULL; + m_cmLog = NULL; + m_cmDescription = NULL; + m_ConfigureButton = NULL; + m_OkButton = NULL; + m_CancelButton = NULL; + m_DeleteCacheButton = NULL; + m_ClearLogButton = NULL; + m_cmBrowseCell = NULL; +////@end CMakeSetupFrm member initialisation + + wxFrame::Create( parent, id, caption, pos, size, style ); + + // make sure the developer does not assign more then 100 + // would be rediculous but also overlap other id's + wxASSERT(CM_MAX_RECENT_PATHS < 100); + + m_ExitTimer = 0; + + m_progressDlg = 0; + m_noRefresh = false; + m_quitAfterGenerating = false; + + m_config = new wxConfig("CMakeSetup"); + + wxIcon icon(CMakeIcon_xpm); + SetIcon(icon); + + CreateControls(); + + //SetIcon(GetIconResource(wxT("cmake_icon.xpm"))); + //SetIcon(wxIcon("NGDialog.ico", wxBITMAP_TYPE_ICO_RESOURCE)); + Centre(); + + // is it needed to hide console? + m_RunningConfigure = false; + cmSystemTools::SetRunCommandHideConsole(true); + cmSystemTools::SetErrorCallback(MFCMessageCallback, (void *)this); + + // create our cmake instance + m_cmake = new cmake; + m_cmake->SetProgressCallback(updateProgress, (void *)this); + + return TRUE; +} + +CMakeSetupFrm::~CMakeSetupFrm() +{ + wxString str; + + // write configs back to disk + m_config->Write(CM_LASTPROJECT_PATH, m_cmProjectPath->GetValue()); + m_config->Write(CM_LASTBUILD_PATH, m_cmBuildPath->GetValue()); + + // clear the config first + for(size_t i = 0 ; i < CM_MAX_RECENT_PATHS; i++) + { + str.Printf("%s%i", _(CM_RECENT_BUILD_PATH), i); + m_config->Write(str, _("")); + } + + // write the last CM_MAX_RECENT_PATHS items back to config + int i = (m_recentPaths.Count() >= CM_MAX_RECENT_PATHS ? CM_MAX_RECENT_PATHS : m_recentPaths.Count()); + while(i > 0) + { + str.Printf("%s%i", _(CM_RECENT_BUILD_PATH), i); + m_config->Write(str, m_recentPaths[i - 1]); + i--; + } + + // write recent query list to config + for(int j = 0; j < m_cmSearchQuery->GetCount(); j++) + { + // allow max to be written + if(j < CM_MAX_SEARCH_QUERIES) + { + str.Printf("%s%i", _(CM_SEARCH_QUERY), j); + m_config->Write(str, m_cmSearchQuery->GetString(j)); + } + else + break; + } + + // set window pos + size in settings + if(!IsIconized() && !IsMaximized()) + { + int xsize, ysize; + GetSize(&xsize, &ysize); + if(xsize > 0 && ysize > 0) + { + m_config->Write(CM_XSIZE, (long)xsize); + m_config->Write(CM_YSIZE, (long)ysize); + } + + if(m_splitter->GetSashPosition() > 0) + m_config->Write(CM_SPLITTERPOS, (long)m_splitter->GetSashPosition()); + + GetPosition(&xsize, &ysize); + if(xsize != 0 && ysize != 0) + { + m_config->Write(CM_XPOS, (long)xsize); + m_config->Write(CM_YPOS, (long)ysize); + } + } + + // write changes (will be done before deletion) + delete m_config; + + // delete timer + if(m_ExitTimer) + delete m_ExitTimer; + + // delete our cmake instance again + if(m_cmake) + delete m_cmake; +} + +void CMakeSetupFrm::UpdateWindowState() +{ + bool dogenerate = !m_RunningConfigure && !m_cmOptions->IsCacheDirty() && + (m_cmOptions->GetCount() != 0); + + // when configure is running, disable a lot of stuff + m_cmProjectPath->Enable(!m_RunningConfigure); + m_BrowseProjectPathButton->Enable(!m_RunningConfigure); + m_cmBuildPath->Enable(!m_RunningConfigure); + m_BrowseSourcePathButton->Enable(!m_RunningConfigure); + m_cmGeneratorChoice->Enable(!m_RunningConfigure); + m_cmShowAdvanced->Enable(!m_RunningConfigure); + m_cmOptions->Enable(!m_RunningConfigure); + m_ConfigureButton->Enable(!m_RunningConfigure); + m_OkButton->Enable(dogenerate); + m_CancelButton->Enable(m_RunningConfigure); + m_DeleteCacheButton->Enable(!m_RunningConfigure); + m_ClearLogButton->Enable(!m_RunningConfigure); + if(m_RunningConfigure) + m_cmBrowseCell->Enable(false); + + // when cache loaded (items available show other control) + m_cmGeneratorChoice->Enable(m_cmOptions->GetCount() == 0 && !m_RunningConfigure); + m_cmSearchQuery->Enable(!m_RunningConfigure); + m_cmBrowseCell->Enable(!m_RunningConfigure && m_cmOptions->IsSelectedItemBrowsable()); + + // disable the menus when configuring + if(GetMenuBar()) + { + // disable configure button when there is nothing, and generate and exit + // only when it is allowed to generate + GetMenuBar()->Enable(ID_MENU_EXITGENERATE, dogenerate); + GetMenuBar()->Enable(ID_MENU_CONFIGURE, !m_RunningConfigure); + + for(size_t i = 0; i < GetMenuBar()->GetMenuCount(); i++) + GetMenuBar()->EnableTop(i, !m_RunningConfigure); + } +} + +void CMakeSetupFrm::LogMessage(int logkind, const char *msg) +{ + // put CR first but prevent a CR at the end +#ifndef __LINUX__ + if(m_cmLog->IsModified()) + (*m_cmLog) << wxT("\n"); +#else + // Linux requires a different approach + if(!m_cmLog->GetValue().IsEmpty()) + (*m_cmLog) << wxT("\n"); +#endif + + // log error, warning, or message + wxTextAttr defattr = m_cmLog->GetDefaultStyle(); + + switch(logkind) + { + // user message + case 1: + { + wxTextAttr colattr(*wxBLUE); + m_cmLog->SetDefaultStyle(colattr); + (*m_cmLog) << msg; + m_cmLog->SetDefaultStyle(defattr); + } + break; + + // progress + case 0: + (*m_cmLog) << msg; + break; + + // error + case -1: + { + wxTextAttr colattr(*wxRED); + m_cmLog->SetDefaultStyle(colattr); + (*m_cmLog) << msg; + m_cmLog->SetDefaultStyle(defattr); + } + break; + } + + IssueUpdate(); +} + +void CMakeSetupFrm::IssueUpdate() +{ + //::wxSafeYield(m_CancelButton, true); + ::wxYield(); + + // when we pressed cancel on the progress dialog + // stop all activities + if(m_progressDlg) + { + if(m_progressDlg->CancelPressed() && !m_progressDlg->IsCancelling()) + { + m_progressDlg->CancelAcknowledged(); + + // send a button event to cancel the progress + wxCommandEvent event( wxEVT_COMMAND_BUTTON_CLICKED, ID_DO_CANCEL); + wxPostEvent(this, event); + } + } +} + +/*! + * Control creation for CMakeSetupFrm + */ + +void CMakeSetupFrm::CreateControls() +{ +////@begin CMakeSetupFrm content construction + CMakeSetupFrm* itemFrame1 = this; + + wxMenuBar* menuBar = new wxMenuBar; + wxMenu* itemMenu37 = new wxMenu; + itemMenu37->Append(ID_MENU_RELOAD_CACHE, _("&Reload Cache\tCtrl+R"), _("Reload the cache from disk"), wxITEM_NORMAL); + itemMenu37->Append(ID_MENU_DELETE_CACHE, _("&Delete Cache\tCtrl+D"), _("Delete the cache on disk of the current path"), wxITEM_NORMAL); + itemMenu37->AppendSeparator(); + itemMenu37->Append(ID_MENU_QUIT, _("E&xit\tAlt+F4"), _("Quit CMake Setup"), wxITEM_NORMAL); + menuBar->Append(itemMenu37, _("&File")); + wxMenu* itemMenu42 = new wxMenu; + itemMenu42->Append(ID_MENU_CONFIGURE, _("&Configure\tCtrl+N"), _T(""), wxITEM_NORMAL); + itemMenu42->Append(ID_MENU_EXITGENERATE, _("&Generate and Exit\tCtrl+G"), _T(""), wxITEM_NORMAL); + itemMenu42->Append(ID_MENU_TOGGLE_ADVANCED, _("Toggle &Advanced\tCtrl+A"), _T(""), wxITEM_NORMAL); + itemMenu42->AppendSeparator(); + itemMenu42->Append(ID_CMAKE_OPTIONS, _("&Options\tCtrl+O"), _T(""), wxITEM_NORMAL); + menuBar->Append(itemMenu42, _("&Tools")); + wxMenu* itemMenu48 = new wxMenu; + itemMenu48->Append(ID_ABOUTDLG, _("&About ..."), _("Shows the about dialog ..."), wxITEM_NORMAL); + menuBar->Append(itemMenu48, _("&Help")); + itemFrame1->SetMenuBar(menuBar); + + m_splitter = new wxSplitterWindow( itemFrame1, ID_SPLITTERWINDOW, wxDefaultPosition, wxSize(100, 100), wxSP_3DBORDER|wxSP_3DSASH|wxNO_BORDER ); + + wxPanel* itemPanel3 = new wxPanel( m_splitter, ID_MAINPANEL, wxDefaultPosition, wxSize(600, 400), wxNO_BORDER|wxTAB_TRAVERSAL ); + itemPanel3->SetExtraStyle(itemPanel3->GetExtraStyle()|wxWS_EX_VALIDATE_RECURSIVELY); + wxBoxSizer* itemBoxSizer4 = new wxBoxSizer(wxVERTICAL); + itemPanel3->SetSizer(itemBoxSizer4); + + wxBoxSizer* itemBoxSizer5 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer4->Add(itemBoxSizer5, 0, wxGROW|wxTOP|wxBOTTOM, 5); + wxFlexGridSizer* itemFlexGridSizer6 = new wxFlexGridSizer(2, 3, 0, 0); + itemFlexGridSizer6->AddGrowableRow(1); + itemFlexGridSizer6->AddGrowableCol(1); + itemBoxSizer5->Add(itemFlexGridSizer6, 1, wxALIGN_TOP|wxLEFT, 5); + wxStaticText* itemStaticText7 = new wxStaticText( itemPanel3, wxID_STATIC, _("CMake project path"), wxDefaultPosition, wxDefaultSize, 0 ); + itemFlexGridSizer6->Add(itemStaticText7, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxADJUST_MINSIZE, 5); + + m_cmProjectPath = new wxTextCtrl( itemPanel3, ID_PROJECT_PATH, _T(""), wxDefaultPosition, wxSize(50, -1), 0 ); + itemFlexGridSizer6->Add(m_cmProjectPath, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxTOP|wxBOTTOM, 5); + + m_BrowseProjectPathButton = new wxButton( itemPanel3, ID_BROWSE_PROJECT, _("Browse"), wxDefaultPosition, wxSize(55, -1), 0 ); + itemFlexGridSizer6->Add(m_BrowseProjectPathButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxStaticText* itemStaticText10 = new wxStaticText( itemPanel3, wxID_STATIC, _("Project build path"), wxDefaultPosition, wxDefaultSize, 0 ); + itemFlexGridSizer6->Add(itemStaticText10, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxLEFT|wxRIGHT|wxADJUST_MINSIZE, 5); + + m_cmBuildPath = new wxTextCtrl( itemPanel3, ID_SOURCE_BUILD_PATH, _T(""), wxDefaultPosition, wxSize(50, -1), 0 ); + itemFlexGridSizer6->Add(m_cmBuildPath, 1, wxGROW|wxALIGN_TOP|wxTOP|wxBOTTOM, 5); + + m_BrowseSourcePathButton = new wxButton( itemPanel3, ID_BROWSE_BUILD, _("Browse"), wxDefaultPosition, wxSize(55, -1), 0 ); + itemFlexGridSizer6->Add(m_BrowseSourcePathButton, 0, wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL|wxALL, 5); + + wxBoxSizer* itemBoxSizer13 = new wxBoxSizer(wxVERTICAL); + itemBoxSizer5->Add(itemBoxSizer13, 0, wxGROW|wxLEFT|wxRIGHT, 5); + wxFlexGridSizer* itemFlexGridSizer14 = new wxFlexGridSizer(2, 2, 0, 0); + itemBoxSizer13->Add(itemFlexGridSizer14, 0, wxALIGN_CENTER_HORIZONTAL|wxLEFT|wxRIGHT, 5); + wxStaticText* itemStaticText15 = new wxStaticText( itemPanel3, wxID_STATIC, _("Generate"), wxDefaultPosition, wxDefaultSize, 0 ); + itemFlexGridSizer14->Add(itemStaticText15, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxADJUST_MINSIZE, 5); + + wxString* m_cmGeneratorChoiceStrings = NULL; + m_cmGeneratorChoice = new wxComboBox( itemPanel3, ID_CHOOSE_GENERATOR, _T(""), wxDefaultPosition, wxSize(170, -1), 0, m_cmGeneratorChoiceStrings, wxCB_READONLY ); + itemFlexGridSizer14->Add(m_cmGeneratorChoice, 1, wxALIGN_CENTER_HORIZONTAL|wxGROW|wxTOP|wxBOTTOM, 5); + + wxStaticText* itemStaticText17 = new wxStaticText( itemPanel3, wxID_STATIC, _("Search"), wxDefaultPosition, wxDefaultSize, 0 ); + itemFlexGridSizer14->Add(itemStaticText17, 0, wxALIGN_LEFT|wxALIGN_CENTER_VERTICAL|wxRIGHT|wxADJUST_MINSIZE, 5); + + wxString* m_cmSearchQueryStrings = NULL; + m_cmSearchQuery = new wxComboBox( itemPanel3, ID_SEARCHQUERY, _T(""), wxDefaultPosition, wxSize(170, -1), 0, m_cmSearchQueryStrings, wxWANTS_CHARS ); + itemFlexGridSizer14->Add(m_cmSearchQuery, 1, wxALIGN_CENTER_HORIZONTAL|wxGROW|wxTOP|wxBOTTOM, 5); + + m_cmShowAdvanced = new wxCheckBox( itemPanel3, ID_SHOW_ADVANCED, _("Show advanced values"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE ); + m_cmShowAdvanced->SetValue(FALSE); + itemBoxSizer13->Add(m_cmShowAdvanced, 0, wxALIGN_RIGHT|wxLEFT|wxRIGHT, 5); + + m_cmOptions = new wxPropertyList( itemPanel3, ID_OPTIONS, wxDefaultPosition, wxSize(200, 150), wxSTATIC_BORDER|wxWANTS_CHARS|wxVSCROLL ); + m_cmOptions->SetDefaultColSize(250); + m_cmOptions->SetDefaultRowSize(25); + m_cmOptions->SetColLabelSize(20); + m_cmOptions->SetRowLabelSize(0); + m_cmOptions->CreateGrid(10, 2, wxGrid::wxGridSelectRows); + itemBoxSizer4->Add(m_cmOptions, 1, wxGROW|wxALL, 5); + + wxPanel* itemPanel21 = new wxPanel( m_splitter, ID_LOGPANEL, wxDefaultPosition, wxSize(-1, 100), wxNO_BORDER|wxTAB_TRAVERSAL ); + wxBoxSizer* itemBoxSizer22 = new wxBoxSizer(wxVERTICAL); + itemPanel21->SetSizer(itemBoxSizer22); + + wxBoxSizer* itemBoxSizer23 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer22->Add(itemBoxSizer23, 1, wxGROW|wxLEFT|wxRIGHT|wxTOP, 5); + m_cmLog = new wxTextCtrl( itemPanel21, ID_LOG_AREA, _("Select your project path (where CMakeLists.txt is) and then select the build path (where the projects should be saved), or select a previous build path.\n\nRight click on a cache value for additional options (delete and ignore). Press configure to update and display new values in red, press OK to generate the projects and exit."), wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH2|wxSTATIC_BORDER ); + itemBoxSizer23->Add(m_cmLog, 1, wxGROW|wxRIGHT, 5); + + m_cmDescription = new wxTextCtrl( itemPanel21, ID_DESCRIPTION, _T(""), wxDefaultPosition, wxSize(200, -1), wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH2|wxSTATIC_BORDER ); + itemBoxSizer23->Add(m_cmDescription, 0, wxGROW|wxLEFT, 5); + + wxBoxSizer* itemBoxSizer26 = new wxBoxSizer(wxHORIZONTAL); + itemBoxSizer22->Add(itemBoxSizer26, 0, wxALIGN_CENTER_HORIZONTAL|wxALL, 5); + m_ConfigureButton = new wxButton( itemPanel21, ID_DO_CONFIGURE, _("Co&nfigure"), wxDefaultPosition, wxDefaultSize, 0 ); + m_ConfigureButton->SetDefault(); + itemBoxSizer26->Add(m_ConfigureButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_OkButton = new wxButton( itemPanel21, ID_DO_OK, _("&Generate!"), wxDefaultPosition, wxDefaultSize, 0 ); + itemBoxSizer26->Add(m_OkButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_CancelButton = new wxButton( itemPanel21, ID_DO_CANCEL, _("C&ancel"), wxDefaultPosition, wxDefaultSize, 0 ); + itemBoxSizer26->Add(m_CancelButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + +#if defined(__WXMSW__) + wxStaticLine* itemStaticLine30 = new wxStaticLine( itemPanel21, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer26->Add(itemStaticLine30, 0, wxGROW|wxALL, 5); +#endif + + m_DeleteCacheButton = new wxButton( itemPanel21, ID_DO_DELETE_CACHE, _("&Delete Cache"), wxDefaultPosition, wxDefaultSize, 0 ); + itemBoxSizer26->Add(m_DeleteCacheButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_ClearLogButton = new wxButton( itemPanel21, ID_CLEAR_LOG, _("Clear &Log"), wxDefaultPosition, wxDefaultSize, 0 ); + itemBoxSizer26->Add(m_ClearLogButton, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + +#if defined(__WXMSW__) + wxStaticLine* itemStaticLine33 = new wxStaticLine( itemPanel21, wxID_STATIC, wxDefaultPosition, wxDefaultSize, wxLI_HORIZONTAL ); + itemBoxSizer26->Add(itemStaticLine33, 0, wxGROW|wxALL, 5); +#endif + + m_cmBrowseCell = new wxButton( itemPanel21, ID_BROWSE_GRID, _("&Browse"), wxDefaultPosition, wxDefaultSize, 0 ); + itemBoxSizer26->Add(m_cmBrowseCell, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5); + + m_splitter->SplitHorizontally(itemPanel3, itemPanel21, 300); + + wxStatusBar* itemStatusBar35 = new wxStatusBar( itemFrame1, ID_STATUSBAR, wxST_SIZEGRIP|wxNO_BORDER ); + itemStatusBar35->SetFieldsCount(2); + itemFrame1->SetStatusBar(itemStatusBar35); + +////@end CMakeSetupFrm content construction +} + +void CMakeSetupFrm::DoInitFrame(cmCommandLineInfo &cm, const wxString &fn) +{ + // create accelerator table for some commands + // not very useful if the focus is on an edit ctrl all the time ;-) + //wxAcceleratorEntry entries[3]; + //entries[0].Set(wxACCEL_NORMAL, (int) 'c', ID_MENU_CONFIGURE); + //entries[1].Set(wxACCEL_NORMAL, (int) 'g', ID_MENU_EXITGENERATE); + //entries[2].Set(wxACCEL_NORMAL, (int) 't', ID_MENU_TOGGLE_ADVANCED); + //wxAcceleratorTable accel(3, entries); + //SetAcceleratorTable(accel); + + // path to where cmake.exe is + // m_PathToExecutable = cm.GetPathToExecutable().c_str(); + m_PathToExecutable = fn; + + // adjust size of last bar, to display % progress + wxStatusBar *bar = GetStatusBar(); + if(bar) + { + wxASSERT(bar->GetFieldsCount() > 1); + + // fill all with -1. Why this way? because the count of the status bars + // can change. All of the widths must be accounted for and initialised + int *widths = new int[bar->GetFieldsCount()]; + for(int i = 0; i < bar->GetFieldsCount(); i++) + widths[i] = -1; + + // the % field + widths[1] = 75; + bar->SetStatusWidths(bar->GetFieldsCount(), widths); + delete widths; + } + + wxString name, generator; + std::vector<std::string> names; + + m_RunningConfigure = false; + + // set grid labels + m_cmOptions->SetColLabelValue(0, wxT("Cache Name")); + m_cmOptions->SetColLabelValue(1, wxT("Cache Value")); + m_cmOptions->SetProjectGenerated(false); + + // set drop target + m_cmOptions->SetDropTarget(new DnDFile(m_cmBuildPath)); + + m_cmake->GetRegisteredGenerators(names); + for(std::vector<std::string>::iterator i = names.begin(); i != names.end(); ++i) + { + name = i->c_str(); + m_cmGeneratorChoice->Append(name); + } + + // sync advanced option with grid + m_cmOptions->SetShowAdvanced(m_cmShowAdvanced->GetValue()); + + // if none selected, we will see if VS8, VS7 or VS6 is present + if(m_cmGeneratorChoice->GetValue().IsEmpty()) + { + std::string mp; + mp = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\8.0\\Setup;Dbghelp_path]"; + cmSystemTools::ExpandRegistryValues(mp); + if(mp != "/registry") + generator = wxT("Visual Studio 8 2005"); + else + { + mp = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.1;InstallDir]"; + cmSystemTools::ExpandRegistryValues(mp); + if (mp != "/registry") + generator = wxT("Visual Studio 7 .NET 2003"); + else + { + mp = "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\7.0;InstallDir]"; + cmSystemTools::ExpandRegistryValues(mp); + if (mp != "/registry") + generator = wxT("Visual Studio 7"); + else + generator = wxT("Visual Studio 6"); + } + } + } + + // set proper discovered generator + m_cmGeneratorChoice->SetStringSelection(generator); + + wxString str; + //str.Printf("CMake %d.%d - %s", cmake::GetMajorVersion(), cmake::GetMinorVersion(), cmake::GetReleaseVersion()); + str.Printf("CMakeSetup v%i.%i%s", CMAKEGUI_MAJORVER, CMAKEGUI_MINORVER, CMAKEGUI_ADDVER); + + SetTitle(str); + wxString path; + + // get last 5 used projects + for(size_t i = 0; i < CM_MAX_RECENT_PATHS; i++) + { + path.Printf("%s%i", _(CM_RECENT_BUILD_PATH), i); + if(m_config->Read(path, &str)) + AppendPathToRecentList(str); + } + + // get query items + for(size_t i = 0; i < CM_MAX_SEARCH_QUERIES; i++) + { + path.Printf("%s%i", _(CM_SEARCH_QUERY), i); + if(m_config->Read(path, &str)) + m_cmSearchQuery->Append(str); + } + + + // make sure the call to update grid is not executed + m_noRefresh = true; + m_cmSearchQuery->SetValue(_("")); + m_noRefresh = false; + + // Get the parameters from the command line info + // If an unknown parameter is found, try to interpret it too, since it + // is likely to be a file dropped on the shortcut :) + bool sourceDirLoaded = false, + buildDirLoaded = false; + + if(cm.m_LastUnknownParameter.empty()) + { + if(cm.m_WhereSource.size() > 0 ) + { + m_cmProjectPath->SetValue(cm.m_WhereSource.c_str()); + sourceDirLoaded = true; + } + + if (cm.m_WhereBuild.size() > 0 ) + { + m_cmBuildPath->SetValue(cm.m_WhereBuild.c_str()); + buildDirLoaded = true; + } + + m_cmShowAdvanced->SetValue(cm.m_AdvancedValues); + } + else + { + m_cmShowAdvanced->SetValue(false); + + // TODO: Interpret directory from dropped shortcut + //this->ChangeDirectoriesFromFile(cmdInfo->m_LastUnknownParameter.c_str()); + } + + if (cm.m_ExitAfterLoad) + { + int id = GetId(); + m_ExitTimer = new wxTimer(this, id); + m_ExitTimer->Start(3000); + + Connect( id, wxEVT_TIMER,(wxObjectEventFunction) &CMakeSetupFrm::OnExitTimer ); + + } + + // retrieve settings, this needs to be done here + // because writing to the m_cmBuildPath triggers a cache reload + if(!sourceDirLoaded && m_config->Read(CM_LASTPROJECT_PATH, &str)) + m_cmProjectPath->SetValue(str); + + if(!buildDirLoaded) + { + m_cmOptions->RemoveAll(); + if(m_config->Read(CM_LASTBUILD_PATH, &str)) + m_cmBuildPath->SetValue(str); + } + + // set window size from settings + long xsize, ysize, splitpos; + if(m_config->Read(CM_XSIZE, &xsize) && m_config->Read(CM_YSIZE, &ysize) && + m_config->Read(CM_SPLITTERPOS, &splitpos)) + { + SetSize(xsize, ysize); + m_splitter->SetSashPosition(splitpos); + } + + if(m_config->Read(CM_XPOS, &xsize) && m_config->Read(CM_YPOS, &ysize)) + SetSize(xsize, ysize, -1, -1, wxSIZE_USE_EXISTING); + + UpdateWindowState(); +} + +void CMakeSetupFrm::LoadCacheFromDiskToGUI() +{ + wxString builddir = m_cmBuildPath->GetValue(); + + cmCacheManager *cachem = m_cmake->GetCacheManager(); + if(cachem && !builddir.Trim().IsEmpty()) + { + if(cachem->LoadCache(builddir.c_str())) + AppendPathToRecentList(builddir); + + // represent this cache in the grid, but not before we + // wiped all of the old items + FillCacheGUIFromCacheManager(); + + // set the generator string to the one used in the cache + cmCacheManager::CacheIterator it = cachem->GetCacheIterator("CMAKE_GENERATOR"); + if(!it.IsAtEnd()) + { + wxString curGen = it.GetValue(); + m_cmGeneratorChoice->SetStringSelection(curGen); + } + } +} + +void CMakeSetupFrm::AppendPathToRecentList(const wxString &p) +{ + wxFileName path; + wxString str; + + if(p.IsEmpty()) + return; + + // cheap way to get rid of trailing seperators + path.AssignDir(p); + str = path.GetPath(); + + // append the item, or add it to end to make sure + // it is remembered between sessions + for(size_t i = 0; i < m_recentPaths.Count(); i++) + { + if(m_recentPaths[i].IsSameAs(str, false)) + { + m_recentPaths.RemoveAt(i); + + // only re-add when item is still valid + if(::wxDirExists(str)) + m_recentPaths.Add(str); + else + return; // no add when the item is not existing + + return; + } + } + + if(GetMenuBar()) + { + // get file menu + int lastUsedID = 0; + wxMenu *mnu = GetMenuBar()->GetMenu(0); + wxASSERT(mnu != 0); + + if(::wxDirExists(str)) + { + // add to array + if(m_recentPaths.Count() == 0) + mnu->AppendSeparator(); + + lastUsedID = CM_RECENT_BUILD_ITEM + m_recentPaths.Count(); + m_recentPaths.Add(str); + + // when we have more in list then we can display, prune and + // remove some menu items until we have room (and available ID's again) + if(m_recentPaths.Count() > CM_MAX_RECENT_PATHS) + { + // prune the list + while(m_recentPaths.Count() > CM_MAX_RECENT_PATHS) + m_recentPaths.RemoveAt(0); + + // now determine count, and remove until we have room + int index = mnu->GetMenuItemCount() - 1; + int count = 0; + wxASSERT(index > 0); + + wxMenuItem *item; + do + { + item = mnu->FindItemByPosition(index); + if(item) + { + if(item->IsSeparator()) + { + // next index is valid item + index ++; + break; + } + else + count ++; + } + + index --; + } + while(index >= 0 && item); + + // ok, if count > CM_MAX_RECENT_PATHS then we are going to + // delete some items on the index position + if(count >= CM_MAX_RECENT_PATHS) + { + // delete items that are exceeding + while(count >= CM_MAX_RECENT_PATHS) + { + lastUsedID = mnu->FindItemByPosition(index)->GetId(); + mnu->Delete(lastUsedID); + count --; + } + } + } + + // append item + mnu->Append(lastUsedID, str); + } + } +} + +bool CMakeSetupFrm::PerformCacheRun() +{ + bool enable = false; + cmCacheManager *cachem = m_cmake->GetCacheManager(); + cmCacheManager::CacheIterator it = cachem->NewIterator(); + + // remove all items that are no longer present + size_t j = 0; + while(j < m_cmOptions->GetCount()) + { + // check to see if it is still in the CMake cache + // if it is still in the cache then it is no longer new + wxPropertyItem *item = m_cmOptions->GetItem(j); + if ( !it.Find((const char*)item->GetPropName().c_str()) ) + m_cmOptions->RemoveProperty(item); + else + { + // ok we found it, mark as old + item->SetNewValue(false); + int row = m_cmOptions->FindProperty(item); + if(row != -1) + m_cmOptions->UpdatePropertyItem(item, row); + j++; + } + } + + if(cachem->GetSize() > 0 && !cmSystemTools::GetErrorOccuredFlag()) + { + bool enable = true; + for(size_t i = 0; i < m_cmOptions->GetCount(); i++) + { + wxPropertyItem* item = m_cmOptions->GetItem(i); + if(item->GetAdvanced()) + { + if(item->GetNewValue() && m_cmOptions->GetShowAdvanced()) + { + // if one new value then disable to OK button + enable = false; + break; + } + } + else + { + if(item->GetNewValue()) + { + // if one new value then disable to OK button + enable = false; + break; + } + } + } + } + + return enable; +} + +void CMakeSetupFrm::FillCacheGUIFromCacheManager() +{ + cmCacheManager *cachem = m_cmake->GetCacheManager(); + cmCacheManager::CacheIterator it = cachem->NewIterator(); + + // remove all items that are no longer present + size_t j = 0; + while(j < m_cmOptions->GetCount()) + { + // check to see if it is still in the CMake cache + // if it is still in the cache then it is no longer new + wxPropertyItem *item = m_cmOptions->GetItem(j); + if ( !it.Find((const char*)item->GetPropName().c_str()) ) + m_cmOptions->RemoveProperty(item); + else + j++; + } + + // if there are already entries in the cache, then + // put the new ones in the top, so they show up first + bool reverseOrder = false; + for(cmCacheManager::CacheIterator i = cachem->NewIterator(); !i.IsAtEnd(); i.Next()) + { + const char* key = i.GetName(); + + // if value has trailing space or tab, enclose it in single quotes + // to enforce the fact that it has 'invisible' trailing stuff + std::string value = i.GetValue(); + if (value.size() && (value[value.size() - 1] == ' ' || value[value.size() - 1] == '\t')) + value = '\'' + value + '\''; + + bool advanced = i.GetPropertyAsBool("ADVANCED"); + switch(i.GetType() ) + { + case cmCacheManager::BOOL: + { + wxString OnOff; + + if(cmSystemTools::IsOn(value.c_str())) + OnOff = wxT("ON"); + else + OnOff = wxT("OFF"); + + m_cmOptions->AddProperty(key, + OnOff.c_str(), + i.GetProperty("HELPSTRING"), + wxPropertyList::CHECKBOX, "ON|OFF", + reverseOrder, + advanced ); + } + break; + + case cmCacheManager::PATH: + m_cmOptions->AddProperty(key, + value.c_str(), + i.GetProperty("HELPSTRING"), + wxPropertyList::PATH,"", + reverseOrder, advanced); + break; + + case cmCacheManager::FILEPATH: + m_cmOptions->AddProperty(key, + value.c_str(), + i.GetProperty("HELPSTRING"), + wxPropertyList::FILE,"", + reverseOrder, advanced); + break; + + case cmCacheManager::STRING: + m_cmOptions->AddProperty(key, + value.c_str(), + i.GetProperty("HELPSTRING"), + wxPropertyList::EDIT,"", + reverseOrder, advanced); + break; + + case cmCacheManager::INTERNAL: + { + wxPropertyItem *pItem = m_cmOptions->FindPropertyByName(key); + if(pItem) + m_cmOptions->RemoveProperty(pItem); + } + break; + } + } +} + +void CMakeSetupFrm::OnExitTimer(wxTimerEvent &event) +{ + Close(); +} + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BROWSE_PROJECT + */ + +void CMakeSetupFrm::OnButtonBrowseProject( wxCommandEvent& event ) +{ + const wxString& dir = wxDirSelector("Select project directory", m_cmProjectPath->GetValue()); + if(!dir.IsEmpty()) + m_cmProjectPath->SetValue(dir); +} + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BROWSE_BUILD + */ + +void CMakeSetupFrm::OnButtonBrowseBuild( wxCommandEvent& event ) +{ + const wxString& dir = wxDirSelector("Select build directory", m_cmBuildPath->GetValue()); + if(!dir.IsEmpty()) + m_cmBuildPath->SetValue(dir); +} + +/*! + * wxEVT_COMMAND_CHECKBOX_CLICKED event handler for ID_SHOW_ADVANCED + */ + +void CMakeSetupFrm::OnShowAdvancedValues( wxCommandEvent& event ) +{ + if(m_cmShowAdvanced->GetValue()) + m_cmOptions->ShowAdvanced(); + else + m_cmOptions->HideAdvanced(); +} + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_DO_CONFIGURE + */ + +void CMakeSetupFrm::OnButtonConfigure( wxCommandEvent& event ) +{ + DoConfigure(); +} + +void CMakeSetupFrm::DoConfigure() +{ + // enable error messages each time configure is pressed + cmSystemTools::EnableMessages(); + m_cmOptions->HideControls(); + + cmSystemTools::ResetErrorOccuredFlag(); + + // instantiate a dialog for the progress meter + + PerformCacheRun(); + RunCMake(false); +} + +int CMakeSetupFrm::RunCMake(bool generateProjectFiles) +{ + int value = -1; + + // clear log + m_cmLog->Clear(); + m_cmLog->DiscardEdits(); + + wxString builddir = m_cmBuildPath->GetValue(), + sourcedir = m_cmProjectPath->GetValue(), + err = wxT("Error in configuration process, project files may be invalid"); + + + // sanity check for people pressing OK on empty dirs + if(builddir.Trim().IsEmpty() || sourcedir.Trim().IsEmpty()) + { + wxMessageBox(wxT("Please enter a valid source directory and build directory"), wxT("Error"), wxOK | wxICON_ERROR, this); + return -1; + } + + // check if the directory exists, if not, create it + if(!cmSystemTools::FileExists(builddir.c_str())) + { + wxString str; + str << wxT("Build directory does not exist, should I create it?\n\nDirectory: ") << builddir; + + int answer = wxMessageBox(str, wxT("Create directory"), wxYES_NO, this); + if (answer == wxYES) + { + if(!cmSystemTools::MakeDirectory(builddir.c_str())) + { + // could not create, tell and abort + wxMessageBox(wxT("Could not create directory"), wxT("Error"), wxOK | wxICON_ERROR, this); + return -1; + } + } + else + { + // we abort because the user did not want to make the directory + wxMessageBox(wxT("Build Project aborted, nothing done."), wxT("Aborted"), + wxOK | wxICON_EXCLAMATION, this); + return -1; + } + } + + /** show progress dialog that informs the user with a progress bar */ + if(m_progressDlg) + m_progressDlg->Destroy(); + + m_progressDlg = new CMProgressDialog(this); + m_progressDlg->Show(); + + // set the wait cursor + m_RunningConfigure = true; + UpdateWindowState(); + + // always save the current gui values to disk + SaveCacheFromGUI(); + + // Make sure we are working from the cache on disk + LoadCacheFromDiskToGUI(); + + // setup the cmake instance + if (generateProjectFiles) + { + if(m_cmake->Generate() != 0) + { + wxMessageBox(err, wxT("Error"), wxOK | wxICON_ERROR, this); + cmSystemTools::Error(err.c_str()); + value = -1; + } + else + { + value = 0; + m_cmOptions->SetProjectGenerated(true); // clear cache dirty when generated + } + } + else + { + // set paths + m_cmake->SetHomeDirectory(m_cmProjectPath->GetValue().c_str()); + m_cmake->SetStartDirectory(m_cmProjectPath->GetValue().c_str()); + m_cmake->SetHomeOutputDirectory(m_cmBuildPath->GetValue().c_str()); + m_cmake->SetStartOutputDirectory(m_cmBuildPath->GetValue().c_str()); + + m_cmake->SetGlobalGenerator(m_cmake->CreateGlobalGenerator(m_cmGeneratorChoice->GetValue().c_str())); + m_cmake->SetCMakeCommand(m_PathToExecutable.c_str()); + m_cmake->LoadCache(); + if(m_cmake->Configure() != 0) + { + wxMessageBox(err, wxT("Error"), wxOK | wxICON_ERROR, this); + cmSystemTools::Error(err.c_str()); + } + + // update the GUI with any new values in the caused by the + // generation process + LoadCacheFromDiskToGUI(); + } + + m_RunningConfigure = false; + + if(!value) + cmSystemTools::ResetErrorOccuredFlag(); + + m_progressDlg->Destroy(); + m_progressDlg = 0; + + // reset the statusbar progress + wxStatusBar *bar = GetStatusBar(); + if(bar) + bar->SetStatusText(wxEmptyString, 1); + + UpdateWindowState(); + return value; +} + +//! Save GUI values to cmCacheManager and then save to disk. +void CMakeSetupFrm::SaveCacheFromGUI() +{ + cmCacheManager *cachem = m_cmake->GetCacheManager(); + FillCacheManagerFromCacheGUI(); + + // write the cache to disk + if(!m_cmBuildPath->GetValue().Trim().IsEmpty()) + cachem->SaveCache(m_cmBuildPath->GetValue().c_str()); +} + +void CMakeSetupFrm::FillCacheManagerFromCacheGUI() +{ + cmCacheManager *cachem = m_cmake->GetCacheManager(); + + cmCacheManager::CacheIterator it = cachem->NewIterator(); + for(size_t i = 0; i < m_cmOptions->GetCount(); i++) + { + wxPropertyItem* item = m_cmOptions->GetItem(i); + if ( it.Find((const char*)item->GetPropName().c_str()) ) + { + // if value is enclosed in single quotes ('foo') then remove them + // they were used to enforce the fact that it had 'invisible' + // trailing stuff + if (item->GetCurValue().Len() >= 2 && + item->GetCurValue().GetChar(0) == '\'' && + item->GetCurValue().GetChar(item->GetCurValue().Len() - 1) == '\'') + { + it.SetValue(item->GetCurValue().Mid(1, item->GetCurValue().Len() - 2).c_str()); + } + else + it.SetValue(item->GetCurValue().c_str()); + } + } +} + + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_DO_OK + */ + +void CMakeSetupFrm::OnButtonOk( wxCommandEvent& event ) +{ + DoGenerate(); +} + +void CMakeSetupFrm::DoGenerate() +{ + cmSystemTools::EnableMessages(); + + cmSystemTools::ResetErrorOccuredFlag(); + + m_cmOptions->HideControls(); + PerformCacheRun(); + + if(!RunCMake(true)) + { + // issue a close when this is done (this is issued by menu "Generate and Exit" + if(m_quitAfterGenerating) + Close(); + else if(!wxGetKeyState(WXK_SHIFT)) + { + bool close; + m_config->Read(CM_CLOSEAFTERGEN, &close, CM_CLOSEAFTERGEN_DEF); + + if(!close) + wxMessageBox(wxT("Building of project files succesful!"), wxT("Success!"), wxOK|wxICON_INFORMATION); + else + Close(); + } + } +} + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_DO_CANCEL + */ + +void CMakeSetupFrm::OnButtonCancel( wxCommandEvent& event ) +{ + DoCancelButton(); +} + +void CMakeSetupFrm::DoCancelButton() +{ + if(m_RunningConfigure) + { + int result = wxMessageBox(wxT("You are in the middle of a Configure.\n" + "If you Cancel now the configure information will be lost.\n" + "Are you sure you want to Cancel?"), wxT("Warning"), wxYES_NO|wxICON_WARNING); + if(result == wxYES) + cmSystemTools::SetFatalErrorOccured(); + else + if(m_progressDlg) + m_progressDlg->ResetCancel(); + } +} + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_DO_DELETE_CACHE + */ + +void CMakeSetupFrm::OnButtonDeleteCache( wxCommandEvent& event ) +{ + DoDeleteCache(); +} + +void CMakeSetupFrm::DoDeleteCache() +{ + bool deletecache = true; + if(m_cmOptions->IsCacheDirty() || (m_cmOptions->GetCount() > 0 && !m_cmOptions->IsGenerated())) + { + int result = ::wxMessageBox(_("You have changed options, are you sure you want to delete all items?\n"), + _("Warning"), wxYES_NO|wxICON_QUESTION); + + // when user wants to wait, wait.. else quit + if(result == wxNO) + deletecache = false; + + } + + if(deletecache) + { + // indicate that we haven't generated a project yet + m_cmOptions->SetProjectGenerated(false); + + if(!m_cmBuildPath->GetValue().Trim().IsEmpty() && m_cmake != 0) + m_cmake->GetCacheManager()->DeleteCache(m_cmBuildPath->GetValue().Trim()); + + LoadCacheFromDiskToGUI(); + UpdateWindowState(); + } +} + +/*! + * Should we show tooltips? + */ + +bool CMakeSetupFrm::ShowToolTips() +{ + return TRUE; +} + +/*! + * Get bitmap resources + */ + +wxBitmap CMakeSetupFrm::GetBitmapResource( const wxString& name ) +{ + // Bitmap retrieval +////@begin CMakeSetupFrm bitmap retrieval + return wxNullBitmap; +////@end CMakeSetupFrm bitmap retrieval +} + +/*! + * Get icon resources + */ + +wxIcon CMakeSetupFrm::GetIconResource( const wxString& name ) +{ + // Icon retrieval +////@begin CMakeSetupFrm icon retrieval + if (name == wxT("cmake_icon.xpm")) + { + wxIcon icon(_T("cmake_icon.xpm"), wxBITMAP_TYPE_XPM); + return icon; + } + return wxNullIcon; +////@end CMakeSetupFrm icon retrieval +} + +/*! + * wxEVT_COMMAND_SPLITTER_SASH_POS_CHANGING event handler for ID_SPLITTERWINDOW + */ + +void CMakeSetupFrm::OnSplitterPosChanging( wxSplitterEvent& event ) +{ + int width, height; + + GetSize(&width, &height); + + if((height > 100)) + { + if(event.GetSashPosition() < 170) + event.SetSashPosition(170); + else + { + if(event.GetSashPosition() > (height - 180)) + event.SetSashPosition(height - 180); + } + } + else + event.Veto(); + +} + + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_CLEAR_LOG + */ + +void CMakeSetupFrm::OnClearLogClick( wxCommandEvent& event ) +{ + // delete the log text + m_cmLog->Clear(); + m_cmLog->DiscardEdits(); +} + + +/*! + * wxEVT_COMMAND_TEXT_UPDATED event handler for ID_SOURCE_BUILD_PATH + */ + +void CMakeSetupFrm::OnSourceBuildPathUpdated( wxCommandEvent& event ) +{ + DoReloadCache(); +} + +void CMakeSetupFrm::DoReloadCache() +{ + wxString buildpath = m_cmBuildPath->GetValue(); + // The build dir has changed, check if there is a cache, and + // grab the source dir from it + + // make sure the call to update grid is not executed + m_noRefresh = true; + m_cmSearchQuery->SetValue(_("")); + m_noRefresh = false; + + std::string path = buildpath.c_str(); + cmSystemTools::ConvertToUnixSlashes(path); + + // adjust the cmake instance + m_cmake->SetHomeOutputDirectory(buildpath.c_str()); + m_cmake->SetStartOutputDirectory(buildpath.c_str()); + + std::string cache_file = path; + cache_file += "/CMakeCache.txt"; + + // fill in the project path where the source is located, this is + // read from the CMake cache + cmCacheManager *cachem = m_cmake->GetCacheManager(); + cmCacheManager::CacheIterator it = cachem->NewIterator(); + if (cmSystemTools::FileExists(cache_file.c_str()) && cachem->LoadCache(path.c_str()) && + it.Find("CMAKE_HOME_DIRECTORY")) + { + path = ConvertToWindowsPath(it.GetValue()); + m_cmProjectPath->SetValue(path.c_str()); + } + + m_cmOptions->RemoveAll(); + LoadCacheFromDiskToGUI(); + UpdateWindowState(); +} + + +/*! + * wxEVT_COMMAND_TEXT_ENTER event handler for ID_SOURCE_BUILD_PATH + */ + +void CMakeSetupFrm::OnSourceBuildPathEnter( wxCommandEvent& event ) +{ + OnSourceBuildPathUpdated(event); +} + +/*! + * wxEVT_MOTION event handler for ID_OPTIONS + */ + +void CMakeSetupFrm::OnPropertyMotion( wxMouseEvent& event ) +{ + ShowPropertyDescription(m_cmOptions->YToRow(event.GetY())); + event.Skip(); +} + + +/*! + * wxEVT_GRID_SELECT_CELL event handler for ID_OPTIONS + */ + +void CMakeSetupFrm::OnGridSelectCell( wxGridEvent& event ) +{ + // show description + ShowPropertyDescription(event.GetRow()); + + // enable or disable the browse button + m_cmBrowseCell->Enable(m_cmOptions->IsSelectedItemBrowsable(event.GetRow())); + event.Skip(); +} + +void CMakeSetupFrm::ShowPropertyDescription(int row) +{ + if(row == wxNOT_FOUND || row < 0) + m_cmDescription->SetValue(wxEmptyString); + else + { + wxPropertyItem *pItem = m_cmOptions->GetPropertyItemFromRow(row); + if(pItem) + m_cmDescription->SetValue(pItem->GetHelpString()); + else + m_cmDescription->SetValue(wxEmptyString); + } +} + +/*! + * wxEVT_GRID_CELL_CHANGE event handler for ID_OPTIONS + */ + +void CMakeSetupFrm::OnCellChange( wxGridEvent& event ) +{ + // update the button state when the cache is invalidated + UpdateWindowState(); +} + +void CMakeSetupFrm::OnRecentFileMenu( wxCommandEvent &event ) +{ + if(GetMenuBar()) + { + // get file menu + wxMenu *mnu = GetMenuBar()->GetMenu(0); + wxASSERT(mnu != 0); + + wxMenuItem *item = mnu->FindItem(event.GetId()); + if(item) + m_cmBuildPath->SetValue(item->GetLabel()); + } +} +/*! + * wxEVT_COMMAND_COMBOBOX_SELECTED event handler for ID_COMBOBOX + */ + +void CMakeSetupFrm::OnSearchquerySelected( wxCommandEvent& event ) +{ + m_cmOptions->SetQuery(m_cmSearchQuery->GetValue()); +} + +void CMakeSetupFrm::OnAddQuery ( wxCommandEvent &event ) +{ + // add current text if not yet present + if(m_cmSearchQuery->FindString(m_cmSearchQuery->GetValue()) == wxNOT_FOUND) + { + m_cmSearchQuery->Append(m_cmSearchQuery->GetValue()); + + // if too many items are present, prune + while(m_cmSearchQuery->GetCount() > CM_MAX_SEARCH_QUERIES) + m_cmSearchQuery->Delete(0); + } +} + +/*! + * wxEVT_COMMAND_TEXT_UPDATED event handler for ID_SEARCHQUERY + */ + +void CMakeSetupFrm::OnSearchqueryUpdated( wxCommandEvent& event ) +{ + // only refresh when this event was caused by user + if(!m_noRefresh) + m_cmOptions->SetQuery(m_cmSearchQuery->GetValue()); +} + + +/*! + * wxEVT_COMMAND_BUTTON_CLICKED event handler for ID_BROWSE_GRID + */ + +void CMakeSetupFrm::OnBrowseGridClick( wxCommandEvent& event ) +{ + m_cmOptions->BrowseSelectedItem(); +} + + +/*! + * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_RELOAD_CACHE + */ + +void CMakeSetupFrm::OnMenuReloadCacheClick( wxCommandEvent& event ) +{ + bool reload = true; + if(m_cmOptions->IsCacheDirty() || (m_cmOptions->GetCount() > 0 && !m_cmOptions->IsGenerated())) + { + int result = ::wxMessageBox(_("You have changed options, are you sure you want to reload?\n"), + _("Warning"), wxYES_NO|wxICON_QUESTION); + + // when user wants to wait, wait.. else quit + if(result == wxNO) + reload = false; + + } + + if(reload) + DoReloadCache(); +} + +/*! + * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_DELETE_CACHE + */ + +void CMakeSetupFrm::OnMenuDeleteCacheClick( wxCommandEvent& event ) +{ + DoDeleteCache(); +} + + +/*! + * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_QUIT + */ + +void CMakeSetupFrm::OnMenuQuitClick( wxCommandEvent& event ) +{ + // the close event will veto if the user + // did not want to quit due to unsaved changes + Close(); +} + + +/*! + * wxEVT_CLOSE_WINDOW event handler for ID_FRAME + */ + +void CMakeSetupFrm::OnCloseWindow( wxCloseEvent& event ) +{ + // ask quit if: + // - The cache is dirty + // - Or the cache is OK and has some items, and no project was generated recently (configure -> generate) + if(m_cmOptions->IsCacheDirty() || (m_cmOptions->GetCount() > 0 && !m_cmOptions->IsGenerated())) + { + int result = ::wxMessageBox(_("You have changed options, but not yet generated the projects\n" + "are you sure you want to quit?"), _("Warning"), wxYES_NO|wxICON_QUESTION); + + // when user wants to wait, wait.. else quit + if(result == wxNO) + event.Veto(); + else + event.Skip(); + } + else + event.Skip(); +} + + +/*! + * wxEVT_COMMAND_MENU_SELECTED event handler for ID_ABOUTDLG + */ + +void CMakeSetupFrm::OnAboutClick( wxCommandEvent& event ) +{ + CMAboutDlg *dlg = new CMAboutDlg(this); + + wxArrayString generators; + std::vector<std::string> names; + m_cmake->GetRegisteredGenerators(names); + for(std::vector<std::string>::iterator i = names.begin(); i != names.end(); ++i) + generators.Add(i->c_str()); + + wxString cmversion, cmsversion; + cmversion.Printf("v%i.%i %s", cmake::GetMajorVersion(), cmake::GetMinorVersion(), cmake::GetReleaseVersion()); + cmsversion.Printf("v%i.%i%s", CMAKEGUI_MAJORVER, CMAKEGUI_MINORVER, CMAKEGUI_ADDVER); + + dlg->SetAboutText(cmversion, cmsversion, generators); + + dlg->ShowModal(); + dlg->Destroy(); +} + + +/*! + * wxEVT_COMMAND_MENU_SELECTED event handler for ID_CMAKE_OPTIONS + */ + +void CMakeSetupFrm::OnOptionsClick( wxCommandEvent& event ) +{ + CMOptionsDlg *dlg = new CMOptionsDlg(this); + + dlg->SetConfig(m_config); + if(dlg->ShowModal() == wxID_OK) + { + // store volatile settings + dlg->GetConfig(m_config); + + // apply non volatile setting such as clear search query, recent menu, etc. + SyncFormOptions(dlg); + } + + dlg->Destroy(); +} + +void CMakeSetupFrm::SyncFormOptions(CMOptionsDlg *dlg) +{ + // TODO: Clear search query etc. +} +/*! + * wxEVT_COMMAND_SPLITTER_DOUBLECLICKED event handler for ID_SPLITTERWINDOW + */ + +void CMakeSetupFrm::OnSplitterwindowSashDClick( wxSplitterEvent& event ) +{ + event.Veto(); +} + + +/*! + * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_CONFIGURE + */ + +void CMakeSetupFrm::OnMenuConfigureClick( wxCommandEvent& event ) +{ + DoConfigure(); +} + +/*! + * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_EXITGENERATE + */ + +void CMakeSetupFrm::OnMenuGenerateClick( wxCommandEvent& event ) +{ + // set flag so that a close command is issued + // after generating the cmake cache to projects + m_quitAfterGenerating = true; + DoGenerate(); + m_quitAfterGenerating = false; +} + + +/*! + * wxEVT_COMMAND_MENU_SELECTED event handler for ID_MENU_TOGGLE_ADVANCED + */ + +void CMakeSetupFrm::OnMenuToggleAdvancedClick( wxCommandEvent& event ) +{ + // toggle the check box + m_cmShowAdvanced->SetValue(!m_cmShowAdvanced->GetValue()); + OnShowAdvancedValues(event); +} + + |