CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/Fireworks/TableWidget/src/FWTableWidget.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     TableWidget
00004 // Class  :     FWTableWidget
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Mon Feb  2 16:45:42 EST 2009
00011 // $Id: FWTableWidget.cc,v 1.25 2012/02/22 00:15:44 amraktad Exp $
00012 //
00013 
00014 // system include files
00015 #include <iostream>
00016 #include "TGScrollBar.h"
00017 #include "TGTableLayout.h"
00018 #include "TGResourcePool.h"
00019 
00020 
00021 // user include files
00022 #include "Fireworks/TableWidget/interface/FWTableWidget.h"
00023 #include "Fireworks/TableWidget/interface/FWTableManagerBase.h"
00024 #include "Fireworks/TableWidget/src/FWTabularWidget.h"
00025 #include "Fireworks/TableWidget/src/FWAdapterHeaderTableManager.h"
00026 #include "Fireworks/TableWidget/src/FWAdapterRowHeaderTableManager.h"
00027 
00028 static const unsigned long kWidgetColor = 0x2f2f2f;
00029 
00030 //
00031 // constants, enums and typedefs
00032 //
00033 static const UInt_t kRowOptions = kLHintsExpandX|kLHintsFillX|kLHintsShrinkX;
00034 static const UInt_t kColOptions = kLHintsExpandY|kLHintsFillY|kLHintsShrinkY;
00035 
00036 //
00037 // static data member definitions
00038 //
00039 
00040 //
00041 // constructors and destructor
00042 //
00043 FWTableWidget::FWTableWidget(FWTableManagerBase* iManager,const TGWindow* p):
00044 TGCompositeFrame(p),
00045    m_bodyTable(iManager),
00046    m_headerTable(iManager->hasLabelHeaders()?new FWAdapterHeaderTableManager(iManager): static_cast<FWTableManagerBase*>(0)),
00047    m_rowHeaderTable(iManager->hasRowHeaders()?new FWAdapterRowHeaderTableManager(iManager): static_cast<FWTableManagerBase*>(0)),
00048    m_header(0),
00049    m_rowHeader(0),
00050    m_showingVSlider(true),
00051    m_showingHSlider(true),
00052    m_sortedColumn(-1),
00053    m_descendingSort(true),
00054    m_forceLayout(false),
00055    m_headerBackground(0),
00056    m_headerForeground(0),
00057    m_lineSeparator(0)
00058 {
00059    SetLayoutManager( new TGTableLayout(this,3,3) );
00060    
00061    if(0!=m_headerTable) {
00062       m_header = new FWTabularWidget(m_headerTable,this);
00063       AddFrame(m_header, new TGTableLayoutHints(1,2,0,1,kLHintsTop|kLHintsLeft|kRowOptions));   
00064       if (m_bodyTable->cellDataIsSortable()) m_header->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)","FWTableWidget",this,"buttonReleasedInHeader(Int_t,Int_t,Event_t*,Int_t,Int_t)");
00065    }
00066    m_body = new FWTabularWidget(iManager,this,GetWhiteGC()());
00067    //m_body->SetBackgroundColor(kWidgetColor);
00068    AddFrame(m_body, new TGTableLayoutHints(1,2,1,2,kLHintsTop|kLHintsLeft|kRowOptions|kColOptions));
00069    m_body->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)","FWTableWidget",this,"buttonReleasedInBody(Int_t,Int_t,Event_t*,Int_t,Int_t)");
00070 
00071    //set sizes
00072    std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
00073    if(0!=m_header) {
00074       std::vector<unsigned int> headerWidths = m_header->widthOfTextInColumns();
00075       for(std::vector<unsigned int>::iterator it = columnWidths.begin(), itEnd=columnWidths.end(), itHeader=headerWidths.begin();
00076           it != itEnd;
00077           ++it,++itHeader) {
00078          if(*itHeader > *it) {
00079             *it = *itHeader;
00080          }
00081       }
00082    }
00083    if(0!=m_header) {
00084       m_header->setWidthOfTextInColumns(columnWidths);
00085    }
00086    m_body->setWidthOfTextInColumns(columnWidths);
00087    if(m_rowHeaderTable) {
00088       m_rowHeader = new FWTabularWidget(m_rowHeaderTable,this, GetWhiteGC()());
00089       //m_rowHeader->SetBackgroundColor(kWidgetColor);
00090 
00091       AddFrame(m_rowHeader, new TGTableLayoutHints(0,1,1,2,kLHintsTop|kLHintsLeft|kColOptions));
00092       m_rowHeader->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)","FWTableWidget",this,"buttonReleasedInBody(Int_t,Int_t,Event_t*,Int_t,Int_t)");
00093       m_rowHeader->Connect("buttonReleased(Int_t,Int_t,Event_t*,Int_t,Int_t)","FWTableWidget",this,"buttonReleasedInRowHeader(Int_t,Int_t,Event_t*,Int_t,Int_t)");
00094       m_rowHeader->setWidthOfTextInColumns(m_rowHeader->widthOfTextInColumns());
00095    }
00096 
00097    m_hSlider = new TGHScrollBar(this);
00098    AddFrame(m_hSlider, new TGTableLayoutHints(1,2,2,3,kRowOptions));
00099    m_hSlider->Connect("ProcessedEvent(Event_t*)", "FWTableWidget", this, "childrenEvent(Event_t *)");
00100    m_vSlider = new TGVScrollBar(this);
00101    m_vSlider->SetSmallIncrement(12);
00102    AddFrame(m_vSlider, new TGTableLayoutHints(2,3,1,2,kColOptions));
00103    m_vSlider->Connect("ProcessedEvent(Event_t*)", "FWTableWidget", this, "childrenEvent(Event_t *)");
00104    MapSubwindows();
00105    Layout();
00106    //HideFrame(m_hSlider);
00107    //HideFrame(m_vSlider);
00108    m_hSlider->Associate(this);
00109    m_vSlider->Associate(this);
00110    
00111    m_hSlider->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
00112    m_vSlider->SetEditDisabled(kEditDisable | kEditDisableGrab | kEditDisableBtnEnable);
00113    m_bodyTable->Connect("dataChanged()","FWTableWidget",this,"dataChanged()");
00114 }
00115 
00116 // FWTableWidget::FWTableWidget(const FWTableWidget& rhs)
00117 // {
00118 //    // do actual copying here;
00119 // }
00120 
00121 FWTableWidget::~FWTableWidget()
00122 {
00123    if(0!=m_headerBackground) {
00124       gClient->GetResourcePool()->GetGCPool()->FreeGC(m_headerBackground->GetGC());
00125    }
00126    if(0!= m_headerForeground) {
00127       gClient->GetResourcePool()->GetGCPool()->FreeGC(m_headerForeground->GetGC());
00128    }
00129    
00130    if(0!= m_lineSeparator) {
00131       gClient->GetResourcePool()->GetGCPool()->FreeGC(m_lineSeparator->GetGC());
00132    }
00133       
00134 }
00135 
00136 //
00137 // assignment operators
00138 //
00139 // const FWTableWidget& FWTableWidget::operator=(const FWTableWidget& rhs)
00140 // {
00141 //   //An exception safe implementation is
00142 //   FWTableWidget temp(rhs);
00143 //   swap(rhs);
00144 //
00145 //   return *this;
00146 // }
00147 
00148 //
00149 // member functions
00150 //
00151 void 
00152 FWTableWidget::sort(UInt_t iColumn, bool iDescendingSort)
00153 {
00154    if(0!=m_headerTable) {
00155       m_headerTable->sort(iColumn,iDescendingSort);
00156    }
00157    m_bodyTable->sort(iColumn,iDescendingSort);
00158    m_sortedColumn =iColumn;
00159    m_descendingSort=iDescendingSort;
00160    
00161    //fClient->NeedRedraw(m_header);
00162    //fClient->NeedRedraw(m_body);
00163 }
00164 
00165 void 
00166 FWTableWidget::SetBackgroundColor(Pixel_t iColor)
00167 {
00168    TGFrame::SetBackgroundColor(iColor);
00169    if(m_rowHeaderTable) {
00170       m_rowHeader->SetBackgroundColor(iColor);
00171       fClient->NeedRedraw(m_rowHeader);
00172    }
00173    if(m_header) {
00174       m_header->SetBackgroundColor(iColor);
00175       fClient->NeedRedraw(m_header);
00176    }
00177    m_body->SetBackgroundColor(iColor);
00178    fClient->NeedRedraw(m_body);
00179    fClient->NeedRedraw(this);
00180 }
00181 
00182 void 
00183 FWTableWidget::SetHeaderBackgroundColor(Pixel_t iColor)
00184 {
00185    if(0==m_headerBackground) {
00186       GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
00187       m_headerBackground = gClient->GetResourcePool()->GetGCPool()->GetGC(&t,kTRUE);
00188    }
00189    m_headerBackground->SetForeground(iColor);
00190    if(0!=m_header) {
00191       m_header->setBackgroundAreaContext((*m_headerBackground)());
00192    }
00193 }
00194 void 
00195 FWTableWidget::SetHeaderForegroundColor(Pixel_t iColor)
00196 {
00197    if(0==m_headerForeground) {
00198       GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
00199       m_headerForeground = gClient->GetResourcePool()->GetGCPool()->GetGC(&t,kTRUE);
00200    }
00201    m_headerForeground->SetForeground(iColor);
00202    if(0!=m_header) {
00203       m_header->setLineContext((*m_headerForeground)());
00204    }
00205 }
00206 
00207 void 
00208 FWTableWidget::SetLineSeparatorColor(Pixel_t iColor)
00209 {
00210    if(0==m_lineSeparator) {
00211       GCValues_t t = *(gClient->GetResourcePool()->GetFrameGC()->GetAttributes());
00212       m_lineSeparator = gClient->GetResourcePool()->GetGCPool()->GetGC(&t,kTRUE);
00213    }
00214    m_lineSeparator->SetForeground(iColor);
00215    m_body->setLineContext( (*m_lineSeparator)());
00216    if(m_rowHeader) {
00217       m_rowHeader->setLineContext( (*m_lineSeparator)() );
00218    }
00219 }
00220 
00221 
00222 void 
00223 FWTableWidget::Resize(UInt_t w, UInt_t h)
00224 {
00225    handleResize(w,h);
00226    TGCompositeFrame::Resize(w,h);
00227 }
00228 
00229 bool 
00230 FWTableWidget::handleResize(UInt_t w, UInt_t h)
00231 {
00232    //std::cout <<"Resize"<<std::endl;
00233    bool redoLayout=false;
00234 
00235    TGDimension def  = m_body->GetDefaultSize();
00236    UInt_t fullWidth = def.fWidth;
00237    if(m_rowHeader) {
00238       fullWidth += m_rowHeader->GetDefaultSize().fWidth;
00239    }
00240 
00241    UInt_t headerHeight = 0;
00242    if(m_header) {
00243       headerHeight = m_header->GetHeight();
00244    }
00245    UInt_t fullHeight = def.fHeight + headerHeight;
00246 
00247    UInt_t sBarWidth  = (h < fullHeight) ? m_vSlider->GetWidth()  : 0;
00248    UInt_t sBarHeight = (w < fullWidth)  ? m_hSlider->GetHeight() : 0;
00249    if (sBarWidth == 0 && sBarHeight > 0 && h < fullHeight + sBarHeight)
00250       sBarWidth = m_vSlider->GetWidth();
00251    else if (sBarHeight == 0 && sBarWidth > 0 && h < fullWidth + sBarWidth)
00252       sBarHeight = m_hSlider->GetHeight();
00253    fullWidth  += sBarWidth;
00254    fullHeight += sBarHeight;
00255 
00256    if(w < fullWidth) {
00257       if(!m_showingHSlider) {
00258          ShowFrame(m_hSlider);
00259          redoLayout=true;
00260          m_showingHSlider=true;
00261       }
00262       m_hSlider->SetRange(fullWidth,w);
00263    } else {
00264       if(m_showingHSlider) {
00265          HideFrame(m_hSlider);
00266          m_hSlider->SetPosition(0);
00267          m_showingHSlider = false;
00268          redoLayout=true;
00269       }
00270    }
00271 
00272    if(h < fullHeight) {
00273       if(!m_showingVSlider) {
00274          ShowFrame(m_vSlider);
00275          m_showingVSlider=true;
00276          redoLayout=true;
00277       }
00278       m_vSlider->SetRange(fullHeight,h);
00279    } else {
00280       if(m_showingVSlider) {
00281          HideFrame(m_vSlider);
00282          m_vSlider->SetPosition(0);
00283          m_showingVSlider = false;
00284          redoLayout=true;
00285       }
00286    }
00287    if(redoLayout) {
00288       Layout();
00289    }
00290 
00291    return redoLayout;
00292 }
00293 
00294 void    
00295 FWTableWidget::MoveResize(Int_t x, Int_t y, UInt_t w, UInt_t h)
00296 {
00297    //std::cout <<"MoveResize"<<std::endl;
00298    if(w != GetWidth() || h != GetHeight()) {
00299       handleResize(w,h);
00300    }
00301    TGCompositeFrame::MoveResize(x,y,w,h);
00302 }
00303 
00304 Bool_t 
00305 FWTableWidget::ProcessMessage(Long_t msg, Long_t parm1, Long_t)
00306 {
00307    // Handle message generated by the canvas scrollbars.
00308 
00309    switch (GET_MSG(msg)) {
00310       case kC_HSCROLL:
00311          switch (GET_SUBMSG(msg)) {
00312             case kSB_SLIDERTRACK:
00313             case kSB_SLIDERPOS:
00314                m_body->setHorizontalOffset(parm1);
00315                if(m_header) {
00316                   m_header->setHorizontalOffset(parm1);
00317                }
00318                break;
00319          }
00320          break;
00321 
00322       case kC_VSCROLL:
00323          switch (GET_SUBMSG(msg)) {
00324             case kSB_SLIDERTRACK:
00325             case kSB_SLIDERPOS:
00326                m_body->setVerticalOffset(parm1);
00327                if(m_rowHeader) {
00328                   m_rowHeader->setVerticalOffset(parm1);
00329                }
00330                break;
00331          }
00332          break;
00333 
00334       default:
00335          break;
00336    }
00337    return kTRUE;
00338 }
00339 
00340 void 
00341 FWTableWidget::buttonReleasedInHeader(Int_t row, Int_t column, Event_t* event,Int_t,Int_t)
00342 {
00343    Int_t btn = event->fCode;
00344    Int_t keyMod = event->fState;
00345    //Int_t keyMod = event->fState;
00346    if (btn == kButton1 || btn == kButton3) {
00347         if(m_sortedColumn==column) {
00348              sort(column, !m_descendingSort);
00349         } else {
00350              sort(column,true);
00351         }
00352    }
00353    columnClicked(column, btn, keyMod);
00354 }
00355 
00356 void 
00357 FWTableWidget::buttonReleasedInBody(Int_t row, Int_t column, Event_t* event,Int_t iRelX,Int_t iRelY)
00358 {
00359    Int_t btn = event->fCode;
00360    Int_t keyMod = event->fState;
00361    if(btn == kButton5){
00362       //should scroll down
00363       if(m_vSlider) {
00364          Int_t p = m_vSlider->GetPosition();
00365          Int_t mx = m_vSlider->GetRange();
00366          p+=m_vSlider->GetSmallIncrement();
00367          if(p>mx){ p=mx;}
00368          m_vSlider->SetPosition(p);
00369       }
00370       return;
00371    }
00372    if(btn == kButton4){
00373       //should scroll up
00374       if(m_vSlider) {
00375          Int_t p = m_vSlider->GetPosition();
00376          p -=m_vSlider->GetSmallIncrement();
00377          if(0>p) {p=0;}
00378          m_vSlider->SetPosition(p);
00379       }
00380       return;
00381    }
00382    if(btn != kButton1 && btn != kButton3) {return;}
00383    if(row>=-1 and row < m_bodyTable->numberOfRows()) {
00384       Int_t globalX,globalY;
00385       Window_t childdum;
00386       gVirtualX->TranslateCoordinates(m_body->GetId(),
00387                                       gClient->GetDefaultRoot()->GetId(),
00388                                       event->fX,event->fY,globalX,globalY,childdum);
00389       cellClicked(m_bodyTable->unsortedRowNumber(row), column, btn, keyMod, globalX, globalY);
00390       rowClicked(m_bodyTable->unsortedRowNumber(row), btn,keyMod,globalX,globalY);
00391    }
00392 }
00393 
00394 void
00395 FWTableWidget::cellClicked(Int_t row, Int_t column, Int_t btn, Int_t keyMod, Int_t iGlobalX, Int_t iGlobalY)
00396 {
00397    keyMod = (keyMod&(kKeyShiftMask|kKeyControlMask));
00398    //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
00399    Long_t args[6];
00400    args[0]=(Long_t)row;
00401    args[1]=(Long_t)column;
00402    args[2]=(Long_t)btn;
00403    args[3]=(Long_t)keyMod;
00404    args[4]=(Long_t)iGlobalX;
00405    args[5]=(Long_t)iGlobalY;
00406    Emit("cellClicked(Int_t,Int_t,Int_t,Int_t,Int_t,Int_t)",args);
00407 }
00408 
00409 void
00410 FWTableWidget::childrenEvent(Event_t *)
00411 {
00412    Clicked();
00413 }
00414 
00415 void
00416 FWTableWidget::Clicked()
00417 {
00418    Emit("Clicked()");
00419 }
00420 
00421 void 
00422 FWTableWidget::rowClicked(Int_t row, Int_t btn, Int_t keyMod, Int_t iGlobalX, Int_t iGlobalY)
00423 {
00424    keyMod = (keyMod&(kKeyShiftMask|kKeyControlMask));
00425    //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
00426    Long_t args[5];
00427    args[0]=(Long_t)row;
00428    args[1]=(Long_t)btn;
00429    args[2]=(Long_t)keyMod;
00430    args[3]=(Long_t)iGlobalX;
00431    args[4]=(Long_t)iGlobalY;
00432    Emit("rowClicked(Int_t,Int_t,Int_t,Int_t,Int_t)",args);      
00433 }
00434 
00435 void 
00436 FWTableWidget::columnClicked(Int_t column, Int_t btn, Int_t keyMod)
00437 {
00438    keyMod = (keyMod&(kKeyShiftMask|kKeyControlMask));
00439    //std::cout <<"rowClicked "<<row<<" "<<btn<<" "<<keyMod<<std::endl;
00440    Long_t args[3];
00441    args[0]=(Long_t)column;
00442    args[1]=(Long_t)btn;
00443    args[2]=(Long_t)keyMod;
00444    Emit("columnClicked(Int_t,Int_t,Int_t)",args);      
00445 }
00446 
00447 void 
00448 FWTableWidget::dataChanged()
00449 {
00450    bool needs_layout = m_forceLayout; m_forceLayout = false;
00451 
00452    m_body->dataChanged();
00453    if(m_rowHeader) {
00454       m_rowHeader->dataChanged();
00455       m_rowHeader->setWidthOfTextInColumns(m_rowHeader->widthOfTextInColumns());
00456    }
00457    //set sizes
00458    std::vector<unsigned int> columnWidths = m_body->widthOfTextInColumns();
00459    if(m_header) {
00460       // reset header back to its internal max rather than the last width
00461       m_header->dataChanged();  
00462       std::vector<unsigned int> headerWidths = m_header->widthOfTextInColumns();
00463       for(std::vector<unsigned int>::iterator it = columnWidths.begin(), itEnd=columnWidths.end(), itHeader=headerWidths.begin();
00464           it != itEnd;
00465           ++it,++itHeader) {
00466          if(*itHeader > *it) {
00467             *it = *itHeader;
00468          }
00469       }
00470       m_header->setWidthOfTextInColumns(columnWidths);
00471    } 
00472    m_body->setWidthOfTextInColumns(columnWidths);
00473 
00474    //this updates sliders to match our new data
00475    bool layoutDoneByhandleResize = handleResize(GetWidth(), GetHeight());
00476    if (needs_layout && ! layoutDoneByhandleResize)
00477    {
00478       Layout();
00479    }
00480    gClient->NeedRedraw(m_body);
00481    if (m_header) gClient->NeedRedraw(m_header);
00482    if (m_rowHeader) gClient->NeedRedraw(m_rowHeader);
00483    
00484 }
00485 
00486 void 
00487 FWTableWidget::buttonPressedInRowHeader(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY)
00488 {
00489    Int_t btn = event->fCode;
00490    if(btn != kButton1 && btn != kButton3) {return;}
00491    m_bodyTable->buttonReleasedInRowHeader(row, event, relX, relY);
00492 }
00493 void 
00494 FWTableWidget::buttonReleasedInRowHeader(Int_t row, Int_t column, Event_t* event, Int_t relX, Int_t relY)
00495 {
00496    Int_t btn = event->fCode;
00497    if(btn != kButton1 && btn != kButton3) {return;}
00498    m_bodyTable->buttonReleasedInRowHeader(row, event, relX, relY);
00499 }
00500 
00501 //
00502 // const member functions
00503 //
00504 TGDimension 
00505 FWTableWidget::GetDefaultSize() const
00506 {
00507    TGDimension returnValue;
00508    if(m_header){
00509       returnValue.fHeight += m_header->GetDefaultHeight();
00510    }
00511    if(m_rowHeader) {
00512       returnValue.fWidth += m_rowHeader->GetDefaultWidth();
00513    }
00514    returnValue = returnValue + m_body->GetDefaultSize();
00515    returnValue.fHeight += m_hSlider->GetDefaultHeight();
00516    returnValue.fWidth += m_vSlider->GetDefaultWidth();
00517    
00518    return returnValue;
00519 }
00520 
00521 void
00522 FWTableWidget::disableGrowInWidth()
00523 {
00524    m_body->disableGrowInWidth();
00525    if (m_header) m_header->disableGrowInWidth();
00526    if (m_rowHeader) m_rowHeader->disableGrowInWidth();
00527 }
00528 
00529 void
00530 FWTableWidget::DoRedraw()
00531 {
00532    // override virtual TGFrame::DoRedraw() to prevent call of gVirtualX->ClearArea();
00533 }
00534 //
00535 // static member functions
00536 //
00537 
00538 ClassImp(FWTableWidget)