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 }