00001
00002
00003 #include <math.h>
00004 #include <sstream>
00005 #include <cassert>
00006
00007 #include "TClass.h"
00008 #include "TGClient.h"
00009
00010 #include "Fireworks/Core/interface/FWTableViewTableManager.h"
00011 #include "Fireworks/Core/interface/FWTableView.h"
00012 #include "Fireworks/Core/interface/FWEventItem.h"
00013 #include "Fireworks/Core/interface/FWColorManager.h"
00014 #include "Fireworks/Core/interface/fwLog.h"
00015
00016 #include "Fireworks/TableWidget/interface/FWTableWidget.h"
00017 #include "Fireworks/TableWidget/interface/FWFramedTextTableCellRenderer.h"
00018
00019 FWTableViewTableManager::FWTableViewTableManager (const FWTableView *view)
00020 : m_view(view),
00021 m_graphicsContext(0),
00022 m_renderer(0),
00023 m_rowContext(0),
00024 m_rowRenderer(0),
00025 m_tableFormats(0),
00026 m_caughtExceptionInCellRender(false)
00027 {
00028 GCValues_t gc = *(m_view->m_tableWidget->GetWhiteGC().GetAttributes());
00029 m_graphicsContext = gClient->GetResourcePool()->GetGCPool()->GetGC(&gc,kTRUE);
00030 m_highlightContext = gClient->GetResourcePool()->GetGCPool()->GetGC(&gc,kTRUE);
00031 m_highlightContext->SetForeground(gVirtualX->GetPixel(kBlue));
00032 m_highlightContext->SetBackground(gVirtualX->GetPixel(kBlue));
00033 m_renderer = new FWTextTableCellRenderer(m_graphicsContext,
00034 m_highlightContext,
00035 FWTextTableCellRenderer::kJustifyRight);
00036
00037
00038
00039 m_rowFillContext = gClient->GetResourcePool()->GetGCPool()->GetGC(&gc,kTRUE);
00040 m_rowRenderer = new FWFramedTextTableCellRenderer(m_graphicsContext,
00041 m_rowFillContext,
00042 FWFramedTextTableCellRenderer::kJustifyRight);
00043
00044 }
00045
00046 FWTableViewTableManager::~FWTableViewTableManager ()
00047 {
00048 delete m_renderer;
00049 delete m_rowRenderer;
00050 }
00051
00052 int FWTableViewTableManager::numberOfRows() const
00053 {
00054 if (m_view->item() != 0)
00055 return m_view->item()->size();
00056 else return 0;
00057 }
00058
00059 int FWTableViewTableManager::numberOfColumns() const
00060 {
00061 return m_evaluators.size();
00062 }
00063
00064 std::vector<std::string> FWTableViewTableManager::getTitles () const
00065 {
00066 unsigned int n = numberOfColumns();
00067 std::vector<std::string> ret;
00068 ret.reserve(n);
00069 for (unsigned int i = 0; i < n; ++i) {
00070 ret.push_back(m_tableFormats->at(i).name);
00071
00072 }
00073 return ret;
00074 }
00075
00076 int FWTableViewTableManager::unsortedRowNumber(int iSortedRowNumber) const
00077 {
00078 if (iSortedRowNumber >= (int)m_sortedToUnsortedIndices.size())
00079 return 0;
00080 return m_sortedToUnsortedIndices[iSortedRowNumber];
00081 }
00082
00083 FWTableCellRendererBase *FWTableViewTableManager::cellRenderer(int iSortedRowNumber, int iCol) const
00084 {
00085 const int realRowNumber = unsortedRowNumber(iSortedRowNumber);
00086 if (m_view->item() != 0 &&
00087 m_view->item()->size() &&
00088 m_view->item()->modelData(realRowNumber) != 0 &&
00089 iCol < (int)m_evaluators.size()) {
00090 double ret;
00091 try {
00092
00093 ret = m_evaluators[iCol].evalExpression(m_view->item()->modelData(realRowNumber));
00094 } catch (...) {
00095 if (!m_caughtExceptionInCellRender){
00096 fwLog(fwlog::kError) << "Error: caught exception in the cell renderer while evaluating an expression. Return -999. Error is suppressed in future\n";
00097 }
00098 m_caughtExceptionInCellRender = true;
00099 ret = -999;
00100 }
00101 int precision = m_tableFormats->at(iCol).precision;
00102 char s[100];
00103 char fs[100];
00104 switch (precision) {
00105 case FWTableViewManager::TableEntry::INT:
00106 snprintf(s, sizeof(s), "%d", int(rint(ret)));
00107 break;
00108 case FWTableViewManager::TableEntry::INT_HEX:
00109 snprintf(s, sizeof(s), "0x%x", int(rint(ret)));
00110 break;
00111 case FWTableViewManager::TableEntry::BOOL:
00112 snprintf(s, sizeof(s), int(rint(ret)) != 0 ? "true" : "false");
00113 break;
00114 default:
00115 snprintf(fs, sizeof(fs), "%%.%df", precision);
00116 snprintf(s, sizeof(s), fs, ret);
00117 break;
00118 }
00119 if (not m_view->item()->modelInfo(realRowNumber).isSelected()) {
00120 if (m_view->item()->modelInfo(realRowNumber).displayProperties().isVisible())
00121 if (m_view->m_manager->colorManager().background() == kBlack) {
00122 m_graphicsContext->
00123 SetForeground(gVirtualX->GetPixel(kWhite));
00124 } else {
00125 m_graphicsContext->
00126 SetForeground(gVirtualX->GetPixel(kBlack));
00127 }
00128 else {
00129 if (m_view->m_manager->colorManager().background() == kBlack) {
00130 m_graphicsContext->SetForeground(0x888888);
00131 } else {
00132 m_graphicsContext->SetForeground(0x888888);
00133 }
00134 }
00135 m_renderer->setGraphicsContext(m_graphicsContext);
00136 } else {
00137 m_graphicsContext->
00138 SetForeground(0xffffff);
00139 m_renderer->setGraphicsContext(m_graphicsContext);
00140 }
00141 m_renderer->setData(s, m_view->item()->modelInfo(realRowNumber).isSelected());
00142 } else {
00143 m_renderer->setData("invalid", false);
00144 }
00145 return m_renderer;
00146 }
00147
00148 namespace {
00149 struct itemOrderGt {
00150 bool operator () (const std::pair<bool, double> &i1,
00151 const std::pair<bool, double> &i2)
00152 {
00153
00154 if (i1.first and not i2.first)
00155 return true;
00156 if (i2.first and not i1.first)
00157 return false;
00158
00159 else return i1.second > i2.second;
00160 }
00161 };
00162 struct itemOrderLt {
00163 bool operator () (const std::pair<bool, double> &i1,
00164 const std::pair<bool, double> &i2)
00165 {
00166
00167 if (i1.first and not i2.first)
00168 return true;
00169 if (i2.first and not i1.first)
00170 return false;
00171
00172 else return i1.second < i2.second;
00173 }
00174 };
00175 template<typename S>
00176 void doSort(const FWEventItem& iItem,
00177 int iCol,
00178 const std::vector<FWExpressionEvaluator> &evaluators,
00179 std::multimap<std::pair<bool, double>, int, S>& iMap,
00180 std::vector<int>& oNewSort)
00181 {
00182 int size = iItem.size();
00183 for(int index = 0; index < size; ++index) {
00184 double ret;
00185 try {
00186
00187 ret = evaluators[iCol].evalExpression(iItem.modelData(index));
00188 } catch (...) {
00189 ret = -999;
00190 }
00191 iMap.insert(std::make_pair(
00192 std::make_pair(
00193 iItem.modelInfo(index).displayProperties().isVisible(), ret),
00194 index));
00195 }
00196 std::vector<int>::iterator itVec = oNewSort.begin();
00197 for(typename std::multimap<std::pair<bool, double>,int,S>::iterator
00198 it = iMap.begin(),
00199 itEnd = iMap.end();
00200 it != itEnd;
00201 ++it,++itVec) {
00202 *itVec = it->second;
00203 }
00204 }
00205 }
00206
00207 void FWTableViewTableManager::implSort(int iCol, bool iSortOrder)
00208 {
00209 static const bool sort_down = true;
00210 if (iCol >= (int)m_evaluators.size())
00211 return;
00212 if (0!=m_view->item()) {
00213
00214 if (iSortOrder == sort_down) {
00215 std::multimap<std::pair<bool, double>, int, itemOrderGt> s;
00216 doSort(*m_view->item(), iCol, m_evaluators, s, m_sortedToUnsortedIndices);
00217 } else {
00218 std::multimap<std::pair<bool, double>, int, itemOrderLt> s;
00219 doSort(*m_view->item(), iCol, m_evaluators, s, m_sortedToUnsortedIndices);
00220 }
00221 }
00222 m_view->m_tableWidget->dataChanged();
00223 }
00224
00225 void
00226 FWTableViewTableManager::dataChanged()
00227 {
00228 if (0!=m_view->item()) {
00229 std::vector<int> visible;
00230 visible.reserve(m_view->item()->size());
00231 std::vector<int> invisible;
00232 invisible.reserve(m_view->item()->size());
00233 m_sortedToUnsortedIndices.clear();
00234 m_sortedToUnsortedIndices.reserve(m_view->item()->size());
00235 for(int i=0; i< static_cast<int>(m_view->item()->size()); ++i) {
00236 if (m_view->item()->modelInfo(i).displayProperties().isVisible())
00237 visible.push_back(i);
00238 else invisible.push_back(i);
00239 }
00240 m_sortedToUnsortedIndices.insert(m_sortedToUnsortedIndices.end(),
00241 visible.begin(), visible.end());
00242 m_sortedToUnsortedIndices.insert(m_sortedToUnsortedIndices.end(),
00243 invisible.begin(), invisible.end());
00244 assert(m_sortedToUnsortedIndices.size() == m_view->item()->size());
00245 } else {
00246 m_sortedToUnsortedIndices.clear();
00247 }
00248 FWTableManagerBase::dataChanged();
00249 }
00250
00251 void FWTableViewTableManager::updateEvaluators ()
00252 {
00253 if (m_view->m_iColl == -1) {
00254
00255 m_evaluators.clear();
00256 return;
00257 }
00258 const FWEventItem *item = m_view->m_manager->items()[m_view->m_iColl];
00259 if(0==item) { return;}
00260 std::vector<FWExpressionEvaluator> &ev = m_evaluators;
00261 ev.clear();
00262 for (std::vector<FWTableViewManager::TableEntry>::const_iterator
00263 i = m_tableFormats->begin(),
00264 end = m_tableFormats->end();
00265 i != end; ++i) {
00266 try {
00267 ev.push_back(FWExpressionEvaluator(i->expression, item->modelType()->GetName()));
00268 } catch (...) {
00269 fwLog(fwlog::kError) << "expression "<< i->expression << " is not valid, skipping\n";
00270 ev.push_back(FWExpressionEvaluator("0", item->modelType()->GetName()));
00271 }
00272 }
00273
00274 }
00275
00276 bool FWTableViewTableManager::hasRowHeaders() const
00277 {
00278 return true;
00279 }
00280 FWTableCellRendererBase* FWTableViewTableManager::rowHeader(int iSortedRowNumber) const
00281 {
00282 const int realRowNumber = unsortedRowNumber(iSortedRowNumber);
00283 if (m_view->item() != 0 &&
00284 m_view->item()->size() &&
00285 m_view->item()->modelData(realRowNumber) != 0) {
00286 if (m_view->item()->modelInfo(realRowNumber).displayProperties().isVisible()) {
00287 if (m_view->m_manager->colorManager().background() == kBlack) {
00288 m_graphicsContext->
00289 SetForeground(gVirtualX->GetPixel(kWhite));
00290 } else {
00291 m_graphicsContext->
00292 SetForeground(gVirtualX->GetPixel(kBlack));
00293 }
00294 m_rowFillContext->
00295 SetForeground(gVirtualX->GetPixel(m_view->item()->modelInfo(realRowNumber).
00296 displayProperties().color()));
00297 } else {
00298 m_graphicsContext->SetForeground(0x888888);
00299 m_rowFillContext->SetForeground(m_view->m_manager->colorManager().background());
00300 }
00301
00302 std::ostringstream s;
00303 s<<realRowNumber;
00304 m_rowRenderer->setData(s.str().c_str());
00305 } else {
00306 m_rowRenderer->setData("");
00307 }
00308 return m_rowRenderer;
00309 }
00310