975 lines
28 KiB
C++
975 lines
28 KiB
C++
#include "AbstractTableView.h"
|
|
#include "Configuration.h"
|
|
|
|
AbstractTableView::AbstractTableView(QWidget *parent) : QAbstractScrollArea(parent)
|
|
{
|
|
// Class variable initialization
|
|
mTableOffset = 0;
|
|
mPrevTableOffset = mTableOffset + 1;
|
|
Header_t data;
|
|
data.isVisible=true;
|
|
data.height=20;
|
|
data.activeButtonIndex=-1;
|
|
mHeader = data;
|
|
|
|
QFont font("Monospace", 8);
|
|
//QFont font("Terminal", 7);
|
|
//font.setBold(true); //bold
|
|
|
|
font.setFixedPitch(true);
|
|
font.setStyleHint(QFont::Monospace);
|
|
this->setFont(font);
|
|
|
|
backgroundColor=ConfigColor("AbstractTableViewBackgroundColor");
|
|
textColor=ConfigColor("AbstractTableViewTextColor");
|
|
separatorColor=ConfigColor("AbstractTableViewSeparatorColor");
|
|
headerTextColor=ConfigColor("AbstractTableViewHeaderTextColor");
|
|
selectionColor=ConfigColor("AbstractTableViewSelectionColor");
|
|
|
|
int wRowsHeight = QFontMetrics(this->font()).height();
|
|
wRowsHeight = (wRowsHeight * 105) / 100;
|
|
wRowsHeight = (wRowsHeight % 2) == 0 ? wRowsHeight : wRowsHeight + 1;
|
|
mRowHeight = wRowsHeight;
|
|
|
|
mRowCount = 0;
|
|
|
|
mHeaderButtonSytle.setStyleSheet(" QPushButton {\n background-color: rgb(192, 192, 192);\n border-style: outset;\n border-width: 2px;\n border-color: rgb(128, 128, 128);\n }\n QPushButton:pressed {\n background-color: rgb(192, 192, 192);\n border-style: inset;\n }");
|
|
|
|
mNbrOfLineToPrint = 0;
|
|
|
|
memset(&mColResizeData, 0, sizeof(mColResizeData));
|
|
|
|
mGuiState = AbstractTableView::NoState;
|
|
|
|
mShouldReload = true;
|
|
|
|
// ScrollBar Init
|
|
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
|
memset(&mScrollBarAttributes, 0, sizeof(mScrollBarAttributes));
|
|
|
|
setMouseTracking(true);
|
|
|
|
// Signals/Slots Connections
|
|
connect(verticalScrollBar(), SIGNAL(actionTriggered(int)), this, SLOT(vertSliderActionSlot(int)));
|
|
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(colorsUpdatedSlot()));
|
|
}
|
|
|
|
void AbstractTableView::colorsUpdatedSlot()
|
|
{
|
|
colorsUpdated();
|
|
}
|
|
|
|
void AbstractTableView::colorsUpdated()
|
|
{
|
|
backgroundColor=ConfigColor("AbstractTableViewBackgroundColor");
|
|
textColor=ConfigColor("AbstractTableViewTextColor");
|
|
separatorColor=ConfigColor("AbstractTableViewSeparatorColor");
|
|
headerTextColor=ConfigColor("AbstractTableViewHeaderTextColor");
|
|
selectionColor=ConfigColor("AbstractTableViewSelectionColor");
|
|
}
|
|
|
|
/************************************************************************************
|
|
Painting Stuff
|
|
************************************************************************************/
|
|
/**
|
|
* @brief This method has been reimplemented. It paints the whole table.
|
|
*
|
|
* @param[in] event Paint event
|
|
*
|
|
* @return Nothing.
|
|
*/
|
|
void AbstractTableView::paintEvent(QPaintEvent* event)
|
|
{
|
|
Q_UNUSED(event);
|
|
QPainter wPainter(this->viewport());
|
|
int wViewableRowsCount = getViewableRowsCount();
|
|
|
|
int x = 0;
|
|
int y = 0;
|
|
|
|
// Reload data if needed
|
|
if(mPrevTableOffset != mTableOffset || mShouldReload == true)
|
|
{
|
|
prepareData();
|
|
mPrevTableOffset = mTableOffset;
|
|
mShouldReload = false;
|
|
}
|
|
|
|
// Paints background
|
|
wPainter.fillRect(wPainter.viewport(), QBrush(backgroundColor));
|
|
|
|
// Paints header
|
|
if(mHeader.isVisible == true)
|
|
{
|
|
for(int i = 0; i < getColumnCount(); i++)
|
|
{
|
|
QStyleOptionButton wOpt;
|
|
if((mColumnList[i].header.isPressed == true) && (mColumnList[i].header.isMouseOver == true))
|
|
wOpt.state = QStyle::State_Sunken;
|
|
else
|
|
wOpt.state = QStyle::State_Enabled;
|
|
|
|
wOpt.rect = QRect(x, y, getColumnWidth(i), getHeaderHeight());
|
|
|
|
mHeaderButtonSytle.style()->drawControl(QStyle::CE_PushButton, &wOpt, &wPainter,&mHeaderButtonSytle);
|
|
|
|
wPainter.setPen(headerTextColor);
|
|
wPainter.drawText(QRect(x + 4, y, getColumnWidth(i) - 8, getHeaderHeight()), Qt::AlignVCenter | Qt::AlignLeft, mColumnList[i].title);
|
|
|
|
x += getColumnWidth(i);
|
|
}
|
|
x = 0;
|
|
y = getHeaderHeight();
|
|
}
|
|
|
|
// Iterate over all columns and cells
|
|
for(int j = 0; j < getColumnCount(); j++)
|
|
{
|
|
for(int i = 0; i < wViewableRowsCount; i++)
|
|
{
|
|
// Paints cell contents
|
|
if(i < mNbrOfLineToPrint)
|
|
{
|
|
QString wStr = paintContent(&wPainter, mTableOffset, i, j, x, y, getColumnWidth(j), getRowHeight());
|
|
if(wStr.length())
|
|
{
|
|
wPainter.setPen(textColor);
|
|
wPainter.drawText(QRect(x + 4, y, getColumnWidth(j) - 4, getRowHeight()), Qt::AlignVCenter | Qt::AlignLeft, wStr);
|
|
}
|
|
}
|
|
|
|
// Paints cell right borders
|
|
wPainter.setPen(separatorColor);
|
|
wPainter.drawLine(x + getColumnWidth(j) - 1, y, x + getColumnWidth(j) - 1, y + getRowHeight() - 1);
|
|
|
|
// Update y for the next iteration
|
|
y += getRowHeight();
|
|
}
|
|
|
|
y = getHeaderHeight();
|
|
x += getColumnWidth(j);
|
|
}
|
|
emit repainted();
|
|
}
|
|
|
|
|
|
/************************************************************************************
|
|
Mouse Management
|
|
************************************************************************************/
|
|
/**
|
|
* @brief This method has been reimplemented. It manages the following actions:
|
|
* - Column resizing
|
|
* - Header button
|
|
*
|
|
* @param[in] event Mouse event
|
|
*
|
|
* @return Nothing.
|
|
*/
|
|
void AbstractTableView::mouseMoveEvent(QMouseEvent* event)
|
|
{
|
|
// qDebug() << "mouseMoveEvent";
|
|
|
|
switch (mGuiState)
|
|
{
|
|
case AbstractTableView::NoState:
|
|
{
|
|
//qDebug() << "State = NoState";
|
|
|
|
int wColIndex = getColumnIndexFromX(event->x());
|
|
int wStartPos = getColumnPosition(wColIndex); // Position X of the start of column
|
|
int wEndPos = getColumnPosition(wColIndex) + getColumnWidth(wColIndex); // Position X of the end of column
|
|
|
|
if(event->buttons() == Qt::NoButton)
|
|
{
|
|
bool wHandle = true;
|
|
bool wHasCursor;
|
|
|
|
wHasCursor = cursor().shape() == Qt::SplitHCursor ? true : false;
|
|
|
|
if(((wColIndex != 0) && (event->x() >= wStartPos) && (event->x() <= (wStartPos + 2))) || ((wColIndex != (getColumnCount() - 1)) && (event->x() <= wEndPos) && (event->x() >= (wEndPos - 2))))
|
|
{
|
|
wHandle = true;
|
|
}
|
|
else
|
|
{
|
|
wHandle = false;
|
|
}
|
|
|
|
if((wHandle == true) && (wHasCursor == false))
|
|
{
|
|
setCursor(Qt::SplitHCursor);
|
|
mColResizeData.splitHandle = true;
|
|
mGuiState = AbstractTableView::ReadyToResize;
|
|
}
|
|
if ((wHandle == false) && (wHasCursor == true))
|
|
{
|
|
unsetCursor();
|
|
mColResizeData.splitHandle = false;
|
|
mGuiState = AbstractTableView::NoState;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
QWidget::mouseMoveEvent(event);
|
|
}
|
|
break;
|
|
}
|
|
case AbstractTableView::ReadyToResize:
|
|
{
|
|
//qDebug() << "State = ReadyToResize";
|
|
|
|
int wColIndex = getColumnIndexFromX(event->x());
|
|
int wStartPos = getColumnPosition(wColIndex); // Position X of the start of column
|
|
int wEndPos = getColumnPosition(wColIndex) + getColumnWidth(wColIndex); // Position X of the end of column
|
|
|
|
if(event->buttons() == Qt::NoButton)
|
|
{
|
|
bool wHandle = true;
|
|
|
|
if(((wColIndex != 0) && (event->x() >= wStartPos) && (event->x() <= (wStartPos + 2))) || ((wColIndex != (getColumnCount() - 1)) && (event->x() <= wEndPos) && (event->x() >= (wEndPos - 2))))
|
|
{
|
|
wHandle = true;
|
|
}
|
|
else
|
|
{
|
|
wHandle = false;
|
|
}
|
|
|
|
if ((wHandle == false) && (mGuiState == AbstractTableView::ReadyToResize))
|
|
{
|
|
unsetCursor();
|
|
mColResizeData.splitHandle = false;
|
|
mGuiState = AbstractTableView::NoState;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case AbstractTableView::ResizeColumnState:
|
|
{
|
|
//qDebug() << "State = ResizeColumnState";
|
|
|
|
int delta = event->x() - mColResizeData.lastPosX;
|
|
|
|
int wNewSize = ((getColumnWidth(mColResizeData.index) + delta) >= 20) ? (getColumnWidth(mColResizeData.index) + delta) : (20);
|
|
|
|
setColumnWidth(mColResizeData.index, wNewSize);
|
|
|
|
mColResizeData.lastPosX = event->x();
|
|
|
|
repaint();
|
|
|
|
break;
|
|
}
|
|
case AbstractTableView::HeaderButtonPressed:
|
|
{
|
|
//qDebug() << "State = HeaderButtonPressed";
|
|
|
|
int wColIndex = getColumnIndexFromX(event->x());
|
|
|
|
if((wColIndex == mHeader.activeButtonIndex) && (event->y() <= getHeaderHeight()) && (event->y() >= 0))
|
|
{
|
|
mColumnList[mHeader.activeButtonIndex].header.isMouseOver = true;
|
|
}
|
|
else
|
|
{
|
|
mColumnList[mHeader.activeButtonIndex].header.isMouseOver = false;
|
|
}
|
|
|
|
repaint();
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief This method has been reimplemented. It manages the following actions:
|
|
* - Column resizing
|
|
* - Header button
|
|
*
|
|
* @param[in] event Mouse event
|
|
*
|
|
* @return Nothing.
|
|
*/
|
|
void AbstractTableView::mousePressEvent(QMouseEvent* event)
|
|
{
|
|
if(((event->buttons() & Qt::LeftButton) != 0) && ((event->buttons() & Qt::RightButton) == 0))
|
|
{
|
|
if(mColResizeData.splitHandle == true)
|
|
{
|
|
int wColIndex = getColumnIndexFromX(event->x());
|
|
int wStartPos = getColumnPosition(wColIndex); // Position X of the start of column
|
|
|
|
mGuiState = AbstractTableView::ResizeColumnState;
|
|
|
|
if(event->x() <= (wStartPos + 2))
|
|
{
|
|
mColResizeData.index = wColIndex - 1;
|
|
}
|
|
else
|
|
{
|
|
mColResizeData.index = wColIndex;
|
|
}
|
|
|
|
mColResizeData.lastPosX = event->x();
|
|
}
|
|
else if((mHeader.isVisible == true) && (event->y() <= getHeaderHeight()) && (event->y() >= 0))
|
|
{
|
|
int wColIndex = getColumnIndexFromX(event->x());
|
|
|
|
//qDebug() << "Button " << wColIndex << "has been pressed.";
|
|
emit headerButtonPressed(wColIndex);
|
|
|
|
mColumnList[wColIndex].header.isPressed = true;
|
|
mColumnList[wColIndex].header.isMouseOver = true;
|
|
|
|
mHeader.activeButtonIndex = wColIndex;
|
|
|
|
mGuiState = AbstractTableView::HeaderButtonPressed;
|
|
|
|
repaint();
|
|
}
|
|
}
|
|
|
|
//QWidget::mousePressEvent(event);
|
|
}
|
|
|
|
/**
|
|
* @brief This method has been reimplemented. It manages the following actions:
|
|
* - Column resizing
|
|
* - Header button
|
|
*
|
|
* @param[in] event Mouse event
|
|
*
|
|
* @return Nothing.
|
|
*/
|
|
void AbstractTableView::mouseReleaseEvent(QMouseEvent* event)
|
|
{
|
|
if((event->buttons() & Qt::LeftButton) == 0)
|
|
{
|
|
if(mGuiState == AbstractTableView::ResizeColumnState)
|
|
{
|
|
mGuiState = AbstractTableView::NoState;
|
|
}
|
|
else if(mGuiState == AbstractTableView::HeaderButtonPressed)
|
|
{
|
|
if(mColumnList[mHeader.activeButtonIndex].header.isMouseOver == true)
|
|
{
|
|
//qDebug() << "Button " << mHeader.activeButtonIndex << "has been released.";
|
|
emit headerButtonReleased(mHeader.activeButtonIndex);
|
|
}
|
|
mGuiState = AbstractTableView::NoState;
|
|
}
|
|
else
|
|
{
|
|
QWidget::mouseReleaseEvent(event);
|
|
}
|
|
|
|
// Release all buttons
|
|
for(int i = 0; i < getColumnCount(); i++)
|
|
{
|
|
mColumnList[i].header.isPressed = false;
|
|
}
|
|
|
|
repaint();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief This method has been reimplemented. It manages the following actions:
|
|
* - Mouse wheel
|
|
*
|
|
* @param[in] event Wheel event
|
|
*
|
|
* @return Nothing.
|
|
*/
|
|
void AbstractTableView::wheelEvent(QWheelEvent* event)
|
|
{
|
|
//qDebug() << "wheelEvent";
|
|
|
|
if(event->delta() > 0)
|
|
{
|
|
verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepSub);
|
|
verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepSub);
|
|
}
|
|
else
|
|
{
|
|
verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepAdd);
|
|
verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepAdd);
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief This method has been reimplemented. It repaints the table when the height changes.
|
|
*
|
|
* @param[in] event Resize event
|
|
*
|
|
* @return Nothing.
|
|
*/
|
|
void AbstractTableView::resizeEvent(QResizeEvent* event)
|
|
{
|
|
if(event->size().height() != event->oldSize().height())
|
|
{
|
|
mShouldReload = true;
|
|
}
|
|
|
|
QWidget::resizeEvent(event);
|
|
}
|
|
|
|
|
|
/************************************************************************************
|
|
Keyboard Management
|
|
************************************************************************************/
|
|
/**
|
|
* @brief This method has been reimplemented. It manages the following actions:
|
|
* - Pressed keys
|
|
*
|
|
* @param[in] event Key event
|
|
*
|
|
* @return Nothing.
|
|
*/
|
|
void AbstractTableView::keyPressEvent(QKeyEvent* event)
|
|
{
|
|
int wKey = event->key();
|
|
|
|
if(wKey == Qt::Key_Up)
|
|
{
|
|
verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepSub);
|
|
}
|
|
else if(wKey == Qt::Key_Down)
|
|
{
|
|
verticalScrollBar()->triggerAction(QAbstractSlider::SliderSingleStepAdd);
|
|
}
|
|
else if(wKey == Qt::Key_PageUp)
|
|
{
|
|
verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepSub);
|
|
}
|
|
else if(wKey == Qt::Key_PageDown)
|
|
{
|
|
verticalScrollBar()->triggerAction(QAbstractSlider::SliderPageStepAdd);
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************************
|
|
ScrollBar Management
|
|
***********************************************************************************/
|
|
/**
|
|
* @brief This method is the slot connected to the actionTriggered signal of the vertical scrollbar.
|
|
*
|
|
* @param[in] action Slider action type
|
|
*
|
|
* @return Nothing.
|
|
*/
|
|
void AbstractTableView::vertSliderActionSlot(int action)
|
|
{
|
|
int_t wDelta;
|
|
int wSliderPos = verticalScrollBar()->sliderPosition();
|
|
int wNewScrollBarValue;
|
|
|
|
// Bounding
|
|
wSliderPos = wSliderPos > verticalScrollBar()->maximum() ? verticalScrollBar()->maximum() : wSliderPos;
|
|
wSliderPos = wSliderPos < 0 ? 0 : wSliderPos;
|
|
|
|
// Determine the delta
|
|
switch(action)
|
|
{
|
|
case QAbstractSlider::SliderNoAction:
|
|
break;
|
|
case QAbstractSlider::SliderSingleStepAdd:
|
|
wDelta = 1;
|
|
break;
|
|
case QAbstractSlider::SliderSingleStepSub:
|
|
wDelta = -1;
|
|
break;
|
|
case QAbstractSlider::SliderPageStepAdd:
|
|
wDelta = 30;
|
|
break;
|
|
case QAbstractSlider::SliderPageStepSub:
|
|
wDelta = -30;
|
|
break;
|
|
case QAbstractSlider::SliderToMinimum:
|
|
case QAbstractSlider::SliderToMaximum:
|
|
case QAbstractSlider::SliderMove:
|
|
#ifdef _WIN64
|
|
wDelta = scaleFromScrollBarRangeToUint64(wSliderPos) - mTableOffset;
|
|
#else
|
|
wDelta = wSliderPos - mTableOffset;
|
|
#endif
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Call the hook (Usefull for disassembly)
|
|
mTableOffset = sliderMovedHook(action, mTableOffset, wDelta);
|
|
emit tableOffsetChanged(mTableOffset);
|
|
|
|
// Scale the new table offset to the 32bits scrollbar range
|
|
#ifdef _WIN64
|
|
wNewScrollBarValue = scaleFromUint64ToScrollBarRange(mTableOffset);
|
|
#else
|
|
wNewScrollBarValue = mTableOffset;
|
|
#endif
|
|
|
|
emit repainted();
|
|
|
|
// Update scrollbar attributes
|
|
verticalScrollBar()->setValue(wNewScrollBarValue);
|
|
verticalScrollBar()->setSliderPosition(wNewScrollBarValue);
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief This virtual method is called at the end of the vertSliderActionSlot(...) method.
|
|
* It allows changing the table offset according to the action type, the old table offset
|
|
* and delta between the old and the new table offset.
|
|
*
|
|
* @param[in] type Type of action (Refer to the QAbstractSlider::SliderAction enum)
|
|
* @param[in] value Old table offset
|
|
* @param[in] delta Scrollbar value delta compared to the previous state
|
|
*
|
|
* @return Return the value of the new table offset.
|
|
*/
|
|
int_t AbstractTableView::sliderMovedHook(int type, int_t value, int_t delta)
|
|
{
|
|
Q_UNUSED(type);
|
|
int_t wValue = value + delta;
|
|
int_t wMax = getRowCount() - getViewableRowsCount() + 1;
|
|
|
|
// Bounding
|
|
wValue = wValue > wMax ? wMax : wValue;
|
|
wValue = wValue < 0 ? 0 : wValue;
|
|
|
|
return wValue;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief This method scale the given 64bits integer to the scrollbar range (32bits).
|
|
*
|
|
* @param[in] value 64bits integer to rescale
|
|
*
|
|
* @return 32bits integer.
|
|
*/
|
|
#ifdef _WIN64
|
|
int AbstractTableView::scaleFromUint64ToScrollBarRange(int_t value)
|
|
{
|
|
if(mScrollBarAttributes.is64 == true)
|
|
{
|
|
int_t wValue = ((int_t)value) >> mScrollBarAttributes.rightShiftCount;
|
|
int_t wValueMax = ((int_t)getRowCount() - 1) >> mScrollBarAttributes.rightShiftCount;
|
|
|
|
if(value == ((int_t)getRowCount() - 1))
|
|
return (int)(verticalScrollBar()->maximum());
|
|
else
|
|
return (int)((int_t)((int_t)verticalScrollBar()->maximum() * (int_t)wValue) / (int_t)wValueMax);
|
|
}
|
|
else
|
|
{
|
|
return (int)value;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/**
|
|
* @brief This method scale the given 32bits integer to the table range (64bits).
|
|
*
|
|
* @param[in] value 32bits integer to rescale
|
|
*
|
|
* @return 64bits integer.
|
|
*/
|
|
#ifdef _WIN64
|
|
int_t AbstractTableView::scaleFromScrollBarRangeToUint64(int value)
|
|
{
|
|
if(mScrollBarAttributes.is64 == true)
|
|
{
|
|
int_t wValueMax = ((int_t)getRowCount() - 1) >> mScrollBarAttributes.rightShiftCount;
|
|
|
|
if(value == (int)0x7FFFFFFF)
|
|
return (int_t)(getRowCount() - 1);
|
|
else
|
|
return (int_t)(((int_t)((int_t)wValueMax * (int_t)value) / (int_t)0x7FFFFFFF) << mScrollBarAttributes.rightShiftCount);
|
|
}
|
|
else
|
|
{
|
|
return (int_t)value;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/**
|
|
* @brief This method updates the scrollbar range and pre-computes some attributes for the 32<->64bits conversion methods.
|
|
*
|
|
* @param[in] range New table range (size)
|
|
*
|
|
* @return 32bits integer.
|
|
*/
|
|
void AbstractTableView::updateScrollBarRange(int_t range)
|
|
{
|
|
int_t wMax = range - getViewableRowsCount() + 1;
|
|
|
|
if(wMax > 0)
|
|
{
|
|
#ifdef _WIN64
|
|
if((uint_t)wMax < (uint_t)0x0000000080000000)
|
|
{
|
|
mScrollBarAttributes.is64 = false;
|
|
mScrollBarAttributes.rightShiftCount = 0;
|
|
verticalScrollBar()->setRange(0, wMax);
|
|
}
|
|
else
|
|
{
|
|
uint_t wMask = 0x8000000000000000;
|
|
int wLeadingZeroCount;
|
|
|
|
// Count leading zeros
|
|
for(wLeadingZeroCount = 0; wLeadingZeroCount < 64; wLeadingZeroCount++)
|
|
{
|
|
if((uint_t)wMax < wMask)
|
|
{
|
|
wMask = wMask >> 1;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
mScrollBarAttributes.is64 = true;
|
|
mScrollBarAttributes.rightShiftCount = 32 - wLeadingZeroCount;
|
|
verticalScrollBar()->setRange(0, 0x7FFFFFFF);
|
|
}
|
|
#else
|
|
verticalScrollBar()->setRange(0, wMax);
|
|
#endif
|
|
}
|
|
}
|
|
|
|
|
|
/************************************************************************************
|
|
Coordinates Utils
|
|
************************************************************************************/
|
|
/**
|
|
* @brief Returns the index offset (relative to the table offset) corresponding to the given y coordinate.
|
|
*
|
|
* @param[in] y Pixel offset starting from the top of the table (without the header)
|
|
*
|
|
* @return row index offset.
|
|
*/
|
|
int AbstractTableView::getIndexOffsetFromY(int y)
|
|
{
|
|
return (y / getRowHeight());
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Returns the index of the column corresponding to the given x coordinate.
|
|
*
|
|
* @param[in] x Pixel offset starting from the left of the table
|
|
*
|
|
* @return Column index.
|
|
*/
|
|
int AbstractTableView::getColumnIndexFromX(int x)
|
|
{
|
|
int wX = 0;
|
|
int wColIndex = 0;
|
|
|
|
while(wColIndex < getColumnCount())
|
|
{
|
|
wX += getColumnWidth(wColIndex);
|
|
|
|
if(x <= wX)
|
|
{
|
|
return wColIndex;
|
|
}
|
|
else if(wColIndex < getColumnCount())
|
|
{
|
|
wColIndex++;
|
|
}
|
|
}
|
|
return getColumnCount() - 1;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Returns the x coordinate of the beginning of the column at index index.
|
|
*
|
|
* @param[in] index Column index.
|
|
*
|
|
* @return X coordinate of the column index.
|
|
*/
|
|
int AbstractTableView::getColumnPosition(int index)
|
|
{
|
|
int posX = 0;
|
|
|
|
if((index >= 0) && (index < getColumnCount()))
|
|
{
|
|
for(int i = 0; i <= (index - 1); i++)
|
|
{
|
|
posX += getColumnWidth(i);
|
|
}
|
|
|
|
return posX;
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Substracts the header heigth from the given y.
|
|
*
|
|
* @param[in] y y coordinate
|
|
*
|
|
* @return y - getHeaderHeigth().
|
|
*/
|
|
int AbstractTableView::transY(int y)
|
|
{
|
|
return y - getHeaderHeight();
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Returns the number of viewable rows in the current window (Partially viewable rows are aslo counted).
|
|
*
|
|
* @return Number of viewable rows.
|
|
*/
|
|
int AbstractTableView::getViewableRowsCount()
|
|
{
|
|
int wTableHeight = this->height() - getHeaderHeight();
|
|
int wCount = wTableHeight / getRowHeight();
|
|
|
|
wCount += (wTableHeight % getRowHeight()) > 0 ? 1 : 0;
|
|
|
|
emit viewableRows(wCount);
|
|
return wCount;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief This virtual method returns the number of remaining lines to print.
|
|
*
|
|
* @return Number of remaining lines to print.
|
|
*/
|
|
int AbstractTableView::getLineToPrintcount()
|
|
{
|
|
int wViewableRowsCount = getViewableRowsCount();
|
|
int_t wRemainingRowsCount = getRowCount() - mTableOffset;
|
|
int wCount = (int_t)wRemainingRowsCount > (int_t)wViewableRowsCount ? (int)wViewableRowsCount : (int)wRemainingRowsCount;
|
|
return wCount;
|
|
}
|
|
|
|
|
|
/************************************************************************************
|
|
New Columns/New Size
|
|
************************************************************************************/
|
|
/**
|
|
* @brief This mehtod adds a new column to the table.
|
|
*
|
|
* @param[in] width Width of the column in pixel
|
|
* @param[in] isClickable Boolean that tells whether the header is clickable or not
|
|
*
|
|
* @return Nothing.
|
|
*/
|
|
void AbstractTableView::addColumnAt(int width, QString title, bool isClickable)
|
|
{
|
|
HeaderButton_t wHeaderButton;
|
|
Column_t wColumn;
|
|
|
|
wHeaderButton.isPressed = false;
|
|
wHeaderButton.isClickable = isClickable;
|
|
wHeaderButton.isMouseOver = false;
|
|
|
|
wColumn.header = wHeaderButton;
|
|
wColumn.width = width;
|
|
|
|
wColumn.title = title;
|
|
|
|
mColumnList.append(wColumn);
|
|
}
|
|
|
|
void AbstractTableView::setRowCount(int_t count)
|
|
{
|
|
if(count> getViewableRowsCount())
|
|
updateScrollBarRange(count);
|
|
mRowCount = count;
|
|
}
|
|
|
|
void AbstractTableView::deleteAllColumns()
|
|
{
|
|
mColumnList.clear();
|
|
}
|
|
|
|
void AbstractTableView::setColTitle(int index, QString title)
|
|
{
|
|
if(mColumnList.size() > 0 && index >= 0 && index < mColumnList.size())
|
|
{
|
|
Column_t wColum = mColumnList.takeAt(index);
|
|
wColum.title = title;
|
|
mColumnList.insert(index - 1, wColum);
|
|
}
|
|
}
|
|
|
|
QString AbstractTableView::getColTitle(int index)
|
|
{
|
|
if(mColumnList.size() > 0 && index >= 0 && index < mColumnList.size())
|
|
return mColumnList.at(index).title;
|
|
return "";
|
|
}
|
|
|
|
|
|
/************************************************************************************
|
|
Getter & Setter
|
|
************************************************************************************/
|
|
int_t AbstractTableView::getRowCount()
|
|
{
|
|
return mRowCount;
|
|
}
|
|
|
|
|
|
int AbstractTableView::getColumnCount()
|
|
{
|
|
return mColumnList.size();
|
|
}
|
|
|
|
|
|
int AbstractTableView::getRowHeight()
|
|
{
|
|
return mRowHeight;
|
|
}
|
|
|
|
|
|
int AbstractTableView::getColumnWidth(int index)
|
|
{
|
|
if(index < 0)
|
|
{
|
|
return -1;
|
|
}
|
|
else if(index < (getColumnCount() - 1))
|
|
{
|
|
return mColumnList.at(index).width;
|
|
}
|
|
else if(index == (getColumnCount() - 1))
|
|
{
|
|
int wGlobWidth = 0;
|
|
|
|
for(int i = 0; i < getColumnCount() - 1; i++)
|
|
wGlobWidth += getColumnWidth(i);
|
|
|
|
return this->width() - wGlobWidth;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void AbstractTableView::setColumnWidth(int index, int width)
|
|
{
|
|
mColumnList[index].width = width;
|
|
}
|
|
|
|
|
|
int AbstractTableView::getHeaderHeight()
|
|
{
|
|
if(mHeader.isVisible == true)
|
|
return mHeader.height;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
|
|
int AbstractTableView::getTableHeigth()
|
|
{
|
|
return this->height() - getHeaderHeight();
|
|
}
|
|
|
|
|
|
int AbstractTableView::getGuiState()
|
|
{
|
|
return mGuiState;
|
|
}
|
|
|
|
|
|
int AbstractTableView::getNbrOfLineToPrint()
|
|
{
|
|
return mNbrOfLineToPrint;
|
|
}
|
|
|
|
|
|
void AbstractTableView::setNbrOfLineToPrint(int parNbrOfLineToPrint)
|
|
{
|
|
mNbrOfLineToPrint = parNbrOfLineToPrint;
|
|
}
|
|
|
|
void AbstractTableView::setShowHeader(bool show)
|
|
{
|
|
mHeader.isVisible=show;
|
|
}
|
|
|
|
|
|
/************************************************************************************
|
|
Table Offset Management
|
|
************************************************************************************/
|
|
int_t AbstractTableView::getTableOffset()
|
|
{
|
|
return mTableOffset;
|
|
}
|
|
|
|
|
|
void AbstractTableView::setTableOffset(int_t val)
|
|
{
|
|
int_t wMaxOffset = getRowCount() - getViewableRowsCount() + 1;
|
|
wMaxOffset = wMaxOffset > 0 ? wMaxOffset : 0;
|
|
if(val > wMaxOffset)
|
|
return;
|
|
mTableOffset = val;
|
|
emit tableOffsetChanged(val);
|
|
|
|
#ifdef _WIN64
|
|
int wNewValue = scaleFromUint64ToScrollBarRange(mTableOffset);
|
|
verticalScrollBar()->setValue(wNewValue);
|
|
verticalScrollBar()->setSliderPosition(wNewValue);
|
|
#else
|
|
verticalScrollBar()->setValue(val);
|
|
verticalScrollBar()->setSliderPosition(val);
|
|
#endif
|
|
}
|
|
|
|
|
|
/************************************************************************************
|
|
Update/Reload/Refresh/Repaint
|
|
************************************************************************************/
|
|
void AbstractTableView::reloadData()
|
|
{
|
|
mShouldReload = true;
|
|
emit tableOffsetChanged(mTableOffset);
|
|
repaint();
|
|
}
|
|
|
|
|
|
void AbstractTableView::repaint()
|
|
{
|
|
this->viewport()->repaint();
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief This method is called when data have to be reloaded (e.g. When table offset changes).
|
|
*
|
|
* @return Nothing.
|
|
*/
|
|
void AbstractTableView::prepareData()
|
|
{
|
|
int wViewableRowsCount = getViewableRowsCount();
|
|
int_t wRemainingRowsCount = getRowCount() - mTableOffset;
|
|
mNbrOfLineToPrint = (int_t)wRemainingRowsCount > (int_t)wViewableRowsCount ? (int)wViewableRowsCount : (int)wRemainingRowsCount;
|
|
}
|