File indexing completed on 2024-05-12 13:56:03
0001 /* 0002 This file is part of the Okteta Gui library, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2004, 2008 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "abstracteditor.hpp" 0010 0011 // lib 0012 #include <bytearraytablelayout.hpp> 0013 #include <bytearraytablecursor.hpp> 0014 #include <abstractbytearrayview.hpp> 0015 // Okteta core 0016 #include <Okteta/AbstractByteArrayModel> 0017 #include <Okteta/TextByteArrayAnalyzer> 0018 // Qt 0019 #include <QKeyEvent> 0020 0021 namespace Okteta { 0022 0023 AbstractEditor::AbstractEditor(ByteArrayTableCursor* cursor, AbstractByteArrayView* view, AbstractController* parent) 0024 : AbstractController(parent) 0025 , mCursor(cursor) 0026 , mView(view) 0027 { 0028 } 0029 0030 AbstractEditor::~AbstractEditor() = default; 0031 0032 bool AbstractEditor::handleKeyPress(QKeyEvent* keyEvent) 0033 { 0034 const bool shiftPressed = keyEvent->modifiers() & Qt::SHIFT; 0035 const bool controlPressed = keyEvent->modifiers() & Qt::CTRL; 0036 const bool altPressed = keyEvent->modifiers() & Qt::ALT; 0037 0038 bool keyUsed = true; 0039 // we only care for cursor keys and the like, won't hardcode any other keys 0040 // we also don't check whether the commands are allowed 0041 // as the commands are also available as API so the check has to be done 0042 // in each command anyway 0043 switch (keyEvent->key()) 0044 { 0045 case Qt::Key_Delete: 0046 if (shiftPressed) { 0047 mView->cut(); 0048 } else if (mView->hasSelectedData()) { 0049 mView->removeSelectedData(); 0050 } else { 0051 doEditAction(controlPressed ? WordDelete : CharDelete); 0052 } 0053 break; 0054 case Qt::Key_Insert: 0055 if (shiftPressed) { 0056 mView->paste(); 0057 } else if (controlPressed) { 0058 mView->copy(); 0059 } else { 0060 mView->setOverwriteMode(!mView->isOverwriteMode()); 0061 } 0062 break; 0063 case Qt::Key_Backspace: 0064 if (altPressed) { 0065 break; 0066 } else if (mView->hasSelectedData()) { 0067 mView->removeSelectedData(); 0068 break; 0069 } 0070 0071 doEditAction(controlPressed ? WordBackspace : CharBackspace); 0072 break; 0073 case Qt::Key_F16: // "Copy" key on Sun keyboards 0074 mView->copy(); 0075 break; 0076 case Qt::Key_F18: // "Paste" key on Sun keyboards 0077 mView->paste(); 0078 break; 0079 case Qt::Key_F20: // "Cut" key on Sun keyboards 0080 mView->cut(); 0081 break; 0082 default: 0083 keyUsed = false; 0084 } 0085 0086 return keyUsed ? true : AbstractController::handleKeyPress(keyEvent); 0087 } 0088 0089 void AbstractEditor::doEditAction(EditAction action) 0090 { 0091 Okteta::AbstractByteArrayModel* byteArrayModel = mView->byteArrayModel(); 0092 switch (action) 0093 { 0094 case CharDelete: 0095 if (!mView->isOverwriteMode()) { 0096 const Address index = mCursor->realIndex(); 0097 if (index < mView->layout()->length()) { 0098 byteArrayModel->remove(AddressRange::fromWidth(index, 1)); 0099 } 0100 } 0101 break; 0102 case WordDelete: // kills data until the start of the next word 0103 if (!mView->isOverwriteMode()) { 0104 const Address index = mCursor->realIndex(); 0105 if (index < mView->layout()->length()) { 0106 const TextByteArrayAnalyzer textAnalyzer(byteArrayModel, mView->charCodec()); 0107 const Address end = textAnalyzer.indexOfBeforeNextWordStart(index); 0108 byteArrayModel->remove(AddressRange(index, end)); 0109 } 0110 } 0111 break; 0112 case CharBackspace: 0113 if (mView->isOverwriteMode()) { 0114 mView->pauseCursor(); 0115 mCursor->gotoPreviousByte(); 0116 mView->ensureCursorVisible(); 0117 mView->unpauseCursor(); 0118 } else { 0119 const Address deleteIndex = mCursor->realIndex() - 1; 0120 if (deleteIndex >= 0) { 0121 byteArrayModel->remove(AddressRange::fromWidth(deleteIndex, 1)); 0122 } 0123 } 0124 break; 0125 case WordBackspace: 0126 { 0127 const int leftIndex = mCursor->realIndex() - 1; 0128 if (leftIndex >= 0) { 0129 const TextByteArrayAnalyzer textAnalyzer(byteArrayModel, mView->charCodec()); 0130 const Address wordStart = textAnalyzer.indexOfPreviousWordStart(leftIndex); 0131 if (!mView->isOverwriteMode()) { 0132 byteArrayModel->remove(AddressRange(wordStart, leftIndex)); 0133 } 0134 } 0135 } 0136 } 0137 } 0138 0139 }