diff options
Diffstat (limited to 'Source/CursesDialog/cmCursesMainForm.cxx')
-rw-r--r-- | Source/CursesDialog/cmCursesMainForm.cxx | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/Source/CursesDialog/cmCursesMainForm.cxx b/Source/CursesDialog/cmCursesMainForm.cxx new file mode 100644 index 0000000..52d3ef3 --- /dev/null +++ b/Source/CursesDialog/cmCursesMainForm.cxx @@ -0,0 +1,381 @@ +#include "cmCursesMainForm.h" +#include "cmCursesStringWidget.h" +#include "cmCursesLabelWidget.h" +#include "cmCursesBoolWidget.h" +#include "cmCursesPathWidget.h" +#include "cmCursesFilePathWidget.h" +#include "cmCursesDummyWidget.h" +#include "cmCursesCacheEntryComposite.h" +#include "cmCacheManager.h" +#include "cmSystemTools.h" +#include "cmake.h" + +cmCursesMainForm::cmCursesMainForm(const char* whereSource, + bool newCache) : + m_WhereSource(whereSource) +{ + m_Fields = 0; + m_Window = 0; + m_Height = 0; + m_Entries = 0; +} + +cmCursesMainForm::~cmCursesMainForm() +{ + if (m_Form) + { + unpost_form(m_Form); + free_form(m_Form); + m_Form = 0; + } + delete[] m_Fields; + + // Clean-up composites + if (m_Entries) + { + std::vector<cmCursesCacheEntryComposite*>::iterator it; + for (it = m_Entries->begin(); it != m_Entries->end(); ++it) + { + delete *it; + } + } + delete m_Entries; +} + +bool cmCursesMainForm::LookForCacheEntry(const char* key) +{ + if (!key || !m_Entries) + { + return false; + } + + std::vector<cmCursesCacheEntryComposite*>::iterator it; + for (it = m_Entries->begin(); it != m_Entries->end(); ++it) + { + if (!strcmp(key, (*it)->m_Key.c_str())) + { + return true; + } + } + + return false; +} + +void cmCursesMainForm::InitializeUI(WINDOW* w) +{ + m_Window = w; + + // Get the cache entries. + const cmCacheManager::CacheEntryMap &cache = + cmCacheManager::GetInstance()->GetCacheMap(); + + std::vector<cmCursesCacheEntryComposite*>* newEntries = + new std::vector<cmCursesCacheEntryComposite*>; + newEntries->reserve(cache.size()); + + // Count non-internal and non-static entries + int count=0; + for(cmCacheManager::CacheEntryMap::const_iterator i = cache.begin(); + i != cache.end(); ++i) + { + const cmCacheManager::CacheEntry& value = i->second; + if ( value.m_Type != cmCacheManager::INTERNAL && + value.m_Type != cmCacheManager::STATIC ) + { + ++count; + } + } + + cmCursesCacheEntryComposite* comp; + if ( count == 0 ) + { + // If cache is empty, display a label saying so and a + // dummy entry widget (does not respond to input) + comp = new cmCursesCacheEntryComposite("EMPTY CACHE"); + comp->m_Entry = new cmCursesDummyWidget(1, 1, 1, 1); + newEntries->push_back(comp); + } + else + { + // Create the composites. + + // First add entries which are new + for(cmCacheManager::CacheEntryMap::const_iterator i = cache.begin(); + i != cache.end(); ++i) + { + const char* key = i->first.c_str(); + const cmCacheManager::CacheEntry& value = i->second; + if ( value.m_Type == cmCacheManager::INTERNAL || + value.m_Type == cmCacheManager::STATIC ) + { + continue; + } + + if (!this->LookForCacheEntry(key)) + { + newEntries->push_back(new cmCursesCacheEntryComposite(key, value, + true)); + } + } + + // then add entries which are old + for(cmCacheManager::CacheEntryMap::const_iterator i = cache.begin(); + i != cache.end(); ++i) + { + const char* key = i->first.c_str(); + const cmCacheManager::CacheEntry& value = i->second; + if ( value.m_Type == cmCacheManager::INTERNAL || + value.m_Type == cmCacheManager::STATIC ) + { + continue; + } + + if (this->LookForCacheEntry(key)) + { + newEntries->push_back(new cmCursesCacheEntryComposite(key, value, + false)); + } + } + } + + if (m_Entries) + { + std::vector<cmCursesCacheEntryComposite*>::iterator it; + for (it = m_Entries->begin(); it != m_Entries->end(); ++it) + { + delete *it; + } + } + delete m_Entries; + m_Entries = newEntries; + + // Create the fields to be passed to the form. + if (m_Form) + { + unpost_form(m_Form); + free_form(m_Form); + m_Form = 0; + } + delete[] m_Fields; + int size = m_Entries->size(); + m_Fields = new FIELD*[3*size+1]; + for(int j=0; j < size; j++) + { + m_Fields[3*j] = (*m_Entries)[j]->m_Label->m_Field; + m_Fields[3*j+1] = (*m_Entries)[j]->m_IsNewLabel->m_Field; + m_Fields[3*j+2] = (*m_Entries)[j]->m_Entry->m_Field; + } + // Has to be null terminated. + m_Fields[3*size] = 0; +} + +void cmCursesMainForm::Render(int left, int top, int width, int height) +{ + + if (m_Form) + { + FIELD* currentField = current_field(m_Form); + cmCursesWidget* cw = reinterpret_cast<cmCursesWidget*> + (field_userptr(currentField)); + if ( cw->GetType() == cmCacheManager::STRING || + cw->GetType() == cmCacheManager::PATH || + cw->GetType() == cmCacheManager::FILEPATH ) + { + cmCursesStringWidget* sw = static_cast<cmCursesStringWidget*>(cw); + sw->SetInEdit(false); + } + unpost_form(m_Form); + free_form(m_Form); + m_Form = 0; + } + if ( width < 22 || height < 2 ) + { + return; + } + + std::cerr << "Rendering again." << std::endl; + + height -= 3; + m_Height = height; + + int size = m_Entries->size(); + bool isNewPage; + for(int i=0; i < size; i++) + { + int row = (i % height) + 1; + int page = (i / height) + 1; + isNewPage = ( page > 1 ) && ( row == 1 ); + + (*m_Entries)[i]->m_Label->Move(left, top+row-1, isNewPage); + (*m_Entries)[i]->m_IsNewLabel->Move(left+32, top+row-1, false); + (*m_Entries)[i]->m_Entry->Move(left+33, top+row-1, false); + } + m_Form = new_form(m_Fields); + post_form(m_Form); + this->UpdateCurrentEntry(); + touchwin(m_Window); + refresh(); +} + +void cmCursesMainForm::UpdateCurrentEntry() +{ + FIELD* cur = current_field(m_Form); + int index = field_index(cur); + char* text = field_buffer(m_Fields[index-2], 0); + + int x,y; + getmaxyx(m_Window, y, x); + move(y-1,0); + printw(text); + + char version[128]; + sprintf(version,"CMake Version %d.%d", cmMakefile::GetMajorVersion(), + cmMakefile::GetMinorVersion()); + int len = strlen(version); + move(y-1, x-len); + printw(version); + + pos_form_cursor(m_Form); +} + +void cmCursesMainForm::RunCMake(bool generateMakefiles) +{ + + int x,y; + getmaxyx(m_Window, y, x); + + endwin(); + // always save the current gui values to disk + this->FillCacheManagerFromUI(); + cmCacheManager::GetInstance()->SaveCache(cmSystemTools::GetCurrentWorkingDirectory().c_str()); + + // create a cmake object + cmake make; + // create the arguments for the cmake object + std::vector<std::string> args; + args.push_back("cmake"); + std::string arg; + arg = m_WhereSource; + args.push_back(arg); + // run the generate process + if(make.Generate(args, generateMakefiles) != 0) + { + // TODO : error message here + cmSystemTools::ResetErrorOccuredFlag(); + } + + m_Window = initscr(); /* Initialization */ + noecho(); /* Echo off */ + cbreak(); /* nl- or cr not needed */ + keypad(m_Window,TRUE); /* Use key symbols as + KEY_DOWN*/ + + this->InitializeUI(m_Window); + this->Render(1, 1, x, y); + +} + +// copy from the list box to the cache manager +void cmCursesMainForm::FillCacheManagerFromUI() +{ + + cmCacheManager::GetInstance()->GetCacheMap(); + int size = m_Entries->size(); + for(int i=0; i < size; i++) + { + cmCacheManager::CacheEntry *entry = + cmCacheManager::GetInstance()->GetCacheEntry( + (*m_Entries)[i]->m_Key.c_str()); + if (entry) + { + entry->m_Value = (*m_Entries)[i]->m_Entry->GetValue(); + } + } +} + +void cmCursesMainForm::HandleInput() +{ + if (!m_Form) + { + return; + } + + FIELD* currentField; + cmCursesWidget* currentWidget; + while(1) + { + this->UpdateCurrentEntry(); + int key = getch(); + + currentField = current_field(m_Form); + currentWidget = reinterpret_cast<cmCursesWidget*>(field_userptr( + currentField)); + + if (!currentWidget || !currentWidget->HandleInput(key, m_Form, m_Window)) + { + if ( key == 'q' ) + { + break; + } + else if ( key == KEY_DOWN ) + { + int x,y; + getmaxyx(m_Window, y, x); + FIELD* cur = current_field(m_Form); + int index = field_index(cur); + if ( index == 3*m_Entries->size()-1 ) + { + continue; + } + if ( (index < 3*m_Entries->size()-1) && new_page(m_Fields[index+1])) + { + form_driver(m_Form, REQ_NEXT_PAGE); + } + else + { + form_driver(m_Form, REQ_NEXT_FIELD); + } + } + else if ( key == KEY_UP ) + { + int x,y; + getmaxyx(m_Window, y, x); + FIELD* cur = current_field(m_Form); + int index = field_index(cur); + if ( index == 2 ) + { + continue; + } + if ( new_page(m_Fields[index-2]) ) + { + form_driver(m_Form, REQ_PREV_PAGE); + set_current_field(m_Form, m_Fields[index-3]); + } + else + { + form_driver(m_Form, REQ_PREV_FIELD); + } + } + else if ( key == KEY_NPAGE ) + { + form_driver(m_Form, REQ_NEXT_PAGE); + } + else if ( key == KEY_PPAGE ) + { + form_driver(m_Form, REQ_PREV_PAGE); + } + else if ( key == 'c' ) + { + this->RunCMake(false); + } + else if ( key == 'o' ) + { + this->RunCMake(true); + break; + } + } + + touchwin(m_Window); + wrefresh(m_Window); + } +} |