1
// pcbuilderdialogDlg.cpp : implementation file
6
// a fun undef for DOT NET
8
#include "CMakeSetup.h"
10
#include "cmVersion.h"
11
#include "PathDialog.h"
12
#include "CMakeSetupDialog.h"
13
#include "CMakeCommandLineInfo.h"
14
#include "../cmExternalMakefileProjectGenerator.h"
15
#include "../cmListFileCache.h"
16
#include "../cmCacheManager.h"
18
#include "../cmGlobalGenerator.h"
19
#include "../cmDynamicLoader.h"
23
static char THIS_FILE[] = __FILE__;
27
/////////////////////////////////////////////////////////////////////////////
28
// CAboutDlg dialog used for App About
30
class CAboutDlg : public CDialog
36
//{{AFX_DATA(CAboutDlg)
37
enum { IDD = IDD_ABOUTBOX };
40
// ClassWizard generated virtual function overrides
41
//{{AFX_VIRTUAL(CAboutDlg)
43
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
48
//{{AFX_MSG(CAboutDlg)
53
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
55
//{{AFX_DATA_INIT(CAboutDlg)
59
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
61
CDialog::DoDataExchange(pDX);
62
//{{AFX_DATA_MAP(CAboutDlg)
66
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
67
//{{AFX_MSG_MAP(CAboutDlg)
68
// No message handlers
73
void MFCMessageCallback(const char* m, const char* title, bool& nomore, void*)
75
std::string message = m;
76
message += "\n\n(Press Cancel to suppress any further messages.)";
77
if(::MessageBox(0, message.c_str(), title,
78
MB_OKCANCEL|MB_TASKMODAL) == IDCANCEL)
84
/////////////////////////////////////////////////////////////////////////////
85
// CMakeSetupDialog dialog
86
void updateProgress(const char *msg, float prog, void *cd)
88
char* tmp = new char[strlen(msg) + 40];
91
sprintf(tmp,"%s %i%%",msg,(int)(100*prog));
95
sprintf(tmp,"%s",msg);
97
CMakeSetupDialog *self = (CMakeSetupDialog *)cd;
98
self->SetDlgItemText(IDC_PROGRESS, tmp);
99
CWnd* cancel = self->GetDlgItem(IDCANCEL);
101
// Retrieve and dispatch any waiting messages.
104
while (::PeekMessage (&wmsg, NULL, 0, 0, PM_REMOVE))
110
case WM_LBUTTONDBLCLK:
112
if(wmsg.hwnd == cancel->m_hWnd)
114
::DispatchMessage(&wmsg);
121
::DispatchMessage(&wmsg);
128
// Convert to Win32 path (slashes). This calls the system tools one and then
129
// removes the spaces. It is not in system tools because we don't want any
130
// generators accidentally use it
131
std::string ConvertToWindowsPath(const char* path)
133
// Convert to output path.
134
// Remove the "" around it (if any) since it's an output path for
135
// the shell. If another shell-oriented feature is not designed
136
// for a GUI use, then we are in trouble.
137
// save the value of the force to unix path option
138
bool saveForce = cmSystemTools::GetForceUnixPaths();
139
// make sure we get windows paths no matter what for the GUI
140
cmSystemTools::SetForceUnixPaths(false);
141
std::string s = cmSystemTools::ConvertToOutputPath(path);
142
// now restore the force unix path to its previous value
143
cmSystemTools::SetForceUnixPaths(saveForce);
146
std::string::iterator i = s.begin();
151
i = s.begin() + s.length() - 1;
160
CMakeSetupDialog::CMakeSetupDialog(const CMakeCommandLineInfo& cmdInfo,
161
CWnd* pParent /*=NULL*/)
162
: CDialog(CMakeSetupDialog::IDD, pParent)
164
m_GeneratorPicked = false;
165
m_Cursor = LoadCursor(NULL, IDC_ARROW);
166
m_RunningConfigure = false;
167
cmSystemTools::SetRunCommandHideConsole(true);
168
cmSystemTools::SetErrorCallback(MFCMessageCallback);
169
m_RegistryKey = "Software\\Kitware\\CMakeSetup\\Settings\\StartPath";
170
m_CacheEntriesList.m_CMakeSetupDialog = this;
172
m_CMakeInstance = new cmake;
173
m_CMakeInstance->SetCMakeEditCommand("CMakeSetup");
174
m_CMakeInstance->SetProgressCallback(updateProgress, (void *)this);
176
//{{AFX_DATA_INIT(CMakeSetupDialog)
179
// Get the parameters from the command line info
180
// If an unknown parameter is found, try to interpret it too, since it
181
// is likely to be a file dropped on the shortcut :)
182
if (cmdInfo.m_LastUnknownParameter.IsEmpty())
184
this->m_WhereSource = cmdInfo.m_WhereSource;
185
this->m_WhereBuild = cmdInfo.m_WhereBuild;
186
this->m_GeneratorDialog.m_GeneratorChoiceString =
187
cmdInfo.m_GeneratorChoiceString;
188
this->m_AdvancedValues = cmdInfo.m_AdvancedValues;
192
this->m_WhereSource = _T("");
193
this->m_WhereBuild = _T("");
194
this->m_AdvancedValues = FALSE;
195
this->m_GeneratorDialog.m_GeneratorChoiceString =
196
cmdInfo.m_GeneratorChoiceString;
197
this->ChangeDirectoriesFromFile((LPCTSTR)cmdInfo.m_LastUnknownParameter);
200
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
201
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
202
m_BuildPathChanged = false;
203
// Find the path to the cmake.exe executable
205
::GetModuleFileName(NULL,fname,1023);
206
// extract just the path part
207
m_PathToExecutable = cmSystemTools::GetProgramPath(fname).c_str();
208
// add the cmake.exe to the path
209
m_PathToExecutable += "/cmake.exe";
212
m_deltaXRemainder = 0;
215
CMakeSetupDialog::~CMakeSetupDialog()
217
delete m_CMakeInstance;
219
cmDynamicLoader::FlushCache();
222
void CMakeSetupDialog::DoDataExchange(CDataExchange* pDX)
224
CDialog::DoDataExchange(pDX);
225
//{{AFX_DATA_MAP(CMakeSetupDialog)
226
DDX_Control(pDX, IDC_AdvancedValues, m_AdvancedValuesControl);
227
DDX_Control(pDX, IDC_SUPPRESS_DEV_WARNINGS, m_SuppressDevWarningsControl);
228
DDX_Check(pDX, IDC_SUPPRESS_DEV_WARNINGS, m_SuppressDevValue);
229
DDX_Control(pDX, IDC_BROWSE_SOURCE, m_BrowseSource);
230
DDX_Control(pDX, IDC_BROWSE_BUILD, m_BrowseBuild);
231
DDX_Control(pDX, IDC_DELETE_BUTTON, m_DeleteButton);
232
DDX_Control(pDX, IDC_HELP_BUTTON, m_HelpButton);
233
DDX_Control(pDX, IDC_OK, m_OKButton);
234
DDX_Control(pDX, IDCANCEL, m_CancelButton);
235
DDX_CBStringExact(pDX, IDC_WhereSource, m_WhereSource);
236
DDX_CBStringExact(pDX, IDC_WhereBuild, m_WhereBuild);
237
DDX_Control(pDX, IDC_FRAME, m_ListFrame);
238
DDX_Control(pDX, IDC_WhereSource, m_WhereSourceControl);
239
DDX_Control(pDX, IDC_WhereBuild, m_WhereBuildControl);
240
DDX_Control(pDX, IDC_LIST2, m_CacheEntriesList);
241
DDX_Control(pDX, IDC_MouseHelpCaption, m_MouseHelp);
242
DDX_Control(pDX, IDC_PROGRESS, m_StatusDisplay);
243
DDX_Control(pDX, IDC_BuildProjects, m_Configure);
244
DDX_Check(pDX, IDC_AdvancedValues, m_AdvancedValues);
248
BEGIN_MESSAGE_MAP(CMakeSetupDialog, CDialog)
249
//{{AFX_MSG_MAP(CMakeSetupDialog)
252
ON_WM_QUERYDRAGICON()
253
ON_BN_CLICKED(IDC_BUTTON2, OnBrowseWhereSource)
254
ON_BN_CLICKED(IDC_BuildProjects, OnConfigure)
255
ON_BN_CLICKED(IDC_BUTTON3, OnBrowseWhereBuild)
256
ON_CBN_EDITCHANGE(IDC_WhereBuild, OnChangeWhereBuild)
257
ON_CBN_SELCHANGE(IDC_WhereBuild, OnSelendokWhereBuild)
258
ON_CBN_EDITCHANGE(IDC_WhereSource, OnChangeWhereSource)
259
ON_CBN_SELENDOK(IDC_WhereSource, OnSelendokWhereSource)
261
ON_WM_GETMINMAXINFO()
262
ON_BN_CLICKED(IDC_OK, OnOk)
263
ON_BN_CLICKED(IDC_DELETE_BUTTON, OnDeleteButton)
264
ON_BN_CLICKED(IDC_HELP_BUTTON, OnHelpButton)
265
ON_BN_CLICKED(IDC_AdvancedValues, OnAdvancedValues)
266
ON_BN_CLICKED(IDC_SUPPRESS_DEV_WARNINGS, OnSuppressDevValue)
267
ON_BN_DOUBLECLICKED(IDC_SUPPRESS_DEV_WARNINGS, OnDoubleclickedSuppressDevValue)
268
ON_BN_DOUBLECLICKED(IDC_AdvancedValues, OnDoubleclickedAdvancedValues)
270
ON_BN_CLICKED(IDCANCEL, OnCancel)
275
/////////////////////////////////////////////////////////////////////////////
276
// CMakeSetupDialog message handlers
278
BOOL CMakeSetupDialog::OnInitDialog()
280
CDialog::OnInitDialog();
281
this->DragAcceptFiles(true);
283
// Add "Create shortcut" menu item to system menu.
285
// IDM_CREATESHORTCUT must be in the system command range.
286
ASSERT((IDM_CREATESHORTCUT & 0xFFF0) == IDM_CREATESHORTCUT);
287
ASSERT(IDM_CREATESHORTCUT < 0xF000);
289
// Add "About..." menu item to system menu.
291
// IDM_ABOUTBOX must be in the system command range.
292
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
293
ASSERT(IDM_ABOUTBOX < 0xF000);
295
CMenu* pSysMenu = GetSystemMenu(FALSE);
296
if (pSysMenu != NULL)
298
CString strCreateShortcutMenu;
299
strCreateShortcutMenu.LoadString(IDS_CREATESHORTCUT);
300
if (!strCreateShortcutMenu.IsEmpty())
302
pSysMenu->AppendMenu(MF_SEPARATOR);
303
pSysMenu->AppendMenu(MF_STRING,
305
strCreateShortcutMenu);
308
CString strAboutMenu;
309
strAboutMenu.LoadString(IDS_ABOUTBOX);
310
if (!strAboutMenu.IsEmpty())
312
pSysMenu->AppendMenu(MF_SEPARATOR);
313
pSysMenu->AppendMenu(MF_STRING,
319
// Set the icon for this dialog. The framework does this automatically
320
// when the application's main window is not a dialog
321
SetIcon(m_hIcon, TRUE); // Set big icon
322
SetIcon(m_hIcon, FALSE); // Set small icon
323
// Load source and build dirs from registry
324
this->LoadFromRegistry();
326
// try to load the cmake cache from disk
327
this->LoadCacheFromDiskToGUI();
328
m_WhereBuildControl.LimitText(2048);
329
m_WhereSourceControl.LimitText(2048);
331
// Set the version number
333
sprintf(tmp,"CMake %d.%d - %s", cmVersion::GetMajorVersion(),
334
cmVersion::GetMinorVersion(),
335
cmVersion::GetReleaseVersion().c_str());
336
SetDlgItemText(IDC_PROGRESS, "");
337
this->SetWindowText(tmp);
338
this->UpdateData(FALSE);
339
return TRUE; // return TRUE unless you set the focus to a control
343
// About dialog invoke
344
void CMakeSetupDialog::OnSysCommand(UINT nID, LPARAM lParam)
346
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
351
else if ((nID & 0xFFF0) == IDM_CREATESHORTCUT)
357
CDialog::OnSysCommand(nID, lParam);
361
// If you add a minimize button to your dialog, you will need the code below
362
// to draw the icon. For MFC applications using the document/view model,
363
// this is automatically done for you by the framework.
365
void CMakeSetupDialog::OnPaint()
369
CPaintDC dc(this); // device context for painting
371
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
373
// Center icon in client rectangle
374
int cxIcon = GetSystemMetrics(SM_CXICON);
375
int cyIcon = GetSystemMetrics(SM_CYICON);
377
GetClientRect(&rect);
378
int x = (rect.Width() - cxIcon + 1) / 2;
379
int y = (rect.Height() - cyIcon + 1) / 2;
382
dc.DrawIcon(x, y, m_hIcon);
390
// The system calls this to obtain the cursor to display while the user drags
391
// the minimized window.
392
HCURSOR CMakeSetupDialog::OnQueryDragIcon()
394
return (HCURSOR) m_hIcon;
400
bool CMakeSetupDialog::Browse(CString &result, const char *title)
402
CString initialDir = result;
403
initialDir.Replace("/", "\\");
404
CPathDialog dlg("Select Path", title, initialDir);
405
if(dlg.DoModal()==IDOK)
407
result = dlg.GetPathName();
419
void CMakeSetupDialog::SaveToRegistry()
424
if(RegCreateKeyEx(HKEY_CURRENT_USER,
426
0, "", REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE,
427
NULL, &hKey, &dwDummy) != ERROR_SUCCESS)
436
// write the size of the dialog
438
this->GetWindowRect(&size);
439
unsigned long width = size.Width();
440
unsigned long height = size.Height();
441
RegSetValueEx(hKey, _T("Width"), 0, REG_DWORD,
442
(CONST BYTE *)(&width),4);
443
RegSetValueEx(hKey, _T("Height"), 0, REG_DWORD,
444
(CONST BYTE *)(&height),4);
446
this->ReadRegistryValue(hKey, &(regvalue),"WhereSource1","C:\\");
448
if(m_WhereSource != regvalue)
453
for (i = 2; i < 10; ++i)
456
sprintf(keyName,"WhereSource%i",i);
457
this->ReadRegistryValue(hKey, &(regvalue),keyName,"");
458
// check for short circuit, if the new value is already in
459
// the list then we stop
460
if (m_WhereSource == regvalue)
466
for (i = shiftEnd; i; --i)
469
sprintf(keyName,"WhereSource%i",i);
470
sprintf(keyName2,"WhereSource%i",i+1);
472
this->ReadRegistryValue(hKey, &(regvalue),keyName,"");
473
if (strlen(regvalue))
475
RegSetValueEx(hKey, _T(keyName2), 0, REG_SZ,
476
(CONST BYTE *)(const char *)regvalue,
477
regvalue.GetLength());
480
RegSetValueEx(hKey, _T("WhereSource1"), 0, REG_SZ,
481
(CONST BYTE *)(const char *)m_WhereSource,
482
m_WhereSource.GetLength());
485
this->ReadRegistryValue(hKey, &(regvalue),"WhereBuild1","C:\\");
486
if(m_WhereBuild != regvalue)
491
for (i = 2; i < 10; ++i)
494
sprintf(keyName,"WhereBuild%i",i);
495
this->ReadRegistryValue(hKey, &(regvalue),keyName,"");
496
// check for short circuit, if the new value is already in
497
// the list then we stop
498
if (m_WhereBuild == regvalue)
503
for (i = shiftEnd; i; --i)
506
sprintf(keyName,"WhereBuild%i",i);
507
sprintf(keyName2,"WhereBuild%i",i+1);
509
this->ReadRegistryValue(hKey, &(regvalue),keyName,"");
510
if (strlen(regvalue))
512
RegSetValueEx(hKey, _T(keyName2), 0, REG_SZ,
513
(CONST BYTE *)(const char *)regvalue,
514
regvalue.GetLength());
517
RegSetValueEx(hKey, _T("WhereBuild1"), 0, REG_SZ,
518
(CONST BYTE *)(const char *)m_WhereBuild,
519
m_WhereBuild.GetLength());
526
void CMakeSetupDialog::ReadRegistryValue(HKEY hKey,
529
const char *adefault)
531
DWORD dwType, dwSize;
535
pb = val->GetBuffer(MAX_PATH);
537
if(RegQueryValueEx(hKey,_T(key), NULL, &dwType,
538
(BYTE *)pb, &dwSize) != ERROR_SUCCESS)
540
val->ReleaseBuffer();
545
val->ReleaseBuffer();
550
void CMakeSetupDialog::LoadFromRegistry()
553
if(RegOpenKeyEx(HKEY_CURRENT_USER,
555
0, KEY_READ, &hKey) != ERROR_SUCCESS)
565
if (RegQueryValueEx(hKey,_T("Width"), NULL, NULL,
566
(BYTE *)&width, &dwSize) == ERROR_SUCCESS &&
567
RegQueryValueEx(hKey,_T("Height"), NULL, NULL,
568
(BYTE *)&height, &dwSize) == ERROR_SUCCESS)
570
this->SetWindowPos(0,0,0,width,height,SWP_NOZORDER | SWP_NOMOVE);
573
if (m_WhereSource.IsEmpty())
575
this->ReadRegistryValue(hKey, &(m_WhereSource),"WhereSource1","C:\\");
577
if (m_WhereBuild.IsEmpty())
579
this->ReadRegistryValue(hKey, &(m_WhereBuild),"WhereBuild1","C:\\");
581
m_WhereSourceControl.AddString(m_WhereSource);
582
m_WhereBuildControl.AddString(m_WhereBuild);
587
for (i = 2; i <= 10; ++i)
589
sprintf(keyname,"WhereSource%i",i);
591
this->ReadRegistryValue(hKey, &(regvalue),keyname,"C:\\");
592
if (strcmp("C:\\",regvalue))
594
m_WhereSourceControl.AddString(regvalue);
596
sprintf(keyname,"WhereBuild%i",i);
598
this->ReadRegistryValue(hKey, &(regvalue),keyname,"C:\\");
599
if (strcmp("C:\\",regvalue))
601
m_WhereBuildControl.AddString(regvalue);
610
// Callback for browse source button
611
void CMakeSetupDialog::OnBrowseWhereSource()
614
Browse(m_WhereSource, "Enter Path to Source");
615
this->UpdateData(false);
616
this->OnChangeWhereSource();
619
// Callback for browser build button
620
void CMakeSetupDialog::OnBrowseWhereBuild()
623
Browse(m_WhereBuild, "Enter Path to Build");
624
this->UpdateData(false);
625
this->OnChangeWhereBuild();
628
void CMakeSetupDialog::RunCMake(bool generateProjectFiles)
630
if(!cmSystemTools::FileExists(m_WhereBuild))
632
std::string message =
633
"Build directory does not exist, should I create it?\n\n"
635
message += (const char*)m_WhereBuild;
636
if(MessageBox(message.c_str(), "Create Directory", MB_OKCANCEL) == IDOK)
638
cmSystemTools::MakeDirectory(m_WhereBuild);
642
MessageBox("Build Project aborted, nothing done.");
646
// set the wait cursor
647
m_Cursor = LoadCursor(NULL, IDC_WAIT);
648
::SetCursor(m_Cursor);
649
m_RunningConfigure = true;
651
// get all the info from the dialog
653
// always save the current gui values to disk
654
this->SaveCacheFromGUI();
655
// Make sure we are working from the cache on disk
656
this->LoadCacheFromDiskToGUI();
657
m_OKButton.EnableWindow(false);
659
// setup the cmake instance
660
if (generateProjectFiles)
662
if(m_CMakeInstance->Generate() != 0)
664
cmSystemTools::Error(
665
"Error in generation process, project files may be invalid");
670
m_CMakeInstance->SetHomeDirectory(m_WhereSource);
671
m_CMakeInstance->SetStartDirectory(m_WhereSource);
672
m_CMakeInstance->SetHomeOutputDirectory(m_WhereBuild);
673
m_CMakeInstance->SetStartOutputDirectory(m_WhereBuild);
674
m_CMakeInstance->SetGlobalGenerator(
675
m_CMakeInstance->CreateGlobalGenerator(m_GeneratorDialog.m_GeneratorChoiceString));
676
m_CMakeInstance->SetCMakeCommand(m_PathToExecutable);
677
m_CMakeInstance->LoadCache();
678
if(m_SuppressDevValue)
680
m_CMakeInstance->SetSuppressDevWarnings(true);
684
m_CMakeInstance->SetSuppressDevWarnings(false);
686
if(m_CMakeInstance->Configure() != 0)
688
cmSystemTools::Error(
689
"Error in configuration process, project files may be invalid");
691
// update the GUI with any new values in the caused by the
692
// generation process
693
this->LoadCacheFromDiskToGUI();
696
// save source and build paths to registry
697
this->SaveToRegistry();
698
// path is up-to-date now
699
m_BuildPathChanged = false;
700
// put the cursor back
701
m_Cursor = LoadCursor(NULL, IDC_ARROW);
702
::SetCursor(m_Cursor);
703
m_RunningConfigure = false;
704
cmSystemTools::ResetErrorOccuredFlag();
708
// Callback for build projects button
709
void CMakeSetupDialog::OnConfigure()
711
if(!m_GeneratorPicked)
713
m_GeneratorDialog.m_CMakeInstance = this->m_CMakeInstance;
714
if(m_GeneratorDialog.DoModal() != IDOK)
718
// save the generator choice in the registry
722
if(RegCreateKeyEx(HKEY_CURRENT_USER,
724
0, "", REG_OPTION_NON_VOLATILE, KEY_READ|KEY_WRITE,
725
NULL, &hKey, &dwDummy) == ERROR_SUCCESS)
728
RegSetValueEx(hKey, _T("LastGenerator"), 0, REG_SZ,
729
(CONST BYTE *)(const char *)m_GeneratorDialog.m_GeneratorChoiceString,
730
m_GeneratorDialog.m_GeneratorChoiceString.GetLength());
734
// enable error messages each time configure is pressed
735
cmSystemTools::EnableMessages();
736
this->RunCMake(false);
742
// callback for combo box menu where build selection
743
void CMakeSetupDialog::OnSelendokWhereBuild()
745
m_WhereBuildControl.GetLBText(m_WhereBuildControl.GetCurSel(),
747
m_WhereBuildControl.SetWindowText( m_WhereBuild);
748
this->UpdateData(FALSE);
749
this->OnChangeWhereBuild();
752
// callback for combo box menu where source selection
753
void CMakeSetupDialog::OnSelendokWhereSource()
755
m_WhereSourceControl.GetLBText(m_WhereSourceControl.GetCurSel(),
757
this->UpdateData(FALSE);
758
this->OnChangeWhereSource();
761
// callback for chaing source directory
762
void CMakeSetupDialog::OnChangeWhereSource()
766
// callback for changing the build directory
767
void CMakeSetupDialog::OnChangeWhereBuild()
771
// The build dir has changed, check if there is a cache, and
772
// grab the source dir from it
774
std::string path = this->m_WhereBuild;
775
cmSystemTools::ConvertToUnixSlashes(path);
777
// adjust the cmake instance
778
m_CMakeInstance->SetHomeOutputDirectory(m_WhereBuild);
779
m_CMakeInstance->SetStartOutputDirectory(m_WhereBuild);
781
std::string cache_file = path;
782
cache_file += "/CMakeCache.txt";
784
cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager();
785
cmCacheManager::CacheIterator it = cachem->NewIterator();
787
m_GeneratorPicked = false;
789
// make sure we have a normal cache file, specifically if one exists make
790
// sure it can be read
791
if (cmSystemTools::FileExists(cache_file.c_str()))
793
if (cachem->LoadCache(path.c_str()))
795
if (it.Find("CMAKE_HOME_DIRECTORY"))
797
path = ConvertToWindowsPath(it.GetValue());
798
this->m_WhereSource = path.c_str();
799
this->m_WhereSourceControl.SetWindowText(this->m_WhereSource);
800
this->OnChangeWhereSource();
801
m_GeneratorPicked = true;
806
//file exists but cqnnot be read
807
cmSystemTools::Error("There is a CMakeCache.txt file for the current binary tree but cmake does not have permission to read it. Please check the permissions of the directory you are trying to run CMake on.");
812
m_CacheEntriesList.RemoveAll();
813
m_CacheEntriesList.ShowWindow(SW_SHOW);
814
this->LoadCacheFromDiskToGUI();
815
m_BuildPathChanged = true;
819
// copy from the cache manager to the cache edit list box
820
void CMakeSetupDialog::FillCacheGUIFromCacheManager()
822
cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager();
823
cmCacheManager::CacheIterator it = cachem->NewIterator();
825
// if there are already entries in the cache, then
826
// put the new ones in the top, so they show up first
827
bool reverseOrder = false;
828
// all the current values are not new any more
829
std::set<CPropertyItem*> items = m_CacheEntriesList.GetItems();
830
for(std::set<CPropertyItem*>::iterator i = items.begin();
831
i != items.end(); ++i)
833
// first check to see if it is still in the cache
834
CPropertyItem* item = *i;
835
if ( !it.Find((const char*)item->m_propName) )
837
m_CacheEntriesList.RemoveProperty((const char*)item->m_propName);
841
// if it is still in the cache then it is no longer new
842
item->m_NewValue = false;
845
for(cmCacheManager::CacheIterator i = cachem->NewIterator();
846
!i.IsAtEnd(); i.Next())
848
const char* key = i.GetName();
850
// if value has trailing space or tab, enclose it in single quotes
851
// to enforce the fact that it has 'invisible' trailing stuff
852
std::string value = i.GetValue();
854
(value[value.size() - 1] == ' ' ||
855
value[value.size() - 1] == '\t'))
857
value = '\'' + value + '\'';
859
bool advanced = i.GetPropertyAsBool("ADVANCED");
862
case cmCacheManager::BOOL:
863
if(cmSystemTools::IsOn(value.c_str()))
865
m_CacheEntriesList.AddProperty(key,
867
i.GetProperty("HELPSTRING"),
868
CPropertyList::COMBO,"ON|OFF",
875
m_CacheEntriesList.AddProperty(key,
877
i.GetProperty("HELPSTRING"),
878
CPropertyList::COMBO,"ON|OFF",
879
reverseOrder, advanced
883
case cmCacheManager::PATH:
884
m_CacheEntriesList.AddProperty(key,
886
i.GetProperty("HELPSTRING"),
887
CPropertyList::PATH,"",
888
reverseOrder, advanced
891
case cmCacheManager::FILEPATH:
892
m_CacheEntriesList.AddProperty(key,
894
i.GetProperty("HELPSTRING"),
895
CPropertyList::FILE,"",
896
reverseOrder, advanced
899
case cmCacheManager::STRING:
900
m_CacheEntriesList.AddProperty(key,
902
i.GetProperty("HELPSTRING"),
903
CPropertyList::EDIT,"",
904
reverseOrder, advanced
907
case cmCacheManager::INTERNAL:
908
m_CacheEntriesList.RemoveProperty(key);
912
if(m_CacheEntriesList.GetShowAdvanced())
914
m_CacheEntriesList.ShowAdvanced();
918
m_CacheEntriesList.HideAdvanced();
921
m_OKButton.EnableWindow(false);
922
if(cachem->GetSize() > 0 && !cmSystemTools::GetErrorOccuredFlag())
925
items = m_CacheEntriesList.GetItems();
926
for(std::set<CPropertyItem*>::iterator i = items.begin();
927
i != items.end(); ++i)
929
CPropertyItem* item = *i;
930
if(item->m_Advanced )
932
if(item->m_NewValue && m_CacheEntriesList.GetShowAdvanced())
942
// if one new value then disable to OK button
950
m_OKButton.EnableWindow(true);
955
m_CacheEntriesList.SetTopIndex(0);
956
m_CacheEntriesList.Invalidate();
959
// copy from the list box to the cache manager
960
void CMakeSetupDialog::FillCacheManagerFromCacheGUI()
962
cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager();
963
std::set<CPropertyItem*> items = m_CacheEntriesList.GetItems();
964
cmCacheManager::CacheIterator it = cachem->NewIterator();
965
for(std::set<CPropertyItem*>::iterator i = items.begin();
966
i != items.end(); ++i)
968
CPropertyItem* item = *i;
969
if ( it.Find((const char*)item->m_propName) )
971
// if value is enclosed in single quotes ('foo') then remove them
972
// they were used to enforce the fact that it had 'invisible'
974
if (item->m_curValue.GetLength() >= 2 &&
975
item->m_curValue[0] == '\'' &&
976
item->m_curValue[item->m_curValue.GetLength() - 1] == '\'')
978
it.SetValue(item->m_curValue.Mid(
979
1, item->m_curValue.GetLength() - 2));
983
it.SetValue(item->m_curValue);
991
//! Load cache file from m_WhereBuild and display in GUI editor
992
void CMakeSetupDialog::LoadCacheFromDiskToGUI()
994
cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager();
995
if(m_WhereBuild != "")
997
if (!cachem->LoadCache(m_WhereBuild))
999
// if it does exist, but isn;t readable then warn the user
1000
std::string cacheFile = m_WhereBuild;
1001
cacheFile += "/CMakeCache.txt";
1002
if(cmSystemTools::FileExists(cacheFile.c_str()))
1004
cmSystemTools::Error("There is a CMakeCache.txt file for the current binary tree but cmake does not have permission to read it. Please check the permissions of the directory you are trying to run CMake on.");
1008
cmCacheManager::CacheIterator itm = cachem->NewIterator();
1009
if ( itm.Find("CMAKE_HOME_DIRECTORY"))
1011
std::string path = ConvertToWindowsPath(itm.GetValue());
1012
this->m_WhereSource = path.c_str();
1013
this->m_WhereSourceControl.SetWindowText(this->m_WhereSource);
1014
this->OnChangeWhereSource();
1016
m_CMakeInstance->SetHomeDirectory(m_WhereSource);
1017
m_CMakeInstance->SetStartDirectory(m_WhereSource);
1018
m_CMakeInstance->SetHomeOutputDirectory(m_WhereBuild);
1019
m_CMakeInstance->SetStartOutputDirectory(m_WhereBuild);
1020
m_CMakeInstance->PreLoadCMakeFiles();
1021
this->FillCacheGUIFromCacheManager();
1022
cmCacheManager::CacheIterator it =
1023
cachem->GetCacheIterator("CMAKE_GENERATOR");
1026
m_GeneratorPicked = true;
1027
const char* extraGen = cachem->GetCacheValue("CMAKE_EXTRA_GENERATOR");
1028
std::string curGen = cmExternalMakefileProjectGenerator::
1029
CreateFullGeneratorName(it.GetValue(), extraGen);
1031
if(m_GeneratorDialog.m_GeneratorChoiceString != curGen.c_str())
1033
m_GeneratorDialog.m_GeneratorChoiceString = curGen.c_str();
1034
this->UpdateData(FALSE);
1040
//! Save GUI values to cmCacheManager and then save to disk.
1041
void CMakeSetupDialog::SaveCacheFromGUI()
1043
cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager();
1044
this->FillCacheManagerFromCacheGUI();
1045
if(m_WhereBuild != "")
1047
cachem->SaveCache(m_WhereBuild);
1052
void CMakeSetupDialog::OnSize(UINT nType, int cx, int cy)
1054
if (nType == SIZE_MINIMIZED)
1056
CDialog::OnSize(nType, cx, cy);
1064
int deltax = cx - m_oldCX;
1065
int deltay = cy - m_oldCY;
1070
CDialog::OnSize(nType, cx, cy);
1072
if (deltax == 0 && deltay == 0)
1077
if(m_CacheEntriesList.m_hWnd)
1079
// get the original sizes/positions
1081
m_AdvancedValuesControl.GetWindowRect(&cRect);
1082
this->ScreenToClient(&cRect);
1083
m_AdvancedValuesControl.SetWindowPos(&wndTop, cRect.left + deltax,
1087
SWP_NOSIZE | SWP_NOZORDER);
1088
m_SuppressDevWarningsControl.GetWindowRect(&cRect);
1089
this->ScreenToClient(&cRect);
1090
m_SuppressDevWarningsControl.SetWindowPos(&wndTop, cRect.left + deltax,
1094
SWP_NOSIZE | SWP_NOZORDER);
1095
m_BrowseSource.GetWindowRect(&cRect);
1096
this->ScreenToClient(&cRect);
1097
m_BrowseSource.SetWindowPos(&wndTop, cRect.left + deltax,
1100
SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOZORDER);
1101
m_BrowseBuild.GetWindowRect(&cRect);
1102
this->ScreenToClient(&cRect);
1103
m_BrowseBuild.SetWindowPos(&wndTop, cRect.left + deltax,
1106
SWP_NOCOPYBITS | SWP_NOSIZE | SWP_NOZORDER);
1108
m_WhereSourceControl.GetWindowRect(&cRect);
1109
m_WhereSourceControl.SetWindowPos(&wndTop, cRect.left, cRect.top,
1110
cRect.Width() + deltax,
1113
SWP_NOMOVE | SWP_NOZORDER);
1114
m_WhereBuildControl.GetWindowRect(&cRect);
1115
m_WhereBuildControl.SetWindowPos(&wndTop, cRect.left, cRect.top,
1116
cRect.Width() + deltax,
1119
SWP_NOMOVE | SWP_NOZORDER);
1120
m_ListFrame.GetWindowRect(&cRect);
1121
m_ListFrame.SetWindowPos(&wndTop, cRect.left, cRect.top,
1122
cRect.Width() + deltax,
1123
cRect.Height() + deltay,
1124
SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER);
1125
m_CacheEntriesList.GetWindowRect(&cRect);
1126
m_CacheEntriesList.SetWindowPos(&wndTop, cRect.left, cRect.top,
1127
cRect.Width() + deltax,
1128
cRect.Height() + deltay,
1129
SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER);
1131
m_StatusDisplay.GetWindowRect(&cRect);
1132
this->ScreenToClient(&cRect);
1133
m_StatusDisplay.SetWindowPos(&wndBottom, cRect.left,
1135
cRect.Width() + deltax, cRect.Height(),
1138
m_MouseHelp.GetWindowRect(&cRect);
1139
this->ScreenToClient(&cRect);
1140
m_MouseHelp.SetWindowPos(&wndTop, cRect.left ,
1142
cRect.Width() + deltax, cRect.Height(),
1143
SWP_NOCOPYBITS | SWP_NOZORDER);
1145
deltax = int(deltax + m_deltaXRemainder);
1146
m_deltaXRemainder = float(deltax%2);
1149
m_Configure.GetWindowRect(&cRect);
1150
this->ScreenToClient(&cRect);
1151
m_Configure.SetWindowPos(&wndTop, cRect.left + deltax/2,
1154
SWP_NOCOPYBITS | SWP_NOSIZE);
1155
m_CancelButton.GetWindowRect(&cRect);
1156
this->ScreenToClient(&cRect);
1157
m_CancelButton.SetWindowPos(&wndTop, cRect.left + deltax/2,
1160
SWP_NOCOPYBITS | SWP_NOSIZE);
1161
m_OKButton.GetWindowRect(&cRect);
1162
this->ScreenToClient(&cRect);
1163
m_OKButton.SetWindowPos(&wndTop, cRect.left + deltax/2,
1166
SWP_NOCOPYBITS | SWP_NOSIZE);
1167
m_DeleteButton.GetWindowRect(&cRect);
1168
this->ScreenToClient(&cRect);
1169
m_DeleteButton.SetWindowPos(&wndTop, cRect.left + deltax/2,
1172
SWP_NOCOPYBITS | SWP_NOSIZE);
1173
m_HelpButton.GetWindowRect(&cRect);
1174
this->ScreenToClient(&cRect);
1175
m_HelpButton.SetWindowPos(&wndTop, cRect.left + deltax/2,
1178
SWP_NOCOPYBITS | SWP_NOSIZE);
1184
void CMakeSetupDialog::OnGetMinMaxInfo( MINMAXINFO FAR* lpMMI )
1186
lpMMI->ptMinTrackSize.x = 550;
1187
lpMMI->ptMinTrackSize.y = 272;
1190
void CMakeSetupDialog::OnCancel()
1192
if(m_RunningConfigure)
1194
if(MessageBox("You are in the middle of a Configure.\n"
1195
"If you Cancel now the configure information will be lost.\n"
1196
"Are you sure you want to Cancel?", "Confirm Exit",
1199
cmSystemTools::SetFatalErrorOccured();
1203
if(m_CacheEntriesList.IsDirty())
1205
if(MessageBox("You have changed options but not rebuilt, "
1206
"are you sure you want to exit?", "Confirm Exit",
1218
void CMakeSetupDialog::OnOk()
1220
// enable error messages each time configure is pressed
1221
cmSystemTools::EnableMessages();
1222
m_CacheEntriesList.ClearDirty();
1223
this->RunCMake(true);
1225
// save the size of the dialog
1228
if (!(::GetKeyState(VK_SHIFT) & 0x1000))
1234
// Create a shortcut on the desktop with the current Source/Build dir.
1235
int CMakeSetupDialog::CreateShortcut()
1237
// Find the desktop folder and create the link name
1240
if(RegOpenKeyEx(HKEY_CURRENT_USER,
1241
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
1242
0, KEY_READ, &hKey) != ERROR_SUCCESS)
1244
AfxMessageBox ("Create shortcut: unable to find 'Shell Folders' key in registry!");
1248
DWORD dwType, dwSize;
1249
#define MAXPATH 1024
1250
char link_name[MAXPATH];
1252
if(RegQueryValueEx(hKey,
1257
&dwSize) != ERROR_SUCCESS)
1259
AfxMessageBox ("Create shortcut: unable to find 'Desktop' registry value in 'Shell Folders' key!");
1263
if(dwType != REG_SZ)
1265
AfxMessageBox ("Create shortcut: 'Desktop' registry value in 'Shell Folders' key has wrong type!");
1269
strcat(link_name, "\\CMake - ");
1270
std::string current_dir = cmSystemTools::GetFilenameName((LPCTSTR)m_WhereSource);
1271
strcat(link_name, current_dir.c_str());
1272
strcat(link_name, ".lnk");
1274
// Find the path to the current executable
1276
char path_to_current_exe[MAXPATH];
1277
::GetModuleFileName(NULL, path_to_current_exe, MAXPATH);
1279
// Create the shortcut
1284
// Initialize the COM library
1286
hres = CoInitialize(NULL);
1288
if (! SUCCEEDED (hres))
1290
AfxMessageBox ("Create shortcut: unable to initialize the COM library!");
1294
// Create an IShellLink object and get a pointer to the IShellLink
1295
// interface (returned from CoCreateInstance).
1297
hres = CoCreateInstance(CLSID_ShellLink,
1299
CLSCTX_INPROC_SERVER,
1303
if (! SUCCEEDED (hres))
1305
AfxMessageBox ("Create shortcut: unable to create IShellLink instance!");
1311
// Query IShellLink for the IPersistFile interface for
1312
// saving the shortcut in persistent storage.
1314
hres = psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
1316
if (SUCCEEDED (hres))
1318
// Set the path to the shortcut target.
1319
hres = psl->SetPath(path_to_current_exe);
1321
if (! SUCCEEDED (hres))
1323
AfxMessageBox ("Create shortcut: SetPath failed!");
1326
// Set the arguments of the shortcut.
1327
CString args = " /H=\"" + m_WhereSource + "\" /B=\"" + m_WhereBuild + "\" /G=\"" + m_GeneratorDialog.m_GeneratorChoiceString + "\" /A=\"" + (m_AdvancedValues ? "TRUE" : "FALSE") + "\"";
1329
hres = psl->SetArguments(args);
1331
if (! SUCCEEDED (hres))
1333
AfxMessageBox ("Create shortcut: SetArguments failed!");
1336
// Set the description of the shortcut.
1337
hres = psl->SetDescription("Shortcut to CMakeSetup");
1339
if (! SUCCEEDED (hres))
1341
AfxMessageBox ("Create shortcut: SetDescription failed!");
1344
// Ensure that the string consists of ANSI characters.
1345
WORD wszAr[MAX_PATH];
1346
LPWSTR wsz = (LPWSTR)wszAr;
1347
MultiByteToWideChar(CP_ACP, 0, link_name, -1, (LPWSTR)(wsz), MAX_PATH);
1349
// Save the shortcut via the IPersistFile::Save member function.
1350
hres = ppf->Save(wsz, TRUE);
1352
if (! SUCCEEDED (hres))
1354
AfxMessageBox ("Create shortcut: Save failed!");
1357
// Release the pointer to IPersistFile.
1360
// Release the pointer to IShellLink.
1366
void CMakeSetupDialog::OnHelpButton()
1372
void CMakeSetupDialog::OnDeleteButton()
1374
std::string message = "Are you sure you want to delete the CMakeCache.txt file for:\n";
1375
message += m_WhereBuild;
1376
if(::MessageBox(0, message.c_str(), "Delete Cache?",
1377
MB_YESNO|MB_TASKMODAL) == IDNO)
1381
m_GeneratorPicked = false;
1383
if(m_WhereBuild != "" && this->m_CMakeInstance)
1385
this->m_CMakeInstance->GetCacheManager()->DeleteCache(m_WhereBuild);
1388
// Make sure we are working from the cache on disk
1389
this->LoadCacheFromDiskToGUI();
1391
m_OKButton.EnableWindow(false);
1394
void CMakeSetupDialog::ShowAdvancedValues()
1396
m_CacheEntriesList.ShowAdvanced();
1399
void CMakeSetupDialog::RemoveAdvancedValues()
1401
m_CacheEntriesList.HideAdvanced();
1405
void CMakeSetupDialog::OnSuppressDevValue()
1409
void CMakeSetupDialog::OnDoubleclickedSuppressDevValue()
1411
this->OnSuppressDevValue();
1414
void CMakeSetupDialog::OnAdvancedValues()
1417
if(m_AdvancedValues)
1419
this->ShowAdvancedValues();
1423
this->RemoveAdvancedValues();
1427
void CMakeSetupDialog::OnDoubleclickedAdvancedValues()
1429
this->OnAdvancedValues();
1432
// Handle param or single dropped file.
1433
void CMakeSetupDialog::ChangeDirectoriesFromFile(const char* arg)
1435
// Check if the argument refers to a CMakeCache.txt or
1436
// CMakeLists.txt file.
1437
std::string listPath;
1438
std::string cachePath;
1439
bool argIsFile = false;
1440
if(cmSystemTools::FileIsDirectory(arg))
1442
std::string path = cmSystemTools::CollapseFullPath(arg);
1443
cmSystemTools::ConvertToUnixSlashes(path);
1444
std::string cacheFile = path;
1445
cacheFile += "/CMakeCache.txt";
1446
std::string listFile = path;
1447
listFile += "/CMakeLists.txt";
1448
if(cmSystemTools::FileExists(cacheFile.c_str()))
1452
if(cmSystemTools::FileExists(listFile.c_str()))
1457
else if(cmSystemTools::FileExists(arg))
1460
std::string fullPath = cmSystemTools::CollapseFullPath(arg);
1461
std::string name = cmSystemTools::GetFilenameName(fullPath.c_str());
1462
name = cmSystemTools::LowerCase(name);
1463
if(name == "cmakecache.txt")
1465
cachePath = cmSystemTools::GetFilenamePath(fullPath.c_str());
1467
else if(name == "cmakelists.txt")
1469
listPath = cmSystemTools::GetFilenamePath(fullPath.c_str());
1473
// If there is a CMakeCache.txt file, use its settings.
1474
if(cachePath.length() > 0)
1476
cmCacheManager* cachem = m_CMakeInstance->GetCacheManager();
1477
cmCacheManager::CacheIterator it = cachem->NewIterator();
1478
if(cachem->LoadCache(cachePath.c_str()) && it.Find("CMAKE_HOME_DIRECTORY"))
1480
std::string path = ConvertToWindowsPath(cachePath.c_str());
1481
m_WhereBuild = path.c_str();
1483
path = ConvertToWindowsPath(it.GetValue());
1484
m_WhereSource = path.c_str();
1486
m_GeneratorDialog.m_GeneratorChoiceString = _T("");
1491
// If there is a CMakeLists.txt file, use it as the source tree.
1492
if(listPath.length() > 0)
1494
std::string path = ConvertToWindowsPath(listPath.c_str());
1495
m_WhereSource = path.c_str();
1499
// Source CMakeLists.txt file given. It was probably dropped
1500
// onto the window or executable. Default to an in-source
1502
m_WhereBuild = path.c_str();
1506
// Source directory given on command line. Use current working
1507
// directory as build tree.
1508
std::string cwd = cmSystemTools::GetCurrentWorkingDirectory();
1509
path = ConvertToWindowsPath(cwd.c_str());
1510
m_WhereBuild = path.c_str();
1516
// The framework calls this member function when the user releases the
1517
// left mouse button over a window that has registered itself as the
1518
// recipient of dropped files.
1520
void CMakeSetupDialog::OnDropFiles(HDROP hDropInfo)
1522
UINT nb_files = DragQueryFile(hDropInfo, 0xFFFFFFFF, NULL, 0);
1525
UINT buffer_size = DragQueryFile(hDropInfo, 0, NULL, 0);
1526
char *buffer = new char [buffer_size + 1];
1527
DragQueryFile(hDropInfo, 0, buffer, buffer_size + 1);
1529
this->ChangeDirectoriesFromFile(buffer);
1532
this->m_WhereSourceControl.SetWindowText(this->m_WhereSource);
1533
this->m_WhereBuildControl.SetWindowText(this->m_WhereBuild);
1535
this->UpdateData(FALSE);
1537
this->OnChangeWhereSource();
1538
this->OnChangeWhereBuild();
1541
DragFinish(hDropInfo);
1544
BOOL CMakeSetupDialog::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
1546
CDialog::OnSetCursor(pWnd, nHitTest, message);
1547
if(m_Cursor == LoadCursor(NULL, IDC_WAIT))
1549
::SetCursor(m_Cursor);