1 /* 2 This file is part of the Okteta Kasten module, made within the KDE community. 3 4 SPDX-FileCopyrightText: 2009 Friedrich W. H. Kossebau <kossebau@kde.org> 5 6 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 7 */ 8 9 #include "gotooffsettool.hpp" 10 11 // Okteta Kasten gui 12 #include <Kasten/Okteta/ByteArrayView> 13 // Okteta Kasten core 14 #include <Kasten/Okteta/ByteArrayDocument> 15 // Okteta core 16 #include <Okteta/AbstractByteArrayModel> 17 #include <Okteta/ArrayChangeMetricsList> 18 // KF 19 #include <KLocalizedString> 20 21 namespace Kasten { 22 GotoOffsetTool()23GotoOffsetTool::GotoOffsetTool() 24 { 25 setObjectName(QStringLiteral("GotoOffset")); 26 } 27 28 GotoOffsetTool::~GotoOffsetTool() = default; 29 currentOffset() const30int GotoOffsetTool::currentOffset() const 31 { 32 return mByteArrayView ? 33 mByteArrayView->startOffset() + mByteArrayView->cursorPosition() : 34 -1; 35 } 36 isUsable() const37bool GotoOffsetTool::isUsable() const 38 { 39 return (mByteArrayView && mByteArrayModel && (mByteArrayModel->size() > 0)); 40 } 41 isApplyable() const42bool GotoOffsetTool::isApplyable() const 43 { 44 const int newPosition = finalTargetOffset(); 45 46 return (mByteArrayView && mByteArrayModel 47 && (0 <= newPosition) && (newPosition <= mByteArrayModel->size())); 48 } 49 title() const50QString GotoOffsetTool::title() const { return i18nc("@title:window of the tool to set a new offset for the cursor", "Goto"); } 51 setTargetModel(AbstractModel * model)52void GotoOffsetTool::setTargetModel(AbstractModel* model) 53 { 54 const bool oldIsUsable = isUsable(); 55 const bool oldIsApplyable = isApplyable(); 56 57 if (mByteArrayView) { 58 mByteArrayView->disconnect(this); 59 } 60 if (mByteArrayModel) { 61 mByteArrayModel->disconnect(this); 62 } 63 64 mByteArrayView = model ? model->findBaseModel<ByteArrayView*>() : nullptr; 65 66 ByteArrayDocument* document = 67 mByteArrayView ? qobject_cast<ByteArrayDocument*>(mByteArrayView->baseModel()) : nullptr; 68 mByteArrayModel = document ? document->content() : nullptr; 69 70 if (mByteArrayView && mByteArrayModel) { 71 connect(mByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, 72 this, &GotoOffsetTool::onContentsChanged); 73 // TODO: update isApplyable on cursor movement and size changes 74 } 75 76 const bool newIsUsable = isUsable(); 77 const bool newIsApplyable = isApplyable(); 78 if (oldIsUsable != newIsUsable) { 79 emit isUsableChanged(newIsUsable); 80 } 81 if (oldIsApplyable != newIsApplyable) { 82 emit isApplyableChanged(newIsApplyable); 83 } 84 } 85 setTargetOffset(Okteta::Address targetOffset)86void GotoOffsetTool::setTargetOffset(Okteta::Address targetOffset) 87 { 88 const bool oldIsApplyable = isApplyable(); 89 90 mTargetOffset = targetOffset; 91 92 const bool newIsApplyable = isApplyable(); 93 if (oldIsApplyable != newIsApplyable) { 94 emit isApplyableChanged(newIsApplyable); 95 } 96 } 97 setIsRelative(bool isRelative)98void GotoOffsetTool::setIsRelative(bool isRelative) 99 { 100 const bool oldIsApplyable = isApplyable(); 101 102 mIsRelative = isRelative; 103 104 const bool newIsApplyable = isApplyable(); 105 if (oldIsApplyable != newIsApplyable) { 106 emit isApplyableChanged(newIsApplyable); 107 } 108 } 109 setIsSelectionToExtent(bool isSelectionToExtent)110void GotoOffsetTool::setIsSelectionToExtent(bool isSelectionToExtent) 111 { 112 const bool oldIsApplyable = isApplyable(); 113 114 mIsSelectionToExtent = isSelectionToExtent; 115 116 const bool newIsApplyable = isApplyable(); 117 if (oldIsApplyable != newIsApplyable) { 118 emit isApplyableChanged(newIsApplyable); 119 } 120 } 121 setIsBackwards(bool isBackwards)122void GotoOffsetTool::setIsBackwards(bool isBackwards) 123 { 124 const bool oldIsApplyable = isApplyable(); 125 126 mIsBackwards = isBackwards; 127 128 const bool newIsApplyable = isApplyable(); 129 if (oldIsApplyable != newIsApplyable) { 130 emit isApplyableChanged(newIsApplyable); 131 } 132 } 133 gotoOffset()134void GotoOffsetTool::gotoOffset() 135 { 136 const int newPosition = finalTargetOffset(); 137 138 if (mIsSelectionToExtent) { 139 mByteArrayView->setSelectionCursorPosition(newPosition); 140 } else { 141 mByteArrayView->setCursorPosition(newPosition); 142 } 143 mByteArrayView->setFocus(); 144 } 145 finalTargetOffset() const146int GotoOffsetTool::finalTargetOffset() const 147 { 148 const int newPosition = 149 (!mByteArrayView) ? -1 : 150 mIsRelative ? 151 (mIsBackwards ? mByteArrayView->cursorPosition() - mTargetOffset : 152 mByteArrayView->cursorPosition() + mTargetOffset) : 153 (mIsBackwards ? mByteArrayModel->size() - mTargetOffset : 154 mTargetOffset); 155 156 return newPosition; 157 } 158 onContentsChanged()159void GotoOffsetTool::onContentsChanged() 160 { 161 // TODO: find status before content changed, e.g. by caching 162 emit isUsableChanged(isUsable()); 163 } 164 165 } 166