File indexing completed on 2023-05-30 10:45:26

0001 /*
0002     SPDX-FileCopyrightText: 2002-2010 Peter Hedlund <peter.hedlund@kdemail.net>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "kwqcommands.h"
0007 
0008 #include <QApplication>
0009 #include <QClipboard>
0010 #include <QHeaderView>
0011 
0012 #include "kwqtablemodel.h"
0013 
0014 void copyToClipboard(QTableView * view)
0015 {
0016   QModelIndexList selIndexes = view->selectionModel()->selectedIndexes();
0017   if( selIndexes.isEmpty())
0018      return;
0019   int tr = selIndexes.first().row();
0020   int lc = selIndexes.first().column();
0021   int br = selIndexes.last().row();
0022   int rc = selIndexes.last().column();
0023 
0024   QString s;
0025   for (int r = tr; r <= br; ++r)
0026   {
0027     for (int c = lc; c <= rc; ++c)
0028     {
0029       QVariant v =  view->model()->data(view->model()->index(r, c, QModelIndex()), Qt::DisplayRole);
0030       s.append(v.toString());
0031       s.append(QLatin1Char('\t'));
0032     }
0033     s.append(QLatin1Char('\n'));
0034   }
0035   QApplication::clipboard()->setText(s.trimmed());
0036 }
0037 
0038 
0039 KWQUndoCommand::KWQUndoCommand(KWQTableView * view) : QUndoCommand()
0040 {
0041   m_view = view;
0042   m_currentIndex = m_view->selectionModel()->currentIndex();  
0043   m_selectedIndexes = m_view->selectionModel()->selectedIndexes();
0044   if (m_selectedIndexes.isEmpty())
0045       m_selectedIndexes.append(m_currentIndex);
0046       
0047   foreach (const QModelIndex &index, m_selectedIndexes) {
0048     IndexAndData id;
0049     id.index = index;
0050     id.data = m_view->model()->data(index, Qt::DisplayRole);
0051     id.image = m_view->model()->data(index, KWQTableModel::ImageRole);
0052     id.sound = m_view->model()->data(index, KWQTableModel::SoundRole);
0053     id.height = m_view->rowHeight(index.row());
0054     m_indexAndData.append(id);
0055   }
0056 }
0057 
0058 
0059 void KWQUndoCommand::undo()
0060 {
0061   m_view->selectionModel()->clear();
0062   foreach (const IndexAndData &id, m_indexAndData) {
0063     m_view->model()->setData(id.index, id.data, Qt::EditRole);
0064     m_view->model()->setData(id.index, id.image, KWQTableModel::ImageRole);
0065     m_view->model()->setData(id.index, id.sound, KWQTableModel::SoundRole);
0066     m_view->selectionModel()->select(id.index, QItemSelectionModel::Select);
0067   }
0068   m_view->selectionModel()->setCurrentIndex(m_currentIndex, QItemSelectionModel::Current);
0069 }
0070 
0071 
0072 KWQCommandClear::KWQCommandClear(KWQTableView * view) : KWQUndoCommand(view)
0073 {
0074   setText(i18nc("@item:inmenu undo clear", "Clear"));
0075 }
0076 
0077 
0078 void KWQCommandClear::redo()
0079 {
0080   view()->selectionModel()->clear();
0081   foreach (const QModelIndex &index, oldSelectedIndexes()) {
0082     if (Prefs::clearText() || Prefs::clearAll())
0083       view()->model()->setData(index, QVariant(), Qt::EditRole);
0084     if (Prefs::clearImageLink() || Prefs::clearAll())
0085       view()->model()->setData(index, QVariant(), KWQTableModel::ImageRole);
0086     if (Prefs::clearSoundLink() || Prefs::clearAll())
0087       view()->model()->setData(index, QVariant(), KWQTableModel::SoundRole);
0088     view()->selectionModel()->select(index, QItemSelectionModel::Select);
0089   }
0090   view()->selectionModel()->setCurrentIndex(oldCurrentIndex(), QItemSelectionModel::Current);
0091 }
0092 
0093 
0094 KWQCommandCut::KWQCommandCut(KWQTableView * view) : KWQCommandClear(view)
0095 {
0096   setText(i18nc("@item:inmenu undo cut", "Cut"));
0097 }
0098 
0099 
0100 void KWQCommandCut::redo()
0101 {
0102   copyToClipboard(view());
0103   KWQCommandClear::redo();
0104 }
0105 
0106 
0107 KWQCommandPaste::KWQCommandPaste(KWQTableView * view) : KWQUndoCommand(view)
0108 {
0109   setText(i18nc("@item:inmenu undo paste", "Paste"));
0110   m_rowCount = view->model()->rowCount();
0111 }
0112 
0113 void KWQCommandPaste::undo()
0114 {
0115   foreach (const IndexAndData &id, m_pasteIndexAndData)
0116     view()->model()->setData(id.index, id.data, Qt::EditRole);
0117 
0118   while (view()->model()->rowCount(QModelIndex()) > m_rowCount) {
0119       view()->model()->removeRows(view()->model()->rowCount() - 1, 1, QModelIndex());
0120     }
0121 
0122   KWQUndoCommand::undo();
0123 }
0124 
0125 void KWQCommandPaste::redo()
0126 {
0127   QModelIndexList selIndexes = oldSelectedIndexes();
0128   if(selIndexes.isEmpty())
0129      return;
0130   QModelIndex topLeft = view()->model()->index(selIndexes.first().row(), selIndexes.first().column(), QModelIndex());
0131   QModelIndex bottomRight = view()->model()->index(selIndexes.last().row(), selIndexes.last().column(), QModelIndex());
0132 
0133   int tr;
0134   int lc;
0135   int ar = tr = topLeft.row();
0136   int ac = lc = topLeft.column();
0137   int rc = bottomRight.column();
0138   int br = bottomRight.row();
0139 
0140   QString s = QApplication::clipboard()->text();
0141   QStringList sl = s.split('\n', Qt::SkipEmptyParts);
0142   if (sl.isEmpty())
0143     return;
0144   QStringList sr;
0145   int i = 0;
0146 
0147   if (selIndexes.count() == 1) //one cell selected
0148   {
0149     //Do we need to add entries (rows)?
0150     while (sl.count() + tr > view()->model()->rowCount(QModelIndex())) {
0151       view()->model()->insertRows(view()->model()->rowCount(), 1, QModelIndex());
0152     }
0153 
0154     br = tr + sl.count() - 1;
0155 
0156     if (lc == 0) //left col?
0157       if (sl[0].indexOf(QLatin1Char('\t')) > -1)
0158         rc = 1; //expand to second column;
0159 
0160     while (i < sl.count() && br <= view()->model()->rowCount(QModelIndex())) {
0161       ac = lc;
0162 
0163       sr = sl.at(i).split(QLatin1Char('\t'));
0164       int c = 0;
0165       while (ac <= rc) {
0166         IndexAndData id;
0167         id.index = view()->model()->index(ar, ac);
0168         id.data = view()->model()->data(id.index, Qt::DisplayRole);
0169         m_pasteIndexAndData.append(id);
0170         if (c < sr.count())
0171             view()->model()->setData(id.index, QVariant(sr[c]), Qt::EditRole);
0172         view()->selectionModel()->select(id.index, QItemSelectionModel::Select);
0173         ac++;
0174         c++;
0175       }
0176       ar++;
0177       i++;
0178     }
0179   }
0180   else
0181   {
0182     while (i < sl.count() && ar <= br) {
0183       ac = lc;
0184 
0185       sr = sl.at(i).split(QLatin1Char('\t'));
0186       int c = 0;
0187       while (ac <= rc) {
0188         if (view()->selectionModel()->isSelected(view()->model()->index(ar, ac)))
0189             if (c < sr.count())
0190                 view()->model()->setData(view()->model()->index(ar, ac), QVariant(sr[c]), Qt::EditRole);
0191         ac++;
0192         c++;
0193       }
0194       ar++;
0195       i++;
0196     }
0197   }
0198 }
0199 
0200 
0201 KWQCommandSort::KWQCommandSort(QTableView * view, int column)
0202 {
0203   m_view = view;
0204   m_column = column;
0205   setText(i18nc("@item:inmenu undo sort", "Sort"));
0206 }
0207 
0208 
0209 void KWQCommandSort::undo()
0210 {
0211   m_view->setUpdatesEnabled(false);
0212   static_cast<KWQSortFilterModel*>(m_view->model())->restoreNativeOrder();
0213   m_view->horizontalHeader()->setSortIndicatorShown(false);
0214   m_view->setUpdatesEnabled(true);
0215 }
0216 
0217 
0218 void KWQCommandSort::redo()
0219 {
0220   int currentRow = m_view->currentIndex().row();
0221   int currentColumn = m_view->currentIndex().column();
0222   m_view->sortByColumn(m_column, Qt::AscendingOrder);
0223   m_view->horizontalHeader()->setSortIndicatorShown(true);
0224   m_view->horizontalHeader()->setSortIndicator(m_column, m_view->horizontalHeader()->sortIndicatorOrder());
0225   m_view->setCurrentIndex(m_view->model()->index(currentRow, currentColumn, QModelIndex()));
0226 }
0227 
0228 
0229 KWQCommandShuffle::KWQCommandShuffle(QTableView * view, int column) : KWQCommandSort(view, column)
0230 {
0231   m_view = view;
0232   setText(i18nc("@item:inmenu undo shuffle", "Shuffle"));
0233 }
0234 
0235 void KWQCommandShuffle::undo()
0236 {
0237   KWQCommandSort::undo();
0238 }
0239 
0240 void KWQCommandShuffle::redo()
0241 {
0242   int currentRow = m_view->currentIndex().row();
0243   int currentColumn = m_view->currentIndex().column();
0244   static_cast<KWQSortFilterModel*>(m_view->model())->shuffle();
0245   m_view->horizontalHeader()->setSortIndicatorShown(false);
0246   m_view->setCurrentIndex(m_view->model()->index(currentRow, currentColumn, QModelIndex()));
0247 }
0248 
0249 
0250 KWQCommandInsert::KWQCommandInsert(KWQTableView * view) : KWQUndoCommand(view)
0251 {
0252   setText(i18nc("@item:inmenu undo insert", "Insert"));
0253 }
0254 
0255 void KWQCommandInsert::undo()
0256 {
0257   QModelIndexList selIndexes = oldSelectedIndexes();
0258   QModelIndex topLeft = view()->model()->index(selIndexes.first().row(), selIndexes.first().column(), QModelIndex());
0259   QModelIndex bottomRight = view()->model()->index(selIndexes.last().row(), selIndexes.last().column(), QModelIndex());
0260 
0261   view()->model()->removeRows(topLeft.row(), bottomRight.row() - topLeft.row() + 1, QModelIndex());
0262 
0263   view()->selectionModel()->clear();
0264   view()->setCurrentIndex(view()->model()->index(oldCurrentIndex().row(), oldCurrentIndex().column(), QModelIndex()));
0265   view()->selectionModel()->select(QItemSelection(topLeft, bottomRight), QItemSelectionModel::Select);
0266 }
0267 
0268 void KWQCommandInsert::redo()
0269 {
0270   QModelIndexList selIndexes = oldSelectedIndexes();
0271   QModelIndex topLeft = view()->model()->index(selIndexes.first().row(), selIndexes.first().column(), QModelIndex());
0272   QModelIndex bottomRight = view()->model()->index(selIndexes.last().row(), selIndexes.last().column(), QModelIndex());
0273 
0274   view()->model()->insertRows(topLeft.row(), bottomRight.row() - topLeft.row() + 1, QModelIndex());
0275 
0276   view()->selectionModel()->clear();
0277   view()->setCurrentIndex(view()->model()->index(oldCurrentIndex().row(), oldCurrentIndex().column(), QModelIndex()));
0278   view()->selectionModel()->select(QItemSelection(topLeft, bottomRight), QItemSelectionModel::Select);
0279 }
0280 
0281 
0282 KWQCommandDelete::KWQCommandDelete(KWQTableView * view) : KWQUndoCommand(view)
0283 {
0284   setText(i18nc("@item:inmenu undo delete", "Delete"));
0285 }
0286 
0287 
0288 void KWQCommandDelete::undo()
0289 {
0290   QModelIndexList selIndexes = oldSelectedIndexes();
0291   QModelIndex topLeft = view()->model()->index(selIndexes.first().row(), selIndexes.first().column(), QModelIndex());
0292   QModelIndex bottomRight = view()->model()->index(selIndexes.last().row(), selIndexes.last().column(), QModelIndex());
0293 
0294   view()->model()->insertRows(topLeft.row(), bottomRight.row() - topLeft.row() + 1, QModelIndex());
0295 
0296   for (const IndexAndData &id : qAsConst(m_deleteIndexAndData))
0297     view()->model()->setData(id.index, id.data, Qt::EditRole);
0298 
0299   view()->selectionModel()->clear();
0300   view()->setCurrentIndex(view()->model()->index(oldCurrentIndex().row(), oldCurrentIndex().column(), QModelIndex()));
0301   view()->selectionModel()->select(QItemSelection(topLeft, bottomRight), QItemSelectionModel::Select);
0302 }
0303 
0304 
0305 void KWQCommandDelete::redo()
0306 {
0307   QModelIndexList selIndexes = oldSelectedIndexes();
0308   QModelIndex topLeft = view()->model()->index(selIndexes.first().row(), selIndexes.first().column(), QModelIndex());
0309   QModelIndex bottomRight = view()->model()->index(selIndexes.last().row(), selIndexes.last().column(), QModelIndex());
0310 
0311   QModelIndex topLeftDeletion = view()->model()->index(selIndexes.first().row(), 0, QModelIndex());
0312   QModelIndex bottomRightDeletion = view()->model()->index(selIndexes.last().row(), 1, QModelIndex());
0313 
0314   QItemSelection deletion(topLeftDeletion, bottomRightDeletion);
0315   m_deleteIndexAndData.clear();
0316   foreach (const QModelIndex &idx, deletion.indexes()) {
0317     IndexAndData id;
0318     id.index = idx;
0319     id.data = view()->model()->data(id.index, Qt::DisplayRole);
0320     m_deleteIndexAndData.append(id);
0321   }
0322 
0323   view()->model()->removeRows(topLeft.row(), bottomRight.row() - topLeft.row() + 1, QModelIndex());
0324 
0325   view()->selectionModel()->clear();
0326   view()->setCurrentIndex(view()->model()->index(oldCurrentIndex().row(), oldCurrentIndex().column(), QModelIndex()));
0327   view()->selectionModel()->select(QItemSelection(topLeft, bottomRight), QItemSelectionModel::Select);
0328 }
0329 
0330 
0331 KWQCommandUnmarkBlank::KWQCommandUnmarkBlank(KWQTableView * view) : KWQUndoCommand(view)
0332 {
0333   setText(i18nc("@item:inmenu undo unmark blank", "Unmark Blank"));
0334 }
0335 
0336 
0337 void KWQCommandUnmarkBlank::redo()
0338 {
0339   QString s;
0340   view()->selectionModel()->clear();
0341   foreach (const QModelIndex &index, oldSelectedIndexes())
0342   {
0343     s = view()->model()->data(index, Qt::DisplayRole).toString();
0344     s = s.remove(delim_start);
0345     s = s.remove(delim_end);
0346     view()->model()->setData(index, QVariant(s), Qt::EditRole);
0347     view()->selectionModel()->select(index, QItemSelectionModel::Select);
0348   }
0349   view()->selectionModel()->setCurrentIndex(oldCurrentIndex(), QItemSelectionModel::Current);
0350 }
0351 
0352 
0353 KWQCommandIdentifiers::KWQCommandIdentifiers(KWQTableView * view, const ColumnDataList &newColumnData) : KWQUndoCommand(view)
0354 {
0355   setText(i18nc("@item:inmenu undo column titles", "Column Settings"));
0356   m_oldColumnData.clear();
0357   ColumnData columnData;
0358   columnData.identifier = view->model()->headerData(0, Qt::Horizontal, Qt::DisplayRole).toString();
0359   columnData.layout = view->model()->headerData(0, Qt::Horizontal, KWQTableModel::KeyboardLayoutRole).toString();
0360   columnData.width = view->model()->headerData(0, Qt::Horizontal, Qt::SizeHintRole).toSize().width();
0361   m_oldColumnData.append(columnData);
0362 
0363   columnData.identifier = view->model()->headerData(1, Qt::Horizontal, Qt::DisplayRole).toString();
0364   columnData.layout = view->model()->headerData(1, Qt::Horizontal, KWQTableModel::KeyboardLayoutRole).toString();
0365   columnData.width = view->model()->headerData(1, Qt::Horizontal, Qt::SizeHintRole).toSize().width();
0366   m_oldColumnData.append(columnData);
0367 
0368   m_newColumnData = newColumnData;
0369 }
0370 
0371 
0372 void KWQCommandIdentifiers::undo()
0373 {
0374   view()->model()->setHeaderData(0, Qt::Horizontal, m_oldColumnData[0].identifier, Qt::EditRole);
0375   view()->model()->setHeaderData(1, Qt::Horizontal, m_oldColumnData[1].identifier, Qt::EditRole);
0376 
0377   view()->model()->setHeaderData(0, Qt::Horizontal, m_oldColumnData[0].layout, KWQTableModel::KeyboardLayoutRole);
0378   view()->model()->setHeaderData(1, Qt::Horizontal, m_oldColumnData[1].layout, KWQTableModel::KeyboardLayoutRole);
0379 
0380   view()->model()->setHeaderData(0, Qt::Horizontal, QSize(m_oldColumnData[0].width, 25), Qt::SizeHintRole);
0381   view()->model()->setHeaderData(1, Qt::Horizontal, QSize(m_oldColumnData[1].width, 25), Qt::SizeHintRole);
0382 }
0383 
0384 
0385 void KWQCommandIdentifiers::redo()
0386 {
0387   view()->model()->setHeaderData(0, Qt::Horizontal, m_newColumnData[0].identifier, Qt::EditRole);
0388   view()->model()->setHeaderData(1, Qt::Horizontal, m_newColumnData[1].identifier, Qt::EditRole);
0389 
0390   view()->model()->setHeaderData(0, Qt::Horizontal, m_newColumnData[0].layout, KWQTableModel::KeyboardLayoutRole);
0391   view()->model()->setHeaderData(1, Qt::Horizontal, m_newColumnData[1].layout, KWQTableModel::KeyboardLayoutRole);
0392 
0393   view()->model()->setHeaderData(0, Qt::Horizontal, QSize(m_newColumnData[0].width, 25), Qt::SizeHintRole);
0394   view()->model()->setHeaderData(1, Qt::Horizontal, QSize(m_newColumnData[1].width, 25), Qt::SizeHintRole);
0395 }
0396 
0397 
0398 KWQCommandImage::KWQCommandImage(KWQTableView *view, const QUrl &newUrl) : KWQUndoCommand(view), m_newUrl(newUrl)
0399 {
0400   setText(i18nc("@item:inmenu undo link image", "Link Image"));
0401   m_oldUrl = QUrl(view->model()->data(oldCurrentIndex(), KWQTableModel::ImageRole).toString());
0402 }
0403 
0404 
0405 void KWQCommandImage::undo()
0406 {
0407   view()->model()->setData(oldCurrentIndex(), QVariant(m_oldUrl), KWQTableModel::ImageRole);
0408 }
0409 
0410 
0411 void KWQCommandImage::redo()
0412 {
0413   view()->model()->setData(oldCurrentIndex(), QVariant(m_newUrl), KWQTableModel::ImageRole);
0414 }
0415 
0416 
0417 KWQCommandSound::KWQCommandSound(KWQTableView *view, const QUrl &newUrl) : KWQUndoCommand(view), m_newUrl(newUrl)
0418 {
0419   setText(i18nc("@item:inmenu undo link sound", "Link Sound"));
0420   m_oldUrl = QUrl(view->model()->data(oldCurrentIndex(), KWQTableModel::SoundRole).toString());
0421 }
0422 
0423 
0424 void KWQCommandSound::undo()
0425 {
0426   view()->model()->setData(oldCurrentIndex(), QVariant(m_oldUrl), KWQTableModel::SoundRole);
0427 }
0428 
0429 
0430 void KWQCommandSound::redo()
0431 {
0432   view()->model()->setData(oldCurrentIndex(), QVariant(m_newUrl), KWQTableModel::SoundRole);
0433 }