| /*========================================================================= |
| |
| Program: WXDialog - wxWidgets X-platform GUI Front-End for CMake |
| Module: $RCSfile: CMakeSetupFrame.cpp,v $ |
| Language: C++ |
| Date: $Date: 2012/03/29 17:21:10 $ |
| Version: $Revision: 1.1.1.1 $ |
| |
| 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 "../cmVersion.h" |
| #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) |
| { |
| // 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 we have a command line query that a generator |
| // needs to be chosen instead of the default, take it |
| bool foundGivenGenerator = false; |
| if(!cm.m_GeneratorChoiceString.IsEmpty()) |
| { |
| // set proper discovered generator |
| foundGivenGenerator = m_cmGeneratorChoice->SetStringSelection(cm.m_GeneratorChoiceString); |
| } |
| |
| // if none selected, we will see if VS8, VS7 or VS6 is present |
| if(!foundGivenGenerator || 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", cmVersion::GetMajorVersion(), |
| cmVersion::GetMinorVersion(), |
| cmVersion::GetReleaseVersion().c_str()); |
| 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); |
| } |
| |
| |