/***************************************************************************
 *   Copyright (C) 2008 by S. MANKOWSKI / G. DE BURE support@mankowski.fr  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>  *
 ***************************************************************************/
/** @file
 * A table widget with more features.
 *
 * @author Stephane MANKOWSKI / Guillaume DE BURE
 */
#include "skgtablewidget.h"
#include "skgtraces.h"

#include <QKeyEvent>
#include <QApplication>
#include <QClipboard>
#include <QScrollBar>

SKGTableWidget::SKGTableWidget(QWidget* parent)
    : QTableWidget(parent), stickH(false), stickV(false)
{
    this->installEventFilter(this);
    connect(horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onActionTriggered()));
    connect(verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(onActionTriggered()));
    connect(horizontalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(onRangeChanged()));
    connect(verticalScrollBar(), SIGNAL(rangeChanged(int,int)), this, SLOT(onRangeChanged()));
}

SKGTableWidget::~SKGTableWidget()
{
}

void SKGTableWidget::onRangeChanged()
{
    QScrollBar* scroll = qobject_cast<QScrollBar*>(sender());
    if ((stickH && scroll == horizontalScrollBar()) || (stickV && scroll == verticalScrollBar())) {
        scroll->setValue(scroll->maximum());
    }
}

void SKGTableWidget::onActionTriggered()
{
    QScrollBar* scroll = qobject_cast<QScrollBar*>(sender());
    if (scroll) {
        if (scroll == horizontalScrollBar()) stickH = (scroll->value() == scroll->maximum());
        if (scroll == verticalScrollBar()) stickV = (scroll->value() == scroll->maximum());
    }
}

void SKGTableWidget::setStickHorizontal(bool iStick)
{
    stickH = iStick;
}

bool SKGTableWidget::stickHorizontal() const
{
    return stickH;
}

void SKGTableWidget::setStickVertical(bool iStick)
{
    stickV = iStick;
}
bool SKGTableWidget::stickVertical() const
{
    return stickV;
}

bool SKGTableWidget::eventFilter(QObject* object, QEvent* event)
{
    if (object == this) {
        QKeyEvent* kevent = dynamic_cast<QKeyEvent*>(event);
        if (kevent) {
            if (kevent->key() == Qt::Key_Delete && state() != QAbstractItemView::EditingState) {
                QList<QTableWidgetItem*> selectedItems = this->selectedItems();
                if (selectedItems.count() > 0) {
                    Q_EMIT removeSelectedItems();
                    if (event) event->accept();
                    return true; //stop the process
                }
            } else if (kevent->matches(QKeySequence::Copy) && this->state() != QAbstractItemView::EditingState) {
                copy();
                if (event) event->accept();
                return true; //stop the process
            }
        }
    }

    return false;
}

void SKGTableWidget::copy()
{
    QItemSelectionModel* selection = selectionModel();
    if (selection) {
        QModelIndexList indexes = selection->selectedIndexes();

        if (indexes.size() < 1) return;

        qSort(indexes.begin(), indexes.end());

        // You need a pair of indexes to find the row changes
        QModelIndex previous = indexes.first();
        indexes.removeFirst();
        QString header_text;
        bool header_done = false;
        QString selected_text;
        foreach(const QModelIndex & current, indexes) {
            selected_text.append(model()->data(previous).toString());
            if (!header_done) header_text.append(model()->headerData(previous.column(), Qt::Horizontal).toString());
            if (current.row() != previous.row()) {
                selected_text.append(QLatin1Char('\n'));
                header_done = true;
            } else {
                selected_text.append(QLatin1Char(';'));
                if (!header_done) header_text.append(QLatin1Char(';'));
            }
            previous = current;
        }

        // add last element
        selected_text.append(model()->data(previous).toString());
        selected_text.append(QLatin1Char('\n'));
        QApplication::clipboard()->setText(header_text + '\n' + selected_text);
    }
}

#include "skgtablewidget.moc"
