CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch13/src/Fireworks/Core/src/FWGUIValidatingTextEntry.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Core
00004 // Class  :     FWGUIValidatingTextEntry
00005 //
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Fri Aug 22 18:13:39 EDT 2008
00011 // $Id: FWGUIValidatingTextEntry.cc,v 1.7 2009/01/23 21:35:43 amraktad Exp $
00012 //
00013 
00014 // system include files
00015 #include <iostream>
00016 #include "TGComboBox.h"
00017 #include "KeySymbols.h"
00018 #include "TTimer.h"
00019 #include "TGWindow.h"
00020 
00021 // user include files
00022 #include "Fireworks/Core/src/FWGUIValidatingTextEntry.h"
00023 #include "Fireworks/Core/src/FWExpressionValidator.h"
00024 
00025 
00026 //
00027 // constants, enums and typedefs
00028 //
00029 
00030 //
00031 // static data member definitions
00032 //
00033 
00034 //
00035 // constructors and destructor
00036 //
00037 FWGUIValidatingTextEntry::FWGUIValidatingTextEntry(const TGWindow *parent, const char *text, Int_t id ) :
00038    TGTextEntry(parent,text,id),
00039    m_validator(0)
00040 {
00041    m_popup = new TGComboBoxPopup(fClient->GetDefaultRoot(), 100, 100, kVerticalFrame);
00042    m_list = new TGListBox(m_popup, 1 /*widget id*/, kChildFrame);
00043    m_list->Resize(100,100);
00044    m_list->Associate(this);
00045    m_list->GetScrollBar()->GrabPointer(kFALSE);
00046    m_popup->AddFrame(m_list, new TGLayoutHints(kLHintsExpandX| kLHintsExpandY));
00047    m_popup->MapSubwindows();
00048    m_popup->Resize(m_popup->GetDefaultSize());
00049    m_list->GetContainer()->AddInput(kButtonPressMask | kButtonReleaseMask | kPointerMotionMask);
00050    m_list->SetEditDisabled(kEditDisable);
00051    m_list->GetContainer()->Connect("KeyPressed(TGFrame*,UInt_t,UInt_t)",
00052                                    "FWGUIValidatingTextEntry", this,
00053                                    "keyPressedInPopup(TGFrame*,UInt_t,UInt_t)");
00054    m_list->GetContainer()->SetEditDisabled(kEditDisable);
00055    Connect("TabPressed()", "FWGUIValidatingTextEntry", this, "showOptions()");
00056 
00057 }
00058 
00059 // FWGUIValidatingTextEntry::FWGUIValidatingTextEntry(const FWGUIValidatingTextEntry& rhs)
00060 // {
00061 //    // do actual copying here;
00062 // }
00063 
00064 FWGUIValidatingTextEntry::~FWGUIValidatingTextEntry()
00065 {
00066 }
00067 
00068 //
00069 // assignment operators
00070 //
00071 // const FWGUIValidatingTextEntry& FWGUIValidatingTextEntry::operator=(const FWGUIValidatingTextEntry& rhs)
00072 // {
00073 //   //An exception safe implementation is
00074 //   FWGUIValidatingTextEntry temp(rhs);
00075 //   swap(rhs);
00076 //
00077 //   return *this;
00078 // }
00079 
00080 //
00081 // member functions
00082 //
00083 void
00084 FWGUIValidatingTextEntry::setValidator(FWValidatorBase* iValidator)
00085 {
00086    m_validator = iValidator;
00087 }
00088 
00089 
00090 Bool_t
00091 FWGUIValidatingTextEntry::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
00092 {
00093    //STOLEN FROM TGComboBox.cxx
00094    switch (GET_MSG(msg)) {
00095       case kC_COMMAND:
00096          switch (GET_SUBMSG(msg)) {
00097             case kCM_LISTBOX:
00098                RequestFocus();
00099                insertTextOption(m_options[m_list->GetSelected()].second);
00100                hideOptions();
00101                break;
00102          }
00103          break;
00104 
00105       default:
00106          break;
00107    }
00108    return kTRUE;
00109 
00110 }
00111 
00112 void
00113 FWGUIValidatingTextEntry::keyPressedInPopup(TGFrame*, UInt_t keysym, UInt_t mask)
00114 {
00115    switch(keysym) {
00116       case kKey_Tab:
00117       case kKey_Escape:
00118          RequestFocus();
00119          hideOptions();
00120          break;
00121       case kKey_Return:
00122          RequestFocus();
00123          //NOTE: If chosen from the keyboard, m_list->GetSelected() does not work, however
00124          // m_list->GetSelectedEntries does work
00125          TList selected;
00126          m_list->GetSelectedEntries(&selected);
00127          assert(selected.GetEntries() == 1);
00128          const TGLBEntry* entry = dynamic_cast<TGLBEntry*> (selected.First());
00129          assert(0!=entry);
00130          insertTextOption(m_options[entry->EntryId()].second);
00131          hideOptions();
00132          break;
00133    }
00134 }
00135 
00136 namespace {
00137    class ChangeFocusTimer : public TTimer {
00138 public:
00139       ChangeFocusTimer(TGWindow* iWindow) :
00140          TTimer(100),
00141          m_window(iWindow) {
00142       }
00143       virtual Bool_t Notify() {
00144          TurnOff();
00145          m_window->RequestFocus();
00146          return kTRUE;
00147       }
00148 private:
00149       TGWindow* m_window;
00150    };
00151 }
00152 
00153 
00154 void
00155 FWGUIValidatingTextEntry::showOptions() {
00156 
00157    if(0!=m_validator) {
00158       const char* text = GetText();
00159       std::string subText(text,text+GetCursorPosition());
00160       //std::cout <<subText<<std::endl;
00161 
00162       typedef std::vector<std::pair<boost::shared_ptr<std::string>, std::string> > Options;
00163       m_validator->fillOptions(text, text+GetCursorPosition(), m_options);
00164       if(m_options.empty()) { return;}
00165       if(m_options.size()==1) {
00166          insertTextOption(m_options.front().second);
00167          return;
00168       }
00169       m_list->RemoveAll();
00170       int index = 0;
00171       for(Options::iterator it = m_options.begin(), itEnd = m_options.end();
00172           it != itEnd; ++it,++index) {
00173          m_list->AddEntry(it->first->c_str(),index);
00174       }
00175       {
00176          unsigned int h = m_list->GetNumberOfEntries()*
00177                           m_list->GetItemVsize();
00178          if(h && (h<100)) {
00179             m_list->Resize(m_list->GetWidth(),h);
00180          } else {
00181             m_list->Resize(m_list->GetWidth(),100);
00182          }
00183       }
00184       m_list->Select(0,kTRUE);
00185 
00186       int ax,ay;
00187       Window_t wdummy;
00188       gVirtualX->TranslateCoordinates(GetId(), m_popup->GetParent()->GetId(),
00189                                       0, GetHeight(), ax, ay, wdummy);
00190 
00191       //Wait to change focus for when the popup has already openned
00192       std::auto_ptr<TTimer> timer( new ChangeFocusTimer(m_list->GetContainer()) );
00193       timer->TurnOn();
00194       //NOTE: this call has its own internal GUI event loop and will not return
00195       // until the popup has been shut down
00196       m_popup->PlacePopup(ax, ay,
00197                           GetWidth()-2, m_popup->GetDefaultHeight());
00198    }
00199 }
00200 
00201 void
00202 FWGUIValidatingTextEntry::hideOptions() {
00203    m_popup->EndPopup();
00204    fClient->NeedRedraw(this);
00205 }
00206 
00207 void
00208 FWGUIValidatingTextEntry::insertTextOption(const std::string& iOption)
00209 {
00210    long pos = GetCursorPosition();
00211    InsertText(iOption.c_str(), pos);
00212    SetCursorPosition(pos + iOption.size());
00213 
00214 }
00215 
00216 //
00217 // const member functions
00218 //
00219 
00220 //
00221 // static member functions
00222 //