File indexing completed on 2024-05-26 05:56:36
0001 /* 0002 This file is part of the Okteta Kasten module, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2009 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 "selectrangetool.hpp" 0010 0011 // Okteta Kasten gui 0012 #include <Kasten/Okteta/ByteArrayView> 0013 // Okteta Kasten core 0014 #include <Kasten/Okteta/ByteArrayDocument> 0015 // Okteta core 0016 #include <Okteta/AbstractByteArrayModel> 0017 #include <Okteta/ArrayChangeMetricsList> 0018 // KF 0019 #include <KLocalizedString> 0020 0021 namespace Kasten { 0022 0023 SelectRangeTool::SelectRangeTool() 0024 : mIsEndRelative(false) 0025 , mIsEndBackwards(false) 0026 { 0027 setObjectName(QStringLiteral("SelectRange")); 0028 } 0029 0030 SelectRangeTool::~SelectRangeTool() = default; 0031 0032 int SelectRangeTool::currentSelectionStart() const 0033 { 0034 return mByteArrayView ? 0035 mByteArrayView->startOffset() + mByteArrayView->selection().start() : 0036 -1; 0037 } 0038 int SelectRangeTool::currentSelectionEnd() const 0039 { 0040 return mByteArrayView ? 0041 mByteArrayView->startOffset() + mByteArrayView->selection().end() : 0042 -1; 0043 } 0044 0045 bool SelectRangeTool::isUsable() const 0046 { 0047 return (mByteArrayView && mByteArrayModel && (mByteArrayModel->size() > 0)); 0048 } 0049 0050 bool SelectRangeTool::isApplyable() const 0051 { 0052 const int start = finalTargetSelectionStart(); 0053 const int end = finalTargetSelectionEnd(); 0054 0055 return (mByteArrayView && mByteArrayModel 0056 && (start <= end) 0057 && (0 <= start) && (start < mByteArrayModel->size()) 0058 && (0 <= end) && (end < mByteArrayModel->size())); 0059 } 0060 0061 QString SelectRangeTool::title() const { return i18nc("@title:window of the tool to select a range", "Select"); } 0062 0063 void SelectRangeTool::setTargetModel(AbstractModel* model) 0064 { 0065 const bool oldIsUsable = isUsable(); 0066 const bool oldIsApplyable = isApplyable(); 0067 0068 if (mByteArrayView) { 0069 mByteArrayView->disconnect(this); 0070 } 0071 if (mByteArrayModel) { 0072 mByteArrayModel->disconnect(this); 0073 } 0074 0075 mByteArrayView = model ? model->findBaseModel<ByteArrayView*>() : nullptr; 0076 0077 ByteArrayDocument* document = 0078 mByteArrayView ? qobject_cast<ByteArrayDocument*>(mByteArrayView->baseModel()) : nullptr; 0079 mByteArrayModel = document ? document->content() : nullptr; 0080 0081 if (mByteArrayView && mByteArrayModel) { 0082 connect(mByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, 0083 this, &SelectRangeTool::onContentsChanged); 0084 // TODO: update isApplyable on cursor movement and size changes 0085 } 0086 0087 const bool newIsUsable = isUsable(); 0088 const bool newIsApplyable = isApplyable(); 0089 if (oldIsUsable != newIsUsable) { 0090 Q_EMIT isUsableChanged(newIsUsable); 0091 } 0092 if (oldIsApplyable != newIsApplyable) { 0093 Q_EMIT isApplyableChanged(newIsApplyable); 0094 } 0095 } 0096 0097 void SelectRangeTool::setTargetStart(Okteta::Address start) 0098 { 0099 const bool oldIsApplyable = isApplyable(); 0100 0101 mTargetStart = start; 0102 0103 const bool newIsApplyable = isApplyable(); 0104 if (oldIsApplyable != newIsApplyable) { 0105 Q_EMIT isApplyableChanged(newIsApplyable); 0106 } 0107 } 0108 0109 void SelectRangeTool::setTargetEnd(Okteta::Address end) 0110 { 0111 const bool oldIsApplyable = isApplyable(); 0112 0113 mTargetEnd = end; 0114 0115 const bool newIsApplyable = isApplyable(); 0116 if (oldIsApplyable != newIsApplyable) { 0117 Q_EMIT isApplyableChanged(newIsApplyable); 0118 } 0119 } 0120 0121 void SelectRangeTool::setIsEndRelative(bool isEndRelative) 0122 { 0123 const bool oldIsApplyable = isApplyable(); 0124 0125 mIsEndRelative = isEndRelative; 0126 0127 const bool newIsApplyable = isApplyable(); 0128 if (oldIsApplyable != newIsApplyable) { 0129 Q_EMIT isApplyableChanged(newIsApplyable); 0130 } 0131 } 0132 0133 void SelectRangeTool::setIsEndBackwards(bool isEndBackwards) 0134 { 0135 const bool oldIsApplyable = isApplyable(); 0136 0137 mIsEndBackwards = isEndBackwards; 0138 0139 const bool newIsApplyable = isApplyable(); 0140 if (oldIsApplyable != newIsApplyable) { 0141 Q_EMIT isApplyableChanged(newIsApplyable); 0142 } 0143 } 0144 0145 void SelectRangeTool::select() 0146 { 0147 const int start = finalTargetSelectionStart(); 0148 const int end = finalTargetSelectionEnd(); 0149 0150 mByteArrayView->setSelection(start, end); 0151 mByteArrayView->setFocus(); 0152 } 0153 0154 int SelectRangeTool::finalTargetSelectionStart() const 0155 { 0156 const int start = 0157 (!mByteArrayView) ? 0158 -1 : 0159 mIsEndRelative && mIsEndBackwards ? 0160 mTargetStart - mTargetEnd + 1 : 0161 /* else */ 0162 mTargetStart; 0163 0164 return start; 0165 } 0166 0167 int SelectRangeTool::finalTargetSelectionEnd() const 0168 { 0169 const int end = 0170 (!mByteArrayView) ? 0171 -1 : 0172 (!mIsEndRelative) ? 0173 mTargetEnd : 0174 mIsEndBackwards ? 0175 mTargetStart : 0176 /* else */ 0177 mTargetStart + mTargetEnd - 1; 0178 0179 return end; 0180 } 0181 0182 void SelectRangeTool::onContentsChanged() 0183 { 0184 // TODO: find status before content changed, e.g. by caching 0185 Q_EMIT isUsableChanged(isUsable()); 0186 } 0187 0188 } 0189 0190 #include "moc_selectrangetool.cpp"