Project

General

Profile

Bug #2111 » ItemViewAutoSize.cc

autosize adapter implementation - Stefan Ruppert, 08/16/2013 11:12 AM

 
#include "myarmconfig.h"

#include "web/util/ItemViewAutoSize.h"
#include "web/WebBrowserIf.h"

#include <algorithm>

#include "lib/preferences.h"

#include <Wt/WDateTime>

using namespace Wt;

namespace myarm
{

namespace web
{


ItemViewAutoSize::ItemViewAutoSize(Wt::WAbstractItemModel* model,
Wt::WAbstractItemView* view)
: columns_()
, defColumnWidth_(150)
, scrollBarWidth_(0)
, model_(model)
, view_(view)
{
}

void ItemViewAutoSize::setColumnHidden(int column, bool hidden)
{
adjustColumns();
if(column >= 0 && column < (int)columns_.size())
{
columns_[column].hidden_ = hidden;
}
}

void ItemViewAutoSize::clearColumns()
{
adjustColumns();
for(size_t i=0; i<columns_.size(); ++i)
{
columns_[i].clear();
}
}

void ItemViewAutoSize::setColumnWidth(int column, const WLength& width)
{
adjustColumns();
if(column >= 0 && column < (int)columns_.size())
{
columns_[column].width_ = width;
}
}

void ItemViewAutoSize::autoSize(int viewWidth, int visibleRows)
{
adjustColumns();

int viewRows = model_->rowCount();
int fixedWidth = 0;
int avgChars[columns_.size()];
int avgTotalChars = 0;
int shownColumns = 0;
if(scrollBarWidth_ == 0)
scrollBarWidth_ = WebBrowserIf::instance()->verticalScrollbarWidth();

for(size_t i=0; i<columns_.size(); ++i)
{
// do not count hidden columns
if(isHidden(i))
continue;

++shownColumns;
if(columns_[i].fixedWidth_)
{
fixedWidth += columns_[i].width_.toPixels();
} else
{
if(columns_[i].count_ > 0)
{
int avgchr = (columns_[i].accLength_ / columns_[i].count_) + 1;
avgChars[i] = avgchr;
avgTotalChars += avgchr;
} else
{
avgChars[i] = 0;
}
}
}
if(avgTotalChars <= 0)
return;

// add 7 pixel for each shown column
fixedWidth += shownColumns*7;

if(viewRows > visibleRows)
fixedWidth += scrollBarWidth_;

double stretchWidth = std::max(viewWidth - fixedWidth, 10);
for(size_t i=0; i<columns_.size(); ++i)
{
view_->setColumnHidden(i, isHidden(i));
// do not count hidden columns
if(isHidden(i))
continue;
if(!columns_[i].fixedWidth_)
{
double percent = (double)avgChars[i] / (double)avgTotalChars;
double maxPix = WLength(columns_[i].maxLength_, WLength::FontEm).toPixels()/2.0;
double pixel = std::max(stretchWidth*percent, maxPix);
columns_[i].width_ = WLength(pixel, WLength::Pixel);
}
view_->setColumnWidth(i, columns_[i].width_);
}
}

void ItemViewAutoSize::calcSize()
{
size_t rows = model_->rowCount();
size_t columns = model_->columnCount();
adjustColumns();
for(size_t c=0; c<columns; ++c)
columns_[c].clear();
for(size_t r=0; r<rows; ++r)
{
for(size_t c=0; c<columns; ++c)
{
size_t len = asString(model_->data(r, c)).value().size();
if(len > 0)
{
if(columns_[c].maxLength_ < len)
columns_[c].maxLength_ = len;
columns_[c].accLength_ += len;
++columns_[c].count_;
}
}
}
}

void ItemViewAutoSize::adjustColumns() const
{
if(columns_.size() != (size_t)model_->columnCount())
columns_.resize(model_->columnCount());
}

bool ItemViewAutoSize::isHidden(int column) const
{
if(column >= 0 && column < (int)columns_.size())
{
const Column& col = columns_[column];
return col.hidden_ || col.count_ == 0;
}
return true;
}

} // namespace web

} // namespace myarm
(3-3/4)