Просмотр исходного кода

ENH: try to find a gui for the Mac

Bill Hoffman 20 лет назад
Родитель
Сommit
46521aef8c

+ 24 - 0
Source/FLTKDialog/CMakeLists.txt

@@ -0,0 +1,24 @@
+FIND_PACKAGE(FLTK)
+
+SET(SRCS
+CMakeSetupGUIImplementation.cxx
+FLTKDialog.cxx
+FLTKPropertyItemRow.cxx
+FLTKPropertyList.cxx
+)
+
+SET(FLTK_GUI_Files_SRCS
+CMakeSetupGUI.fl
+)
+
+
+LINK_LIBRARIES(${FLTK_LIBRARY})
+
+
+INCLUDE_DIRECTORIES(${FLTK_INCLUDE_PATH})
+
+FLTK_WRAP_UI(FLCMakeSetup ${FLTK_GUI_Files_SRCS})
+
+ADD_EXECUTABLE(FLCMakeSetup ${SRCS} ${FLCMakeSetup_FLTK_SRCS})
+TARGET_LINK_LIBRARIES(FLCMakeSetup CMakeLib)
+

+ 116 - 0
Source/FLTKDialog/CMakeSetupGUI.fl

@@ -0,0 +1,116 @@
+# data file for the Fltk User Interface Designer (fluid)
+version 1.0009 
+header_name {.h} 
+code_name {.cxx} 
+gridx 5 
+gridy 5 
+snap 3
+class CMakeSetupGUI {open
+} {
+  Function {CMakeSetupGUI()} {open
+  } {
+    Fl_Window dialogWindow {
+      label CMakeSetupDialog
+      callback {recentSourceDirectoriesBrowser->hide();
+recentBinaryDirectoriesBrowser->hide();}
+      xywh {646 144 562 373} resizable visible
+    } {
+      Fl_Input sourcePathTextInput {
+        label {Where is the source code: }
+        callback {SetSourcePath( sourcePathTextInput->value() );}
+        xywh {219 15 200 20} labelsize 11 when 8 textsize 11
+      }
+      Fl_Button {} {
+        label {Browse...}
+        callback {BrowseForSourcePath();}
+        xywh {453 14 65 22} shortcut 0x80073 labelsize 11
+      }
+      Fl_Input binaryPathTextInput {
+        label {Where do you want to build the binaries: }
+        callback {SetBinaryPath( binaryPathTextInput->value() );}
+        xywh {219 50 200 20} labelsize 11 when 8 textsize 11
+      }
+      Fl_Button {} {
+        label {Browse...}
+        callback {BrowseForBinaryPath();}
+        xywh {453 49 65 22} shortcut 0x80062 labelsize 11
+      }
+      Fl_Button m_CancelButton {
+        label Cancel
+        callback {ClickOnCancel();}
+        xywh {390 332 100 23} shortcut 0x80071 labelsize 11
+      }
+      Fl_Button m_ConfigureButton {
+        label Configure
+        callback {ClickOnConfigure();}
+        xywh {105 332 100 23} shortcut 0x8006d labelsize 11
+      }
+      Fl_Group {} {
+        xywh {25 80 515 222} box ENGRAVED_BOX labelsize 11 align 0 resizable
+      } {
+        Fl_Scroll cacheValuesScroll {
+          label {Cache Values} open
+          xywh {40 98 485 190} type BOTH_ALWAYS box DOWN_FRAME labelsize 11 align 5 when 1 resizable
+        } {
+          Fl_Pack propertyListPack {
+            xywh {40 99 485 185} resizable
+          } {}
+        }
+      }
+      Fl_Box {} {
+        label {Right click on cache entries for additional options}
+        xywh {160 305 275 25} labelsize 11
+      }
+      Fl_Button {} {
+        label {@\#2>}
+        callback {ShowRecentSourceDirectories();}
+        xywh {420 15 22 21} labeltype SYMBOL_LABEL
+      }
+      Fl_Button {} {
+        label {@\#2>}
+        callback {ShowRecentBinaryDirectories();}
+        xywh {420 50 22 21} labeltype SYMBOL_LABEL
+      }
+      Fl_Browser recentSourceDirectoriesBrowser {
+        callback {SelectOneRecentSourceDirectory();}
+        xywh {15 35 535 115} type Hold box BORDER_BOX hide
+      }
+      Fl_Browser recentBinaryDirectoriesBrowser {
+        callback {SelectOneRecentBinaryDirectory();}
+        xywh {15 70 535 115} type Hold box BORDER_BOX hide
+      }
+      Fl_Button m_OKButton {
+        label OK
+        callback {ClickOnOK();} selected
+        xywh {250 332 100 23} shortcut 0x8006d labelsize 11
+      }
+    }
+  }
+  Function {~CMakeSetupGUI()} {} {}
+  Function {Close(void)} {return_type {virtual void}
+  } {}
+  Function {BrowseForSourcePath(void)} {return_type {virtual void}
+  } {}
+  Function {BrowseForBinaryPath(void)} {return_type {virtual void}
+  } {}
+  Function {Show(void)} {return_type {virtual void}
+  } {}
+  Function {SetBinaryPath(const char *)} {return_type {virtual void}
+  } { }
+  Function {SetSourcePath(const char *)} {return_type {virtual void}
+  } {  }
+  Function {ShowRecentBinaryDirectories(void)} {return_type {virtual void}
+  } {}
+  Function {ShowRecentSourceDirectories(void)} {return_type {virtual void}
+  } {}
+  Function {SelectOneRecentBinaryDirectory(void)} {return_type {virtual void}
+  } {}
+  Function {SelectOneRecentSourceDirectory(void)} {return_type {virtual void}
+  } {}
+  Function {ClickOnConfigure(void)} {return_type {virtual void}
+  } {}
+  Function {ClickOnOK(void)} {return_type {virtual void}
+  } {}
+  Function {ClickOnCancel(void)} {return_type {virtual void}
+  } {}
+} 

+ 838 - 0
Source/FLTKDialog/CMakeSetupGUIImplementation.cxx

@@ -0,0 +1,838 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Insight Consortium. All rights reserved.
+  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+#include "CMakeSetupGUIImplementation.h"
+#include "FL/fl_file_chooser.H"
+#include "FL/filename.H"
+#include "FL/fl_ask.H"
+#include "../cmCacheManager.h"
+#include "../cmMakefile.h"
+#include <iostream>
+#include "FLTKPropertyList.h"
+#include "FLTKPropertyItemRow.h"
+#include "FL/fl_draw.H"
+#include "../cmake.h"
+
+void FLTKMessageCallback(const char* message, const char* title, bool& nomore, void*)
+{
+  std::string msg = message;
+  msg += "\nPress cancel to suppress any further messages.";
+  int choice = fl_choice( msg.c_str(), "Cancel","Ok",0);
+  if(choice==0)
+    {
+    nomore = true;
+    }
+}
+
+/**
+ * Constructor
+ */
+CMakeSetupGUIImplementation
+::CMakeSetupGUIImplementation():m_CacheEntriesList(this)
+{
+  m_CMakeInstance = new cmake;
+  cmSystemTools::SetErrorCallback(FLTKMessageCallback);
+  m_BuildPathChanged = false;
+}
+
+
+
+/**
+ * Destructor
+ */
+CMakeSetupGUIImplementation
+::~CMakeSetupGUIImplementation()
+{
+}
+
+
+
+
+/**
+ * Show the graphic interface
+ */
+void
+CMakeSetupGUIImplementation
+::Show( void )
+{
+  dialogWindow->show();
+}
+
+
+
+
+
+/**
+ * Hide the graphic interface
+ */
+void
+CMakeSetupGUIImplementation
+::Close( void )
+{
+  SaveRecentDirectories();
+  dialogWindow->hide();
+}
+
+
+
+
+
+/**
+ * Browse for the path to the sources
+ */
+void
+CMakeSetupGUIImplementation
+::BrowseForSourcePath( void )
+{
+  const char * path = 
+                  fl_dir_chooser(
+                    "Path to Sources",
+                    sourcePathTextInput->value() );
+                    
+  if( !path )
+  {
+    return;
+  }
+  
+  SetSourcePath( path );
+
+}
+
+
+
+
+/**
+ * Browse for the path to the binaries
+ */
+void
+CMakeSetupGUIImplementation
+::BrowseForBinaryPath( void )
+{
+  const char * path = 
+                  fl_dir_chooser(
+                    "Path to Binaries",
+                    binaryPathTextInput->value() );
+                    
+  if( !path )
+  {
+    return;
+  }
+
+  SetBinaryPath( path );
+
+}
+
+
+
+
+
+/**
+ * Set path to executable. Used to get the path to CMake
+ */
+void
+CMakeSetupGUIImplementation
+::SetPathToExecutable( const char * path )
+{
+  m_PathToExecutable = cmSystemTools::CollapseFullPath(path);
+  m_PathToExecutable = cmSystemTools::GetProgramPath(m_PathToExecutable.c_str()).c_str();
+#ifdef _WIN32
+  m_PathToExecutable += "/cmake.exe";
+#else
+  m_PathToExecutable += "/cmake";
+#endif
+}
+
+
+
+/**
+ * Set the source path
+ */
+void
+CMakeSetupGUIImplementation
+::SetSourcePath( const char * path )
+{
+
+  if( !path || strlen(path)==0 )
+  {
+    fl_alert("Please select the path to the sources");
+    return;
+  }
+
+  std::string expandedAbsolutePath = ExpandPathAndMakeItAbsolute( path );
+  
+  sourcePathTextInput->value( expandedAbsolutePath.c_str() );
+    
+  if( VerifySourcePath( expandedAbsolutePath ) )
+  {
+    m_WhereSource = expandedAbsolutePath;
+  }
+
+}
+
+
+
+
+/**
+ * Expand environment variables in the path and make it absolute
+ */
+std::string
+CMakeSetupGUIImplementation
+::ExpandPathAndMakeItAbsolute( const std::string & inputPath ) const
+{
+  return cmSystemTools::CollapseFullPath(inputPath.c_str());
+}
+
+
+/**
+ * Set the binary path
+ */
+void
+CMakeSetupGUIImplementation
+::SetBinaryPath( const char * path )
+{
+
+  if( !path || strlen(path)==0 )
+  {
+    fl_alert("Please select the path to the binaries");
+    return;
+  }
+
+  std::string expandedAbsolutePath = ExpandPathAndMakeItAbsolute( path );
+  
+  binaryPathTextInput->value( expandedAbsolutePath.c_str() );
+
+  if( !VerifyBinaryPath( expandedAbsolutePath.c_str() ) )
+  {
+  return;
+  }
+
+  if( m_WhereBuild != expandedAbsolutePath )
+  {
+    m_BuildPathChanged  = true;
+    m_WhereBuild        = expandedAbsolutePath;
+    m_CacheEntriesList.RemoveAll(); // remove data from other project
+    this->LoadCacheFromDiskToGUI();
+  }
+  else 
+  {
+    m_BuildPathChanged = false;
+  }
+  
+
+}
+
+
+
+/**
+ * Verify the path to binaries
+ */
+bool
+CMakeSetupGUIImplementation
+::VerifyBinaryPath( const std::string & path ) const
+{
+
+  bool pathIsOK = false;
+
+  if( cmSystemTools::FileIsDirectory( path.c_str() ) )
+    {
+    pathIsOK = true;
+    }
+  else
+    {
+    int userWantsToCreateDirectory = 
+      fl_ask("The directory \n %s \n Doesn't exist. Do you want to create it ?",
+              path.c_str() );
+    
+    if( userWantsToCreateDirectory  )
+      {
+      cmSystemTools::MakeDirectory( path.c_str() );
+      pathIsOK = true;
+      }
+    else
+      {
+      pathIsOK = false; 
+      }
+    }
+  
+  return pathIsOK;
+
+}
+
+
+
+/**
+ * Verify the path to sources
+ */
+bool
+CMakeSetupGUIImplementation
+::VerifySourcePath( const std::string & path ) const
+{
+
+  if( !cmSystemTools::FileIsDirectory(( path.c_str())))
+    {
+    fl_alert("The Source directory \n %s \n Doesn't exist or is not a directory", path.c_str() );
+    return false; 
+    }
+  
+  return true;
+}
+
+
+
+
+/**
+ * Build the project files
+ */
+void
+CMakeSetupGUIImplementation
+::RunCMake( bool generateProjectFiles )
+{
+
+  if(!cmSystemTools::FileIsDirectory( m_WhereBuild.c_str() ))
+    {
+    std::string message =
+      "Build directory does not exist, should I create it?\n\n"
+      "Directory: ";
+    message += m_WhereBuild;
+    int userWantToCreateDirectory =
+      fl_ask(message.c_str());
+    if( userWantToCreateDirectory )
+      {
+      cmSystemTools::MakeDirectory( m_WhereBuild.c_str() );
+      }
+    else
+      {
+      fl_alert("Build Project aborted, nothing done.");
+      return;
+      }
+    }
+
+  
+  // set the wait cursor
+  fl_cursor(FL_CURSOR_WAIT,FL_BLACK,FL_WHITE);
+
+
+  // save the current GUI values to the cache
+  this->SaveCacheFromGUI();
+
+  // Make sure we are working from the cache on disk
+  this->LoadCacheFromDiskToGUI();
+
+  UpdateListOfRecentDirectories();
+  SaveRecentDirectories();
+  if (generateProjectFiles)
+    {
+    if(m_CMakeInstance->Generate() != 0)
+      {
+      cmSystemTools::Error(
+        "Error in generation process, project files may be invalid");
+      }
+    }
+  else
+    {
+    m_CMakeInstance->SetHomeDirectory(m_WhereSource.c_str());
+    m_CMakeInstance->SetStartDirectory(m_WhereSource.c_str());
+    m_CMakeInstance->SetHomeOutputDirectory(m_WhereBuild.c_str());
+    m_CMakeInstance->SetStartOutputDirectory(m_WhereBuild.c_str());
+    m_CMakeInstance->SetGlobalGenerator(
+      m_CMakeInstance->CreateGlobalGenerator("NMake Makefiles"));
+    m_CMakeInstance->SetCMakeCommand(m_PathToExecutable.c_str());
+    m_CMakeInstance->LoadCache();
+    if(m_CMakeInstance->Configure() != 0)
+      {
+      cmSystemTools::Error(
+        "Error in configuration process, project files may be invalid");
+      }
+    // update the GUI with any new values in the caused by the
+    // generation process
+    this->LoadCacheFromDiskToGUI();
+    }
+
+  // path is up-to-date now
+  m_BuildPathChanged = false;
+
+
+  // put the cursor back
+  fl_cursor(FL_CURSOR_DEFAULT,FL_BLACK,FL_WHITE);
+  fl_message("Done !");
+
+}
+
+
+
+
+/**
+ * Load Cache from disk to GUI
+ */
+void
+CMakeSetupGUIImplementation
+::LoadCacheFromDiskToGUI( void )
+{
+  
+    
+  if( m_WhereBuild != "" )
+    { 
+    cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager();
+    cachem->LoadCache( m_WhereBuild.c_str() );
+    this->FillCacheGUIFromCacheManager();
+    }
+}
+   
+
+/**
+ * Save Cache from disk to GUI
+ */
+void
+CMakeSetupGUIImplementation
+::SaveCacheFromGUI( void )
+{
+  cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager();
+  this->FillCacheManagerFromCacheGUI();
+  if(m_WhereBuild != "")
+    {
+    cachem->SaveCache(m_WhereBuild.c_str());
+    }
+}
+
+
+/**
+ * Fill Cache GUI from cache manager
+ */
+void
+CMakeSetupGUIImplementation
+::FillCacheGUIFromCacheManager( void )
+{
+  cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager();
+  cmCacheManager::CacheIterator it = cachem->NewIterator();
+  size_t size = m_CacheEntriesList.GetItems().size();
+  bool reverseOrder = false;
+  // if there are already entries in the cache, then
+  // put the new ones in the top, so they show up first
+  if(size)
+    {
+    reverseOrder = true;
+    }
+
+  // all the current values are not new any more
+  std::set<fltk::PropertyItem*> items = m_CacheEntriesList.GetItems();
+  for(std::set<fltk::PropertyItem*>::iterator i = items.begin();
+      i != items.end(); ++i)
+    {
+    fltk::PropertyItem* item = *i;
+    item->m_NewValue = false;
+    }
+  // Prepare to add rows to the FLTK scroll/pack
+  propertyListPack->clear();
+  propertyListPack->begin();
+
+//    const cmCacheManager::CacheEntryMap &cache =
+//      cmCacheManager::GetInstance()->GetCacheMap();
+//    if(cache.size() == 0)
+//      {
+//      m_OKButton->deactivate();
+//      }
+//    else
+//      {
+//      m_OKButton->activate();
+//      }
+
+
+
+
+  for(cmCacheManager::CacheIterator i = cachem->NewIterator();
+      !i.IsAtEnd(); i.Next())
+    {
+    const char* key = i.GetName();
+    std::string value = i.GetValue();
+    bool advanced = i.GetPropertyAsBool("ADVANCED");
+    switch(i.GetType() )
+      {
+      case cmCacheManager::BOOL:
+        if(cmSystemTools::IsOn(value.c_str()))
+          {
+         m_CacheEntriesList.AddProperty(key,
+                                         "ON",
+                                         i.GetProperty("HELPSTRING"),
+                                         fltk::PropertyList::CHECKBOX,"",
+                                         reverseOrder);
+          }
+        else
+          {
+           m_CacheEntriesList.AddProperty(key,
+                                         "OFF",
+                                         i.GetProperty("HELPSTRING"),
+                                         fltk::PropertyList::CHECKBOX,"",
+                                         reverseOrder);
+          }
+        break;
+      case cmCacheManager::PATH:
+         m_CacheEntriesList.AddProperty(key, 
+                                       value.c_str(),
+                                       i.GetProperty("HELPSTRING"),
+                                       fltk::PropertyList::PATH,"",
+                                       reverseOrder);
+        break;
+      case cmCacheManager::FILEPATH:
+         m_CacheEntriesList.AddProperty(key, 
+                                       value.c_str(),
+                                       i.GetProperty("HELPSTRING"),
+                                       fltk::PropertyList::FILE,"",
+                                       reverseOrder);
+         break;
+      case cmCacheManager::STRING:
+        m_CacheEntriesList.AddProperty(key,
+                                       value.c_str(),
+                                       i.GetProperty("HELPSTRING"),
+                                       fltk::PropertyList::EDIT,"",
+                                       reverseOrder);
+        break;
+      case cmCacheManager::STATIC:
+      case cmCacheManager::INTERNAL:
+        m_CacheEntriesList.RemoveProperty(key);
+        break;
+      }
+    }
+
+  // Add the old entry to the end of the pack
+  for(std::set<fltk::PropertyItem*>::iterator i = items.begin();
+      i != items.end(); ++i)
+    {
+    fltk::PropertyItem* item = *i;
+    if( !(item->m_NewValue) )
+      {
+      new fltk::PropertyItemRow( item ); // GUI of the old property row
+      }
+    }
+
+  propertyListPack->end();
+  propertyListPack->init_sizes();
+  cacheValuesScroll->position( 0, 0 );
+
+  propertyListPack->redraw();
+
+  Fl::check();
+
+  this->UpdateData(false);
+
+}
+
+
+/**
+ * UpdateData
+ */
+void
+CMakeSetupGUIImplementation
+::UpdateData( bool option )
+{
+  dialogWindow->redraw();
+  Fl::check();
+}
+
+
+
+/**
+ * Fill cache manager from Cache GUI 
+ */
+void
+CMakeSetupGUIImplementation
+::FillCacheManagerFromCacheGUI( void )
+{
+  cmCacheManager *cachem = this->m_CMakeInstance->GetCacheManager();
+  cmCacheManager::CacheIterator it = cachem->NewIterator();
+  std::set<fltk::PropertyItem*> items = m_CacheEntriesList.GetItems();
+  for(std::set<fltk::PropertyItem*>::iterator i = items.begin();
+      i != items.end(); ++i)
+    {
+      fltk::PropertyItem* item = *i; 
+      if ( it.Find((const char*)item->m_propName.c_str()) )
+        {
+        it.SetValue(item->m_curValue.c_str());
+        }
+      if( item->m_Dirty )
+        {
+        m_CacheEntriesList.SetDirty();
+        }
+    }
+}
+
+
+
+
+/**
+ * Load Recent Directories
+ */
+void
+CMakeSetupGUIImplementation
+::LoadRecentDirectories( void )
+{
+  std::string home = getenv("HOME");
+  std::string filename = home + "/.cmakerc";
+  
+  std::ifstream input;
+  input.open(filename.c_str());
+  
+  if( input.fail() ) 
+  {
+    // probably the file doesn't exist
+    return;
+  }
+  
+  m_RecentBinaryDirectories.clear();
+  m_RecentSourceDirectories.clear();
+
+  std::string key;
+  std::string onedirectory;
+
+  while( !input.eof() )
+  {
+    input >> key;
+    
+    if( input.eof() ) break;
+
+    if( key == "MostRecentSource" )
+    {
+      input >> onedirectory;
+      m_WhereSource = onedirectory;
+      sourcePathTextInput->value( m_WhereSource.c_str() );
+    } else
+    if( key == "MostRecentBinary" )
+    {
+      input >> onedirectory;
+      m_WhereBuild = onedirectory;
+      binaryPathTextInput->value( m_WhereBuild.c_str() );
+      LoadCacheFromDiskToGUI();
+    } else
+    if( key == "Binary" )
+    {
+      input >> onedirectory;
+      // insert is only done if the directory doesn't exist
+      m_RecentBinaryDirectories.insert( onedirectory );
+      recentBinaryDirectoriesBrowser->add(
+                      (onedirectory.c_str()),
+                      (void*)(onedirectory.c_str()) );
+    } else
+    if( key == "Source" )
+    {
+      input >> onedirectory;
+      // insert is only done if the directory doesn't exist
+      m_RecentSourceDirectories.insert( onedirectory );
+      recentSourceDirectoriesBrowser->add(
+                      (onedirectory.c_str()),
+                      (void*)(onedirectory.c_str()) );
+    }
+
+  }
+
+  input.close();
+}
+
+
+
+/**
+ * Save Recent Directories
+ */
+void
+CMakeSetupGUIImplementation
+::SaveRecentDirectories( void )
+{
+  std::string home = getenv("HOME");
+
+  if( home.empty() )
+  {
+    return;
+  }
+  
+  std::string filename = home + "/.cmakerc";
+  
+  std::ofstream output;
+  output.open(filename.c_str());
+
+  output << "MostRecentBinary " << m_WhereBuild  << std::endl;
+  output << "MostRecentSource " << m_WhereSource << std::endl;
+
+  // Save Recent binary directories
+  std::set< std::string >::iterator bindir = 
+                m_RecentBinaryDirectories.begin();
+
+  while( bindir != m_RecentBinaryDirectories.end() )
+  {
+    output << "Binary " << *bindir << std::endl;
+    bindir++;
+  }
+
+
+  // Save Recent source directories
+  std::set< std::string >::iterator srcdir = 
+                m_RecentSourceDirectories.begin();
+
+  while( srcdir != m_RecentSourceDirectories.end() )
+  {
+    output << "Source " << *srcdir << std::endl;
+    srcdir++;
+  }
+
+}
+
+
+/**
+ * Show Recent Binary Directories
+ */
+void
+CMakeSetupGUIImplementation
+::ShowRecentBinaryDirectories( void )
+{
+  if( recentBinaryDirectoriesBrowser->size() )
+    {
+    recentBinaryDirectoriesBrowser->Fl_Widget::show();
+    }
+}
+
+
+/**
+ * Show Recent Source Directories
+ */
+void
+CMakeSetupGUIImplementation
+::ShowRecentSourceDirectories( void )
+{
+  if( recentSourceDirectoriesBrowser->size() )
+    {
+    recentSourceDirectoriesBrowser->Fl_Widget::show();
+    }
+}
+
+
+/**
+ * Select one Recent Binary Directory
+ */
+void
+CMakeSetupGUIImplementation
+::SelectOneRecentBinaryDirectory( void )
+{
+  const int selected = recentBinaryDirectoriesBrowser->value();
+  if( selected == 0 )
+  {
+    return;
+  }
+  
+  m_WhereBuild = static_cast<char *>(
+           recentBinaryDirectoriesBrowser->data( selected ));
+  binaryPathTextInput->value( m_WhereBuild.c_str() );
+  recentBinaryDirectoriesBrowser->Fl_Widget::hide();
+  m_CacheEntriesList.RemoveAll(); // remove data from other project
+  LoadCacheFromDiskToGUI();
+}
+
+
+/**
+ * Select one Recent Source Directory
+ */
+void
+CMakeSetupGUIImplementation
+::SelectOneRecentSourceDirectory( void )
+{
+  const int selected = recentSourceDirectoriesBrowser->value();
+  if( selected == 0 )
+  {
+    return;
+  }
+  m_WhereSource =  static_cast< char * >(
+          recentSourceDirectoriesBrowser->data( selected ));
+  sourcePathTextInput->value( m_WhereSource.c_str() );
+  recentSourceDirectoriesBrowser->Fl_Widget::hide();
+}
+
+
+
+/**
+ * Update List of Recent Directories
+ */
+void
+CMakeSetupGUIImplementation
+::UpdateListOfRecentDirectories( void )
+{
+
+  // Update Recent binary directories
+  // insert is only done if the directory doesn't exist
+  m_RecentBinaryDirectories.insert( m_WhereBuild );
+  
+  // Update Recent source directories
+  // insert is only done if the directory doesn't exist
+  m_RecentSourceDirectories.insert( m_WhereSource );
+
+}
+
+
+
+
+
+/**
+ * Clicked on Configure Button
+ */
+void
+CMakeSetupGUIImplementation
+::ClickOnConfigure( void )
+{
+  this->RunCMake(false);
+}
+
+
+
+
+/**
+ * Clicked on OK Button
+ */
+void
+CMakeSetupGUIImplementation
+::ClickOnOK( void )
+{
+  m_CacheEntriesList.ClearDirty();
+  this->RunCMake(true);
+  this->Close();
+}
+
+
+
+
+/**
+ * Clicked on Cancel Button
+ */
+void
+CMakeSetupGUIImplementation
+::ClickOnCancel( void )
+{
+  if(m_CacheEntriesList.IsDirty())
+    {
+    int userWantsExitEvenThoughOptionsHaveChanged = 
+      fl_ask("You have changed options but not rebuilt, \n"
+                  "are you sure you want to exit?");
+    if( userWantsExitEvenThoughOptionsHaveChanged )
+      {
+      this->Close();
+      }
+    }
+  else
+    {
+    this->Close();
+    }
+
+}
+
+
+
+
+

+ 85 - 0
Source/FLTKDialog/CMakeSetupGUIImplementation.h

@@ -0,0 +1,85 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Insight Consortium. All rights reserved.
+  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+#ifndef CMakeSetupGUIImplementation_h
+#define CMakeSetupGUIImplementation_h
+
+#include "CMakeSetupGUI.h"
+#include "FLTKPropertyList.h"
+#include <set>
+
+
+/**
+ *
+ *  This class implements the virtual methods 
+ *  declared in the GUI interface
+ *
+ */
+   
+class cmake;
+
+class CMakeSetupGUIImplementation : public CMakeSetupGUI 
+{
+
+public:
+
+  CMakeSetupGUIImplementation();
+  virtual ~CMakeSetupGUIImplementation();
+  virtual void Close( void );
+  virtual void Show( void );
+  virtual void UpdateData( bool option );
+  virtual void BrowseForBinaryPath( void );
+  virtual void BrowseForSourcePath( void );
+  virtual void SetBinaryPath( const char * path );
+  virtual void SetSourcePath( const char * path );
+  virtual void SaveCacheFromGUI( void );
+  virtual void LoadCacheFromDiskToGUI( void );
+  virtual void FillCacheGUIFromCacheManager( void );
+  virtual void FillCacheManagerFromCacheGUI( void );
+        virtual void SetPathToExecutable( const char * path );
+  virtual void LoadRecentDirectories(void);
+  virtual void SaveRecentDirectories(void);
+  virtual void ShowRecentBinaryDirectories(void);
+  virtual void ShowRecentSourceDirectories(void);
+  virtual void SelectOneRecentSourceDirectory(void);
+  virtual void SelectOneRecentBinaryDirectory(void);
+  virtual void UpdateListOfRecentDirectories(void);
+  virtual void ClickOnConfigure(void);
+  virtual void ClickOnOK(void);
+  virtual void ClickOnCancel(void);
+  virtual void RunCMake( bool generateProjectFiles );
+  cmake *GetCMakeInstance() {return m_CMakeInstance; }
+private:  
+  virtual bool VerifyBinaryPath( const std::string & path ) const;
+  virtual bool VerifySourcePath( const std::string & path ) const;
+  virtual std::string ExpandPathAndMakeItAbsolute( const std::string & inputPath ) const;
+
+private:
+  fltk::PropertyList   m_CacheEntriesList;
+  std::string          m_WhereBuild;
+  std::string          m_WhereSource;
+  std::string          m_PathToExecutable;
+  std::string            m_GeneratorChoiceString;
+  bool                 m_BuildPathChanged;
+  
+  std::set< std::string > m_RecentBinaryDirectories;
+  std::set< std::string > m_RecentSourceDirectories;
+  cmake *m_CMakeInstance;
+};
+
+
+#endif

+ 41 - 0
Source/FLTKDialog/FLTKDialog.cxx

@@ -0,0 +1,41 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Insight Consortium. All rights reserved.
+  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+#include "CMakeSetupGUIImplementation.h"
+#include "FL/Fl.H"
+#include "FL/fl_ask.H"
+
+int main(int argc, char * argv[] ) 
+{
+
+  fl_message_font(FL_HELVETICA,11);
+
+  CMakeSetupGUIImplementation * gui 
+       = new CMakeSetupGUIImplementation;
+
+  gui->SetPathToExecutable( argv[0] );
+  gui->Show();
+  gui->LoadRecentDirectories();
+  gui->LoadCacheFromDiskToGUI();
+
+  Fl::run();
+
+  delete gui;
+  
+  return 0;
+  
+}

+ 116 - 0
Source/FLTKDialog/FLTKDialog.dsp

@@ -0,0 +1,116 @@
+# Microsoft Developer Studio Project File - Name="FLTKDialog" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=FLTKDialog - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "FLTKDialog.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "FLTKDialog.mak" CFG="FLTKDialog - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "FLTKDialog - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "FLTKDialog - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "FLTKDialog - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "Release"
+# PROP BASE Intermediate_Dir "Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "Release"
+# PROP Intermediate_Dir "Release"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /I "H:/usr/local/fltk" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x409 /d "NDEBUG"
+# ADD RSC /l 0x409 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 fltk.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "FLTKDialog - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "FLTKDialog___Win32_Debug"
+# PROP BASE Intermediate_Dir "FLTKDialog___Win32_Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "FLTKDialog___Win32_Debug"
+# PROP Intermediate_Dir "FLTKDialog___Win32_Debug"
+# PROP Target_Dir ""
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
+# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "H:/usr/local/fltk" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
+# ADD BASE RSC /l 0x409 /d "_DEBUG"
+# ADD RSC /l 0x409 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 fltk.lib wsock32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"H:/usr/local/fltk/lib/Debug"
+
+!ENDIF 
+
+# Begin Target
+
+# Name "FLTKDialog - Win32 Release"
+# Name "FLTKDialog - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# Begin Source File
+
+SOURCE=.\CMakeSetupGUI.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\CMakeSetupGUIImplementation.cpp
+# End Source File
+# Begin Source File
+
+SOURCE=.\FLTKDialog.cpp
+# End Source File
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# Begin Source File
+
+SOURCE=.\CMakeSetupGUI.h
+# End Source File
+# Begin Source File
+
+SOURCE=.\CMakeSetupGUIImplementation.h
+# End Source File
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project

+ 387 - 0
Source/FLTKDialog/FLTKPropertyItemRow.cxx

@@ -0,0 +1,387 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Insight Consortium. All rights reserved.
+  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#include "FLTKPropertyItemRow.h"
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Button.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Tile.H>
+#include <FL/fl_ask.H>
+#include <FL/fl_file_chooser.H>
+#include <FL/Fl_Color_Chooser.H>
+#include <FL/Fl_Menu_Button.H>
+#include "../cmCacheManager.h"
+#include "FLTKPropertyList.h"
+#include "CMakeSetupGUIImplementation.h"
+#include <stdio.h>
+#include "../cmake.h"
+#include "../cmCacheManager.h"
+
+namespace fltk {
+
+
+
+CMakeSetupGUIImplementation * PropertyItemRow::m_CMakeSetup = 0;
+
+
+
+
+PropertyItemRow
+::PropertyItemRow( PropertyItem * pItem ):Fl_Tile(0,0,10,10,"")
+{
+   
+  m_PropertyItem =     pItem;
+  m_ItemValue    =     new ItemValue;
+
+  const unsigned int fontsize     =         11;
+  const unsigned int nameWidth    =        200;
+  const unsigned int textWidth    =       1400;
+  const unsigned int checkWidth   =  textWidth;
+  const unsigned int browseWidth  =         20;
+  const unsigned int firstColumn  =          0;
+
+  const unsigned int secondColumn =  nameWidth;
+
+  const unsigned int rowHeight    =         20;
+ 
+  size( nameWidth + textWidth , rowHeight );
+
+  // Make the parent Fl_Pack widget at least a row wide.
+  parent()->size( nameWidth + textWidth , rowHeight );
+
+  m_NameButton = new 
+          Fl_Button( firstColumn, 0, nameWidth, rowHeight, 
+                                    m_PropertyItem->m_propName.c_str() );
+
+  m_NameButton->align( FL_ALIGN_CLIP | FL_ALIGN_LEFT | FL_ALIGN_INSIDE );
+  m_NameButton->labelsize( fontsize );
+  m_NameButton->box( FL_DOWN_BOX );
+  m_NameButton->size( secondColumn, rowHeight );
+  m_NameButton->callback( NameButtonCallback, (void *)m_PropertyItem );
+  if( m_PropertyItem->m_NewValue ) 
+    {
+    m_NameButton->color(FL_RED);
+    }
+    
+  switch( m_PropertyItem->m_nItemType )
+  {
+    case PropertyList::COMBO:
+    {
+      break;
+    }
+    case PropertyList::EDIT: 
+    {
+
+      Fl_Input * input = new 
+                    Fl_Input( secondColumn, 0, textWidth ,rowHeight ,"");
+      input->value( m_PropertyItem->m_curValue.c_str() );
+      input->textsize( fontsize );
+      input->callback( InputTextCallback, (void *)m_PropertyItem );
+      input->when( FL_WHEN_CHANGED );
+
+      break;
+    }
+    case PropertyList::COLOR:
+    {
+      Fl_Button * colorButton = new
+            Fl_Button( secondColumn, 0, textWidth  ,rowHeight ,"");
+      colorButton->labelsize( fontsize );
+      //colorButton->color();
+      colorButton->callback( ColorSelectionCallback, (void *)m_PropertyItem );
+
+      break;
+    }
+    case PropertyList::FILE:
+    {
+
+      Fl_Button * browseButton = new 
+            Fl_Button( secondColumn, 0, browseWidth  ,rowHeight ,"...");
+      browseButton->labelsize( fontsize );
+
+      Fl_Input * input = new 
+                    Fl_Input( secondColumn+browseWidth, 0, textWidth ,rowHeight ,"");
+      input->value( m_PropertyItem->m_curValue.c_str() );
+      input->textsize( fontsize );
+
+      m_ItemValue->m_InputText    = input;
+      m_ItemValue->m_PropertyItem = m_PropertyItem;
+        
+      browseButton->callback( BrowsePathCallback, (void *)m_ItemValue );
+      input->callback( InputTextCallback, m_PropertyItem );
+      input->when( FL_WHEN_CHANGED );
+      
+      break;
+    }
+    case PropertyList::CHECKBOX:
+    {
+      Fl_Button * button = new 
+            Fl_Button( secondColumn, 0, checkWidth  ,rowHeight ,"");
+      button->align( FL_ALIGN_INSIDE | FL_ALIGN_LEFT );
+      button->callback( CheckButtonCallback, (void *)m_PropertyItem );
+
+      if( m_PropertyItem->m_curValue == "ON" ) 
+      {
+        button->label(" ON  ");
+        button->value(1);
+      }
+      else if( m_PropertyItem->m_curValue == "OFF" )
+      {
+        button->label(" OFF ");
+        button->value(0);
+      }
+      button->type( FL_TOGGLE_BUTTON );
+      button->labelsize( fontsize );
+      break;
+    }
+    case PropertyList::PATH:
+    {
+
+      Fl_Button * browseButton = new 
+            Fl_Button( secondColumn, 0, browseWidth  ,rowHeight ,"...");
+      browseButton->labelsize( fontsize );
+
+      Fl_Input * input = new 
+                    Fl_Input( secondColumn+browseWidth, 0, textWidth ,rowHeight ,"");
+      input->value( m_PropertyItem->m_curValue.c_str() );
+      input->textsize( fontsize );
+
+      m_ItemValue->m_InputText    = input;
+      m_ItemValue->m_PropertyItem = m_PropertyItem;
+        
+      browseButton->callback( BrowsePathCallback, (void *)m_ItemValue );
+      input->callback( InputTextCallback, (void *)m_PropertyItem );
+      input->when( FL_WHEN_CHANGED );
+      
+      break;
+    }
+    break;
+  default:
+    fl_alert("Unkown item type %d",m_PropertyItem->m_nItemType);
+    break;
+  }
+
+
+  end(); // Close the inclusion of widgets in the Tile object
+
+}
+
+
+
+
+
+PropertyItemRow::~PropertyItemRow( )
+{
+  delete m_ItemValue;
+}
+
+
+
+void PropertyItemRow
+::SetCMakeSetupGUI( CMakeSetupGUIImplementation * cmakeSetup )
+{
+  m_CMakeSetup   =     cmakeSetup;
+}
+
+
+  
+void 
+PropertyItemRow::
+NameButtonCallback( Fl_Widget * widget, void * data) 
+{
+  Fl_Button    * button = (Fl_Button *)widget;
+  PropertyItem * pItem  = (PropertyItem *)data;
+  
+  static Fl_Menu_Button * popupMenu = 0;
+  if( !popupMenu )
+  {
+    int lastMousePositionX = Fl::event_x();
+    int lastMousePositionY = Fl::event_y();
+    popupMenu = new Fl_Menu_Button(lastMousePositionX,
+                                   lastMousePositionY,100,200);
+  }
+  
+  popupMenu->type( Fl_Menu_Button::POPUP3 );
+  popupMenu->add("Help|Remove|Properties...");
+  popupMenu->popup();
+ 
+  typedef enum {
+    HELP=0,
+    REMOVE,
+    PROPERTIES
+  } MenuOptions;
+    
+  
+  switch( popupMenu->value() )
+  {
+    case HELP:
+      fl_message( pItem->m_HelpString.c_str() );
+      break;
+    case REMOVE: // Remove
+    {
+      const char * propertyName = pItem->m_propName.c_str();
+      int answer = fl_ask( "Do you want to remove property %s", propertyName );
+      if( answer == 1 )
+      {
+        // Remove the entry from the cache
+        m_CMakeSetup->GetCMakeInstance()->GetCacheManager()->RemoveCacheEntry(propertyName);
+          // Get the parent: Fl_Tile that manages the whole row in the GUI
+        Fl_Group * parentGroup      = dynamic_cast<Fl_Group *>(button->parent());
+        // Get the grandParent: Fl_Pack with the property list
+        Fl_Group * grandParentGroup = dynamic_cast<Fl_Group *>( parentGroup->parent() );
+        // Remove the row from the list
+        grandParentGroup->remove( *parentGroup );
+        // Destroy the row
+        delete parentGroup;  // Patricide... ?
+        // Redraw the list
+        grandParentGroup->redraw();
+        FillCacheManagerFromCacheGUI();        
+        return;
+      }
+      break;
+    }
+    case PROPERTIES: // Properties
+      break;
+  }
+}
+  
+
+
+void
+PropertyItemRow::
+FillCacheManagerFromCacheGUI( void )
+{
+  if( m_CMakeSetup )
+  {
+    m_CMakeSetup->FillCacheManagerFromCacheGUI();
+  }
+}
+
+
+
+void 
+PropertyItemRow::
+CheckButtonCallback( Fl_Widget * widget, void * data) 
+{
+  Fl_Button    * button = (Fl_Button *)widget;
+  PropertyItem * pItem  = (PropertyItem *)data;
+  
+  int value = button->value();
+
+  if( value )
+  {
+    button->label(" ON ");
+    pItem->m_curValue = "ON";
+  }
+  else 
+  {
+    button->label(" OFF ");
+    pItem->m_curValue = "OFF";
+  }
+
+  pItem->m_Dirty = true;
+    
+  button->redraw();
+  
+  FillCacheManagerFromCacheGUI();
+
+}
+
+
+
+void 
+PropertyItemRow::
+InputTextCallback(   Fl_Widget * widget, void * data)
+{
+  Fl_Input  * input     = (Fl_Input *)widget;
+  PropertyItem * item   = (PropertyItem *)data;
+  
+  item->m_curValue      = input->value();
+
+  item->m_Dirty = true;
+
+  FillCacheManagerFromCacheGUI();
+
+}
+
+
+
+void 
+PropertyItemRow::
+ColorSelectionCallback(   Fl_Widget * widget, void * data)
+{
+  Fl_Button    * colorButton   = (Fl_Button *)widget;
+  PropertyItem * propertyItem  = (PropertyItem *)data;
+
+  static Fl_Color colorIndex = FL_FREE_COLOR;
+
+  unsigned char red   = 0;
+  unsigned char blue  = 0;
+  unsigned char green = 0;
+  fl_color_chooser("Please pick a color",red,green,blue);
+  char buffer[300];
+  sprintf( buffer,"RGB(%d,%d,%d)", red, green, blue );
+  propertyItem->m_curValue = buffer;
+  Fl::set_color( colorIndex, red, green, blue );
+  colorButton->color( colorIndex );
+  colorIndex = (Fl_Color)( colorIndex + 1 );
+  if( colorIndex == FL_FREE_COLOR + FL_NUM_FREE_COLOR )
+  {
+    fl_alert("Maximum number of free colors used, recycling...");
+    colorIndex = FL_FREE_COLOR;
+  }
+
+  propertyItem->m_Dirty = true;
+
+  colorButton->redraw();
+ 
+  FillCacheManagerFromCacheGUI();
+
+}
+
+
+
+
+
+
+void 
+PropertyItemRow::
+BrowsePathCallback(   Fl_Widget * widget, void * data)
+{
+  ItemValue    * itemValue    = (ItemValue *)data;
+  Fl_Input     * inputText    = itemValue->m_InputText;
+  PropertyItem * propertyItem = itemValue->m_PropertyItem;
+
+  const char * newpath = 
+    fl_file_chooser("Select a path","*", inputText->value() );
+  
+  if( newpath ) 
+  {
+    propertyItem->m_curValue = newpath;
+    inputText->value( newpath );
+  }
+
+  propertyItem->m_Dirty = true;
+
+  FillCacheManagerFromCacheGUI();
+
+}
+
+
+
+
+} // end namespace fltk

+ 83 - 0
Source/FLTKDialog/FLTKPropertyItemRow.h

@@ -0,0 +1,83 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Insight Consortium. All rights reserved.
+  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+
+#ifndef  FLTKPropertyItemRow_h
+#define  FLTKPropertyItemRow_h
+
+#include "FLTKPropertyList.h"
+
+#include <FL/Fl_Tile.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Button.H>
+
+
+class CMakeSetupGUIImplementation;  
+
+
+namespace fltk {
+  
+
+/**
+
+   Class to manage a GUI row corresponding to a property
+  
+  */
+class PropertyItemRow  : public Fl_Tile
+{
+
+  // Helper class for passing data to callbacks
+  struct ItemValue
+  {
+    PropertyItem * m_PropertyItem;
+    Fl_Input     * m_InputText;
+  };
+
+ 
+  public:
+
+    PropertyItemRow( PropertyItem *);
+    ~PropertyItemRow();
+
+  private:
+    
+    PropertyItem * m_PropertyItem;
+    ItemValue    * m_ItemValue;
+    Fl_Button    * m_NameButton;
+
+    static CMakeSetupGUIImplementation * m_CMakeSetup;
+
+    static void CheckButtonCallback( Fl_Widget *, void *);
+    static void NameButtonCallback( Fl_Widget *, void *);
+    static void InputTextCallback(   Fl_Widget *, void *);
+    static void BrowsePathCallback(  Fl_Widget *, void *);
+    static void ColorSelectionCallback(   Fl_Widget * widget, void * data);
+
+
+    static void FillCacheManagerFromCacheGUI( void );
+
+  public:
+    
+    static void SetCMakeSetupGUI( CMakeSetupGUIImplementation * );
+};
+
+
+} // end namespace fltk
+
+
+#endif
+
+

+ 184 - 0
Source/FLTKDialog/FLTKPropertyList.cxx

@@ -0,0 +1,184 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Insight Consortium. All rights reserved.
+  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+// FLTKPropertyList.cxx : implementation file
+//
+
+#include "FLTKPropertyList.h"
+#include "../cmCacheManager.h"
+#include "FLTKPropertyItemRow.h"
+#include "FL/filename.H"
+#include "FL/fl_file_chooser.H"
+#include "FL/Fl_Color_Chooser.H"
+#include "FL/fl_ask.H"
+#include "FL/Fl_Button.H"
+#include "CMakeSetupGUIImplementation.h"
+
+
+namespace fltk {
+
+/////////////////////////////////////////////////////////////////////////////
+// PropertyList
+
+PropertyList::PropertyList( CMakeSetupGUIImplementation * cmakeSetup )
+{
+  m_CMakeSetup = cmakeSetup;
+  PropertyItemRow::SetCMakeSetupGUI( cmakeSetup );
+  m_Dirty = false;
+}
+
+
+
+PropertyList::~PropertyList()
+{
+  for(std::set<PropertyItem*>::iterator i = m_PropertyItems.begin();
+      i != m_PropertyItems.end(); ++i)
+    {
+    delete *i;
+    }
+}
+
+
+
+
+int PropertyList::AddItem( std::string txt)
+{
+  int nIndex =0;
+  return nIndex;
+}
+
+
+
+int PropertyList::AddPropItem(PropertyItem* pItem, bool reverseOrder)
+{
+
+  int nIndex =0; 
+  if(reverseOrder)
+    {
+    nIndex = 0;
+    }
+  else
+    {
+    nIndex = m_PropertyItems.size();
+    }
+
+  new PropertyItemRow( pItem ); // GUI of the new property row
+
+  m_PropertyItems.insert(pItem);
+
+  return nIndex;
+}
+
+
+
+int PropertyList::AddProperty(const char* name,
+                               const char* value,
+                               const char* helpString,
+                               int type,
+                               const char* comboItems,
+                               bool reverseOrder)
+{ 
+
+  PropertyItem* pItem = 0;
+  for(int i =0; i < this->GetCount(); ++i)
+    {
+    PropertyItem* item = this->GetItem(i);
+    if(item->m_propName == name)
+      {
+      pItem = item;
+      if(pItem->m_curValue != value)
+        {
+        pItem->m_curValue = value;
+        pItem->m_HelpString = helpString;
+        Invalidate();
+        }
+      return i;
+      }
+    }
+  // if it is not found, then create a new one
+  if(!pItem)
+    {
+    pItem = new PropertyItem(name, value, helpString, type, comboItems);
+    }
+  return this->AddPropItem(pItem,reverseOrder);
+}
+
+
+void PropertyList::RemoveProperty(const char* name)
+{
+  for(int i =0; i < this->GetCount(); ++i)
+    {
+    PropertyItem* pItem = (PropertyItem*) GetItemDataPtr(i);
+    if(pItem->m_propName == name)
+      {
+      m_PropertyItems.erase(pItem);
+      delete pItem; 
+      return;
+      }
+    }
+}
+
+
+
+void PropertyList::RemoveAll()
+{
+  int c = this->GetCount();
+  for(int i =0; i < c; ++i)
+    {
+    PropertyItem* pItem = (PropertyItem*) GetItemDataPtr(0);
+//    cmCacheManager::GetInstance()->RemoveCacheEntry(pItem->m_propName.c_str());
+    m_PropertyItems.erase(pItem);
+    delete pItem;
+    }
+  Invalidate();
+}
+
+
+
+PropertyItem * PropertyList::GetItemDataPtr(int index)
+{
+    std::set<PropertyItem*>::iterator it =  m_PropertyItems.begin();
+    for(int i=0; it != m_PropertyItems.end() && i<index; i++) 
+    {
+      ++it;
+    }
+    return *it;
+}
+
+
+PropertyItem * PropertyList::GetItem(int index)
+{
+    std::set<PropertyItem*>::iterator it =  m_PropertyItems.begin();
+    for(int i=0; it != m_PropertyItems.end() && i<index; i++) 
+    {
+      ++it;
+    }
+    return *it;
+}
+
+void
+PropertyList
+::InvalidateList(void)
+{
+  Invalidate();
+  m_Dirty = true;
+}
+
+
+} // end fltk namespace
+
+
+

+ 143 - 0
Source/FLTKDialog/FLTKPropertyList.h

@@ -0,0 +1,143 @@
+/*=========================================================================
+
+  Program:   Insight Segmentation & Registration Toolkit
+  Module:    $RCSfile$
+  Language:  C++
+  Date:      $Date$
+  Version:   $Revision$
+
+  Copyright (c) 2002 Insight Consortium. All rights reserved.
+  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even 
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
+     PURPOSE.  See the above copyright notices for more information.
+
+=========================================================================*/
+#ifndef FLTKPROPERTYLIST_H
+#define FLTKPROPERTYLIST_H
+
+#include "../cmStandardIncludes.h"
+#include <string>
+
+
+class CMakeSetupGUIImplementation;  
+
+
+namespace fltk {
+
+
+/////////////////////////////////////////////////////////////////////////////
+//PropertyList Items
+class PropertyItem 
+{
+// Attributes
+public:
+  std::string m_HelpString;
+  std::string m_propName;
+  std::string m_curValue;
+  int m_nItemType;
+  std::string m_cmbItems;
+  bool m_Removed;
+  bool m_NewValue;
+  bool m_Dirty;
+public:
+  PropertyItem( std::string propName, 
+                std::string curValue,
+                std::string helpString,
+                int nItemType, 
+                std::string cmbItems )
+    {
+      m_HelpString  = helpString;
+      m_propName    = propName;
+      m_curValue    = curValue;
+      m_nItemType   = nItemType;
+      m_cmbItems    = cmbItems;
+      m_Removed     = false;
+      m_NewValue    = true;
+      m_Dirty       = false;
+    }
+};
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// PropertyList window
+
+class PropertyList 
+{
+// Construction
+public:
+  enum ItemType 
+    {
+      COMBO = 0,
+      EDIT,
+      COLOR,
+      FONT,
+      FILE,
+      CHECKBOX,
+      PATH
+    };
+
+  PropertyList( CMakeSetupGUIImplementation * );
+  
+// Attributes
+public:
+
+// Operations
+public:
+  int AddItem( std::string txt );
+  int AddProperty(const char* name,
+                  const char* value,
+                  const char* helpString,
+                  int type,
+                  const char* comboItems,
+                  bool reverseOrder);
+  void RemoveProperty(const char* name);
+  std::set<PropertyItem*> & GetItems() 
+    {
+      return m_PropertyItems;
+    }
+
+  void InvalidateList(void);
+  void Invalidate(void) 
+  {
+    // fltk redraw();
+  }
+  
+  int GetCount(void) const 
+  {
+    return m_PropertyItems.size();
+  }
+  void OnButton(void);
+  void OnHelp(void);
+  void RemoveAll();
+  PropertyItem* GetItem(int index);
+  PropertyItem* GetItemDataPtr(int m_curSel);
+
+  void ClearDirty(void)    { m_Dirty = false; }
+  void SetDirty(void)      { m_Dirty = true;  }
+  bool IsDirty(void) const { return m_Dirty;  }
+
+// Implementation
+public:
+  virtual ~PropertyList();
+
+protected:
+
+  int AddPropItem(PropertyItem* pItem,bool reverseOrder);
+
+  std::set<PropertyItem*> m_PropertyItems;
+
+  CMakeSetupGUIImplementation * m_CMakeSetup;
+
+  bool            m_Dirty;
+
+};
+
+
+} // end namespace fltk
+
+#endif