summaryrefslogtreecommitdiffstats
path: root/Source/CursesDialog
diff options
context:
space:
mode:
authorBerk Geveci <berk.geveci@kitware.com>2001-11-04 23:05:21 (GMT)
committerBerk Geveci <berk.geveci@kitware.com>2001-11-04 23:05:21 (GMT)
commit939d614978ff6772aae619bfbc3ef89e27b69f73 (patch)
tree0b6d52df9911a29a10d25afc7650cf7a1c5ba2f1 /Source/CursesDialog
parentef74458b34dcf2d25b3948c535d59273c2307546 (diff)
downloadCMake-939d614978ff6772aae619bfbc3ef89e27b69f73.zip
CMake-939d614978ff6772aae619bfbc3ef89e27b69f73.tar.gz
CMake-939d614978ff6772aae619bfbc3ef89e27b69f73.tar.bz2
Adding curses support.
Diffstat (limited to 'Source/CursesDialog')
-rw-r--r--Source/CursesDialog/CMakeLists.txt18
-rw-r--r--Source/CursesDialog/ccurses.cxx71
-rw-r--r--Source/CursesDialog/cmCursesBoolWidget.cxx61
-rw-r--r--Source/CursesDialog/cmCursesBoolWidget.h28
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.cxx73
-rw-r--r--Source/CursesDialog/cmCursesCacheEntryComposite.h28
-rw-r--r--Source/CursesDialog/cmCursesDummyWidget.cxx15
-rw-r--r--Source/CursesDialog/cmCursesDummyWidget.h23
-rw-r--r--Source/CursesDialog/cmCursesFilePathWidget.cxx9
-rw-r--r--Source/CursesDialog/cmCursesFilePathWidget.h17
-rw-r--r--Source/CursesDialog/cmCursesForm.cxx16
-rw-r--r--Source/CursesDialog/cmCursesForm.h28
-rw-r--r--Source/CursesDialog/cmCursesLabelWidget.cxx21
-rw-r--r--Source/CursesDialog/cmCursesLabelWidget.h28
-rw-r--r--Source/CursesDialog/cmCursesMainForm.cxx381
-rw-r--r--Source/CursesDialog/cmCursesMainForm.h55
-rw-r--r--Source/CursesDialog/cmCursesPathWidget.cxx9
-rw-r--r--Source/CursesDialog/cmCursesPathWidget.h17
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.cxx106
-rw-r--r--Source/CursesDialog/cmCursesStringWidget.h39
-rw-r--r--Source/CursesDialog/cmCursesWidget.cxx46
-rw-r--r--Source/CursesDialog/cmCursesWidget.h47
22 files changed, 1136 insertions, 0 deletions
diff --git a/Source/CursesDialog/CMakeLists.txt b/Source/CursesDialog/CMakeLists.txt
new file mode 100644
index 0000000..63d958d
--- /dev/null
+++ b/Source/CursesDialog/CMakeLists.txt
@@ -0,0 +1,18 @@
+SOURCE_FILES( CURSES_SRCS
+ cmCursesBoolWidget
+ cmCursesCacheEntryComposite
+ cmCursesDummyWidget
+ cmCursesFilePathWidget
+ cmCursesForm
+ cmCursesLabelWidget
+ cmCursesMainForm
+ cmCursesPathWidget
+ cmCursesStringWidget
+ cmCursesWidget
+ ccurses
+ )
+
+INCLUDE_DIRECTORIES(${CURSES_INCLUDE_PATH})
+LINK_LIBRARIES(${CURSES_LIBRARY} ${FORM_LIBRARY})
+
+ADD_EXECUTABLE(ccurses CURSES_SRCS) \ No newline at end of file
diff --git a/Source/CursesDialog/ccurses.cxx b/Source/CursesDialog/ccurses.cxx
new file mode 100644
index 0000000..21b07e3
--- /dev/null
+++ b/Source/CursesDialog/ccurses.cxx
@@ -0,0 +1,71 @@
+#include "cmCursesMainForm.h"
+#include "cmCacheManager.h"
+#include "cmSystemTools.h"
+
+#include <curses.h>
+#include <form.h>
+#include <signal.h>
+#include <sys/ioctl.h>
+
+static cmCursesMainForm* myform=0;
+//std::ofstream log("log.txt", std::ios::out);
+
+void onsig(int sig)
+{
+ if (myform)
+ {
+ endwin();
+ WINDOW* w= initscr(); /* Initialization */
+ noecho(); /* Echo off */
+ cbreak(); /* nl- or cr not needed */
+ keypad(stdscr,TRUE); /* Use key symbols as
+ KEY_DOWN*/
+ refresh();
+ int x,y;
+ getmaxyx(w, y, x);
+ myform->SetWindow(w);
+ myform->Render(1,1,x,y);
+ std::cerr << "Size change: " << x << " " << y << std::endl;
+ }
+ signal(SIGWINCH, onsig);
+}
+
+int main(int argc, char** argv)
+{
+
+ if ( argc != 2 )
+ {
+ std::cerr << "Usage: " << argv[0] << " source_directory"
+ << std::endl;
+ return -1;
+ }
+
+ int newCache = false;
+ if (!cmCacheManager::GetInstance()->LoadCache(cmSystemTools::GetCurrentWorkingDirectory().c_str()))
+ {
+ newCache = true;
+ }
+
+
+ WINDOW* w=initscr(); /* Initialization */
+ noecho(); /* Echo off */
+ cbreak(); /* nl- or cr not needed */
+ keypad(stdscr,TRUE); /* Use key symbols as
+ KEY_DOWN*/
+
+ signal(SIGWINCH, onsig);
+
+ int x,y;
+ getmaxyx(w, y, x);
+
+ myform = new cmCursesMainForm(argv[1], newCache);
+ myform->InitializeUI(w);
+ myform->Render(1, 1, x, y);
+ myform->HandleInput();
+
+ // Need to clean-up better
+ endwin();
+ delete myform;
+ return 0;
+
+}
diff --git a/Source/CursesDialog/cmCursesBoolWidget.cxx b/Source/CursesDialog/cmCursesBoolWidget.cxx
new file mode 100644
index 0000000..4057a3f
--- /dev/null
+++ b/Source/CursesDialog/cmCursesBoolWidget.cxx
@@ -0,0 +1,61 @@
+#include "cmCursesBoolWidget.h"
+
+cmCursesBoolWidget::cmCursesBoolWidget(int width, int height,
+ int left, int top) :
+ cmCursesWidget(width, height, left, top)
+{
+ m_Type = cmCacheManager::BOOL;
+ set_field_fore(m_Field, A_NORMAL);
+ set_field_back(m_Field, A_STANDOUT);
+ field_opts_off(m_Field, O_STATIC);
+ this->SetValueAsBool(false);
+}
+
+bool cmCursesBoolWidget::HandleInput(int& key, FORM* form, WINDOW* w)
+{
+ // 10 == enter
+ if (key == 10)
+ {
+ if (this->GetValueAsBool())
+ {
+ this->SetValueAsBool(false);
+ }
+ else
+ {
+ this->SetValueAsBool(true);
+ }
+
+ touchwin(w);
+ wrefresh(w);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+
+}
+
+void cmCursesBoolWidget::SetValueAsBool(bool value)
+{
+ if (value)
+ {
+ this->SetValue("ON");
+ }
+ else
+ {
+ this->SetValue("OFF");
+ }
+}
+
+bool cmCursesBoolWidget::GetValueAsBool()
+{
+ if (m_Value == "ON")
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
diff --git a/Source/CursesDialog/cmCursesBoolWidget.h b/Source/CursesDialog/cmCursesBoolWidget.h
new file mode 100644
index 0000000..a4dff63
--- /dev/null
+++ b/Source/CursesDialog/cmCursesBoolWidget.h
@@ -0,0 +1,28 @@
+#ifndef __cmCursesBoolWidget_h
+#define __cmCursesBoolWidget_h
+
+#include "cmCursesWidget.h"
+
+class cmCursesBoolWidget : public cmCursesWidget
+{
+public:
+ cmCursesBoolWidget(int width, int height, int left, int top);
+
+ // Description:
+ // Handle user input. Called by the container of this widget
+ // when this widget has focus. Returns true if the input was
+ // handled.
+ virtual bool HandleInput(int& key, FORM* form, WINDOW* w);
+
+ // Description:
+ // Set/Get the value (on/off).
+ void SetValueAsBool(bool value);
+ bool GetValueAsBool();
+
+protected:
+ cmCursesBoolWidget(const cmCursesBoolWidget& from);
+ void operator=(const cmCursesBoolWidget&);
+
+};
+
+#endif // __cmCursesBoolWidget_h
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.cxx b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
new file mode 100644
index 0000000..1391e0e
--- /dev/null
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.cxx
@@ -0,0 +1,73 @@
+#include "cmCursesCacheEntryComposite.h"
+#include "cmCursesStringWidget.h"
+#include "cmCursesLabelWidget.h"
+#include "cmCursesBoolWidget.h"
+#include "cmCursesPathWidget.h"
+#include "cmCursesFilePathWidget.h"
+#include "cmCursesDummyWidget.h"
+#include "cmSystemTools.h"
+
+cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(const char* key) :
+ m_Key(key)
+{
+ m_Label = new cmCursesLabelWidget(30, 1, 1, 1, key);
+ m_IsNewLabel = new cmCursesLabelWidget(1, 1, 1, 1, " ");
+ m_Entry = 0;
+}
+
+cmCursesCacheEntryComposite::cmCursesCacheEntryComposite(
+ const char* key, const cmCacheManager::CacheEntry& value, bool isNew) :
+ m_Key(key)
+{
+ m_Label = new cmCursesLabelWidget(30, 1, 1, 1, key);
+ if (isNew)
+ {
+ m_IsNewLabel = new cmCursesLabelWidget(1, 1, 1, 1, "*");
+ }
+ else
+ {
+ m_IsNewLabel = new cmCursesLabelWidget(1, 1, 1, 1, " ");
+ }
+
+ m_Entry = 0;
+ switch ( value.m_Type )
+ {
+ case cmCacheManager::BOOL:
+ m_Entry = new cmCursesBoolWidget(30, 1, 1, 1);
+ if (cmSystemTools::IsOn(value.m_Value.c_str()))
+ {
+ static_cast<cmCursesBoolWidget*>(m_Entry)->SetValueAsBool(true);
+ }
+ else
+ {
+ static_cast<cmCursesBoolWidget*>(m_Entry)->SetValueAsBool(false);
+ }
+ break;
+ case cmCacheManager::PATH:
+ m_Entry = new cmCursesPathWidget(30, 1, 1, 1);
+ static_cast<cmCursesPathWidget*>(m_Entry)->SetString(
+ value.m_Value.c_str());
+ break;
+ case cmCacheManager::FILEPATH:
+ m_Entry = new cmCursesFilePathWidget(30, 1, 1, 1);
+ static_cast<cmCursesFilePathWidget*>(m_Entry)->SetString(
+ value.m_Value.c_str());
+ break;
+ case cmCacheManager::STRING:
+ m_Entry = new cmCursesStringWidget(30, 1, 1, 1);
+ static_cast<cmCursesStringWidget*>(m_Entry)->SetString(
+ value.m_Value.c_str());
+ break;
+ default:
+ // TODO : put warning message here
+ break;
+ }
+
+}
+
+cmCursesCacheEntryComposite::~cmCursesCacheEntryComposite()
+{
+ delete m_Label;
+ delete m_IsNewLabel;
+ delete m_Entry;
+}
diff --git a/Source/CursesDialog/cmCursesCacheEntryComposite.h b/Source/CursesDialog/cmCursesCacheEntryComposite.h
new file mode 100644
index 0000000..e22f551
--- /dev/null
+++ b/Source/CursesDialog/cmCursesCacheEntryComposite.h
@@ -0,0 +1,28 @@
+#ifndef __cmCursesCacheEntryComposite_h
+#define __cmCursesCacheEntryComposite_h
+
+#include "cmCursesLabelWidget.h"
+#include "cmCacheManager.h"
+
+class cmCursesCacheEntryComposite
+{
+public:
+ cmCursesCacheEntryComposite(const char* key);
+ cmCursesCacheEntryComposite(const char* key,
+ const cmCacheManager::CacheEntry& value,
+ bool isNew);
+ ~cmCursesCacheEntryComposite();
+
+ friend class cmCursesMainForm;
+
+protected:
+ cmCursesCacheEntryComposite(const cmCursesCacheEntryComposite& from);
+ void operator=(const cmCursesCacheEntryComposite&);
+
+ cmCursesLabelWidget* m_Label;
+ cmCursesLabelWidget* m_IsNewLabel;
+ cmCursesWidget* m_Entry;
+ std::string m_Key;
+};
+
+#endif // __cmCursesCacheEntryComposite_h
diff --git a/Source/CursesDialog/cmCursesDummyWidget.cxx b/Source/CursesDialog/cmCursesDummyWidget.cxx
new file mode 100644
index 0000000..432b3e1
--- /dev/null
+++ b/Source/CursesDialog/cmCursesDummyWidget.cxx
@@ -0,0 +1,15 @@
+#include "cmCursesDummyWidget.h"
+
+cmCursesDummyWidget::cmCursesDummyWidget(int width, int height,
+ int left, int top) :
+ cmCursesWidget(width, height, left, top)
+{
+ m_Type = cmCacheManager::INTERNAL;
+}
+
+
+bool cmCursesDummyWidget::HandleInput(int& key, FORM* form, WINDOW* w)
+{
+ return false;
+}
+
diff --git a/Source/CursesDialog/cmCursesDummyWidget.h b/Source/CursesDialog/cmCursesDummyWidget.h
new file mode 100644
index 0000000..ead9699
--- /dev/null
+++ b/Source/CursesDialog/cmCursesDummyWidget.h
@@ -0,0 +1,23 @@
+#ifndef __cmCursesDummyWidget_h
+#define __cmCursesDummyWidget_h
+
+#include "cmCursesWidget.h"
+
+class cmCursesDummyWidget : public cmCursesWidget
+{
+public:
+ cmCursesDummyWidget(int width, int height, int left, int top);
+
+ // Description:
+ // Handle user input. Called by the container of this widget
+ // when this widget has focus. Returns true if the input was
+ // handled.
+ virtual bool HandleInput(int& key, FORM* form, WINDOW* w);
+
+protected:
+ cmCursesDummyWidget(const cmCursesDummyWidget& from);
+ void operator=(const cmCursesDummyWidget&);
+
+};
+
+#endif // __cmCursesDummyWidget_h
diff --git a/Source/CursesDialog/cmCursesFilePathWidget.cxx b/Source/CursesDialog/cmCursesFilePathWidget.cxx
new file mode 100644
index 0000000..e1c7058
--- /dev/null
+++ b/Source/CursesDialog/cmCursesFilePathWidget.cxx
@@ -0,0 +1,9 @@
+#include "cmCursesFilePathWidget.h"
+
+cmCursesFilePathWidget::cmCursesFilePathWidget(int width, int height,
+ int left, int top) :
+ cmCursesStringWidget(width, height, left, top)
+{
+ m_Type = cmCacheManager::FILEPATH;
+}
+
diff --git a/Source/CursesDialog/cmCursesFilePathWidget.h b/Source/CursesDialog/cmCursesFilePathWidget.h
new file mode 100644
index 0000000..7c8268b
--- /dev/null
+++ b/Source/CursesDialog/cmCursesFilePathWidget.h
@@ -0,0 +1,17 @@
+#ifndef __cmCursesFilePathWidget_h
+#define __cmCursesFilePathWidget_h
+
+#include "cmCursesStringWidget.h"
+
+class cmCursesFilePathWidget : public cmCursesStringWidget
+{
+public:
+ cmCursesFilePathWidget(int width, int height, int left, int top);
+
+protected:
+ cmCursesFilePathWidget(const cmCursesFilePathWidget& from);
+ void operator=(const cmCursesFilePathWidget&);
+
+};
+
+#endif // __cmCursesFilePathWidget_h
diff --git a/Source/CursesDialog/cmCursesForm.cxx b/Source/CursesDialog/cmCursesForm.cxx
new file mode 100644
index 0000000..8d9c444
--- /dev/null
+++ b/Source/CursesDialog/cmCursesForm.cxx
@@ -0,0 +1,16 @@
+#include "cmCursesForm.h"
+
+cmCursesForm::cmCursesForm()
+{
+ m_Form = 0;
+}
+
+cmCursesForm::~cmCursesForm()
+{
+ if (m_Form)
+ {
+ unpost_form(m_Form);
+ free_form(m_Form);
+ m_Form = 0;
+ }
+}
diff --git a/Source/CursesDialog/cmCursesForm.h b/Source/CursesDialog/cmCursesForm.h
new file mode 100644
index 0000000..4924f2e
--- /dev/null
+++ b/Source/CursesDialog/cmCursesForm.h
@@ -0,0 +1,28 @@
+#ifndef __cmCursesForm_h
+#define __cmCursesForm_h
+
+#include <curses.h>
+#include <form.h>
+
+class cmCursesForm
+{
+public:
+ cmCursesForm();
+ virtual ~cmCursesForm();
+
+ // Description:
+ // Handle user input.
+ virtual void HandleInput() = 0;
+
+ // Description:
+ // Display form.
+ virtual void Render(int left, int top, int width, int height) = 0;
+
+protected:
+ cmCursesForm(const cmCursesForm& from);
+ void operator=(const cmCursesForm&);
+
+ FORM* m_Form;
+};
+
+#endif // __cmCursesForm_h
diff --git a/Source/CursesDialog/cmCursesLabelWidget.cxx b/Source/CursesDialog/cmCursesLabelWidget.cxx
new file mode 100644
index 0000000..6c8adcc
--- /dev/null
+++ b/Source/CursesDialog/cmCursesLabelWidget.cxx
@@ -0,0 +1,21 @@
+#include "cmCursesLabelWidget.h"
+
+cmCursesLabelWidget::cmCursesLabelWidget(int width, int height,
+ int left, int top,
+ const std::string& name) :
+ cmCursesWidget(width, height, left, top)
+{
+ field_opts_off(m_Field, O_EDIT);
+ field_opts_off(m_Field, O_ACTIVE);
+ this->SetValue(name.c_str());
+}
+
+cmCursesLabelWidget::~cmCursesLabelWidget()
+{
+}
+
+bool cmCursesLabelWidget::HandleInput(int& key, FORM* form, WINDOW* w)
+{
+ // Static text. No input is handled here.
+ return false;
+}
diff --git a/Source/CursesDialog/cmCursesLabelWidget.h b/Source/CursesDialog/cmCursesLabelWidget.h
new file mode 100644
index 0000000..b32eb0d
--- /dev/null
+++ b/Source/CursesDialog/cmCursesLabelWidget.h
@@ -0,0 +1,28 @@
+#ifndef __cmCursesLabelWidget_h
+#define __cmCursesLabelWidget_h
+
+#include <iostream>
+#include <curses.h>
+#include <form.h>
+#include "cmCursesWidget.h"
+
+
+class cmCursesLabelWidget : public cmCursesWidget
+{
+public:
+ cmCursesLabelWidget(int width, int height, int left, int top,
+ const std::string& name);
+ virtual ~cmCursesLabelWidget();
+
+ // Description:
+ // Handle user input. Called by the container of this widget
+ // when this widget has focus. Returns true if the input was
+ // handled
+ virtual bool HandleInput(int& key, FORM* form, WINDOW* w);
+
+protected:
+ cmCursesLabelWidget(const cmCursesLabelWidget& from);
+ void operator=(const cmCursesLabelWidget&);
+};
+
+#endif // __cmCursesLabelWidget_h
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);
+ }
+}
diff --git a/Source/CursesDialog/cmCursesMainForm.h b/Source/CursesDialog/cmCursesMainForm.h
new file mode 100644
index 0000000..7e4a7f7
--- /dev/null
+++ b/Source/CursesDialog/cmCursesMainForm.h
@@ -0,0 +1,55 @@
+#ifndef __cmCursesMainForm_h
+#define __cmCursesMainForm_h
+
+#include <iostream>
+#include <curses.h>
+#include <form.h>
+#include "cmCursesForm.h"
+
+class cmCursesCacheEntryComposite;
+
+class cmCursesMainForm : public cmCursesForm
+{
+public:
+ cmCursesMainForm(const char* whereSource, bool newCache);
+ virtual ~cmCursesMainForm();
+
+ // Description:
+ // Set the widgets which represent the cache entries.
+ void InitializeUI(WINDOW* w);
+
+ // Description:
+ // Handle user input.
+ virtual void HandleInput();
+
+ // Description:
+ // Display form. Use a window of size width x height, starting
+ // at top, left.
+ 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:
+ // Returns true if an entry with the given key is in the
+ // list of current composites.
+ bool LookForCacheEntry(const char* key);
+
+protected:
+ cmCursesMainForm(const cmCursesMainForm& from);
+ void operator=(const cmCursesMainForm&);
+
+ void UpdateCurrentEntry();
+ void RunCMake(bool generateMakefiles);
+ void FillCacheManagerFromUI();
+
+ std::vector<cmCursesCacheEntryComposite*>* m_Entries;
+ FIELD** m_Fields;
+ WINDOW* m_Window;
+ std::string m_WhereSource;
+ int m_Height;
+};
+
+#endif // __cmCursesMainForm_h
diff --git a/Source/CursesDialog/cmCursesPathWidget.cxx b/Source/CursesDialog/cmCursesPathWidget.cxx
new file mode 100644
index 0000000..8f86272
--- /dev/null
+++ b/Source/CursesDialog/cmCursesPathWidget.cxx
@@ -0,0 +1,9 @@
+#include "cmCursesPathWidget.h"
+
+cmCursesPathWidget::cmCursesPathWidget(int width, int height,
+ int left, int top) :
+ cmCursesStringWidget(width, height, left, top)
+{
+ m_Type = cmCacheManager::PATH;
+}
+
diff --git a/Source/CursesDialog/cmCursesPathWidget.h b/Source/CursesDialog/cmCursesPathWidget.h
new file mode 100644
index 0000000..a1f9b23
--- /dev/null
+++ b/Source/CursesDialog/cmCursesPathWidget.h
@@ -0,0 +1,17 @@
+#ifndef __cmCursesPathWidget_h
+#define __cmCursesPathWidget_h
+
+#include "cmCursesStringWidget.h"
+
+class cmCursesPathWidget : public cmCursesStringWidget
+{
+public:
+ cmCursesPathWidget(int width, int height, int left, int top);
+
+protected:
+ cmCursesPathWidget(const cmCursesPathWidget& from);
+ void operator=(const cmCursesPathWidget&);
+
+};
+
+#endif // __cmCursesPathWidget_h
diff --git a/Source/CursesDialog/cmCursesStringWidget.cxx b/Source/CursesDialog/cmCursesStringWidget.cxx
new file mode 100644
index 0000000..90ca05c
--- /dev/null
+++ b/Source/CursesDialog/cmCursesStringWidget.cxx
@@ -0,0 +1,106 @@
+#include "cmCursesStringWidget.h"
+inline int ctrl(int z)
+{
+ return (z&037);
+}
+
+cmCursesStringWidget::cmCursesStringWidget(int width, int height,
+ int left, int top) :
+ cmCursesWidget(width, height, left, top)
+{
+ m_InEdit = false;
+ m_Type = cmCacheManager::STRING;
+ set_field_fore(m_Field, A_NORMAL);
+ set_field_back(m_Field, A_STANDOUT);
+ field_opts_off(m_Field, O_STATIC);
+}
+
+
+bool cmCursesStringWidget::HandleInput(int& key, FORM* form, WINDOW* w)
+{
+ // 10 == enter
+ if (!m_InEdit && ( key != 10 ) )
+ {
+ return false;
+ }
+
+ char* originalStr=0;
+
+ // <Enter> is used to change edit mode (like <Esc> in vi).
+ while(1)
+ {
+ if (!m_InEdit && ( key != 10 ) )
+ {
+ return false;
+ }
+ // 10 == enter
+ if (key == 10)
+ {
+ if (m_InEdit)
+ {
+ m_InEdit = false;
+ delete[] originalStr;
+ // trick to force forms to update the field buffer
+ form_driver(form, REQ_NEXT_FIELD);
+ form_driver(form, REQ_PREV_FIELD);
+ return true;
+ }
+ else
+ {
+ m_InEdit = true;
+ char* buf = field_buffer(m_Field, 0);
+ originalStr = new char[strlen(buf)+1];
+ strcpy(originalStr, buf);
+ }
+ }
+ else if (key == 27)
+ {
+ if (m_InEdit)
+ {
+ m_InEdit = false;
+ this->SetString(originalStr);
+ delete[] originalStr;
+ touchwin(w);
+ wrefresh(w);
+ return true;
+ }
+ }
+ else if ( key == KEY_LEFT || key == ctrl('b') )
+ {
+ form_driver(form, REQ_PREV_CHAR);
+ }
+ else if ( key == KEY_RIGHT || key == ctrl('f') )
+ {
+ form_driver(form, REQ_NEXT_CHAR);
+ }
+ else if ( key == ctrl('d') || key == 127 )
+ {
+ form_driver(form, REQ_DEL_PREV);
+ }
+ else
+ {
+ form_driver(form, key);
+ }
+
+ touchwin(w);
+ wrefresh(w);
+
+ key=getch();
+ }
+}
+
+void cmCursesStringWidget::SetString(const char* value)
+{
+ this->SetValue(value);
+}
+
+const char* cmCursesStringWidget::GetString()
+{
+ return this->GetValue();
+}
+
+const char* cmCursesStringWidget::GetValue()
+{
+ std::cout << field_buffer(m_Field, 0) << std::endl;
+ return field_buffer(m_Field, 0);
+}
diff --git a/Source/CursesDialog/cmCursesStringWidget.h b/Source/CursesDialog/cmCursesStringWidget.h
new file mode 100644
index 0000000..29fb281
--- /dev/null
+++ b/Source/CursesDialog/cmCursesStringWidget.h
@@ -0,0 +1,39 @@
+#ifndef __cmCursesStringWidget_h
+#define __cmCursesStringWidget_h
+
+#include "cmCursesWidget.h"
+
+class cmCursesStringWidget : public cmCursesWidget
+{
+public:
+ cmCursesStringWidget(int width, int height, int left, int top);
+
+ // Description:
+ // Handle user input. Called by the container of this widget
+ // when this widget has focus. Returns true if the input was
+ // handled.
+ virtual bool HandleInput(int& key, FORM* form, WINDOW* w);
+
+ // Description:
+ // Set/Get the string.
+ void SetString(const char* value);
+ const char* GetString();
+ virtual const char* GetValue();
+
+ // Description:
+ // Set/Get InEdit flag. Can be used to tell the widget to leave
+ // edit mode (in case of a resize for example).
+ void SetInEdit(bool inedit)
+ { m_InEdit = inedit; }
+ bool GetInEdit()
+ { return m_InEdit; }
+
+protected:
+ cmCursesStringWidget(const cmCursesStringWidget& from);
+ void operator=(const cmCursesStringWidget&);
+
+ // true if the widget is in edit mode
+ bool m_InEdit;
+};
+
+#endif // __cmCursesStringWidget_h
diff --git a/Source/CursesDialog/cmCursesWidget.cxx b/Source/CursesDialog/cmCursesWidget.cxx
new file mode 100644
index 0000000..55c9e76
--- /dev/null
+++ b/Source/CursesDialog/cmCursesWidget.cxx
@@ -0,0 +1,46 @@
+#include "cmCursesWidget.h"
+
+cmCursesWidget::cmCursesWidget(int width, int height, int left, int top)
+{
+ m_Field = new_field(height, width, top, left, 0, 0);
+ set_field_userptr(m_Field, reinterpret_cast<char*>(this));
+ field_opts_off(m_Field, O_AUTOSKIP);
+}
+
+cmCursesWidget::~cmCursesWidget()
+{
+ if (m_Field)
+ {
+ free_field(m_Field);
+ m_Field = 0;
+ }
+}
+
+void cmCursesWidget::Move(int x, int y, bool isNewPage)
+{
+ if (!m_Field)
+ {
+ return;
+ }
+
+ move_field(m_Field, y, x);
+ if (isNewPage)
+ {
+ set_new_page(m_Field, TRUE);
+ }
+ else
+ {
+ set_new_page(m_Field, FALSE);
+ }
+}
+
+void cmCursesWidget::SetValue(const char* value)
+{
+ m_Value = value;
+ set_field_buffer(m_Field, 0, value);
+}
+
+const char* cmCursesWidget::GetValue()
+{
+ return m_Value.c_str();
+}
diff --git a/Source/CursesDialog/cmCursesWidget.h b/Source/CursesDialog/cmCursesWidget.h
new file mode 100644
index 0000000..3e0a8e4
--- /dev/null
+++ b/Source/CursesDialog/cmCursesWidget.h
@@ -0,0 +1,47 @@
+#ifndef __cmCursesWidget_h
+#define __cmCursesWidget_h
+
+#include <curses.h>
+#include <form.h>
+#include "cmCacheManager.h"
+
+class cmCursesWidget
+{
+public:
+ cmCursesWidget(int width, int height, int left, int top);
+ virtual ~cmCursesWidget();
+
+ // Description:
+ // Handle user input. Called by the container of this widget
+ // when this widget has focus. Returns true if the input was
+ // handled
+ virtual bool HandleInput(int& key, FORM* form, WINDOW* w) = 0;
+
+ // Description:
+ // Change the position of the widget. Set isNewPage to true
+ // if this widget marks the beginning of a new page.
+ virtual void Move(int x, int y, bool isNewPage);
+
+ // Description:
+ // Set/Get the value (setting the value also changes the contents
+ // of the field buffer).
+ virtual void SetValue(const char* value);
+ virtual const char* GetValue();
+
+ // Description:
+ // Get the type of the widget (STRING, PATH etc...)
+ cmCacheManager::CacheEntryType GetType()
+ { return m_Type; }
+
+ friend class cmCursesMainForm;
+
+protected:
+ cmCursesWidget(const cmCursesWidget& from);
+ void operator=(const cmCursesWidget&);
+
+ cmCacheManager::CacheEntryType m_Type;
+ std::string m_Value;
+ FIELD* m_Field;
+};
+
+#endif // __cmCursesWidget_h