#include <qxtscheduleview_p.h>
Definition at line 104 of file qxtscheduleview_p.h.
QxtScheduleViewPrivate::QxtScheduleViewPrivate | ( | ) |
Definition at line 418 of file qxtscheduleview_p.cpp.
References delegate, handlesConcurrency, m_Cols, m_hHeader, m_Model, m_selectedItem, m_vHeader, m_zoomStepWidth, scrollTimer, and scrollTimerTimeout().
{ m_Cols = 0; m_vHeader = 0; m_hHeader = 0; m_Model = 0; m_selectedItem = 0; handlesConcurrency = false; delegate = 0; m_zoomStepWidth = 0; connect(&scrollTimer, SIGNAL(timeout()), this, SLOT(scrollTimerTimeout())); }
QVector< QRect > QxtScheduleViewPrivate::calculateRangeGeometries | ( | const int | iStartOffset, |
const int | iEndOffset | ||
) | const |
Definition at line 64 of file qxtscheduleview_p.cpp.
References m_hHeader, m_vHeader, offsetToVisualColumn(), offsetToVisualRow(), and visualIndexToOffset().
{ QVector<QRect> rects; if (iStartOffset < 0 || iEndOffset < 0) return rects; if (iEndOffset < iStartOffset) return rects; int iCurrentStartOffset = iStartOffset; int iCurrentEndOffset; do { if (offsetToVisualColumn(iCurrentStartOffset) == offsetToVisualColumn(iEndOffset)) iCurrentEndOffset = iEndOffset; else iCurrentEndOffset = visualIndexToOffset(m_vHeader->count() - 1, offsetToVisualColumn(iCurrentStartOffset)); qint32 iLeft = m_hHeader->sectionPosition(offsetToVisualColumn(iCurrentStartOffset)); qint32 iTop = m_vHeader->sectionPosition(offsetToVisualRow(iCurrentStartOffset)); qint32 iBottom = m_vHeader->sectionPosition(offsetToVisualRow(iCurrentEndOffset)) + m_vHeader->sectionSize(offsetToVisualRow(iCurrentEndOffset)); qint32 iRight = m_hHeader->sectionPosition(offsetToVisualColumn(iCurrentEndOffset)) + m_hHeader->sectionSize(offsetToVisualColumn(iCurrentEndOffset)); rects.append(QRect(iLeft + 1, iTop + 1, iRight - iLeft - 1, iBottom - iTop - 1)); iCurrentStartOffset = visualIndexToOffset(0, offsetToVisualColumn(iCurrentEndOffset) + 1); } while (iCurrentEndOffset < iEndOffset); return rects; }
QList< QLinkedList< QxtScheduleInternalItem * > > QxtScheduleViewPrivate::findConcurrentItems | ( | const int | from, |
const int | to | ||
) | const |
collects groups of concurrent items in the offset range
Definition at line 173 of file qxtscheduleview_p.cpp.
References m_Items, and qxtScheduleItemLessThan().
Referenced by handleItemConcurrency().
{ QList< QLinkedList<QxtScheduleInternalItem *> > allConcurrentItems; QList<QxtScheduleInternalItem *> allItemsSorted = m_Items; if(m_Items.size() == 0) return allConcurrentItems; qSort(allItemsSorted.begin(), allItemsSorted.end(), qxtScheduleItemLessThan); int startItem = 0; int endItem = allItemsSorted.size() - 1; //find the startitem that interferes with our range for (int i = 0; i < allItemsSorted.size(); i++) { if (i > 0) { if (!(allItemsSorted.at(i - 1)->visualEndTableOffset() >= allItemsSorted.at(i)->visualStartTableOffset() && allItemsSorted.at(i - 1)->visualStartTableOffset() <= allItemsSorted.at(i)->visualEndTableOffset())) startItem = i; } if (allItemsSorted.at(i)->visualEndTableOffset() >= from && allItemsSorted.at(i)->visualStartTableOffset() <= to) break; } //find the last item that interferes with our range for (int i = allItemsSorted.size() - 1; i >= 0 ; i--) { if (i < allItemsSorted.size() - 1) { if (!(allItemsSorted.at(i + 1)->visualEndTableOffset() >= allItemsSorted.at(i)->visualStartTableOffset() && allItemsSorted.at(i + 1)->visualStartTableOffset() <= allItemsSorted.at(i)->visualEndTableOffset())) endItem = i; } if (allItemsSorted.at(i)->visualEndTableOffset() >= from && allItemsSorted.at(i)->visualStartTableOffset() <= to) break; } int startOffset = allItemsSorted.at(startItem)->visualStartTableOffset(); int endOffset = allItemsSorted.at(endItem)->visualEndTableOffset(); /*now we have to populate a list with all items that interfere with our range */ QLinkedList<QxtScheduleInternalItem *> concurrentItems; for (int iAllItemLoop = startItem; iAllItemLoop <= endItem; iAllItemLoop++) { int tempStartOffset = allItemsSorted.at(iAllItemLoop)->visualStartTableOffset(); int tempEndOffset = allItemsSorted.at(iAllItemLoop)->visualEndTableOffset(); if (tempEndOffset >= startOffset && tempStartOffset <= endOffset) { if (concurrentItems.size() >= 1) { bool bAppend = false; /*check all items in the list if the current items interfers although the items are ordered by startIndex *we can loose some of them if the endTime of the last Item is before the endTime of the pre last item */ for (QLinkedList<QxtScheduleInternalItem *>::iterator it = concurrentItems.begin(); it != concurrentItems.end(); ++it) { int lastStartOffset = (*it)->visualStartTableOffset(); int lastEndOffset = (*it)->visualEndTableOffset(); if (tempEndOffset >= lastStartOffset && tempStartOffset <= lastEndOffset) { bAppend = true; break; } } if (bAppend) { concurrentItems.append(allItemsSorted.at(iAllItemLoop)); } else { allConcurrentItems.append(concurrentItems); concurrentItems.clear(); concurrentItems.append(allItemsSorted.at(iAllItemLoop)); } } else concurrentItems.append(allItemsSorted.at(iAllItemLoop)); if (tempStartOffset < startOffset) startOffset = tempStartOffset; if (tempEndOffset > endOffset) endOffset = tempEndOffset; } } if (concurrentItems.size() > 0) allConcurrentItems.append(concurrentItems); return allConcurrentItems; }
void QxtScheduleViewPrivate::handleItemConcurrency | ( | const int | from, |
const int | to | ||
) |
Definition at line 274 of file qxtscheduleview_p.cpp.
References findConcurrentItems(), handlesConcurrency, m_hHeader, m_Items, offsetToVisualColumn(), and QxtPrivate< QxtScheduleView >::qxt_p().
Referenced by handleItemConcurrency(), and reloadItemsFromModel().
{ /*collect all items that interfere only in that range*/ if (from < 0 || to < 0 || m_Items.size() == 0){ //do a update or we may have artifacts qxt_p().viewport()->update(); return; } qDebug() << "handleItemConcurrency"; if (handlesConcurrency) return; handlesConcurrency = true; QList< QLinkedList<QxtScheduleInternalItem *> > allConcurrentItems = findConcurrentItems(from, to); /*thx to ahigerd for suggesting that algorithm*/ //[16:24] <ahigerd> Start with the first event. Put it in a list. //[16:25] <ahigerd> Iterate until you find an event that doesn't overlap with the first event. Put it in the list. Repeat until you've reached the last event. //[16:25] <ahigerd> This fills the left column optimally. //[16:25] <ahigerd> Repeat the algorithm for the second column, etc., until there aren't any events left that don't have a column. //[16:27] <ahigerd> This algorithm is O(n*m), where n is the number of events and m is the maximum number of overlapping events. QList< QList< QxtScheduleInternalItem *> >virtualTable; for (int iListLoop = 0; iListLoop < allConcurrentItems.size(); iListLoop++) { QLinkedList<QxtScheduleInternalItem *> & currentItems = allConcurrentItems[iListLoop]; QList< QxtScheduleInternalItem * > currentColumn; qDebug() << "handle overlapping for " << currentItems.size() << " Items"; virtualTable.clear(); //we iterate over the currect collection and remove every item that can be placed in the current column //when the collection is empty we are done while (currentItems.size()) { QMutableLinkedListIterator< QxtScheduleInternalItem * > iter(currentItems); while (iter.hasNext()) { iter.next(); //initialize the current column if (currentColumn.isEmpty() || currentColumn[currentColumn.size()-1]->visualEndTableOffset() < iter.value()->visualStartTableOffset()) { currentColumn.append(iter.value()); iter.remove(); continue; } } if (!currentColumn.isEmpty()) { virtualTable.append(currentColumn); currentColumn.clear(); } } qDebug() << "Found columns" << virtualTable.size(); //this code part resizes the item geometries for (int col = 0; col < virtualTable.size(); col++) { for (int item = 0; item < virtualTable.at(col).size() ; item++) { int startVisualCol = offsetToVisualColumn(virtualTable[col][item]->visualStartTableOffset()); QVector<QRect> geo = virtualTable[col][item]->geometry(); for (int rect = 0; rect < geo.size(); rect++) { int sectionStart = m_hHeader->sectionPosition(startVisualCol); int fullWidth = m_hHeader->sectionSize(startVisualCol); int oneItemWidth = fullWidth / virtualTable.size(); int itemWidth = oneItemWidth; int itemXStart = (col * oneItemWidth) + sectionStart; int overlap = oneItemWidth / 10; int adjustX1 = 0; int adjustX2 = 0; //this is very expensive.I try to check if my item can span over more than one col int possibleCols = 1; bool foundCollision; for (int tmpCol = col + 1; tmpCol < virtualTable.size(); tmpCol++) { foundCollision = false; for (int tmpItem = 0; tmpItem < virtualTable.at(tmpCol).size() ; tmpItem++) { if ((virtualTable[tmpCol][tmpItem]->visualEndTableOffset() >= virtualTable[col][item]->visualStartTableOffset() && virtualTable[tmpCol][tmpItem]->visualStartTableOffset() <= virtualTable[col][item]->visualEndTableOffset())) { foundCollision = true; break; } } if (!foundCollision) possibleCols++; else break; } //now lets adjust the size to get a nice overlapping of items if (virtualTable.size() > 1) { if (col == 0) adjustX2 = overlap; else if (col == virtualTable.size() - 1) { adjustX1 = -overlap; adjustX2 = overlap; } else { if (col + possibleCols == virtualTable.size()) adjustX2 = overlap; else adjustX2 = overlap * 2; adjustX1 = -overlap; } } // possibleCols = 1; itemWidth = oneItemWidth * possibleCols; qDebug() << "orginial rect" << geo[rect]; geo[rect].setLeft(itemXStart + adjustX1); geo[rect].setWidth(itemWidth + adjustX2); qDebug() << "new rect" << geo[rect]; startVisualCol++; } virtualTable[col][item]->setGeometry(geo); } } } handlesConcurrency = false; qxt_p().viewport()->update(); }
void QxtScheduleViewPrivate::handleItemConcurrency | ( | QxtScheduleInternalItem * | item ) | [inline] |
Definition at line 141 of file qxtscheduleview_p.h.
References handleItemConcurrency(), QxtScheduleInternalItem::rows(), and QxtScheduleInternalItem::startTableOffset().
{ if (item) { int startOffset = item->startTableOffset(); int endOffset = startOffset + item->rows() - 1 ; handleItemConcurrency(startOffset, endOffset); } }
void QxtScheduleViewPrivate::init | ( | ) |
Definition at line 142 of file qxtscheduleview_p.cpp.
References m_hHeader, m_vHeader, QxtPrivate< QxtScheduleView >::qxt_p(), reloadItemsFromModel(), and QxtScheduleView::updateGeometries().
{ if (qxt_p().model()) { qxt_p().viewport()->setMouseTracking(true); if (!m_vHeader) { m_vHeader = new QxtScheduleHeaderWidget(Qt::Vertical, &qxt_p()); connect(m_vHeader, SIGNAL(geometriesChanged()), &qxt_p(), SLOT(updateGeometries())); } m_vHeader->show(); if (!m_hHeader) { m_hHeader = new QxtScheduleHeaderWidget(Qt::Horizontal, &qxt_p()); connect(m_hHeader, SIGNAL(geometriesChanged()), &qxt_p(), SLOT(updateGeometries())); } m_hHeader->show(); /*here we also initialize the items*/ m_vHeader->setDefaultSectionSize(20); m_vHeader->setResizeMode(QHeaderView::Fixed); reloadItemsFromModel(); } qxt_p().updateGeometries(); }
QxtScheduleInternalItem * QxtScheduleViewPrivate::internalItemAt | ( | const QPoint & | pt ) |
Definition at line 108 of file qxtscheduleview_p.cpp.
References QxtScheduleInternalItem::contains(), and m_Items.
{ QListIterator<QxtScheduleInternalItem *>iterator(m_Items); QxtScheduleInternalItem *currentItem; iterator.toBack(); while (iterator.hasPrevious()) { currentItem = iterator.previous(); if (currentItem->contains(pt)) return currentItem; } return 0; }
QxtScheduleInternalItem* QxtScheduleViewPrivate::internalItemAtModelIndex | ( | const QModelIndex & | index ) |
QxtScheduleInternalItem* QxtScheduleViewPrivate::itemForModelIndex | ( | const QModelIndex & | index ) | const [inline] |
void QxtScheduleViewPrivate::itemGeometryChanged | ( | QxtScheduleInternalItem * | item, |
QVector< QRect > | oldGeometry | ||
) | [slot] |
Definition at line 432 of file qxtscheduleview_p.cpp.
References QxtScheduleInternalItem::geometry(), and QxtPrivate< QxtScheduleView >::qxt_p().
Referenced by reloadItemsFromModel().
{ QRegion oldRegion; if (item->geometry() == oldGeometry) return; QVectorIterator<QRect> iter(oldGeometry); QRect currRect; while (iter.hasNext()) { currRect = iter.next(); currRect.adjust(-1, -1, 2, 2); oldRegion += currRect; } //viewport()->update(oldRegion); QRegion newRegion; QVectorIterator<QRect> newIter(item->geometry()); while (newIter.hasNext()) { currRect = newIter.next(); currRect.adjust(-1, -1, 2, 2); newRegion += currRect; } //viewport()->update(newRegion); qxt_p().viewport()->update(); }
int QxtScheduleViewPrivate::offsetToUnixTime | ( | const int | offset, |
bool | indexEndTime = false |
||
) | const |
Definition at line 539 of file qxtscheduleview_p.cpp.
References m_currentZoomDepth, m_endUnixTime, m_startUnixTime, offsetToVisualColumn(), offsetToVisualRow(), QxtPrivate< QxtScheduleView >::qxt_p(), and QxtScheduleView::rows().
{ qint32 rows = qxt_p().rows(); uint unixTime = (offsetToVisualRow(offset) + (offsetToVisualColumn(offset) * rows)) * m_currentZoomDepth; unixTime += m_startUnixTime; if (indexEndTime) { unixTime += m_currentZoomDepth; } if (unixTime >= m_startUnixTime && unixTime <= m_endUnixTime + 1) return unixTime; return -1; }
int QxtScheduleViewPrivate::offsetToVisualColumn | ( | const int | iOffset ) | const |
Definition at line 45 of file qxtscheduleview_p.cpp.
References QxtPrivate< QxtScheduleView >::qxt_p(), and QxtScheduleView::rows().
Referenced by calculateRangeGeometries(), handleItemConcurrency(), and offsetToUnixTime().
int QxtScheduleViewPrivate::offsetToVisualRow | ( | const int | iOffset ) | const |
Definition at line 57 of file qxtscheduleview_p.cpp.
References QxtPrivate< QxtScheduleView >::qxt_p(), and QxtScheduleView::rows().
Referenced by calculateRangeGeometries(), and offsetToUnixTime().
int QxtScheduleViewPrivate::pointToOffset | ( | const QPoint & | point ) |
Definition at line 99 of file qxtscheduleview_p.cpp.
References m_hHeader, m_vHeader, and visualIndexToOffset().
{ int iRow = m_vHeader->visualIndexAt(point.y()); int iCol = m_hHeader->visualIndexAt(point.x()); return visualIndexToOffset(iRow, iCol); }
void QxtScheduleViewPrivate::reloadItemsFromModel | ( | ) |
Definition at line 123 of file qxtscheduleview_p.cpp.
References handleItemConcurrency(), itemGeometryChanged(), m_Items, m_selectedItem, QxtScheduleView::model(), and QxtPrivate< QxtScheduleView >::qxt_p().
Referenced by init().
{ qDeleteAll(m_Items.begin(), m_Items.end()); m_Items.clear(); m_selectedItem = NULL; int iNumItems = qxt_p().model()->rowCount(); //delete all old stuff here QxtScheduleInternalItem *currentItem; for (int iLoop = 0; iLoop < iNumItems; iLoop++) { currentItem = new QxtScheduleInternalItem(&qxt_p(), qxt_p().model()->index(iLoop, 0)); m_Items.append(currentItem); connect(currentItem, SIGNAL(geometryChanged(QxtScheduleInternalItem*, QVector<QRect>)), this, SLOT(itemGeometryChanged(QxtScheduleInternalItem * , QVector< QRect >))); } handleItemConcurrency(0, (qxt_p().rows()*qxt_p().cols()) - 1); }
void QxtScheduleViewPrivate::scrollTimerTimeout | ( | ) | [slot] |
Definition at line 485 of file qxtscheduleview_p.cpp.
References m_hHeader, m_vHeader, and QxtPrivate< QxtScheduleView >::qxt_p().
Referenced by QxtScheduleViewPrivate().
{ QPoint globalPos = QCursor::pos(); QPoint viewportPos = qxt_p().viewport()->mapFromGlobal(globalPos); int iScrollVertical = this->m_vHeader->defaultSectionSize(); int iScrollHorizontal = this->m_hHeader->defaultSectionSize(); if (viewportPos.y() <= iScrollVertical) { int iCurrPos = qxt_p().verticalScrollBar()->value(); if (iCurrPos > qxt_p().verticalScrollBar()->minimum() + iScrollVertical) { qxt_p().verticalScrollBar()->setValue(iCurrPos - iScrollVertical); } else qxt_p().verticalScrollBar()->setValue(qxt_p().verticalScrollBar()->minimum()); } else if (viewportPos.y() >= qxt_p().viewport()->height() - iScrollVertical) { int iCurrPos = qxt_p().verticalScrollBar()->value(); if (iCurrPos < qxt_p().verticalScrollBar()->maximum() - iScrollVertical) { qxt_p().verticalScrollBar()->setValue(iCurrPos + iScrollVertical); } else qxt_p().verticalScrollBar()->setValue(qxt_p().verticalScrollBar()->maximum()); } if (viewportPos.x() <= iScrollHorizontal / 2) { int iCurrPos = qxt_p().horizontalScrollBar()->value(); if (iCurrPos > qxt_p().horizontalScrollBar()->minimum() + iScrollHorizontal) { qxt_p().horizontalScrollBar()->setValue(iCurrPos - iScrollHorizontal); } else qxt_p().horizontalScrollBar()->setValue(qxt_p().horizontalScrollBar()->minimum()); } else if (viewportPos.x() >= qxt_p().viewport()->width() - (iScrollHorizontal / 2)) { int iCurrPos = qxt_p().horizontalScrollBar()->value(); if (iCurrPos < qxt_p().horizontalScrollBar()->maximum() - iScrollHorizontal) { qxt_p().horizontalScrollBar()->setValue(iCurrPos + iScrollHorizontal); } else qxt_p().horizontalScrollBar()->setValue(qxt_p().horizontalScrollBar()->maximum()); } }
int QxtScheduleViewPrivate::unixTimeToOffset | ( | const uint | constUnixTime, |
bool | indexEndTime = false |
||
) | const |
Definition at line 462 of file qxtscheduleview_p.cpp.
References m_currentZoomDepth, m_endUnixTime, m_startUnixTime, QxtPrivate< QxtScheduleView >::qxt_p(), QxtScheduleView::rows(), and visualIndexToOffset().
{ uint unixTime = constUnixTime; if (unixTime >= m_startUnixTime && unixTime <= m_endUnixTime) { if (indexEndTime) { unixTime -= m_currentZoomDepth; } qint32 rows = qxt_p().rows(); qint32 iOffset = unixTime - m_startUnixTime; //round to the closest boundaries iOffset = qRound((qreal)iOffset / (qreal)m_currentZoomDepth); qint32 iCol = iOffset / rows; qint32 iRow = iOffset % rows; return visualIndexToOffset(iRow, iCol); } //virtual void handleItemOverlapping(QxtScheduleInternalItem *item); return -1; }
int QxtScheduleViewPrivate::visualIndexToOffset | ( | const int | iRow, |
const int | iCol | ||
) | const |
Definition at line 52 of file qxtscheduleview_p.cpp.
References QxtPrivate< QxtScheduleView >::qxt_p().
Referenced by calculateRangeGeometries(), pointToOffset(), and unixTimeToOffset().
{ return (iCol* qxt_p().rows()) + iRow; }
friend class QxtScheduleView [friend] |
Definition at line 109 of file qxtscheduleview_p.h.
Definition at line 174 of file qxtscheduleview_p.h.
Definition at line 173 of file qxtscheduleview_p.h.
Referenced by QxtScheduleViewPrivate().
Definition at line 172 of file qxtscheduleview_p.h.
Referenced by handleItemConcurrency(), and QxtScheduleViewPrivate().
Definition at line 169 of file qxtscheduleview_p.h.
Referenced by QxtScheduleViewPrivate().
Definition at line 151 of file qxtscheduleview_p.h.
Definition at line 157 of file qxtscheduleview_p.h.
Definition at line 155 of file qxtscheduleview_p.h.
Referenced by offsetToUnixTime(), and unixTimeToOffset().
Definition at line 159 of file qxtscheduleview_p.h.
Referenced by offsetToUnixTime(), and unixTimeToOffset().
Definition at line 167 of file qxtscheduleview_p.h.
Referenced by calculateRangeGeometries(), handleItemConcurrency(), init(), pointToOffset(), QxtScheduleViewPrivate(), and scrollTimerTimeout().
Definition at line 162 of file qxtscheduleview_p.h.
Definition at line 161 of file qxtscheduleview_p.h.
Referenced by findConcurrentItems(), handleItemConcurrency(), internalItemAt(), itemForModelIndex(), and reloadItemsFromModel().
Definition at line 154 of file qxtscheduleview_p.h.
QAbstractItemModel* QxtScheduleViewPrivate::m_Model |
Definition at line 171 of file qxtscheduleview_p.h.
Referenced by QxtScheduleViewPrivate().
Definition at line 152 of file qxtscheduleview_p.h.
Referenced by QxtScheduleViewPrivate(), and reloadItemsFromModel().
Definition at line 158 of file qxtscheduleview_p.h.
Referenced by offsetToUnixTime(), and unixTimeToOffset().
Definition at line 166 of file qxtscheduleview_p.h.
Referenced by calculateRangeGeometries(), init(), pointToOffset(), QxtScheduleViewPrivate(), and scrollTimerTimeout().
Definition at line 156 of file qxtscheduleview_p.h.
Referenced by QxtScheduleViewPrivate().
Definition at line 164 of file qxtscheduleview_p.h.
Referenced by QxtScheduleViewPrivate().