GroupAndFooterSummaries Example

#include <QtGui>
#include <QMessageBox>

#include "window.h"

/* Window */
Window::Window()
: DemoMainWindow(QStringLiteral("QtitanDataGrid"), QStringLiteral(QTN_VERSION_DATAGRID_STR))
{
    setWindowTitle(tr("QtitanDataGrid Demo (Summaries)"));
    setGeometry(150, 150, 1000, 800);

    Grid::loadTranslation();

    m_grid = new Qtitan::Grid(this);
    SummaryDemoModel* model = new SummaryDemoModel(m_grid);

    // Configure grid view
    m_grid->setViewType(Qtitan::Grid::BandedTableView);
    Qtitan::GridBandedTableView* view = m_grid->view<Qtitan::GridBandedTableView>();
    view->beginUpdate();

    view->addBand(tr("Section 1"));
    view->addBand(tr("Section 2"));
    view->addBand(tr("Section 3"));
    view->options().setFooterSummaryVisible(true);
    //view->options().setGroupSummaryPlace(GroupSummaryFooter);

    //Connect Grid's context menu handler.
    connect(view, SIGNAL(contextMenu(ContextMenuEventArgs*)), this, SLOT(contextMenu(ContextMenuEventArgs* )));
    connect(view, SIGNAL(summaryFooterTextChanging(SummaryTextEventArgs*)), this, SLOT(summaryFooterTextChanging(SummaryTextEventArgs*)));
    connect(view, SIGNAL(summaryGroupTextChanging(SummaryGroupTextEventArgs*)), this, SLOT(summaryGroupTextChanging(SummaryGroupTextEventArgs*)));

    view->setModel(model);

    Qtitan::GridBandedTableColumn* column = (Qtitan::GridBandedTableColumn *)view->getColumn(0);
    column->setBandIndex(0);
    column->editorRepository()->setAlignment(Qt::AlignCenter);

    //Configure the summary
    column->setDefaultGroupSummary(GridSummary::Max);
    column = (Qtitan::GridBandedTableColumn *)view->getColumn(1);
    column->setBandIndex(1);

    //Configure the summary
    column->setDefaultGroupSummary(GridSummary::Avg);
    column->setFooterSummary(GridSummary::Avg);
    column = (Qtitan::GridBandedTableColumn *)view->getColumn(2);
    column->setBandIndex(1);

    //Configure the summary
    column->setDefaultGroupSummary(GridSummary::Count);
    column->setFooterSummary(GridSummary::Count);
    column = (Qtitan::GridBandedTableColumn *)view->getColumn(3);
    column->setBandIndex(1);
    //column->setTextOrientation(Qt::Vertical);

    //Add cell button to the column.
    column->addButton();
    connect(column, SIGNAL(buttonClicked(CellButtonClickEventArgs*)), this, SLOT(cellButtonClicked(CellButtonClickEventArgs*)));

    column = (Qtitan::GridBandedTableColumn *)view->getColumn(4);
    column->setBandIndex(2);

    //Add cell button to the column.
    column->addButton(GridColumn::ClearButtonIcon, Qtitan::AtBeginning, GridColumn::MouseOverPolicy);
    connect(column, SIGNAL(buttonClicked(CellButtonClickEventArgs*)), this, SLOT(cellButtonClicked(CellButtonClickEventArgs*)));

    column = (Qtitan::GridBandedTableColumn *)view->getColumn(4);
    column->setGroupIndex(0);

    //Configure the summary
    column->setDefaultGroupSummary(GridSummary::Min);
    column->setFooterSummary(GridSummary::Max);

    //Show button menu for all column headers.
    for (int i = 0; i < view->getColumnCount(); ++i)
        static_cast<GridTableColumn *>(view->getColumn(i))->setMenuButtonVisible(true);

    GridTableBand* band = view->getBand(0);
    band->setFixedKind(Qtitan::AtBeginning);
    band->setWidth(200);

    band = view->getBand(1);
    band->setWidth(300);

    band = view->getBand(2);
    band->setWidth(150);

    view->endUpdate();

    view->expandAll();

    setDemoWidget(m_grid, createSettingsWidget());
}

QWidget* Window::createSettingsWidget()
{
    QWidget* settings = new QWidget(this);
    QVBoxLayout* l = new QVBoxLayout(settings);

    l->addLayout(createStyleSetting());

    QCheckBox* autoWidthCheck = new QCheckBox(settings);
    l->addWidget(autoWidthCheck);
    autoWidthCheck->setText(tr("Column auto width"));
    connect(autoWidthCheck, SIGNAL(stateChanged(int)), this, SLOT(autoWidthStateChanged(int)));

    QCheckBox* fastScrollCheck = new QCheckBox(settings);
    fastScrollCheck->setText(tr("Fast scroll effect"));
    connect(fastScrollCheck, SIGNAL(stateChanged(int)), this, SLOT(fastScrollChanged(int)));
    l->addWidget(fastScrollCheck);
    fastScrollCheck->setChecked(true);

    QCheckBox* dottedLineCheck = new QCheckBox(settings);
    dottedLineCheck->setText(tr("Dotted grid line"));
    connect(dottedLineCheck, SIGNAL(stateChanged(int)), this, SLOT(dottedLineChanged(int)));
    l->addWidget(dottedLineCheck);
    dottedLineCheck->setChecked(false);

    QLabel* label = new QLabel(settings);
    QHBoxLayout* hl = new QHBoxLayout(0);
    label->setText(tr("Grid line style:"));
    QComboBox* lineStylesSelect = new QComboBox(settings);

    lineStylesSelect->addItem(tr("None"));
    lineStylesSelect->addItem(tr("Both"));
    lineStylesSelect->addItem(tr("Both2D"));
    lineStylesSelect->addItem(tr("Horizontal"));
    lineStylesSelect->addItem(tr("Horizontal2D"));
    lineStylesSelect->addItem(tr("Vertical"));
    lineStylesSelect->addItem(tr("Vertical2D"));
    connect(lineStylesSelect, SIGNAL(currentIndexChanged(int)), this, SLOT(selectGridLineStyles(int)));
    hl->addWidget(label);
    hl->addWidget(lineStylesSelect);
    l->addLayout(hl);
    lineStylesSelect->setCurrentIndex(4);

    label = new QLabel(settings);
    hl = new QHBoxLayout(settings);
    label->setText(tr("Group Summary Place:"));
    QComboBox* groupSummarySelect = new QComboBox(settings);

    groupSummarySelect->addItem(tr("Hide"));
    groupSummarySelect->addItem(tr("Footer"));
    groupSummarySelect->addItem(tr("Group"));
    groupSummarySelect->addItem(tr("Group Plus"));
    connect(groupSummarySelect, SIGNAL(currentIndexChanged(int)), this, SLOT(selectGroupSummaryPlace(int)));
    hl->addWidget(label);
    hl->addWidget(groupSummarySelect);
    l->addLayout(hl);
    groupSummarySelect->setCurrentIndex(1);

    QCheckBox* zoomEnable = new QCheckBox(settings);
    zoomEnable->setText(tr("Zoom enabled"));
    zoomEnable->setChecked(true);
    connect(zoomEnable, SIGNAL(stateChanged(int)), this, SLOT(zoomEnabledChanged(int)));
    l->addWidget(zoomEnable);

    QCheckBox* zoomIndicator = new QCheckBox(settings);
    zoomIndicator->setText(tr("Show zoom indicator"));
    zoomIndicator->setChecked(true);
    connect(zoomIndicator, SIGNAL(stateChanged(int)), this, SLOT(zoomIndicatorChanged(int)));
    l->addWidget(zoomIndicator);

    QSlider* zoomSlider = new QSlider(settings);
    zoomSlider->setOrientation(Qt::Horizontal);
    zoomSlider->setTickPosition(QSlider::TicksBothSides);
    zoomSlider->setMinimum(25);
    zoomSlider->setMaximum(300);
    zoomSlider->setTickInterval(25);
    zoomSlider->setSingleStep(25);
    zoomSlider->setValue(100);
    connect(zoomSlider, SIGNAL(sliderMoved(int)), this, SLOT(zoomValueChanged(int)));
    connect(m_grid->view<Qtitan::GridTableView>(), SIGNAL(zoomChanged(int)), zoomSlider, SLOT(setValue(int)));
    l->addWidget(zoomSlider);

    QCheckBox* cellAutoRaise = new QCheckBox(settings);
    cellAutoRaise->setText(tr("Auto raise cell button"));
    connect(cellAutoRaise, SIGNAL(stateChanged(int)), this, SLOT(cellButtonAutoRaiseEnabled(int)));
    cellAutoRaise->setChecked(true);
    l->addWidget(cellAutoRaise);

    QCheckBox* frozenRowsBox = new QCheckBox(settings);
    frozenRowsBox->setText(tr("Frozen Rows"));
    connect(frozenRowsBox, SIGNAL(stateChanged(int)), this, SLOT(frozenRowsEnabled(int)));
    frozenRowsBox->setChecked(true);
    l->addWidget(frozenRowsBox);

    QCheckBox* transparentBox = new QCheckBox(settings);
    transparentBox->setText(tr("Transparent Background"));
    connect(transparentBox, SIGNAL(stateChanged(int)), this, SLOT(transparentBackgroundEnabled(int)));
    transparentBox->setChecked(false);
    l->addWidget(transparentBox);

    QCheckBox* rowSizingBox = new QCheckBox(settings);
    rowSizingBox->setText(tr("Resizing row (new)"));
    connect(rowSizingBox, SIGNAL(stateChanged(int)), this, SLOT(rowSizingEnabled(int)));
    rowSizingBox->setChecked(false);
    l->addWidget(rowSizingBox);

    QPushButton* printButton = new QPushButton(settings);
    printButton->setText(tr("Print Preview"));
    connect(printButton, SIGNAL(clicked()), this, SLOT(printPreview()));
    l->addWidget(printButton);

    return settings;
}

void Window::setShadeColor(const QColor& color)
{
    m_grid->themeManager()->setShadeColor(color);
}

void Window::autoWidthStateChanged(int state)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    view->tableOptions().setColumnAutoWidth(state == Qt::Checked);
}

void Window::fastScrollChanged(int state)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    view->options().setFastScrollEffect(state == Qt::Checked);
}

void Window::dottedLineChanged(int state)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    QPen pen = view->options().gridLinePen();
    pen.setStyle(state == Qt::Checked ? Qt::DotLine : Qt::SolidLine);
    view->options().setGridLinePen(pen);
}

void Window::selectGroupSummaryPlace(int index)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    switch (index)
    {
    case 0:
        view->options().setGroupSummaryPlace(GridViewOptions::SummaryHidden);
        break;
    case 1:
        view->options().setGroupSummaryPlace(GridViewOptions::SummaryRowFooter);
        break;
    case 2:
        view->options().setGroupSummaryPlace(GridViewOptions::SummaryRow);
        break;
    default:
        view->options().setGroupSummaryPlace(GridViewOptions::SummaryRowPlus);
    }
}

void Window::selectGridLineStyles(int index)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    switch (index)
    {
    case 0:
        view->options().setGridLines(Qtitan::LinesNone);
        break;
    case 1:
        view->options().setGridLines(Qtitan::LinesBoth);
        break;
    case 2:
        view->options().setGridLines(Qtitan::LinesBoth2D);
        break;
    case 3:
        view->options().setGridLines(Qtitan::LinesHorizontal);
        break;
    case 4:
        view->options().setGridLines(Qtitan::LinesHorizontal2D);
        break;
    case 5:
        view->options().setGridLines(Qtitan::LinesVertical);
        break;
    case 6:
        view->options().setGridLines(Qtitan::LinesVertical2D);
        break;
    default:
        view->options().setGridLines(Qtitan::LinesBoth);
    }
 }

void Window::zoomEnabledChanged(int state)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    view->options().setZoomEnabled(state == Qt::Checked);
}

void Window::zoomIndicatorChanged(int state)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    view->options().setZoomIndicatorActive(state == Qt::Checked);
}

void Window::zoomValueChanged(int value)
{
    double factor = qCeil((double)value / 25) * 25;
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    view->options().setZoomFactor(factor / 100);
}

void Window::cellButtonAutoRaiseEnabled(int state)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    view->options().setCellButtonAutoRaise(state == Qt::Checked);
}

void Window::frozenRowsEnabled(int state)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    view->tableOptions().setRowFrozenButtonVisible(state == Qt::Checked);
    view->tableOptions().setFrozenPlaceQuickSelection(state == Qt::Checked);
}

void Window::transparentBackgroundEnabled(int state)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    view->options().setTransparentBackground(state == Qt::Checked);
    view->options().setAlternatingRowColors(!view->options().alternatingRowColors());
}

void Window::rowSizingEnabled(int state)
{
    Qtitan::GridTableView* view = m_grid->view<Qtitan::GridTableView>();
    view->tableOptions().setRowSizingEnabled(state == Qt::Checked);
}

void Window::contextMenu(ContextMenuEventArgs* args)
{
    args->contextMenu()->addAction(tr("Print Preview"), this, SLOT(printPreview()));
    args->contextMenu()->addSeparator();
    args->contextMenu()->addAction(tr("Developer Machines on the Web"), this, SLOT(showCompanyWebSite()));
}

void Window::cellButtonClicked(CellButtonClickEventArgs* args)
{
    QMessageBox::information(this, tr("Cell button clicked"),
        tr("Clicked: Button - %1, Column Title - %2, RowIndex - %3").arg(args->buttonIndex()).arg(args->column()->caption()).arg(args->row().rowIndex()));
}

void Window::summaryFooterTextChanging(SummaryTextEventArgs* args)
{
    Q_UNUSED(args);
#if 1
    args->setTextColor(Qt::white);
    args->setBackgroundColor(QColor(Qt::red).darker());
#endif
}

void Window::summaryGroupTextChanging(SummaryGroupTextEventArgs* args)
{
    Q_UNUSED(args);
#if 1
    args->setTextColor(Qt::black);
    args->setBackgroundColor(QColor(Qt::green).lighter());
    args->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
#endif
}

void Window::printPreview()
{
    m_grid->view<Qtitan::GridTableView>()->printPreview();
}

/* SummaryDemoModel */
SummaryDemoModel::SummaryDemoModel(QObject *parent)
: QAbstractItemModel(parent)
{
    m_values.resize(100);
    int y = 2000;
    int m = 1;
    int d = 1;
    for (int i = 0; i < m_values.size(); ++i)
    {
        m_values[i].v0 = true;
        m_values[i].v1 = i;
        m_values[i].v2 = QStringLiteral("String-1 = %1").arg(i);
        m_values[i].v3 = QStringLiteral("String-2 = %1").arg(i);
        if (d > 28)
        {
            d = 1;
            m++;
            if (m > 12)
            {
                m = 1;
                y++;
            }
        }
        m_values[i].v4 = QDate(y, m, d);
        if (!(i % 10))
            d++;
    }
}

SummaryDemoModel::~SummaryDemoModel()
{
}

QVariant SummaryDemoModel::headerData(int section, Qt::Orientation orientation,
                                      int role) const
{
    Q_UNUSED(orientation);
    Q_UNUSED(role);
    switch (section)
    {
    case 0:
        {
            return QStringLiteral("Boolean");
        }
        break;
    case 1:
        {
            return QStringLiteral("Integer");
        }
        break;
    case 2:
        {
            return QStringLiteral("String");
        }
        break;
    case 3:
        {
            return QStringLiteral("String");
        }
        break;
    case 4:
        {
            return QStringLiteral("Date");
        }
        break;
    }
    return QVariant();
}

QModelIndex SummaryDemoModel::parent(const QModelIndex & /*child*/) const
{
    return QModelIndex();
}

bool SummaryDemoModel::hasChildren(const QModelIndex &parent) const
{
    if (parent.model() == this || !parent.isValid())
    {
        return rowCount(parent) > 0 && columnCount(parent) > 0;
    }
    return false;
}

int SummaryDemoModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    return m_values.size();
}

int SummaryDemoModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    return 5;
}

QModelIndex SummaryDemoModel::index(int row, int column, const QModelIndex &parent) const
{
    if (parent.isValid())
        return QModelIndex();

    if (row < 0 || row >= rowCount(parent))
        return QModelIndex();

    if (column < 0 || column >= columnCount(parent))
        return QModelIndex();

    return createIndex(row, column, (void*)NULL);
}

QVariant SummaryDemoModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (index.row() < 0 || index.row() >= rowCount(index.parent()))
        return QVariant();

    if (index.column() < 0 || index.column() >= columnCount(index.parent()))
        return QVariant();

    if (role == Qt::DisplayRole || role == Qt::EditRole)
    {
        switch (index.column())
        {
        case 0:
            {
                return m_values[index.row()].v0;
            }
            break;
        case 1:
            {
                return m_values[index.row()].v1;
            }
            break;
        case 2:
            {
                return m_values[index.row()].v2;
            }
            break;
        case 3:
            {
                return m_values[index.row()].v3;
            }
            break;
        case 4:
            {
                return m_values[index.row()].v4;
            }
            break;
        }
    }
    else if (role == Qt::CheckStateRole)
    {
        switch (index.column())
        {
        case 0:
            {
                return m_values[index.row()].v0;
            }
            break;
        }
    }
    return QVariant();
}

bool SummaryDemoModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (!index.isValid())
        return false;

    if (index.row() < 0 || index.row() >= rowCount(index.parent()))
        return false;

    if (index.column() < 0 || index.column() >= columnCount(index.parent()))
        return false;

    if (role != Qt::EditRole)
        return false;

    switch (index.column())
    {
    case 0:
        {
            m_values[index.row()].v0 = value.toBool();
        }
        break;
    case 1:
        {
            m_values[index.row()].v1 = value.toInt();
        }
        break;
    case 2:
        {
            m_values[index.row()].v2 = value.toString();
        }
        break;
    case 3:
        {
            m_values[index.row()].v3 = value.toString();
        }
        break;
    case 4:
        {
            m_values[index.row()].v4 = value.toDate();
        }
        break;
    }

    emit dataChanged(index, index);
    return true;
}

Qt::ItemFlags SummaryDemoModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return Qt::ItemFlags();

    //if (index.column() == 0)
    //{
    //    return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsUserCheckable;
    //}
    //else if (index.column() == 4)
    //{
    //    return Qt::ItemIsEnabled | Qt::ItemIsEditable;
    //}
    return Qt::ItemIsEnabled | Qt::ItemIsEditable;
}