File indexing completed on 2024-05-12 16:41:07

0001 /********************************************************************************************
0002     begin                : Sunday Jun 27 2008
0003     Copyright (C) 2008 by Mathias Soeken (msoeken@informatik.uni-bremen.de)
0004               (C) 2005-2006 by Holger Danielsson (holger.danielsson@t-online.de)
0005               (C) 2011 by Felix Mauch (felix_mauch@web.de)
0006  ********************************************************************************************/
0007 
0008 /***************************************************************************
0009  *                                                                         *
0010  *   This program is free software; you can redistribute it and/or modify  *
0011  *   it under the terms of the GNU General Public License as published by  *
0012  *   the Free Software Foundation; either version 2 of the License, or     *
0013  *   (at your option) any later version.                                   *
0014  *                                                                         *
0015  ***************************************************************************/
0016 
0017 #include "tabulartable.h"
0018 
0019 #include <QApplication>
0020 #include <QClipboard>
0021 #include <QEvent>
0022 #include <QHeaderView>
0023 #include <QKeyEvent>
0024 #include <QPainter>
0025 #include <QPaintEvent>
0026 #include <QDebug>
0027 
0028 #include <KLocalizedString>
0029 #include <KMessageBox>
0030 
0031 #include "tabularcell.h"
0032 #include "tabularcelldelegate.h"
0033 
0034 namespace KileDialog {
0035 
0036 TabularTable::TabularTable(QWidget *parent)
0037     : QTableWidget(parent), m_ManualBorderPosition(QPoint(-1, -1)),
0038       m_ManualBorderStart(QPoint(-1, -1)),m_LastItem(Q_NULLPTR) {
0039     setItemDelegate(new TabularCellDelegate(this));
0040     setShowGrid(false);
0041     setAttribute(Qt::WA_Hover, true);
0042     horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
0043     installEventFilter(this);
0044     m_DefaultMode = selectionMode();
0045 }
0046 
0047 bool TabularTable::eventFilter(QObject *obj, QEvent *event)
0048 {
0049     if(obj == this) {
0050         if(event->type() == QEvent::KeyPress) {
0051             QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
0052 
0053             if(keyEvent->key() == Qt::Key_Return  && selectedItems().count() == 1) {
0054                 QTableWidgetItem *selectedItem = selectedItems()[0];
0055                 int row = selectedItem->row();
0056                 int column = selectedItem->column();
0057                 if(column < (columnCount() - 1)) {
0058                     selectedItem->setSelected(false);
0059                     item(row, column + 1)->setSelected(true);
0060                     setCurrentItem(item(row, column + 1));
0061                 } else {
0062                     if(row == (rowCount() - 1)) {
0063                         emit rowAppended();
0064                     }
0065                     selectedItem->setSelected(false);
0066                     item(row + 1, 0)->setSelected(true);
0067                     setCurrentItem(item(row + 1, 0));
0068                 }
0069                 return true;
0070             }
0071             else if(keyEvent->matches(QKeySequence::Paste)) {
0072                 paste();
0073             }
0074         }
0075         else if(event->type() == QEvent::HoverMove) {
0076             QHoverEvent *hoverEvent = static_cast<QHoverEvent*>(event);
0077             QPoint pos = viewport()->mapFromGlobal(mapToGlobal(hoverEvent->pos()));
0078             QTableWidgetItem *itemAtPos = itemAt(pos);
0079 
0080             if(itemAtPos) {
0081                 if(itemAtPos->row() == 0 && itemAtPos->column() == columnCount() - 1 &&
0082                         (visualItemRect(itemAtPos).topRight() - pos).manhattanLength() <= 8) {
0083                     setCursor(Qt::CrossCursor);
0084                     m_ManualBorderPosition.setX(columnCount());
0085                     m_ManualBorderPosition.setY(0);
0086                 }
0087                 else if(itemAtPos->row() == 0 &&
0088                         (visualItemRect(itemAtPos).topLeft() - pos).manhattanLength() <= 8) {
0089                     setCursor(Qt::CrossCursor);
0090                     m_ManualBorderPosition.setX(itemAtPos->column());
0091                     m_ManualBorderPosition.setY(0);
0092                 }
0093                 else if(itemAtPos->column() == columnCount() - 1 &&
0094                         (visualItemRect(itemAtPos).bottomRight() - pos).manhattanLength() <= 8) {
0095                     setCursor(Qt::CrossCursor);
0096                     m_ManualBorderPosition.setX(columnCount());
0097                     m_ManualBorderPosition.setY(itemAtPos->row() + 1);
0098                 }
0099                 else if((visualItemRect(itemAtPos).bottomLeft() - pos).manhattanLength() <= 8) {
0100                     setCursor(Qt::CrossCursor);
0101                     m_ManualBorderPosition.setX(itemAtPos->column());
0102                     m_ManualBorderPosition.setY(itemAtPos->row() + 1);
0103                 }
0104                 else {
0105                     unsetCursor();
0106                     m_ManualBorderPosition.setX(-1);
0107                     m_ManualBorderPosition.setY(-1);
0108                 }
0109             }
0110             else {
0111                 unsetCursor();
0112                 m_ManualBorderPosition.setX(-1);
0113                 m_ManualBorderPosition.setY(-1);
0114             }
0115 
0116             m_HoverPosition = pos;
0117             viewport()->update();
0118 
0119             return true;
0120         }
0121     }
0122 
0123     return QTableWidget::eventFilter(obj, event);
0124 }
0125 
0126 void TabularTable::mousePressEvent(QMouseEvent *event)
0127 {
0128     m_ManualBorderStart = m_ManualBorderPosition;
0129     if(m_ManualBorderStart.x() > -1) {
0130         setSelectionMode(QAbstractItemView::NoSelection);
0131         if(currentItem()) {
0132             m_LastItem = currentItem();
0133             currentItem()->setSelected(false);
0134         }
0135     }
0136 
0137     QTableWidget::mousePressEvent(event);
0138 }
0139 
0140 void TabularTable::mouseReleaseEvent(QMouseEvent *event)
0141 {
0142     if(m_ManualBorderStart.x() > -1) {
0143         if(m_ManualBorderPosition.x() > -1) {
0144             if(m_ManualBorderStart != m_ManualBorderPosition) {
0145                 if(m_ManualBorderStart.x() == m_ManualBorderPosition.x()) {
0146                     int column = (m_ManualBorderStart.x() == columnCount()) ? m_ManualBorderStart.x() - 1 : m_ManualBorderStart.x();
0147                     for(int row = qMin(m_ManualBorderStart.y(), m_ManualBorderPosition.y());
0148                             row < qMax(m_ManualBorderStart.y(), m_ManualBorderPosition.y()); ++row) {
0149                         TabularCell *cell = static_cast<TabularCell*>(item(row, column));
0150                         int border = cell->border() | ((m_ManualBorderStart.x() == columnCount()) ? TabularCell::Right : TabularCell::Left);
0151                         cell->setBorder(border);
0152                     }
0153                 } else if(m_ManualBorderStart.y() == m_ManualBorderPosition.y()) {
0154                     int row = (m_ManualBorderStart.y() == rowCount()) ? m_ManualBorderStart.y() - 1 : m_ManualBorderStart.y();
0155                     for(int column = qMin(m_ManualBorderStart.x(), m_ManualBorderPosition.x());
0156                             column < qMax(m_ManualBorderStart.x(), m_ManualBorderPosition.x()); ++column) {
0157                         TabularCell *cell = static_cast<TabularCell*>(item(row, column));
0158                         int border = cell->border() | ((m_ManualBorderStart.y() == rowCount()) ? TabularCell::Bottom : TabularCell::Top);
0159                         cell->setBorder(border);
0160                     }
0161                 }
0162                 viewport()->update();
0163             }
0164 
0165             m_ManualBorderPosition.setX(-1);
0166             m_ManualBorderPosition.setY(-1);
0167         }
0168 
0169         m_ManualBorderStart.setX(-1);
0170         m_ManualBorderStart.setY(-1);
0171     }
0172 
0173     setSelectionMode(m_DefaultMode);
0174     if(m_LastItem) {
0175         setCurrentItem(m_LastItem);
0176         currentItem()->setSelected(true);
0177         m_LastItem = 0;
0178     }
0179     QTableWidget::mouseReleaseEvent(event);
0180 }
0181 
0182 void TabularTable::paintEvent(QPaintEvent *event)
0183 {
0184     QPainter painter(viewport());
0185     if(m_ManualBorderStart.x() > -1) {
0186         QTableWidgetItem *startItem = item(
0187                                           (m_ManualBorderStart.y() == rowCount() ? m_ManualBorderStart.y() - 1 : m_ManualBorderStart.y()),
0188                                           (m_ManualBorderStart.x() == columnCount() ? m_ManualBorderStart.x() - 1 : m_ManualBorderStart.x()));
0189 
0190         int xStart = (m_ManualBorderStart.x() == columnCount() ? visualItemRect(startItem).right() : visualItemRect(startItem).left());
0191         int yStart = (m_ManualBorderStart.y() == rowCount() ? visualItemRect(startItem).bottom() : visualItemRect(startItem).top());
0192 
0193         QColor color =
0194             ((m_ManualBorderStart != m_ManualBorderPosition) &&
0195              ((m_ManualBorderStart.x() == m_ManualBorderPosition.x()) ||
0196               (m_ManualBorderStart.y() == m_ManualBorderPosition.y())) ? Qt::darkGreen : Qt::darkRed);
0197         painter.setPen(QPen(color, 2));
0198         painter.drawLine(xStart, yStart, m_HoverPosition.x(), m_HoverPosition.y());
0199     }
0200 
0201     QTableWidget::paintEvent(event);
0202 }
0203 
0204 }
0205 
0206 void KileDialog::TabularTable::paste()
0207 {
0208     // Maybe we want to insert content at a certain point in the table
0209     int selectedRow = 0;
0210     int selectedCol = 0;
0211     if(!selectedItems().isEmpty()) {
0212         selectedRow = selectedItems().first()->row();
0213         selectedCol = selectedItems().first()->column();
0214     }
0215 
0216     //Clipboard->QStringlist
0217     QString selectedText = qApp->clipboard()->text();
0218     selectedText = selectedText.remove('\r');
0219     if(selectedText.isEmpty()) {
0220         KMessageBox::information(this, i18n("There is no content to insert into the table as the clipboard is empty."), i18n("Empty Clipboard"));
0221         return;
0222     }
0223     if(!selectedText.endsWith('\n')) {
0224         selectedText += '\n';
0225     }
0226     QStringList cells = selectedText.split(QRegExp(QLatin1String("\\n|\\t")));
0227     while(!cells.empty() && cells.back().size() == 0) {
0228         cells.pop_back(); // strip empty trailing tokens
0229     }
0230     int rows = selectedText.count(QLatin1Char('\n'));
0231     int cols = cells.size() / rows;
0232 
0233     // Fill everything in the tableWidget
0234     // If needed, new rows and cols get generated on the fly
0235     int cell = 0;
0236     for(int row = 0; row < rows; ++row) {
0237         if(selectedRow + row > (rowCount() - 1)) {
0238             emit rowAppended();
0239         }
0240         for(int col = 0; col < cols; ++col, ++cell) {
0241             if(selectedCol + col > (columnCount() - 1)) {
0242                 emit colAppended();
0243             }
0244             item(selectedRow + row, selectedCol + col)->setText(cells[cell]);
0245         }
0246     }
0247 }
0248 
0249