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