CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/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.9 2011/07/20 20:17:54 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_popup(0),
00040    m_list(0),
00041    m_validator(0),
00042    m_listHeight(100)
00043 {
00044    m_popup = new TGComboBoxPopup(fClient->GetDefaultRoot(), 100, 100, kVerticalFrame);
00045    m_list = new TGListBox(m_popup, 1 /*widget id*/, kChildFrame);
00046    m_list->Resize(100,m_listHeight);
00047    m_list->Associate(this);
00048    m_list->GetScrollBar()->GrabPointer(kFALSE);
00049    m_popup->AddFrame(m_list, new TGLayoutHints(kLHintsExpandX| kLHintsExpandY));
00050    m_popup->MapSubwindows();
00051    m_popup->Resize(m_popup->GetDefaultSize());
00052    m_list->GetContainer()->AddInput(kButtonPressMask | kButtonReleaseMask | kPointerMotionMask);
00053    m_list->SetEditDisabled(kEditDisable);
00054    m_list->GetContainer()->Connect("KeyPressed(TGFrame*,UInt_t,UInt_t)",
00055                                    "FWGUIValidatingTextEntry", this,
00056                                    "keyPressedInPopup(TGFrame*,UInt_t,UInt_t)");
00057    m_list->GetContainer()->SetEditDisabled(kEditDisable);
00058    Connect("TabPressed()", "FWGUIValidatingTextEntry", this, "showOptions()");
00059 
00060 }
00061 
00062 // FWGUIValidatingTextEntry::FWGUIValidatingTextEntry(const FWGUIValidatingTextEntry& rhs)
00063 // {
00064 //    // do actual copying here;
00065 // }
00066 
00067 FWGUIValidatingTextEntry::~FWGUIValidatingTextEntry()
00068 {
00069 }
00070 
00071 //
00072 // assignment operators
00073 //
00074 // const FWGUIValidatingTextEntry& FWGUIValidatingTextEntry::operator=(const FWGUIValidatingTextEntry& rhs)
00075 // {
00076 //   //An exception safe implementation is
00077 //   FWGUIValidatingTextEntry temp(rhs);
00078 //   swap(rhs);
00079 //
00080 //   return *this;
00081 // }
00082 
00083 //
00084 // member functions
00085 //
00086 void
00087 FWGUIValidatingTextEntry::setValidator(FWValidatorBase* iValidator)
00088 {
00089    m_validator = iValidator;
00090 }
00091 
00092 
00093 Bool_t
00094 FWGUIValidatingTextEntry::ProcessMessage(Long_t msg, Long_t parm1, Long_t parm2)
00095 {
00096    //STOLEN FROM TGComboBox.cxx
00097    switch (GET_MSG(msg)) {
00098       case kC_COMMAND:
00099          switch (GET_SUBMSG(msg)) {
00100             case kCM_LISTBOX:
00101                RequestFocus();
00102                insertTextOption(m_options[m_list->GetSelected()].second);
00103                hideOptions();
00104                break;
00105          }
00106          break;
00107 
00108       default:
00109          break;
00110    }
00111    return kTRUE;
00112 
00113 }
00114 
00115 void
00116 FWGUIValidatingTextEntry::keyPressedInPopup(TGFrame* f, UInt_t keysym, UInt_t mask)
00117 {
00118    switch(keysym) {
00119       case kKey_Tab:
00120       case kKey_Escape:
00121          RequestFocus();
00122          hideOptions();
00123          break;
00124       case kKey_Return:
00125          RequestFocus();
00126          //NOTE: If chosen from the keyboard, m_list->GetSelected() does not work, however
00127          // m_list->GetSelectedEntries does work
00128 
00129          //AMT NOTE: TGListEntry does not select entry on key return event, it has to be selected here.
00130          //          Code stolen from TGComboBox::KeyPressed
00131 
00132          const TGLBEntry* entry = dynamic_cast<TGLBEntry*> (f);
00133          if (entry)
00134          {
00135             insertTextOption(m_options[entry->EntryId()].second);
00136             m_list->Selected(entry->EntryId());
00137          }
00138          hideOptions();
00139          break;
00140    }
00141 }
00142 
00143 namespace {
00144    class ChangeFocusTimer : public TTimer {
00145 public:
00146       ChangeFocusTimer(TGWindow* iWindow) :
00147          TTimer(100),
00148          m_window(iWindow) {
00149       }
00150       virtual Bool_t Notify() {
00151          TurnOff();
00152          m_window->RequestFocus();
00153          return kTRUE;
00154       }
00155 private:
00156       TGWindow* m_window;
00157    };
00158 }
00159 
00160 
00161 void
00162 FWGUIValidatingTextEntry::showOptions() {
00163 
00164    if(0!=m_validator) {
00165       const char* text = GetText();
00166       std::string subText(text,text+GetCursorPosition());
00167       //std::cout <<subText<<std::endl;
00168 
00169       typedef std::vector<std::pair<boost::shared_ptr<std::string>, std::string> > Options;
00170       m_validator->fillOptions(text, text+GetCursorPosition(), m_options);
00171       if(m_options.empty()) { return;}
00172       if(m_options.size()==1) {
00173          insertTextOption(m_options.front().second);
00174          return;
00175       }
00176       m_list->RemoveAll();
00177       int index = 0;
00178       for(Options::iterator it = m_options.begin(), itEnd = m_options.end();
00179           it != itEnd; ++it,++index) {
00180          m_list->AddEntry(it->first->c_str(),index);
00181       }
00182       {
00183          unsigned int h = m_list->GetNumberOfEntries()*
00184                           m_list->GetItemVsize();
00185          if(h && (h<m_listHeight)) {
00186             m_list->Resize(m_list->GetWidth(),h);
00187          } else {
00188             m_list->Resize(m_list->GetWidth(),m_listHeight);
00189          }
00190       }
00191       m_list->Select(0,kTRUE);
00192 
00193       int ax,ay;
00194       Window_t wdummy;
00195       gVirtualX->TranslateCoordinates(GetId(), m_popup->GetParent()->GetId(),
00196                                       0, GetHeight(), ax, ay, wdummy);
00197 
00198       //Wait to change focus for when the popup has already openned
00199       std::auto_ptr<TTimer> timer( new ChangeFocusTimer(m_list->GetContainer()) );
00200       timer->TurnOn();
00201       //NOTE: this call has its own internal GUI event loop and will not return
00202       // until the popup has been shut down
00203       m_popup->PlacePopup(ax, ay,
00204                           GetWidth()-2, m_popup->GetDefaultHeight());
00205    }
00206 }
00207 
00208 void
00209 FWGUIValidatingTextEntry::hideOptions() {
00210    m_popup->EndPopup();
00211    fClient->NeedRedraw(this);
00212 }
00213 
00214 void
00215 FWGUIValidatingTextEntry::insertTextOption(const std::string& iOption)
00216 {
00217    long pos = GetCursorPosition();
00218    InsertText(iOption.c_str(), pos);
00219    SetCursorPosition(pos + iOption.size());
00220 }
00221 
00222 //
00223 // const member functions
00224 //
00225 
00226 //
00227 // static member functions
00228 //