1 /*
2 This file is part of the Okteta Kasten module, made within the KDE community.
3
4 SPDX-FileCopyrightText: 2007-2009, 2012 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 "stringsextracttool.hpp"
10
11 // lib
12 #include "extractstringsjob.hpp"
13 // Okteta Kasten gui
14 #include <Kasten/Okteta/ByteArrayView>
15 // Okteta Kasten core
16 #include <Kasten/Okteta/ByteArrayDocument>
17 // Okteta core
18 #include <Okteta/CharCodec>
19 #include <Okteta/AbstractByteArrayModel>
20 #include <Okteta/ArrayChangeMetricsList>
21 // KF
22 #include <KLocalizedString>
23 // Qt
24 #include <QApplication>
25
26 namespace Kasten {
27
28 static constexpr int DefaultMinLength = 3;
29
StringsExtractTool()30 StringsExtractTool::StringsExtractTool()
31 : mExtractedStringsUptodate(false)
32 , mSourceByteArrayModelUptodate(false)
33 , mMinLength(DefaultMinLength)
34 {
35 setObjectName(QStringLiteral("Strings"));
36 }
37
38 StringsExtractTool::~StringsExtractTool() = default;
39
isApplyable() const40 bool StringsExtractTool::isApplyable() const
41 {
42 return (mByteArrayModel && mByteArrayView && mByteArrayView->hasSelectedData() && mMinLength > 0);
43 }
44
canHighlightString() const45 bool StringsExtractTool::canHighlightString() const
46 {
47 return (mSourceByteArrayModel == mByteArrayModel
48 && mByteArrayView && mSourceByteArrayModelUptodate);
49 }
50
title() const51 QString StringsExtractTool::title() const { return i18nc("@title:window of the tool to extract strings", "Strings"); }
52
53 // TODO: add model with offset and string
54 // doubleclick moves cursor to offset
55 // filter für Suche, inkl. Regulärausdrücke
56 // groß/kleinschreibung
57 // voll strings, auch mit Leerzeichen
setTargetModel(AbstractModel * model)58 void StringsExtractTool::setTargetModel(AbstractModel* model)
59 {
60 if (mByteArrayView) {
61 mByteArrayView->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(mByteArrayView, &ByteArrayView::selectedDataChanged,
72 this, &StringsExtractTool::onSelectionChanged);
73
74 // if strings are from same model, adapt offsetcoding
75 if (mSourceByteArrayModel == mByteArrayModel) {
76 connect(mByteArrayView, &ByteArrayView::offsetCodingChanged,
77 this, &StringsExtractTool::offsetCodingChanged);
78 }
79 }
80
81 // TODO: if there is no view, there is nothing to extract.
82 // or this could be the view where we got the strings from and it did not change
83 checkUptoDate();
84 emit uptodateChanged(mExtractedStringsUptodate);
85 emit isApplyableChanged(isApplyable());
86 emit canHighlightStringChanged(canHighlightString());
87 if (mSourceByteArrayModel == mByteArrayModel && mByteArrayView) {
88 emit offsetCodingChanged(mByteArrayView->offsetCoding());
89 }
90 }
91
offsetCoding() const92 int StringsExtractTool::offsetCoding() const { return (mByteArrayView ? mByteArrayView->offsetCoding() : 0); }
93
setMinLength(int minLength)94 void StringsExtractTool::setMinLength(int minLength)
95 {
96 mMinLength = minLength;
97 checkUptoDate();
98 emit uptodateChanged(mExtractedStringsUptodate);
99 }
100
checkUptoDate()101 void StringsExtractTool::checkUptoDate()
102 {
103 mExtractedStringsUptodate =
104 (mSourceByteArrayModel == mByteArrayModel
105 && mByteArrayView && mSourceSelection == mByteArrayView->selection()
106 && mSourceMinLength == mMinLength
107 && mSourceByteArrayModelUptodate);
108 }
109
markString(int stringId)110 void StringsExtractTool::markString(int stringId)
111 {
112 if (mSourceByteArrayView != mByteArrayView) {
113 if (mSourceByteArrayView) {
114 mSourceByteArrayView->disconnect(this);
115 }
116 mSourceByteArrayView = mByteArrayView;
117 connect(mSourceByteArrayView, &ByteArrayView::destroyed,
118 this, &StringsExtractTool::onSourceViewDestroyed);
119 }
120 const ContainedString& containedString = mContainedStringList.at(stringId);
121 const Okteta::Address offset = containedString.offset();
122 const int length = containedString.string().length();
123 const Okteta::AddressRange markingRange = Okteta::AddressRange::fromWidth(offset, length);
124 mSourceByteArrayView->setMarking(markingRange, true);
125 }
126
unmarkString()127 void StringsExtractTool::unmarkString()
128 {
129 // TODO: marked region is property of document, not view?
130 if (mSourceByteArrayView) {
131 mSourceByteArrayView->setMarking(Okteta::AddressRange());
132 }
133 }
134
onSelectionChanged()135 void StringsExtractTool::onSelectionChanged()
136 {
137 // TODO: could be quicker using the selection data
138 checkUptoDate();
139 emit uptodateChanged(mExtractedStringsUptodate);
140 emit isApplyableChanged(isApplyable());
141 }
142
onSourceChanged()143 void StringsExtractTool::onSourceChanged()
144 {
145 mExtractedStringsUptodate = false;
146 mSourceByteArrayModelUptodate = false;
147 emit uptodateChanged(false);
148 emit canHighlightStringChanged(false);
149 }
150
onSourceDestroyed()151 void StringsExtractTool::onSourceDestroyed()
152 {
153 mSourceByteArrayModel = nullptr;
154 onSourceChanged();
155 }
156
onSourceViewDestroyed()157 void StringsExtractTool::onSourceViewDestroyed()
158 {
159 mSourceByteArrayView = nullptr;
160 }
161
162 // TODO: use TextByteArrayAnalyzer
extractStrings()163 void StringsExtractTool::extractStrings()
164 {
165 // forget old string source
166 if (mSourceByteArrayModel) {
167 mSourceByteArrayModel->disconnect(this);
168 }
169
170 QApplication::setOverrideCursor(Qt::WaitCursor);
171
172 Okteta::CharCodec* charCodec = Okteta::CharCodec::createCodec(mByteArrayView->charCodingName());
173 ExtractStringsJob* extractStringsJob =
174 new ExtractStringsJob(mByteArrayModel, mByteArrayView->selection(), charCodec, mMinLength,
175 &mContainedStringList);
176 extractStringsJob->exec();
177 delete charCodec;
178
179 QApplication::restoreOverrideCursor();
180
181 // remember new string source
182 mSourceByteArrayModel = mByteArrayModel;
183 mSourceSelection = mByteArrayView->selection();
184 mSourceMinLength = mMinLength;
185 connect(mSourceByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged,
186 this, &StringsExtractTool::onSourceChanged);
187 connect(mSourceByteArrayModel, &Okteta::AbstractByteArrayModel::destroyed,
188 this, &StringsExtractTool::onSourceDestroyed);
189 connect(mByteArrayView, &ByteArrayView::offsetCodingChanged,
190 this, &StringsExtractTool::offsetCodingChanged);
191
192 mExtractedStringsUptodate = true;
193 mSourceByteArrayModelUptodate = true;
194 emit uptodateChanged(true);
195 emit canHighlightStringChanged(true);
196 emit offsetCodingChanged(mByteArrayView->offsetCoding());
197 }
198
199 }
200