summaryrefslogtreecommitdiffstats
path: root/Source/CursesDialog/cmCursesMainForm.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'Source/CursesDialog/cmCursesMainForm.cxx')
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx381
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);
+ }
+}