Improvements to the curses interface.

This commit is contained in:
Berk Geveci 2001-11-29 16:44:22 -05:00
parent e57a982136
commit 521d8d9410
11 changed files with 442 additions and 138 deletions

View File

@ -6,6 +6,7 @@ SOURCE_FILES( CURSES_SRCS
cmCursesFilePathWidget cmCursesFilePathWidget
cmCursesForm cmCursesForm
cmCursesLabelWidget cmCursesLabelWidget
cmCursesLongMessageForm
cmCursesMainForm cmCursesMainForm
cmCursesPathWidget cmCursesPathWidget
cmCursesStringWidget cmCursesStringWidget

View File

@ -1,5 +1,6 @@
#include "../cmCacheManager.h" #include "../cmCacheManager.h"
#include "../cmSystemTools.h" #include "../cmSystemTools.h"
#include "../cmake.h"
#include <signal.h> #include <signal.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -9,11 +10,11 @@
#include <curses.h> #include <curses.h>
#include <form.h> #include <form.h>
static cmCursesMainForm* myform=0; cmCursesForm* cmCursesForm::CurrentForm=0;
void onsig(int sig) void onsig(int sig)
{ {
if (myform) if (cmCursesForm::CurrentForm)
{ {
endwin(); endwin();
WINDOW* w= initscr(); /* Initialization */ WINDOW* w= initscr(); /* Initialization */
@ -23,30 +24,44 @@ void onsig(int sig)
KEY_DOWN*/ KEY_DOWN*/
refresh(); refresh();
int x,y; int x,y;
getmaxyx(w, y, x); getmaxyx(stdscr, y, x);
myform->SetWindow(w); cmCursesForm::CurrentForm->Render(1,1,x,y);
myform->Render(1,1,x,y); cmCursesForm::CurrentForm->UpdateStatusBar();
myform->UpdateStatusBar();
} }
signal(SIGWINCH, onsig); signal(SIGWINCH, onsig);
} }
void CMakeErrorHandler(const char* message, const char* title, bool& disable)
{
cmCursesForm::CurrentForm->AddError(message, title);
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
unsigned int i;
if ( argc > 2 ) cmake msg;
std::vector<std::string> args;
for(i =0; i < argc; ++i)
{ {
std::cerr << "Usage: " << argv[0] << " source_directory." args.push_back(argv[i]);
<< std::endl;
return -1;
} }
int newCache = false; for(i=1; i < args.size(); ++i)
if (!cmCacheManager::GetInstance()->LoadCache(cmSystemTools::GetCurrentWorkingDirectory().c_str())) {
{ std::string arg = args[i];
newCache = true; if(arg.find("-help",0) != std::string::npos ||
} arg.find("--help",0) != std::string::npos ||
arg.find("/?",0) != std::string::npos ||
arg.find("-usage",0) != std::string::npos)
{
msg.Usage(args[0].c_str());
return -1;
}
}
cmSystemTools::DisableRunCommandOutput();
cmCacheManager::GetInstance()->LoadCache(cmSystemTools::GetCurrentWorkingDirectory().c_str());
WINDOW* w=initscr(); /* Initialization */ WINDOW* w=initscr(); /* Initialization */
noecho(); /* Echo off */ noecho(); /* Echo off */
@ -57,25 +72,40 @@ int main(int argc, char** argv)
signal(SIGWINCH, onsig); signal(SIGWINCH, onsig);
int x,y; int x,y;
getmaxyx(w, y, x); getmaxyx(stdscr, y, x);
std::string whereCMake = cmSystemTools::GetProgramPath(argv[0]); if ( x < cmCursesMainForm::MIN_WIDTH ||
whereCMake += "/cmake"; y < cmCursesMainForm::MIN_HEIGHT )
if ( argc == 2 )
{ {
endwin();
std::cerr << "Window is too small. A size of at least "
<< cmCursesMainForm::MIN_WIDTH << " x "
<< cmCursesMainForm::MIN_HEIGHT
<< " is required to run ccmake." << std::endl;
return 1;
}
cmCursesMainForm* myform;
myform = new cmCursesMainForm(args);
cmSystemTools::SetErrorCallback(CMakeErrorHandler);
cmCursesForm::CurrentForm = myform;
myform->InitializeUI();
myform->RunCMake(false);
myform = new cmCursesMainForm(argv[1], whereCMake.c_str(), newCache);
}
else
{
myform = new cmCursesMainForm("", whereCMake.c_str(), newCache);
}
myform->InitializeUI(w);
myform->Render(1, 1, x, y); myform->Render(1, 1, x, y);
myform->HandleInput(); myform->HandleInput();
// Need to clean-up better // Need to clean-up better
clear();
touchwin(stdscr);
endwin(); endwin();
delete myform; delete cmCursesForm::CurrentForm;
cmCursesForm::CurrentForm = 0;
return 0; return 0;
} }

View File

@ -71,3 +71,15 @@ cmCursesCacheEntryComposite::~cmCursesCacheEntryComposite()
delete m_IsNewLabel; delete m_IsNewLabel;
delete m_Entry; delete m_Entry;
} }
const char* cmCursesCacheEntryComposite::GetValue()
{
if (m_Label)
{
return m_Label->GetValue();
}
else
{
return 0;
}
}

View File

@ -12,6 +12,7 @@ public:
const cmCacheManager::CacheEntry& value, const cmCacheManager::CacheEntry& value,
bool isNew); bool isNew);
~cmCursesCacheEntryComposite(); ~cmCursesCacheEntryComposite();
const char* GetValue();
friend class cmCursesMainForm; friend class cmCursesMainForm;

View File

@ -17,6 +17,17 @@ public:
// Display form. // Display form.
virtual void Render(int left, int top, int width, int height) = 0; virtual void Render(int left, int top, int width, int height) = 0;
// Description:
// This method should normally called only by the form.
// The only exception is during a resize.
virtual void UpdateStatusBar() = 0;
// During a CMake run, an error handle should add errors
// to be displayed afterwards.
virtual void AddError(const char* message, const char* title) {};
static cmCursesForm* CurrentForm;
protected: protected:
cmCursesForm(const cmCursesForm& from); cmCursesForm(const cmCursesForm& from);
void operator=(const cmCursesForm&); void operator=(const cmCursesForm&);

View File

@ -9,6 +9,7 @@
#include "cmCursesFilePathWidget.h" #include "cmCursesFilePathWidget.h"
#include "cmCursesDummyWidget.h" #include "cmCursesDummyWidget.h"
#include "cmCursesCacheEntryComposite.h" #include "cmCursesCacheEntryComposite.h"
#include "cmCursesLongMessageForm.h"
const int cmCursesMainForm::MIN_WIDTH = 65; const int cmCursesMainForm::MIN_WIDTH = 65;
const int cmCursesMainForm::MIN_HEIGHT = 6; const int cmCursesMainForm::MIN_HEIGHT = 6;
@ -20,15 +21,16 @@ inline int ctrl(int z)
return (z&037); return (z&037);
} }
cmCursesMainForm::cmCursesMainForm(const char* whereSource, cmCursesMainForm::cmCursesMainForm(std::vector<std::string> const& args) :
const char* whereCMake, m_Args(args)
bool newCache) :
m_WhereSource(whereSource), m_WhereCMake(whereCMake)
{ {
m_Fields = 0; m_Fields = 0;
m_Window = 0;
m_Height = 0; m_Height = 0;
m_Entries = 0; m_Entries = 0;
m_AdvancedMode = false;
m_NumberOfVisibleEntries = 0;
m_OkToGenerate = false;
m_HelpMessage.push_back(s_ConstHelpMessage);
} }
cmCursesMainForm::~cmCursesMainForm() cmCursesMainForm::~cmCursesMainForm()
@ -72,9 +74,8 @@ bool cmCursesMainForm::LookForCacheEntry(const char* key)
return false; return false;
} }
void cmCursesMainForm::InitializeUI(WINDOW* w) void cmCursesMainForm::InitializeUI()
{ {
m_Window = w;
// Get the cache entries. // Get the cache entries.
const cmCacheManager::CacheEntryMap &cache = const cmCacheManager::CacheEntryMap &cache =
@ -126,6 +127,7 @@ void cmCursesMainForm::InitializeUI(WINDOW* w)
{ {
newEntries->push_back(new cmCursesCacheEntryComposite(key, value, newEntries->push_back(new cmCursesCacheEntryComposite(key, value,
true)); true));
m_OkToGenerate = false;
} }
} }
@ -160,6 +162,12 @@ void cmCursesMainForm::InitializeUI(WINDOW* w)
delete m_Entries; delete m_Entries;
m_Entries = newEntries; m_Entries = newEntries;
this->RePost();
}
void cmCursesMainForm::RePost()
{
// Create the fields to be passed to the form. // Create the fields to be passed to the form.
if (m_Form) if (m_Form)
{ {
@ -168,16 +176,45 @@ void cmCursesMainForm::InitializeUI(WINDOW* w)
m_Form = 0; m_Form = 0;
} }
delete[] m_Fields; delete[] m_Fields;
int size = m_Entries->size();
m_Fields = new FIELD*[3*size+1]; if (m_AdvancedMode)
for(int j=0; j < size; j++)
{ {
m_Fields[3*j] = (*m_Entries)[j]->m_Label->m_Field; m_NumberOfVisibleEntries = m_Entries->size();
m_Fields[3*j+1] = (*m_Entries)[j]->m_IsNewLabel->m_Field;
m_Fields[3*j+2] = (*m_Entries)[j]->m_Entry->m_Field;
} }
else
{
m_NumberOfVisibleEntries = 0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (!m_AdvancedMode && cmCacheManager::GetInstance()->IsAdvanced(
(*it)->GetValue()))
{
continue;
}
m_NumberOfVisibleEntries++;
}
}
m_Fields = new FIELD*[3*m_NumberOfVisibleEntries+1];
int j=0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (!m_AdvancedMode && cmCacheManager::GetInstance()->IsAdvanced(
(*it)->GetValue()))
{
continue;
}
m_Fields[3*j] = (*it)->m_Label->m_Field;
m_Fields[3*j+1] = (*it)->m_IsNewLabel->m_Field;
m_Fields[3*j+2] = (*it)->m_Entry->m_Field;
j++;
}
// Has to be null terminated. // Has to be null terminated.
m_Fields[3*size] = 0; m_Fields[3*m_NumberOfVisibleEntries] = 0;
} }
void cmCursesMainForm::Render(int left, int top, int width, int height) void cmCursesMainForm::Render(int left, int top, int width, int height)
@ -205,41 +242,82 @@ void cmCursesMainForm::Render(int left, int top, int width, int height)
return; return;
} }
height -= 5; height -= 6;
m_Height = height; m_Height = height;
int size = m_Entries->size(); if (m_AdvancedMode)
bool isNewPage;
for(int i=0; i < size; i++)
{ {
m_NumberOfVisibleEntries = m_Entries->size();
}
else
{
m_NumberOfVisibleEntries = 0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (!m_AdvancedMode && cmCacheManager::GetInstance()->IsAdvanced(
(*it)->GetValue()))
{
continue;
}
m_NumberOfVisibleEntries++;
}
}
bool isNewPage;
int i=0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (!m_AdvancedMode && cmCacheManager::GetInstance()->IsAdvanced(
(*it)->GetValue()))
{
continue;
}
int row = (i % height) + 1; int row = (i % height) + 1;
int page = (i / height) + 1; int page = (i / height) + 1;
isNewPage = ( page > 1 ) && ( row == 1 ); isNewPage = ( page > 1 ) && ( row == 1 );
(*m_Entries)[i]->m_Label->Move(left, top+row-1, isNewPage); (*it)->m_Label->Move(left, top+row-1, isNewPage);
(*m_Entries)[i]->m_IsNewLabel->Move(left+32, top+row-1, false); (*it)->m_IsNewLabel->Move(left+32, top+row-1, false);
(*m_Entries)[i]->m_Entry->Move(left+33, top+row-1, false); (*it)->m_Entry->Move(left+33, top+row-1, false);
i++;
} }
m_Form = new_form(m_Fields); m_Form = new_form(m_Fields);
post_form(m_Form); post_form(m_Form);
this->UpdateStatusBar(); this->UpdateStatusBar();
this->PrintKeys(); this->PrintKeys();
touchwin(m_Window); touchwin(stdscr);
refresh(); refresh();
} }
void cmCursesMainForm::PrintKeys() void cmCursesMainForm::PrintKeys()
{ {
int x,y; int x,y;
getmaxyx(m_Window, y, x); getmaxyx(stdscr, y, x);
if ( x < cmCursesMainForm::MIN_WIDTH || if ( x < cmCursesMainForm::MIN_WIDTH ||
y < cmCursesMainForm::MIN_HEIGHT ) y < cmCursesMainForm::MIN_HEIGHT )
{ {
return; return;
} }
char firstLine[512], secondLine[512]; char firstLine[512], secondLine[512];
sprintf(firstLine, "C)onfigure G)enerate and Exit"); if (m_OkToGenerate)
sprintf(secondLine, "Q)uit H)elp"); {
sprintf(firstLine, "C)onfigure G)enerate and Exit H)elp");
}
else
{
sprintf(firstLine, "C)onfigure H)elp");
}
if (m_AdvancedMode)
{
sprintf(secondLine, "Q)uit Without Generating T)oggle Advanced Mode (On)");
}
else
{
sprintf(secondLine, "Q)uit Without Generating T)oggle Advanced Mode (Off)");
}
curses_move(y-2,0); curses_move(y-2,0);
printw(firstLine); printw(firstLine);
@ -254,66 +332,104 @@ void cmCursesMainForm::PrintKeys()
void cmCursesMainForm::UpdateStatusBar() void cmCursesMainForm::UpdateStatusBar()
{ {
int x,y; int x,y;
getmaxyx(m_Window, y, x); getmaxyx(stdscr, y, x);
if ( x < cmCursesMainForm::MIN_WIDTH || if ( x < cmCursesMainForm::MIN_WIDTH ||
y < cmCursesMainForm::MIN_HEIGHT ) y < cmCursesMainForm::MIN_HEIGHT )
{ {
clear();
curses_move(0,0); curses_move(0,0);
printw("Window is too small. A size of at least %dx%d is required.", printw("Window is too small. A size of at least %dx%d is required.",
cmCursesMainForm::MIN_WIDTH, cmCursesMainForm::MIN_HEIGHT); cmCursesMainForm::MIN_WIDTH, cmCursesMainForm::MIN_HEIGHT);
touchwin(m_Window); touchwin(stdscr);
wrefresh(m_Window); wrefresh(stdscr);
return; return;
} }
FIELD* cur = current_field(m_Form); FIELD* cur = current_field(m_Form);
int index = field_index(cur); int index = field_index(cur);
char* curField = field_buffer(m_Fields[index-2], 0); cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(field_userptr(
m_Fields[index-2]));
const char* curField = lbl->GetValue();
// We want to display this on the right
char help[128];
const char* helpString;
cmCacheManager::CacheEntry *entry =
cmCacheManager::GetInstance()->GetCacheEntry(curField);
if (entry)
{
helpString = entry->m_HelpString.c_str();
if (strlen(helpString) > 127)
{
sprintf(help,"%127s", helpString);
}
else
{
sprintf(help,"%s", helpString);
}
}
else
{
sprintf(help," ");
}
char version[128];
sprintf(version,"(CMake Version %d.%d)", cmMakefile::GetMajorVersion(),
cmMakefile::GetMinorVersion());
char bar[cmCursesMainForm::MAX_WIDTH]; char bar[cmCursesMainForm::MAX_WIDTH];
int i, curFieldLen = strlen(curField); int i, curFieldLen = strlen(curField);
int versionLen = strlen(version); int helpLen = strlen(help);
int leftLen = cmCursesMainForm::IDEAL_WIDTH - versionLen;
if (curFieldLen >= leftLen) int width;
if (x < cmCursesMainForm::MAX_WIDTH )
{ {
strncpy(bar, curField, leftLen); width = x;
}
else
{
width = cmCursesMainForm::MAX_WIDTH;
}
int leftLen = width - helpLen;
if (curFieldLen >= width)
{
strncpy(bar, curField, width);
} }
else else
{ {
strcpy(bar, curField); strcpy(bar, curField);
for(i=curFieldLen; i < leftLen; ++i) { bar[i] = ' '; } bar[curFieldLen] = ':';
} bar[curFieldLen+1] = ' ';
strcpy(bar+leftLen, version); if (curFieldLen + helpLen + 2 >= width)
if ( x < cmCursesMainForm::MAX_WIDTH )
{
if (x > cmCursesMainForm::IDEAL_WIDTH )
{ {
for(i=cmCursesMainForm::IDEAL_WIDTH; i < x; i++) strncpy(bar+curFieldLen+2, help, width
{ - curFieldLen - 2);
bar[i] = ' '; }
else
{
strcpy(bar+curFieldLen+2, help);
for(i=curFieldLen+helpLen+2; i < width; ++i)
{
bar[i] = ' ';
} }
} }
bar[x] = '\0';
}
else
{
for(i=cmCursesMainForm::IDEAL_WIDTH;
i < cmCursesMainForm::MAX_WIDTH-1; i++)
{
bar[i] = ' ';
}
bar[cmCursesMainForm::MAX_WIDTH-1] = '\0';
} }
curses_move(y-3,0); bar[width] = '\0';
char version[cmCursesMainForm::MAX_WIDTH];
char vertmp[128];
sprintf(vertmp,"CMake Version %d.%d", cmMakefile::GetMajorVersion(),
cmMakefile::GetMinorVersion());
int sideSpace = (width-strlen(vertmp));
for(i=0; i<sideSpace; i++) { version[i] = ' '; }
sprintf(version+sideSpace, "%s", vertmp);
version[width] = '\0';
curses_move(y-4,0);
attron(A_STANDOUT); attron(A_STANDOUT);
printw(bar); printw(bar);
attroff(A_STANDOUT); attroff(A_STANDOUT);
curses_move(y-3,0);
printw(version);
pos_form_cursor(m_Form); pos_form_cursor(m_Form);
} }
@ -321,8 +437,13 @@ void cmCursesMainForm::RunCMake(bool generateMakefiles)
{ {
int x,y; int x,y;
getmaxyx(m_Window, y, x); getmaxyx(stdscr, y, x);
clear();
curses_move(1,1);
printw("Running CMake, please wait.");
touchwin(stdscr);
refresh();
endwin(); endwin();
// always save the current gui values to disk // always save the current gui values to disk
this->FillCacheManagerFromUI(); this->FillCacheManagerFromUI();
@ -331,32 +452,66 @@ void cmCursesMainForm::RunCMake(bool generateMakefiles)
// create a cmake object // create a cmake object
cmake make; cmake make;
// create the arguments for the cmake object // create the arguments for the cmake object
std::vector<std::string> args; std::string whereCMake = cmSystemTools::GetProgramPath(m_Args[0].c_str());
args.push_back(m_WhereCMake); whereCMake += "/cmake";
if (m_WhereSource != "")
{ m_Args[0] = whereCMake;
std::string arg;
arg = m_WhereSource; // Get rid of previous errors
args.push_back(arg); m_Errors = std::vector<std::string>();
}
// run the generate process // run the generate process
if(make.Generate(args, generateMakefiles) != 0) m_OkToGenerate = true;
if(make.Generate(m_Args, generateMakefiles) != 0 || !m_Errors.empty())
{ {
// TODO : error message here m_OkToGenerate = false;
cmSystemTools::ResetErrorOccuredFlag(); cmSystemTools::ResetErrorOccuredFlag();
int x,y;
getmaxyx(stdscr, y, x);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(m_Errors,
"Errors which during last pass.");
CurrentForm = msgs;
msgs->Render(1,1,x,y);
msgs->HandleInput();
CurrentForm = this;
this->Render(1,1,x,y);
} }
m_Window = initscr(); /* Initialization */ initscr(); /* Initialization */
noecho(); /* Echo off */ noecho(); /* Echo off */
cbreak(); /* nl- or cr not needed */ cbreak(); /* nl- or cr not needed */
keypad(m_Window,TRUE); /* Use key symbols as keypad(stdscr,TRUE); /* Use key symbols as
KEY_DOWN*/ KEY_DOWN*/
this->InitializeUI(m_Window); this->InitializeUI();
this->Render(1, 1, x, y); this->Render(1, 1, x, y);
} }
void cmCursesMainForm::AddError(const char* message, const char* title)
{
m_Errors.push_back(message);
}
void cmCursesMainForm::RemoveEntry(const char* value)
{
if (!value)
{
return;
}
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
const char* val = (*it)->GetValue();
if ( val && !strcmp(value, val) )
{
m_Entries->erase(it);
break;
}
}
}
// copy from the list box to the cache manager // copy from the list box to the cache manager
void cmCursesMainForm::FillCacheManagerFromUI() void cmCursesMainForm::FillCacheManagerFromUI()
{ {
@ -397,7 +552,7 @@ void cmCursesMainForm::HandleInput()
currentWidget = reinterpret_cast<cmCursesWidget*>(field_userptr( currentWidget = reinterpret_cast<cmCursesWidget*>(field_userptr(
currentField)); currentField));
if (!currentWidget || !currentWidget->HandleInput(key, m_Form, m_Window)) if (!currentWidget || !currentWidget->HandleInput(key, m_Form, stdscr))
{ {
// quit // quit
if ( key == 'q' ) if ( key == 'q' )
@ -405,15 +560,19 @@ void cmCursesMainForm::HandleInput()
break; break;
} }
// if not end of page, next field otherwise next page // if not end of page, next field otherwise next page
// each entry consists of fields: label, isnew, value
// therefore, the label field for the prev. entry is index-5
// and the label field for the next entry is index+1
// (index always corresponds to the value field)
else if ( key == KEY_DOWN || key == ctrl('n') ) else if ( key == KEY_DOWN || key == ctrl('n') )
{ {
FIELD* cur = current_field(m_Form); FIELD* cur = current_field(m_Form);
unsigned int index = field_index(cur); unsigned int index = field_index(cur);
if ( index == 3*m_Entries->size()-1 ) if ( index == 3*m_NumberOfVisibleEntries-1 )
{ {
continue; continue;
} }
if ( (index < 3*m_Entries->size()-1) && new_page(m_Fields[index+1])) if (new_page(m_Fields[index+1]))
{ {
form_driver(m_Form, REQ_NEXT_PAGE); form_driver(m_Form, REQ_NEXT_PAGE);
} }
@ -423,6 +582,10 @@ void cmCursesMainForm::HandleInput()
} }
} }
// if not beginning of page, previous field, otherwise previous page // if not beginning of page, previous field, otherwise previous page
// each entry consists of fields: label, isnew, value
// therefore, the label field for the prev. entry is index-5
// and the label field for the next entry is index+1
// (index always corresponds to the value field)
else if ( key == KEY_UP || key == ctrl('p') ) else if ( key == KEY_UP || key == ctrl('p') )
{ {
FIELD* cur = current_field(m_Form); FIELD* cur = current_field(m_Form);
@ -456,11 +619,56 @@ void cmCursesMainForm::HandleInput()
{ {
this->RunCMake(false); this->RunCMake(false);
} }
// display help
else if ( key == 'h' )
{
int x,y;
getmaxyx(stdscr, y, x);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(m_HelpMessage,
"Help.");
CurrentForm = msgs;
msgs->Render(1,1,x,y);
msgs->HandleInput();
CurrentForm = this;
this->Render(1,1,x,y);
}
// display last errors
else if ( key == 'l' )
{
int x,y;
getmaxyx(stdscr, y, x);
cmCursesLongMessageForm* msgs = new cmCursesLongMessageForm(m_Errors,
"Errors which during last pass.");
CurrentForm = msgs;
msgs->Render(1,1,x,y);
msgs->HandleInput();
CurrentForm = this;
this->Render(1,1,x,y);
}
// switch advanced on/off
else if ( key == 't' )
{
if (m_AdvancedMode)
{
m_AdvancedMode = false;
}
else
{
m_AdvancedMode = true;
}
int x,y;
getmaxyx(stdscr, y, x);
this->RePost();
this->Render(1, 1, x, y);
}
// generate and exit // generate and exit
else if ( key == 'g' ) else if ( key == 'g' )
{ {
this->RunCMake(true); if ( m_OkToGenerate )
break; {
this->RunCMake(true);
break;
}
} }
// delete cache entry // delete cache entry
else if ( key == 'd' ) else if ( key == 'd' )
@ -469,11 +677,16 @@ void cmCursesMainForm::HandleInput()
unsigned int index = field_index(cur); unsigned int index = field_index(cur);
// make the next or prev. current field after deletion // make the next or prev. current field after deletion
// each entry consists of fields: label, isnew, value
// therefore, the label field for the prev. entry is index-5
// and the label field for the next entry is index+1
// (index always corresponds to the value field)
FIELD* nextCur; FIELD* nextCur;
if ( index == 2 ) if ( index == 2 )
{ {
nextCur=0;
} }
else if ( index == 3*m_Entries->size()-1 ) else if ( index == 3*m_NumberOfVisibleEntries-1 )
{ {
nextCur = m_Fields[index-5]; nextCur = m_Fields[index-5];
} }
@ -483,36 +696,49 @@ void cmCursesMainForm::HandleInput()
} }
// Get the label widget // Get the label widget
// each entry consists of fields: label, isnew, value
// therefore, the label field for the is index-2
// (index always corresponds to the value field)
cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(field_userptr( cmCursesWidget* lbl = reinterpret_cast<cmCursesWidget*>(field_userptr(
m_Fields[index-2])); m_Fields[index-2]));
cmCacheManager::GetInstance()->RemoveCacheEntry(lbl->GetValue()); cmCacheManager::GetInstance()->RemoveCacheEntry(lbl->GetValue());
std::string nextVal (reinterpret_cast<cmCursesWidget*>(field_userptr(nextCur))->GetValue()); std::string nextVal;
if (nextCur)
{
nextVal = (reinterpret_cast<cmCursesWidget*>(field_userptr(nextCur))->GetValue());
}
int x,y; int x,y;
getmaxyx(m_Window, y, x); getmaxyx(stdscr, y, x);
this->InitializeUI(m_Window); this->RemoveEntry(lbl->GetValue());
this->RePost();
this->Render(1, 1, x, y); this->Render(1, 1, x, y);
// make the next or prev. current field after deletion
nextCur = 0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (nextVal == (*it)->m_Key)
{
nextCur = (*it)->m_Entry->m_Field;
}
}
if (nextCur) if (nextCur)
{ {
set_current_field(m_Form, nextCur); // make the next or prev. current field after deletion
nextCur = 0;
std::vector<cmCursesCacheEntryComposite*>::iterator it;
for (it = m_Entries->begin(); it != m_Entries->end(); ++it)
{
if (nextVal == (*it)->m_Key)
{
nextCur = (*it)->m_Entry->m_Field;
}
}
if (nextCur)
{
set_current_field(m_Form, nextCur);
}
} }
} }
} }
touchwin(m_Window); touchwin(stdscr);
wrefresh(m_Window); wrefresh(stdscr);
} }
} }
const char* cmCursesMainForm::s_ConstHelpMessage = "CMake is used to configure and generate build files for software projects. The basic steps for configuring a project are as follows:\n\n1. Select the source directory for the project. This should contain the CMakeLists.txt files for the project.\n\n2. Select the build directory for the project. This is the directory where the project will be built. It can be the same or a different directory than the source directory. For easy clean up, a separate build directory is recommended. CMake will create the directory if it does not exist.\n\n3. Once the source and binary directories are selected, it is time to press the Configure button. This will cause CMake to read all of the input files and discover all the variables used by the project. The first time a variable is displayed it will be in Red. Users should inspect red variables making sure the values are correct. For some projects the Configure process can be iterative, so continue to press the Configure button until there are no longer red entries.\n\n4. Once there are no longer red entries, you should click the OK button. This will write the build files to the build directory and exit CMake.";

View File

@ -10,13 +10,12 @@ class cmCursesCacheEntryComposite;
class cmCursesMainForm : public cmCursesForm class cmCursesMainForm : public cmCursesForm
{ {
public: public:
cmCursesMainForm(const char* whereSource, const char* whereCMake, cmCursesMainForm(std::vector<string> const& args);
bool newCache);
virtual ~cmCursesMainForm(); virtual ~cmCursesMainForm();
// Description: // Description:
// Set the widgets which represent the cache entries. // Set the widgets which represent the cache entries.
void InitializeUI(WINDOW* w); void InitializeUI();
// Description: // Description:
// Handle user input. // Handle user input.
@ -27,11 +26,6 @@ public:
// at top, left. // at top, left.
virtual void Render(int left, int top, int width, int height); virtual void Render(int left, int top, int width, int height);
// Description:
// Change the window containing the form.
void SetWindow(WINDOW* w)
{ m_Window = w; }
// Description: // Description:
// Returns true if an entry with the given key is in the // Returns true if an entry with the given key is in the
// list of current composites. // list of current composites.
@ -45,26 +39,44 @@ public:
// Description: // Description:
// This method should normally called only by the form. // This method should normally called only by the form.
// The only exception is during a resize. // The only exception is during a resize.
void UpdateStatusBar(); virtual void UpdateStatusBar();
// Description: // Description:
// This method should normally called only by the form. // This method should normally called only by the form.
// The only exception is during a resize. // The only exception is during a resize.
void PrintKeys(); void PrintKeys();
// Description:
// During a CMake run, an error handle should add errors
// to be displayed afterwards.
virtual void AddError(const char* message, const char* title);
// Description:
// Used to run cmake.
void RunCMake(bool generateMakefiles);
protected: protected:
cmCursesMainForm(const cmCursesMainForm& from); cmCursesMainForm(const cmCursesMainForm& from);
void operator=(const cmCursesMainForm&); void operator=(const cmCursesMainForm&);
void RunCMake(bool generateMakefiles);
void FillCacheManagerFromUI(); void FillCacheManagerFromUI();
void RePost();
void RemoveEntry(const char* value);
std::vector<cmCursesCacheEntryComposite*>* m_Entries; std::vector<cmCursesCacheEntryComposite*>* m_Entries;
std::vector<std::string> m_Errors;
std::vector<std::string> m_Args;
std::vector<std::string> m_HelpMessage;
static const char* s_ConstHelpMessage;
FIELD** m_Fields; FIELD** m_Fields;
WINDOW* m_Window;
std::string m_WhereSource; std::string m_WhereSource;
std::string m_WhereCMake; std::string m_WhereCMake;
int m_Height; int m_Height;
int m_NumberOfVisibleEntries;
bool m_AdvancedMode;
bool m_OkToGenerate;
}; };

View File

@ -71,16 +71,21 @@ bool cmListFileCache::CacheFile(const char* path)
std::vector<std::string> arguments; std::vector<std::string> arguments;
cmListFile inFile; cmListFile inFile;
inFile.m_ModifiedTime = cmSystemTools::ModifiedTime(path); inFile.m_ModifiedTime = cmSystemTools::ModifiedTime(path);
bool parseError;
while ( fin ) while ( fin )
{ {
cmListFileFunction inFunction; cmListFileFunction inFunction;
if(cmSystemTools::ParseFunction(fin, if(cmSystemTools::ParseFunction(fin,
inFunction.m_Name, inFunction.m_Name,
inFunction.m_Arguments, inFunction.m_Arguments,
path)) path, parseError))
{ {
inFile.m_Functions.push_back(inFunction); inFile.m_Functions.push_back(inFunction);
} }
if (parseError)
{
inFile.m_ModifiedTime = 0;
}
} }
m_ListFileCache[path] = inFile; m_ListFileCache[path] = inFile;
return true; return true;

View File

@ -522,8 +522,10 @@ const char *cmSystemTools::ConvertToWindowsSlashesAndCleanUp(std::string& path)
bool cmSystemTools::ParseFunction(std::ifstream& fin, bool cmSystemTools::ParseFunction(std::ifstream& fin,
std::string& name, std::string& name,
std::vector<std::string>& arguments, std::vector<std::string>& arguments,
const char* filename) const char* filename,
bool& parseError)
{ {
parseError = false;
name = ""; name = "";
arguments = std::vector<std::string>(); arguments = std::vector<std::string>();
const int BUFFER_SIZE = 4096; const int BUFFER_SIZE = 4096;
@ -586,6 +588,7 @@ bool cmSystemTools::ParseFunction(std::ifstream& fin,
} }
else else
{ {
parseError = true;
cmSystemTools::Error("Parse error in read function missing end )\nIn File: ", cmSystemTools::Error("Parse error in read function missing end )\nIn File: ",
filename, "\nCurrent line:", inbuffer); filename, "\nCurrent line:", inbuffer);
return false; return false;
@ -595,6 +598,7 @@ bool cmSystemTools::ParseFunction(std::ifstream& fin,
} }
else else
{ {
parseError = true;
cmSystemTools::Error("Parse error in read function\nIn file:", cmSystemTools::Error("Parse error in read function\nIn file:",
filename, "\nCurrent line:", inbuffer); filename, "\nCurrent line:", inbuffer);
return false; return false;

View File

@ -133,7 +133,7 @@ public:
static bool ParseFunction(std::ifstream&, static bool ParseFunction(std::ifstream&,
std::string& name, std::string& name,
std::vector<std::string>& arguments, std::vector<std::string>& arguments,
const char* filename); const char* filename, bool& parseError);
/** /**
* Extract white-space separated arguments from a string. * Extract white-space separated arguments from a string.

View File

@ -107,9 +107,11 @@ void ctest::ProcessDirectory(int &passed, int &failed)
cmRegularExpression var(this->m_RegExp.c_str()); cmRegularExpression var(this->m_RegExp.c_str());
cmRegularExpression dartStuff("([\t\n ]*<DartMeasurement.*/DartMeasurement[a-zA-Z]*>[\t ]*[\n]*)"); cmRegularExpression dartStuff("([\t\n ]*<DartMeasurement.*/DartMeasurement[a-zA-Z]*>[\t ]*[\n]*)");
bool parseError;
while ( fin ) while ( fin )
{ {
if(cmSystemTools::ParseFunction(fin, name, args, "DartTestfile.txt")) if(cmSystemTools::ParseFunction(fin, name, args, "DartTestfile.txt",
parseError))
{ {
if (name == "SUBDIRS") if (name == "SUBDIRS")
{ {