diff --git a/README.packagers b/README.packagers new file mode 100644 index 00000000..5705f576 --- /dev/null +++ b/README.packagers @@ -0,0 +1,59 @@ +PACKAGING RECOMMENDATIONS +------------------------- + +You might want to create 4 basic sub-packages from a build of the Okteta +sources with all features enabled, besides the devel-packages. + + +1. Okteta libraries for QWidget-based hex editing widgets + +LibOktetaCore and LibOktetaGui provide classes to have hex editing/viewing +QWidgets in Qt-based applications, similar to what is possible with QTextEdit +& QTextDocument. +Supplemented with a Qt Designer plugin for the Okteta widgets. + +Proposed package description: "Hex editor/viewer QWidgets libraries" + + +2. Kasten libraries + +Kasten is a WIP higher-level framework for composable document-centric +applications. LibKastenCore, LibKastenGui & LibKastenControllers are the +generic libraries. Due to its development state its still part of Okteta +sources and not used in other published software AFAIK. Except for KDevelop, +whose hex editor plugin is done using the Okteta Kasten libraries and +therefore also Kasten libraries. + +So for now it makes sense to simply bundle both the generic Kasten libraries +with the Okteta specific Kasten libraries, LibOktetaKastenCore, +LibOktetaKastenGui, & LibOktetaKastenControllers. + +All the data files for the Structures tool belong also to this, as well as the +s-m-i extension file. + +Known public user of these libs: +* KDevelop for the hex editor plugin + +Proposed package description: "High-level hex editor/viewer framework libraries" +Needs: 1.) + + +3. Okteta app + +The actual hex editor program itself. + +Proposed package description: "Editor for the raw data of files" +(please fix ancient package descriptions "editor for binary files" as this a bit wrongly limiting) +Needs: 1.) 2.) +(does _not_ use 4,) + + +4. KParts plugin + +The oktetapart is a plugin for the KParts system. While KParts usage having +declined in Qt5/KF5 era, at least Krusader makes explicit use of the plugin, +other KParts software can get it when requesting a viewer for the MIME/media +type application/octet-stream. + +Proposed package description: "Hex editing component for KParts" +Needs: 1.) 2.) diff --git a/core/codecs/textcharcodec.cpp b/core/codecs/textcharcodec.cpp index 687615aa..94f5c3e5 100644 --- a/core/codecs/textcharcodec.cpp +++ b/core/codecs/textcharcodec.cpp @@ -1,257 +1,257 @@ /* This file is part of the Okteta Core library, made within the KDE community. Copyright 2004,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "textcharcodec.hpp" // lib #include -// KF5 +// KF #include // Qt #include namespace Okteta { // static const char QTextCodecWhiteSpace = 63; static constexpr struct EncodingData { CharCoding encodingId; const char* name; } encodingDataList[] = { { ISO8859_1Encoding, "ISO-8859-1" }, { ISO8859_2Encoding, "ISO-8859-2" }, { ISO8859_3Encoding, "ISO-8859-3" }, { ISO8859_4Encoding, "ISO-8859-4" }, { ISO8859_5Encoding, "ISO-8859-5" }, { ISO8859_6Encoding, "ISO-8859-6" }, { ISO8859_7Encoding, "ISO-8859-7" }, { ISO8859_8Encoding, "ISO-8859-8" }, { ISO8859_8_IEncoding, "ISO-8859-8-I" }, { ISO8859_9Encoding, "ISO-8859-9" }, { ISO8859_10Encoding, "ISO-8859-10" }, { ISO8859_11Encoding, "TIS-620" }, // was: ISO-8859-11 { ISO8859_13Encoding, "ISO-8859-13" }, { ISO8859_14Encoding, "ISO-8859-14" }, { ISO8859_15Encoding, "ISO-8859-15" }, { ISO8859_16Encoding, "ISO-8859-16" }, { CP1250Encoding, "windows-1250" }, { CP1251Encoding, "windows-1251" }, { CP1252Encoding, "windows-1252" }, { CP1253Encoding, "windows-1253" }, { CP1254Encoding, "windows-1254" }, { CP1255Encoding, "windows-1255" }, { CP1256Encoding, "windows-1256" }, { CP1257Encoding, "windows-1257" }, { CP1258Encoding, "windows-1258" }, { IBM850Encoding, "IBM850" }, { IBM866Encoding, "IBM866" }, { IBM874Encoding, "IBM874" }, { KOI8_REncoding, "KOI8-R" }, { KOI8_UEncoding, "KOI8-U" } }; // TODO: WS2 static bool is8Bit(QTextCodec* codec) { bool result = false; const QByteArray& codecName = codec->name(); for (auto& encodingData : encodingDataList) { if (qstrcmp(codecName, encodingData.name) == 0) { result = true; break; } } return result; } static QTextCodec* createLatin1() { return KCharsets::charsets()->codecForName(QLatin1String(encodingDataList[0].name)); } /* heuristic seems to be doomed :( static bool is8Bit( QTextCodec *Codec ) { bool Result = true; // first test different for 0 unsigned char c[4]; c[0] = 0; c[1] = c[2] = c[3] = 230; QString S = Codec->toUnicode( (const char*)&c,4 ); int Length = 1; QCString CS = Codec->fromUnicode( S, Length ); //qCDebug(LOG_OKTETA_CORE) << Codec->name() << " "< 0 ) Result = false; // test if all chars survive the recoding else do { ++c[0]; S = Codec->toUnicode( (const char*)&c,4 ); Length = 1; CS = Codec->fromUnicode( S, Length ); //qCDebug(LOG_OKTETA_CORE) << Codec->name() << " "<"<availableEncodingNames(); for( QStringList::ConstIterator it = CharSets.begin(); it != CharSets.end(); ++it ) { bool Found = true; QTextCodec* Codec = KCharsets::charsets()->codecForName( *it, Found ); if( Found && is8Bit(Codec) ) CodecNames.append( QString::fromLatin1(Codec->name()) ); } } return CodecNames; } QString TextCharCodec::nameOfEncoding( CharCoding _char ) { TextCharCodec *Codec = 0; const char* N = 0; for( unsigned int i=0; icodecForName(codecName, isOk); if (isOk) { isOk = is8Bit(codec); } return isOk ? new TextCharCodec(codec) : nullptr; } const QStringList& TextCharCodec::codecNames() { static QStringList textCodecNames; // first call? if (textCodecNames.isEmpty()) { KCharsets* charsets = KCharsets::charsets(); for (auto& encodingData : encodingDataList) { bool isCodecFound = false; const QString codecName = QString::fromLatin1(encodingData.name); QTextCodec* codec = charsets->codecForName(codecName, isCodecFound); if (isCodecFound) { textCodecNames.append(QString::fromLatin1(codec->name())); } } } return textCodecNames; } TextCharCodec::TextCharCodec(QTextCodec* textCodec) : mCodec(textCodec) , mDecoder(textCodec->makeDecoder()) , mEncoder(textCodec->makeEncoder()) { } TextCharCodec::~TextCharCodec() { delete mDecoder; delete mEncoder; } bool TextCharCodec::canEncode(const QChar& _char) const { return mCodec->canEncode(_char); } bool TextCharCodec::encode(Byte* byte, const QChar& _char) const { if (!mCodec->canEncode(_char)) { // TODO: do we really need the codec? return false; } const QByteArray encoded = mEncoder->fromUnicode(QString(_char)); if (encoded.size() > 0) { *byte = encoded.at(0); return true; } return false; } Character TextCharCodec::decode(Byte byte) const { // QTextCodecs "use this codepoint when input data cannot be represented in Unicode." (Qt docs) constexpr QChar replacementChar = QChar(QChar::ReplacementCharacter); const QString string = mDecoder->toUnicode(reinterpret_cast(&byte), 1); const QChar qchar = string.at(0); const bool isDecoded = (qchar != replacementChar); return {qchar, !isDecoded}; } const QString& TextCharCodec::name() const { if (mName.isNull()) { mName = QString::fromLatin1(mCodec->name()); } return mName; } } diff --git a/core/piecetable/grouppiecetablechange.cpp b/core/piecetable/grouppiecetablechange.cpp index 7fbdf5da..fd93cdfc 100644 --- a/core/piecetable/grouppiecetablechange.cpp +++ b/core/piecetable/grouppiecetablechange.cpp @@ -1,180 +1,180 @@ /* This file is part of the Okteta Core library, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "grouppiecetablechange.hpp" // lib #include "piecetable.hpp" // #include #include -// KF5 +// KF #include namespace KPieceTable { GroupPieceTableChange::~GroupPieceTableChange() { while (!mChangeStack.isEmpty()) { delete mChangeStack.pop(); } } int GroupPieceTableChange::type() const { return GroupId; } QString GroupPieceTableChange::description() const { return mDescription; } bool GroupPieceTableChange::merge(const AbstractPieceTableChange* other) { bool result = false; if (!mChangeStack.isEmpty()) { result = mChangeStack.last()->merge(other); } return result; } AddressRange GroupPieceTableChange::apply(PieceTable* pieceTable) const { Q_UNUSED(pieceTable) // pieceTable->insert( mInsertOffset, mInsertLength, mStorageOffset ); return AddressRange();// ( mInsertOffset, pieceTable->size()-1 ); } AddressRange GroupPieceTableChange::revert(PieceTable* pieceTable) const { Q_UNUSED(pieceTable) // const int oldLast = pieceTable->size() - 1; // pieceTable->remove( AddressRange::fromWidth(mInsertOffset,mInsertLength) ); return AddressRange();// ( mInsertOffset, oldLast ); } ArrayChangeMetrics GroupPieceTableChange::metrics() const { return ArrayChangeMetrics::asReplacement(0, 0, 0); } bool GroupPieceTableChange::appendChange(AbstractPieceTableChange* change) { #if 0 // chop unapplied changes if (mAppliedChangesCount < mChangeStack.count()) { // hide baseindex if needed if (mBaseBeforeChangeIndex > mAppliedChangesCount) { mBaseBeforeChangeIndex = -1; } do { AbstractPieceTableChange* droppedChange = mChangeStack.pop(); delete droppedChange; } while (mAppliedChangesCount < mChangeStack.count()); } #endif mAppliedChangesDataSize += change->dataSize(); bool isNotMerged = true; if (mTryToMergeAppendedChange && mAppliedChangesCount > 0) { isNotMerged = !mChangeStack.top()->merge(change); } else { mTryToMergeAppendedChange = true; } if (isNotMerged) { mChangeStack.push(change); ++mAppliedChangesCount; } else { delete change; } return isNotMerged; } AddressRangeList GroupPieceTableChange::applyGroup(PieceTable* pieceTable) const { AddressRangeList result; for (const AbstractPieceTableChange* change : mChangeStack) { if (change->type() == AbstractPieceTableChange::GroupId) { const auto* groupChange = static_cast(change); const AddressRangeList changedRangeList = groupChange->applyGroup(pieceTable); result.addAddressRangeList(changedRangeList); } else { result.append(change->apply(pieceTable)); } } return result; } AddressRangeList GroupPieceTableChange::revertGroup(PieceTable* pieceTable) const { AddressRangeList result; QStack::ConstIterator it = mChangeStack.end(); while (it != mChangeStack.begin()) { --it; AbstractPieceTableChange* change = *it; if (change->type() == AbstractPieceTableChange::GroupId) { const auto* groupChange = static_cast(change); const AddressRangeList changedRangeList = groupChange->revertGroup(pieceTable); result.addAddressRangeList(changedRangeList); } else { result.append(change->revert(pieceTable)); } } return result; } ArrayChangeMetricsList GroupPieceTableChange::groupMetrics(bool reverted) const { ArrayChangeMetricsList result; for (const AbstractPieceTableChange* change : mChangeStack) { if (change->type() == AbstractPieceTableChange::GroupId) { const auto* groupChange = static_cast(change); const ArrayChangeMetricsList metricsList = groupChange->groupMetrics(reverted); result += metricsList; } else { ArrayChangeMetrics changeMetrics = change->metrics(); if (reverted) { changeMetrics.revert(); } result.append(changeMetrics); } } return result; } Size GroupPieceTableChange::dataSize() const { return mAppliedChangesDataSize; } } diff --git a/core/piecetable/insertpiecetablechange.cpp b/core/piecetable/insertpiecetablechange.cpp index 273916b9..e247c039 100644 --- a/core/piecetable/insertpiecetablechange.cpp +++ b/core/piecetable/insertpiecetablechange.cpp @@ -1,83 +1,83 @@ /* This file is part of the Okteta Core library, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "insertpiecetablechange.hpp" // lib #include "piecetable.hpp" // #include -// KF5 +// KF #include namespace KPieceTable { InsertPieceTableChange::~InsertPieceTableChange() = default; int InsertPieceTableChange::type() const { return InsertId; } QString InsertPieceTableChange::description() const { return i18nc("name of the change", "Insert"); } Address InsertPieceTableChange::storageOffset() const { return mStorageOffset; } bool InsertPieceTableChange::merge(const AbstractPieceTableChange* other) { // TODO: remove me again after synching solved // return false; bool result = false; if (other->type() == InsertId) { const auto* otherInsertChange = static_cast(other); if (mInsertOffset + mInsertLength == otherInsertChange->mInsertOffset) { mInsertLength += otherInsertChange->mInsertLength; result = true; } } return result; } AddressRange InsertPieceTableChange::apply(PieceTable* pieceTable) const { pieceTable->insert(mInsertOffset, mInsertLength, mStorageOffset); return AddressRange(mInsertOffset, pieceTable->size() - 1); } AddressRange InsertPieceTableChange::revert(PieceTable* pieceTable) const { const Address oldLast = pieceTable->size() - 1; pieceTable->remove(AddressRange::fromWidth(mInsertOffset, mInsertLength)); return AddressRange(mInsertOffset, oldLast); } ArrayChangeMetrics InsertPieceTableChange::metrics() const { return ArrayChangeMetrics::asReplacement(mInsertOffset, 0, mInsertLength); } Size InsertPieceTableChange::dataSize() const { return mInsertLength; } } diff --git a/core/piecetable/removepiecetablechange.cpp b/core/piecetable/removepiecetablechange.cpp index 4450b221..9baf5ddc 100644 --- a/core/piecetable/removepiecetablechange.cpp +++ b/core/piecetable/removepiecetablechange.cpp @@ -1,89 +1,89 @@ /* This file is part of the Okteta Core library, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "removepiecetablechange.hpp" // lib #include "piecetable.hpp" // #include -// KF5 +// KF #include namespace KPieceTable { RemovePieceTableChange::~RemovePieceTableChange() = default; int RemovePieceTableChange::type() const { return RemoveId; } QString RemovePieceTableChange::description() const { return i18nc("name of the change", "Remove"); } bool RemovePieceTableChange::merge(const AbstractPieceTableChange* other) { // TODO: remove me again after synching solved // return false; bool result = false; if (other->type() == RemoveId) { const auto* otherRemoveChange = static_cast(other); // other removed at the same start? if (mRemoveRange.start() == otherRemoveChange->mRemoveRange.start()) { mRemoveRange.moveEndBy(otherRemoveChange->mRemoveRange.width()); mRemovedPieces.append(otherRemoveChange->mRemovedPieces); result = true; } // other removed before? else if (otherRemoveChange->mRemoveRange.nextBehindEnd() == mRemoveRange.start()) { mRemoveRange.setStart(otherRemoveChange->mRemoveRange.start()); mRemovedPieces.prepend(otherRemoveChange->mRemovedPieces); result = true; } } return result; } AddressRange RemovePieceTableChange::apply(PieceTable* pieceTable) const { const Address oldLast = pieceTable->size() - 1; pieceTable->remove(mRemoveRange); return AddressRange(mRemoveRange.start(), oldLast); } AddressRange RemovePieceTableChange::revert(PieceTable* pieceTable) const { pieceTable->insert(mRemoveRange.start(), mRemovedPieces); return AddressRange(mRemoveRange.start(), pieceTable->size() - 1); } ArrayChangeMetrics RemovePieceTableChange::metrics() const { return ArrayChangeMetrics::asReplacement(mRemoveRange.start(), mRemoveRange.width(), 0); } } diff --git a/core/piecetable/replacepiecetablechange.cpp b/core/piecetable/replacepiecetablechange.cpp index 818a2859..5efe23d8 100644 --- a/core/piecetable/replacepiecetablechange.cpp +++ b/core/piecetable/replacepiecetablechange.cpp @@ -1,100 +1,100 @@ /* This file is part of the Okteta Core library, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "replacepiecetablechange.hpp" // lib #include "piecetable.hpp" // #include -// KF5 +// KF #include namespace KPieceTable { ReplacePieceTableChange::~ReplacePieceTableChange() = default; int ReplacePieceTableChange::type() const { return ReplaceId; } QString ReplacePieceTableChange::description() const { return i18nc("name of the change", "Replace"); } Address ReplacePieceTableChange::storageOffset() const { return mStorageOffset; } bool ReplacePieceTableChange::merge(const AbstractPieceTableChange* other) { // TODO: remove me again after synching solved // return false; bool result = false; if (other->type() == ReplaceId) { const auto* otherReplaceChange = static_cast(other); // other replaced after? if (mRemoveRange.start() + mInsertLength == otherReplaceChange->mRemoveRange.start()) { mRemoveRange.moveEndBy(otherReplaceChange->mRemoveRange.width()); mInsertLength += otherReplaceChange->mInsertLength; mRemovedPieces.append(otherReplaceChange->mRemovedPieces); result = true; } // other replaced before would be two swapped ranges in the change buffer, if this ever needed/wanted? } return result; } AddressRange ReplacePieceTableChange::apply(PieceTable* pieceTable) const { const Size oldSize = pieceTable->size(); pieceTable->replace(mRemoveRange, mInsertLength, mStorageOffset); const Size newSize = pieceTable->size(); const Address lastChanged = (newSize == oldSize) ? mRemoveRange.end() : (newSize > oldSize) ? newSize - 1 : oldSize - 1; return AddressRange(mRemoveRange.start(), lastChanged); } AddressRange ReplacePieceTableChange::revert(PieceTable* pieceTable) const { const Size oldSize = pieceTable->size(); const AddressRange insertedSection = AddressRange::fromWidth(mRemoveRange.start(), mInsertLength); pieceTable->replace(insertedSection, mRemovedPieces); const Size newSize = pieceTable->size(); const Address lastChanged = (newSize == oldSize) ? insertedSection.end() : (newSize > oldSize) ? newSize - 1 : oldSize - 1; return AddressRange(mRemoveRange.start(), lastChanged); } ArrayChangeMetrics ReplacePieceTableChange::metrics() const { return ArrayChangeMetrics::asReplacement(mRemoveRange.start(), mRemoveRange.width(), mInsertLength); } Size ReplacePieceTableChange::dataSize() const { return mInsertLength; } } diff --git a/core/piecetable/swaprangespiecetablechange.cpp b/core/piecetable/swaprangespiecetablechange.cpp index 9c4fd8ac..19ea4182 100644 --- a/core/piecetable/swaprangespiecetablechange.cpp +++ b/core/piecetable/swaprangespiecetablechange.cpp @@ -1,62 +1,62 @@ /* This file is part of the Okteta Core library, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "swaprangespiecetablechange.hpp" // lib #include "piecetable.hpp" // #include -// KF5 +// KF #include namespace KPieceTable { SwapRangesPieceTableChange::~SwapRangesPieceTableChange() = default; int SwapRangesPieceTableChange::type() const { return SwapRangesId; } QString SwapRangesPieceTableChange::description() const { return i18nc("name of the change", "Swap Ranges"); } AddressRange SwapRangesPieceTableChange::apply(PieceTable* pieceTable) const { pieceTable->swap(mFirstStart, mSecondRange); return AddressRange(mFirstStart, mSecondRange.end()); } AddressRange SwapRangesPieceTableChange::revert(PieceTable* pieceTable) const { pieceTable->swap(mFirstStart, AddressRange(mFirstStart + mSecondRange.width(), mSecondRange.end())); return AddressRange(mFirstStart, mSecondRange.end()); } ArrayChangeMetrics SwapRangesPieceTableChange::metrics() const { return ArrayChangeMetrics::asSwapping(mFirstStart, mSecondRange.start(), mSecondRange.width()); } } diff --git a/core/tests/charcodectest.cpp b/core/tests/charcodectest.cpp index f7101496..80896167 100644 --- a/core/tests/charcodectest.cpp +++ b/core/tests/charcodectest.cpp @@ -1,94 +1,94 @@ /* This file is part of the Okteta Core library, made within the KDE community. Copyright 2006,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "charcodectest.hpp" // test object #include // lib #include -// KF5 +// KF #include namespace Okteta { //---------------------------------------------------------------------------- Tests ----- void CharCodecTest::testCreateCodec_data() { QTest::addColumn("codecName"); for (const QString& codecName : CharCodec::codecNames()) { QTest::newRow(codecName.toLatin1().constData()) << codecName; } } void CharCodecTest::testCreateCodec() { QFETCH(QString, codecName); CharCodec* codec = CharCodec::createCodec(codecName); QVERIFY(codec != nullptr); QCOMPARE(codec->name(), codecName); delete codec; } void CharCodecTest::testEncodeDecode_data() { QTest::addColumn("codecName"); QTest::addColumn("byteValue"); for (const QString& codecName : CharCodec::codecNames()) { for (int i = 0; i < 256; ++i) { const QString rowTitle = codecName + QStringLiteral(" - %1").arg(i); QTest::newRow(rowTitle.toLatin1().constData()) << codecName << i; } } } void CharCodecTest::testEncodeDecode() { QFETCH(QString, codecName); QFETCH(int, byteValue); CharCodec* codec = CharCodec::createCodec(codecName); // current assumption: the mapping of chars to byte values is biunique for all used charsets const Byte byte = Byte(byteValue); Character character = codec->decode(byte); if (!character.isUndefined()) { QVERIFY(codec->canEncode(character)); Byte encodedByte; const bool encodeSuccess = codec->encode(&encodedByte, character); QVERIFY(encodeSuccess); QCOMPARE(encodedByte, byte); } delete codec; } } QTEST_GUILESS_MAIN(Okteta::CharCodecTest) diff --git a/core/tests/textcharcodectest.cpp b/core/tests/textcharcodectest.cpp index b2e19548..2ccc555f 100644 --- a/core/tests/textcharcodectest.cpp +++ b/core/tests/textcharcodectest.cpp @@ -1,70 +1,70 @@ /* This file is part of the Okteta Core library, made within the KDE community. Copyright 2006,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "textcharcodectest.hpp" // test object #include -// KF5 +// KF #include namespace Okteta { //---------------------------------------------------------------------------- Tests ----- void TextCharCodecTest::testCreateCodec_data() { QTest::addColumn("codecName"); for (const QString& codecName : TextCharCodec::codecNames()) { QTest::newRow(codecName.toLatin1().constData()) << codecName; } } void TextCharCodecTest::testCreateCodec() { QFETCH(QString, codecName); CharCodec* codec = TextCharCodec::createCodec(codecName); QVERIFY(codec != nullptr); QCOMPARE(codec->name(), codecName); delete codec; } void TextCharCodecTest::testCreateLocalCodec() { TextCharCodec* codec = TextCharCodec::createLocalCodec(); QVERIFY(codec != nullptr); delete codec; } void TextCharCodecTest::testCreateNonexistingCodec() { TextCharCodec* codec = TextCharCodec::createCodec(QStringLiteral("NonexistingCode")); QVERIFY(codec == nullptr); } } QTEST_GUILESS_MAIN(Okteta::TextCharCodecTest) diff --git a/gui/abstractbytearraycolumnrenderer_p.cpp b/gui/abstractbytearraycolumnrenderer_p.cpp index e348d979..5de88713 100644 --- a/gui/abstractbytearraycolumnrenderer_p.cpp +++ b/gui/abstractbytearraycolumnrenderer_p.cpp @@ -1,789 +1,789 @@ /* This file is part of the Okteta Gui library, made within the KDE community. Copyright 2003,2007-2009,2019 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "abstractbytearraycolumnrenderer_p.hpp" // lib #include "oktetagui.hpp" #include "bytearraytableranges.hpp" #include "bytearraytablecursor.hpp" #include "bytearraytablelayout.hpp" #include "helper.hpp" // lib #include // Okteta core #include #include #include -// KF5 +// KF #include // Qt #include #include namespace Okteta { void AbstractByteArrayColumnRendererPrivate::set(AbstractByteArrayModel* byteArrayModel) { mByteArrayModel = byteArrayModel; mBookmarks = qobject_cast(byteArrayModel); } void AbstractByteArrayColumnRendererPrivate::resetXBuffer() { delete [] mLinePosLeftPixelX; delete [] mLinePosRightPixelX; mLastLinePos = mLayout->noOfBytesPerLine() - 1; mLinePosLeftPixelX = new PixelX[mLastLinePos + 1]; mLinePosRightPixelX = new PixelX[mLastLinePos + 1]; if (mLinePosLeftPixelX) { recalcX(); } } void AbstractByteArrayColumnRendererPrivate::setFontMetrics(const QFontMetrics& fontMetrics) { mFontMetrics = fontMetrics; mDigitBaseLine = fontMetrics.ascent(); mDigitWidth = fontMetrics.maxWidth(); // recalculate depend sizes recalcByteWidth(); if (mLinePosLeftPixelX) { recalcX(); } } bool AbstractByteArrayColumnRendererPrivate::setSpacing(PixelX byteSpacingWidth, int NoGB, PixelX groupSpacingWidth) { // no changes? if (mByteSpacingWidth == byteSpacingWidth && mNoOfGroupedBytes == NoGB && mGroupSpacingWidth == groupSpacingWidth) { return false; } mByteSpacingWidth = byteSpacingWidth; mNoOfGroupedBytes = NoGB; mGroupSpacingWidth = groupSpacingWidth; // recalculate depend sizes if (mLinePosLeftPixelX) { recalcX(); } return true; } bool AbstractByteArrayColumnRendererPrivate::setByteSpacingWidth(PixelX byteSpacingWidth) { // no changes? if (mByteSpacingWidth == byteSpacingWidth) { return false; } mByteSpacingWidth = byteSpacingWidth; // recalculate depend sizes if (mLinePosLeftPixelX) { recalcX(); } return true; } bool AbstractByteArrayColumnRendererPrivate::setNoOfGroupedBytes(int NoGB) { // no changes? if (mNoOfGroupedBytes == NoGB) { return false; } mNoOfGroupedBytes = NoGB; if (mLinePosLeftPixelX) { recalcX(); } return true; } bool AbstractByteArrayColumnRendererPrivate::setGroupSpacingWidth(PixelX groupSpacingWidth) { // no changes? if (mGroupSpacingWidth == groupSpacingWidth) { return false; } mGroupSpacingWidth = groupSpacingWidth; // recalculate depend sizes if (mLinePosLeftPixelX) { recalcX(); } return true; } void AbstractByteArrayColumnRendererPrivate::recalcByteWidth() { setByteWidth(mDigitWidth); } void AbstractByteArrayColumnRendererPrivate::recalcX() { Q_Q(AbstractByteArrayColumnRenderer); mSpacingTrigger = noOfGroupedBytes() > 0 ? noOfGroupedBytes() - 1 : mLastLinePos + 1; // last ensures to never trigger the spacing PixelX newWidth = 0; Size groupedBytes = 0; PixelX* PX = mLinePosLeftPixelX; PixelX* PRX = mLinePosRightPixelX; LinePosition p = 0; for (; p <= mLastLinePos; ++PX, ++PRX, ++p, ++groupedBytes) { *PX = newWidth; newWidth += mByteWidth; *PRX = newWidth - 1; // is there a space behind the actual byte (if it is not the last)? if (groupedBytes == mSpacingTrigger) { newWidth += mGroupSpacingWidth; groupedBytes = -1; } else { newWidth += mByteSpacingWidth; } } q->setWidth(mLinePosRightPixelX[mLastLinePos] + 1); } // TODO: why are inlined functions not available as symbols when defined before their use // TODO: works not precisely for the byte rects but includes spacing and left and right /*inline*/ LinePosition AbstractByteArrayColumnRendererPrivate::linePositionOfX(PixelX PX) const { Q_Q(const AbstractByteArrayColumnRenderer); if (!mLinePosLeftPixelX) { return NoByteFound; } // translate PX -= q->x(); // search backwards for the first byte that is equalleft to x for (LinePosition p = mLastLinePos; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= PX) { return p; } } return 0; // NoByteFound; } LinePosition AbstractByteArrayColumnRendererPrivate::magneticLinePositionOfX(PixelX PX) const { Q_Q(const AbstractByteArrayColumnRenderer); if (!mLinePosLeftPixelX) { return NoByteFound; } // translate PX -= q->x(); // search backwards for the first byte that is equalleft to x for (LinePosition p = mLastLinePos; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= PX) { // are we close to the right? if (mLinePosRightPixelX[p] - PX < mDigitWidth / 2) { // TODO: perhaps cache also the middle xpos's ++p; } return p; } } return 0; // NoByteFound; } LinePositionRange AbstractByteArrayColumnRendererPrivate::linePositionsOfX(PixelX PX, PixelX PW) const { Q_Q(const AbstractByteArrayColumnRenderer); if (!mLinePosLeftPixelX) { return LinePositionRange(); } // translate PX -= q->x(); const PixelX PRX = PX + PW - 1; LinePositionRange positions; // search backwards for the first byte that is equalleft to x for (LinePosition p = mLastLinePos; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= PRX) { positions.setEnd(p); for (; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= PX) { positions.setStart(p); break; } } break; } } return positions; } PixelX AbstractByteArrayColumnRendererPrivate::xOfLinePosition(LinePosition linePosition) const { Q_Q(const AbstractByteArrayColumnRenderer); return q->x() + (mLinePosLeftPixelX ? mLinePosLeftPixelX[linePosition] : 0); } PixelX AbstractByteArrayColumnRendererPrivate::rightXOfLinePosition(LinePosition linePosition) const { Q_Q(const AbstractByteArrayColumnRenderer); return q->x() + (mLinePosRightPixelX ? mLinePosRightPixelX[linePosition] : 0); } LinePosition AbstractByteArrayColumnRendererPrivate::linePositionOfColumnX(PixelX PX) const { if (!mLinePosLeftPixelX) { return NoByteFound; } // search backwards for the first byte that is equalleft to x for (LinePosition p = mLastLinePos; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= PX) { return p; } } return 0; // NoByteFound; } LinePositionRange AbstractByteArrayColumnRendererPrivate::linePositionsOfColumnXs(PixelX pixelX, PixelX pixelWidth) const { if (!mLinePosLeftPixelX) { return LinePositionRange(); } const PixelX rightPixelX = pixelX + pixelWidth - 1; LinePositionRange positions; // search backwards for the first byte that is equalleft to x for (LinePosition p = mLastLinePos; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= rightPixelX) { const LinePosition endPos = p; positions.setEnd(p); for (p = 0; p <= endPos; ++p) { if (mLinePosRightPixelX[p] >= pixelX) { positions.setStart(p); break; } } break; } } return positions; } PixelX AbstractByteArrayColumnRendererPrivate::columnXOfLinePosition(LinePosition linePosition) const { return mLinePosLeftPixelX ? mLinePosLeftPixelX[linePosition] : 0; } PixelX AbstractByteArrayColumnRendererPrivate::columnRightXOfLinePosition(LinePosition linePosition) const { return mLinePosRightPixelX ? mLinePosRightPixelX[linePosition] : 0; } PixelXRange AbstractByteArrayColumnRendererPrivate::xsOfLinePositionsInclSpaces(const LinePositionRange& linePositions) const { const PixelX x = (linePositions.start() > 0) ? rightXOfLinePosition(linePositions.nextBeforeStart()) + 1 : xOfLinePosition(linePositions.start()); const PixelX rightX = (linePositions.end() < mLastLinePos) ? xOfLinePosition(linePositions.nextBehindEnd()) - 1 : rightXOfLinePosition(linePositions.end()); return PixelXRange(x, rightX); } PixelXRange AbstractByteArrayColumnRendererPrivate::columnXsOfLinePositionsInclSpaces(const LinePositionRange& linePositions) const { const PixelX x = (linePositions.start() > 0) ? columnRightXOfLinePosition(linePositions.nextBeforeStart()) + 1 : columnXOfLinePosition(linePositions.start()); const PixelX rightX = (linePositions.end() < mLastLinePos) ? columnXOfLinePosition(linePositions.nextBehindEnd()) - 1 : columnRightXOfLinePosition(linePositions.end()); return PixelXRange(x, rightX); } QRect AbstractByteArrayColumnRendererPrivate::byteRect(const Coord& coord) const { Q_Q(const AbstractByteArrayColumnRenderer); const PixelY lineHeight = q->lineHeight(); const int x = xOfLinePosition(coord.pos()); const int y = lineHeight * coord.line(); const int w = mByteWidth; const int h = lineHeight; const QPoint point(x, y); const QSize size(w, h); const QRect result(point, size); return result; } void AbstractByteArrayColumnRendererPrivate::prepareRendering(const PixelXRange& _Xs) { Q_Q(AbstractByteArrayColumnRenderer); PixelXRange Xs(_Xs); q->restrictToXSpan(&Xs); // translate Xs.moveBy(-q->x()); // store the values mRenderX = Xs.start(); mRenderWidth = Xs.width(); // get line linePositions to paint mRenderLinePositions = linePositionsOfColumnXs(mRenderX, mRenderWidth); } void AbstractByteArrayColumnRendererPrivate::renderFirstLine(QPainter* painter, const PixelXRange& Xs, Line firstLineIndex) { prepareRendering(Xs); mRenderLine = firstLineIndex; renderLinePositions(painter, mRenderLine++, mRenderLinePositions); } void AbstractByteArrayColumnRendererPrivate::renderNextLine(QPainter* painter) { renderLinePositions(painter, mRenderLine++, mRenderLinePositions); } void AbstractByteArrayColumnRendererPrivate::renderLinePositions(QPainter* painter, Line lineIndex, const LinePositionRange& _linePositions) { // clear background const unsigned int blankFlag = (_linePositions.start() != 0 ? StartsBefore : 0) | (_linePositions.end() != mLastLinePos ? EndsLater : 0); const QBrush& backgroundBrush = mStylist->palette().brush(QPalette::Base); renderRange(painter, backgroundBrush, _linePositions, blankFlag); // no bytes to paint? if (!mLayout->hasContent(lineIndex)) { return; } // Go through the lines TODO: handle first and last line more effeciently // check for leading and trailing spaces const LinePositionRange existingLinePositions = mLayout->linePositions(lineIndex); LinePositionRange linePositions = _linePositions; linePositions.restrictTo(existingLinePositions); const int firstLinePosition = linePositions.start(); // check for leading and trailing spaces AddressRange byteIndizes = AddressRange::fromWidth(mLayout->indexAtCoord(Coord(linePositions.start(), lineIndex)), linePositions.width()); unsigned int selectionFlag = 0; unsigned int markingFlag = 0; AddressRange selectedRange; AddressRange markedRange; bool hasMarking = mRanges->hasMarking(); bool hasSelection = mRanges->hasSelection(); // qCDebug(LOG_OKTETA_GUI) << QString("painting linePositions (painter%1-%2L%3): ").arg(linePositions.start()).arg(linePositions.end()).arg(lineIndex) // <createBookmarksConstIterator(); if (bit.findNextFrom(byteIndex)) { nextBookmarkOffset = bit.next().offset(); } } const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::View); // paint all the bytes affected for (LinePosition linePosition = linePositions.start(); linePosition <= linePositions.end(); ++linePosition, ++byteIndex) { const PixelX x = columnXOfLinePosition(linePosition); // draw the byte painter->translate(x, 0); if (byteIndex == nextBookmarkOffset) { renderBookmark(painter, colorScheme.background(KColorScheme::NeutralBackground)); nextBookmarkOffset = bit.hasNext() ? bit.next().offset() : -1;// TODO )&& ( bit->offset() <= LastIndex ); } const Byte byte = mByteArrayModel->byte(byteIndex); const Character byteChar = mCharCodec->decode(byte); const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); const QColor& charColor = brush.color();// palette.text().color();//colorForChar(byteChar) renderByteText(painter, byte, byteChar, charColor); painter->translate(-x, 0); } } void AbstractByteArrayColumnRendererPrivate::renderSelection(QPainter* painter, const LinePositionRange& linePositions, Address byteIndex, int flag) { BookmarksConstIterator bit; Address nextBookmarkOffset = -1; const bool hasBookmarks = (mBookmarks != nullptr); if (hasBookmarks) { bit = mBookmarks->createBookmarksConstIterator(); if (bit.findNextFrom(byteIndex)) { nextBookmarkOffset = bit.next().offset(); } } const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::Selection); renderRange(painter, colorScheme.background(), linePositions, flag); // paint all the bytes affected for (LinePosition linePosition = linePositions.start(); linePosition <= linePositions.end(); ++linePosition, ++byteIndex) { const PixelX x = columnXOfLinePosition(linePosition); // draw the byte painter->translate(x, 0); if (byteIndex == nextBookmarkOffset) { renderBookmark(painter, colorScheme.background(KColorScheme::NeutralBackground)); nextBookmarkOffset = bit.hasNext() ? bit.next().offset() : -1;// TODO )&& ( bit->offset() <= LastIndex ); } const Byte byte = mByteArrayModel->byte(byteIndex); const Character byteChar = mCharCodec->decode(byte); const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); const QColor& charColor = brush.color(); renderByteText(painter, byte, byteChar, charColor); painter->translate(-x, 0); } } void AbstractByteArrayColumnRendererPrivate::renderSelectionSpaceBehind(QPainter* painter, LinePosition linePosition) { const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::Selection); renderSpaceBehind(painter, colorScheme.background(), linePosition); } void AbstractByteArrayColumnRendererPrivate::renderMarking(QPainter* painter, const LinePositionRange& linePositions, Address byteIndex, int flag) { const QPalette& palette = mStylist->palette(); renderRange(painter, palette.text(), linePositions, flag); const QColor& baseColor = palette.base().color(); // paint all the bytes affected for (LinePosition p = linePositions.start(); p <= linePositions.end(); ++p, ++byteIndex) { const PixelX x = columnXOfLinePosition(p); // draw the byte painter->translate(x, 0); const Byte byte = mByteArrayModel->byte(byteIndex); const Character byteChar = mCharCodec->decode(byte); renderByteText(painter, byte, byteChar, baseColor); painter->translate(-x, 0); } } void AbstractByteArrayColumnRendererPrivate::renderBookmark(QPainter* painter, const QBrush& brush) { Q_Q(AbstractByteArrayColumnRenderer); // TODO: think about how bookmarks should really be rendered painter->fillRect(1, 1, mByteWidth - 2, q->lineHeight() - 2, brush); } void AbstractByteArrayColumnRendererPrivate::renderRange(QPainter* painter, const QBrush& brush, const LinePositionRange& linePositions, int flag) { Q_Q(AbstractByteArrayColumnRenderer); const PixelX rangeX = (flag & StartsBefore) ? columnRightXOfLinePosition(linePositions.nextBeforeStart()) + 1 : columnXOfLinePosition(linePositions.start()); const PixelX rangeW = ((flag & EndsLater) ? columnXOfLinePosition(linePositions.nextBehindEnd()) : columnRightXOfLinePosition(linePositions.end()) + 1) - rangeX; painter->fillRect(rangeX, 0, rangeW, q->lineHeight(), brush); } void AbstractByteArrayColumnRendererPrivate::renderSpaceBehind(QPainter* painter, const QBrush& brush, LinePosition linePosition) { Q_Q(AbstractByteArrayColumnRenderer); const PixelX rangeX = columnRightXOfLinePosition(linePosition) + 1; const PixelX rangeW = columnXOfLinePosition(linePosition + 1) - rangeX; painter->fillRect(rangeX, 0, rangeW, q->lineHeight(), brush); } void AbstractByteArrayColumnRendererPrivate::renderByte(QPainter* painter, Address byteIndex) { Q_Q(AbstractByteArrayColumnRenderer); const Byte byte = (byteIndex > -1) ? mByteArrayModel->byte(byteIndex) : EmptyByte; const Character byteChar = mCharCodec->decode(byte); const QPalette& palette = mStylist->palette(); KColorScheme::ColorSet colorSet = KColorScheme::View; if (byteIndex > -1) { if (mRanges->selectionIncludes(byteIndex)) { colorSet = KColorScheme::Selection; } // else if( mRanges->markingIncludes(byteIndex) ) // { // charColor = palette.base().color(); // brush = palette.text(); // } } KColorScheme colorScheme(palette.currentColorGroup(), colorSet); const QBrush backgroundBrush = colorScheme.background(); painter->fillRect(0, 0, mByteWidth, q->lineHeight(), backgroundBrush); if (mBookmarks && mBookmarks->containsBookmarkFor(byteIndex)) { renderBookmark(painter, colorScheme.background(KColorScheme::NeutralBackground)); } if (byteIndex > -1) { const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); const QColor& charColor = brush.color(); renderByteText(painter, byte, byteChar, charColor); } } // TODO: think about making framestyle a enum of a class ByteArrayColumnCursor void AbstractByteArrayColumnRendererPrivate::renderFramedByte(QPainter* painter, Address byteIndex, AbstractByteArrayColumnRenderer::FrameStyle frameStyle) { Q_Q(AbstractByteArrayColumnRenderer); renderByte(painter, byteIndex); const Byte byte = (byteIndex > -1) ? mByteArrayModel->byte(byteIndex) : EmptyByte; const Character byteChar = mCharCodec->decode(byte); const bool isInSelection = (byteIndex > -1 && mRanges->selectionIncludes(byteIndex)); const KColorScheme::ColorSet colorSet = isInSelection ? KColorScheme::Selection : KColorScheme::View; const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), colorSet); const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); QPen pen(brush.color()); pen.setJoinStyle(Qt::MiterJoin); painter->setPen(pen); if (frameStyle == AbstractByteArrayColumnRenderer::Frame) { painter->drawRect(QRectF(0.5, 0.5, mByteWidth - 1, q->lineHeight() - 1)); } else if (frameStyle == AbstractByteArrayColumnRenderer::Left) { painter->drawLine(QPointF(0.5, 0.5), QPointF(0.5, q->lineHeight() - 0.5)); } else { painter->drawLine(QPointF(mByteWidth - 0.5, 0.5), QPointF(mByteWidth - 0.5, q->lineHeight() - 0.5)); } } void AbstractByteArrayColumnRendererPrivate::renderCursor(QPainter* painter, Address byteIndex) { Q_Q(AbstractByteArrayColumnRenderer); const Byte byte = (byteIndex > -1) ? mByteArrayModel->byte(byteIndex) : EmptyByte; const Character byteChar = mCharCodec->decode(byte); const bool isInSelection = (byteIndex > -1 && mRanges->selectionIncludes(byteIndex)); const KColorScheme::ColorSet colorSet = isInSelection ? KColorScheme::Selection : KColorScheme::View; const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), colorSet); const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); painter->fillRect(0, 0, mByteWidth, q->lineHeight(), brush); } bool AbstractByteArrayColumnRendererPrivate::getNextSelectedAddressRange(AddressRange* _selection, unsigned int* _flag, const AddressRange& range) const { const AddressRange* overlappingSelectedSection = mRanges->firstOverlappingSelection(range); if (!overlappingSelectedSection) { return false; } AddressRange selectedRange = *overlappingSelectedSection; unsigned int flag = 0; // does selectedRange start before asked range? if (selectedRange.startsBefore(range)) { selectedRange.setStart(range.start()); flag |= StartsBefore; } // does selectedRange go on behind asked range? if (selectedRange.endsBehind(range)) { selectedRange.setEnd(range.end()); flag |= EndsLater; } *_selection = selectedRange; *_flag = flag; return true; } bool AbstractByteArrayColumnRendererPrivate::getNextMarkedAddressRange(AddressRange* _markedSection, unsigned int* _flag, const AddressRange& range) const { const AddressRange* overlappingMarkedSection = mRanges->overlappingMarking(range); if (!overlappingMarkedSection) { return false; } unsigned int flag = 0; AddressRange markedRange = *overlappingMarkedSection; if (markedRange.startsBefore(range)) { markedRange.setStart(range.start()); flag |= StartsBefore; } if (markedRange.endsBehind(range)) { markedRange.setEnd(range.end()); flag |= EndsLater; } *_markedSection = markedRange; *_flag = flag; return true; } } diff --git a/gui/bytearrayrowcolumnrenderer_p.cpp b/gui/bytearrayrowcolumnrenderer_p.cpp index de1d3f64..2b6a211e 100644 --- a/gui/bytearrayrowcolumnrenderer_p.cpp +++ b/gui/bytearrayrowcolumnrenderer_p.cpp @@ -1,926 +1,926 @@ /* This file is part of the Okteta Gui library, made within the KDE community. Copyright 2008-2009,2019 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayrowcolumnrenderer_p.hpp" // lib #include "bytearraytableranges.hpp" #include "bytearraytablecursor.hpp" #include "bytearraytablelayout.hpp" #include "helper.hpp" // lib #include // Okteta core #include #include #include #include -// KF5 +// KF #include // Qt #include #include namespace Okteta { AbstractByteArrayView::CodingTypeId ByteArrayRowColumnRendererPrivate::codingIdofY(PixelY y) const { return (mVisibleCodings != AbstractByteArrayView::ValueAndCharCodings) ? (AbstractByteArrayView::CodingTypeId)mVisibleCodings : (y < mDigitHeight) ? AbstractByteArrayView::ValueCodingId : AbstractByteArrayView::CharCodingId; } PixelY ByteArrayRowColumnRendererPrivate::rowHeight() const { const int noOfCodings = (mVisibleCodings > 2) ? 2 : 1; return noOfCodings * mDigitHeight + DefaultRowSpacingHeight; } PixelY ByteArrayRowColumnRendererPrivate::yOfCodingId(AbstractByteArrayView::CodingTypeId codingId) const { PixelY result = (mVisibleCodings <= 2) ? 0 : (codingId == AbstractByteArrayView::ValueCodingId) ? 0 : mDigitHeight; return result; } void ByteArrayRowColumnRendererPrivate::set(AbstractByteArrayModel* byteArrayModel) { mByteArrayModel = byteArrayModel; mBookmarks = qobject_cast(byteArrayModel); } void ByteArrayRowColumnRendererPrivate::resetXBuffer() { delete [] mLinePosLeftPixelX; delete [] mLinePosRightPixelX; mLastLinePos = mLayout->noOfBytesPerLine() - 1; mLinePosLeftPixelX = new PixelX[mLastLinePos + 1]; mLinePosRightPixelX = new PixelX[mLastLinePos + 1]; if (mLinePosLeftPixelX) { recalcX(); } } void ByteArrayRowColumnRendererPrivate::setVisibleCodings(int visibleCodings) { mVisibleCodings = (AbstractByteArrayView::CodingTypes)(visibleCodings); } void ByteArrayRowColumnRendererPrivate::setFontMetrics(const QFontMetrics& fontMetrics) { mFontMetrics = fontMetrics; mDigitBaseLine = fontMetrics.ascent(); mDigitHeight = fontMetrics.height(); mDigitWidth = fontMetrics.maxWidth(); // recalculate depend sizes recalcByteWidth(); if (mLinePosLeftPixelX) { recalcX(); } } bool ByteArrayRowColumnRendererPrivate::setSpacing(PixelX byteSpacingWidth, Size NoGB, PixelX groupSpacingWidth) { // no changes? if (mByteSpacingWidth == byteSpacingWidth && mNoOfGroupedBytes == NoGB && mGroupSpacingWidth == groupSpacingWidth) { return false; } mByteSpacingWidth = byteSpacingWidth; mNoOfGroupedBytes = NoGB; mGroupSpacingWidth = groupSpacingWidth; // recalculate depend sizes if (mLinePosLeftPixelX) { recalcX(); } return true; } bool ByteArrayRowColumnRendererPrivate::setByteSpacingWidth(PixelX byteSpacingWidth) { // no changes? if (mByteSpacingWidth == byteSpacingWidth) { return false; } mByteSpacingWidth = byteSpacingWidth; // recalculate depend sizes if (mLinePosLeftPixelX) { recalcX(); } return true; } bool ByteArrayRowColumnRendererPrivate::setNoOfGroupedBytes(Size NoGB) { // no changes? if (mNoOfGroupedBytes == NoGB) { return false; } mNoOfGroupedBytes = NoGB; if (mLinePosLeftPixelX) { recalcX(); } return true; } bool ByteArrayRowColumnRendererPrivate::setGroupSpacingWidth(PixelX groupSpacingWidth) { // no changes? if (mGroupSpacingWidth == groupSpacingWidth) { return false; } mGroupSpacingWidth = groupSpacingWidth; // recalculate depend sizes if (mLinePosLeftPixelX) { recalcX(); } return true; } void ByteArrayRowColumnRendererPrivate::setValueCodec(ValueCoding valueCoding, const ValueCodec* valueCodec) { mValueCoding = valueCoding; mValueCodec = valueCodec; mDecodedByteText.resize(mValueCodec->encodingWidth()); // recalculate depend sizes recalcByteWidth(); if (mLinePosLeftPixelX) { recalcX(); } } bool ByteArrayRowColumnRendererPrivate::setBinaryGapWidth(PixelX binaryGapWidth) { // no changes? if (mBinaryGapWidth == binaryGapWidth) { return false; } mBinaryGapWidth = binaryGapWidth; // recalculate depend sizes recalcByteWidth(); if (mLinePosLeftPixelX) { recalcX(); } return true; } void ByteArrayRowColumnRendererPrivate::recalcByteWidth() { // use 0 as reference, using a fixed font should always yield same width mValueCodec->encode(&mDecodedByteText, 0, Byte(0)); if (mValueCoding == BinaryCoding) { const int binaryHalfWidth = mFontMetrics.width(mDecodedByteText.left(4)); mBinaryHalfOffset = binaryHalfWidth + mBinaryGapWidth; mByteWidth = mBinaryHalfOffset + binaryHalfWidth; } else { mByteWidth = mFontMetrics.width(mDecodedByteText); } } // perhaps sometimes there will be a grammar void ByteArrayRowColumnRendererPrivate::renderEditedByte(QPainter* painter, Byte byte, const QString& editBuffer) { const Character byteChar = mCharCodec->decode(byte); const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::View); const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); painter->fillRect(0, 0, byteWidth(), mDigitHeight, brush); const QBrush backgroundBrush = colorScheme.background(); const QColor& charColor = backgroundBrush.color(); renderCode(painter, editBuffer, charColor); } void ByteArrayRowColumnRendererPrivate::renderByteText(QPainter* painter, Byte byte, Character byteChar, int codings, const QColor& color) const { PixelY charBaseLine = mDigitBaseLine; if (codings & AbstractByteArrayView::ValueCodingId) { mValueCodec->encode(&mDecodedByteText, 0, byte); renderCode(painter, mDecodedByteText, color); charBaseLine += mDigitHeight; } if (codings & AbstractByteArrayView::CharCodingId) { // turn into a drawable String const QString text(byteChar.isUndefined() ? Character(mUndefinedChar) : !(mShowingNonprinting || byteChar.isPrint()) ? Character(mSubstituteChar) : byteChar); painter->setPen(color); painter->drawText(0, charBaseLine, text); } } void ByteArrayRowColumnRendererPrivate::renderCode(QPainter* painter, const QString& code, const QColor& color) const { painter->setPen(color); if (mValueCoding == BinaryCoding) { // leave a gap in the middle painter->drawText(0, mDigitBaseLine, code.left(4)); painter->drawText(mBinaryHalfOffset, mDigitBaseLine, code.right(4)); } else { painter->drawText(0, mDigitBaseLine, code); } } void ByteArrayRowColumnRendererPrivate::recalcX() { Q_Q(ByteArrayRowColumnRenderer); mSpacingTrigger = noOfGroupedBytes() > 0 ? noOfGroupedBytes() - 1 : mLastLinePos + 1; // last ensures to never trigger the spacing PixelX newWidth = 0; Size groupedBytes = 0; PixelX* PX = mLinePosLeftPixelX; PixelX* PRX = mLinePosRightPixelX; LinePosition p = 0; for (; p <= mLastLinePos; ++PX, ++PRX, ++p, ++groupedBytes) { *PX = newWidth; newWidth += mByteWidth; *PRX = newWidth - 1; // is there a space behind the actual byte (if it is not the last)? if (groupedBytes == mSpacingTrigger) { newWidth += mGroupSpacingWidth; groupedBytes = -1; } else { newWidth += mByteSpacingWidth; } } q->setWidth(mLinePosRightPixelX[mLastLinePos] + 1); } // TODO: why are inlined functions not available as symbols when defined before their use // TODO: works not precisely for the byte rects but includes spacing and left and right /*inline*/ LinePosition ByteArrayRowColumnRendererPrivate::linePositionOfX(PixelX PX) const { Q_Q(const ByteArrayRowColumnRenderer); if (!mLinePosLeftPixelX) { return NoByteFound; } // translate PX -= q->x(); // search backwards for the first byte that is equalleft to x for (LinePosition p = mLastLinePos; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= PX) { return p; } } return 0; // NoByteFound; } LinePosition ByteArrayRowColumnRendererPrivate::magneticLinePositionOfX(PixelX PX) const { Q_Q(const ByteArrayRowColumnRenderer); if (!mLinePosLeftPixelX) { return NoByteFound; } // translate PX -= q->x(); // search backwards for the first byte that is equalleft to x for (LinePosition p = mLastLinePos; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= PX) { // are we close to the right? if (mLinePosRightPixelX[p] - PX < mDigitWidth / 2) { // TODO: perhaps cache also the middle xpos's ++p; } return p; } } return 0; // NoByteFound; } LinePositionRange ByteArrayRowColumnRendererPrivate::linePositionsOfX(PixelX PX, PixelX PW) const { Q_Q(const ByteArrayRowColumnRenderer); if (!mLinePosLeftPixelX) { return LinePositionRange(); } // translate PX -= q->x(); const PixelX PRX = PX + PW - 1; LinePositionRange positions; // search backwards for the first byte that is equalleft to x for (LinePosition p = mLastLinePos; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= PRX) { positions.setEnd(p); for (; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= PX) { positions.setStart(p); break; } } break; } } return positions; } PixelX ByteArrayRowColumnRendererPrivate::xOfLinePosition(LinePosition linePosition) const { Q_Q(const ByteArrayRowColumnRenderer); return q->x() + (mLinePosLeftPixelX ? mLinePosLeftPixelX[linePosition] : 0); } PixelX ByteArrayRowColumnRendererPrivate::rightXOfLinePosition(LinePosition linePosition) const { Q_Q(const ByteArrayRowColumnRenderer); return q->x() + (mLinePosRightPixelX ? mLinePosRightPixelX[linePosition] : 0); } LinePosition ByteArrayRowColumnRendererPrivate::linePositionOfColumnX(PixelX PX) const { if (!mLinePosLeftPixelX) { return NoByteFound; } // search backwards for the first byte that is equalleft to x for (LinePosition p = mLastLinePos; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= PX) { return p; } } return 0; // NoByteFound; } LinePositionRange ByteArrayRowColumnRendererPrivate::linePositionsOfColumnXs(PixelX pixelX, PixelX pixelWidth) const { if (!mLinePosLeftPixelX) { return LinePositionRange(); } const PixelX rightPixelX = pixelX + pixelWidth - 1; LinePositionRange positions; // search backwards for the first byte that is equalleft to x for (LinePosition p = mLastLinePos; p >= 0; --p) { if (mLinePosLeftPixelX[p] <= rightPixelX) { const LinePosition endPos = p; positions.setEnd(p); for (p = 0; p <= endPos; ++p) { if (mLinePosRightPixelX[p] >= pixelX) { positions.setStart(p); break; } } break; } } return positions; } PixelX ByteArrayRowColumnRendererPrivate::columnXOfLinePosition(LinePosition linePosition) const { return mLinePosLeftPixelX ? mLinePosLeftPixelX[linePosition] : 0; } PixelX ByteArrayRowColumnRendererPrivate::columnRightXOfLinePosition(LinePosition linePosition) const { return mLinePosRightPixelX ? mLinePosRightPixelX[linePosition] : 0; } PixelXRange ByteArrayRowColumnRendererPrivate::xsOfLinePositionsInclSpaces(const LinePositionRange& linePositions) const { const PixelX x = (linePositions.start() > 0) ? rightXOfLinePosition(linePositions.nextBeforeStart()) + 1 : xOfLinePosition(linePositions.start()); const PixelX rightX = (linePositions.end() < mLastLinePos) ? xOfLinePosition(linePositions.nextBehindEnd()) - 1 : rightXOfLinePosition(linePositions.end()); return PixelXRange(x, rightX); } PixelXRange ByteArrayRowColumnRendererPrivate::columnXsOfLinePositionsInclSpaces(const LinePositionRange& linePositions) const { const PixelX x = (linePositions.start() > 0) ? columnRightXOfLinePosition(linePositions.nextBeforeStart()) + 1 : columnXOfLinePosition(linePositions.start()); const PixelX rightX = (linePositions.end() < mLastLinePos) ? columnXOfLinePosition(linePositions.nextBehindEnd()) - 1 : columnRightXOfLinePosition(linePositions.end()); return PixelXRange(x, rightX); } QRect ByteArrayRowColumnRendererPrivate::byteRect(const Coord& coord) const { Q_Q(const ByteArrayRowColumnRenderer); const PixelY lineHeight = q->lineHeight(); const int x = xOfLinePosition(coord.pos()); const int y = lineHeight * coord.line(); const int w = mByteWidth; const int h = lineHeight; const QPoint point(x, y); const QSize size(w, h); const QRect result(point, size); return result; } QRect ByteArrayRowColumnRendererPrivate::byteRect(const Coord& coord, AbstractByteArrayView::CodingTypeId codingId) const { Q_Q(const ByteArrayRowColumnRenderer); const int x = xOfLinePosition(coord.pos()); const int y = q->lineHeight() * coord.line() + yOfCodingId(codingId); const int w = mByteWidth; const int h = mDigitHeight; const QPoint point(x, y); const QSize size(w, h); const QRect result(point, size); return result; } void ByteArrayRowColumnRendererPrivate::prepareRendering(const PixelXRange& _Xs) { Q_Q(ByteArrayRowColumnRenderer); PixelXRange Xs(_Xs); q->restrictToXSpan(&Xs); // translate Xs.moveBy(-q->x()); // store the values mRenderX = Xs.start(); mRenderWidth = Xs.width(); // get line linePositions to paint mRenderLinePositions = linePositionsOfColumnXs(mRenderX, mRenderWidth); } void ByteArrayRowColumnRendererPrivate::renderFirstLine(QPainter* painter, const PixelXRange& Xs, Line firstLineIndex) { prepareRendering(Xs); mRenderLine = firstLineIndex; renderLinePositions(painter, mRenderLine++, mRenderLinePositions); } void ByteArrayRowColumnRendererPrivate::renderNextLine(QPainter* painter) { renderLinePositions(painter, mRenderLine++, mRenderLinePositions); } void ByteArrayRowColumnRendererPrivate::renderLinePositions(QPainter* painter, Line lineIndex, const LinePositionRange& _linePositions) { // clear background const unsigned int blankFlag = (_linePositions.start() != 0 ? StartsBefore : 0) | (_linePositions.end() != mLastLinePos ? EndsLater : 0); const QBrush& backgroundBrush = mStylist->palette().brush(QPalette::Base); renderRange(painter, backgroundBrush, _linePositions, blankFlag); // no bytes to paint? if (!mLayout->hasContent(lineIndex)) { return; } // Go through the lines TODO: handle first and last line more effeciently // check for leading and trailing spaces const LinePositionRange existingLinePositions = mLayout->linePositions(lineIndex); LinePositionRange linePositions = _linePositions; linePositions.restrictTo(existingLinePositions); const int firstLinePosition = linePositions.start(); // check for leading and trailing spaces AddressRange byteIndizes = AddressRange::fromWidth(mLayout->indexAtCoord(Coord(linePositions.start(), lineIndex)), linePositions.width()); unsigned int selectionFlag = 0; unsigned int markingFlag = 0; AddressRange selectedRange; AddressRange markedRange; bool hasMarking = mRanges->hasMarking(); bool hasSelection = mRanges->hasSelection(); // qCDebug(LOG_OKTETA_GUI) << QString("painting linePositions (painter%1-%2L%3): ").arg(linePositions.start()).arg(linePositions.end()).arg(lineIndex) // <createBookmarksConstIterator(); if (bit.findNextFrom(byteIndex)) { nextBookmarkOffset = bit.next().offset(); } } const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::View); // paint all the bytes affected for (LinePosition linePosition = linePositions.start(); linePosition <= linePositions.end(); ++linePosition, ++byteIndex) { const PixelX x = columnXOfLinePosition(linePosition); // draw the byte painter->translate(x, 0); if (byteIndex == nextBookmarkOffset) { renderBookmark(painter, colorScheme.background(KColorScheme::NeutralBackground)); nextBookmarkOffset = bit.hasNext() ? bit.next().offset() : -1;// TODO )&& ( bit->offset() <= LastIndex ); } const Byte byte = mByteArrayModel->byte(byteIndex); const Character byteChar = mCharCodec->decode(byte); const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); const QColor& charColor = brush.color();// palette.text().color();//colorForChar(byteChar) renderByteText(painter, byte, byteChar, mVisibleCodings, charColor); painter->translate(-x, 0); } } void ByteArrayRowColumnRendererPrivate::renderSelection(QPainter* painter, const LinePositionRange& linePositions, Address byteIndex, int flag) { BookmarksConstIterator bit; Address nextBookmarkOffset = -1; const bool hasBookmarks = (mBookmarks != nullptr); if (hasBookmarks) { bit = mBookmarks->createBookmarksConstIterator(); if (bit.findNextFrom(byteIndex)) { nextBookmarkOffset = bit.next().offset(); } } const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::Selection); renderRange(painter, colorScheme.background(), linePositions, flag); // paint all the bytes affected for (LinePosition linePosition = linePositions.start(); linePosition <= linePositions.end(); ++linePosition, ++byteIndex) { const PixelX x = columnXOfLinePosition(linePosition); // draw the byte painter->translate(x, 0); if (byteIndex == nextBookmarkOffset) { renderBookmark(painter, colorScheme.background(KColorScheme::NeutralBackground)); nextBookmarkOffset = bit.hasNext() ? bit.next().offset() : -1;// TODO )&& ( bit->offset() <= LastIndex ); } const Byte byte = mByteArrayModel->byte(byteIndex); const Character byteChar = mCharCodec->decode(byte); const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); const QColor& charColor = brush.color(); renderByteText(painter, byte, byteChar, mVisibleCodings, charColor); painter->translate(-x, 0); } } void ByteArrayRowColumnRendererPrivate::renderSelectionSpaceBehind(QPainter* painter, LinePosition linePosition) { const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::Selection); renderSpaceBehind(painter, colorScheme.background(), linePosition); } void ByteArrayRowColumnRendererPrivate::renderMarking(QPainter* painter, const LinePositionRange& linePositions, Address byteIndex, int flag) { const QPalette& palette = mStylist->palette(); renderRange(painter, palette.text(), linePositions, flag); const QColor& baseColor = palette.base().color(); // paint all the bytes affected for (LinePosition p = linePositions.start(); p <= linePositions.end(); ++p, ++byteIndex) { const PixelX x = columnXOfLinePosition(p); // draw the byte painter->translate(x, 0); const Byte byte = mByteArrayModel->byte(byteIndex); const Character byteChar = mCharCodec->decode(byte); renderByteText(painter, byte, byteChar, mVisibleCodings, baseColor); painter->translate(-x, 0); } } void ByteArrayRowColumnRendererPrivate::renderBookmark(QPainter* painter, const QBrush& brush) { Q_Q(ByteArrayRowColumnRenderer); // TODO: think about how bookmarks should really be rendered painter->fillRect(1, 1, mByteWidth - 2, q->lineHeight() - 2, brush); } void ByteArrayRowColumnRendererPrivate::renderRange(QPainter* painter, const QBrush& brush, const LinePositionRange& linePositions, int flag) { Q_Q(ByteArrayRowColumnRenderer); const PixelX rangeX = (flag & StartsBefore) ? columnRightXOfLinePosition(linePositions.nextBeforeStart()) + 1 : columnXOfLinePosition(linePositions.start()); const PixelX rangeW = ((flag & EndsLater) ? columnXOfLinePosition(linePositions.nextBehindEnd()) : columnRightXOfLinePosition(linePositions.end()) + 1) - rangeX; painter->fillRect(rangeX, 0, rangeW, q->lineHeight(), brush); } void ByteArrayRowColumnRendererPrivate::renderSpaceBehind(QPainter* painter, const QBrush& brush, LinePosition linePosition) { Q_Q(ByteArrayRowColumnRenderer); const PixelX rangeX = columnRightXOfLinePosition(linePosition) + 1; const PixelX rangeW = columnXOfLinePosition(linePosition + 1) - rangeX; painter->fillRect(rangeX, 0, rangeW, q->lineHeight(), brush); } void ByteArrayRowColumnRendererPrivate::renderByte(QPainter* painter, Address byteIndex, AbstractByteArrayView::CodingTypeId codingId) { const Byte byte = (byteIndex > -1) ? mByteArrayModel->byte(byteIndex) : EmptyByte; const Character byteChar = mCharCodec->decode(byte); const QPalette& palette = mStylist->palette(); KColorScheme::ColorSet colorSet = KColorScheme::View; if (byteIndex > -1) { if (mRanges->selectionIncludes(byteIndex)) { colorSet = KColorScheme::Selection; } // else if( mRanges->markingIncludes(byteIndex) ) // { // charColor = palette.base().color(); // brush = palette.text(); // } } KColorScheme colorScheme(palette.currentColorGroup(), colorSet); const QBrush backgroundBrush = colorScheme.background(); painter->fillRect(0, 0, mByteWidth, mDigitHeight, backgroundBrush); if (mBookmarks && mBookmarks->containsBookmarkFor(byteIndex)) { const QBrush bookmarkBackgroundBrush = colorScheme.background(KColorScheme::NeutralBackground); painter->fillRect(1, 1, mByteWidth - 2, mDigitHeight - 2, bookmarkBackgroundBrush); } if (byteIndex > -1) { const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); const QColor& charColor = brush.color(); renderByteText(painter, byte, byteChar, codingId, charColor); } } // TODO: think about making framestyle a enum of a class ByteArrayColumnCursor void ByteArrayRowColumnRendererPrivate::renderFramedByte(QPainter* painter, Address byteIndex, AbstractByteArrayView::CodingTypeId codingId, ByteArrayRowColumnRenderer::FrameStyle frameStyle) { renderByte(painter, byteIndex, codingId); const Byte byte = (byteIndex > -1) ? mByteArrayModel->byte(byteIndex) : EmptyByte; const Character byteChar = mCharCodec->decode(byte); const bool isInSelection = (byteIndex > -1 && mRanges->selectionIncludes(byteIndex)); const KColorScheme::ColorSet colorSet = isInSelection ? KColorScheme::Selection : KColorScheme::View; const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), colorSet); const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); QPen pen(brush.color()); pen.setJoinStyle(Qt::MiterJoin); painter->setPen(pen); if (frameStyle == ByteArrayRowColumnRenderer::Frame) { painter->drawRect(QRectF(0.5, 0.5, mByteWidth - 1, mDigitHeight - 1)); } else if (frameStyle == ByteArrayRowColumnRenderer::Left) { painter->drawLine(QPointF(0.5, 0.5), QPointF(0.5, mDigitHeight - 0.5)); } else { painter->drawLine(QPointF(mByteWidth - 0.5, 0), QPointF(mByteWidth - 0.5, mDigitHeight - 0.5)); } } void ByteArrayRowColumnRendererPrivate::renderCursor(QPainter* painter, Address byteIndex, AbstractByteArrayView::CodingTypeId codingId) { Q_UNUSED(codingId) const Byte byte = (byteIndex > -1) ? mByteArrayModel->byte(byteIndex) : EmptyByte; const Character byteChar = mCharCodec->decode(byte); const bool isInSelection = (byteIndex > -1 && mRanges->selectionIncludes(byteIndex)); const KColorScheme::ColorSet colorSet = isInSelection ? KColorScheme::Selection : KColorScheme::View; const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), colorSet); const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); painter->fillRect(0, 0, mByteWidth, mDigitHeight, brush); } bool ByteArrayRowColumnRendererPrivate::getNextSelectedAddressRange(AddressRange* _selection, unsigned int* _flag, const AddressRange& range) const { const AddressRange* overlappingSelectedSection = mRanges->firstOverlappingSelection(range); if (!overlappingSelectedSection) { return false; } AddressRange selectedRange = *overlappingSelectedSection; unsigned int flag = 0; // does selectedRange start before asked range? if (selectedRange.startsBefore(range)) { selectedRange.setStart(range.start()); flag |= StartsBefore; } // does selectedRange go on behind asked range? if (selectedRange.endsBehind(range)) { selectedRange.setEnd(range.end()); flag |= EndsLater; } *_selection = selectedRange; *_flag = flag; return true; } bool ByteArrayRowColumnRendererPrivate::getNextMarkedAddressRange(AddressRange* _markedSection, unsigned int* _flag, const AddressRange& range) const { const AddressRange* overlappingMarkedSection = mRanges->overlappingMarking(range); if (!overlappingMarkedSection) { return false; } unsigned int flag = 0; AddressRange markedRange = *overlappingMarkedSection; if (markedRange.startsBefore(range)) { markedRange.setStart(range.start()); flag |= StartsBefore; } if (markedRange.endsBehind(range)) { markedRange.setEnd(range.end()); flag |= EndsLater; } *_markedSection = markedRange; *_flag = flag; return true; } } diff --git a/gui/controller/valueeditor.cpp b/gui/controller/valueeditor.cpp index 45f6626b..1fa9340b 100644 --- a/gui/controller/valueeditor.cpp +++ b/gui/controller/valueeditor.cpp @@ -1,299 +1,299 @@ /* This file is part of the Okteta Gui library, made within the KDE community. Copyright 2004,2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "valueeditor.hpp" // lib #include #include // Okteta core #include #include #include -// KF5 +// KF #include // Qt #include namespace Okteta { ValueEditor::ValueEditor(ByteArrayTableCursor* cursor, AbstractByteArrayView* view, AbstractController* parent) : AbstractEditor(cursor, view, parent) , mInEditMode(false) , mEditModeByInsert(false) { } ValueEditor::~ValueEditor() = default; void ValueEditor::adaptToValueCodecChange() { const uint newCodingWidth = mView->valueCodec()->encodingWidth(); mValueString.resize(newCodingWidth); } void ValueEditor::startEdit(const QString& description) { Q_ASSERT(!mInEditMode); Okteta::AbstractByteArrayModel* byteArrayModel = mView->byteArrayModel(); Okteta::ChangesDescribable* changesDescribable = qobject_cast(byteArrayModel); if (changesDescribable) { changesDescribable->openGroupedChange(description); } mInEditMode = true; } void ValueEditor::cancelEdit(bool undoChanges) { // Q_ASSERT( mInEditMode ); if (!mInEditMode) { return; } mInEditMode = false; if (undoChanges) { Okteta::AbstractByteArrayModel* byteArrayModel = mView->byteArrayModel(); Okteta::ChangesDescribable* changesDescribable = qobject_cast(byteArrayModel); // TODO: if !changesDescribable the changes need to be undone, too if (changesDescribable) { changesDescribable->cancelGroupedChange(); } } } void ValueEditor::finishEdit() { if (!mInEditMode) { return; } mInEditMode = false; Okteta::AbstractByteArrayModel* byteArrayModel = mView->byteArrayModel(); Okteta::ChangesDescribable* changesDescribable = qobject_cast(byteArrayModel); if (changesDescribable) { changesDescribable->closeGroupedChange(); } } bool ValueEditor::handleKeyPress(QKeyEvent* keyEvent) { bool keyUsed = true; // TODO: for now we don't touch it if there are selections if (!mView->hasSelectedData()) { // switch (keyEvent->key()) { case Qt::Key_Plus: doValueEditAction(IncValue); break; case Qt::Key_Minus: doValueEditAction(DecValue); break; case Qt::Key_Space: if (!mInEditMode) { keyUsed = false; break; } // fallthrough case Qt::Key_Enter: case Qt::Key_Return: doValueEditAction(mInEditMode ? LeaveValue : EnterValue); break; case Qt::Key_Escape: if (mInEditMode) { cancelEdit(); } else { keyUsed = false; } break; case Qt::Key_Backspace: if (mInEditMode) { doValueEditAction(ValueBackspace); } else { keyUsed = false; } break; default: { // is plain char? const QString text = keyEvent->text(); if (text.length() > 0 && (!(keyEvent->modifiers() & (Qt::CTRL | Qt::ALT | Qt::META)))) { const int input = text.at(0).toLatin1(); // no usable char? if (input < 32) { keyUsed = false; break; } const Okteta::ValueCodec* valueCodec = mView->valueCodec(); if (mInEditMode) { if (mInsertedDigitsCount < valueCodec->encodingWidth()) { doValueEditAction(ValueAppend, input); } } else { Byte inputValue = 0; // valid digit? if (valueCodec->appendDigit(&inputValue, input)) { if (mView->isOverwriteMode()) { doValueEditAction(ValueEdit, inputValue); } else { const Address index = mCursor->realIndex(); startEdit(i18nc("name of the change", "Insert")); if (mView->byteArrayModel()->insert(index, &inputValue, 1) > 0) { mEditModeByInsert = true; mOldValue = mEditValue = inputValue; mInsertedDigitsCount = 1; valueCodec->encode(&mValueString, 0, mEditValue); mCursor->gotoIndex(index); mView->ensureCursorVisible(); // mView->updateCursors(); emit mView->cursorPositionChanged(mCursor->realIndex()); } else { cancelEdit(); } } } } } else { keyUsed = false; } } } } else { keyUsed = false; } return keyUsed ? true : AbstractEditor::handleKeyPress(keyEvent); } void ValueEditor::doValueEditAction(ValueEditAction Action, int input) { const Okteta::ValueCodec* valueCodec = mView->valueCodec(); // we are not yet in edit mode? if (!mInEditMode) { const Address validIndex = mCursor->validIndex(); // no valid cursor position? if (validIndex == -1 || (!mView->isOverwriteMode() && input == -1) || mCursor->isBehind()) { return; } startEdit(i18nc("name of the change", "Replace")); mEditModeByInsert = false; // default, to be overwritten if so // save old value mOldValue = mEditValue = (unsigned char)mView->byteArrayModel()->byte(validIndex); mInsertedDigitsCount = valueCodec->encodingWidth(); } // Byte newValue = mEditValue; bool stayInEditMode = true; bool moveToNext = false; switch (Action) { case ValueEdit: newValue = input; mEditValue = newValue ^ 255; // force update mEditModeByInsert = true; mInsertedDigitsCount = 1; break; case ValueBackspace: if (mInsertedDigitsCount > 0) { if (newValue > 0) { valueCodec->removeLastDigit(&newValue); } --mInsertedDigitsCount; } break; case EnterValue: mEditValue ^= 255; // force update break; case IncValue: if (newValue < 255) { ++newValue; mInsertedDigitsCount = valueCodec->encodingWidth(); } break; case DecValue: if (newValue > 0) { --newValue; mInsertedDigitsCount = valueCodec->encodingWidth(); } break; case ValueAppend: if (valueCodec->appendDigit(&newValue, input)) { ++mInsertedDigitsCount; if (mEditModeByInsert && (newValue >= valueCodec->digitsFilledLimit() || mInsertedDigitsCount == valueCodec->encodingWidth())) { stayInEditMode = false; moveToNext = true; } } break; case LeaveValue: stayInEditMode = false; moveToNext = mEditModeByInsert; break; } // change happened? if (newValue != mEditValue) { // sync value mEditValue = newValue; valueCodec->encode(&mValueString, 0, mEditValue); mView->byteArrayModel()->replace(mCursor->index(), 1, &mEditValue, 1); } // mView->updateCursors(); if (!stayInEditMode) { mView->pauseCursor(); finishEdit(); if (moveToNext) { mCursor->gotoNextByte(); } mView->unpauseCursor(); if (moveToNext) { emit mView->cursorPositionChanged(mCursor->realIndex()); } } } } diff --git a/gui/helper.hpp b/gui/helper.hpp index a073edb4..3dab6f54 100644 --- a/gui/helper.hpp +++ b/gui/helper.hpp @@ -1,54 +1,54 @@ /* This file is part of the Okteta Gui library, made within the KDE community. Copyright 2003,2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef OKTETA_HELPER #define OKTETA_HELPER // Okteta core #include -// KF5 +// KF #include // Qt #include // temporary solution until syntax highlighting is implemented static inline QColor colorForChar(const Okteta::Character byteChar) { return byteChar.isUndefined() ? Qt::yellow : byteChar.isPunct() ? Qt::red : byteChar.isPrint() ? Qt::black : (byteChar == QLatin1Char(0x0A) || byteChar == QLatin1Char(0x0D)) ? Qt::darkCyan : Qt::blue; } static inline KColorScheme::ForegroundRole foregroundRoleForChar(const Okteta::Character byteChar) { return byteChar.isUndefined() ? KColorScheme::NegativeText : byteChar.isPunct() ? KColorScheme::InactiveText : byteChar.isPrint() ? KColorScheme::NormalText : (byteChar == QLatin1Char(0x0A) || byteChar == QLatin1Char(0x0D)) ? KColorScheme::VisitedText : KColorScheme::ActiveText; } #endif diff --git a/gui/valuebytearraycolumnrenderer_p.cpp b/gui/valuebytearraycolumnrenderer_p.cpp index 8d0875a2..c60965ea 100644 --- a/gui/valuebytearraycolumnrenderer_p.cpp +++ b/gui/valuebytearraycolumnrenderer_p.cpp @@ -1,125 +1,125 @@ /* This file is part of the Okteta Gui library, made within the KDE community. Copyright 2003,2008,2019 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "valuebytearraycolumnrenderer_p.hpp" // lib #include "helper.hpp" // lib #include // Okteta core #include #include -// KF5 +// KF #include // Qt #include namespace Okteta { void ValueByteArrayColumnRendererPrivate::setValueCodec(ValueCoding valueCoding, const ValueCodec* valueCodec) { mValueCoding = valueCoding; mValueCodec = valueCodec; mDecodedByteText.resize(mValueCodec->encodingWidth()); // recalculate depend sizes recalcByteWidth(); if (mLinePosLeftPixelX) { recalcX(); } } bool ValueByteArrayColumnRendererPrivate::setBinaryGapWidth(PixelX binaryGapWidth) { // no changes? if (mBinaryGapWidth == binaryGapWidth) { return false; } mBinaryGapWidth = binaryGapWidth; // recalculate depend sizes recalcByteWidth(); if (mLinePosLeftPixelX) { recalcX(); } return true; } void ValueByteArrayColumnRendererPrivate::recalcByteWidth() { // use 0 as reference, using a fixed font should always yield same width mValueCodec->encode(&mDecodedByteText, 0, Byte(0)); if (mValueCoding == BinaryCoding) { const int binaryHalfWidth = mFontMetrics.width(mDecodedByteText.left(4)); mBinaryHalfOffset = binaryHalfWidth + mBinaryGapWidth; setByteWidth(mBinaryHalfOffset + binaryHalfWidth); } else { setByteWidth(mFontMetrics.width(mDecodedByteText)); } } // perhaps sometimes there will be a grammar void ValueByteArrayColumnRendererPrivate::renderEditedByte(QPainter* painter, Byte byte, const QString& editBuffer) { Q_Q(ValueByteArrayColumnRenderer); const Character byteChar = mCharCodec->decode(byte); const QPalette& palette = mStylist->palette(); KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::View); const KColorScheme::ForegroundRole foregroundRole = mByteTypeColored ? foregroundRoleForChar(byteChar) : KColorScheme::NormalText; const QBrush brush = colorScheme.foreground(foregroundRole); painter->fillRect(0, 0, byteWidth(), q->lineHeight(), brush); const QBrush backgroundBrush = colorScheme.background(); const QColor& charColor = backgroundBrush.color(); renderCode(painter, editBuffer, charColor); } void ValueByteArrayColumnRendererPrivate::renderByteText(QPainter* painter, Byte byte, Character byteChar, const QColor& color) const { Q_UNUSED(byteChar) mValueCodec->encode(&mDecodedByteText, 0, byte); renderCode(painter, mDecodedByteText, color); } void ValueByteArrayColumnRendererPrivate::renderCode(QPainter* painter, const QString& code, const QColor& color) const { painter->setPen(color); if (mValueCoding == Okteta::BinaryCoding) { // leave a gap in the middle painter->drawText(0, mDigitBaseLine, code.left(4)); painter->drawText(mBinaryHalfOffset, mDigitBaseLine, code.right(4)); } else { painter->drawText(0, mDigitBaseLine, code); } } } diff --git a/kasten/controllers/document/info/documentinfotool.cpp b/kasten/controllers/document/info/documentinfotool.cpp index b06e8fa1..2b6e8f66 100644 --- a/kasten/controllers/document/info/documentinfotool.cpp +++ b/kasten/controllers/document/info/documentinfotool.cpp @@ -1,185 +1,185 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008,2010,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "documentinfotool.hpp" // lib #include "bytearraymodeliodevice.hpp" // Okteta Kasten core #include // Kasten core #include #include // Okteta core #include #include -// KF5 +// KF #include // Qt #include #include #include #include namespace Kasten { static constexpr int mimeTypeUpdateTimeInterval = 500; // msec DocumentInfoTool::DocumentInfoTool(DocumentSyncManager* syncManager) : mDocumentSyncManager(syncManager) , mMimeTypeUpdateTimer(new QTimer(this)) { setObjectName(QStringLiteral("DocumentInfo")); mMimeTypeUpdateTimer->setInterval(mimeTypeUpdateTimeInterval); mMimeTypeUpdateTimer->setSingleShot(true); connect(mMimeTypeUpdateTimer, &QTimer::timeout, this, &DocumentInfoTool::updateMimeType); } DocumentInfoTool::~DocumentInfoTool() = default; // TODO: file or document or ...? QString DocumentInfoTool::title() const { return i18nc("@title:window", "File Info"); } QString DocumentInfoTool::documentTitle() const { return mDocument ? mDocument->title() : QString(); } QString DocumentInfoTool::location() const { QString result; if (mDocument) { const QUrl url = mDocumentSyncManager->urlOf(mDocument); result = url.toDisplayString(QUrl::PrettyDecoded | QUrl::PreferLocalFile); } return result; } int DocumentInfoTool::documentSize() const { int documentSize = -1; if (mByteArrayModel) { documentSize = mByteArrayModel->size(); } return documentSize; } void DocumentInfoTool::setTargetModel(AbstractModel* model) { if (mSynchronizer) { mSynchronizer->disconnect(this); } if (mDocument) { mDocument->disconnect(this); } if (mByteArrayModel) { mByteArrayModel->disconnect(this); } mDocument = model ? model->findBaseModel() : nullptr; mByteArrayModel = mDocument ? mDocument->content() : nullptr; const bool hasDocument = (mDocument != nullptr); AbstractModelSynchronizer* synchronizer = nullptr; QString documentTitle; int documentSize = -1; if (hasDocument) { documentTitle = mDocument->title(); documentSize = mByteArrayModel->size(); synchronizer = mDocument->synchronizer(); connect(mDocument, &ByteArrayDocument::titleChanged, this, &DocumentInfoTool::documentTitleChanged); connect(mDocument, &ByteArrayDocument::synchronizerChanged, this, &DocumentInfoTool::onSynchronizerChanged); connect(mByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, this, &DocumentInfoTool::onContentsChanged); } onSynchronizerChanged(synchronizer); emit documentTitleChanged(documentTitle); emit documentSizeChanged(documentSize); } // TODO: should this be done in a worker thread, to not block the UI? void DocumentInfoTool::updateMimeType() { QMimeType currentMimeType; if (mDocument) { // TODO: also get file mode, if available, for findByNameAndContent() const QString filename = mDocumentSyncManager->urlOf(mDocument).fileName(); Okteta::ByteArrayModelIoDevice byteArrayModelIoDevice(mByteArrayModel); QMimeDatabase db; currentMimeType = filename.isEmpty() ? db.mimeTypeForData(&byteArrayModelIoDevice) : db.mimeTypeForFileNameAndData(filename, &byteArrayModelIoDevice); } if (mMimeType != currentMimeType) { mMimeType = currentMimeType; emit documentMimeTypeChanged(currentMimeType); } } void DocumentInfoTool::onContentsChanged() { if (!mMimeTypeUpdateTimer->isActive()) { mMimeTypeUpdateTimer->start(); } emit documentSizeChanged(mByteArrayModel->size()); } void DocumentInfoTool::onSynchronizerChanged(AbstractModelSynchronizer* synchronizer) { // do an instant update, no need to delay if (mMimeTypeUpdateTimer->isActive()) { mMimeTypeUpdateTimer->stop(); } updateMimeType(); if (mSynchronizer) { mSynchronizer->disconnect(this); } mSynchronizer = synchronizer; if (mSynchronizer) { connect(mSynchronizer, &AbstractModelSynchronizer::urlChanged, this, &DocumentInfoTool::onUrlChanged); } emit locationChanged(location()); } void DocumentInfoTool::onUrlChanged(const QUrl& url) { Q_UNUSED(url); emit locationChanged(location()); } } diff --git a/kasten/controllers/document/info/documentinfotoolviewfactory.cpp b/kasten/controllers/document/info/documentinfotoolviewfactory.cpp index 6841d678..6513d707 100644 --- a/kasten/controllers/document/info/documentinfotoolviewfactory.cpp +++ b/kasten/controllers/document/info/documentinfotoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2019 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "documentinfotoolviewfactory.hpp" // lib #include "documentinfotoolview.hpp" #include "documentinfotool.hpp" -// KF5 +// KF #include namespace Kasten { DocumentInfoToolViewFactory::DocumentInfoToolViewFactory() = default; DocumentInfoToolViewFactory::~DocumentInfoToolViewFactory() = default; QString DocumentInfoToolViewFactory::iconName() const { return QStringLiteral("documentinfo"); } QString DocumentInfoToolViewFactory::title() const { return i18nc("@title:window", "File Info"); } QString DocumentInfoToolViewFactory::id() const { return QStringLiteral("org.kde.okteta.DocumentInfoToolView"); } SidePosition DocumentInfoToolViewFactory::defaultPosition() const { return LeftSidePosition; } AbstractToolView* DocumentInfoToolViewFactory::create(AbstractTool* tool) const { return new DocumentInfoToolView(qobject_cast(tool)); } } diff --git a/kasten/controllers/document/info/documentinfoview.cpp b/kasten/controllers/document/info/documentinfoview.cpp index 337e28cb..739e3e17 100644 --- a/kasten/controllers/document/info/documentinfoview.cpp +++ b/kasten/controllers/document/info/documentinfoview.cpp @@ -1,192 +1,192 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "documentinfoview.hpp" // #include "documentinfotool.hpp" -// KF5 +// KF #include #include #include #include #include // Qt #include #include #include #include #include #include namespace Kasten { DocumentInfoView::DocumentInfoView(DocumentInfoTool* tool, QWidget* parent) : QWidget(parent) , mTool(tool) { auto* baseLayout = new QVBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); // icon mIconLabel = new QLabel(this); // int bsize = 66 + 2 * mIconLabel->style()->pixelMetric( QStyle::PM_ButtonMargin ); // mIconLabel->setFixedSize(bsize, bsize); mIconLabel->setFixedHeight(KIconLoader::SizeEnormous); mIconLabel->setMinimumWidth(KIconLoader::SizeEnormous); mIconLabel->setAlignment(Qt::AlignHCenter); baseLayout->addWidget(mIconLabel); // file label mDocumentTitleLabel = new QLabel(this); QFont font = mDocumentTitleLabel->font(); font.setBold(true); mDocumentTitleLabel->setFont(font); mDocumentTitleLabel->setAlignment(Qt::AlignHCenter); mDocumentTitleLabel->setWordWrap(true); mDocumentTitleLabel->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); baseLayout->addWidget(mDocumentTitleLabel); // separator KSeparator* separator = new KSeparator(Qt::Horizontal, this); baseLayout->addWidget(separator); // property grid auto* propertyGrid = new QGridLayout(); // unknown rows propertyGrid->setColumnStretch(0, 0); propertyGrid->setColumnStretch(1, 1); int currentPropertyRow = 0; // type property QLabel* label = new QLabel(i18n("Type:"), this); propertyGrid->addWidget(label, currentPropertyRow, 0, Qt::AlignRight); mMimeTypeLabel = new QLabel(QString(), this); propertyGrid->addWidget(mMimeTypeLabel, currentPropertyRow++, 1); // location property label = new QLabel(i18n("Location:"), this); propertyGrid->addWidget(label, currentPropertyRow, 0, Qt::AlignRight); mLocationLabel = new KSqueezedTextLabel(this); // force the layout direction to be always LTR mLocationLabel->setLayoutDirection(Qt::LeftToRight); // but if we are in RTL mode, align the text to the right // otherwise the text is on the wrong side of the dialog if (layoutDirection() == Qt::RightToLeft) { mLocationLabel->setAlignment(Qt::AlignRight); } // TODO: for some reason if building with enable_final flag the compiler sees // an ambiguous conversion without the explicit Qt::TextInteractionFlags(...) mLocationLabel->setTextInteractionFlags(Qt::TextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard)); propertyGrid->addWidget(mLocationLabel, currentPropertyRow++, 1); // size property label = new QLabel(i18n("Size:"), this); propertyGrid->addWidget(label, currentPropertyRow, 0, Qt::AlignRight); mSizeLabel = new QLabel(this); propertyGrid->addWidget(mSizeLabel, currentPropertyRow++, 1); #if 0 label = new QLabel(i18n("Created/Loaded:"), this); // TODO: make adjustable depending on document propertyGrid->addWidget(label, currentPropertyRow, 0, Qt::AlignRight); currentPropertyRow++; label = new QLabel(i18n("Last modified:"), this); propertyGrid->addWidget(label, currentPropertyRow, 0, Qt::AlignRight); currentPropertyRow++; label = new QLabel(i18n("Last synchronized:"), this); propertyGrid->addWidget(label, currentPropertyRow, 0, Qt::AlignRight); currentPropertyRow++; // last accessed from remote KDateTime dt;// = item.time(KFileItem::CreationTime); if (!dt.isNull()) { label = new QLabel(i18n("Created:"), this); propertyGrid->addWidget(label, currentPropertyRow, 0, Qt::AlignRight); label = new QLabel(KLocale::global()->formatDateTime(dt), this); propertyGrid->addWidget(label, currentPropertyRow++, 2); } #endif baseLayout->addLayout(propertyGrid); baseLayout->addStretch(10); connect(mTool, &DocumentInfoTool::documentTitleChanged, this, &DocumentInfoView::onDocumentTitleChanged); connect(mTool, &DocumentInfoTool::documentMimeTypeChanged, this, &DocumentInfoView::onMimeTypeChanged); connect(mTool, &DocumentInfoTool::locationChanged, this, &DocumentInfoView::onLocationChanged); connect(mTool, &DocumentInfoTool::documentSizeChanged, this, &DocumentInfoView::onDocumentSizeChanged); onDocumentTitleChanged(mTool->documentTitle()); onMimeTypeChanged(mTool->mimeType()); onLocationChanged(mTool->location()); onDocumentSizeChanged(mTool->documentSize()); } DocumentInfoView::~DocumentInfoView() = default; void DocumentInfoView::onDocumentTitleChanged(const QString& documentTitle) { mDocumentTitleLabel->setText(documentTitle); } void DocumentInfoView::onMimeTypeChanged(const QMimeType& mimeType) { QString mimeTypeComment; QPixmap mimeTypeIcon; if (!mimeType.isValid()) { mimeTypeComment = QStringLiteral("-"); // mimeTypeIcon = ? } else { mimeTypeComment = mimeType.comment(); mimeTypeIcon = KIconLoader::global()->loadIcon(mimeType.iconName(), KIconLoader::Desktop, KIconLoader::SizeEnormous); } mIconLabel->setPixmap(mimeTypeIcon); mMimeTypeLabel->setText(mimeTypeComment); } void DocumentInfoView::onLocationChanged(const QString& location) { const QString entry = location.isEmpty() ? i18nc("There is no storage location assigned to yet.", "[None]") : location; mLocationLabel->setText(entry); } void DocumentInfoView::onDocumentSizeChanged(int newSize) { const QString size = (newSize != -1) ? KIO::convertSize(newSize) + QLatin1String(" (") + QLocale().toString(newSize) + QLatin1Char(')') : QStringLiteral("-"); mSizeLabel->setText(size); } } diff --git a/kasten/controllers/document/overwriteonly/overwriteonlycontroller.cpp b/kasten/controllers/document/overwriteonly/overwriteonlycontroller.cpp index f2173636..2ee0abb7 100644 --- a/kasten/controllers/document/overwriteonly/overwriteonlycontroller.cpp +++ b/kasten/controllers/document/overwriteonly/overwriteonlycontroller.cpp @@ -1,70 +1,70 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "overwriteonlycontroller.hpp" // Okteta core #include -// KF5 +// KF #include #include #include #include namespace Kasten { OverwriteOnlyController::OverwriteOnlyController(KXMLGUIClient* guiClient) { mSetOverwriteOnlyAction = new KToggleAction(i18nc("@option:check", "Overwrite only"), this); connect(mSetOverwriteOnlyAction, &QAction::triggered, this, &OverwriteOnlyController::setOverwriteOnly); guiClient->actionCollection()->addAction(QStringLiteral("isoverwriteonly"), mSetOverwriteOnlyAction); setTargetModel(nullptr); } void OverwriteOnlyController::setTargetModel(AbstractModel* model) { Q_UNUSED(model) // if( mByteArrayModel ) mByteArrayModel->disconnect( mSetOverwriteOnlyAction ); mByteArrayModel = nullptr; // view ? view->baseModel() : nullptr; if (mByteArrayModel) { // mSetOverwriteOnlyAction->setChecked( mByteArrayModel->isOverwriteOnly() ); // connect( mByteArrayModel, SIGNAL(overwriteOnlyChanged(bool)), // mSetOverwriteOnlyAction, SLOT(setChecked(bool)) ); // connect( mByteArrayModel, SIGNAL(modifiableChanged(bool)), // mSetOverwriteOnlyAction, SLOT(setEnabled(bool)) ); } mSetOverwriteOnlyAction->setEnabled(false); // mByteArrayModel ? mByteArrayModel->isModifiable() : false ); } void OverwriteOnlyController::setOverwriteOnly(bool isOverwriteOnly) { Q_UNUSED(isOverwriteOnly) // mByteArrayModel->setOverwriteOnly( isOverwriteOnly ); } } diff --git a/kasten/controllers/view/bookmarks/bookmarklistmodel.cpp b/kasten/controllers/view/bookmarks/bookmarklistmodel.cpp index a2db125f..2bbe8741 100644 --- a/kasten/controllers/view/bookmarks/bookmarklistmodel.cpp +++ b/kasten/controllers/view/bookmarks/bookmarklistmodel.cpp @@ -1,230 +1,230 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bookmarklistmodel.hpp" // lib #include "bookmarkstool.hpp" // Okteta core #include -// KF5 +// KF #include namespace Kasten { BookmarkListModel::BookmarkListModel(BookmarksTool* tool, QObject* parent) : QAbstractTableModel(parent) , mTool(tool) { mPrintFunction = Okteta::OffsetFormat::printFunction((Okteta::OffsetFormat::Format)tool->offsetCoding()); connect(mTool, &BookmarksTool::hasBookmarksChanged, this, &BookmarkListModel::onHasBookmarksChanged); connect(mTool, &BookmarksTool::bookmarksAdded, this, QOverload<>::of(&BookmarkListModel::onBookmarksChanged)); connect(mTool, &BookmarksTool::bookmarksRemoved, this, QOverload<>::of(&BookmarkListModel::onBookmarksChanged)); connect(mTool, &BookmarksTool::bookmarksModified, this, QOverload&>::of(&BookmarkListModel::onBookmarksChanged)); connect(mTool, &BookmarksTool::offsetCodingChanged, this, &BookmarkListModel::onOffsetCodingChanged); } BookmarkListModel::~BookmarkListModel() = default; int BookmarkListModel::rowCount(const QModelIndex& parent) const { return (!parent.isValid()) ? mTool->bookmarksCount() : 0; } int BookmarkListModel::columnCount(const QModelIndex& parent) const { return (!parent.isValid()) ? NoOfColumnIds : 0; } QVariant BookmarkListModel::data(const QModelIndex& index, int role) const { QVariant result; switch (role) { case Qt::DisplayRole: { const int bookmarkIndex = index.row(); const Okteta::Bookmark& bookmark = mTool->bookmarkAt(bookmarkIndex); const int tableColumn = index.column(); switch (tableColumn) { case OffsetColumnId: { mPrintFunction(mCodedOffset, bookmark.offset()); result = QString::fromLatin1(mCodedOffset); break; } case TitleColumnId: result = bookmark.name(); break; default: ; } break; } case Qt::EditRole: { const int bookmarkIndex = index.row(); const int column = index.column(); if (column == TitleColumnId) { const Okteta::Bookmark& bookmark = mTool->bookmarkAt(bookmarkIndex); result = bookmark.name(); } break; } default: break; } return result; } Qt::ItemFlags BookmarkListModel::flags(const QModelIndex& index) const { Qt::ItemFlags result = QAbstractTableModel::flags(index); const int column = index.column(); if (column == TitleColumnId) { result |= Qt::ItemIsEditable; } return result; } QVariant BookmarkListModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant result; if (role == Qt::DisplayRole) { const QString titel = section == OffsetColumnId ? i18nc("@title:column offset of the bookmark", "Offset") : section == TitleColumnId ? i18nc("@title:column title of the bookmark", "Title") : QString(); result = titel; } else { result = QAbstractTableModel::headerData(section, orientation, role); } return result; } bool BookmarkListModel::setData(const QModelIndex& index, const QVariant& value, int role) { bool result; if (role == Qt::EditRole) { const int bookmarkIndex = index.row(); const int column = index.column(); if (column == TitleColumnId) { mTool->setBookmarkName(bookmarkIndex, value.toString()); // emit dataChanged( index, index ); result = true; } else { result = false; } } else { result = QAbstractItemModel::setData(index, value, role); } return result; } const Okteta::Bookmark& BookmarkListModel::bookmark(const QModelIndex& index) const { const int bookmarkIndex = index.row(); return mTool->bookmarkAt(bookmarkIndex); } QModelIndex BookmarkListModel::index(const Okteta::Bookmark& bookmark, int column) const { QModelIndex result; const int indexOfBookmark = mTool->indexOf(bookmark); if (indexOfBookmark != -1) { result = createIndex(indexOfBookmark, column); } return result; } void BookmarkListModel::onHasBookmarksChanged(bool hasBookmarks) { Q_UNUSED(hasBookmarks) beginResetModel(); endResetModel(); } void BookmarkListModel::onBookmarksChanged() { beginResetModel(); endResetModel(); } void BookmarkListModel::onBookmarksChanged(const QVector& bookmarkIndizes) { for (int row : bookmarkIndizes) { emit dataChanged(index(row, OffsetColumnId), index(row, TitleColumnId)); } } void BookmarkListModel::onOffsetCodingChanged(int offsetCoding) { mPrintFunction = Okteta::OffsetFormat::printFunction((Okteta::OffsetFormat::Format)offsetCoding); beginResetModel(); endResetModel(); } #if 0 void BookmarkListModel::onRevertedToVersionIndex(int versionIndex) { if (mVersionIndex == versionIndex) { return; } const int oldVersionIndex = mVersionIndex; mVersionIndex = versionIndex; emit dataChanged(index(versionIndex, CurrentColumnId), index(versionIndex, CurrentColumnId)); emit dataChanged(index(oldVersionIndex, CurrentColumnId), index(oldVersionIndex, CurrentColumnId)); } void BookmarkListModel::onHeadVersionDataChanged(const DocumentVersionData& versionData) { Q_UNUSED(versionData) const int headVersionIndex = mVersionControl->versionCount() - 1; emit dataChanged(index(headVersionIndex, CurrentColumnId), index(headVersionIndex, ChangeDescriptionColumnId)); } #endif } diff --git a/kasten/controllers/view/bookmarks/bookmarkscontroller.cpp b/kasten/controllers/view/bookmarks/bookmarkscontroller.cpp index d9e9deb8..495b7c3c 100644 --- a/kasten/controllers/view/bookmarks/bookmarkscontroller.cpp +++ b/kasten/controllers/view/bookmarks/bookmarkscontroller.cpp @@ -1,318 +1,318 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007-2009,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bookmarkscontroller.hpp" // controller #include "bookmarkeditpopup.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Kasten core #include // Okteta gui #include // Okteta core #include #include #include #include #include #include -// KF5 +// KF #include #include #include #include // Qt #include namespace Kasten { static constexpr char BookmarkListActionListId[] = "bookmark_list"; // TODO: Sortieren nach Offset oder Zeit BookmarksController::BookmarksController(KXMLGUIClient* guiClient) : mGuiClient(guiClient) { KActionCollection* actionCollection = mGuiClient->actionCollection(); mCreateAction = KStandardAction::addBookmark(this, &BookmarksController::createBookmark, this); mDeleteAction = new QAction(QIcon::fromTheme(QStringLiteral("bookmark-remove")), i18nc("@action:inmenu", "Remove Bookmark"), this); mDeleteAction->setObjectName(QStringLiteral("bookmark_remove")); connect(mDeleteAction, &QAction::triggered, this, &BookmarksController::deleteBookmark); actionCollection->setDefaultShortcut(mDeleteAction, Qt::CTRL + Qt::SHIFT + Qt::Key_B); mDeleteAllAction = new QAction(QIcon::fromTheme(QStringLiteral("bookmark-remove")), i18nc("@action:inmenu", "Remove All Bookmarks"), this); mDeleteAllAction->setObjectName(QStringLiteral("bookmark_remove_all")); connect(mDeleteAllAction, &QAction::triggered, this, &BookmarksController::deleteAllBookmarks); // actionCollection->setDefaultShortcut( mDeleteAllAction, Qt::CTRL + Qt::Key_G ); mGotoNextBookmarkAction = new QAction(QIcon::fromTheme(QStringLiteral("go-next")), i18nc("@action:inmenu", "Go to Next Bookmark"), this); mGotoNextBookmarkAction->setObjectName(QStringLiteral("bookmark_next")); connect(mGotoNextBookmarkAction, &QAction::triggered, this, &BookmarksController::gotoNextBookmark); actionCollection->setDefaultShortcut(mGotoNextBookmarkAction, Qt::ALT + Qt::Key_Down); mGotoPreviousBookmarkAction = new QAction(QIcon::fromTheme(QStringLiteral("go-previous")), i18nc("@action:inmenu", "Go to Previous Bookmark"), this); mGotoPreviousBookmarkAction->setObjectName(QStringLiteral("bookmark_previous")); connect(mGotoPreviousBookmarkAction, &QAction::triggered, this, &BookmarksController::gotoPreviousBookmark); actionCollection->setDefaultShortcut(mGotoPreviousBookmarkAction, Qt::ALT + Qt::Key_Up); mBookmarksActionGroup = new QActionGroup(this); // TODO: do we use this only for the signal mapping? // mBookmarksActionGroup->setExclusive( true ); connect(mBookmarksActionGroup, &QActionGroup::triggered, this, &BookmarksController::onBookmarkTriggered); actionCollection->addActions({ mCreateAction, mDeleteAction, mDeleteAllAction, mGotoNextBookmarkAction, mGotoPreviousBookmarkAction }); setTargetModel(nullptr); } BookmarksController::~BookmarksController() = default; void BookmarksController::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(this); } if (mByteArray) { mByteArray->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArray = document ? document->content() : nullptr; mBookmarks = (mByteArray && mByteArrayView) ? qobject_cast(mByteArray) : nullptr; const bool hasViewWithBookmarks = (mBookmarks != nullptr); int bookmarksCount = 0; if (hasViewWithBookmarks) { bookmarksCount = mBookmarks->bookmarksCount(); connect(mByteArray, SIGNAL(bookmarksAdded(QVector)), SLOT(onBookmarksAdded(QVector))); connect(mByteArray, SIGNAL(bookmarksRemoved(QVector)), SLOT(onBookmarksRemoved(QVector))); connect(mByteArray, SIGNAL(bookmarksModified(QVector)), SLOT(updateBookmarks())); connect(mByteArrayView, &ByteArrayView::cursorPositionChanged, this, &BookmarksController::onCursorPositionChanged); connect(mByteArrayView, &ByteArrayView::offsetCodingChanged, this, &BookmarksController::updateBookmarks); } updateBookmarks(); const bool hasBookmarks = hasViewWithBookmarks && (bookmarksCount != 0); if (hasViewWithBookmarks) { onCursorPositionChanged(mByteArrayView->cursorPosition()); } else { mCreateAction->setEnabled(false); mDeleteAction->setEnabled(false); } mDeleteAllAction->setEnabled(hasBookmarks); mGotoNextBookmarkAction->setEnabled(hasBookmarks); mGotoPreviousBookmarkAction->setEnabled(hasBookmarks); } void BookmarksController::updateBookmarks() { mGuiClient->unplugActionList(QLatin1String(BookmarkListActionListId)); qDeleteAll(mBookmarksActionGroup->actions()); if (!mBookmarks) { return; } const int startOffset = mByteArrayView->startOffset(); Okteta::OffsetFormat::print printFunction = Okteta::OffsetFormat::printFunction((Okteta::OffsetFormat::Format)mByteArrayView->offsetCoding()); char codedOffset[Okteta::OffsetFormat::MaxFormatWidth + 1]; constexpr int firstWithNumericShortCut = 1; constexpr int lastWithNumericShortCut = 9; int b = firstWithNumericShortCut; Okteta::BookmarksConstIterator bit = mBookmarks->createBookmarksConstIterator(); while (bit.hasNext()) { const Okteta::Bookmark& bookmark = bit.next(); printFunction(codedOffset, startOffset + bookmark.offset()); QString title = i18nc("@item description of bookmark", "%1: %2", QString::fromUtf8(codedOffset), bookmark.name()); if (b <= lastWithNumericShortCut) { title = QStringLiteral("&%1 %2").arg(b).arg(title); // = KStringHandler::rsqueeze( view->title(), MaxEntryLength ); ++b; } auto* action = new QAction(title, mBookmarksActionGroup); action->setData(bookmark.offset()); mBookmarksActionGroup->addAction(action); } mGuiClient->plugActionList(QString::fromUtf8(BookmarkListActionListId), mBookmarksActionGroup->actions()); } void BookmarksController::onBookmarksAdded(const QVector& bookmarks) { Q_UNUSED(bookmarks) const int currentPosition = mByteArrayView->cursorPosition(); onCursorPositionChanged(currentPosition); const int bookmarksCount = mBookmarks->bookmarksCount(); const bool hasBookmarks = (bookmarksCount != 0); mDeleteAllAction->setEnabled(hasBookmarks); updateBookmarks(); } void BookmarksController::onBookmarksRemoved(const QVector& bookmarks) { Q_UNUSED(bookmarks) const int currentPosition = mByteArrayView->cursorPosition(); onCursorPositionChanged(currentPosition); const int bookmarksCount = mBookmarks->bookmarksCount(); const bool hasBookmarks = (bookmarksCount != 0); mDeleteAllAction->setEnabled(hasBookmarks); updateBookmarks(); } void BookmarksController::onCursorPositionChanged(Okteta::Address newPosition) { const int bookmarksCount = mBookmarks->bookmarksCount(); const bool hasBookmarks = (bookmarksCount != 0); const bool isInsideByteArray = (newPosition < mByteArray->size()); bool isAtBookmark; bool hasPrevious; bool hasNext; if (hasBookmarks) { isAtBookmark = mBookmarks->containsBookmarkFor(newPosition); Okteta::BookmarksConstIterator bookmarksIterator = mBookmarks->createBookmarksConstIterator(); hasPrevious = bookmarksIterator.findPreviousFrom(newPosition); hasNext = bookmarksIterator.findNextFrom(newPosition); } else { isAtBookmark = false; hasPrevious = false; hasNext = false; } mCreateAction->setEnabled(!isAtBookmark && isInsideByteArray); mDeleteAction->setEnabled(isAtBookmark); mGotoNextBookmarkAction->setEnabled(hasNext); mGotoPreviousBookmarkAction->setEnabled(hasPrevious); } void BookmarksController::createBookmark() { const int cursorPosition = mByteArrayView->cursorPosition(); // search for text at cursor const Okteta::CharCodec* charCodec = Okteta::CharCodec::createCodec(mByteArrayView->charCodingName()); const Okteta::TextByteArrayAnalyzer textAnalyzer(mByteArray, charCodec); QString bookmarkName = textAnalyzer.text(cursorPosition, cursorPosition + MaxBookmarkNameSize - 1); delete charCodec; if (bookmarkName.isEmpty()) { bookmarkName = i18nc("default name of a bookmark", "Bookmark"); // %1").arg( 0 ) ); // TODO: use counter like with new file, globally } auto* bookmarkEditPopup = new BookmarkEditPopup(mByteArrayView->widget()); QPoint popupPoint = mByteArrayView->cursorRect().topLeft(); // popupPoint.ry() += mSlider->height() / 2; popupPoint = mByteArrayView->widget()->mapToGlobal(popupPoint); bookmarkEditPopup->setPosition(popupPoint); bookmarkEditPopup->setName(bookmarkName); const bool success = (bookmarkEditPopup->exec() != 0); if (success) { Okteta::Bookmark bookmark(cursorPosition); bookmark.setName(bookmarkEditPopup->name()); const QVector bookmarks { bookmark }; mBookmarks->addBookmarks(bookmarks); } delete bookmarkEditPopup; } void BookmarksController::deleteBookmark() { const int cursorPosition = mByteArrayView->cursorPosition(); const QVector bookmarks { cursorPosition }; mBookmarks->removeBookmarks(bookmarks); } void BookmarksController::deleteAllBookmarks() { mBookmarks->removeAllBookmarks(); } void BookmarksController::gotoNextBookmark() { const int currentPosition = mByteArrayView->cursorPosition(); Okteta::BookmarksConstIterator bookmarksIterator = mBookmarks->createBookmarksConstIterator(); const bool hasNext = bookmarksIterator.findNextFrom(currentPosition); if (hasNext) { const int newPosition = bookmarksIterator.next().offset(); mByteArrayView->setCursorPosition(newPosition); } } void BookmarksController::gotoPreviousBookmark() { const int currentPosition = mByteArrayView->cursorPosition(); Okteta::BookmarksConstIterator bookmarksIterator = mBookmarks->createBookmarksConstIterator(); const bool hasPrevious = bookmarksIterator.findPreviousFrom(currentPosition); if (hasPrevious) { const int newPosition = bookmarksIterator.previous().offset(); mByteArrayView->setCursorPosition(newPosition); } } void BookmarksController::onBookmarkTriggered(QAction* action) { const int newPosition = action->data().toInt(); mByteArrayView->setCursorPosition(newPosition); } } diff --git a/kasten/controllers/view/bookmarks/bookmarkstool.cpp b/kasten/controllers/view/bookmarks/bookmarkstool.cpp index f7b160aa..0dbdf2f5 100644 --- a/kasten/controllers/view/bookmarks/bookmarkstool.cpp +++ b/kasten/controllers/view/bookmarks/bookmarkstool.cpp @@ -1,202 +1,202 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bookmarkstool.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Kasten core #include // Okteta gui #include // Okteta core #include #include #include #include #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { BookmarksTool::BookmarksTool() { setObjectName(QStringLiteral("Bookmarks")); } BookmarksTool::~BookmarksTool() = default; QString BookmarksTool::title() const { return i18nc("@title:window", "Bookmarks"); } bool BookmarksTool::canCreateBookmark() const { return mCanCreateBookmark; } const Okteta::Bookmark& BookmarksTool::bookmarkAt(unsigned int index) const { return mBookmarks->bookmarkAt(index); } int BookmarksTool::indexOf(const Okteta::Bookmark& bookmark) const { int result = -1; Okteta::BookmarksConstIterator bit = mBookmarks->createBookmarksConstIterator(); int i = 0; while (bit.hasNext()) { if (bookmark == bit.next()) { result = i; break; } ++i; } return result; } unsigned int BookmarksTool::bookmarksCount() const { return mBookmarks ? mBookmarks->bookmarksCount() : 0; } int BookmarksTool::offsetCoding() const { return mByteArrayView ? mByteArrayView->offsetCoding() : 0; } void BookmarksTool::setTargetModel(AbstractModel* model) { const int oldOffsetCoding = offsetCoding(); if (mByteArrayView) { mByteArrayView->disconnect(this); } if (mByteArray) { mByteArray->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArray = document ? document->content() : nullptr; mBookmarks = (mByteArray && mByteArrayView) ? qobject_cast(mByteArray) : nullptr; const bool hasViewWithBookmarks = (mBookmarks != nullptr); if (hasViewWithBookmarks) { onCursorPositionChanged(mByteArrayView->cursorPosition()); connect(mByteArray, SIGNAL(bookmarksAdded(QVector)), SIGNAL(bookmarksAdded(QVector))); connect(mByteArray, SIGNAL(bookmarksRemoved(QVector)), SIGNAL(bookmarksRemoved(QVector))); connect(mByteArray, SIGNAL(bookmarksAdded(QVector)), SLOT(onBookmarksModified())); connect(mByteArray, SIGNAL(bookmarksRemoved(QVector)), SLOT(onBookmarksModified())); connect(mByteArray, SIGNAL(bookmarksModified(QVector)), SIGNAL(bookmarksModified(QVector))); connect(mByteArrayView, &ByteArrayView::cursorPositionChanged, this, &BookmarksTool::onCursorPositionChanged); connect(mByteArrayView, &ByteArrayView::offsetCodingChanged, this, &BookmarksTool::offsetCodingChanged); } else { constexpr bool cantCreateBookmark = false; if (mCanCreateBookmark != cantCreateBookmark) { mCanCreateBookmark = cantCreateBookmark; emit canCreateBookmarkChanged(cantCreateBookmark); } } const int newOffsetCoding = offsetCoding(); if (oldOffsetCoding != newOffsetCoding) { emit offsetCodingChanged(newOffsetCoding); } emit hasBookmarksChanged(hasViewWithBookmarks); } Okteta::Bookmark BookmarksTool::createBookmark() { Okteta::Bookmark bookmark; if (mBookmarks) { const int cursorPosition = mByteArrayView->cursorPosition(); // search for text at cursor const Okteta::CharCodec* charCodec = Okteta::CharCodec::createCodec(mByteArrayView->charCodingName()); const Okteta::TextByteArrayAnalyzer textAnalyzer(mByteArray, charCodec); QString bookmarkName = textAnalyzer.text(cursorPosition, cursorPosition + MaxBookmarkNameSize - 1); delete charCodec; if (bookmarkName.isEmpty()) { bookmarkName = i18nc("default name of a bookmark", "Bookmark"); } // %1").arg( 0 ) ); // TODO: use counter like with new file, globally bookmark.setOffset(mByteArrayView->cursorPosition()); bookmark.setName(bookmarkName); const QVector bookmarksToBeCreated { bookmark }; mBookmarks->addBookmarks(bookmarksToBeCreated); } return bookmark; } void BookmarksTool::deleteBookmarks(const QVector& bookmarks) { if (mBookmarks) { mBookmarks->removeBookmarks(bookmarks); } mByteArrayView->widget()->setFocus(); } void BookmarksTool::gotoBookmark(const Okteta::Bookmark& bookmark) { if (mByteArrayView) { mByteArrayView->setCursorPosition(bookmark.offset()); mByteArrayView->widget()->setFocus(); } } void BookmarksTool::setBookmarkName(unsigned int bookmarkIndex, const QString& name) { Okteta::Bookmark bookmark = mBookmarks->bookmarkAt(bookmarkIndex); bookmark.setName(name); mBookmarks->setBookmark(bookmarkIndex, bookmark); mByteArrayView->widget()->setFocus(); } void BookmarksTool::onCursorPositionChanged(Okteta::Address newPosition) { const int bookmarksCount = mBookmarks->bookmarksCount(); const bool hasBookmarks = (bookmarksCount != 0); const bool isInsideByteArray = (newPosition < mByteArray->size()); const bool isAtBookmark = hasBookmarks ? mBookmarks->containsBookmarkFor(newPosition) : false; const bool canCreateBookmark = (!isAtBookmark && isInsideByteArray); if (canCreateBookmark != mCanCreateBookmark) { mCanCreateBookmark = canCreateBookmark; emit canCreateBookmarkChanged(canCreateBookmark); } } // TODO: is a hack // better just only check for the added and removed, if they include the current position, then change mCanCreateBookmark void BookmarksTool::onBookmarksModified() { const int cursorPosition = mByteArrayView->cursorPosition(); onCursorPositionChanged(cursorPosition); } } diff --git a/kasten/controllers/view/bookmarks/bookmarkstoolviewfactory.cpp b/kasten/controllers/view/bookmarks/bookmarkstoolviewfactory.cpp index 82c0b551..990f35fe 100644 --- a/kasten/controllers/view/bookmarks/bookmarkstoolviewfactory.cpp +++ b/kasten/controllers/view/bookmarks/bookmarkstoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bookmarkstoolviewfactory.hpp" // lib #include "bookmarkstoolview.hpp" #include "bookmarkstool.hpp" -// KF5 +// KF #include namespace Kasten { BookmarksToolViewFactory::BookmarksToolViewFactory() = default; BookmarksToolViewFactory::~BookmarksToolViewFactory() = default; QString BookmarksToolViewFactory::iconName() const { return QStringLiteral("bookmarks"); } QString BookmarksToolViewFactory::title() const { return i18nc("@title:window", "Bookmarks"); } QString BookmarksToolViewFactory::id() const { return QStringLiteral("org.kde.okteta.BookmarksToolView"); } SidePosition BookmarksToolViewFactory::defaultPosition() const { return LeftSidePosition; } AbstractToolView* BookmarksToolViewFactory::create(AbstractTool* tool) const { return new BookmarksToolView(qobject_cast(tool)); } } diff --git a/kasten/controllers/view/bookmarks/bookmarksview.cpp b/kasten/controllers/view/bookmarks/bookmarksview.cpp index bd24ef0b..895ef290 100644 --- a/kasten/controllers/view/bookmarks/bookmarksview.cpp +++ b/kasten/controllers/view/bookmarks/bookmarksview.cpp @@ -1,203 +1,203 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bookmarksview.hpp" // tool #include "bookmarklistmodel.hpp" #include "bookmarkstool.hpp" // Okteta core #include -// KF5 +// KF #include #include // Qt #include #include #include #include namespace Kasten { BookmarksView::BookmarksView(BookmarksTool* tool, QWidget* parent) : QWidget(parent) , mTool(tool) { mBookmarkListModel = new BookmarkListModel(mTool, this); connect(mBookmarkListModel, &BookmarkListModel::modelReset, this, &BookmarksView::onBookmarkSelectionChanged); auto* baseLayout = new QVBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); // bookmarks list mBookmarkListView = new QTreeView(this); mBookmarkListView->setObjectName(QStringLiteral("BookmarkListView")); mBookmarkListView->setRootIsDecorated(false); mBookmarkListView->setItemsExpandable(false); mBookmarkListView->setUniformRowHeights(true); mBookmarkListView->setAllColumnsShowFocus(true); mBookmarkListView->setSelectionMode(QAbstractItemView::ExtendedSelection); mBookmarkListView->setModel(mBookmarkListModel); mBookmarkListView->header()->setSectionResizeMode(QHeaderView::Interactive); connect(mBookmarkListView, &QTreeView::doubleClicked, this, &BookmarksView::onBookmarkDoubleClicked); connect(mBookmarkListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &BookmarksView::onBookmarkSelectionChanged); baseLayout->addWidget(mBookmarkListView, 10); // actions TODO: make this view work like the filebrowser, with actions on top? auto* actionsLayout = new QHBoxLayout(); const KGuiItem createBookmarkGuiItem = KGuiItem(QString() /*i18n("C&opy")*/, QStringLiteral("bookmark-new"), i18nc("@info:tooltip", "Creates a new bookmark for the current cursor position."), i18nc("@info:whatsthis", "If you press this button, a new bookmark will be created " "for the current cursor position.")); mCreateBookmarkButton = new QPushButton(this); KGuiItem::assign(mCreateBookmarkButton, createBookmarkGuiItem); mCreateBookmarkButton->setEnabled(mTool->canCreateBookmark()); connect(mCreateBookmarkButton, &QPushButton::clicked, this, &BookmarksView::onCreateBookmarkButtonClicked); connect(mTool, &BookmarksTool::canCreateBookmarkChanged, mCreateBookmarkButton, &QPushButton::setEnabled); actionsLayout->addWidget(mCreateBookmarkButton); const KGuiItem deleteBookmarkGuiItem = KGuiItem(QString() /*i18n("&Go to")*/, QStringLiteral("edit-delete"), i18nc("@info:tooltip", "Deletes all the selected bookmarks."), i18nc("@info:whatsthis", "If you press this button, all bookmarks which are " "selected will be deleted.")); mDeleteBookmarksButton = new QPushButton(this); KGuiItem::assign(mDeleteBookmarksButton, deleteBookmarkGuiItem); connect(mDeleteBookmarksButton, &QPushButton::clicked, this, &BookmarksView::onDeleteBookmarkButtonClicked); actionsLayout->addWidget(mDeleteBookmarksButton); actionsLayout->addStretch(); const KGuiItem gotoGuiItem = KGuiItem(QString() /*i18n("&Go to")*/, QStringLiteral("go-jump"), i18nc("@info:tooltip", "Moves the cursor to the selected bookmark."), i18nc("@info:whatsthis", "If you press this button, the cursor is moved to the position " "of the bookmark which has been last selected.")); mGotoBookmarkButton = new QPushButton(this); KGuiItem::assign(mGotoBookmarkButton, gotoGuiItem); connect(mGotoBookmarkButton, &QPushButton::clicked, this, &BookmarksView::onGotoBookmarkButtonClicked); actionsLayout->addWidget(mGotoBookmarkButton); const KGuiItem renameGuiItem = KGuiItem(QString() /*i18n("&Go to")*/, QStringLiteral("edit-rename"), i18nc("@info:tooltip", "Enables renaming of the selected bookmark."), i18nc("@info:whatsthis", "If you press this button, the name of the bookmark " "which was last selected can be edited.")); mRenameBookmarkButton = new QPushButton(this); KGuiItem::assign(mRenameBookmarkButton, renameGuiItem); connect(mRenameBookmarkButton, &QPushButton::clicked, this, &BookmarksView::onRenameBookmarkButtonClicked); actionsLayout->addWidget(mRenameBookmarkButton); baseLayout->addLayout(actionsLayout); onBookmarkSelectionChanged(); } BookmarksView::~BookmarksView() = default; void BookmarksView::onBookmarkDoubleClicked(const QModelIndex& index) { const int column = index.column(); const bool isOffsetColum = (column == BookmarkListModel::OffsetColumnId); if (isOffsetColum) { mTool->gotoBookmark(mBookmarkListModel->bookmark(index)); } } void BookmarksView::onBookmarkSelectionChanged() { const QItemSelectionModel* selectionModel = mBookmarkListView->selectionModel(); // TODO: selectionModel->selectedIndexes() is a expensive operation, // but with Qt 4.4.3 hasSelection() has the flaw to return true with a current index const bool hasSelection = !selectionModel->selectedIndexes().isEmpty(); mDeleteBookmarksButton->setEnabled(hasSelection); const bool bookmarkSelected = selectionModel->isSelected(selectionModel->currentIndex()); mRenameBookmarkButton->setEnabled(bookmarkSelected); mGotoBookmarkButton->setEnabled(bookmarkSelected); } void BookmarksView::onCreateBookmarkButtonClicked() { const Okteta::Bookmark bookmark = mTool->createBookmark(); if (bookmark.isValid()) { const QModelIndex index = mBookmarkListModel->index(bookmark, BookmarkListModel::TitleColumnId); if (index.isValid()) { mBookmarkListView->edit(index); } } } void BookmarksView::onDeleteBookmarkButtonClicked() { const QModelIndexList selectedRows = mBookmarkListView->selectionModel()->selectedRows(); QVector bookmarksToBeDeleted; bookmarksToBeDeleted.reserve(selectedRows.size()); for (const QModelIndex& index : selectedRows) { const Okteta::Bookmark& bookmark = mBookmarkListModel->bookmark(index); bookmarksToBeDeleted.append(bookmark); } mTool->deleteBookmarks(bookmarksToBeDeleted); } void BookmarksView::onGotoBookmarkButtonClicked() { const QModelIndex index = mBookmarkListView->selectionModel()->currentIndex(); if (index.isValid()) { mTool->gotoBookmark(mBookmarkListModel->bookmark(index)); } } void BookmarksView::onRenameBookmarkButtonClicked() { QModelIndex index = mBookmarkListView->selectionModel()->currentIndex(); const QModelIndex nameIndex = index.sibling(index.row(), BookmarkListModel::TitleColumnId); if (nameIndex.isValid()) { mBookmarkListView->edit(nameIndex); } } } diff --git a/kasten/controllers/view/bytetable/bytetablemodel.cpp b/kasten/controllers/view/bytetable/bytetablemodel.cpp index cc4bd1b0..d302eff0 100644 --- a/kasten/controllers/view/bytetable/bytetablemodel.cpp +++ b/kasten/controllers/view/bytetable/bytetablemodel.cpp @@ -1,194 +1,194 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytetablemodel.hpp" // Okteta core #include #include #include -// KF5 +// KF #include #include // Qt #include namespace Kasten { static constexpr QChar ByteTableDefaultSubstituteChar = QLatin1Char('.'); static constexpr QChar ByteTableDefaultUndefinedChar = QChar(QChar::ReplacementCharacter); static constexpr int ByteSetSize = 256; ByteTableModel::ByteTableModel(QObject* parent) : QAbstractTableModel(parent) , mCharCodec(Okteta::CharCodec::createCodec(Okteta::LocalEncoding)) , mSubstituteChar(ByteTableDefaultSubstituteChar) , mUndefinedChar(ByteTableDefaultUndefinedChar) { constexpr Okteta::ValueCoding CodingIds[NofOfValueCodings] = { Okteta::DecimalCoding, Okteta::HexadecimalCoding, Okteta::OctalCoding, Okteta::BinaryCoding }; for (int i = 0; i < NofOfValueCodings; ++i) { mValueCodec[i] = Okteta::ValueCodec::createCodec(CodingIds[i]); } } ByteTableModel::~ByteTableModel() { for (auto* codec : qAsConst(mValueCodec)) { delete codec; } delete mCharCodec; } void ByteTableModel::setSubstituteChar(QChar substituteChar) { if (substituteChar.isNull()) { substituteChar = ByteTableDefaultSubstituteChar; } if (mSubstituteChar == substituteChar) { return; } mSubstituteChar = substituteChar; emit dataChanged(index(0, CharacterId), index(ByteSetSize - 1, CharacterId)); } void ByteTableModel::setUndefinedChar(QChar undefinedChar) { if (undefinedChar.isNull()) { undefinedChar = ByteTableDefaultUndefinedChar; } if (mUndefinedChar == undefinedChar) { return; } mUndefinedChar = undefinedChar; emit dataChanged(index(0, CharacterId), index(ByteSetSize - 1, CharacterId)); } void ByteTableModel::setCharCodec(const QString& codeName) { if (codeName == mCharCodec->name()) { return; } delete mCharCodec; mCharCodec = Okteta::CharCodec::createCodec(codeName); emit dataChanged(index(0, CharacterId), index(ByteSetSize - 1, CharacterId)); } int ByteTableModel::rowCount(const QModelIndex& parent) const { return (!parent.isValid()) ? ByteSetSize : 0; } int ByteTableModel::columnCount(const QModelIndex& parent) const { return (!parent.isValid()) ? NoOfIds : 0; } QVariant ByteTableModel::data(const QModelIndex& index, int role) const { QVariant result; if (role == Qt::DisplayRole) { QString content; const unsigned char byte = index.row(); const int column = index.column(); if (column == CharacterId) { const Okteta::Character decodedChar = mCharCodec->decode(byte); content = decodedChar.isUndefined() ? i18nc("@item:intable character is not defined", "undef.") : !decodedChar.isPrint() ? QString(mSubstituteChar) : QString(static_cast(decodedChar)); // TODO: show proper descriptions for all control values, incl. space and delete // cmp. KCharSelect } else if (column < CharacterId) { mValueCodec[column]->encode(&content, 0, byte); } result = content; } else if (role == Qt::ForegroundRole) { const int column = index.column(); if (column == CharacterId) { const unsigned char byte = index.row(); const Okteta::Character decodedChar = mCharCodec->decode(byte); if (decodedChar.isUndefined() || !decodedChar.isPrint()) { const QPalette& palette = QApplication::palette(); const KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::View); result = colorScheme.foreground(KColorScheme::InactiveText); } } } else if (role == Qt::TextAlignmentRole) { result = Qt::AlignRight; } return result; } QVariant ByteTableModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant result; if (role == Qt::DisplayRole) { const QString titel = section == DecimalId ? i18nc("@title:column short for Decimal", "Dec") : section == HexadecimalId ? i18nc("@title:column short for Hexadecimal", "Hex") : section == OctalId ? i18nc("@title:column short for Octal", "Oct") : section == BinaryId ? i18nc("@title:column short for Binary", "Bin") : section == CharacterId ? i18nc("@title:column short for Character", "Char") : QString(); result = titel; } else if (role == Qt::ToolTipRole) { const QString titel = section == DecimalId ? i18nc("@info:tooltip column contains the value in decimal format", "Decimal") : section == HexadecimalId ? i18nc("@info:tooltip column contains the value in hexadecimal format", "Hexadecimal") : section == OctalId ? i18nc("@info:tooltip column contains the value in octal format", "Octal") : section == BinaryId ? i18nc("@info:tooltip column contains the value in binary format", "Binary") : section == CharacterId ? i18nc("@info:tooltip column contains the character with the value", "Character") : QString(); result = titel; } else { result = QAbstractTableModel::headerData(section, orientation, role); } return result; } } diff --git a/kasten/controllers/view/bytetable/bytetabletool.cpp b/kasten/controllers/view/bytetable/bytetabletool.cpp index a9e6bb1b..2d7041c5 100644 --- a/kasten/controllers/view/bytetable/bytetabletool.cpp +++ b/kasten/controllers/view/bytetable/bytetabletool.cpp @@ -1,129 +1,129 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytetabletool.hpp" // controller #include "bytetablemodel.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include #include #include -// KF5 +// KF #include namespace Kasten { ByteTableTool::ByteTableTool() : mByteTableModel(new ByteTableModel(this)) { setObjectName(QStringLiteral("ByteTable")); } ByteTableTool::~ByteTableTool() = default; QString ByteTableTool::title() const { return i18nc("@title:window", "Value/Char Table"); } ByteTableModel* ByteTableTool::byteTableModel() const { return mByteTableModel; } bool ByteTableTool::hasWriteable() const { return (mByteArrayView && mByteArrayModel) ? !mByteArrayView->isReadOnly() : false; } void ByteTableTool::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(mByteTableModel); mByteArrayView->disconnect(this); } mByteArrayView = model ? qobject_cast(model) : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; const bool hasView = (mByteArrayView && mByteArrayModel); if (hasView) { mByteTableModel->setCharCodec(mByteArrayView->charCodingName()); mByteTableModel->setSubstituteChar(mByteArrayView->substituteChar()); mByteTableModel->setUndefinedChar(mByteArrayView->undefinedChar()); connect(mByteArrayView, &ByteArrayView::charCodecChanged, mByteTableModel, &ByteTableModel::setCharCodec); connect(mByteArrayView, &ByteArrayView::substituteCharChanged, mByteTableModel, &ByteTableModel::setSubstituteChar); connect(mByteArrayView, &ByteArrayView::undefinedCharChanged, mByteTableModel, &ByteTableModel::setUndefinedChar); connect(mByteArrayView, &ByteArrayView::readOnlyChanged, this, &ByteTableTool::onReadOnlyChanged); } else { // TODO: use default view profile chars and char codec mByteTableModel->setSubstituteChar(QChar()); mByteTableModel->setUndefinedChar(QChar()); } const bool isWriteable = (hasView && !mByteArrayView->isReadOnly()); emit hasWriteableChanged(isWriteable); } void ByteTableTool::insert(unsigned char byte, int count) { const QByteArray data(count, byte); Okteta::ChangesDescribable* changesDescribable = qobject_cast(mByteArrayModel); if (changesDescribable) { // TODO: how to note the byte? charcoding might change... const QString changeDescription = i18np("Inserted 1 Byte", "Inserted %1 Bytes", count); changesDescribable->openGroupedChange(changeDescription); } mByteArrayView->insert(data); if (changesDescribable) { changesDescribable->closeGroupedChange(); } // void ByteTableController::fill( const QByteArray &Data ) // { // if( HexEdit && ByteArray ) // ByteArray->insert( HexEdit->cursorPosition(), Data ); // } mByteArrayView->setFocus(); } void ByteTableTool::onReadOnlyChanged(bool isReadOnly) { const bool isWriteable = !isReadOnly; emit hasWriteableChanged(isWriteable); } } diff --git a/kasten/controllers/view/bytetable/bytetabletoolviewfactory.cpp b/kasten/controllers/view/bytetable/bytetabletoolviewfactory.cpp index 9232cde2..be31034c 100644 --- a/kasten/controllers/view/bytetable/bytetabletoolviewfactory.cpp +++ b/kasten/controllers/view/bytetable/bytetabletoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytetabletoolviewfactory.hpp" // lib #include "bytetabletoolview.hpp" #include "bytetabletool.hpp" -// KF5 +// KF #include namespace Kasten { ByteTableToolViewFactory::ByteTableToolViewFactory() = default; ByteTableToolViewFactory::~ByteTableToolViewFactory() = default; QString ByteTableToolViewFactory::iconName() const { return QStringLiteral("table"); } QString ByteTableToolViewFactory::title() const { return i18nc("@title:window", "Value/Char Table"); } QString ByteTableToolViewFactory::id() const { return QStringLiteral("org.kde.okteta.ByteTableToolView"); } SidePosition ByteTableToolViewFactory::defaultPosition() const { return RightSidePosition; } AbstractToolView* ByteTableToolViewFactory::create(AbstractTool* tool) const { return new ByteTableToolView(qobject_cast(tool)); } } diff --git a/kasten/controllers/view/bytetable/bytetableview.cpp b/kasten/controllers/view/bytetable/bytetableview.cpp index 0909a5af..6c1063a1 100644 --- a/kasten/controllers/view/bytetable/bytetableview.cpp +++ b/kasten/controllers/view/bytetable/bytetableview.cpp @@ -1,177 +1,177 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007,2009 Friedrich W. H. Kossebau Copyright 2011 Alex Richardson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytetableview.hpp" // tool #include "bytetabletool.hpp" #include "bytetablemodel.hpp" #include -// KF5 +// KF #include #include #include // Qt #include #include #include #include #include #include #include namespace Kasten { ByteTableView::ByteTableView(ByteTableTool* tool, QWidget* parent) : AbstractToolWidget(parent) , mTool(tool) { auto* baseLayout = new QVBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); mByteTableView = new QTreeView(this); // TODO: find a signal/event emitted when fixedfont changes // connect( KGlobalSettings::self(), &KGlobalSettings::kdisplayFontChanged, // this, &ByteTableView::setFixedFontByGlobalSettings ); // connect( KGlobalSettings::self(), &KGlobalSettings::kdisplayFontChanged, // this, &ByteTableView::resizeColumnsWidth ); // connect( KGlobalSettings::self(), &KGlobalSettings::kdisplayStyleChanged, // this, &ByteTableView::resizeColumnsWidth ); setFixedFontByGlobalSettings(); // do this before setting model mByteTableView->setObjectName(QStringLiteral("ByteTable")); mByteTableView->setRootIsDecorated(false); mByteTableView->setItemsExpandable(false); mByteTableView->setUniformRowHeights(true); mByteTableView->setAllColumnsShowFocus(true); mByteTableView->setSortingEnabled(false); QHeaderView* header = mByteTableView->header(); header->setFont(font()); header->setSectionResizeMode(QHeaderView::Interactive); header->setStretchLastSection(false); mByteTableView->setModel(mTool->byteTableModel()); connect(mByteTableView, &QTreeView::doubleClicked, this, &ByteTableView::onDoubleClicked); baseLayout->addWidget(mByteTableView, 10); auto* insertLayout = new QHBoxLayout(); QLabel* label = new QLabel(i18nc("@label:spinbox number of bytes to insert", "Number (bytes):"), this); insertLayout->addWidget(label); mInsertCountEdit = new QSpinBox(this); mInsertCountEdit->setRange(1, INT_MAX); mInsertCountEdit->setValue(1); label->setBuddy(mInsertCountEdit); insertLayout->addWidget(mInsertCountEdit); const QString insertCountToolTip = i18nc("@info:tooltip", "Number of repeats of the currently selected byte in the table to be inserted."); label->setToolTip(insertCountToolTip); mInsertCountEdit->setToolTip(insertCountToolTip); insertLayout->addStretch(); mInsertButton = new QPushButton(this); KGuiItem::assign(mInsertButton, KStandardGuiItem::insert()); mInsertButton->setEnabled(mTool->hasWriteable()); connect(mTool, &ByteTableTool::hasWriteableChanged, mInsertButton, &QPushButton::setEnabled); connect(mInsertButton, &QPushButton::clicked, this, &ByteTableView::onInsertClicked); const QString insertButtonToolTip = i18nc("@info:tooltip", "Insert the currently selected byte in the table repeated the given number of times."); mInsertButton->setToolTip(insertButtonToolTip); addButton(mInsertButton, AbstractToolWidget::Default); insertLayout->addWidget(mInsertButton); baseLayout->addLayout(insertLayout); // if nothing has changed reuse the old values. This means the bytetable is fully constructed // after ~3ms and not 800 as it was before. If the saved values can not be reused it takes ~100ms const QList columnsWidth = ByteTableViewSettings::columnsWidth(); const QString styleName = QApplication::style()->objectName(); const QString fixedFontData = QFontDatabase::systemFont(QFontDatabase::FixedFont).toString(); if (columnsWidth.size() < ByteTableModel::NoOfIds || styleName != ByteTableViewSettings::style() || fixedFontData != ByteTableViewSettings::fixedFont()) { resizeColumnsWidth(); } else { for (int i = 0; i < ByteTableModel::NoOfIds; ++i) { header->resizeSection(i, columnsWidth.at(i)); } } } ByteTableView::~ByteTableView() { QList columnsWidth; columnsWidth.reserve(ByteTableModel::NoOfIds); const QHeaderView* header = mByteTableView->header(); for (int i = 0; i < ByteTableModel::NoOfIds; ++i) { columnsWidth.append(header->sectionSize(i)); } ByteTableViewSettings::setColumnsWidth(columnsWidth); ByteTableViewSettings::setStyle(QApplication::style()->objectName()); ByteTableViewSettings::setFixedFont(QFontDatabase::systemFont(QFontDatabase::FixedFont).toString()); ByteTableViewSettings::self()->save(); } void ByteTableView::resizeColumnsWidth() { QHeaderView* header = mByteTableView->header(); for (int i = 0; i < ByteTableModel::NoOfIds; ++i) { if (i == ByteTableModel::CharacterId) { mByteTableView->resizeColumnToContents(i); continue; } // since all indexes in one row have same number of chars it is enough to calculate one row // this speeds up calculating the width from 800ms to 100ms const QModelIndex index = mTool->byteTableModel()->index(0, i); const int indexWidthHint = mByteTableView->sizeHintForIndex(index).width(); const int headerWidthHint = header->sectionSizeHint(i); header->resizeSection(i, qMax(indexWidthHint, headerWidthHint)); } } void ByteTableView::setFixedFontByGlobalSettings() { mByteTableView->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); } void ByteTableView::onDoubleClicked(const QModelIndex& index) { if (!mTool->hasWriteable()) { return; } const unsigned char byte = index.row(); mTool->insert(byte, mInsertCountEdit->value()); } void ByteTableView::onInsertClicked() { const unsigned char byte = mByteTableView->currentIndex().row(); mTool->insert(byte, mInsertCountEdit->value()); } } diff --git a/kasten/controllers/view/charsetconversion/charsetconversiontool.cpp b/kasten/controllers/view/charsetconversion/charsetconversiontool.cpp index 54be0570..cbdd335e 100644 --- a/kasten/controllers/view/charsetconversion/charsetconversiontool.cpp +++ b/kasten/controllers/view/charsetconversion/charsetconversiontool.cpp @@ -1,188 +1,188 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "charsetconversiontool.hpp" // tool #include "charsetconversionjob.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { CharsetConversionTool::CharsetConversionTool() { setObjectName(QStringLiteral("CharsetConversion")); } CharsetConversionTool::~CharsetConversionTool() = default; bool CharsetConversionTool::isApplyable() const { return (mByteArrayModel && mByteArrayView && mByteArrayView->hasSelectedData() && !mOtherCharCodecName.isEmpty() && mByteArrayView->charCodingName() != mOtherCharCodecName); } QString CharsetConversionTool::title() const { return i18nc("@title:window of the tool to convert between charsets", "Charset Conversion"); } QString CharsetConversionTool::otherCharCodecName() const { return mOtherCharCodecName; } CharsetConversionTool::ConversionDirection CharsetConversionTool::conversionDirection() const { return mConversionDirection; } bool CharsetConversionTool::isSubstitutingMissingChars() const { return mSubstitutingMissingChars; } Okteta::Byte CharsetConversionTool::substituteByte() const { return mSubstituteByte; } void CharsetConversionTool::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; if (mByteArrayView && mByteArrayModel) { connect(mByteArrayView, &ByteArrayView::charCodecChanged, this, &CharsetConversionTool::onViewChanged); connect(mByteArrayView, &ByteArrayView::selectedDataChanged, this, &CharsetConversionTool::onViewChanged); } onViewChanged(); } void CharsetConversionTool::setOtherCharCodecName(const QString& codecName) { if (codecName == mOtherCharCodecName) { return; } mOtherCharCodecName = codecName; emit isApplyableChanged(isApplyable()); } void CharsetConversionTool::setConversionDirection(int conversionDirection) { mConversionDirection = (ConversionDirection)conversionDirection; } void CharsetConversionTool::setSubstitutingMissingChars(bool isSubstitutingMissingChars) { mSubstitutingMissingChars = isSubstitutingMissingChars; } void CharsetConversionTool::setSubstituteByte(int byte) { mSubstituteByte = (Okteta::Byte)byte; } void CharsetConversionTool::convertChars() { QApplication::setOverrideCursor(Qt::WaitCursor); const Okteta::AddressRange convertedSection = mByteArrayView->selection(); QByteArray conversionResult; conversionResult.resize(convertedSection.width()); Okteta::CharCodec* viewCharCodec = Okteta::CharCodec::createCodec(mByteArrayView->charCodingName()); Okteta::CharCodec* otherCharCodec = Okteta::CharCodec::createCodec(mOtherCharCodecName); const bool convertToOther = (mConversionDirection == ConvertTo); Okteta::CharCodec* fromCharCodec = convertToOther ? viewCharCodec : otherCharCodec; Okteta::CharCodec* toCharCodec = convertToOther ? otherCharCodec : viewCharCodec; auto* charsetConversionJob = new CharsetConversionJob(reinterpret_cast(conversionResult.data()), mByteArrayModel, convertedSection, convertToOther ? viewCharCodec : otherCharCodec, convertToOther ? otherCharCodec : viewCharCodec, mSubstitutingMissingChars, mSubstituteByte ); // TODO: report also actually converted bytes const bool success = charsetConversionJob->exec(); if (success) { // TODO: if nothing needed to be converted, just report and don't add change Okteta::ChangesDescribable* changesDescribable = qobject_cast(mByteArrayModel); if (changesDescribable) { const QString description = i18nc("Converted from charset 1 to charset 2", "%1 to %2", fromCharCodec->name(), toCharCodec->name()); changesDescribable->openGroupedChange(description); } mByteArrayModel->replace(convertedSection, conversionResult); if (changesDescribable) { changesDescribable->closeGroupedChange(); } } delete viewCharCodec; delete otherCharCodec; QApplication::restoreOverrideCursor(); const QMap& failedPerByteCount = charsetConversionJob->failedPerByteCount(); const int convertedBytesCount = charsetConversionJob->convertedBytesCount(); mByteArrayView->setFocus(); emit conversionDone(success, convertedBytesCount, failedPerByteCount); } void CharsetConversionTool::onViewChanged() { emit isApplyableChanged(isApplyable()); } } diff --git a/kasten/controllers/view/charsetconversion/charsetconversiontoolviewfactory.cpp b/kasten/controllers/view/charsetconversion/charsetconversiontoolviewfactory.cpp index 01784b90..ce2c02c8 100644 --- a/kasten/controllers/view/charsetconversion/charsetconversiontoolviewfactory.cpp +++ b/kasten/controllers/view/charsetconversion/charsetconversiontoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "charsetconversiontoolviewfactory.hpp" // lib #include "charsetconversiontoolview.hpp" #include "charsetconversiontool.hpp" -// KF5 +// KF #include namespace Kasten { CharsetConversionToolViewFactory::CharsetConversionToolViewFactory() = default; CharsetConversionToolViewFactory::~CharsetConversionToolViewFactory() = default; QString CharsetConversionToolViewFactory::iconName() const { return QStringLiteral("okteta"); } QString CharsetConversionToolViewFactory::title() const { return i18nc("@title:window", "Charset Conversion"); } QString CharsetConversionToolViewFactory::id() const { return QStringLiteral("org.kde.okteta.CharsetConversionToolView"); } SidePosition CharsetConversionToolViewFactory::defaultPosition() const { return RightSidePosition; } AbstractToolView* CharsetConversionToolViewFactory::create(AbstractTool* tool) const { return new CharsetConversionToolView(qobject_cast(tool)); } } diff --git a/kasten/controllers/view/charsetconversion/charsetconversionview.cpp b/kasten/controllers/view/charsetconversion/charsetconversionview.cpp index c934c142..5afc2b7a 100644 --- a/kasten/controllers/view/charsetconversion/charsetconversionview.cpp +++ b/kasten/controllers/view/charsetconversion/charsetconversionview.cpp @@ -1,238 +1,238 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "charsetconversionview.hpp" // tool #include "charsetconversiontool.hpp" // Okteta Kasten gui #include // Okteta core #include -// KF5 +// KF #include #include #include #include // Qt #include #include #include #include #include #include namespace Kasten { CharsetConversionView::CharsetConversionView(CharsetConversionTool* tool, QWidget* parent) : QWidget(parent) , mTool(tool) { auto* baseLayout = new QVBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); // source/target charset auto* directionCharsetLayout = new QHBoxLayout(); mDirectionComboBox = new KComboBox(this); const QStringList directionList { i18nc("@item:inmenu Is converted _from_ charset (selected in combobox next to this)", "From"), i18nc("@item:inmenu Is converted _to_ charset (selected in combobox next to this)", "To"), }; mDirectionComboBox->addItems(directionList); mDirectionComboBox->setCurrentIndex(mTool->conversionDirection()); const QString directionToolTip = i18nc("@info:tooltip", "The direction the bytes are converted, to or from the selected charset."); mDirectionComboBox->setToolTip(directionToolTip); const QString directionWhatsThis = i18nc("@info:whatsthis", "Select the direction the bytes are converted, to or from the selected charset."); mDirectionComboBox->setWhatsThis(directionWhatsThis); connect(mDirectionComboBox, QOverload::of(&KComboBox::activated), mTool, &CharsetConversionTool::setConversionDirection); directionCharsetLayout->addWidget(mDirectionComboBox); mOtherCharSetComboBox = new KComboBox(this); const QStringList charCodecNames = Okteta::CharCodec::codecNames(); const int indexOfCurrentCharCodec = charCodecNames.indexOf(mTool->otherCharCodecName()); mOtherCharSetComboBox->addItems(charCodecNames); mOtherCharSetComboBox->setCurrentIndex(indexOfCurrentCharCodec); const QString targetCharsetToolTip = i18nc("@info:tooltip", "The charset the bytes are converted to."); mOtherCharSetComboBox->setToolTip(targetCharsetToolTip); const QString targetCharsetWhatsThis = i18nc("@info:whatsthis", "Select the charset the bytes are converted to."); mOtherCharSetComboBox->setWhatsThis(targetCharsetWhatsThis); connect(mOtherCharSetComboBox, QOverload::of(&KComboBox::activated), mTool, &CharsetConversionTool::setOtherCharCodecName); directionCharsetLayout->addWidget(mOtherCharSetComboBox, 10); baseLayout->addLayout(directionCharsetLayout); // settings QGroupBox* settingsBox = new QGroupBox(i18nc("@title:group", "Parameters"), this); auto* settingsLayout = new QFormLayout(); const QString substituteMissingCharLabelText = i18nc("@option:check substitute bytes whose char is not part of the target charset", "Substitute missing:"); mSubstituteMissingCharCheckBox = new QCheckBox(this); mSubstituteMissingCharCheckBox->setChecked(mTool->isSubstitutingMissingChars()); const QString substituteMissingCharToolTip = i18nc("@info:tooltip", "Selects if bytes should be substituted with a default byte " "if its char in the source charset is not part of the target charset."); const QString substituteMissingCharWhatsThis = i18nc("@info:whatsthis", "Set to true if bytes should be substituted with a default byte " "if its char in the source charset is not part of the target charset."); mSubstituteMissingCharCheckBox->setToolTip(substituteMissingCharToolTip); mSubstituteMissingCharCheckBox->setWhatsThis(substituteMissingCharWhatsThis); connect(mSubstituteMissingCharCheckBox, &QCheckBox::toggled, mTool, &CharsetConversionTool::setSubstitutingMissingChars); settingsLayout->addRow(substituteMissingCharLabelText, mSubstituteMissingCharCheckBox); // TODO: control what happens on conflicts or unmatched chars in the target set // option to try only if no conflicts or unmatched chars are hit // choosing substitute for unmatched and resolve conflicts (general/case-by-case) // TODO: extra button to request check if all chars are matched, shows state // TODO: option to switch view to target charset, once done, if "to" other charset // default byte const QString substituteByteLabelText = i18nc("@label:textbox byte to use for chars which are not part of the target charset", "Substitute byte:"); mSubstituteByteEdit = new Okteta::ByteArrayComboBox(this); mSubstituteByteEdit->setMinLength(1); mSubstituteByteEdit->setMaxLength(1); const QString substituteByteToolTip = i18nc("@info:tooltip", "The byte to use for chars which are not part of the target charset."); const QString substituteByteWhatsThis = i18nc("@info:whatsthis", "Define the byte to use for chars which are not part of the target charset."); mSubstituteByteEdit->setToolTip(substituteByteToolTip); mSubstituteByteEdit->setWhatsThis(substituteByteWhatsThis); // mSubstituteByteEdit->setEnabled( mTool->isSubstitutingMissingChars() ); mSubstituteByteEdit->setEnabled(false); // TODO: fix char entering and enable again connect(mSubstituteByteEdit, &Okteta::ByteArrayComboBox::byteArrayChanged, this, &CharsetConversionView::onDefaultByteEditChanged); // connect( mSubstituteMissingCharCheckBox, SIGNAL(toggled(bool)), // mSubstituteByteEdit, SLOT(setEnabled(bool)) ); mSubstituteByteEdit->setByteArray(QByteArray(1, mTool->substituteByte())); settingsLayout->addRow(substituteByteLabelText, mSubstituteByteEdit); settingsBox->setLayout(settingsLayout); baseLayout->addWidget(settingsBox); // action auto* actionsLayout = new QHBoxLayout(); actionsLayout->addStretch(); const KGuiItem convertGuiItem = KGuiItem(i18n("Con&vert"), QStringLiteral("run-build"), i18nc("@info:tooltip", "Converts the bytes in the selected range."), xi18nc("@info:whatsthis", "If you press the Convert button, " "all bytes in the selected range " "will be replaced by bytes which represent the same character " "in the selected target charset.")); mConvertButton = new QPushButton(this); KGuiItem::assign(mConvertButton, convertGuiItem); connect(mConvertButton, &QPushButton::clicked, this, &CharsetConversionView::onConvertButtonClicked); actionsLayout->addWidget(mConvertButton); baseLayout->addLayout(actionsLayout); baseLayout->addStretch(); connect(mTool, &CharsetConversionTool::isApplyableChanged, this, &CharsetConversionView::onApplyableChanged); connect(mTool, &CharsetConversionTool::conversionDone, this, &CharsetConversionView::onConversionDone); } CharsetConversionView::~CharsetConversionView() = default; void CharsetConversionView::onApplyableChanged(bool isApplyable) { mConvertButton->setEnabled(isApplyable); } void CharsetConversionView::onDefaultByteEditChanged(const QByteArray& byteArray) { Q_UNUSED(byteArray); } void CharsetConversionView::onConvertButtonClicked() { mTool->convertChars(); } void CharsetConversionView::onConversionDone(bool success, int convertedBytesCount, const QMap& failedPerByteCount) { const QString messageBoxTitle = mTool->title(); if (success) { QString conversionReport = (convertedBytesCount == 0) ? i18nc("@info", "No bytes converted.") : i18ncp("@info", "1 byte converted.", "%1 bytes converted.", convertedBytesCount); if (mTool->isSubstitutingMissingChars()) { int totalFailedByteCount = 0; for (int failedByteCount : failedPerByteCount) { totalFailedByteCount += failedByteCount; } // TODO: show table with failed bytes and their number. conversionReport += QLatin1String("
"); conversionReport += (totalFailedByteCount == 0) ? i18nc("@info", "No bytes substituted.") : i18ncp("@info", "1 byte substituted.", "%1 bytes substituted.", totalFailedByteCount); } KMessageBox::information(/*mParentWidget*/ nullptr, conversionReport, messageBoxTitle); } else { // TODO: show/goto byte which on which conversion fails KMessageBox::sorry(/*mParentWidget*/ nullptr, i18nc("@info", "Conversion cancelled because of chars which are not " "in the target charset."), messageBoxTitle); } } } diff --git a/kasten/controllers/view/checksum/checksumtool.cpp b/kasten/controllers/view/checksum/checksumtool.cpp index 2818345b..3eac861d 100644 --- a/kasten/controllers/view/checksum/checksumtool.cpp +++ b/kasten/controllers/view/checksum/checksumtool.cpp @@ -1,203 +1,203 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ // QCA // need to have this first, as QCA needs QT_NO_CAST_FROM_ASCII disabled when included #include // krazy:excludeall=includes #ifdef HAVE_QCA2 // disable QT_NO_CAST_FROM_ASCII #ifdef QT_NO_CAST_FROM_ASCII #undef QT_NO_CAST_FROM_ASCII #endif #include #endif #include "checksumtool.hpp" // lib #include "checksumcalculatejob.hpp" #include "checksumlogging.hpp" // #include #include // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { ChecksumTool::ChecksumTool() : mChecksumUptodate(false) , mSourceByteArrayModelUptodate(false) { setObjectName(QStringLiteral("Checksum")); // TODO: find a better place to do and store the initialization #ifdef HAVE_QCA2 mQcaInitializer = new QCA::Initializer(QCA::Practical, 64); qCDebug(LOG_OKTETA_KASTEN_CONTROLLER_CHECKSUM) << QCA::supportedFeatures();// Hash::supportedTypes(); #endif mAlgorithmList = ByteArrayChecksumAlgorithmFactory::createAlgorithms(); } ChecksumTool::~ChecksumTool() { qDeleteAll(mAlgorithmList); #ifdef HAVE_QCA2 delete mQcaInitializer; #endif } QVector ChecksumTool::algorithmList() const { return mAlgorithmList; } bool ChecksumTool::isApplyable() const { return (mByteArrayModel && mByteArrayView && mByteArrayView->hasSelectedData()); } QString ChecksumTool::title() const { return i18nc("@title:window of the tool to calculate checksums", "Checksum"); } AbstractByteArrayChecksumParameterSet* ChecksumTool::parameterSet() { AbstractByteArrayChecksumAlgorithm* algorithm = mAlgorithmList.at(mAlgorithmId); return algorithm ? algorithm->parameterSet() : nullptr; } void ChecksumTool::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; if (mByteArrayView && mByteArrayModel) { connect(mByteArrayView, &ByteArrayView::selectedDataChanged, this, &ChecksumTool::onSelectionChanged); } // TODO: if there is no view, there is nothing calculate a checksum from // or this could be the view where we did the checksum from and it did not change checkUptoDate(); emit uptodateChanged(mChecksumUptodate); emit isApplyableChanged(isApplyable()); } void ChecksumTool::checkUptoDate() { mChecksumUptodate = (mSourceByteArrayModel == mByteArrayModel && mByteArrayView && mSourceSelection == mByteArrayView->selection() && mSourceAlgorithmId == mAlgorithmId && mSourceByteArrayModelUptodate); } void ChecksumTool::calculateChecksum() { AbstractByteArrayChecksumAlgorithm* algorithm = mAlgorithmList.at(mAlgorithmId); if (algorithm) { // forget old string source if (mSourceByteArrayModel) { mSourceByteArrayModel->disconnect(this); } QApplication::setOverrideCursor(Qt::WaitCursor); ChecksumCalculateJob* checksumCalculateJob = new ChecksumCalculateJob(&mCheckSum, algorithm, mByteArrayModel, mByteArrayView->selection()); checksumCalculateJob->exec(); QApplication::restoreOverrideCursor(); // remember checksum source mSourceAlgorithmId = mAlgorithmId; mSourceByteArrayModel = mByteArrayModel; mSourceSelection = mByteArrayView->selection(); connect(mSourceByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, this, &ChecksumTool::onSourceChanged); connect(mSourceByteArrayModel, &Okteta::AbstractByteArrayModel::destroyed, this, &ChecksumTool::onSourceDestroyed); mChecksumUptodate = true; mSourceByteArrayModelUptodate = true; emit checksumChanged(mCheckSum); emit uptodateChanged(true); } } void ChecksumTool::setAlgorithm(int algorithmId) { mAlgorithmId = algorithmId; checkUptoDate(); emit uptodateChanged(mChecksumUptodate); emit isApplyableChanged(isApplyable()); } // TODO: hack! // better would be to store the parameter set used for the source and compare if equal // this hack does the same, except for that the source will never be uptodate void ChecksumTool::resetSourceTool() { mSourceAlgorithmId = -1; checkUptoDate(); emit uptodateChanged(mChecksumUptodate); emit isApplyableChanged(isApplyable()); } void ChecksumTool::onSelectionChanged() { // TODO: could be quicker using the selection data checkUptoDate(); emit uptodateChanged(mChecksumUptodate); emit isApplyableChanged(isApplyable()); } void ChecksumTool::onSourceChanged() { mChecksumUptodate = false; mSourceByteArrayModelUptodate = false; emit uptodateChanged(false); } void ChecksumTool::onSourceDestroyed() { mSourceByteArrayModel = nullptr; onSourceChanged(); } } diff --git a/kasten/controllers/view/checksum/checksumtoolviewfactory.cpp b/kasten/controllers/view/checksum/checksumtoolviewfactory.cpp index ec126f20..b13aba00 100644 --- a/kasten/controllers/view/checksum/checksumtoolviewfactory.cpp +++ b/kasten/controllers/view/checksum/checksumtoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "checksumtoolviewfactory.hpp" // lib #include "checksumtoolview.hpp" #include "checksumtool.hpp" -// KF5 +// KF #include namespace Kasten { ChecksumToolViewFactory::ChecksumToolViewFactory() = default; ChecksumToolViewFactory::~ChecksumToolViewFactory() = default; QString ChecksumToolViewFactory::iconName() const { return QStringLiteral("accessories-calculator"); } QString ChecksumToolViewFactory::title() const { return i18nc("@title:window of the tool to calculate checksums", "Checksum"); } QString ChecksumToolViewFactory:: id() const { return QStringLiteral("org.kde.okteta.ChecksumToolView"); } SidePosition ChecksumToolViewFactory::defaultPosition() const { return BottomSidePosition; } AbstractToolView* ChecksumToolViewFactory::create(AbstractTool* tool) const { return new ChecksumToolView(qobject_cast(tool)); } } diff --git a/kasten/controllers/view/checksum/checksumview.cpp b/kasten/controllers/view/checksum/checksumview.cpp index 5701cf5c..d466382a 100644 --- a/kasten/controllers/view/checksum/checksumview.cpp +++ b/kasten/controllers/view/checksum/checksumview.cpp @@ -1,202 +1,202 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "checksumview.hpp" // tool #include "checksumtool.hpp" // lib #include #include #include #include -// KF5 +// KF #include #include #include // Qt #include #include #include #include #include #include #include #include #include namespace Kasten { ChecksumView::ChecksumView(ChecksumTool* tool, QWidget* parent) : AbstractToolWidget(parent) , mTool(tool) { auto* baseLayout = new QVBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); // algorithm auto* algorithmLayout = new QHBoxLayout(); QLabel* label = new QLabel(i18nc("@label:listbox algorithm to use for the checksum", "Algorithm:"), this); mAlgorithmComboBox = new KComboBox(this); connect(mAlgorithmComboBox, QOverload::of(&KComboBox::activated), this, &ChecksumView::onOperationChange); label->setBuddy(mAlgorithmComboBox); const QString algorithmWhatsThis = i18nc("@info:whatsthis", "Select the algorithm to use for the checksum."); label->setWhatsThis(algorithmWhatsThis); mAlgorithmComboBox->setWhatsThis(algorithmWhatsThis); algorithmLayout->addWidget(label); algorithmLayout->addWidget(mAlgorithmComboBox, 10); baseLayout->addLayout(algorithmLayout); // parameter QGroupBox* parameterSetBox = new QGroupBox(i18nc("@title:group", "Parameters"), this); baseLayout->addWidget(parameterSetBox); auto* parameterSetLayout = new QVBoxLayout(parameterSetBox); mParameterSetEditStack = new QStackedWidget(parameterSetBox); parameterSetLayout->addWidget(mParameterSetEditStack); // calculate auto* calculateLayout = new QHBoxLayout(); calculateLayout->addStretch(); const KGuiItem updateGuiItem = KGuiItem(i18nc("@action:button calculate the checksum", "&Calculate"), QStringLiteral("run-build"), i18nc("@info:tooltip", "Calculate the checksum for the bytes in the selected range."), xi18nc("@info:whatsthis", "If you press the Calculate button, the list will be updated " "to all strings which are contained in the selected range and have the set minimum length.")); mCalculateButton = new QPushButton(this); KGuiItem::assign(mCalculateButton, updateGuiItem); mCalculateButton->setEnabled(mTool->isApplyable()); connect(mCalculateButton, &QPushButton::clicked, this, &ChecksumView::onCalculateClicked); addButton(mCalculateButton, AbstractToolWidget::Default); calculateLayout->addWidget(mCalculateButton); baseLayout->addLayout(calculateLayout); mChecksumLabel = new QLineEdit(this); mChecksumLabel->setReadOnly(true); mChecksumLabel->setText(mTool->checkSum()); connect(mTool, &ChecksumTool::checksumChanged, mChecksumLabel, &QLineEdit::setText); baseLayout->addWidget(mChecksumLabel, 10); baseLayout->addStretch(10); connect(mTool, &ChecksumTool::uptodateChanged, this, &ChecksumView::onChecksumUptodateChanged); connect(mTool, &ChecksumTool::isApplyableChanged, this, &ChecksumView::onApplyableChanged); // automatically set focus to the parameters if a operation has been selected QAbstractItemView* algorithmComboBoxListView = mAlgorithmComboBox->view(); QObject::connect(algorithmComboBoxListView, &QAbstractItemView::activated, mParameterSetEditStack, QOverload<>::of(&QStackedWidget::setFocus)); // TODO: is a workaround for Qt 4.5.1 which doesn't emit activated() for mouse clicks QObject::connect(algorithmComboBoxListView, &QAbstractItemView::pressed, mParameterSetEditStack, QOverload<>::of(&QStackedWidget::setFocus)); // TODO: goto filter button if there are no parameters addAlgorithms(); } ChecksumView::~ChecksumView() = default; void ChecksumView::addAlgorithms() { // const QVector algorithmList = mTool->algorithmList(); for (AbstractByteArrayChecksumAlgorithm* algorithm : algorithmList) { mAlgorithmComboBox->addItem(algorithm->name()); const char* const parameterSetId = algorithm->parameterSet()->id(); AbstractByteArrayChecksumParameterSetEdit* parameterEdit = ByteArrayChecksumParameterSetEditFactory::createEdit(parameterSetId); mParameterSetEditStack->addWidget(parameterEdit); } onOperationChange(mTool->algorithmId()); } void ChecksumView::getParameterSet(AbstractByteArrayChecksumParameterSet* parameterSet) const { auto* parametersetEdit = qobject_cast(mParameterSetEditStack->currentWidget()); if (parametersetEdit) { parametersetEdit->getParameterSet(parameterSet); } } void ChecksumView::onCalculateClicked() { AbstractByteArrayChecksumParameterSet* parameterSet = mTool->parameterSet(); if (parameterSet) { getParameterSet(parameterSet); } mTool->calculateChecksum(); } void ChecksumView::onOperationChange(int index) { QWidget* oldWidget = mParameterSetEditStack->currentWidget(); if (oldWidget) { oldWidget->disconnect(this); oldWidget->disconnect(mTool); } mTool->setAlgorithm(index); mParameterSetEditStack->setCurrentIndex(index); auto* parametersetEdit = qobject_cast(mParameterSetEditStack->currentWidget()); if (parametersetEdit) { connect(parametersetEdit, &AbstractByteArrayChecksumParameterSetEdit::validityChanged, this, &ChecksumView::onValidityChanged); // TODO: hack, see checksum source connect(parametersetEdit, &AbstractByteArrayChecksumParameterSetEdit::valuesChanged, mTool, &ChecksumTool::resetSourceTool); onValidityChanged(parametersetEdit->isValid()); } } void ChecksumView::onChecksumUptodateChanged(bool checksumUptodate) { const bool isApplyable = mTool->isApplyable(); mCalculateButton->setEnabled(!checksumUptodate && isApplyable); } void ChecksumView::onApplyableChanged(bool isApplyable) { mCalculateButton->setEnabled(!mTool->isUptodate() && isApplyable); } void ChecksumView::onValidityChanged(bool isValid) { mCalculateButton->setEnabled(mTool->isApplyable() && isValid); } } diff --git a/kasten/controllers/view/filter/filtertool.cpp b/kasten/controllers/view/filter/filtertool.cpp index 8cee9e5b..2b53d382 100644 --- a/kasten/controllers/view/filter/filtertool.cpp +++ b/kasten/controllers/view/filter/filtertool.cpp @@ -1,143 +1,143 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "filtertool.hpp" // tool #include "filterjob.hpp" // filter #include #include // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include -// KF5 +// KF #include // Qt #include #include namespace Kasten { FilterTool::FilterTool() { setObjectName(QStringLiteral("BinaryFilter")); mFilterList = ByteArrayFilterFactory::createFilters(); } FilterTool::~FilterTool() { qDeleteAll(mFilterList); } QString FilterTool::title() const { return i18nc("@title:window", "Binary Filter"); } QVector FilterTool::filterList() const { return mFilterList; } QString FilterTool::charCodecName() const { return mByteArrayView ? mByteArrayView->charCodingName() : QString(); } bool FilterTool::hasWriteable() const { return mHasWritable; } AbstractByteArrayFilterParameterSet* FilterTool::parameterSet(int filterId) { AbstractByteArrayFilter* byteArrayFilter = mFilterList.at(filterId); return byteArrayFilter ? byteArrayFilter->parameterSet() : nullptr; } void FilterTool::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; const bool hasByteArray = (mByteArrayModel && mByteArrayView); QString newCharCodecName; if (hasByteArray) { newCharCodecName = mByteArrayView->charCodingName(); connect(mByteArrayView, &ByteArrayView::hasSelectedDataChanged, this, &FilterTool::onApplyableChanged); connect(mByteArrayView, &ByteArrayView::readOnlyChanged, this, &FilterTool::onApplyableChanged); connect(mByteArrayView, &ByteArrayView::charCodecChanged, this, &FilterTool::charCodecChanged); } onApplyableChanged(); emit charCodecChanged(newCharCodecName); } void FilterTool::filter(int filterId) const { AbstractByteArrayFilter* byteArrayFilter = mFilterList.at(filterId); if (byteArrayFilter) { const Okteta::AddressRange filteredSection = mByteArrayView->selection(); QByteArray filterResult; filterResult.resize(filteredSection.width()); QApplication::setOverrideCursor(Qt::WaitCursor); auto* filterJob = new FilterJob(byteArrayFilter, reinterpret_cast(filterResult.data()), mByteArrayModel, filteredSection); const bool success = filterJob->exec(); QApplication::restoreOverrideCursor(); if (success) { Okteta::ChangesDescribable* changesDescribable = qobject_cast(mByteArrayModel); if (changesDescribable) { changesDescribable->openGroupedChange(byteArrayFilter->name()); } mByteArrayModel->replace(filteredSection, filterResult); if (changesDescribable) { changesDescribable->closeGroupedChange(); } } } mByteArrayView->setFocus(); } void FilterTool::onApplyableChanged() { const bool newHasWriteable = (mByteArrayModel && mByteArrayView && !mByteArrayView->isReadOnly() && mByteArrayView->hasSelectedData()); if (newHasWriteable != mHasWritable) { mHasWritable = newHasWriteable; emit hasWriteableChanged(newHasWriteable); } } } diff --git a/kasten/controllers/view/filter/filtertoolviewfactory.cpp b/kasten/controllers/view/filter/filtertoolviewfactory.cpp index 300cdfcc..183cd0c6 100644 --- a/kasten/controllers/view/filter/filtertoolviewfactory.cpp +++ b/kasten/controllers/view/filter/filtertoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "filtertoolviewfactory.hpp" // lib #include "filtertoolview.hpp" #include "filtertool.hpp" -// KF5 +// KF #include namespace Kasten { FilterToolViewFactory::FilterToolViewFactory() = default; FilterToolViewFactory::~FilterToolViewFactory() = default; QString FilterToolViewFactory::iconName() const { return QStringLiteral("okteta"); } QString FilterToolViewFactory::title() const { return i18nc("@title:window", "Binary Filter"); } QString FilterToolViewFactory:: id() const { return QStringLiteral("org.kde.okteta.FilterToolView"); } SidePosition FilterToolViewFactory::defaultPosition() const { return BottomSidePosition; } AbstractToolView* FilterToolViewFactory::create(AbstractTool* tool) const { return new FilterToolView(qobject_cast(tool)); } } diff --git a/kasten/controllers/view/filter/filterview.cpp b/kasten/controllers/view/filter/filterview.cpp index fa42184d..2df587d3 100644 --- a/kasten/controllers/view/filter/filterview.cpp +++ b/kasten/controllers/view/filter/filterview.cpp @@ -1,203 +1,203 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "filterview.hpp" // #include "filtertool.hpp" // filter #include #include #include #include -// KF5 +// KF #include #include #include // Qt #include #include #include #include #include #include namespace Kasten { FilterView::FilterView(FilterTool* tool, QWidget* parent) : AbstractToolWidget(parent) , mTool(tool) { auto* baseLayout = new QVBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); // filter auto* operationLayout = new QHBoxLayout(); QLabel* label = new QLabel(i18nc("@label:listbox operation to use by the filter", "Operation:"), this); mOperationComboBox = new KComboBox(this); connect(mOperationComboBox, QOverload::of(&KComboBox::activated), this, &FilterView::onOperationChange); label->setBuddy(mOperationComboBox); const QString operationToolTip = i18nc("@info:tooltip", "The operation to use for the filter."); label->setToolTip(operationToolTip); mOperationComboBox->setToolTip(operationToolTip); const QString operationWhatsThis = i18nc("@info:whatsthis", "Select the operation to use for the filter."); label->setWhatsThis(operationWhatsThis); mOperationComboBox->setWhatsThis(operationWhatsThis); operationLayout->addWidget(label); operationLayout->addWidget(mOperationComboBox, 10); baseLayout->addLayout(operationLayout); QGroupBox* parameterSetBox = new QGroupBox(i18nc("@title:group", "Parameters"), this); baseLayout->addWidget(parameterSetBox); auto* parameterSetLayout = new QVBoxLayout; parameterSetBox->setLayout(parameterSetLayout); mParameterSetEditStack = new QStackedWidget(parameterSetBox); parameterSetLayout->addWidget(mParameterSetEditStack); // filter button auto* buttonLayout = new QHBoxLayout(); buttonLayout->addStretch(10); mFilterButton = new QPushButton(this); KGuiItem::assign(mFilterButton, KGuiItem(i18nc("@action:button", "&Filter"), QStringLiteral("run-build"), i18nc("@info:tooltip", "Executes the filter for the bytes in the selected range."), xi18nc("@info:whatsthis", "If you press the Filter button, the operation you selected " "above is executed for the bytes in the selected range with the given options."))); mFilterButton->setEnabled(mTool->hasWriteable()); connect(mTool, &FilterTool::hasWriteableChanged, this, &FilterView::onHasWriteableChanged); connect(mTool, &FilterTool::charCodecChanged, this, &FilterView::onCharCodecChanged); connect(mFilterButton, &QPushButton::clicked, this, &FilterView::onFilterClicked); addButton(mFilterButton, AbstractToolWidget::Default); buttonLayout->addWidget(mFilterButton); baseLayout->addLayout(buttonLayout); baseLayout->addStretch(10); // automatically set focus to the parameters if a operation has been selected QAbstractItemView* operationComboBoxListView = mOperationComboBox->view(); QObject::connect(operationComboBoxListView, &QAbstractItemView::activated, mParameterSetEditStack, QOverload<>::of(&QStackedWidget::setFocus)); // TODO: is a workaround for Qt 4.5.1 which doesn't emit activated() for mouse clicks QObject::connect(operationComboBoxListView, &QAbstractItemView::pressed, mParameterSetEditStack, QOverload<>::of(&QStackedWidget::setFocus)); // TODO: goto filter button if there are no parameters addFilters(); } FilterView::~FilterView() = default; void FilterView::addFilters() { // const QVector filterList = mTool->filterList(); for (AbstractByteArrayFilter* filter : filterList) { mOperationComboBox->addItem(filter->name()); const char* parameterSetId = filter->parameterSet()->id(); AbstractByteArrayFilterParameterSetEdit* parameterEdit = ByteArrayFilterParameterSetEditFactory::createEdit(parameterSetId); mParameterSetEditStack->addWidget(parameterEdit); } onOperationChange(0); } void FilterView::getParameterSet(AbstractByteArrayFilterParameterSet* parameterSet) const { auto* parametersetEdit = qobject_cast(mParameterSetEditStack->currentWidget()); if (parametersetEdit) { parametersetEdit->getParameterSet(parameterSet); } } void FilterView::onFilterClicked() { const int filterId = mOperationComboBox->currentIndex(); auto* parametersetEdit = qobject_cast(mParameterSetEditStack->currentWidget()); if (parametersetEdit) { parametersetEdit->rememberCurrentSettings(); } AbstractByteArrayFilterParameterSet* parameterSet = mTool->parameterSet(filterId); if (parameterSet) { getParameterSet(parameterSet); } mTool->filter(filterId); } void FilterView::onOperationChange(int index) { QWidget* oldWidget = mParameterSetEditStack->currentWidget(); if (oldWidget) { oldWidget->disconnect(this); } mParameterSetEditStack->setCurrentIndex(index); auto* parametersetEdit = qobject_cast(mParameterSetEditStack->currentWidget()); if (parametersetEdit) { connect(parametersetEdit, &AbstractByteArrayFilterParameterSetEdit::validityChanged, this, &FilterView::onValidityChanged); onValidityChanged(parametersetEdit->isValid()); } } void FilterView::onHasWriteableChanged(bool hasWriteable) { auto* parametersetEdit = qobject_cast(mParameterSetEditStack->currentWidget()); const bool isValid = (parametersetEdit ? parametersetEdit->isValid() : false); mFilterButton->setEnabled(hasWriteable && isValid); } void FilterView::onCharCodecChanged(const QString& charCodecName) { auto* parametersetEdit = qobject_cast(mParameterSetEditStack->currentWidget()); if (parametersetEdit) { parametersetEdit->setCharCodec(charCodecName); } } void FilterView::onValidityChanged(bool isValid) { mFilterButton->setEnabled(mTool->hasWriteable() && isValid); } } diff --git a/kasten/controllers/view/gotooffset/gotooffsetcontroller.cpp b/kasten/controllers/view/gotooffset/gotooffsetcontroller.cpp index 9ce53026..e5fbf0af 100644 --- a/kasten/controllers/view/gotooffset/gotooffsetcontroller.cpp +++ b/kasten/controllers/view/gotooffset/gotooffsetcontroller.cpp @@ -1,80 +1,80 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "gotooffsetcontroller.hpp" // controller #include "gotooffsettoolview.hpp" #include "gotooffsettool.hpp" // Kasten gui #include -// KF5 +// KF #include #include #include // Qt #include namespace Kasten { // TODO: for docked widgets signal widgets if embedded or floating, if horizontal/vertical GotoOffsetController::GotoOffsetController(If::ToolInlineViewable* toolInlineViewable, KXMLGUIClient* guiClient) : mToolInlineViewable(toolInlineViewable) { KActionCollection* actionCollection = guiClient->actionCollection(); mGotoOffsetAction = new QAction(QIcon::fromTheme(QStringLiteral("go-jump")), i18nc("@action:inmenu", "&Go to Offset..."), this); connect(mGotoOffsetAction, &QAction::triggered,this, &GotoOffsetController::gotoOffset); actionCollection->setDefaultShortcut(mGotoOffsetAction, Qt::CTRL + Qt::Key_G); actionCollection->addAction(QStringLiteral("goto_offset"), mGotoOffsetAction); mTool = new GotoOffsetTool(); connect(mTool, &GotoOffsetTool::isUsableChanged, mGotoOffsetAction, &QAction::setEnabled); mGotoOffsetAction->setEnabled(mTool->isUsable()); mView = new GotoOffsetToolView(mTool); } GotoOffsetController::~GotoOffsetController() { if (mToolInlineViewable->currentToolInlineView() == mView) { mToolInlineViewable->setCurrentToolInlineView(nullptr); } delete mView; delete mTool; } void GotoOffsetController::setTargetModel(AbstractModel* model) { mTool->setTargetModel(model); } void GotoOffsetController::gotoOffset() { mToolInlineViewable->setCurrentToolInlineView(mView); } } diff --git a/kasten/controllers/view/gotooffset/gotooffsettool.cpp b/kasten/controllers/view/gotooffset/gotooffsettool.cpp index fbaf4bed..b951906a 100644 --- a/kasten/controllers/view/gotooffset/gotooffsettool.cpp +++ b/kasten/controllers/view/gotooffset/gotooffsettool.cpp @@ -1,179 +1,179 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "gotooffsettool.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include -// KF5 +// KF #include namespace Kasten { GotoOffsetTool::GotoOffsetTool() { setObjectName(QStringLiteral("GotoOffset")); } GotoOffsetTool::~GotoOffsetTool() = default; int GotoOffsetTool::currentOffset() const { return mByteArrayView ? mByteArrayView->startOffset() + mByteArrayView->cursorPosition() : -1; } bool GotoOffsetTool::isUsable() const { return (mByteArrayView && mByteArrayModel && (mByteArrayModel->size() > 0)); } bool GotoOffsetTool::isApplyable() const { const int newPosition = finalTargetOffset(); return (mByteArrayView && mByteArrayModel && (0 <= newPosition) && (newPosition <= mByteArrayModel->size())); } QString GotoOffsetTool::title() const { return i18nc("@title:window of the tool to set a new offset for the cursor", "Goto"); } void GotoOffsetTool::setTargetModel(AbstractModel* model) { const bool oldIsUsable = isUsable(); const bool oldIsApplyable = isApplyable(); if (mByteArrayView) { mByteArrayView->disconnect(this); } if (mByteArrayModel) { mByteArrayModel->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; if (mByteArrayView && mByteArrayModel) { connect(mByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, this, &GotoOffsetTool::onContentsChanged); // TODO: update isApplyable on cursor movement and size changes } const bool newIsUsable = isUsable(); const bool newIsApplyable = isApplyable(); if (oldIsUsable != newIsUsable) { emit isUsableChanged(newIsUsable); } if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void GotoOffsetTool::setTargetOffset(Okteta::Address targetOffset) { const bool oldIsApplyable = isApplyable(); mTargetOffset = targetOffset; const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void GotoOffsetTool::setIsRelative(bool isRelative) { const bool oldIsApplyable = isApplyable(); mIsRelative = isRelative; const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void GotoOffsetTool::setIsSelectionToExtent(bool isSelectionToExtent) { const bool oldIsApplyable = isApplyable(); mIsSelectionToExtent = isSelectionToExtent; const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void GotoOffsetTool::setIsBackwards(bool isBackwards) { const bool oldIsApplyable = isApplyable(); mIsBackwards = isBackwards; const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void GotoOffsetTool::gotoOffset() { const int newPosition = finalTargetOffset(); if (mIsSelectionToExtent) { mByteArrayView->setSelectionCursorPosition(newPosition); } else { mByteArrayView->setCursorPosition(newPosition); } mByteArrayView->setFocus(); } int GotoOffsetTool::finalTargetOffset() const { const int newPosition = (!mByteArrayView) ? -1 : mIsRelative ? (mIsBackwards ? mByteArrayView->cursorPosition() - mTargetOffset : mByteArrayView->cursorPosition() + mTargetOffset) : (mIsBackwards ? mByteArrayModel->size() - mTargetOffset : mTargetOffset); return newPosition; } void GotoOffsetTool::onContentsChanged() { // TODO: find status before content changed, e.g. by caching emit isUsableChanged(isUsable()); } } diff --git a/kasten/controllers/view/gotooffset/gotooffsetview.cpp b/kasten/controllers/view/gotooffset/gotooffsetview.cpp index 6113e154..046e285d 100644 --- a/kasten/controllers/view/gotooffset/gotooffsetview.cpp +++ b/kasten/controllers/view/gotooffset/gotooffsetview.cpp @@ -1,186 +1,186 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "gotooffsetview.hpp" // tool #include "gotooffsettool.hpp" // Okteta Kasten gui #include #include -// KF5 +// KF #include #include #include // Qt #include #include #include namespace Kasten { GotoOffsetView::GotoOffsetView(GotoOffsetTool* tool, QWidget* parent) : AbstractToolWidget(parent) , mTool(tool) { auto* baseLayout = new QHBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); // offset auto* offsetLayout = new QHBoxLayout(); offsetLayout->setContentsMargins(0, 0, 0, 0); QLabel* label = new QLabel(i18nc("@label:listbox", "O&ffset:"), this); mAddressEdit = new Okteta::AddressComboBox(this); connect(mAddressEdit, &Okteta::AddressComboBox::addressChanged, mTool, &GotoOffsetTool::setTargetOffset); connect(mAddressEdit, &Okteta::AddressComboBox::formatChanged, this, &GotoOffsetView::onFormatChanged); connect(mAddressEdit, &Okteta::AddressComboBox::addressTypeChanged, this, &GotoOffsetView::onAddressTypeChanged); label->setBuddy(mAddressEdit); const QString inputWhatsThis = i18nc("@info:whatsthis", "Enter an offset to go to, or select a previous offset from the list."); label->setWhatsThis(inputWhatsThis); mAddressEdit->setWhatsThis(inputWhatsThis); offsetLayout->addWidget(label); offsetLayout->addWidget(mAddressEdit, 1); baseLayout->addLayout(offsetLayout, 1); baseLayout->setAlignment(offsetLayout, Qt::AlignTop); setFocusProxy(mAddressEdit); // TODO: see how KDialog does it, e.g. see if there is already a focuswidget as child // options auto* optionsLayout = new QVBoxLayout(); optionsLayout->setContentsMargins(0, 0, 0, 0); mAtCursorCheckBox = new QCheckBox(i18nc("@option:check", "From c&ursor"), this); mAtCursorCheckBox->setWhatsThis( i18nc("@info:whatsthis", "Go relative from the current cursor location and not absolute.")); connect(mAtCursorCheckBox, &QCheckBox::toggled, mTool, &GotoOffsetTool::setIsRelative); mExtendSelectionCheckBox = new QCheckBox(i18nc("@option:check", "&Extend selection"), this); mExtendSelectionCheckBox->setWhatsThis( i18nc("@info:whatsthis", "Extend the selection by the cursor move.")); connect(mExtendSelectionCheckBox, &QCheckBox::toggled, mTool, &GotoOffsetTool::setIsSelectionToExtent); mBackwardsCheckBox = new QCheckBox(i18nc("@option:check", "&Backwards"), this); mBackwardsCheckBox->setWhatsThis( i18nc("@info:whatsthis", "Go backwards from the end or the current cursor location.")); connect(mBackwardsCheckBox, &QCheckBox::toggled, mTool, &GotoOffsetTool::setIsBackwards); auto* upperOptionsLayout = new QHBoxLayout(); upperOptionsLayout->setContentsMargins(0, 0, 0, 0); upperOptionsLayout->addWidget(mAtCursorCheckBox); upperOptionsLayout->addWidget(mBackwardsCheckBox); optionsLayout->addLayout(upperOptionsLayout); optionsLayout->addWidget(mExtendSelectionCheckBox); baseLayout->addLayout(optionsLayout); // Goto button const KGuiItem gotoGuiItem = KGuiItem(i18nc("@action:button", "&Go"), QStringLiteral("go-jump"), i18nc("@info:tooltip", "Go to the Offset"), xi18nc("@info:whatsthis", "If you press the Go " "button, the cursor will be moved in the document to or, " "on your option, by the offset you entered above.")); mGotoButton = new QPushButton(this); KGuiItem::assign(mGotoButton, gotoGuiItem); connect(mGotoButton, &QPushButton::clicked, this, &GotoOffsetView::onGotoButtonClicked); addButton(mGotoButton, AbstractToolWidget::Default); baseLayout->addWidget(mGotoButton); baseLayout->setAlignment(mGotoButton, Qt::AlignTop); setTabOrder(mAddressEdit, mAtCursorCheckBox); setTabOrder(mAtCursorCheckBox, mBackwardsCheckBox); setTabOrder(mBackwardsCheckBox, mExtendSelectionCheckBox); setTabOrder(mExtendSelectionCheckBox, mGotoButton); connect(mTool, &GotoOffsetTool::isApplyableChanged, this, &GotoOffsetView::onApplyableChanged); onApplyableChanged(mTool->isApplyable()); } GotoOffsetView::~GotoOffsetView() = default; void GotoOffsetView::onApplyableChanged(bool isApplyable) { // TODO: set error tooltip, like offset out of range or no document // TODO: set color flag to offset input mGotoButton->setEnabled(isApplyable); } void GotoOffsetView::onGotoButtonClicked() { // TODO: collect recently used offset in tool instead? mAddressEdit->rememberCurrentAddress(); mTool->gotoOffset(); // emit toolUsed(); } void GotoOffsetView::onAddressTypeChanged(int addressType) { const bool isNotExpression = (mAddressEdit->format() != 2); if (isNotExpression || addressType == Okteta::AddressValidator::InvalidAddressType) { return; } bool fromCursor = false; bool backwards = false; if (addressType == Okteta::AddressValidator::AbsoluteAddress) { fromCursor = false; backwards = false; // TODO: there is no way yet for: absolute from end } else if (addressType == Okteta::AddressValidator::RelativeForwards) { fromCursor = true; backwards = false; } else if (addressType == Okteta::AddressValidator::RelativeBackwards) { fromCursor = true; backwards = true; } mAtCursorCheckBox->setChecked(fromCursor); mTool->setIsRelative(fromCursor); mBackwardsCheckBox->setChecked(backwards); mTool->setIsBackwards(backwards); } void GotoOffsetView::onFormatChanged(int formatIndex) { // TODO: make sure Expr is always at index 2 const bool isNotExpression = (formatIndex != 2); mAtCursorCheckBox->setEnabled(isNotExpression); mBackwardsCheckBox->setEnabled(isNotExpression); } } diff --git a/kasten/controllers/view/info/infotool.cpp b/kasten/controllers/view/info/infotool.cpp index 726a7909..bd6691b9 100644 --- a/kasten/controllers/view/info/infotool.cpp +++ b/kasten/controllers/view/info/infotool.cpp @@ -1,160 +1,160 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "infotool.hpp" // controller #include "statistictablemodel.hpp" #include "createstatisticjob.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { InfoTool::InfoTool() : mStatisticTableModel(new StatisticTableModel(mByteCount, this)) { setObjectName(QStringLiteral("Info")); updateStatistic(); } InfoTool::~InfoTool() = default; QString InfoTool::title() const { return i18nc("@title:window", "Statistics"); } StatisticTableModel* InfoTool::statisticTableModel() const { return mStatisticTableModel; } int InfoTool::size() const { return (mByteArrayModel != nullptr) ? mByteArrayModel->size() : -1; } bool InfoTool::isApplyable() const { return (mByteArrayModel && mByteArrayView && mByteArrayView->hasSelectedData() && !isStatisticUptodate()); } bool InfoTool::isStatisticUptodate() const { return (mSourceByteArrayModelUptodate && mSourceByteArrayModel == mByteArrayModel && mByteArrayView && mSourceSelection == mByteArrayView->selection()); } void InfoTool::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(mStatisticTableModel); mByteArrayView->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; if (mByteArrayView && mByteArrayModel) { mStatisticTableModel->setCharCodec(mByteArrayView->charCodingName()); mStatisticTableModel->setValueCoding(mByteArrayView->valueCoding()); mStatisticTableModel->setSubstituteChar(mByteArrayView->substituteChar()); mStatisticTableModel->setUndefinedChar(mByteArrayView->undefinedChar()); connect(mByteArrayView, &ByteArrayView::charCodecChanged, mStatisticTableModel, &StatisticTableModel::setCharCodec); connect(mByteArrayView, &ByteArrayView::valueCodingChanged, mStatisticTableModel, &StatisticTableModel::setValueCoding); connect(mByteArrayView, &ByteArrayView::substituteCharChanged, mStatisticTableModel, &StatisticTableModel::setSubstituteChar); connect(mByteArrayView, &ByteArrayView::undefinedCharChanged, mStatisticTableModel, &StatisticTableModel::setUndefinedChar); connect(mByteArrayView, &ByteArrayView::selectedDataChanged, this, &InfoTool::onSelectionChanged); } else { // TODO: set based on default view profile, also char codec mStatisticTableModel->setSubstituteChar(QChar()); mStatisticTableModel->setUndefinedChar(QChar()); } emit statisticDirty(!isStatisticUptodate()); emit isApplyableChanged(isApplyable()); } void InfoTool::onSelectionChanged() { // TODO: could be quicker using the selection data emit statisticDirty(!isStatisticUptodate()); emit isApplyableChanged(isApplyable()); } void InfoTool::onSourceChanged() { mSourceByteArrayModelUptodate = false; emit statisticDirty(true); emit isApplyableChanged(isApplyable()); } void InfoTool::onSourceDestroyed() { mSourceByteArrayModel = nullptr; onSourceChanged(); } void InfoTool::updateStatistic() { // forget old string source if (mSourceByteArrayModel) { mSourceByteArrayModel->disconnect(this); } QApplication::setOverrideCursor(Qt::WaitCursor); const Okteta::AddressRange selection = (mByteArrayView ? mByteArrayView->selection() : Okteta::AddressRange()); auto* createStatisticJob = new CreateStatisticJob(mByteArrayModel, selection, mByteCount); const int selectionSize = createStatisticJob->exec(); QApplication::restoreOverrideCursor(); mStatisticTableModel->update(selectionSize); // remember new string source mSourceByteArrayModel = mByteArrayModel; mSourceSelection = selection; if (mSourceByteArrayModel) { connect(mSourceByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, this, &InfoTool::onSourceChanged); connect(mSourceByteArrayModel, &Okteta::AbstractByteArrayModel::destroyed, this, &InfoTool::onSourceDestroyed); } mSourceByteArrayModelUptodate = true; emit statisticDirty(false); emit isApplyableChanged(false); if (mByteArrayView) { mByteArrayView->setFocus(); } } } diff --git a/kasten/controllers/view/info/infotoolviewfactory.cpp b/kasten/controllers/view/info/infotoolviewfactory.cpp index 78af6eb6..76f6e699 100644 --- a/kasten/controllers/view/info/infotoolviewfactory.cpp +++ b/kasten/controllers/view/info/infotoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "infotoolviewfactory.hpp" // lib #include "infotoolview.hpp" #include "infotool.hpp" -// KF5 +// KF #include namespace Kasten { InfoToolViewFactory::InfoToolViewFactory() = default; InfoToolViewFactory::~InfoToolViewFactory() = default; QString InfoToolViewFactory::iconName() const { return QStringLiteral("okteta"); } QString InfoToolViewFactory::title() const { return i18nc("@title:window", "Statistics"); } QString InfoToolViewFactory::id() const { return QStringLiteral("org.kde.okteta.StatisticsToolView"); } SidePosition InfoToolViewFactory::defaultPosition() const { return RightSidePosition; } AbstractToolView* InfoToolViewFactory::create(AbstractTool* tool) const { return new InfoToolView(qobject_cast(tool)); } } diff --git a/kasten/controllers/view/info/infoview.cpp b/kasten/controllers/view/info/infoview.cpp index fb425269..50c04b2d 100644 --- a/kasten/controllers/view/info/infoview.cpp +++ b/kasten/controllers/view/info/infoview.cpp @@ -1,175 +1,175 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "infoview.hpp" // tool #include "infotool.hpp" #include "statistictablemodel.hpp" #include -// KF5 +// KF #include #include // Qt #include #include #include #include #include #include #include #include #include namespace Kasten { InfoView::InfoView(InfoTool* tool, QWidget* parent) : QWidget(parent) , mTool(tool) { auto* baseLayout = new QVBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); auto* topLineLayout = new QHBoxLayout(); QLabel* label = new QLabel(i18nc("@label size of selected bytes", "Size:"), this); topLineLayout->addWidget(label); mSizeLabel = new QLabel(this); const QString sizeToolTip = i18nc("@info:tooltip", "The number of the bytes the statistic was built for."); label->setToolTip(sizeToolTip); mSizeLabel->setToolTip(sizeToolTip); topLineLayout->addWidget(mSizeLabel, 10); connect(mTool->statisticTableModel(), &StatisticTableModel::sizeChanged, this, &InfoView::setByteArraySize); topLineLayout->addStretch(); const KGuiItem updateGuiItem = KGuiItem(i18nc("@action:button build the statistic of the byte frequency", "&Build"), QStringLiteral("run-build"), i18nc("@info:tooltip", "Builds the byte frequency statistic for the bytes in the selected range."), xi18nc("@info:whatsthis", "If you press the Build button," " the byte frequency statistic is built for the bytes in the selected range.")); mUpdateButton = new QPushButton(this); KGuiItem::assign(mUpdateButton, updateGuiItem); mUpdateButton->setEnabled(mTool->isApplyable()); connect(mTool, &InfoTool::isApplyableChanged, mUpdateButton, &QPushButton::setEnabled); connect(mUpdateButton, &QPushButton::clicked, mTool, &InfoTool::updateStatistic); topLineLayout->addWidget(mUpdateButton); baseLayout->addLayout(topLineLayout); mStatisticTableView = new QTreeView(this); // TODO: find a signal/event emitted when fixedfont changes // connect( KGlobalSettings::self(), &KGlobalSettings::kdisplayFontChanged, // this, &InfoView::setFixedFontByGlobalSettings ); // connect( KGlobalSettings::self(), &KGlobalSettings::kdisplayFontChanged, // this, &InfoView::resizeColumnsWidth ); // connect( KGlobalSettings::self(), &KGlobalSettings::kdisplayStyleChanged, // this, &InfoView::resizeColumnsWidth ); setFixedFontByGlobalSettings(); // do this before setting model mStatisticTableView->setObjectName(QStringLiteral("StatisticTable")); mStatisticTableView->setRootIsDecorated(false); mStatisticTableView->setItemsExpandable(false); mStatisticTableView->setUniformRowHeights(true); mStatisticTableView->setAllColumnsShowFocus(true); mStatisticTableView->setSortingEnabled(true); QHeaderView* header = mStatisticTableView->header(); header->setFont(font()); header->setSectionResizeMode(QHeaderView::Interactive); header->setStretchLastSection(false); // TODO: write subclass to filter count and percent by num, not string auto* proxyModel = new QSortFilterProxyModel(this); proxyModel->setDynamicSortFilter(true); proxyModel->setSourceModel(mTool->statisticTableModel()); mStatisticTableView->setModel(proxyModel); mStatisticTableView->sortByColumn(StatisticTableModel::CountId, Qt::DescendingOrder); connect(mTool->statisticTableModel(), &StatisticTableModel::headerChanged, this, &InfoView::updateHeader); baseLayout->addWidget(mStatisticTableView, 10); setByteArraySize(mTool->size()); // if nothing has changed reuse the old values. This means the info view is fully constructed much quicker. const QList columnsWidth = InfoViewSettings::columnsWidth(); const QString styleName = QApplication::style()->objectName(); const QString fixedFontData = QFontDatabase::systemFont(QFontDatabase::FixedFont).toString(); if (columnsWidth.size() < StatisticTableModel::NoOfIds || styleName != InfoViewSettings::style() || fixedFontData != InfoViewSettings::fixedFont()) { resizeColumnsWidth(); } else { for (int i = 0; i < StatisticTableModel::NoOfIds; ++i) { header->resizeSection(i, columnsWidth.at(i)); } } } InfoView::~InfoView() { QList columnsWidth; columnsWidth.reserve(StatisticTableModel::NoOfIds); const QHeaderView* header = mStatisticTableView->header(); for (int i = 0; i < StatisticTableModel::NoOfIds; ++i) { columnsWidth.append(header->sectionSize(i)); } InfoViewSettings::setColumnsWidth(columnsWidth); InfoViewSettings::setStyle(QApplication::style()->objectName()); InfoViewSettings::setFixedFont(QFontDatabase::systemFont(QFontDatabase::FixedFont).toString()); InfoViewSettings::self()->save(); } void InfoView::updateHeader() { mStatisticTableView->resizeColumnToContents(StatisticTableModel::ValueId); mStatisticTableView->header()->headerDataChanged(Qt::Horizontal, StatisticTableModel::ValueId, StatisticTableModel::ValueId); } void InfoView::resizeColumnsWidth() { for (int i = 0; i < StatisticTableModel::NoOfIds; ++i) { mStatisticTableView->resizeColumnToContents(i); } } void InfoView::setByteArraySize(int size) { const QString sizeText = (size < 1) ? // -1 is default, 0 should not happen QStringLiteral("-") : i18np("1 byte", "%1 bytes", size); mSizeLabel->setText(sizeText); } void InfoView::setFixedFontByGlobalSettings() { mStatisticTableView->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); } } diff --git a/kasten/controllers/view/info/statistictablemodel.cpp b/kasten/controllers/view/info/statistictablemodel.cpp index 0690fc37..065dec4e 100644 --- a/kasten/controllers/view/info/statistictablemodel.cpp +++ b/kasten/controllers/view/info/statistictablemodel.cpp @@ -1,254 +1,254 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "statistictablemodel.hpp" // Okteta core #include #include #include -// KF5 +// KF #include #include // Qt #include namespace Kasten { static constexpr QChar StatisticsDefaultSubstituteChar = QLatin1Char('.'); static constexpr QChar StatisticsDefaultUndefinedChar = QChar(QChar::ReplacementCharacter); static constexpr Okteta::ValueCoding DefaultValueCoding = Okteta::HexadecimalCoding; static constexpr int StatisticsByteSetSize = 256; StatisticTableModel::StatisticTableModel(int* byteCount, QObject* parent) : QAbstractTableModel(parent) , mByteCount(byteCount) , mValueCoding(DefaultValueCoding) , mValueCodec(Okteta::ValueCodec::createCodec(DefaultValueCoding)) , mCharCodec(Okteta::CharCodec::createCodec(Okteta::LocalEncoding)) , mSubstituteChar(StatisticsDefaultSubstituteChar) , mUndefinedChar(StatisticsDefaultUndefinedChar) { } StatisticTableModel::~StatisticTableModel() { delete mValueCodec; delete mCharCodec; } void StatisticTableModel::update(int size) { mSize = size; emit dataChanged(index(0, CountId), index(StatisticsByteSetSize - 1, PercentId)); emit sizeChanged(mSize); } void StatisticTableModel::setSubstituteChar(QChar substituteChar) { if (substituteChar.isNull()) { substituteChar = StatisticsDefaultSubstituteChar; } if (mSubstituteChar == substituteChar) { return; } mSubstituteChar = substituteChar; emit dataChanged(index(0, CharacterId), index(StatisticsByteSetSize - 1, CharacterId)); } void StatisticTableModel::setUndefinedChar(QChar undefinedChar) { if (undefinedChar.isNull()) { undefinedChar = StatisticsDefaultUndefinedChar; } if (mUndefinedChar == undefinedChar) { return; } mUndefinedChar = undefinedChar; emit dataChanged(index(0, CharacterId), index(StatisticsByteSetSize - 1, CharacterId)); } void StatisticTableModel::setValueCoding(int valueCoding) { // no changes? if (mValueCoding == valueCoding) { return; } delete mValueCodec; mValueCoding = (Okteta::ValueCoding)valueCoding; mValueCodec = Okteta::ValueCodec::createCodec(mValueCoding); // CodedByte.resize( ByteCodec->encodingWidth() ); emit dataChanged(index(0, ValueId), index(StatisticsByteSetSize - 1, ValueId)); emit headerChanged(); } void StatisticTableModel::setCharCodec(const QString& codeName) { if (codeName == mCharCodec->name()) { return; } delete mCharCodec; mCharCodec = Okteta::CharCodec::createCodec(codeName); emit dataChanged(index(0, CharacterId), index(StatisticsByteSetSize - 1, CharacterId)); } int StatisticTableModel::rowCount(const QModelIndex& parent) const { return (!parent.isValid()) ? StatisticsByteSetSize : 0; } int StatisticTableModel::columnCount(const QModelIndex& parent) const { return (!parent.isValid()) ? NoOfIds : 0; } QVariant StatisticTableModel::data(const QModelIndex& index, int role) const { QVariant result; if (role == Qt::DisplayRole) { const unsigned char byte = index.row(); const int column = index.column(); switch (column) { case CharacterId: { const Okteta::Character decodedChar = mCharCodec->decode(byte); result = decodedChar.isUndefined() ? i18nc("@item:intable character is not defined", "undef.") : !decodedChar.isPrint() ? QString(mSubstituteChar) : QString(static_cast(decodedChar)); // TODO: show proper descriptions for all control values, incl. space and delete // cmp. KCharSelect break; } case ValueId: { QString value; mValueCodec->encode(&value, 0, byte); result = value; break; } case CountId: result = (mSize == -1) ? QVariant(QStringLiteral("-")) : QVariant(mByteCount[byte]); break; case PercentId: result = (mSize > 0) ? // TODO: before we printed only a string (which killed sorting) with QString::number( x, 'f', 6 ) // Qt now cuts trailing 0s, results in unaligned numbers, not so beautiful. QVariant(100.0 * (double)mByteCount[byte] / mSize) : QVariant(QStringLiteral("-")); break; default: ; } } else if (role == Qt::TextAlignmentRole) { result = Qt::AlignRight; } else if (role == Qt::ForegroundRole) { const int column = index.column(); bool isInactive = false; switch (column) { case CharacterId: { const unsigned char byte = index.row(); const Okteta::Character decodedChar = mCharCodec->decode(byte); isInactive = decodedChar.isUndefined() || !decodedChar.isPrint(); break; } case CountId: isInactive = (mSize == -1); break; case PercentId: isInactive = (mSize <= 0); break; default: ; } if (isInactive) { const QPalette& palette = QApplication::palette(); const KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::View); result = colorScheme.foreground(KColorScheme::InactiveText); } } return result; } QVariant StatisticTableModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant result; if (role == Qt::DisplayRole) { const QString titel = section == ValueId ? ( mValueCoding == Okteta::HexadecimalCoding ? i18nc("@title:column short for Hexadecimal", "Hex") : mValueCoding == Okteta::DecimalCoding ? i18nc("@title:column short for Decimal", "Dec") : mValueCoding == Okteta::OctalCoding ? i18nc("@title:column short for Octal", "Oct") : mValueCoding == Okteta::BinaryCoding ? i18nc("@title:column short for Binary", "Bin") : QString()) : section == CharacterId ? i18nc("@title:column short for Character", "Char") : section == CountId ? i18nc("@title:column count of characters", "Count") : section == PercentId ? i18nc("@title:column Percent of byte in total", "Percent") : QString(); result = titel; } else if (role == Qt::ToolTipRole) { const QString titel = section == ValueId ? ( mValueCoding == Okteta::HexadecimalCoding ? i18nc("@info:tooltip column contains the value in hexadecimal format", "Hexadecimal") : mValueCoding == Okteta::DecimalCoding ? i18nc("@info:tooltip column contains the value in decimal format", "Decimal") : mValueCoding == Okteta::OctalCoding ? i18nc("@info:tooltip column contains the value in octal format", "Octal") : mValueCoding == Okteta::BinaryCoding ? i18nc("@info:tooltip column contains the value in binary format", "Binary") : // else QString()) : section == CharacterId ? i18nc("@info:tooltip column contains the character with the value", "Character") : // section == CountId ? i18nc("@info:tooltip count of characters", "Count") : // section == PercentId ? i18nc("@info:tooltip Percent of byte in total", "Percent") : QString(); result = titel; } else { result = QAbstractTableModel::headerData(section, orientation, role); } return result; } } diff --git a/kasten/controllers/view/libbytearraychecksum/algorithm/adler32bytearraychecksumalgorithm.cpp b/kasten/controllers/view/libbytearraychecksum/algorithm/adler32bytearraychecksumalgorithm.cpp index 1f77a5de..fef2f2e4 100644 --- a/kasten/controllers/view/libbytearraychecksum/algorithm/adler32bytearraychecksumalgorithm.cpp +++ b/kasten/controllers/view/libbytearraychecksum/algorithm/adler32bytearraychecksumalgorithm.cpp @@ -1,63 +1,63 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "adler32bytearraychecksumalgorithm.hpp" // Okteta core #include -// KF5 +// KF #include static constexpr int MOD_ADLER = 65521; Adler32ByteArrayChecksumAlgorithm::Adler32ByteArrayChecksumAlgorithm() : AbstractByteArrayChecksumAlgorithm( i18nc("name of the checksum algorithm", "Adler-32")) {} Adler32ByteArrayChecksumAlgorithm::~Adler32ByteArrayChecksumAlgorithm() = default; AbstractByteArrayChecksumParameterSet* Adler32ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; } bool Adler32ByteArrayChecksumAlgorithm::calculateChecksum(QString* result, const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { quint32 a = 1; quint32 b = 0; // TODO: this is the "inefficient but straightforward implementation" from the Wikipedia entry, search for improved Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; for (Okteta::Address i = range.start(); i <= range.end(); ++i) { a = (a + model->byte(i)) % MOD_ADLER; b = (b + a) % MOD_ADLER; if (i >= nextBlockEnd) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes(range.localIndex(i) + 1); } } const quint32 sum = (b << 16) | a; *result = QStringLiteral("%1").arg(sum, 8, 16, QChar::fromLatin1('0')); return true; } diff --git a/kasten/controllers/view/libbytearraychecksum/algorithm/crc32bytearraychecksumalgorithm.cpp b/kasten/controllers/view/libbytearraychecksum/algorithm/crc32bytearraychecksumalgorithm.cpp index 5ecc189d..41b117f3 100644 --- a/kasten/controllers/view/libbytearraychecksum/algorithm/crc32bytearraychecksumalgorithm.cpp +++ b/kasten/controllers/view/libbytearraychecksum/algorithm/crc32bytearraychecksumalgorithm.cpp @@ -1,110 +1,110 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "crc32bytearraychecksumalgorithm.hpp" // Okteta core #include -// KF5 +// KF #include class Crc32LookupTable { public: Crc32LookupTable(); public: const quint32& operator[](int i) const; private: static quint32 reverseBits(quint32 bits, char bitCount); private: quint32 mTable[256]; }; Crc32LookupTable::Crc32LookupTable() { quint32 polynomial = 0x04c11db7; // 256 values representing ASCII character codes. for (int i = 0; i < 256; ++i) { int value = reverseBits(i, 8) << 24; for (int j = 0; j < 8; ++j) { const bool hasMsb = (value & (1 << 31)); value <<= 1; if (hasMsb) { value ^= polynomial; } } mTable[i] = reverseBits(value, 32); } } quint32 Crc32LookupTable::reverseBits(quint32 bits, char bitCount) { quint32 result = 0; for (int i = 1; i <= bitCount; ++i) { if (bits & 0x01) { result |= (1 << (bitCount - i)); } bits >>= 1; } return result; } inline const quint32& Crc32LookupTable::operator[](int i) const { return mTable[i]; } Crc32ByteArrayChecksumAlgorithm::Crc32ByteArrayChecksumAlgorithm() : AbstractByteArrayChecksumAlgorithm( i18nc("name of the checksum algorithm, Cyclic Redundancy Check 32", "CRC-32")) {} Crc32ByteArrayChecksumAlgorithm::~Crc32ByteArrayChecksumAlgorithm() = default; AbstractByteArrayChecksumParameterSet* Crc32ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; } bool Crc32ByteArrayChecksumAlgorithm::calculateChecksum(QString* result, const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { Crc32LookupTable lookupTable; quint32 crcBits = 0xffffffff; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; for (Okteta::Address i = range.start(); i <= range.end(); ++i) { const uchar value = (crcBits & 0xFF) ^ model->byte(i); crcBits >>= 8; crcBits ^= lookupTable[value]; if (i >= nextBlockEnd) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes(range.localIndex(i) + 1); } } crcBits ^= 0xffffffff; *result = QStringLiteral("%1").arg(crcBits, 8, 16, QChar::fromLatin1('0')); return true; } diff --git a/kasten/controllers/view/libbytearraychecksum/algorithm/modsum16bytearraychecksumalgorithm.cpp b/kasten/controllers/view/libbytearraychecksum/algorithm/modsum16bytearraychecksumalgorithm.cpp index 7c726666..a0d7d5cb 100644 --- a/kasten/controllers/view/libbytearraychecksum/algorithm/modsum16bytearraychecksumalgorithm.cpp +++ b/kasten/controllers/view/libbytearraychecksum/algorithm/modsum16bytearraychecksumalgorithm.cpp @@ -1,109 +1,109 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "modsum16bytearraychecksumalgorithm.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include ModSum16ByteArrayChecksumAlgorithm::ModSum16ByteArrayChecksumAlgorithm() : AbstractByteArrayChecksumAlgorithm( i18nc("name of the checksum algorithm", "Modular sum 16-bit")) {} ModSum16ByteArrayChecksumAlgorithm::~ModSum16ByteArrayChecksumAlgorithm() = default; AbstractByteArrayChecksumParameterSet* ModSum16ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; } bool ModSum16ByteArrayChecksumAlgorithm::calculateChecksum(QString* result, const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { const bool useLittleEndian = (mParameterSet.endianness() == LittleEndian); quint16 modSum = useLittleEndian ? calculateModSumWithLittleEndian(model, range) : calculateModSumWithBigEndian(model, range); modSum = ~modSum + 1; if (useLittleEndian) { modSum = qbswap(modSum); } *result = QStringLiteral("%1").arg(modSum, 4, 16, QChar::fromLatin1('0')); return true; } quint16 ModSum16ByteArrayChecksumAlgorithm::calculateModSumWithBigEndian(const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { quint16 modSum = 0x0000; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; // TODO: move padding checks into extra code before and after loop for (Okteta::Address i = range.start(); i <= range.end(); ++i) { quint16 value = (quint16)((quint8)(model->byte(i))) << 8; ++i; if (i <= range.end()) { value |= (quint16)((quint8)(model->byte(i))); } modSum += value; #if 0 const uchar value = (crcBits & 0xFF) + model->byte(i); crcBits >>= 8; crcBits ^= lookupTable[value]; #endif if (i >= nextBlockEnd) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes(range.localIndex(i) + 1); } } return modSum; } quint16 ModSum16ByteArrayChecksumAlgorithm::calculateModSumWithLittleEndian(const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { quint16 modSum = 0x0000; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; // TODO: move padding checks into extra code before and after loop for (Okteta::Address i = range.start(); i <= range.end(); ++i) { quint16 value = (quint16)((quint8)(model->byte(i))); ++i; if (i <= range.end()) { value |= (quint16)((quint8)(model->byte(i))) << 8; } modSum += value; if (i >= nextBlockEnd) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes(range.localIndex(i) + 1); } } return modSum; } diff --git a/kasten/controllers/view/libbytearraychecksum/algorithm/modsum32bytearraychecksumalgorithm.cpp b/kasten/controllers/view/libbytearraychecksum/algorithm/modsum32bytearraychecksumalgorithm.cpp index 7e2210bf..2535edb8 100644 --- a/kasten/controllers/view/libbytearraychecksum/algorithm/modsum32bytearraychecksumalgorithm.cpp +++ b/kasten/controllers/view/libbytearraychecksum/algorithm/modsum32bytearraychecksumalgorithm.cpp @@ -1,125 +1,125 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "modsum32bytearraychecksumalgorithm.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include ModSum32ByteArrayChecksumAlgorithm::ModSum32ByteArrayChecksumAlgorithm() : AbstractByteArrayChecksumAlgorithm( i18nc("name of the checksum algorithm", "Modular sum 32-bit")) {} ModSum32ByteArrayChecksumAlgorithm::~ModSum32ByteArrayChecksumAlgorithm() = default; AbstractByteArrayChecksumParameterSet* ModSum32ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; } bool ModSum32ByteArrayChecksumAlgorithm::calculateChecksum(QString* result, const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { const bool useLittleEndian = (mParameterSet.endianness() == LittleEndian); quint32 modSum = useLittleEndian ? calculateModSumWithLittleEndian(model, range) : calculateModSumWithBigEndian(model, range); modSum = ~modSum + 1; if (useLittleEndian) { modSum = qbswap(modSum); } *result = QStringLiteral("%1").arg(modSum, 8, 16, QChar::fromLatin1('0')); return true; } quint32 ModSum32ByteArrayChecksumAlgorithm::calculateModSumWithBigEndian(const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { quint32 modSum = 0x000000; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; // TODO: move padding checks into extra code before and after loop for (Okteta::Address i = range.start(); i <= range.end(); ++i) { quint32 value = (quint32)(quint8)(model->byte(i)) << 24; ++i; if (i <= range.end()) { value |= (quint32)(quint8)(model->byte(i)) << 16; ++i; if (i <= range.end()) { value |= (quint32)(quint8)(model->byte(i)) << 8; ++i; if (i <= range.end()) { value |= (quint32)(quint8)(model->byte(i)); } } } modSum += value; #if 0 const uchar value = (crcBits & 0xFF) + model->byte(i); crcBits >>= 8; crcBits ^= lookupTable[value]; #endif if (i >= nextBlockEnd) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes(range.localIndex(i) + 1); } } return modSum; } quint32 ModSum32ByteArrayChecksumAlgorithm::calculateModSumWithLittleEndian(const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { quint32 modSum = 0x000000; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; // TODO: move padding checks into extra code before and after loop for (Okteta::Address i = range.start(); i <= range.end(); ++i) { quint32 value = (quint32)(quint8)(model->byte(i)); ++i; if (i <= range.end()) { value |= (quint32)(quint8)(model->byte(i)) << 8; ++i; if (i <= range.end()) { value |= (quint32)(quint8)(model->byte(i)) << 16; ++i; if (i <= range.end()) { value |= (quint32)(quint8)(model->byte(i)) << 24; } } } modSum += value; if (i >= nextBlockEnd) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes(range.localIndex(i) + 1); } } return modSum; } diff --git a/kasten/controllers/view/libbytearraychecksum/algorithm/modsum64bytearraychecksumalgorithm.cpp b/kasten/controllers/view/libbytearraychecksum/algorithm/modsum64bytearraychecksumalgorithm.cpp index 5a870313..e4152d07 100644 --- a/kasten/controllers/view/libbytearraychecksum/algorithm/modsum64bytearraychecksumalgorithm.cpp +++ b/kasten/controllers/view/libbytearraychecksum/algorithm/modsum64bytearraychecksumalgorithm.cpp @@ -1,161 +1,161 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "modsum64bytearraychecksumalgorithm.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include ModSum64ByteArrayChecksumAlgorithm::ModSum64ByteArrayChecksumAlgorithm() : AbstractByteArrayChecksumAlgorithm( i18nc("name of the checksum algorithm", "Modular sum 64-bit")) {} ModSum64ByteArrayChecksumAlgorithm::~ModSum64ByteArrayChecksumAlgorithm() = default; AbstractByteArrayChecksumParameterSet* ModSum64ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; } bool ModSum64ByteArrayChecksumAlgorithm::calculateChecksum(QString* result, const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { const bool useLittleEndian = (mParameterSet.endianness() == LittleEndian); quint64 modSum = useLittleEndian ? calculateModSumWithLittleEndian(model, range) : calculateModSumWithBigEndian(model, range); modSum = ~modSum + 1; if (useLittleEndian) { modSum = qbswap(modSum); } *result = QStringLiteral("%1").arg(modSum, 16, 16, QChar::fromLatin1('0')); return true; } quint64 ModSum64ByteArrayChecksumAlgorithm::calculateModSumWithBigEndian(const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { quint64 modSum = 0x00000000; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; // TODO: move padding checks into extra code before and after loop for (Okteta::Address i = range.start(); i <= range.end(); ++i) { quint64 value = (quint64)((quint8)(model->byte(i))) << 56; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 48; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 40; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 32; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 24; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 16; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 8; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))); } } } } } } } modSum += value; #if 0 const uchar value = (crcBits & 0xFF) + model->byte(i); crcBits >>= 8; crcBits ^= lookupTable[value]; #endif if (i >= nextBlockEnd) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes(range.localIndex(i) + 1); } } return modSum; } quint64 ModSum64ByteArrayChecksumAlgorithm::calculateModSumWithLittleEndian(const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { quint64 modSum = 0x00000000; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; // TODO: move padding checks into extra code before and after loop for (Okteta::Address i = range.start(); i <= range.end(); ++i) { quint64 value = (quint8)(model->byte(i)); ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 8; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 16; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 24; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 32; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 40; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 48; ++i; if (i <= range.end()) { value |= (quint64)((quint8)(model->byte(i))) << 56; } } } } } } } modSum += value; #if 0 const uchar value = (crcBits & 0xFF) + model->byte(i); crcBits >>= 8; crcBits ^= lookupTable[value]; #endif if (i >= nextBlockEnd) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes(range.localIndex(i) + 1); } } return modSum; } diff --git a/kasten/controllers/view/libbytearraychecksum/algorithm/modsum8bytearraychecksumalgorithm.cpp b/kasten/controllers/view/libbytearraychecksum/algorithm/modsum8bytearraychecksumalgorithm.cpp index d9875c34..b88ee2ec 100644 --- a/kasten/controllers/view/libbytearraychecksum/algorithm/modsum8bytearraychecksumalgorithm.cpp +++ b/kasten/controllers/view/libbytearraychecksum/algorithm/modsum8bytearraychecksumalgorithm.cpp @@ -1,63 +1,63 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "modsum8bytearraychecksumalgorithm.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include ModSum8ByteArrayChecksumAlgorithm::ModSum8ByteArrayChecksumAlgorithm() : AbstractByteArrayChecksumAlgorithm( i18nc("name of the checksum algorithm", "Modular sum 8-bit")) {} ModSum8ByteArrayChecksumAlgorithm::~ModSum8ByteArrayChecksumAlgorithm() = default; AbstractByteArrayChecksumParameterSet* ModSum8ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; } bool ModSum8ByteArrayChecksumAlgorithm::calculateChecksum(QString* result, const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { quint8 modSum = 0x00; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; for (Okteta::Address i = range.start(); i <= range.end(); ++i) { modSum += (quint8)(model->byte(i)); #if 0 const uchar value = (crcBits & 0xFF) + model->datum(i); crcBits >>= 8; crcBits ^= lookupTable[value]; #endif if (i >= nextBlockEnd) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes(range.localIndex(i) + 1); } } modSum = ~modSum + 1; *result = QStringLiteral("%1").arg(modSum, 2, 16, QChar::fromLatin1('0')); return true; } diff --git a/kasten/controllers/view/libbytearraychecksum/algorithm/modsumbytearraychecksumparametersetedit.cpp b/kasten/controllers/view/libbytearraychecksum/algorithm/modsumbytearraychecksumparametersetedit.cpp index 47c921ef..e1c2704e 100644 --- a/kasten/controllers/view/libbytearraychecksum/algorithm/modsumbytearraychecksumparametersetedit.cpp +++ b/kasten/controllers/view/libbytearraychecksum/algorithm/modsumbytearraychecksumparametersetedit.cpp @@ -1,76 +1,76 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "modsumbytearraychecksumparametersetedit.hpp" // parameterset #include "modsumbytearraychecksumparameterset.hpp" -// KF5 +// KF #include #include // Qt #include const char ModSumByteArrayChecksumParameterSetEdit::Id[] = "ModSum"; ModSumByteArrayChecksumParameterSetEdit::ModSumByteArrayChecksumParameterSetEdit(QWidget* parent) : AbstractByteArrayChecksumParameterSetEdit(parent) { auto* baseLayout = new QFormLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); mByteOrderComboBox = new KComboBox(this); mByteOrderComboBox->addItem(i18nc("@item:inlistbox", "Little-endian")); // add first for index mByteOrderComboBox->addItem(i18nc("@item:inlistbox", "Big-endian")); // add second for index connect(mByteOrderComboBox, QOverload::of(&KComboBox::activated), this, &ModSumByteArrayChecksumParameterSetEdit::valuesChanged); const QString byteOrderLabelText = i18nc("@label:listbox byte order to use for decoding the bytes into integer values", "Byte Order:"); const QString groupSizeToolTip = i18nc("@info:tooltip", "The byte order to use for decoding the bytes into integer values."); mByteOrderComboBox->setToolTip(groupSizeToolTip); baseLayout->addRow(byteOrderLabelText, mByteOrderComboBox); } ModSumByteArrayChecksumParameterSetEdit::~ModSumByteArrayChecksumParameterSetEdit() = default; bool ModSumByteArrayChecksumParameterSetEdit::isValid() const { return true; } void ModSumByteArrayChecksumParameterSetEdit::setParameterSet(const AbstractByteArrayChecksumParameterSet* parameterSet) { const auto* modSumParameterSet = static_cast(parameterSet); mByteOrderComboBox->setCurrentIndex(modSumParameterSet->endianness()); } void ModSumByteArrayChecksumParameterSetEdit::getParameterSet(AbstractByteArrayChecksumParameterSet* parameterSet) const { auto* modSumParameterSet = static_cast(parameterSet); modSumParameterSet->setEndianness(static_cast(mByteOrderComboBox->currentIndex())); } diff --git a/kasten/controllers/view/libbytearraychecksum/algorithm/template/template_bytearraychecksumalgorithm.cpp b/kasten/controllers/view/libbytearraychecksum/algorithm/template/template_bytearraychecksumalgorithm.cpp index a611555e..aeb2cfaf 100644 --- a/kasten/controllers/view/libbytearraychecksum/algorithm/template/template_bytearraychecksumalgorithm.cpp +++ b/kasten/controllers/view/libbytearraychecksum/algorithm/template/template_bytearraychecksumalgorithm.cpp @@ -1,58 +1,58 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau Public domain. */ //// ADAPT(start) //// rename "template_bytearraychecksumalgorithm.hpp" to the name of the header of your checksum algorithm, //// e.g. "mybytearraychecksumalgorithm.hpp" #include "template_bytearraychecksumalgorithm.hpp" //// ADAPT(end) // Okteta core #include -// KF5 +// KF #include Template_ByteArrayChecksumAlgorithm::Template_ByteArrayChecksumAlgorithm() : AbstractByteArrayChecksumAlgorithm( //// ADAPT(start) //// change "TEMPLATE" to a short and descriptive name of the checksum algorithm i18nc("name of the checksum algorithm", "Template")) //// ADAPT(end) {} Template_ByteArrayChecksumAlgorithm::~Template_ByteArrayChecksumAlgorithm() = default; AbstractByteArrayChecksumParameterSet* Template_ByteArrayChecksumAlgorithm::parameterSet() { return &mParameterSet; } bool Template_ByteArrayChecksumAlgorithm::calculateChecksum(QString* result, const Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { bool success = true; //// ADAPT(start) //// modify the following code to calculate the checksum/hashsum. //// The final checksum is passed as a QString to result. const int mask = (1 << mParameterSet.bitNumber()); int sum = 0; Okteta::Address nextBlockEnd = range.start() + CalculatedByteCountSignalLimit; for (Okteta::Address i = range.start(); i <= range.end(); ++i) { sum ^= (model->byte(i) & mask); if (i >= nextBlockEnd) { nextBlockEnd += CalculatedByteCountSignalLimit; emit calculatedBytes(range.localIndex(i) + 1); } } *result = QStringLiteral("%1").arg(sum); //// ADAPT(end) return success; } diff --git a/kasten/controllers/view/libbytearraychecksum/algorithm/template/template_bytearraychecksumparametersetedit.cpp b/kasten/controllers/view/libbytearraychecksum/algorithm/template/template_bytearraychecksumparametersetedit.cpp index b1ef0c91..e6a43d51 100644 --- a/kasten/controllers/view/libbytearraychecksum/algorithm/template/template_bytearraychecksumparametersetedit.cpp +++ b/kasten/controllers/view/libbytearraychecksum/algorithm/template/template_bytearraychecksumparametersetedit.cpp @@ -1,117 +1,117 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau Public domain. */ //// ADAPT(start) //// rename "template_bytearraychecksumparametersetedit.hpp" to the name of the header of your filter, //// e.g. "mybytearraychecksumparametersetedit.hpp" #include "template_bytearraychecksumparametersetedit.hpp" //// ADAPT(end) // parameterset //// ADAPT(start) //// rename "template_bytearraychecksumparameterset.hpp" to the name of the header of your filter, //// e.g. "mybytearraychecksumparameterset.hpp" #include "template_bytearraychecksumparameterset.hpp" //// ADAPT(end) -// KF5 +// KF #include //// ADAPT(start) //// add includes for all elements used in the widget #include // Qt #include //// ADAPT(end) //// ADAPT(start) //// rename "Template_ParameterSetId" to the id of your parameterset, //// e.g. "MyParameterSet" const char Template_ByteArrayChecksumParameterSetEdit::Id[] = "Template_ParameterSetId"; //// ADAPT(end) Template_ByteArrayChecksumParameterSetEdit::Template_ByteArrayChecksumParameterSetEdit(QWidget* parent) : AbstractByteArrayChecksumParameterSetEdit(parent) { //// ADAPT(start) //// setup the widget with all edit fields needed for the parameter set //// if there can be invalid states connect the change signals of the edit fields to some slots //// where you check if the validity changed auto* baseLayout = new QFormLayout(this); // margin is provided by the container for this widget baseLayout->setContentsMargins(0, 0, 0, 0); mBitNumberEdit = new QSpinBox(this); // For demonstration purpose we start at 0, not 1, to show handling of an invalid state // Otherwise the range should start at 1 and there is no need to connect to the valueChanged signal mBitNumberEdit->setRange(0, 8); // start with the invalid number mBitNumberEdit->setValue(0); connect(mBitNumberEdit, QOverload::of(&QSpinBox::valueChanged), this, &Template_ByteArrayChecksumParameterSetEdit::onBitNumberChanged); const QString levelLabelText = i18nc("@label:spinbox number of the bit to use", "Number of bit:"); const QString levelToolTip = i18nc("@info:tooltip", "The number of the bit to use for the parity calculation. 1 means the LSB, 8 the MSB."); mBitNumberEdit->setToolTip(levelToolTip); const QString levelWhatsThis = i18nc("@info:whatsthis", "Select the bit which should be used for the parity calculation. And more explanation."); mBitNumberEdit->setWhatsThis(levelWhatsThis); baseLayout->addRow(levelLabelText, mBitNumberEdit); // note start state mIsValid = isValid(); //// ADAPT(end) } Template_ByteArrayChecksumParameterSetEdit::~Template_ByteArrayChecksumParameterSetEdit() = default; //// ADAPT(start) //// if invalid states are possible implement here the check bool Template_ByteArrayChecksumParameterSetEdit::isValid() const { return mBitNumberEdit->value() != 0; } //// ADAPT(end) //// ADAPT(start) //// change "Template_ByteArrayFilterParameterSet" to the class of the parameter set which this widget should edit //// e.g. "MyByteArrayFilterParameterSet" //// also adapt the passing of the values between the parameter set and the edit fields void Template_ByteArrayChecksumParameterSetEdit::setParameterSet(const AbstractByteArrayChecksumParameterSet* parameterSet) { const auto* template_ParameterSet = static_cast(parameterSet); mBitNumberEdit->setValue(template_ParameterSet->bitNumber()); } void Template_ByteArrayChecksumParameterSetEdit::getParameterSet(AbstractByteArrayChecksumParameterSet* parameterSet) const { auto* template_ParameterSet = static_cast(parameterSet); template_ParameterSet->setBitNumber(mBitNumberEdit->value()); } //// ADAPT(end) //// ADAPT(start) //// define the slots to catch changes in the values to check if the current state is valid or not //// not needed if there cannot be invalid states void Template_ByteArrayChecksumParameterSetEdit::onBitNumberChanged(int value) { const bool isValid = (value != 0); if (mIsValid == isValid) { return; } mIsValid = isValid; emit validityChanged(isValid); } //// ADAPT(end) diff --git a/kasten/controllers/view/libbytearraychecksum/bytearraychecksumalgorithmfactory.cpp b/kasten/controllers/view/libbytearraychecksum/bytearraychecksumalgorithmfactory.cpp index ce5bcad6..8c38550a 100644 --- a/kasten/controllers/view/libbytearraychecksum/bytearraychecksumalgorithmfactory.cpp +++ b/kasten/controllers/view/libbytearraychecksum/bytearraychecksumalgorithmfactory.cpp @@ -1,96 +1,96 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ // QCA // need to have this first, as QCA needs QT_NO_CAST_FROM_ASCII disabled when included #include // krazy:excludeall=includes #ifdef HAVE_QCA2 // disable QT_NO_CAST_FROM_ASCII #ifdef QT_NO_CAST_FROM_ASCII #undef QT_NO_CAST_FROM_ASCII #endif #include #endif #include "bytearraychecksumalgorithmfactory.hpp" // lib #include "algorithm/crc32bytearraychecksumalgorithm.hpp" #include "algorithm/adler32bytearraychecksumalgorithm.hpp" #include "algorithm/modsum8bytearraychecksumalgorithm.hpp" #include "algorithm/modsum16bytearraychecksumalgorithm.hpp" #include "algorithm/modsum32bytearraychecksumalgorithm.hpp" #include "algorithm/modsum64bytearraychecksumalgorithm.hpp" #ifdef HAVE_QCA2 #include "algorithm/qca2bytearraychecksumalgorithm.hpp" #endif // NEWCHECKSUM(start) // Here add the name of your header file of your checksum algorithm, // e.g. // #include "algorithm/mybytearraychecksumalgorithm.hpp" // NEWCHECKSUM(end) -// KF5 +// KF #include // Qt #include #ifdef HAVE_QCA2 static inline void addQca2Algorithm(QVector& algorithmList, const QString& name, const char* type) { if (QCA::isSupported(type)) { algorithmList << new Qca2ByteArrayChecksumAlgorithm(name, QString::fromLatin1(type)); } } #endif QVector ByteArrayChecksumAlgorithmFactory::createAlgorithms() { QVector result { new ModSum8ByteArrayChecksumAlgorithm(), new ModSum16ByteArrayChecksumAlgorithm(), new ModSum32ByteArrayChecksumAlgorithm(), new ModSum64ByteArrayChecksumAlgorithm(), new Adler32ByteArrayChecksumAlgorithm(), new Crc32ByteArrayChecksumAlgorithm(), // NEWCHECKSUM(start) // Here add the creation of an object of your checksum algorithm class and add it to the list, // e.g. // new MyByteArrayChecksumAlgorithm(), // NEWCHECKSUM(end) }; #ifdef HAVE_QCA2 addQca2Algorithm(result, i18nc("name of the hash algorithm", "SHA-0"), "sha0"); addQca2Algorithm(result, i18nc("name of the hash algorithm", "SHA-1"), "sha1"); addQca2Algorithm(result, i18nc("name of the hash algorithm", "MD2"), "md2"); addQca2Algorithm(result, i18nc("name of the hash algorithm", "MD4"), "md4"); addQca2Algorithm(result, i18nc("name of the hash algorithm", "MD5"), "md5"); addQca2Algorithm(result, i18nc("name of the hash algorithm", "RIPEMD160"), "ripemd160"); addQca2Algorithm(result, i18nc("name of the hash algorithm", "SHA-224"), "sha224"); addQca2Algorithm(result, i18nc("name of the hash algorithm", "SHA-256"), "sha256"); addQca2Algorithm(result, i18nc("name of the hash algorithm", "SHA-384"), "sha384"); addQca2Algorithm(result, i18nc("name of the hash algorithm", "SHA-512"), "sha512"); addQca2Algorithm(result, i18nc("name of the hash algorithm", "Whirlpool"), "whirlpool"); #endif return result; } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/andbytearrayfilter.cpp b/kasten/controllers/view/libbytearrayfilter/filter/andbytearrayfilter.cpp index c67a1a07..f3f851be 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/andbytearrayfilter.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/andbytearrayfilter.cpp @@ -1,82 +1,82 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "andbytearrayfilter.hpp" // Okteta core #include -// KF5 +// KF #include AndByteArrayFilter::AndByteArrayFilter() : AbstractByteArrayFilter( i18nc("name of the filter; it does a logic AND operation", "operand AND data")) {} AndByteArrayFilter::~AndByteArrayFilter() = default; AbstractByteArrayFilterParameterSet* AndByteArrayFilter::parameterSet() { return &mParameterSet; } bool AndByteArrayFilter::filter(Okteta::Byte* result, Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { const QByteArray operand = mParameterSet.operand(); const int operandSize = operand.size(); if (mParameterSet.alignAtEnd()) { const int behindLastResult = range.width(); int r = behindLastResult; Okteta::Address m = range.nextBehindEnd(); int nextBlockEnd = r - FilteredByteCountSignalLimit; while (m > range.start()) { int o = operandSize; while (m > range.start() && o > 0) { result[(r--) - 1] = model->byte((m--) - 1) & operand[(o--) - 1]; } if (r <= nextBlockEnd) { nextBlockEnd -= FilteredByteCountSignalLimit; emit filteredBytes(behindLastResult - r); } } } else { int r = 0; Okteta::Address m = range.start(); int nextBlockEnd = FilteredByteCountSignalLimit; while (m <= range.end()) { int o = 0; while (m <= range.end() && o < operandSize) { result[r++] = model->byte(m++) & operand[o++]; } if (r >= nextBlockEnd) { nextBlockEnd += FilteredByteCountSignalLimit; emit filteredBytes(r); } } } return true; } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/invertbytearrayfilter.cpp b/kasten/controllers/view/libbytearrayfilter/filter/invertbytearrayfilter.cpp index 168e76e2..4396dbb9 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/invertbytearrayfilter.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/invertbytearrayfilter.cpp @@ -1,56 +1,56 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "invertbytearrayfilter.hpp" // Okteta core #include -// KF5 +// KF #include InvertByteArrayFilter::InvertByteArrayFilter() : AbstractByteArrayFilter( i18nc("name of the filter; it switches all bits from 0 to 1 and 1 to 0 respectively, so 01111110 becomes 10000001", "INVERT data")) {} InvertByteArrayFilter::~InvertByteArrayFilter() = default; AbstractByteArrayFilterParameterSet* InvertByteArrayFilter::parameterSet() { return &mNoParameterSet; } bool InvertByteArrayFilter::filter(Okteta::Byte* result, Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { int r = 0; Okteta::Address m = range.start(); int nextBlockEnd = FilteredByteCountSignalLimit; while (m <= range.end()) { result[r++] = ~model->byte(m++); if (r >= nextBlockEnd) { nextBlockEnd += FilteredByteCountSignalLimit; emit filteredBytes(r); } } return true; } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/operandbytearrayfilterparametersetedit.cpp b/kasten/controllers/view/libbytearrayfilter/filter/operandbytearrayfilterparametersetedit.cpp index d63a955b..126679d6 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/operandbytearrayfilterparametersetedit.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/operandbytearrayfilterparametersetedit.cpp @@ -1,111 +1,111 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "operandbytearrayfilterparametersetedit.hpp" // #include "operandbytearrayfilterparameterset.hpp" // Okteta Kasten gui #include -// KF5 +// KF #include // Qt #include #include const char OperandByteArrayFilterParameterSetEdit::Id[] = "Operand"; OperandByteArrayFilterParameterSetEdit::OperandByteArrayFilterParameterSetEdit(QWidget* parent) : AbstractByteArrayFilterParameterSetEdit(parent) { auto* baseLayout = new QFormLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); const QString operandLabelText = i18nc("@label:textbox operand to the arithmetic filter function", "Operand:"); mOperandEdit = new Okteta::ByteArrayComboBox(this); connect(mOperandEdit, &Okteta::ByteArrayComboBox::byteArrayChanged, this, &OperandByteArrayFilterParameterSetEdit::onInputChanged); const QString operandToolTip = i18nc("@info:tooltip", "The operand to do the operation with."); const QString operandWhatsThis = i18nc("@info:whatsthis", "Enter an operand, or select a previous operand from the list."); mOperandEdit->setToolTip(operandToolTip); mOperandEdit->setWhatsThis(operandWhatsThis); baseLayout->addRow(operandLabelText, mOperandEdit); const QString alignAtEndLabelText = i18nc("@option:check", "Align at end:"); mAlignAtEndCheckBox = new QCheckBox(this); mAlignAtEndCheckBox->setChecked(false); const QString alignToolTip = i18nc("@info:tooltip", "Sets if the operation will be aligned to the end of the data instead of to the begin."); const QString alignWhatsThis = i18nc("@info:whatsthis", "If set, the operation will be aligned to the end of the data."); mAlignAtEndCheckBox->setToolTip(alignToolTip); mAlignAtEndCheckBox->setWhatsThis(alignWhatsThis); baseLayout->addRow(alignAtEndLabelText, mAlignAtEndCheckBox); } OperandByteArrayFilterParameterSetEdit::~OperandByteArrayFilterParameterSetEdit() = default; bool OperandByteArrayFilterParameterSetEdit::isValid() const { return !mOperandEdit->byteArray().isEmpty(); } void OperandByteArrayFilterParameterSetEdit::setValues(const AbstractByteArrayFilterParameterSet* parameterSet) { const auto* operandParameterSet = static_cast(parameterSet); // mOperandEdit->setValue( operandParameterSet->operand() ); TODO: not yet implemented mAlignAtEndCheckBox->setChecked(operandParameterSet->alignAtEnd()); } void OperandByteArrayFilterParameterSetEdit::setCharCodec(const QString& charCodecName) { mOperandEdit->setCharCodec(charCodecName); } void OperandByteArrayFilterParameterSetEdit::getParameterSet(AbstractByteArrayFilterParameterSet* parameterSet) const { auto* operandParameterSet = static_cast(parameterSet); operandParameterSet->setOperand(mOperandEdit->byteArray()); operandParameterSet->setOperandFormat(mOperandEdit->format()); operandParameterSet->setAlignAtEnd(mAlignAtEndCheckBox->isChecked()); } void OperandByteArrayFilterParameterSetEdit::rememberCurrentSettings() { mOperandEdit->rememberCurrentByteArray(); } void OperandByteArrayFilterParameterSetEdit::onInputChanged(const QByteArray& data) { emit validityChanged(!data.isEmpty()); } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/orbytearrayfilter.cpp b/kasten/controllers/view/libbytearrayfilter/filter/orbytearrayfilter.cpp index 3fa56ef2..52b26c11 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/orbytearrayfilter.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/orbytearrayfilter.cpp @@ -1,82 +1,82 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "orbytearrayfilter.hpp" // Okteta core #include -// KF5 +// KF #include OrByteArrayFilter::OrByteArrayFilter() : AbstractByteArrayFilter( i18nc("name of the filter; it does a logic OR operation", "operand OR data")) {} OrByteArrayFilter::~OrByteArrayFilter() = default; AbstractByteArrayFilterParameterSet* OrByteArrayFilter::parameterSet() { return &mParameterSet; } bool OrByteArrayFilter::filter(Okteta::Byte* result, Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { const QByteArray operand = mParameterSet.operand(); const int operandSize = operand.size(); if (mParameterSet.alignAtEnd()) { const int behindLastResult = range.width(); int r = behindLastResult; Okteta::Address m = range.nextBehindEnd(); int nextBlockEnd = r - FilteredByteCountSignalLimit; while (m > range.start()) { int o = operandSize; while (m > range.start() && o > 0) { result[(r--) - 1] = model->byte((m--) - 1) | operand[(o--) - 1]; } if (r <= nextBlockEnd) { nextBlockEnd -= FilteredByteCountSignalLimit; emit filteredBytes(behindLastResult - r); } } } else { Okteta::Address r = 0; Okteta::Address m = range.start(); Okteta::Address nextBlockEnd = FilteredByteCountSignalLimit; while (m <= range.end()) { int o = 0; while (m <= range.end() && o < operandSize) { result[r++] = model->byte(m++) | operand[o++]; } if (r >= nextBlockEnd) { nextBlockEnd += FilteredByteCountSignalLimit; emit filteredBytes(r); } } } return true; } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/reversebytearrayfilter.cpp b/kasten/controllers/view/libbytearrayfilter/filter/reversebytearrayfilter.cpp index de2faabe..4697df82 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/reversebytearrayfilter.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/reversebytearrayfilter.cpp @@ -1,68 +1,68 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "reversebytearrayfilter.hpp" // Okteta core #include -// KF5 +// KF #include ReverseByteArrayFilter::ReverseByteArrayFilter() : AbstractByteArrayFilter( i18nc("name of the filter; it changes the order of the bytes/bits to backwards, so ABCD becomes DCBA", "REVERSE data")) {} ReverseByteArrayFilter::~ReverseByteArrayFilter() = default; AbstractByteArrayFilterParameterSet* ReverseByteArrayFilter::parameterSet() { return &mParameterSet; } bool ReverseByteArrayFilter::filter(Okteta::Byte* result, Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { Okteta::Size r = range.width() - 1; Okteta::Address m = range.start(); int filteredBytesCount = 0; while (m <= range.end()) { Okteta::Byte byte = model->byte(m++); Okteta::Byte reverseByte; if (mParameterSet.invertsBits()) { reverseByte = 0; for (int b = 7; b >= 0; --b) { reverseByte |= (byte & 0x80) >> b; byte <<= 1; } } else { reverseByte = byte; } result[r--] = reverseByte; ++filteredBytesCount; if (filteredBytesCount >= FilteredByteCountSignalLimit) { filteredBytesCount = 0; emit filteredBytes(m - range.start()); } } return true; } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/reversebytearrayfilterparametersetedit.cpp b/kasten/controllers/view/libbytearrayfilter/filter/reversebytearrayfilterparametersetedit.cpp index ff316b0d..83f3ecd3 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/reversebytearrayfilterparametersetedit.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/reversebytearrayfilterparametersetedit.cpp @@ -1,68 +1,68 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "reversebytearrayfilterparametersetedit.hpp" // #include "reversebytearrayfilterparameterset.hpp" -// KF5 +// KF #include // Qt #include #include const char ReverseByteArrayFilterParameterSetEdit::Id[] = "Reverse"; ReverseByteArrayFilterParameterSetEdit::ReverseByteArrayFilterParameterSetEdit(QWidget* parent) : AbstractByteArrayFilterParameterSetEdit(parent) { auto* baseLayout = new QFormLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); const QString invertsBitsLabelText = i18nc("@option:check", "Reverse also bits:"); mInvertsBitsCheckBox = new QCheckBox(this); mInvertsBitsCheckBox->setChecked(false); const QString alignWhatsThis = i18nc("@info:whatsthis", "If set, the bits are arranged in reverse order as well."); mInvertsBitsCheckBox->setWhatsThis(alignWhatsThis); baseLayout->addRow(invertsBitsLabelText, mInvertsBitsCheckBox); } ReverseByteArrayFilterParameterSetEdit::~ReverseByteArrayFilterParameterSetEdit() = default; void ReverseByteArrayFilterParameterSetEdit::setValues(const AbstractByteArrayFilterParameterSet* parameterSet) { const auto* reverseParameterSet = static_cast(parameterSet); mInvertsBitsCheckBox->setChecked(reverseParameterSet->invertsBits()); } void ReverseByteArrayFilterParameterSetEdit::getParameterSet(AbstractByteArrayFilterParameterSet* parameterSet) const { auto* reverseParameterSet = static_cast(parameterSet); reverseParameterSet->setInvertsBits(mInvertsBitsCheckBox->isChecked()); } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/rotatebytearrayfilter.cpp b/kasten/controllers/view/libbytearrayfilter/filter/rotatebytearrayfilter.cpp index 61cbc502..5e89a9aa 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/rotatebytearrayfilter.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/rotatebytearrayfilter.cpp @@ -1,128 +1,128 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "rotatebytearrayfilter.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include // Std #include static constexpr int RotateBitsPerByte = 8; RotateByteArrayFilter::RotateByteArrayFilter() : AbstractByteArrayFilter( i18nc("name of the filter; it moves the bits and pushes the ones over the end to the begin again", "ROTATE data")) {} RotateByteArrayFilter::~RotateByteArrayFilter() = default; AbstractByteArrayFilterParameterSet* RotateByteArrayFilter::parameterSet() { return &mParameterSet; } bool RotateByteArrayFilter::filter(Okteta::Byte* result, Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { const int groupSize = mParameterSet.groupSize(); const int groupBitCount = (groupSize * RotateBitsPerByte); const int groupShiftBitWidth = std::abs(mParameterSet.moveBitWidth()) % groupBitCount; const int shiftByteWidth = groupShiftBitWidth / RotateBitsPerByte; const int shiftBitWidth = groupShiftBitWidth - shiftByteWidth * RotateBitsPerByte; const int otherShiftBitWidth = RotateBitsPerByte - shiftBitWidth; int filteredBytesCount = 0; const bool toRight = (mParameterSet.moveBitWidth() > 0); if (toRight) { int r = 0; Okteta::Address m = range.start(); while (m <= range.end()) { int g = 0; // round the edge byte layer shift while (g < shiftByteWidth && m + groupSize <= range.end()) { result[r++] = model->byte((m++) + groupSize - shiftByteWidth); ++g; } // normal byte layer shift while (g < groupSize && m <= range.end()) { result[r++] = model->byte((m++) - shiftByteWidth); ++g; } // bit layer shift const unsigned char last = (unsigned char) result[r - 1]; for (int b = 1; b <= g; ++b) { result[r - b] = (unsigned char)result[r - b] >> shiftBitWidth; if (b < g) { result[r - b] |= (unsigned char)result[r - b - 1] << otherShiftBitWidth; } else if (g == groupSize) { result[r - b] |= last << otherShiftBitWidth; } } filteredBytesCount += g; if (filteredBytesCount >= FilteredByteCountSignalLimit) { filteredBytesCount = 0; emit filteredBytes(m - range.start()); } } } else { int r = 0; Okteta::Address m = range.start(); while (m <= range.end()) { int g = 0; // normal byte layer shift while (g + shiftByteWidth < groupSize && m + shiftByteWidth <= range.end()) { result[r++] = model->byte((m++) - shiftByteWidth); ++g; } // round the edge byte layer shift while (g < groupSize && m <= range.end()) { result[r++] = model->byte((m++) + shiftByteWidth - groupSize); ++g; } // bit layer shift const unsigned char first = result[r - g]; for (int b = g; b > 0; --b) { result[r - b] = (unsigned char)result[r - b] << shiftBitWidth; if (b > 1) { result[r - b] |= (unsigned char)result[r - b + 1] >> otherShiftBitWidth; } else if (g == groupSize) { result[r - b] |= first >> otherShiftBitWidth; } } filteredBytesCount += g; if (filteredBytesCount >= FilteredByteCountSignalLimit) { filteredBytesCount = 0; emit filteredBytes(m - range.start()); } } } return true; } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/rotatebytearrayfilterparametersetedit.cpp b/kasten/controllers/view/libbytearrayfilter/filter/rotatebytearrayfilterparametersetedit.cpp index 5f182686..02ba2472 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/rotatebytearrayfilterparametersetedit.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/rotatebytearrayfilterparametersetedit.cpp @@ -1,101 +1,101 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "rotatebytearrayfilterparametersetedit.hpp" // parameterset #include "rotatebytearrayfilterparameterset.hpp" -// KF5 +// KF #include // Qt #include #include const char RotateByteArrayFilterParameterSetEdit::Id[] = "Rotate"; RotateByteArrayFilterParameterSetEdit::RotateByteArrayFilterParameterSetEdit(QWidget* parent) : AbstractByteArrayFilterParameterSetEdit(parent) { auto* baseLayout = new QFormLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); mGroupSizeEdit = new QSpinBox(this); mGroupSizeEdit->setRange(1, INT_MAX); const QString groupSizeLabelText = i18nc("@label:spinbox number of bytes the movement is done within", "&Group size (bytes):"); const QString groupSizeToolTip = i18nc("@info:tooltip", "The number of bytes within which each movement is made."); mGroupSizeEdit->setToolTip(groupSizeToolTip); const QString groupSizeWhatsThis = i18nc("@info:whatsthis", "Control the number of bytes within which each movement is made."); mGroupSizeEdit->setWhatsThis(groupSizeWhatsThis); baseLayout->addRow(groupSizeLabelText, mGroupSizeEdit); mMoveBitWidthEdit = new QSpinBox(this); mMoveBitWidthEdit->setRange(INT_MIN, INT_MAX); connect(mMoveBitWidthEdit, QOverload::of(&QSpinBox::valueChanged), this, &RotateByteArrayFilterParameterSetEdit::onValueChanged); const QString moveBitWidthLabelText = i18nc("@label:spinbox width (in number of bits) the bits are moved", "S&hift width (bits):"); const QString moveBitWidthToolTip = i18nc("@info:tooltip", "The width of the shift. Positive numbers move the bits to the right, negative to the left."); mMoveBitWidthEdit->setToolTip(moveBitWidthToolTip); const QString moveBitWidthWhatsThis = i18nc("@info:whatsthis", "Control the width of the shift. Positive numbers move the bits to the right, negative to the left."); mMoveBitWidthEdit->setWhatsThis(moveBitWidthWhatsThis); baseLayout->addRow(moveBitWidthLabelText, mMoveBitWidthEdit); } RotateByteArrayFilterParameterSetEdit::~RotateByteArrayFilterParameterSetEdit() = default; bool RotateByteArrayFilterParameterSetEdit::isValid() const { return mMoveBitWidthEdit->value() != 0; } void RotateByteArrayFilterParameterSetEdit::setValues(const AbstractByteArrayFilterParameterSet* parameterSet) { const auto* rotateParameterSet = static_cast(parameterSet); mGroupSizeEdit->setValue(rotateParameterSet->groupSize()); mMoveBitWidthEdit->setValue(rotateParameterSet->moveBitWidth()); } void RotateByteArrayFilterParameterSetEdit::getParameterSet(AbstractByteArrayFilterParameterSet* parameterSet) const { auto* rotateParameterSet = static_cast(parameterSet); rotateParameterSet->setGroupSize(mGroupSizeEdit->value()); rotateParameterSet->setMoveBitWidth(mMoveBitWidthEdit->value()); } void RotateByteArrayFilterParameterSetEdit::onValueChanged(int value) { emit validityChanged(value != 0); } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/shiftbytearrayfilter.cpp b/kasten/controllers/view/libbytearrayfilter/filter/shiftbytearrayfilter.cpp index 79db23f7..0746c929 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/shiftbytearrayfilter.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/shiftbytearrayfilter.cpp @@ -1,124 +1,124 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "shiftbytearrayfilter.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include // Std #include // TODO: add option which bit (0/1) to insert static constexpr int ShiftBitsPerByte = 8; ShiftByteArrayFilter::ShiftByteArrayFilter() : AbstractByteArrayFilter( i18nc("name of the filter; it moves the bits, setting freed ones to zero", "SHIFT data")) {} ShiftByteArrayFilter::~ShiftByteArrayFilter() = default; AbstractByteArrayFilterParameterSet* ShiftByteArrayFilter::parameterSet() { return &mParameterSet; } bool ShiftByteArrayFilter::filter(Okteta::Byte* result, Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { const int groupSize = mParameterSet.groupSize(); const int groupBitCount = (groupSize * ShiftBitsPerByte); const int groupShiftBitWidth = std::abs(mParameterSet.moveBitWidth()) % groupBitCount; const int shiftByteWidth = groupShiftBitWidth / ShiftBitsPerByte; const int shiftBitWidth = groupShiftBitWidth - shiftByteWidth * ShiftBitsPerByte; const int otherShiftBitWidth = ShiftBitsPerByte - shiftBitWidth; int filteredBytesCount = 0; const bool toRight = (mParameterSet.moveBitWidth() > 0); if (toRight) { int r = 0; Okteta::Address m = range.start(); while (m <= range.end()) { int g = 0; // full free bytes while (g < shiftByteWidth && m <= range.end()) { result[r++] = 0; ++m; ++g; } // byte layer shift while (g < groupSize && m <= range.end()) { result[r++] = model->byte((m++) - shiftByteWidth); ++g; } // bit layer shift for (int b = 1; b <= g; ++b) { result[r - b] = (unsigned char)result[r - b] >> shiftBitWidth; if (b < g) { result[r - b] |= (unsigned char)result[r - b - 1] << otherShiftBitWidth; } } filteredBytesCount += g; if (filteredBytesCount >= FilteredByteCountSignalLimit) { filteredBytesCount = 0; emit filteredBytes(m - range.start()); } } } else { int r = 0; Okteta::Address m = range.start(); while (m <= range.end()) { int g = 0; // byte layer shift while (g + shiftByteWidth < groupSize && m + shiftByteWidth <= range.end()) { result[r++] = model->byte((m++) + shiftByteWidth); ++g; } // full free bytes while (g < groupSize && m <= range.end()) { result[r++] = 0; ++m; ++g; } // bit layer shift for (int b = g; b > 0; --b) { result[r - b] = (unsigned char)result[r - b] << shiftBitWidth; if (b > 1) { result[r - b] |= (unsigned char)result[r - b + 1] >> otherShiftBitWidth; } } filteredBytesCount += g; if (filteredBytesCount >= FilteredByteCountSignalLimit) { filteredBytesCount = 0; emit filteredBytes(m - range.start()); } } } return true; } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/template/template_bytearrayfilter.cpp b/kasten/controllers/view/libbytearrayfilter/filter/template/template_bytearrayfilter.cpp index d7243142..010958f6 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/template/template_bytearrayfilter.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/template/template_bytearrayfilter.cpp @@ -1,61 +1,61 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau Public domain. */ //// ADAPT(start) //// rename "template_bytearrayfilter.hpp" to the name of the header of your filter, //// e.g. "mybytearrayfilter.hpp" #include "template_bytearrayfilter.hpp" //// ADAPT(end) // Okteta core #include -// KF5 +// KF #include Template_ByteArrayFilter::Template_ByteArrayFilter() : AbstractByteArrayFilter( //// ADAPT(start) //// change "TEMPLATE OPERATION ON" to a short and descriptive name of the operation of this filter, also in upper case i18nc("name of the filter; it does a TEMPLATE OPERATION ON operation", "TEMPLATE OPERATION ON data")) //// ADAPT(end) {} Template_ByteArrayFilter::~Template_ByteArrayFilter() = default; AbstractByteArrayFilterParameterSet* Template_ByteArrayFilter::parameterSet() { return &mParameterSet; } bool Template_ByteArrayFilter::filter(Okteta::Byte* result, Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { bool success = true; //// ADAPT(start) //// modify the following code to write the filtered bytes into the array pointed to by result //// The array is as large as range and not initialized to a value. const unsigned int level = mParameterSet.level(); int r = 0; Okteta::Address m = range.start(); int nextBlockEnd = FilteredByteCountSignalLimit; while (m <= range.end()) { // example code turns all bytes larger than level into 255, the others to 0 const Okteta::Byte byte = model->byte(m++); const Okteta::Byte resultByte = (byte > level) ? 255 : 0; result[r++] = resultByte; if (r >= nextBlockEnd) { nextBlockEnd += FilteredByteCountSignalLimit; emit filteredBytes(r); } } //// ADAPT(end) return success; } diff --git a/kasten/controllers/view/libbytearrayfilter/filter/template/template_bytearrayfilterparametersetedit.cpp b/kasten/controllers/view/libbytearrayfilter/filter/template/template_bytearrayfilterparametersetedit.cpp index fc98bcbf..1a50901b 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/template/template_bytearrayfilterparametersetedit.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/template/template_bytearrayfilterparametersetedit.cpp @@ -1,115 +1,115 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau Public domain. */ //// ADAPT(start) //// rename "template_bytearrayfilterparametersetedit.hpp" to the name of the header of your filter, //// e.g. "mybytearrayfilterparametersetedit.hpp" #include "template_bytearrayfilterparametersetedit.hpp" //// ADAPT(end) // parameterset //// ADAPT(start) //// rename "template_bytearrayfilterparameterset.hpp" to the name of the header of your filter, //// e.g. "mybytearrayfilterparameterset.hpp" #include "template_bytearrayfilterparameterset.hpp" //// ADAPT(end) -// KF5 +// KF #include //// ADAPT(start) //// add includes for all elements used in the widget #include // Qt #include //// ADAPT(end) //// ADAPT(start) //// rename "Template_ParameterSetId" to the id of your parameterset, //// e.g. "MyParameterSet" const char Template_ByteArrayFilterParameterSetEdit::Id[] = "Template_ParameterSetId"; //// ADAPT(end) Template_ByteArrayFilterParameterSetEdit::Template_ByteArrayFilterParameterSetEdit(QWidget* parent) : AbstractByteArrayFilterParameterSetEdit(parent) { //// ADAPT(start) //// setup the widget with all edit fields needed for the parameter set //// if there can be invalid states connect the change signals of the edit fields to some slots //// where you check if the validity changed auto* baseLayout = new QFormLayout(this); // margin is provided by the container for this widget baseLayout->setContentsMargins(0, 0, 0, 0); mLevelEdit = new QSpinBox(this); // For demonstration purpose we start at -1, not 0, to show handling of an invalid state // Otherwise the range should start at 0 and there is no need to connect to the valueChanged signal mLevelEdit->setRange(-1, 256); // start with the invalid number mLevelEdit->setValue(-1); connect(mLevelEdit, QOverload::of(&QSpinBox::valueChanged), this, &Template_ByteArrayFilterParameterSetEdit::onLevelChanged); const QString levelLabelText = i18nc("@label:spinbox decimal value up to which bytes are set to 0", "Level:"); const QString levelToolTip = i18nc("@info:tooltip", "The decimal value up to which the bytes are set to x00. Bytes above this value are set to x01."); mLevelEdit->setToolTip(levelToolTip); const QString levelWhatsThis = i18nc("@info:whatsthis", "Control the value which decides how the bytes are ending up. And more explanation."); mLevelEdit->setWhatsThis(levelWhatsThis); baseLayout->addRow(levelLabelText, mLevelEdit); // note start state mIsValid = isValid(); //// ADAPT(end) } Template_ByteArrayFilterParameterSetEdit::~Template_ByteArrayFilterParameterSetEdit() = default; //// ADAPT(start) //// if invalid states are possible implement here the check bool Template_ByteArrayFilterParameterSetEdit::isValid() const { return mLevelEdit->value() != -1; } //// ADAPT(end) //// ADAPT(start) //// change "Template_ByteArrayFilterParameterSet" to the class of the parameter set which this widget should edit //// e.g. "MyByteArrayFilterParameterSet" //// also adapt the passing of the values between the parameter set and the edit fields void Template_ByteArrayFilterParameterSetEdit::setValues(const AbstractByteArrayFilterParameterSet* parameterSet) { const auto* template_ParameterSet = static_cast(parameterSet); mLevelEdit->setValue(template_ParameterSet->level()); } void Template_ByteArrayFilterParameterSetEdit::getParameterSet(AbstractByteArrayFilterParameterSet* parameterSet) const { auto* template_ParameterSet = static_cast(parameterSet); template_ParameterSet->setLevel(mLevelEdit->value()); } //// ADAPT(end) //// ADAPT(start) //// define the slots to catch changes in the values to check if the current state is valid or not //// not needed if there cannot be invalid states void Template_ByteArrayFilterParameterSetEdit::onLevelChanged(int value) { const bool isValid = (value != -1); if (mIsValid == isValid) { return; } mIsValid = isValid; emit validityChanged(isValid); } //// ADAPT(end) diff --git a/kasten/controllers/view/libbytearrayfilter/filter/xorbytearrayfilter.cpp b/kasten/controllers/view/libbytearrayfilter/filter/xorbytearrayfilter.cpp index 40f79e05..e2afd767 100644 --- a/kasten/controllers/view/libbytearrayfilter/filter/xorbytearrayfilter.cpp +++ b/kasten/controllers/view/libbytearrayfilter/filter/xorbytearrayfilter.cpp @@ -1,82 +1,82 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "xorbytearrayfilter.hpp" // Okteta core #include -// KF5 +// KF #include XOrByteArrayFilter::XOrByteArrayFilter() : AbstractByteArrayFilter( i18nc("name of the filter; it does a logic XOR operation", "operand XOR data")) {} XOrByteArrayFilter::~XOrByteArrayFilter() = default; AbstractByteArrayFilterParameterSet* XOrByteArrayFilter::parameterSet() { return &mParameterSet; } bool XOrByteArrayFilter::filter(Okteta::Byte* result, Okteta::AbstractByteArrayModel* model, const Okteta::AddressRange& range) const { const QByteArray operand = mParameterSet.operand(); const int operandSize = operand.size(); if (mParameterSet.alignAtEnd()) { const int behindLastResult = range.width(); int r = behindLastResult; Okteta::Address m = range.nextBehindEnd(); int nextBlockEnd = r - FilteredByteCountSignalLimit; while (m > range.start()) { int o = operandSize; while (m > range.start() && o > 0) { result[(r--) - 1] = model->byte((m--) - 1) ^ operand[(o--) - 1]; } if (r <= nextBlockEnd) { nextBlockEnd -= FilteredByteCountSignalLimit; emit filteredBytes(behindLastResult - r); } } } else { int r = 0; Okteta::Address m = range.start(); int nextBlockEnd = FilteredByteCountSignalLimit; while (m <= range.end()) { int o = 0; while (m <= range.end() && o < operandSize) { result[r++] = model->byte(m++) ^ operand[o++]; } if (r >= nextBlockEnd) { nextBlockEnd += FilteredByteCountSignalLimit; emit filteredBytes(r); } } } return true; } diff --git a/kasten/controllers/view/libfinddialog/abstractfinddialog.cpp b/kasten/controllers/view/libfinddialog/abstractfinddialog.cpp index 8eb58713..c27c8981 100644 --- a/kasten/controllers/view/libfinddialog/abstractfinddialog.cpp +++ b/kasten/controllers/view/libfinddialog/abstractfinddialog.cpp @@ -1,219 +1,219 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2007 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "abstractfinddialog.hpp" // Okteta Kasten gui #include // Okteta core #include -// KF5 +// KF #include // Qt #include #include #include #include #include #include namespace Kasten { AbstractFindDialog::AbstractFindDialog(QWidget* parent) : QDialog(parent) { // main widget QWidget* mainWidget = new QWidget; MainWidgetLayout = new QVBoxLayout(mainWidget); MainWidgetLayout->setContentsMargins(0, 0, 0, 0); // dialog buttons auto* dialogButtonBox = new QDialogButtonBox; FindButton = new QPushButton; dialogButtonBox->addButton(FindButton, QDialogButtonBox::AcceptRole); connect(dialogButtonBox, &QDialogButtonBox::accepted, this, &AbstractFindDialog::forwardFindButtonClicked); dialogButtonBox->addButton(QDialogButtonBox::Cancel); connect(dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); // main layout auto* layout = new QVBoxLayout; layout->addWidget(mainWidget); layout->addStretch(); layout->addWidget(dialogButtonBox); setLayout(layout); // TODO: setting ok button to disabled as before done gets overwritten to true // if setting the button gui with an inline KGuiItem in the subclass, // which has no parameter for enabled and defaults to true } AbstractFindDialog::~AbstractFindDialog() = default; void AbstractFindDialog::setFindButton(const QString& buttonText, const QString& buttonIconName, const QString& buttonToolTip, const QString& buttonWhatsThis) { FindButton->setText(buttonText); FindButton->setIcon(QIcon::fromTheme(buttonIconName)); FindButton->setToolTip(buttonToolTip); FindButton->setWhatsThis(buttonWhatsThis); } void AbstractFindDialog::setFindButtonEnabled(bool enabled) { FindButton->setEnabled(enabled); } void AbstractFindDialog::setupFindBox() { // find term QGroupBox* findBox = new QGroupBox(i18nc("@title:window", "Find")); MainWidgetLayout->addWidget(findBox); auto* findBoxLayout = new QVBoxLayout; SearchDataEdit = new Okteta::ByteArrayComboBox(findBox); connect(SearchDataEdit, &Okteta::ByteArrayComboBox::byteArrayChanged, this, &AbstractFindDialog::onSearchDataChanged); connect(SearchDataEdit, &Okteta::ByteArrayComboBox::formatChanged, this, &AbstractFindDialog::onSearchDataFormatChanged); const QString toolTip = i18nc("@info:tooltip", "Enter the bytes to search for, or select bytes previously searched for from the list."); SearchDataEdit->setToolTip(toolTip); findBoxLayout->addWidget(SearchDataEdit); findBox->setLayout(findBoxLayout); } void AbstractFindDialog::setupOperationBox(QGroupBox* operationBox) { // operation box if (operationBox) { MainWidgetLayout->addWidget(operationBox); } } void AbstractFindDialog::setupCheckBoxes(QCheckBox* optionCheckBox) { // options QGroupBox* optionsBox = new QGroupBox(i18nc("@title:group", "Options")); MainWidgetLayout->addWidget(optionsBox); auto* optionsBoxLayout = new QGridLayout(optionsBox); CaseSensitiveCheckBox = new QCheckBox(i18nc("@option:check", "C&ase sensitive"), optionsBox); CaseSensitiveCheckBox->setWhatsThis(i18nc("@info:whatsthis", "Perform a case sensitive search: " "entering the pattern 'Joe' will not match 'joe' or 'JOE', only 'Joe'.")); WholeWordsCheckBox = new QCheckBox(i18nc("@option:check", "&Whole words only"), optionsBox); WholeWordsCheckBox->setWhatsThis(i18nc("@info:whatsthis", "Require word boundaries in both ends of a match to succeed.")); AtCursorCheckBox = new QCheckBox(i18nc("@option:check", "From c&ursor"), optionsBox); AtCursorCheckBox->setWhatsThis(i18nc("@info:whatsthis", "Start searching at the current cursor location rather than at the top.")); BackwardsCheckBox = new QCheckBox(i18nc("@option:check", "&Backwards"), optionsBox); BackwardsCheckBox->setWhatsThis(i18nc("@info:whatsthis", "Replace backwards.")); SelectedCheckBox = new QCheckBox(i18nc("@option:check", "&Selected bytes"), optionsBox); SelectedCheckBox->setWhatsThis(i18nc("@info:whatsthis", "Only search within the current selection.")); optionsBoxLayout->addWidget(CaseSensitiveCheckBox, 0, 0); optionsBoxLayout->addWidget(WholeWordsCheckBox, 1, 0); optionsBoxLayout->addWidget(AtCursorCheckBox, 2, 0); optionsBoxLayout->addWidget(BackwardsCheckBox, 0, 1); optionsBoxLayout->addWidget(SelectedCheckBox, 1, 1); if (optionCheckBox) { optionsBoxLayout->addWidget(optionCheckBox, 2, 1); } setTabOrder(CaseSensitiveCheckBox, WholeWordsCheckBox); setTabOrder(WholeWordsCheckBox, AtCursorCheckBox); setTabOrder(AtCursorCheckBox, BackwardsCheckBox); setTabOrder(BackwardsCheckBox, SelectedCheckBox); // if( optionCheckBox ) // setTabOrder( SelectedCheckBox, optionCheckBox ); onSearchDataFormatChanged(SearchDataEdit->format()); } bool AbstractFindDialog::fromCursor() const { return AtCursorCheckBox->isChecked(); } bool AbstractFindDialog::inSelection() const { return SelectedCheckBox->isChecked(); } FindDirection AbstractFindDialog::direction() const { return BackwardsCheckBox->isChecked() ? FindBackward : FindForward; } Qt::CaseSensitivity AbstractFindDialog::caseSensitivity() const { return (SearchDataEdit->format() == Okteta::ByteArrayComboBox::CharCoding) && !CaseSensitiveCheckBox->isChecked() ? Qt::CaseInsensitive : Qt::CaseSensitive; } QByteArray AbstractFindDialog::data() const { return SearchDataEdit->byteArray(); } void AbstractFindDialog::setDirection(FindDirection Direction) { BackwardsCheckBox->setChecked(Direction == FindBackward); } void AbstractFindDialog::setInSelection(bool InSelection) { SelectedCheckBox->setChecked(InSelection); } void AbstractFindDialog::setCharCodec(const QString& codecName) { SearchDataEdit->setCharCodec(codecName); } void AbstractFindDialog::rememberCurrentSettings() { SearchDataEdit->rememberCurrentByteArray(); } void AbstractFindDialog::onFindButtonClicked() { } void AbstractFindDialog::onSearchDataFormatChanged(int index) { const bool isCharCoding = (index == Okteta::ByteArrayComboBox::CharCoding); CaseSensitiveCheckBox->setEnabled(isCharCoding); WholeWordsCheckBox->setEnabled(false); // isCharCoding ); TODO: not implemented! } void AbstractFindDialog::onSearchDataChanged(const QByteArray& data) { FindButton->setEnabled(!data.isEmpty()); } void AbstractFindDialog::forwardFindButtonClicked() { onFindButtonClicked(); } void AbstractFindDialog::showEvent(QShowEvent* showEvent) { QDialog::showEvent(showEvent); SearchDataEdit->setFocus(); } } diff --git a/kasten/controllers/view/overwritemode/overwritemodecontroller.cpp b/kasten/controllers/view/overwritemode/overwritemodecontroller.cpp index 44d706f6..4939da3c 100644 --- a/kasten/controllers/view/overwritemode/overwritemodecontroller.cpp +++ b/kasten/controllers/view/overwritemode/overwritemodecontroller.cpp @@ -1,78 +1,78 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "overwritemodecontroller.hpp" // Okteta Kasten gui #include -// KF5 +// KF #include #include #include #include namespace Kasten { OverwriteModeController::OverwriteModeController(KXMLGUIClient* guiClient) { KActionCollection* actionCollection = guiClient->actionCollection(); mSetOverWriteAction = new KToggleAction(i18nc("@option:check set the view into overwrite mode", "Overwr&ite Mode"), this); mSetOverWriteAction->setWhatsThis( i18nc("@info:whatsthis", "Choose whether you want the input to be inserted or to overwrite existing data.")); // TODO: or should we catch the signal from the view (needs to be added) actionCollection->setDefaultShortcut(mSetOverWriteAction, QKeySequence(Qt::Key_Insert)); connect(mSetOverWriteAction, &KToggleAction::triggered, this, &OverwriteModeController::setOverWrite); actionCollection->addAction(QStringLiteral("set_overwrite"), mSetOverWriteAction); setTargetModel(nullptr); } void OverwriteModeController::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(mSetOverWriteAction); } mByteArrayView = model ? model->findBaseModel() : nullptr; if (mByteArrayView) { mSetOverWriteAction->setChecked(mByteArrayView->isOverwriteMode()); connect(mByteArrayView, &ByteArrayView::overwriteModeChanged, mSetOverWriteAction, &KToggleAction::setChecked); // TODO: catch if isOverwriteOnly changes } const bool canInsert = mByteArrayView && !mByteArrayView->isOverwriteOnly(); mSetOverWriteAction->setEnabled(canInsert); } void OverwriteModeController::setOverWrite(bool isOverWrite) { mByteArrayView->setOverwriteMode(isOverWrite); } } diff --git a/kasten/controllers/view/poddecoder/poddecodertool.cpp b/kasten/controllers/view/poddecoder/poddecodertool.cpp index fb7de28f..941a7316 100644 --- a/kasten/controllers/view/poddecoder/poddecodertool.cpp +++ b/kasten/controllers/view/poddecoder/poddecodertool.cpp @@ -1,345 +1,345 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007-2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "poddecodertool.hpp" // lib #include "typecodecs/binary8codec.hpp" #include "typecodecs/octal8codec.hpp" #include "typecodecs/hexadecimal8codec.hpp" #include "typecodecs/uint8codec.hpp" #include "typecodecs/uint16codec.hpp" #include "typecodecs/uint32codec.hpp" #include "typecodecs/uint64codec.hpp" #include "typecodecs/sint8codec.hpp" #include "typecodecs/sint16codec.hpp" #include "typecodecs/sint32codec.hpp" #include "typecodecs/sint64codec.hpp" #include "typecodecs/float32codec.hpp" #include "typecodecs/float64codec.hpp" #include "typecodecs/char8codec.hpp" #include "typecodecs/utf8codec.hpp" #include "abstracttypecodec.hpp" #include "abstractdifferentsizedialog.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include #include #include -// KF5 +// KF #include namespace Kasten { enum PODTypes { BinaryId = 0, OctalId, HexadecimalId, Signed8BitId, Unsigned8BitId, Signed16BitId, Unsigned16BitId, Signed32BitId, Unsigned32BitId, Signed64BitId, Unsigned64BitId, Float32BitId, Float64BitId, Char8BitId, UTF8Id, // UTF16Id, PODTypeCount }; PODDecoderTool::PODDecoderTool() : mReadOnly(true) , mIsPodMarked(false) , mCharCodec(Okteta::CharCodec::createCodec(Okteta::LocalEncoding)) , mUnsignedAsHex(true) { setObjectName(QStringLiteral("PODDecoder")); setupDecoder(); } PODDecoderTool::~PODDecoderTool() { delete mCharCodec; qDeleteAll(mTypeCodecs); } QString PODDecoderTool::title() const { return i18nc("@title:window", "Decoding Table"); } bool PODDecoderTool::isReadOnly() const { return mReadOnly; } bool PODDecoderTool::isApplyable() const { return (mByteArrayModel != nullptr); } void PODDecoderTool::setTargetModel(AbstractModel* model) { const bool oldIsApplyable = isApplyable(); if (mByteArrayView) { mByteArrayView->disconnect(this); if (mIsPodMarked) { unmarkPOD(); } } if (mByteArrayModel) { mByteArrayModel->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; if (mByteArrayModel && mByteArrayView) { mCursorIndex = mByteArrayView->cursorPosition(); connect(mByteArrayView, &ByteArrayView::cursorPositionChanged, this, &PODDecoderTool::onCursorPositionChange); connect(mByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, this, &PODDecoderTool::onContentsChange); connect(mByteArrayView, &ByteArrayView::charCodecChanged, this, &PODDecoderTool::onCharCodecChange); connect(mByteArrayView, &ByteArrayView::readOnlyChanged, this, &PODDecoderTool::onReadOnlyChanged); onCharCodecChange(mByteArrayView->charCodingName()); } updateData(); onReadOnlyChanged(); const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void PODDecoderTool::setupDecoder() { mTypeCodecs.resize(PODTypeCount); mTypeCodecs[BinaryId] = new Okteta::Binary8Codec(); mTypeCodecs[OctalId] = new Okteta::Octal8Codec(); mTypeCodecs[HexadecimalId] = new Okteta::Hexadecimal8Codec(); mTypeCodecs[Signed8BitId] = new Okteta::SInt8Codec(); mTypeCodecs[Unsigned8BitId] = new Okteta::UInt8Codec(); mTypeCodecs[Signed16BitId] = new Okteta::SInt16Codec(); mTypeCodecs[Unsigned16BitId] = new Okteta::UInt16Codec(); mTypeCodecs[Signed32BitId] = new Okteta::SInt32Codec(); mTypeCodecs[Unsigned32BitId] = new Okteta::UInt32Codec(); mTypeCodecs[Signed64BitId] = new Okteta::SInt64Codec(); mTypeCodecs[Unsigned64BitId] = new Okteta::UInt64Codec(); mTypeCodecs[Float32BitId] = new Okteta::Float32Codec(); mTypeCodecs[Float64BitId] = new Okteta::Float64Codec(); mTypeCodecs[Char8BitId] = new Okteta::Char8Codec(mCharCodec); mTypeCodecs[UTF8Id] = new Okteta::Utf8Codec(); #if 0 mDecoderNameList[UTF16Id] = i18nc("@label:textbox", "UTF-16:"); #endif mDecodedValueList.resize(PODTypeCount); mDecodedValueByteCountList.resize(PODTypeCount); } void PODDecoderTool::setDifferentSizeDialog(AbstractDifferentSizeDialog* differentSizeDialog) { mDifferentSizeDialog = differentSizeDialog; } void PODDecoderTool::setUnsignedAsHex(bool unsignedAsHex) { if (mUnsignedAsHex == unsignedAsHex) { return; } mUnsignedAsHex = unsignedAsHex; updateData(); } void PODDecoderTool::setByteOrder(int byteOrder) { // TODO: test on no change is done in PODData, not this level mPODData.setByteOrder((QSysInfo::Endian)byteOrder); updateData(); } void PODDecoderTool::onCharCodecChange(const QString& codecName) { if (codecName == mCharCodec->name()) { return; } delete mCharCodec; mCharCodec = Okteta::CharCodec::createCodec(codecName); static_cast(mTypeCodecs[Char8BitId])->setCharCodec(mCharCodec); updateData(); } void PODDecoderTool::onCursorPositionChange(Okteta::Address pos) { mCursorIndex = pos; updateData(); } void PODDecoderTool::onContentsChange() { // TODO: only update if affected updateData(); } int PODDecoderTool::podCount() const { return mTypeCodecs.count(); } QString PODDecoderTool::nameOfPOD(int podId) const { return mTypeCodecs[podId]->name(); } QVariant PODDecoderTool::value(int podId) const { // TODO: add caching here return mDecodedValueList[podId]; } void PODDecoderTool::setData(const QVariant& data, int podId) { Okteta::AbstractTypeCodec* typeCodec = mTypeCodecs[podId]; // QVariant::operator=() only compares values' addresses for custom types, // so the comparison for values needs to be done by someone with knowledge about the type. const bool isUnchangedValue = typeCodec->areEqual(data, mDecodedValueList[podId]); if (isUnchangedValue) { return; } QByteArray bytes = typeCodec->valueToBytes(data); const int bytesSize = bytes.size(); if (bytesSize == 0) { return; } // need to swap the bytes if (mPODData.byteOrder() != QSysInfo::ByteOrder) { const int firstHalfBytesCount = bytesSize / 2; int j = bytesSize - 1; for (int i = 0; i < firstHalfBytesCount; ++i, --j) { const char helper = bytes[i]; bytes[i] = bytes[j]; bytes[j] = helper; } } const int oldValueSize = mDecodedValueByteCountList[podId]; int removedBytesSize = bytesSize; if (bytesSize != oldValueSize) { // const int sizeLeft = mByteArrayModel->size() - mCursorIndex; const Answer answer = Cancel; // TODO: non-persistent editor closes on new dialog -> crash after dialog // mDifferentSizeDialog ? mDifferentSizeDialog->query( bytesSize, oldValueSize, sizeLeft ) : Cancel; if (answer == Cancel) { return; } if (answer == AdaptSize) { removedBytesSize = oldValueSize; } } Okteta::ChangesDescribable* changesDescribable = qobject_cast(mByteArrayModel); if (changesDescribable) { changesDescribable->openGroupedChange(i18nc("Edited as %datatype", "Edited as %1", typeCodec->name())); } mByteArrayModel->replace(Okteta::AddressRange::fromWidth(mCursorIndex, removedBytesSize), bytes); if (changesDescribable) { changesDescribable->closeGroupedChange(); } } void PODDecoderTool::updateData() { int dataSize; if (mByteArrayModel) { dataSize = mByteArrayModel->size() - mCursorIndex; if (dataSize > Okteta::PODData::Size) { dataSize = Okteta::PODData::Size; } else if (dataSize < 0) { dataSize = 0; } } else { dataSize = 0; } const bool hasDataSet = (dataSize > 0); if (hasDataSet) { mByteArrayModel->copyTo(mPODData.rawData(), mCursorIndex, Okteta::PODData::Size); } const bool hasChanged = mPODData.updateRawData(dataSize); if (!hasChanged) { return; } // TODO: only calculate on demand + cache for (int podId = 0; podId < PODTypeCount; ++podId) { int byteCount = 0; mDecodedValueList[podId] = mTypeCodecs[podId]->value(mPODData, &byteCount); mDecodedValueByteCountList[podId] = byteCount; } // TODO: only emit for those strings that changed emit dataChanged(); } void PODDecoderTool::markPOD(int podId) { const int length = mDecodedValueByteCountList[podId]; const Okteta::AddressRange markingRange = Okteta::AddressRange::fromWidth(mCursorIndex, length); mByteArrayView->setMarking(markingRange, true); mIsPodMarked = true; } void PODDecoderTool::unmarkPOD() { // TODO: marked region is property of document, not view? mByteArrayView->setMarking(Okteta::AddressRange()); mIsPodMarked = false; } void PODDecoderTool::onReadOnlyChanged() { const bool newReadOnly = ((!mByteArrayModel) || (!mByteArrayView) || mByteArrayView->isReadOnly()); if (newReadOnly != mReadOnly) { mReadOnly = newReadOnly; emit readOnlyChanged(newReadOnly); } } } diff --git a/kasten/controllers/view/poddecoder/poddecodertoolviewfactory.cpp b/kasten/controllers/view/poddecoder/poddecodertoolviewfactory.cpp index 3936dbd5..e123e26d 100644 --- a/kasten/controllers/view/poddecoder/poddecodertoolviewfactory.cpp +++ b/kasten/controllers/view/poddecoder/poddecodertoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "poddecodertoolviewfactory.hpp" // lib #include "poddecodertoolview.hpp" #include "poddecodertool.hpp" -// KF5 +// KF #include namespace Kasten { PodDecoderToolViewFactory::PodDecoderToolViewFactory() = default; PodDecoderToolViewFactory::~PodDecoderToolViewFactory() = default; QString PodDecoderToolViewFactory::iconName() const { return QStringLiteral("okteta"); } QString PodDecoderToolViewFactory::title() const { return i18nc("@title:window", "Decoding Table"); } QString PodDecoderToolViewFactory::id() const { return QStringLiteral("org.kde.okteta.PodDecoderToolView"); } SidePosition PodDecoderToolViewFactory::defaultPosition() const { return RightSidePosition; } AbstractToolView* PodDecoderToolViewFactory::create(AbstractTool* tool) const { return new PODDecoderToolView(qobject_cast(tool)); } } diff --git a/kasten/controllers/view/poddecoder/podtablemodel.cpp b/kasten/controllers/view/poddecoder/podtablemodel.cpp index 41b7f562..6fa9da83 100644 --- a/kasten/controllers/view/poddecoder/podtablemodel.cpp +++ b/kasten/controllers/view/poddecoder/podtablemodel.cpp @@ -1,200 +1,200 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "podtablemodel.hpp" // lib #include "poddecodertool.hpp" -// KF5 +// KF #include #include // Qt #include namespace Kasten { PODTableModel::PODTableModel(PODDecoderTool* tool, QObject* parent) : QAbstractTableModel(parent) , mTool(tool) , mEmptyNote(QLatin1Char('-')) { connect(mTool, &PODDecoderTool::dataChanged, this, &PODTableModel::onDataChanged); } PODTableModel::~PODTableModel() = default; void PODTableModel::onDataChanged() { emit dataChanged(index(0, ValueId), index(mTool->podCount() - 1, ValueId)); } int PODTableModel::rowCount(const QModelIndex& parent) const { return (!parent.isValid()) ? mTool->podCount() : 0; } int PODTableModel::columnCount(const QModelIndex& parent) const { return (!parent.isValid()) ? NoOfColumnIds : 0; } QVariant PODTableModel::data(const QModelIndex& index, int role) const { QVariant result; switch (role) { case Qt::DisplayRole: { const int podId = index.row(); const int column = index.column(); switch (column) { case NameId: { result = mTool->nameOfPOD(podId); break; } case ValueId: { QVariant value = mTool->value(podId); if (value.isNull()) { value = mEmptyNote; } result = value; break; } default: ; } break; } case Qt::EditRole: { const int column = index.column(); if (column == ValueId) { const int podId = index.row(); result = mTool->value(podId); } break; } case Qt::TextAlignmentRole: { const int column = index.column(); result = (column == NameId) ? Qt::AlignRight : Qt::AlignLeft; break; } case Qt::ForegroundRole: { const int column = index.column(); if (column == ValueId) { const int podId = index.row(); const QVariant value = mTool->value(podId); if (value.isNull()) { const QPalette& palette = QApplication::palette(); const KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::View); result = colorScheme.foreground(KColorScheme::InactiveText); } } } default: break; } return result; } Qt::ItemFlags PODTableModel::flags(const QModelIndex& index) const { Qt::ItemFlags result = QAbstractTableModel::flags(index); const int column = index.column(); if (column == ValueId) { const int podId = index.row(); const QVariant value = mTool->value(podId); // TODO: this check does not match types with dynamic byte length, e.g. utf-8! if (!value.isNull()) { result |= Qt::ItemIsEditable; } } return result; } QModelIndex PODTableModel::buddy(const QModelIndex& index) const { QModelIndex result; const int column = index.column(); if (column == NameId) { const int row = index.row(); result = createIndex(row, ValueId); } else { result = index; } return result; } QVariant PODTableModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant result; if (role == Qt::DisplayRole) { const QString titel = section == NameId ? i18nc("@title:column name of the datatype", "Type") : section == ValueId ? i18nc("@title:column value of the bytes for the datatype", "Value") : QString(); result = titel; } else if (role == Qt::ToolTipRole) { const QString titel = section == NameId ? i18nc("@info:tooltip for column Type", "The type of data") : section == ValueId ? i18nc("@info:tooltip for column Value", "The value of the bytes for the datatype") : QString(); result = titel; } else { result = QAbstractTableModel::headerData(section, orientation, role); } return result; } bool PODTableModel::setData(const QModelIndex& index, const QVariant& data, int role) { bool result; if (index.isValid() && role == Qt::EditRole) { const int podId = index.row(); mTool->setData(data, podId); result = true; } else { result = false; } return result; } } diff --git a/kasten/controllers/view/poddecoder/podtableview.cpp b/kasten/controllers/view/poddecoder/podtableview.cpp index f1ba49ce..736434ae 100644 --- a/kasten/controllers/view/poddecoder/podtableview.cpp +++ b/kasten/controllers/view/poddecoder/podtableview.cpp @@ -1,212 +1,212 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "podtableview.hpp" // controller #include "podtablemodel.hpp" #include "poddelegate.hpp" #include "poddecodertool.hpp" -// KF5 +// KF #include #include #include // Qt #include #include #include #include #include #include #include namespace Kasten { PODTableView::PODTableView(PODDecoderTool* tool, QWidget* parent) : QWidget(parent) , mTool(tool) { QBoxLayout* baseLayout = new QVBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); // table mPODTableModel = new PODTableModel(mTool, this); mPODTableView = new QTreeView(this); mPODTableView->setObjectName(QStringLiteral("PODTable")); mPODTableView->setRootIsDecorated(false); mPODTableView->setAlternatingRowColors(true); mPODTableView->setItemsExpandable(false); mPODTableView->setUniformRowHeights(true); mPODTableView->setAllColumnsShowFocus(true); mPODTableView->setItemDelegate(new PODDelegate(mTool, this)); mPODTableView->setEditTriggers(QAbstractItemView::EditKeyPressed | QAbstractItemView::DoubleClicked); mPODTableView->setDragEnabled(true); mPODTableView->setSortingEnabled(false); mPODTableView->setModel(mPODTableModel); mPODTableView->installEventFilter(this); QHeaderView* header = mPODTableView->header(); header->setSectionResizeMode(QHeaderView::Interactive); header->setStretchLastSection(false); connect(mPODTableView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &PODTableView::onCurrentRowChanged); baseLayout->addWidget(mPODTableView, 10); // settings QBoxLayout* settingsLayout = new QHBoxLayout(); settingsLayout->setContentsMargins(0, 0, 0, 0); mByteOrderSelection = new KComboBox(this); mByteOrderSelection->addItem(i18nc("@item:inlistbox", "Big-endian")); // add first for index mByteOrderSelection->addItem(i18nc("@item:inlistbox", "Little-endian")); // add second for index mByteOrderSelection->setCurrentIndex(mTool->byteOrder()); connect(mByteOrderSelection, QOverload::of(&KComboBox::activated), mTool, &PODDecoderTool::setByteOrder); const QString byteOrderToolTip = i18nc("@info:tooltip", "The byte order to use for decoding the bytes."); mByteOrderSelection->setToolTip(byteOrderToolTip); settingsLayout->addWidget(mByteOrderSelection); QLabel* unsignedAsHexLabel = new QLabel(i18nc("@option:check", "Unsigned as hexadecimal:"), this); settingsLayout->addWidget(unsignedAsHexLabel); mUnsignedAsHexCheck = new QCheckBox(this); mUnsignedAsHexCheck->setChecked(mTool->isUnsignedAsHex()); connect(mUnsignedAsHexCheck, &QCheckBox::toggled, mTool, &PODDecoderTool::setUnsignedAsHex); unsignedAsHexLabel->setBuddy(mUnsignedAsHexCheck); const QString unsignedAsHexToolTip = i18nc("@info:tooltip", "Sets whether the values of the unsigned integer types are shown as hexadecimal instead of as decimal."); unsignedAsHexLabel->setToolTip(unsignedAsHexToolTip); mUnsignedAsHexCheck->setToolTip(unsignedAsHexToolTip); settingsLayout->addWidget(mUnsignedAsHexCheck); settingsLayout->addStretch(); baseLayout->addLayout(settingsLayout); mTool->setDifferentSizeDialog(this); // resize to fit width of contents // this is much (!) faster than using setResizeMode(QHeaderView::ResizeToContents) QFont f; QFontMetrics metrics(f); // ideally we should check the width of the longest translated string, but this should be wide enough for most // anyway this is just an initial setting and the width can be changed manually header->resizeSection(0, metrics.width(QStringLiteral("Hexadecimal 8-bit")) + 30); header->resizeSection(1, metrics.width(QStringLiteral("1.01234567890123456789e-111")) + 15); } PODTableView::~PODTableView() = default; Answer PODTableView::query(int newValueSize, int oldValueSize, int sizeLeft) { Q_UNUSED(sizeLeft); Answer answer; int messageBoxAnswer; if (newValueSize < oldValueSize) { const QString message = xi18nc("@info", "The new value needs fewer bytes (%1 instead of %2)." "Keep the unused bytes or remove them?", newValueSize, oldValueSize); const KGuiItem keepGuiItem = KGuiItem(i18nc("@action:button keep the unused bytes", "&Keep"), QString(), i18nc("@info:tooltip", "Keep the unused bytes with their old values.")); messageBoxAnswer = KMessageBox::warningYesNoCancel(this, message, mTool->title(), keepGuiItem, KStandardGuiItem::remove()); } else { const QString message = xi18nc("@info", "The new value needs more bytes (%1 instead of %2)." "Overwrite the following bytes or insert new ones as needed?", newValueSize, oldValueSize); messageBoxAnswer = KMessageBox::warningYesNoCancel(this, message, mTool->title(), KStandardGuiItem::overwrite(), KStandardGuiItem::insert()); } answer = (messageBoxAnswer == KMessageBox::Yes) ? Overwrite : (messageBoxAnswer == KMessageBox::No) ? AdaptSize : Cancel; return answer; } bool PODTableView::eventFilter(QObject* object, QEvent* event) { if (object == mPODTableView) { if (event->type() == QEvent::FocusIn) { const QModelIndex current = mPODTableView->selectionModel()->currentIndex(); const int podId = current.row(); if (current.isValid() && mTool->isApplyable() && !mTool->value(podId).isNull()) { mTool->markPOD(podId); } } else if (event->type() == QEvent::FocusOut) { QWidget* tableViewFocusWidget = mPODTableView->focusWidget(); const bool subChildHasFocus = (tableViewFocusWidget != mPODTableView); if (subChildHasFocus) { mPODTableViewFocusChild = tableViewFocusWidget; mPODTableViewFocusChild->installEventFilter(this); } else if (mTool->isApplyable()) { mTool->unmarkPOD(); } } } else if (object == mPODTableViewFocusChild) { // TODO: it is only assumed the edit widget will be removed if it loses the focus if (event->type() == QEvent::FocusOut) { if (!mPODTableView->hasFocus() && mTool->isApplyable()) { mTool->unmarkPOD(); } mPODTableViewFocusChild->removeEventFilter(this); mPODTableViewFocusChild = nullptr; } } return QWidget::eventFilter(object, event); } void PODTableView::onCurrentRowChanged(const QModelIndex& current, const QModelIndex& previous) { Q_UNUSED(previous) if (!mTool->isApplyable()) { return; } const int podId = current.row(); if (current.isValid() && !mTool->value(podId).isNull()) { mTool->markPOD(podId); } else { mTool->unmarkPOD(); } } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/binary8codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/binary8codec.cpp index 330a6aca..cc171aa5 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/binary8codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/binary8codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "binary8codec.hpp" // tool #include "../types/binary8.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { Binary8Codec::Binary8Codec() : AbstractTypeCodec(i18nc("@label:textbox encoding of one byte as value in the binary format", "Binary 8-bit")) {} Binary8Codec::~Binary8Codec() = default; QVariant Binary8Codec::value(const PODData& data, int* byteCount) const { const unsigned char* pointer = (unsigned char*)data.pointer(1); *byteCount = pointer ? 1 : 0; return pointer ? QVariant::fromValue(Binary8(*pointer)) : QVariant(); } QByteArray Binary8Codec::valueToBytes(const QVariant& value) const { const quint8 number = value.value().value; return QByteArray((const char*)&number, sizeof(quint8)); } bool Binary8Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/char8codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/char8codec.cpp index 6ce5cc23..9b3b60e9 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/char8codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/char8codec.cpp @@ -1,77 +1,77 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "char8codec.hpp" // tool #include "../types/char8.hpp" #include "../poddata.hpp" // Okteta core #include #include -// KF5 +// KF #include namespace Okteta { Char8Codec::Char8Codec(CharCodec* charCodec) : AbstractTypeCodec(i18nc("@label:textbox encoding of one byte as character", "Character 8-bit")) , mCharCodec(charCodec) {} Char8Codec::~Char8Codec() = default; QVariant Char8Codec::value(const PODData& data, int* byteCount) const { const unsigned char* pointer = (unsigned char*)data.pointer(1); *byteCount = pointer ? 1 : 0; QVariant result; if (pointer) { const Okteta::Character decodedChar = mCharCodec->decode(*pointer); result = QVariant::fromValue(Char8(decodedChar)); } return result; } QByteArray Char8Codec::valueToBytes(const QVariant& value) const { const Okteta::Character character = value.value().character; bool success = (!character.isUndefined()); Okteta::Byte byte; if (success) { success = mCharCodec->encode(&byte, character); } return success ? QByteArray(1, byte) : QByteArray(); } bool Char8Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().character == otherValue.value().character); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/float32codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/float32codec.cpp index ff79d706..16d014bf 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/float32codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/float32codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "float32codec.hpp" // tool #include "../types/float32.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { Float32Codec::Float32Codec() : AbstractTypeCodec(i18nc("@label:textbox", "Float 32-bit")) {} Float32Codec::~Float32Codec() = default; QVariant Float32Codec::value(const PODData& data, int* byteCount) const { const float* pointer = (float*)data.pointer(4); *byteCount = pointer ? 4 : 0; return pointer ? QVariant::fromValue(Float32(*pointer)) : QVariant(); } QByteArray Float32Codec::valueToBytes(const QVariant& value) const { const float number = value.value().value; return QByteArray((const char*)&number, sizeof(float)); } bool Float32Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/float64codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/float64codec.cpp index 504aaa89..0e957a0d 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/float64codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/float64codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "float64codec.hpp" // tool #include "../types/float64.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { Float64Codec::Float64Codec() : AbstractTypeCodec(i18nc("@label:textbox", "Float 64-bit")) {} Float64Codec::~Float64Codec() = default; QVariant Float64Codec::value(const PODData& data, int* byteCount) const { const double* pointer = (double*)data.pointer(8); *byteCount = pointer ? 8 : 0; return pointer ? QVariant::fromValue(Float64(*pointer)) : QVariant(); } QByteArray Float64Codec::valueToBytes(const QVariant& value) const { const double number = value.value().value; return QByteArray((const char*)&number, sizeof(double)); } bool Float64Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/hexadecimal8codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/hexadecimal8codec.cpp index 77ea4336..490bb9f3 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/hexadecimal8codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/hexadecimal8codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "hexadecimal8codec.hpp" // tool #include "../types/hexadecimal8.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { Hexadecimal8Codec::Hexadecimal8Codec() : AbstractTypeCodec(i18nc("@label:textbox encoding of one byte as value in the hexadecimal format", "Hexadecimal 8-bit")) {} Hexadecimal8Codec::~Hexadecimal8Codec() = default; QVariant Hexadecimal8Codec::value(const PODData& data, int* byteCount) const { const unsigned char* pointer = (unsigned char*)data.pointer(1); *byteCount = pointer ? 1 : 0; return pointer ? QVariant::fromValue(Hexadecimal8(*pointer)) : QVariant(); } QByteArray Hexadecimal8Codec::valueToBytes(const QVariant& value) const { const quint8 number = value.value().value; return QByteArray((const char*)&number, sizeof(quint8)); } bool Hexadecimal8Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/octal8codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/octal8codec.cpp index 178422df..7c727b9a 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/octal8codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/octal8codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "octal8codec.hpp" // tool #include "../types/octal8.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { Octal8Codec::Octal8Codec() : AbstractTypeCodec(i18nc("@label:textbox encoding of one byte as value in the octal format", "Octal 8-bit")) {} Octal8Codec::~Octal8Codec() = default; QVariant Octal8Codec::value(const PODData& data, int* byteCount) const { const unsigned char* pointer = (unsigned char*)data.pointer(1); *byteCount = pointer ? 1 : 0; return pointer ? QVariant::fromValue(Octal8(*pointer)) : QVariant(); } QByteArray Octal8Codec::valueToBytes(const QVariant& value) const { const quint8 number = value.value().value; return QByteArray((const char*)&number, sizeof(quint8)); } bool Octal8Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/sint16codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/sint16codec.cpp index a41f196d..a54ac7d5 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/sint16codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/sint16codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "sint16codec.hpp" // tool #include "../types/sint16.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { SInt16Codec::SInt16Codec() : AbstractTypeCodec(i18nc("@label:textbox", "Signed 16-bit")) {} SInt16Codec::~SInt16Codec() = default; QVariant SInt16Codec::value(const PODData& data, int* byteCount) const { const qint16* pointer = (qint16*)data.pointer(2); *byteCount = pointer ? 2 : 0; return pointer ? QVariant::fromValue(SInt16(*pointer)) : QVariant(); } QByteArray SInt16Codec::valueToBytes(const QVariant& value) const { const qint16 number = value.value().value; return QByteArray((const char*)&number, sizeof(qint16)); } bool SInt16Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/sint32codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/sint32codec.cpp index b9a7982f..3fbc3d73 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/sint32codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/sint32codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "sint32codec.hpp" // tool #include "../types/sint32.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { SInt32Codec::SInt32Codec() : AbstractTypeCodec(i18nc("@label:textbox", "Signed 32-bit")) {} SInt32Codec::~SInt32Codec() = default; QVariant SInt32Codec::value(const PODData& data, int* byteCount) const { const qint32* pointer = (qint32*)data.pointer(4); *byteCount = pointer ? 4 : 0; return pointer ? QVariant::fromValue(SInt32(*pointer)) : QVariant(); } QByteArray SInt32Codec::valueToBytes(const QVariant& value) const { const qint32 number = value.value().value; return QByteArray((const char*)&number, sizeof(qint32)); } bool SInt32Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/sint64codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/sint64codec.cpp index 98b02749..1c5f2c9a 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/sint64codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/sint64codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "sint64codec.hpp" // tool #include "../types/sint64.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { SInt64Codec::SInt64Codec() : AbstractTypeCodec(i18nc("@label:textbox", "Signed 64-bit")) {} SInt64Codec::~SInt64Codec() = default; QVariant SInt64Codec::value(const PODData& data, int* byteCount) const { const qint64* pointer = (qint64*)data.pointer(8); *byteCount = pointer ? 8 : 0; return pointer ? QVariant::fromValue(SInt64(*pointer)) : QVariant(); } QByteArray SInt64Codec::valueToBytes(const QVariant& value) const { const qint64 number = value.value().value; return QByteArray((const char*)&number, sizeof(qint64)); } bool SInt64Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/sint8codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/sint8codec.cpp index 708b1785..94db59c4 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/sint8codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/sint8codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "sint8codec.hpp" // tool #include "../types/sint8.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { SInt8Codec::SInt8Codec() : AbstractTypeCodec(i18nc("@label:textbox", "Signed 8-bit")) {} SInt8Codec::~SInt8Codec() = default; QVariant SInt8Codec::value(const PODData& data, int* byteCount) const { const qint8* pointer = (qint8*)data.pointer(1); *byteCount = pointer ? 1 : 0; return pointer ? QVariant::fromValue(SInt8(*pointer)) : QVariant(); } QByteArray SInt8Codec::valueToBytes(const QVariant& value) const { const qint8 number = value.value().value; return QByteArray((const char*)&number, sizeof(qint8)); } bool SInt8Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/uint16codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/uint16codec.cpp index bf230572..dcd0573c 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/uint16codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/uint16codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "uint16codec.hpp" // tool #include "../types/uint16.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { UInt16Codec::UInt16Codec() : AbstractTypeCodec(i18nc("@label:textbox", "Unsigned 16-bit")) {} UInt16Codec::~UInt16Codec() = default; QVariant UInt16Codec::value(const PODData& data, int* byteCount) const { const quint16* pointer = (quint16*)data.pointer(2); *byteCount = pointer ? 2 : 0; return pointer ? QVariant::fromValue(UInt16(*pointer)) : QVariant(); } QByteArray UInt16Codec::valueToBytes(const QVariant& value) const { const quint16 number = value.value().value; return QByteArray((const char*)&number, sizeof(quint16)); } bool UInt16Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/uint32codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/uint32codec.cpp index a3bab457..723ab98c 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/uint32codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/uint32codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "uint32codec.hpp" // tool #include "../types/uint32.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { UInt32Codec::UInt32Codec() : AbstractTypeCodec(i18nc("@label:textbox", "Unsigned 32-bit")) {} UInt32Codec::~UInt32Codec() = default; QVariant UInt32Codec::value(const PODData& data, int* byteCount) const { const quint32* pointer = (quint32*)data.pointer(4); *byteCount = pointer ? 4 : 0; return pointer ? QVariant::fromValue(UInt32(*pointer)) : QVariant(); } QByteArray UInt32Codec::valueToBytes(const QVariant& value) const { const quint32 number = value.value().value; return QByteArray((const char*)&number, sizeof(quint32)); } bool UInt32Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/uint64codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/uint64codec.cpp index f1fc2855..19838eb2 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/uint64codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/uint64codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "uint64codec.hpp" // tool #include "../types/uint64.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { UInt64Codec::UInt64Codec() : AbstractTypeCodec(i18nc("@label:textbox", "Unsigned 64-bit")) {} UInt64Codec::~UInt64Codec() = default; QVariant UInt64Codec::value(const PODData& data, int* byteCount) const { const quint64* pointer = (quint64*)data.pointer(8); *byteCount = pointer ? 8 : 0; return pointer ? QVariant::fromValue(UInt64(*pointer)) : QVariant(); } QByteArray UInt64Codec::valueToBytes(const QVariant& value) const { const quint64 number = value.value().value; return QByteArray((const char*)&number, sizeof(quint64)); } bool UInt64Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/uint8codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/uint8codec.cpp index 2f1ae9b7..034ae023 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/uint8codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/uint8codec.cpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "uint8codec.hpp" // tool #include "../types/uint8.hpp" #include "../poddata.hpp" -// KF5 +// KF #include namespace Okteta { UInt8Codec::UInt8Codec() : AbstractTypeCodec(i18nc("@label:textbox", "Unsigned 8-bit")) {} UInt8Codec::~UInt8Codec() = default; QVariant UInt8Codec::value(const PODData& data, int* byteCount) const { const quint8* pointer = (quint8*)data.pointer(1); *byteCount = pointer ? 1 : 0; return pointer ? QVariant::fromValue(UInt8(*pointer)) : QVariant(); } QByteArray UInt8Codec::valueToBytes(const QVariant& value) const { const quint8 number = value.value().value; return QByteArray((const char*)&number, sizeof(quint8)); } bool UInt8Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/poddecoder/typecodecs/utf8codec.cpp b/kasten/controllers/view/poddecoder/typecodecs/utf8codec.cpp index 90864735..d9974d9c 100644 --- a/kasten/controllers/view/poddecoder/typecodecs/utf8codec.cpp +++ b/kasten/controllers/view/poddecoder/typecodecs/utf8codec.cpp @@ -1,78 +1,78 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "utf8codec.hpp" // tool #include "../types/utf8.hpp" #include "../poddata.hpp" -// KF5 +// KF #include // Qt #include namespace Okteta { Utf8Codec::Utf8Codec() : AbstractTypeCodec(i18nc("@label:textbox", "UTF-8")) , mUtf8Codec(QTextCodec::codecForName("UTF-8")) {} Utf8Codec::~Utf8Codec() = default; QVariant Utf8Codec::value(const PODData& data, int* byteCount) const { // UTF-8 // interpreted as a sequence of bytes, there is no endian problem // source: https://unicode.org/faq/utf_bom.html#3 const QChar replacementChar(QChar::ReplacementCharacter); const char* originalData = (const char*)data.originalData(); const int maxUtf8DataSize = data.size(); QString utf8; bool isUtf8 = false; *byteCount = 0; for (int i = 1; i <= maxUtf8DataSize; ++i) { utf8 = mUtf8Codec->toUnicode(originalData, i); if (utf8.size() == 1 && utf8[0] != replacementChar) { isUtf8 = true; *byteCount = i; break; } } return isUtf8 ? QVariant::fromValue(Utf8(utf8[0])) : QVariant(); } QByteArray Utf8Codec::valueToBytes(const QVariant& value) const { const QChar valueChar = value.value().value; return mUtf8Codec->fromUnicode(valueChar); } bool Utf8Codec::areEqual(const QVariant& value, QVariant& otherValue) const { return (value.value().value == otherValue.value().value); } } diff --git a/kasten/controllers/view/print/printcontroller.cpp b/kasten/controllers/view/print/printcontroller.cpp index a5c0234b..f12b4e94 100644 --- a/kasten/controllers/view/print/printcontroller.cpp +++ b/kasten/controllers/view/print/printcontroller.cpp @@ -1,64 +1,64 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "printcontroller.hpp" // controller #include "printtool.hpp" -// KF5 +// KF #include #include #include // Qt #include namespace Kasten { PrintController::PrintController(KXMLGUIClient* guiClient) : mPrintTool(new PrintTool()) { mPrintAction = KStandardAction::print(mPrintTool, &PrintTool::print, this); connect(mPrintTool, &PrintTool::viewChanged, mPrintAction, &QAction::setEnabled); guiClient->actionCollection()->addAction(mPrintAction->objectName(), mPrintAction); setTargetModel(nullptr); } PrintController::~PrintController() { delete mPrintTool; } void PrintController::setTargetModel(AbstractModel* model) { mPrintTool->setTargetModel(model); } void PrintController::print() { mPrintTool->print(); } } diff --git a/kasten/controllers/view/print/printjob.hpp b/kasten/controllers/view/print/printjob.hpp index 8912f3f5..8eb8997a 100644 --- a/kasten/controllers/view/print/printjob.hpp +++ b/kasten/controllers/view/print/printjob.hpp @@ -1,74 +1,74 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_PRINTJOB_HPP #define KASTEN_PRINTJOB_HPP -// KF5 +// KF // #include // Qt #include class FramesToPaperPrinter; class QPrinter; namespace Kasten { class PrintThread; class PrintJob : public QObject // not yet: KJob { Q_OBJECT public: PrintJob(FramesToPaperPrinter* framesPrinter, int firstPage, int lastPage, QPrinter* printer); public: // KJob API // virtual void start(); public: bool exec(); private Q_SLOTS: // void onFinished(); void onPagePrinted(); private: // PrintThread *mPrintThread; FramesToPaperPrinter* mFramesPrinter; const int mFirstPage; const int mLastPage; QPrinter* mPrinter; }; inline PrintJob::PrintJob(FramesToPaperPrinter* framesPrinter, int firstPage, int lastPage, QPrinter* printer) : mFramesPrinter(framesPrinter) , mFirstPage(firstPage) , mLastPage(lastPage) , mPrinter(printer) {} } #endif diff --git a/kasten/controllers/view/print/printtool.cpp b/kasten/controllers/view/print/printtool.cpp index 928c2e0b..55ee8ab0 100644 --- a/kasten/controllers/view/print/printtool.cpp +++ b/kasten/controllers/view/print/printtool.cpp @@ -1,178 +1,178 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "printtool.hpp" // controller #include "printjob.hpp" #include "framestopaperprinter.hpp" #include "headerfooterframerenderer.hpp" #include "bytearrayframerenderer.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include // Kasten core #include -// KF5 +// KF #include #include // Qt #include #include #include #include #include namespace Kasten { PrintTool::PrintTool() = default; PrintTool::~PrintTool() = default; void PrintTool::setTargetModel(AbstractModel* model) { // if( mByteArrayView ) mByteArrayView->disconnect( this ); mByteArrayView = model ? model->findBaseModel() : nullptr; mDocument = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = mDocument ? mDocument->content() : nullptr; const bool hasView = (mByteArrayView && mByteArrayModel); emit viewChanged(hasView); } void PrintTool::print() { const QString processTitle = i18nc("@title:window", "Print Byte Array %1", mDocument->title()); QPrinter printer; // LayoutDialogPage* layoutPage = new LayoutDialogPage(); // QList customDialogPages; // customDialogPages << layoutPage; auto* printDialog = new QPrintDialog(&printer, nullptr); // Disable PrintPageRange, this tells Qt we can't do client-side page selection, // so it will try do server-side page selection if supported printDialog->setOption(QPrintDialog::PrintPageRange, false); // printDialog->setOptionTabs(customDialogPages); printDialog->setWindowTitle(processTitle); if (printDialog->exec() != 0) { const QString creator = QStringLiteral("Print Plugin for Okteta " OKTETA_VERSION); // no i18n(), keep space at end as separator printer.setCreator(creator); FramesToPaperPrinter framesPrinter; framesPrinter.setPaperRect(printer.paperRect()); framesPrinter.setPageRect(printer.pageRect()); printer.setFullPage(true); PrintInfo info; const QRect pageRect = framesPrinter.pageRect(); const int left = pageRect.left(); const int width = pageRect.width(); auto* headerFrameRenderer = new HeaderFooterFrameRenderer(&info); headerFrameRenderer->setTexts(QStringLiteral("%d"), QStringLiteral("%f"), i18nc("in the header of the printed page, e.g. Page 2 of 20", "Page %p of %P")); headerFrameRenderer->setWidth(width); headerFrameRenderer->setPos(pageRect.topLeft()); auto* footerFrameRenderer = new HeaderFooterFrameRenderer(&info); footerFrameRenderer->setTexts(i18nc("in the footer of the printed page, e.g. Printed by: Joe User", "Printed by: %U"), QString(), QStringLiteral("%F")); footerFrameRenderer->setWidth(width); const int footerTop = pageRect.bottom() - footerFrameRenderer->height(); footerFrameRenderer->setPos(left, footerTop); const int contentHeight = pageRect.height() - footerFrameRenderer->height() - headerFrameRenderer->height(); const int contentTop = pageRect.top() + headerFrameRenderer->height(); auto* byteArrayFrameRenderer = new ByteArrayFrameRenderer; byteArrayFrameRenderer->setPos(left, contentTop); byteArrayFrameRenderer->setWidth(width); byteArrayFrameRenderer->setHeight(contentHeight); Okteta::AddressRange range = mByteArrayView->selection(); if (!range.isValid()) { range.setByWidth(0, mByteArrayModel->size()); } byteArrayFrameRenderer->setByteArrayModel(mByteArrayModel, range.start(), range.width()); // TODO: use noOfBytesPerLine of view, scale resolution down if it does not fit the page const int noOfBytesPerLine = mByteArrayView->noOfBytesPerLine(); // byteArrayFrameRenderer->setNoOfBytesPerLine( mByteArrayView->noOfBytesPerLine() ); const Okteta::Address startOffset = mByteArrayView->startOffset() + range.start(); const int line = startOffset / noOfBytesPerLine; const Okteta::Address firstLineOffset = mByteArrayView->firstLineOffset() + line * noOfBytesPerLine; byteArrayFrameRenderer->setFirstLineOffset(firstLineOffset); byteArrayFrameRenderer->setStartOffset(startOffset); byteArrayFrameRenderer->setCharCoding(mByteArrayView->charCodingName()); byteArrayFrameRenderer->setBufferSpacing(mByteArrayView->byteSpacingWidth(), mByteArrayView->noOfGroupedBytes(), mByteArrayView->groupSpacingWidth()); byteArrayFrameRenderer->setBinaryGapWidth(mByteArrayView->binaryGapWidth()); byteArrayFrameRenderer->setValueCoding((Okteta::ValueCoding)mByteArrayView->valueCoding()); byteArrayFrameRenderer->setShowsNonprinting(mByteArrayView->showsNonprinting()); byteArrayFrameRenderer->setSubstituteChar(mByteArrayView->substituteChar()); byteArrayFrameRenderer->setUndefinedChar(mByteArrayView->undefinedChar()); byteArrayFrameRenderer->showByteArrayColumns(mByteArrayView->visibleByteArrayCodings()); // if( !confirmPrintPageNumber( byteArrayFrameRenderer->framesCount()) ) // return; framesPrinter.addFrameRenderer(headerFrameRenderer); framesPrinter.addFrameRenderer(byteArrayFrameRenderer); framesPrinter.addFrameRenderer(footerFrameRenderer); info.setNoOfPages(byteArrayFrameRenderer->framesCount()); AbstractModelSynchronizer* synchronizer = mDocument->synchronizer(); if (synchronizer) { info.setUrl(synchronizer->url()); } QApplication::setOverrideCursor(Qt::WaitCursor); auto* printJob = new PrintJob(&framesPrinter, 0, byteArrayFrameRenderer->framesCount() - 1, &printer); const bool success = printJob->exec(); QApplication::restoreOverrideCursor(); if (!success) { const QString message = i18nc("@info", "Could not print."); KMessageBox::sorry(nullptr, message, processTitle); } } delete printDialog; } } diff --git a/kasten/controllers/view/replace/replacecontroller.cpp b/kasten/controllers/view/replace/replacecontroller.cpp index 0e8f907f..96f912c4 100644 --- a/kasten/controllers/view/replace/replacecontroller.cpp +++ b/kasten/controllers/view/replace/replacecontroller.cpp @@ -1,134 +1,134 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "replacecontroller.hpp" // controller #include "replacedialog.hpp" #include "replaceprompt.hpp" #include "replacetool.hpp" -// KF5 +// KF #include #include #include #include #include // Qt #include namespace Kasten { // TODO: for docked widgets signal widgets if embedded or floating, if horizontal/vertical ReplaceController::ReplaceController(KXMLGUIClient* guiClient, QWidget* parentWidget) : mParentWidget(parentWidget) { mReplaceAction = KStandardAction::replace(this, &ReplaceController::replace, this); guiClient->actionCollection()->addAction(mReplaceAction->objectName(), mReplaceAction); mTool = new ReplaceTool(); mTool->setUserQueryAgent(this); connect(mTool, &ReplaceTool::isApplyableChanged, mReplaceAction, &QAction::setEnabled); connect(mTool, &ReplaceTool::finished, this, &ReplaceController::onFinished); mReplaceAction->setEnabled(false); } ReplaceController::~ReplaceController() { delete mReplaceDialog; delete mReplacePrompt; delete mTool; } void ReplaceController::setTargetModel(AbstractModel* model) { mTool->setTargetModel(model); } void ReplaceController::replace() { // ensure dialog if (!mReplaceDialog) { mReplaceDialog = new ReplaceDialog(mTool, mParentWidget); } mReplaceDialog->show(); } void ReplaceController::onFinished(bool previousFound, int noOfReplacements) { if (mReplacePrompt) { mReplacePrompt->hide(); } const QString messageBoxTitle = i18nc("@title:window", "Replace"); const QString replacementReport = (noOfReplacements == 0) ? i18nc("@info", "No replacements made.") : i18ncp("@info", "1 replacement made.", "%1 replacements made.", noOfReplacements); if (!previousFound) { KMessageBox::sorry(mParentWidget, i18nc("@info", "Replace pattern not found in byte array."), messageBoxTitle); } else { KMessageBox::information(mParentWidget, replacementReport, messageBoxTitle); } } bool ReplaceController::queryContinue(FindDirection direction, int noOfReplacements) const { const QString messageBoxTitle = i18nc("@title:window", "Replace"); const QString replacementReport = (noOfReplacements == 0) ? i18nc("@info", "No replacements made.") : i18ncp("@info", "1 replacement made.", "%1 replacements made.", noOfReplacements); const QString question = (direction == FindForward) ? xi18nc("@info", "End of byte array reached.Continue from the beginning?") : xi18nc("@info", "Beginning of byte array reached.Continue from the end?"); const QString message = replacementReport + QLatin1String("

") + question; const int answer = KMessageBox::questionYesNo(mParentWidget, message, messageBoxTitle, KStandardGuiItem::cont(), KStandardGuiItem::cancel()); const bool result = (answer != KMessageBox::No); return result; } ReplaceBehaviour ReplaceController::queryReplaceCurrent() const { if (!mReplacePrompt) { mReplacePrompt = new ReplacePrompt(mParentWidget); } mReplacePrompt->show(); const ReplaceBehaviour answer = mReplacePrompt->query(); if (answer == ReplaceAll || answer == CancelReplacing) { mReplacePrompt->hide(); } return answer; } } diff --git a/kasten/controllers/view/replace/replacedialog.cpp b/kasten/controllers/view/replace/replacedialog.cpp index d19ace3a..35b502f1 100644 --- a/kasten/controllers/view/replace/replacedialog.cpp +++ b/kasten/controllers/view/replace/replacedialog.cpp @@ -1,129 +1,129 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "replacedialog.hpp" // controller #include "replacetool.hpp" // Okteta Kasten gui #include -// KF5 +// KF #include // Qt #include #include #include #include namespace Kasten { ReplaceDialog::ReplaceDialog(ReplaceTool* tool, QWidget* parent) : AbstractFindDialog(parent) , mTool(tool) { setWindowTitle(i18nc("@title:window", "Replace Bytes")); setFindButton(i18nc("@action;button", "&Replace"), QStringLiteral("edit-find-replace"), i18nc("@info:tooltip", "Start replace"), xi18nc("@info:whatsthis", "If you press the Replace button, " "the bytes you entered above are searched for within " "the byte array and any occurrence is replaced with " "the replacement bytes.")); setupFindBox(); // replace term QGroupBox* ReplaceBox = new QGroupBox(i18nc("@title:group", "Replace With")); auto* ReplaceBoxLayout = new QVBoxLayout; ReplaceDataEdit = new Okteta::ByteArrayComboBox(ReplaceBox); const QString toolTip = i18nc("@info:tooltip", "Enter the bytes to replace with, or select bytes previously replaced with from the list."); ReplaceDataEdit->setToolTip(toolTip); ReplaceBoxLayout->addWidget(ReplaceDataEdit); ReplaceBox->setLayout(ReplaceBoxLayout); setupOperationBox(ReplaceBox); // PromptCheckBox = new QCheckBox(i18nc("@option:check", "&Prompt on replace")); PromptCheckBox->setWhatsThis(i18nc("@info:whatsthis", "Ask before replacing each match found.")); setupCheckBoxes(PromptCheckBox); setFindButtonEnabled(false); setModal(true); } ReplaceDialog::~ReplaceDialog() = default; QByteArray ReplaceDialog::replaceData() const { return ReplaceDataEdit->byteArray(); } bool ReplaceDialog::prompt() const { return PromptCheckBox->isChecked(); } void ReplaceDialog::setCharCodec(const QString& codecName) { ReplaceDataEdit->setCharCodec(codecName); AbstractFindDialog::setCharCodec(codecName); } void ReplaceDialog::onFindButtonClicked() { hide(); rememberCurrentSettings(); mTool->setSearchData(data()); mTool->setReplaceData(replaceData()); mTool->setCaseSensitivity(caseSensitivity()); mTool->setDoPrompt(prompt()); mTool->replace(direction(), fromCursor(), inSelection()); } void ReplaceDialog::showEvent(QShowEvent* showEvent) { AbstractFindDialog::showEvent(showEvent); setInSelection(mTool->hasSelectedData()); setCharCodec(mTool->charCodingName()); } void ReplaceDialog::rememberCurrentSettings() { AbstractFindDialog::rememberCurrentSettings(); ReplaceDataEdit->rememberCurrentByteArray(); } } diff --git a/kasten/controllers/view/replace/replaceprompt.cpp b/kasten/controllers/view/replace/replaceprompt.cpp index dc797dc0..0eb7125a 100644 --- a/kasten/controllers/view/replace/replaceprompt.cpp +++ b/kasten/controllers/view/replace/replaceprompt.cpp @@ -1,98 +1,98 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2007,2009,2013 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "replaceprompt.hpp" -// KF5 +// KF #include // Qt #include #include #include #include namespace Kasten { ReplacePrompt::ReplacePrompt(QWidget* parent) : QDialog(parent) { setModal(true); setWindowTitle(i18nc("@title:window prompt for iterative replacement", "Replace")); // dialog buttons auto* dialogButtonBox = new QDialogButtonBox; QPushButton* button = dialogButtonBox->addButton(i18nc("@action:button", "Replace &All"), QDialogButtonBox::ApplyRole); connect(button, &QAbstractButton::clicked, this, &ReplacePrompt::onReplaceAllButton); button = dialogButtonBox->addButton(i18nc("@action:button", "&Skip"), QDialogButtonBox::ApplyRole); connect(button, &QAbstractButton::clicked, this, &ReplacePrompt::onSkipButton); QPushButton* replaceButton = dialogButtonBox->addButton(i18nc("@action:button", "Replace"), QDialogButtonBox::ApplyRole); connect(replaceButton, &QAbstractButton::clicked, this, &ReplacePrompt::onReplaceButton); button = dialogButtonBox->addButton(QDialogButtonBox::Close); connect(button, &QAbstractButton::clicked, this, &ReplacePrompt::onCloseButton); // main layout auto* layout = new QVBoxLayout; layout->addWidget(dialogButtonBox); setLayout(layout); resize(minimumSize()); replaceButton->setDefault(true); } ReplaceBehaviour ReplacePrompt::query() { QEventLoop eventLoop; mEventLoop = &eventLoop; eventLoop.exec(); return mResult; } void ReplacePrompt::onReplaceAllButton() { mResult = ReplaceAll; mEventLoop->quit(); } void ReplacePrompt::onSkipButton() { mResult = SkipCurrent; mEventLoop->quit(); } void ReplacePrompt::onReplaceButton() { mResult = ReplaceCurrent; mEventLoop->quit(); } void ReplacePrompt::onCloseButton() { mResult = CancelReplacing; mEventLoop->quit(); } } diff --git a/kasten/controllers/view/replace/replacetool.cpp b/kasten/controllers/view/replace/replacetool.cpp index 75d9ed2c..f7af0bc9 100644 --- a/kasten/controllers/view/replace/replacetool.cpp +++ b/kasten/controllers/view/replace/replacetool.cpp @@ -1,282 +1,282 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "replacetool.hpp" // controller #include "replaceuserqueryable.hpp" // search controller #include "../search/searchjob.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { ReplaceTool::ReplaceTool() { setObjectName(QStringLiteral("Replace")); } ReplaceTool::~ReplaceTool() = default; bool ReplaceTool::isApplyable() const { return (mByteArrayView && mByteArrayModel && !mByteArrayView->isReadOnly()); // const int newPosition = finalTargetOffset(); // return ( mByteArrayView && mByteArrayModel // && (0 <= newPosition) && (newPosition <= mByteArrayModel->size()) ); } QString ReplaceTool::title() const { return i18nc("@title", "Replace"); } bool ReplaceTool::hasSelectedData() const { return mByteArrayView->hasSelectedData(); } QString ReplaceTool::charCodingName() const { return mByteArrayView->charCodingName(); } void ReplaceTool::setTargetModel(AbstractModel* model) { const bool oldIsApplyable = isApplyable(); if (mByteArrayView) { mByteArrayView->disconnect(this); } if (mByteArrayModel) { mByteArrayModel->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; if (mByteArrayView && mByteArrayModel) { connect(mByteArrayView, &ByteArrayView::readOnlyChanged, this, &ReplaceTool::onReadOnlyChanged); // TODO: update isApplyable on cursor movement and size changes } const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void ReplaceTool::setUserQueryAgent(If::ReplaceUserQueryable* userQueryAgent) { mUserQueryAgent = userQueryAgent; } void ReplaceTool::setSearchData(const QByteArray& searchData) { // const bool oldIsApplyable = isApplyable(); mSearchData = searchData; // const bool newIsApplyable = isApplyable(); // if( oldIsApplyable != newIsApplyable ) // emit isApplyableChanged( newIsApplyable ); } void ReplaceTool::setReplaceData(const QByteArray& replaceData) { // const bool oldIsApplyable = isApplyable(); mReplaceData = replaceData; // const bool newIsApplyable = isApplyable(); // if( oldIsApplyable != newIsApplyable ) // emit isApplyableChanged( newIsApplyable ); } void ReplaceTool::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity) { // const bool oldIsApplyable = isApplyable(); mCaseSensitivity = caseSensitivity; // const bool newIsApplyable = isApplyable(); // if( oldIsApplyable != newIsApplyable ) // emit isApplyableChanged( newIsApplyable ); } void ReplaceTool::setDoPrompt(bool doPrompt) { mDoPrompt = doPrompt; } void ReplaceTool::replace(FindDirection direction, bool fromCursor, bool inSelection) { mPreviousFound = false; Okteta::Address startIndex; if (inSelection) { const Okteta::AddressRange selection = mByteArrayView->selection(); if (!selection.isValid()) { // nothing selected, so skip any search and finish now emit finished(false, 0); return; } mReplaceFirstIndex = selection.start(); mReplaceLastIndex = selection.end(); startIndex = selection.start(); mDoWrap = true; // TODO: no wrapping needed, or? direction = FindForward; // TODO: why only forward? } else { const Okteta::Address cursorPosition = mByteArrayView->cursorPosition(); if (fromCursor && (cursorPosition != 0)) { mReplaceFirstIndex = cursorPosition; mReplaceLastIndex = cursorPosition - 1; } else { mReplaceFirstIndex = 0; mReplaceLastIndex = mByteArrayModel->size() - 1; } startIndex = (direction == FindForward) ? mReplaceFirstIndex : mReplaceLastIndex /*-mSearchData.size()*/; mDoWrap = (direction == FindForward) ? (mReplaceLastIndex < startIndex) : (startIndex < mReplaceFirstIndex); } doReplace(direction, startIndex); } void ReplaceTool::doReplace(FindDirection direction, Okteta::Address startIndex) { QApplication::setOverrideCursor(Qt::WaitCursor); int noOfReplacements = 0; while (true) { const bool isForward = (direction == FindForward); Okteta::Address endIndex = mDoWrap ? (isForward ? mByteArrayModel->size() - 1 : 0) : (isForward ? mReplaceLastIndex : mReplaceFirstIndex); SearchJob* searchJob = new SearchJob(mByteArrayModel, mSearchData, startIndex, endIndex, mCaseSensitivity, mByteArrayView->charCodingName()); const Okteta::Address pos = searchJob->exec(); if (pos != -1) { mPreviousFound = true; startIndex = pos; bool currentToBeReplaced; bool isCancelled; if (mDoPrompt) { QApplication::restoreOverrideCursor(); mByteArrayView->setSelection(pos, pos + mSearchData.size() - 1); const ReplaceBehaviour replaceBehaviour = mUserQueryAgent ? mUserQueryAgent->queryReplaceCurrent() : ReplaceAll; mByteArrayView->selectAllData(false); switch (replaceBehaviour) { case ReplaceAll: mDoPrompt = false; currentToBeReplaced = true; isCancelled = false; break; case ReplaceCurrent: currentToBeReplaced = true; isCancelled = false; break; case SkipCurrent: if (isForward) { ++startIndex; } else { --startIndex; } currentToBeReplaced = false; isCancelled = false; break; case CancelReplacing: default: currentToBeReplaced = false; isCancelled = true; mDoWrap = false; } } else { currentToBeReplaced = true; isCancelled = false; } if (currentToBeReplaced) { ++noOfReplacements; const Okteta::Size inserted = mByteArrayModel->replace(startIndex, mSearchData.size(), reinterpret_cast(mReplaceData.constData()), mReplaceData.size()); if (isForward) { startIndex += inserted; } else { startIndex -= inserted; } } if (!isCancelled) { continue; } } QApplication::restoreOverrideCursor(); // reached end if (mDoWrap) { const bool wrapping = mUserQueryAgent ? mUserQueryAgent->queryContinue(direction, noOfReplacements) : true; if (!wrapping) { break; } startIndex = (direction == FindForward) ? 0 : mByteArrayModel->size() - 1; mDoWrap = false; noOfReplacements = 0; QApplication::setOverrideCursor(Qt::WaitCursor); } else { emit finished(mPreviousFound, noOfReplacements); break; } } } void ReplaceTool::onReadOnlyChanged(bool isReadOnly) { Q_UNUSED(isReadOnly) // TODO: find out if isApplyable really changed, perhaps by caching the readonly state? emit isApplyableChanged(isApplyable()); } } diff --git a/kasten/controllers/view/search/searchcontroller.cpp b/kasten/controllers/view/search/searchcontroller.cpp index 264079e3..2dbc4237 100644 --- a/kasten/controllers/view/search/searchcontroller.cpp +++ b/kasten/controllers/view/search/searchcontroller.cpp @@ -1,139 +1,139 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "searchcontroller.hpp" // controller #include "searchdialog.hpp" #include "searchtool.hpp" -// KF5 +// KF #include #include #include #include #include // Qt #include namespace Kasten { // TODO: for docked widgets signal widgets if embedded or floating, if horizontal/vertical SearchController::SearchController(KXMLGUIClient* guiClient, QWidget* parentWidget) : mParentWidget(parentWidget) { mFindAction = KStandardAction::find( this, &SearchController::find, this); mFindNextAction = KStandardAction::findNext(this, &SearchController::findNext, this); mFindPrevAction = KStandardAction::findPrev(this, &SearchController::findPrevious, this); guiClient->actionCollection()->addActions({ mFindAction, mFindNextAction, mFindPrevAction }); mTool = new SearchTool(); mTool->setUserQueryAgent(this); connect(mTool, &SearchTool::isApplyableChanged, mFindAction, &QAction::setEnabled); connect(mTool, &SearchTool::isApplyableChanged, mFindNextAction, &QAction::setEnabled); connect(mTool, &SearchTool::isApplyableChanged, mFindPrevAction, &QAction::setEnabled); connect(mTool, &SearchTool::dataNotFound, this, &SearchController::onDataNotFound); mFindAction->setEnabled(false); mFindNextAction->setEnabled(false); mFindPrevAction->setEnabled(false); } SearchController::~SearchController() { delete mSearchDialog; delete mTool; } void SearchController::setTargetModel(AbstractModel* model) { mTool->setTargetModel(model); } void SearchController::find() { showDialog(FindForward); } void SearchController::findNext() { if (mTool->searchData().isEmpty()) { showDialog(FindForward); } else { mTool->search(FindForward, true, false); } ; } void SearchController::findPrevious() { if (mTool->searchData().isEmpty()) { showDialog(FindBackward); } else { mTool->search(FindBackward, true, false); } } void SearchController::showDialog(FindDirection direction) { // ensure dialog if (!mSearchDialog) { mSearchDialog = new SearchDialog(mTool, mParentWidget); } mSearchDialog->setDirection(direction); mSearchDialog->show(); } void SearchController::onDataNotFound() { const QString messageBoxTitle = i18nc("@title:window", "Find"); KMessageBox::sorry(mParentWidget, i18nc("@info", "Search key not found in byte array."), messageBoxTitle); } bool SearchController::queryContinue(FindDirection direction) const { const QString messageBoxTitle = i18nc("@title:window", "Find"); const QString question = (direction == FindForward) ? xi18nc("@info", "End of byte array reached.Continue from the beginning?") : xi18nc("@info", "Beginning of byte array reached.Continue from the end?"); const int answer = KMessageBox::questionYesNo(mParentWidget, question, messageBoxTitle, KStandardGuiItem::cont(), KStandardGuiItem::cancel()); const bool result = (answer != KMessageBox::No); return result; } } diff --git a/kasten/controllers/view/search/searchdialog.cpp b/kasten/controllers/view/search/searchdialog.cpp index 2794ae52..f1853a45 100644 --- a/kasten/controllers/view/search/searchdialog.cpp +++ b/kasten/controllers/view/search/searchdialog.cpp @@ -1,79 +1,79 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "searchdialog.hpp" // controller #include "searchtool.hpp" -// KF5 +// KF #include namespace Kasten { SearchDialog::SearchDialog(SearchTool* tool, QWidget* parent) : AbstractFindDialog(parent) , mTool(tool) { setWindowTitle(i18nc("@title:window", "Find Bytes")); setFindButton(i18nc("@action:button", "&Find"), QStringLiteral("edit-find"), i18nc("@info:tooltip", "Start searching"), xi18nc("@info:whatsthis", "If you press the Find button, " "the bytes you entered above are searched for within " "the byte array.")); setupFindBox(); setupOperationBox(); setupCheckBoxes(); setFindButtonEnabled(false); setModal(false); setCharCodec(mTool->charCodingName()); connect(mTool, &SearchTool::charCodecChanged, this, &SearchDialog::setCharCodec); } SearchDialog::~SearchDialog() = default; void SearchDialog::onFindButtonClicked() { hide(); rememberCurrentSettings(); mTool->setSearchData(data()); mTool->setCaseSensitivity(caseSensitivity()); mTool->search(direction(), fromCursor(), inSelection()); } void SearchDialog::showEvent(QShowEvent* showEvent) { AbstractFindDialog::showEvent(showEvent); setInSelection(mTool->hasSelectedData()); } } diff --git a/kasten/controllers/view/search/searchtool.cpp b/kasten/controllers/view/search/searchtool.cpp index 54e1452e..e74a0891 100644 --- a/kasten/controllers/view/search/searchtool.cpp +++ b/kasten/controllers/view/search/searchtool.cpp @@ -1,190 +1,190 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "searchtool.hpp" // controller #include "searchuserqueryable.hpp" #include "searchjob.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { SearchTool::SearchTool() { setObjectName(QStringLiteral("Search")); } SearchTool::~SearchTool() = default; bool SearchTool::isApplyable() const { return (mByteArrayView && mByteArrayModel); // const int newPosition = finalTargetOffset(); // return ( mByteArrayView && mByteArrayModel // && (0 <= newPosition) && (newPosition <= mByteArrayModel->size()) ); } QString SearchTool::title() const { return i18nc("@title", "Search"); } bool SearchTool::hasSelectedData() const { return mByteArrayView->hasSelectedData(); } QString SearchTool::charCodingName() const { return mByteArrayView->charCodingName(); } void SearchTool::setTargetModel(AbstractModel* model) { const bool oldIsApplyable = isApplyable(); if (mByteArrayView) { mByteArrayView->disconnect(this); } if (mByteArrayModel) { mByteArrayModel->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; if (mByteArrayView && mByteArrayModel) { connect(mByteArrayView, &ByteArrayView::charCodecChanged, this, &SearchTool::charCodecChanged); // TODO: update isApplyable on cursor movement and size changes } const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void SearchTool::setUserQueryAgent(If::SearchUserQueryable* userQueryAgent) { mUserQueryAgent = userQueryAgent; } void SearchTool::setSearchData(const QByteArray& searchData) { // const bool oldIsApplyable = isApplyable(); mSearchData = searchData; // const bool newIsApplyable = isApplyable(); // if( oldIsApplyable != newIsApplyable ) // emit isApplyableChanged( newIsApplyable ); } void SearchTool::setCaseSensitivity(Qt::CaseSensitivity caseSensitivity) { // const bool oldIsApplyable = isApplyable(); mCaseSensitivity = caseSensitivity; // const bool newIsApplyable = isApplyable(); // if( oldIsApplyable != newIsApplyable ) // emit isApplyableChanged( newIsApplyable ); } void SearchTool::search(FindDirection direction, bool fromCursor, bool inSelection) { mPreviousFound = false; if (inSelection) { const Okteta::AddressRange selection = mByteArrayView->selection(); if (!selection.isValid()) { // nothing selected, so skip any search and finish now emit dataNotFound(); return; } mSearchFirstIndex = selection.start(); mSearchLastIndex = selection.end(); } else { const Okteta::Address cursorPosition = mByteArrayView->cursorPosition(); if (fromCursor && (cursorPosition != 0)) { mSearchFirstIndex = cursorPosition; mSearchLastIndex = cursorPosition - 1; } else { mSearchFirstIndex = 0; mSearchLastIndex = mByteArrayModel->size() - 1; } } doSearch(direction); } void SearchTool::doSearch(FindDirection direction) { // TODO: should start at last Okteta::Address startIndex = (direction == FindForward) ? mSearchFirstIndex : mSearchLastIndex /*-mSearchData.size()*/; bool wrapEnabled = (direction == FindForward) ? (mSearchLastIndex < startIndex) : (startIndex < mSearchFirstIndex); while (true) { QApplication::setOverrideCursor(Qt::WaitCursor); Okteta::Address endIndex = wrapEnabled ? ((direction == FindForward) ? mByteArrayModel->size() - 1 : 0) : ((direction == FindForward) ? mSearchLastIndex : mSearchFirstIndex); SearchJob* searchJob = new SearchJob(mByteArrayModel, mSearchData, startIndex, endIndex, mCaseSensitivity, mByteArrayView->charCodingName()); const Okteta::Address pos = searchJob->exec(); QApplication::restoreOverrideCursor(); if (pos != -1) { mPreviousFound = true; mByteArrayView->setSelection(pos, pos + mSearchData.size() - 1); break; } if (wrapEnabled) { const bool wrapping = mUserQueryAgent ? mUserQueryAgent->queryContinue(direction) : true; if (!wrapping) { break; } startIndex = (direction == FindForward) ? 0 : mByteArrayModel->size() - 1; wrapEnabled = false; } else { if (!mPreviousFound) { emit dataNotFound(); } break; } } mByteArrayView->setFocus(); } } diff --git a/kasten/controllers/view/selectrange/selectrangecontroller.cpp b/kasten/controllers/view/selectrange/selectrangecontroller.cpp index 355172ad..46068260 100644 --- a/kasten/controllers/view/selectrange/selectrangecontroller.cpp +++ b/kasten/controllers/view/selectrange/selectrangecontroller.cpp @@ -1,82 +1,82 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "selectrangecontroller.hpp" // controller #include "selectrangetoolview.hpp" #include "selectrangetool.hpp" // Kasten gui #include -// KF5 +// KF #include #include #include // Qt #include namespace Kasten { // TODO: a tool(view) might perhaps be invoked indirectly by asking for a tool for the object, here select // so the status bar selection indicator can invoke the same tool, without knowing about it SelectRangeController::SelectRangeController(If::ToolInlineViewable* toolInlineViewable, KXMLGUIClient* guiClient) : mToolInlineViewable(toolInlineViewable) { KActionCollection* actionCollection = guiClient->actionCollection(); mSelectAction = new QAction(QIcon::fromTheme(QStringLiteral("select-rectangular")), i18nc("@action:inmenu", "&Select Range..."), this); connect(mSelectAction, &QAction::triggered, this, &SelectRangeController::select); actionCollection->setDefaultShortcut(mSelectAction, Qt::CTRL + Qt::Key_E); actionCollection->addAction(QStringLiteral("edit_select"), mSelectAction); mTool = new SelectRangeTool(); connect(mTool, &SelectRangeTool::isUsableChanged, mSelectAction, &QAction::setEnabled); mSelectAction->setEnabled(mTool->isUsable()); mView = new SelectRangeToolView(mTool); } SelectRangeController::~SelectRangeController() { if (mToolInlineViewable->currentToolInlineView() == mView) { mToolInlineViewable->setCurrentToolInlineView(nullptr); } delete mView; delete mTool; } void SelectRangeController::setTargetModel(AbstractModel* model) { mTool->setTargetModel(model); } void SelectRangeController::select() { // mView->activate(); // TODO: show would be better here, or should instead toolInlineViewable be asked? mToolInlineViewable->setCurrentToolInlineView(mView); } } diff --git a/kasten/controllers/view/selectrange/selectrangetool.cpp b/kasten/controllers/view/selectrange/selectrangetool.cpp index edc2b354..88cac85b 100644 --- a/kasten/controllers/view/selectrange/selectrangetool.cpp +++ b/kasten/controllers/view/selectrange/selectrangetool.cpp @@ -1,202 +1,202 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "selectrangetool.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include -// KF5 +// KF #include namespace Kasten { SelectRangeTool::SelectRangeTool() : mIsEndRelative(false) , mIsEndBackwards(false) { setObjectName(QStringLiteral("SelectRange")); } SelectRangeTool::~SelectRangeTool() = default; int SelectRangeTool::currentSelectionStart() const { return mByteArrayView ? mByteArrayView->startOffset() + mByteArrayView->selection().start() : -1; } int SelectRangeTool::currentSelectionEnd() const { return mByteArrayView ? mByteArrayView->startOffset() + mByteArrayView->selection().end() : -1; } bool SelectRangeTool::isUsable() const { return (mByteArrayView && mByteArrayModel && (mByteArrayModel->size() > 0)); } bool SelectRangeTool::isApplyable() const { const int start = finalTargetSelectionStart(); const int end = finalTargetSelectionEnd(); return (mByteArrayView && mByteArrayModel && (start <= end) && (0 <= start) && (start < mByteArrayModel->size()) && (0 <= end) && (end < mByteArrayModel->size())); } QString SelectRangeTool::title() const { return i18nc("@title:window of the tool to select a range", "Select"); } void SelectRangeTool::setTargetModel(AbstractModel* model) { const bool oldIsUsable = isUsable(); const bool oldIsApplyable = isApplyable(); if (mByteArrayView) { mByteArrayView->disconnect(this); } if (mByteArrayModel) { mByteArrayModel->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; if (mByteArrayView && mByteArrayModel) { connect(mByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, this, &SelectRangeTool::onContentsChanged); // TODO: update isApplyable on cursor movement and size changes } const bool newIsUsable = isUsable(); const bool newIsApplyable = isApplyable(); if (oldIsUsable != newIsUsable) { emit isUsableChanged(newIsUsable); } if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void SelectRangeTool::setTargetStart(Okteta::Address start) { const bool oldIsApplyable = isApplyable(); mTargetStart = start; const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void SelectRangeTool::setTargetEnd(Okteta::Address end) { const bool oldIsApplyable = isApplyable(); mTargetEnd = end; const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void SelectRangeTool::setIsEndRelative(bool isEndRelative) { const bool oldIsApplyable = isApplyable(); mIsEndRelative = isEndRelative; const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void SelectRangeTool::setIsEndBackwards(bool isEndBackwards) { const bool oldIsApplyable = isApplyable(); mIsEndBackwards = isEndBackwards; const bool newIsApplyable = isApplyable(); if (oldIsApplyable != newIsApplyable) { emit isApplyableChanged(newIsApplyable); } } void SelectRangeTool::select() { const int start = finalTargetSelectionStart(); const int end = finalTargetSelectionEnd(); mByteArrayView->setSelection(start, end); mByteArrayView->setFocus(); } int SelectRangeTool::finalTargetSelectionStart() const { const int start = (!mByteArrayView) ? -1 : mIsEndRelative && mIsEndBackwards ? mTargetStart - mTargetEnd + 1 : /* else */ mTargetStart; return start; } int SelectRangeTool::finalTargetSelectionEnd() const { const int end = (!mByteArrayView) ? -1 : (!mIsEndRelative) ? mTargetEnd : mIsEndBackwards ? mTargetStart : /* else */ mTargetStart + mTargetEnd - 1; return end; } void SelectRangeTool::onContentsChanged() { // TODO: find status before content changed, e.g. by caching emit isUsableChanged(isUsable()); } } diff --git a/kasten/controllers/view/selectrange/selectrangeview.cpp b/kasten/controllers/view/selectrange/selectrangeview.cpp index ab71aa7c..11c21b2c 100644 --- a/kasten/controllers/view/selectrange/selectrangeview.cpp +++ b/kasten/controllers/view/selectrange/selectrangeview.cpp @@ -1,165 +1,165 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "selectrangeview.hpp" // tool #include "selectrangetool.hpp" // Okteta Kasten gui #include -// KF5 +// KF #include #include #include // Qt #include #include #include namespace Kasten { SelectRangeView::SelectRangeView(SelectRangeTool* tool, QWidget* parent) : AbstractToolWidget(parent) , mTool(tool) { auto* baseLayout = new QHBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); // offsets auto* offsetLayout = new QVBoxLayout(); offsetLayout->setContentsMargins(0, 0, 0, 0); // start offset auto* startOffsetLayout = new QHBoxLayout(); startOffsetLayout->setContentsMargins(0, 0, 0, 0); QLabel* label = new QLabel(i18nc("@label:listbox", "Start offset:"), this); mStartEdit = new Okteta::AddressComboBox(this); connect(mStartEdit, &Okteta::AddressComboBox::addressChanged, mTool, &SelectRangeTool::setTargetStart); label->setBuddy(mStartEdit); const QString startInputWhatsThis = i18nc("@info:whatsthis", "Enter an offset to go to, or select a previous offset from the list."); label->setWhatsThis(startInputWhatsThis); mStartEdit->setWhatsThis(startInputWhatsThis); startOffsetLayout->addWidget(label); startOffsetLayout->addWidget(mStartEdit); setFocusProxy(mStartEdit); // TODO: see how KDialog does it, e.g. see if there is already a focuswidget as child offsetLayout->addLayout(startOffsetLayout); // end offset auto* endOffsetLayout = new QHBoxLayout(); endOffsetLayout->setContentsMargins(0, 0, 0, 0); label = new QLabel(i18nc("@label:listbox", "End offset:"), this); mEndEdit = new Okteta::AddressComboBox(this); connect(mEndEdit, &Okteta::AddressComboBox::addressChanged, mTool, &SelectRangeTool::setTargetEnd); label->setBuddy(mEndEdit); const QString endInputWhatsThis = i18nc("@info:whatsthis", "Enter an offset to go to, or select a previous offset from the list."); label->setWhatsThis(endInputWhatsThis); mEndEdit->setWhatsThis(endInputWhatsThis); endOffsetLayout->addWidget(label); endOffsetLayout->addWidget(mEndEdit); offsetLayout->addLayout(endOffsetLayout); baseLayout->addLayout(offsetLayout); // options auto* optionsLayout = new QVBoxLayout(); optionsLayout->setContentsMargins(0, 0, 0, 0); mRelativeCheckBox = new QCheckBox(i18nc("@option:check", "End relative"), this); mRelativeCheckBox->setWhatsThis( i18nc("@info:whatsthis", "Extend the selection by the cursor move.")); connect(mRelativeCheckBox, &QCheckBox::toggled, mTool, &SelectRangeTool::setIsEndRelative); mRelativeCheckBox->setChecked(mTool->isEndRelative()); mBackwardsCheckBox = new QCheckBox(i18nc("@option:check", "&Backwards"), this); mBackwardsCheckBox->setWhatsThis( i18nc("@info:whatsthis", "Go backwards from the end or the current cursor location.")); connect(mBackwardsCheckBox, &QCheckBox::toggled, mTool, &SelectRangeTool::setIsEndBackwards); mBackwardsCheckBox->setChecked(mTool->isEndBackwards()); connect(mRelativeCheckBox, &QCheckBox::toggled, mBackwardsCheckBox, &QCheckBox::setEnabled); mBackwardsCheckBox->setEnabled(mRelativeCheckBox->isChecked()); optionsLayout->addWidget(mRelativeCheckBox); optionsLayout->addWidget(mBackwardsCheckBox); baseLayout->addLayout(optionsLayout); // Select button const KGuiItem selectGuiItem = KGuiItem(i18nc("@action:button", "&Select"), QString(), i18nc("@info:tooltip", "Select the range."), xi18nc("@info:whatsthis", "If you press the Select " "button, the cursor will be moved in the document to or, " "on your option, by the offset you entered above.")); mSelectButton = new QPushButton(this); KGuiItem::assign(mSelectButton, selectGuiItem); connect(mSelectButton, &QPushButton::clicked, this, &SelectRangeView::onSelectButtonClicked); addButton(mSelectButton, AbstractToolWidget::Default); baseLayout->addWidget(mSelectButton); baseLayout->setAlignment(mSelectButton, Qt::AlignTop); baseLayout->addStretch(); setTabOrder(mStartEdit, mEndEdit); setTabOrder(mEndEdit, mRelativeCheckBox); setTabOrder(mRelativeCheckBox, mBackwardsCheckBox); setTabOrder(mBackwardsCheckBox, mSelectButton); connect(mTool, &SelectRangeTool::isApplyableChanged, this, &SelectRangeView::onApplyableChanged); onApplyableChanged(mTool->isApplyable()); } SelectRangeView::~SelectRangeView() = default; void SelectRangeView::onApplyableChanged(bool isApplyable) { // TODO: set error tooltip, like offset out of range or no document // TODO: set color flag to offset input mSelectButton->setEnabled(isApplyable); } void SelectRangeView::onSelectButtonClicked() { // TODO: collect recently used offsets in tool instead? mStartEdit->rememberCurrentAddress(); mEndEdit->rememberCurrentAddress(); mTool->select(); // emit toolUsed(); } } diff --git a/kasten/controllers/view/stringsextract/containedstringtablemodel.cpp b/kasten/controllers/view/stringsextract/containedstringtablemodel.cpp index e59c742d..49cdc19d 100644 --- a/kasten/controllers/view/stringsextract/containedstringtablemodel.cpp +++ b/kasten/controllers/view/stringsextract/containedstringtablemodel.cpp @@ -1,113 +1,113 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "containedstringtablemodel.hpp" -// KF5 +// KF #include ContainedStringTableModel::ContainedStringTableModel(const QList* containedStringList, int offsetCoding, QObject* parent) : QAbstractTableModel(parent) , mContainedStringList(containedStringList) { mPrintFunction = Okteta::OffsetFormat::printFunction((Okteta::OffsetFormat::Format)offsetCoding); } ContainedStringTableModel::~ContainedStringTableModel() = default; void ContainedStringTableModel::setOffsetCoding(int offsetCoding) { mPrintFunction = Okteta::OffsetFormat::printFunction((Okteta::OffsetFormat::Format)offsetCoding); beginResetModel(); endResetModel(); } void ContainedStringTableModel::update() { beginResetModel(); endResetModel(); } int ContainedStringTableModel::rowCount(const QModelIndex& parent) const { return (!parent.isValid()) ? mContainedStringList->size() : 0; } int ContainedStringTableModel::columnCount(const QModelIndex& parent) const { return (!parent.isValid()) ? NoOfColumnIds : 0; } QVariant ContainedStringTableModel::data(const QModelIndex& index, int role) const { QVariant result; if (role == Qt::DisplayRole || role == Qt::ToolTipRole) { const int stringIndex = index.row(); if (0 <= stringIndex && stringIndex < mContainedStringList->size()) { const ContainedString& string = mContainedStringList->at(stringIndex); const int column = index.column(); switch (column) { case OffsetColumnId: { if (role == Qt::DisplayRole) { mPrintFunction(mCodedOffset, string.offset()); result = QString::fromLatin1(mCodedOffset); } break; } case StringColumnId: { result = string.string(); break; } default: ; } } } return result; } QVariant ContainedStringTableModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant result; if (role == Qt::DisplayRole) { const QString titel = section == OffsetColumnId ? i18nc("@title:column offset of the extracted string", "Offset") : section == StringColumnId ? i18nc("@title:column string extracted from the byte array", "String") : QString(); result = titel; } else { result = QAbstractTableModel::headerData(section, orientation, role); } return result; } diff --git a/kasten/controllers/view/stringsextract/stringsextracttool.cpp b/kasten/controllers/view/stringsextract/stringsextracttool.cpp index 354ff1b4..79368962 100644 --- a/kasten/controllers/view/stringsextract/stringsextracttool.cpp +++ b/kasten/controllers/view/stringsextract/stringsextracttool.cpp @@ -1,213 +1,213 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007-2009,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "stringsextracttool.hpp" // lib #include "extractstringsjob.hpp" // Okteta Kasten gui #include // Okteta Kasten core #include // Okteta core #include #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { static constexpr int DefaultMinLength = 3; StringsExtractTool::StringsExtractTool() : mExtractedStringsUptodate(false) , mSourceByteArrayModelUptodate(false) , mMinLength(DefaultMinLength) { setObjectName(QStringLiteral("Strings")); } StringsExtractTool::~StringsExtractTool() = default; bool StringsExtractTool::isApplyable() const { return (mByteArrayModel && mByteArrayView && mByteArrayView->hasSelectedData() && mMinLength > 0); } bool StringsExtractTool::canHighlightString() const { return (mSourceByteArrayModel == mByteArrayModel && mByteArrayView && mSourceByteArrayModelUptodate); } QString StringsExtractTool::title() const { return i18nc("@title:window of the tool to extract strings", "Strings"); } // TODO: add model with offset and string // doubleclick moves cursor to offset // filter für Suche, inkl. Regulärausdrücke // groß/kleinschreibung // voll strings, auch mit Leerzeichen void StringsExtractTool::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; if (mByteArrayView && mByteArrayModel) { connect(mByteArrayView, &ByteArrayView::selectedDataChanged, this, &StringsExtractTool::onSelectionChanged); // if strings are from same model, adapt offsetcoding if (mSourceByteArrayModel == mByteArrayModel) { connect(mByteArrayView, &ByteArrayView::offsetCodingChanged, this, &StringsExtractTool::offsetCodingChanged); } } // TODO: if there is no view, there is nothing to extract. // or this could be the view where we got the strings from and it did not change checkUptoDate(); emit uptodateChanged(mExtractedStringsUptodate); emit isApplyableChanged(isApplyable()); emit canHighlightStringChanged(canHighlightString()); if (mSourceByteArrayModel == mByteArrayModel && mByteArrayView) { emit offsetCodingChanged(mByteArrayView->offsetCoding()); } } int StringsExtractTool::offsetCoding() const { return (mByteArrayView ? mByteArrayView->offsetCoding() : 0); } void StringsExtractTool::setMinLength(int minLength) { mMinLength = minLength; checkUptoDate(); emit uptodateChanged(mExtractedStringsUptodate); } void StringsExtractTool::checkUptoDate() { mExtractedStringsUptodate = (mSourceByteArrayModel == mByteArrayModel && mByteArrayView && mSourceSelection == mByteArrayView->selection() && mSourceMinLength == mMinLength && mSourceByteArrayModelUptodate); } void StringsExtractTool::markString(int stringId) { if (mSourceByteArrayView != mByteArrayView) { if (mSourceByteArrayView) { mSourceByteArrayView->disconnect(this); } mSourceByteArrayView = mByteArrayView; connect(mSourceByteArrayView, &ByteArrayView::destroyed, this, &StringsExtractTool::onSourceViewDestroyed); } const ContainedString& containedString = mContainedStringList.at(stringId); const Okteta::Address offset = containedString.offset(); const int length = containedString.string().length(); const Okteta::AddressRange markingRange = Okteta::AddressRange::fromWidth(offset, length); mSourceByteArrayView->setMarking(markingRange, true); } void StringsExtractTool::unmarkString() { // TODO: marked region is property of document, not view? if (mSourceByteArrayView) { mSourceByteArrayView->setMarking(Okteta::AddressRange()); } } void StringsExtractTool::onSelectionChanged() { // TODO: could be quicker using the selection data checkUptoDate(); emit uptodateChanged(mExtractedStringsUptodate); emit isApplyableChanged(isApplyable()); } void StringsExtractTool::onSourceChanged() { mExtractedStringsUptodate = false; mSourceByteArrayModelUptodate = false; emit uptodateChanged(false); emit canHighlightStringChanged(false); } void StringsExtractTool::onSourceDestroyed() { mSourceByteArrayModel = nullptr; onSourceChanged(); } void StringsExtractTool::onSourceViewDestroyed() { mSourceByteArrayView = nullptr; } // TODO: use TextByteArrayAnalyzer void StringsExtractTool::extractStrings() { // forget old string source if (mSourceByteArrayModel) { mSourceByteArrayModel->disconnect(this); } QApplication::setOverrideCursor(Qt::WaitCursor); Okteta::CharCodec* charCodec = Okteta::CharCodec::createCodec(mByteArrayView->charCodingName()); ExtractStringsJob* extractStringsJob = new ExtractStringsJob(mByteArrayModel, mByteArrayView->selection(), charCodec, mMinLength, &mContainedStringList); extractStringsJob->exec(); delete charCodec; QApplication::restoreOverrideCursor(); // remember new string source mSourceByteArrayModel = mByteArrayModel; mSourceSelection = mByteArrayView->selection(); mSourceMinLength = mMinLength; connect(mSourceByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, this, &StringsExtractTool::onSourceChanged); connect(mSourceByteArrayModel, &Okteta::AbstractByteArrayModel::destroyed, this, &StringsExtractTool::onSourceDestroyed); connect(mByteArrayView, &ByteArrayView::offsetCodingChanged, this, &StringsExtractTool::offsetCodingChanged); mExtractedStringsUptodate = true; mSourceByteArrayModelUptodate = true; emit uptodateChanged(true); emit canHighlightStringChanged(true); emit offsetCodingChanged(mByteArrayView->offsetCoding()); } } diff --git a/kasten/controllers/view/stringsextract/stringsextracttoolviewfactory.cpp b/kasten/controllers/view/stringsextract/stringsextracttoolviewfactory.cpp index dbabf278..6ec6e487 100644 --- a/kasten/controllers/view/stringsextract/stringsextracttoolviewfactory.cpp +++ b/kasten/controllers/view/stringsextract/stringsextracttoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "stringsextracttoolviewfactory.hpp" // lib #include "stringsextracttoolview.hpp" #include "stringsextracttool.hpp" -// KF5 +// KF #include namespace Kasten { StringsExtractToolViewFactory::StringsExtractToolViewFactory() = default; StringsExtractToolViewFactory::~StringsExtractToolViewFactory() = default; QString StringsExtractToolViewFactory::iconName() const { return QStringLiteral("text-plain"); } QString StringsExtractToolViewFactory::title() const { return i18nc("@title:window", "Strings"); } QString StringsExtractToolViewFactory::id() const { return QStringLiteral("org.kde.okteta.StringsToolView"); } SidePosition StringsExtractToolViewFactory::defaultPosition() const { return RightSidePosition; } AbstractToolView* StringsExtractToolViewFactory::create(AbstractTool* tool) const { return new StringsExtractToolView(qobject_cast(tool)); } } diff --git a/kasten/controllers/view/stringsextract/stringsextractview.cpp b/kasten/controllers/view/stringsextract/stringsextractview.cpp index e724ab4e..0ab02d54 100644 --- a/kasten/controllers/view/stringsextract/stringsextractview.cpp +++ b/kasten/controllers/view/stringsextract/stringsextractview.cpp @@ -1,273 +1,273 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "stringsextractview.hpp" // tool #include "containedstringtablemodel.hpp" #include "stringsextracttool.hpp" -// KF5 +// KF #include #include // Qt #include #include #include #include #include #include #include #include #include #include #include #include namespace Kasten { static constexpr int MinimumStringLength = 1; StringsExtractView::StringsExtractView(StringsExtractTool* tool, QWidget* parent) : QWidget(parent) , mTool(tool) { auto* baseLayout = new QVBoxLayout(this); baseLayout->setContentsMargins(0, 0, 0, 0); // update auto* updateLayout = new QHBoxLayout(); updateLayout->addStretch(); QLabel* label = new QLabel(i18nc("@label:spinbox minimum length for consecutive chars to be seen as a string", "Minimum length:"), this); updateLayout->addWidget(label); mMinLengthSpinBox = new QSpinBox(this); mMinLengthSpinBox->setValue(mTool->minLength()); mMinLengthSpinBox->setMinimum(MinimumStringLength); connect(mMinLengthSpinBox, QOverload::of(&QSpinBox::valueChanged), mTool, &StringsExtractTool::setMinLength); label->setBuddy(mMinLengthSpinBox); updateLayout->addWidget(mMinLengthSpinBox); const KGuiItem updateGuiItem = KGuiItem(i18nc("@action:button extract the strings from the byte array", "&Extract"), QStringLiteral("document-export"), i18nc("@info:tooltip", "Finds the strings contained in the selected range and lists them in the view below."), xi18nc("@info:whatsthis", "If you press the Extract button, " "the selected range is searched for all strings which have the set minimum length. " "This strings found will be listed in the view below.")); mUpdateButton = new QPushButton(this); KGuiItem::assign(mUpdateButton, updateGuiItem); mUpdateButton->setEnabled(mTool->isApplyable()); connect(mUpdateButton, &QPushButton::clicked, mTool, &StringsExtractTool::extractStrings); updateLayout->addWidget(mUpdateButton); baseLayout->addLayout(updateLayout); // filter auto* filterLayout = new QHBoxLayout(); label = new QLabel(i18nc("@label:lineedit filter term for displayed strings", "Filter:"), this); filterLayout->addWidget(label); auto* mFilterEdit = new QLineEdit(this); mFilterEdit->setClearButtonEnabled(true); mFilterEdit->setPlaceholderText(i18n("Enter a term to limit the list.")); label->setBuddy(mFilterEdit); filterLayout->addWidget(mFilterEdit, 10); baseLayout->addLayout(filterLayout); // strings mContainedStringTableModel = new ContainedStringTableModel(mTool->containedStringList(), mTool->offsetCoding(), this); connect(mTool, &StringsExtractTool::offsetCodingChanged, mContainedStringTableModel, &ContainedStringTableModel::setOffsetCoding); mSortFilterProxyModel = new QSortFilterProxyModel(this); mSortFilterProxyModel->setDynamicSortFilter(true); mSortFilterProxyModel->setSourceModel(mContainedStringTableModel); mSortFilterProxyModel->setFilterKeyColumn(ContainedStringTableModel::StringColumnId); mSortFilterProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); connect(mFilterEdit, &QLineEdit::textChanged, mSortFilterProxyModel, &QSortFilterProxyModel::setFilterFixedString); mContainedStringTableView = new QTreeView(this); // TODO: find a signal/event emitted when fixedfont changes // connect( KGlobalSettings::self(), &KGlobalSettings::kdisplayFontChanged, // this, &StringsExtractView::setFixedFontByGlobalSettings ); setFixedFontByGlobalSettings(); // do this before setting model mContainedStringTableView->setObjectName(QStringLiteral("ContainedStringTable")); mContainedStringTableView->setRootIsDecorated(false); mContainedStringTableView->setItemsExpandable(false); mContainedStringTableView->setUniformRowHeights(true); mContainedStringTableView->setAllColumnsShowFocus(true); mContainedStringTableView->setSelectionMode(QAbstractItemView::ExtendedSelection); mContainedStringTableView->setSortingEnabled(true); mContainedStringTableView->installEventFilter(this); QHeaderView* header = mContainedStringTableView->header(); header->setFont(font()); header->setSectionResizeMode(QHeaderView::Interactive); mContainedStringTableView->setModel(mSortFilterProxyModel); mContainedStringTableView->sortByColumn(ContainedStringTableModel::OffsetColumnId, Qt::AscendingOrder); connect(mContainedStringTableView, &QTreeView::doubleClicked, this, &StringsExtractView::onStringDoubleClicked); connect(mContainedStringTableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &StringsExtractView::onStringSelectionChanged); baseLayout->addWidget(mContainedStringTableView, 10); // actions auto* actionsLayout = new QHBoxLayout(); const KGuiItem copyGuiItem = KGuiItem(i18n("C&opy"), QStringLiteral("edit-copy"), i18nc("@info:tooltip", "Copies the selected strings to the clipboard."), xi18nc("@info:whatsthis", "If you press the Copy button, all strings you selected " "in the list are copied to the clipboard.")); mCopyButton = new QPushButton(this); KGuiItem::assign(mCopyButton, copyGuiItem); connect(mCopyButton, &QPushButton::clicked, this, &StringsExtractView::onCopyButtonClicked); actionsLayout->addWidget(mCopyButton); actionsLayout->addStretch(); const KGuiItem gotoGuiItem = KGuiItem(i18n("&Show"), QStringLiteral("go-jump"), i18nc("@info:tooltip", "Shows the selected string in the view."), xi18nc("@info:whatsthis", "If you press the Go to button, the string which was last " "selected is marked and shown in the view.")); mGotoButton = new QPushButton(this); KGuiItem::assign(mGotoButton, gotoGuiItem); connect(mGotoButton, &QPushButton::clicked, this, &StringsExtractView::onGotoButtonClicked); actionsLayout->addWidget(mGotoButton); baseLayout->addLayout(actionsLayout); connect(mTool, &StringsExtractTool::uptodateChanged, this, &StringsExtractView::onStringsUptodateChanged); connect(mTool, &StringsExtractTool::isApplyableChanged, this, &StringsExtractView::onApplyableChanged); connect(mTool, &StringsExtractTool::canHighlightStringChanged, this, &StringsExtractView::onCanHighlightStringChanged); onStringSelectionChanged(); } StringsExtractView::~StringsExtractView() = default; bool StringsExtractView::eventFilter(QObject* object, QEvent* event) { if (object == mContainedStringTableView) { if (event->type() == QEvent::FocusOut) { auto* focusEvent = static_cast(event); const Qt::FocusReason focusReason = focusEvent->reason(); if (focusReason != Qt::ActiveWindowFocusReason && focusReason != Qt::PopupFocusReason) { mTool->unmarkString(); } } } return QWidget::eventFilter(object, event); } void StringsExtractView::setFixedFontByGlobalSettings() { mContainedStringTableView->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); } void StringsExtractView::onStringsUptodateChanged(bool stringsUptodate) { if (stringsUptodate) { mContainedStringTableModel->update(); } const bool isApplyable = mTool->isApplyable(); mUpdateButton->setEnabled(!stringsUptodate && isApplyable); } void StringsExtractView::onApplyableChanged(bool isApplyable) { mUpdateButton->setEnabled(!mTool->isUptodate() && isApplyable); } void StringsExtractView::onCanHighlightStringChanged(bool canHighlightString) { const bool stringSelected = mContainedStringTableView->selectionModel()->currentIndex().isValid(); mGotoButton->setEnabled(canHighlightString && stringSelected); } void StringsExtractView::onGotoButtonClicked() { const QModelIndex index = mContainedStringTableView->selectionModel()->currentIndex(); if (index.isValid()) { // TODO: hack: as currently the marking is only undone if the focus leaves the listview it needs to be moved there before mContainedStringTableView->setFocus(); onStringDoubleClicked(index); } } void StringsExtractView::onCopyButtonClicked() { const QModelIndexList selectedRows = mContainedStringTableView->selectionModel()->selectedRows(); const QList* containedStringList = mTool->containedStringList(); QString strings; for (const QModelIndex& index : selectedRows) { const int i = mSortFilterProxyModel->mapToSource(index).row(); strings += containedStringList->at(i).string(); strings += QLatin1Char('\n'); // TODO: specific linefeed for platforms } QApplication::clipboard()->setText(strings); } void StringsExtractView::onStringSelectionChanged() { const QItemSelectionModel* selectionModel = mContainedStringTableView->selectionModel(); // TODO: selectionModel->selectedIndexes() is a expensive operation, // but with Qt 4.4.3 hasSelection() has the flaw to return true with a current index const bool hasSelection = !selectionModel->selectedIndexes().isEmpty(); mCopyButton->setEnabled(hasSelection); const bool stringSelected = selectionModel->isSelected(selectionModel->currentIndex()); const bool canHighlightString = mTool->canHighlightString(); mGotoButton->setEnabled(canHighlightString && stringSelected); } void StringsExtractView::onStringDoubleClicked(const QModelIndex& index) { if (mTool->canHighlightString()) { mTool->markString(mSortFilterProxyModel->mapToSource(index).row()); } } } diff --git a/kasten/controllers/view/structures/datatypes/primitive/chardatainformation.cpp b/kasten/controllers/view/structures/datatypes/primitive/chardatainformation.cpp index 63b006e1..ef5c0f02 100644 --- a/kasten/controllers/view/structures/datatypes/primitive/chardatainformation.cpp +++ b/kasten/controllers/view/structures/datatypes/primitive/chardatainformation.cpp @@ -1,141 +1,141 @@ /* * This file is part of the Okteta Kasten Framework, made within the KDE community. * * Copyright 2009, 2010, 2011 Alex Richardson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "chardatainformation.hpp" -// KF5 +// KF #include // Qt #include #include #include #include "structureviewpreferences.h" namespace { QString charString(quint8 value) { switch (value) { case '\0': return QStringLiteral("'\\0'"); case '\a': return QStringLiteral("'\\a'"); case '\b': return QStringLiteral("'\\b'"); case '\f': return QStringLiteral("'\\f'"); case '\n': return QStringLiteral("'\\n'"); case '\r': return QStringLiteral("'\\r'"); case '\t': return QStringLiteral("'\\t'"); case '\v': return QStringLiteral("'\\v'"); default: break; } QChar qchar = QChar(quint32(value)); if (!qchar.isPrint()) { qchar = QChar::ReplacementCharacter; } return QString(QLatin1Char('\'') + qchar + QLatin1Char('\'')); } } QString CharDataInformationMethods::staticValueString(quint8 value) { QString charStr = charString(value); if (Kasten::StructureViewPreferences::showCharNumericalValue()) { int base = Kasten::StructureViewPreferences::charDisplayBase(); const QString num = (base == 10 && Kasten::StructureViewPreferences::localeAwareDecimalFormatting()) ? QLocale().toString(value) : QString::number(value, base); charStr += QLatin1String(" (") + PrimitiveDataInformation::basePrefix(base) + num + QLatin1Char(')'); } return charStr; } QWidget* CharDataInformationMethods::staticCreateEditWidget(QWidget* parent) { auto* editWidget = new QLineEdit(parent); editWidget->setClearButtonEnabled(true); return editWidget; } QVariant CharDataInformationMethods::staticDataFromWidget(const QWidget* w) { // TODO fix this code!! const auto* edit = qobject_cast (w); if (edit) { QString text = edit->text(); if (text.length() == 0) { return {}; } if (text.length() == 1) { // TODO char codec return (unsigned char) text.at(0).toLatin1(); } if (text.at(0) == QLatin1Char('\\')) { // escape sequence if (text.at(1) == QLatin1Char('x')) { // hex escape: bool okay; const QStringRef valStr = text.midRef(2, 2); // only 2 chars quint8 val = valStr.toInt(&okay, 16); if (okay) { return val; } return {}; } if (text.at(1) == QLatin1Char('n')) { return (quint8) '\n'; // newline } if (text.at(1) == QLatin1Char('t')) { return (quint8) '\t'; // tab } if (text.at(1) == QLatin1Char('r')) { return (quint8) '\r'; // cr } // octal escape: bool okay; const QStringRef valStr = text.midRef(1, 3); // only 2 chars quint8 val = valStr.toInt(&okay, 8); if (okay) { return val; } return {}; } } return {}; } void CharDataInformationMethods::staticSetWidgetData(quint8 value, QWidget* w) { auto* edit = qobject_cast (w); if (edit) { QChar qchar(value, 0); if (!qchar.isPrint()) { qchar = QChar(QChar::ReplacementCharacter); } edit->setText(qchar); } } QScriptValue CharDataInformationMethods::asScriptValue(quint8 value, QScriptEngine* engine, ScriptHandlerInfo* handler) { Q_UNUSED(engine); Q_UNUSED(handler); return QScriptValue(QString(value > 127 ? QChar::ReplacementCharacter : QChar(value, 0))); } diff --git a/kasten/controllers/view/structures/datatypes/primitive/doubledatainformation.cpp b/kasten/controllers/view/structures/datatypes/primitive/doubledatainformation.cpp index 519a89c1..caa2a7a0 100644 --- a/kasten/controllers/view/structures/datatypes/primitive/doubledatainformation.cpp +++ b/kasten/controllers/view/structures/datatypes/primitive/doubledatainformation.cpp @@ -1,70 +1,70 @@ /* * This file is part of the Okteta Kasten Framework, made within the KDE community. * * Copyright 2009, 2010, 2011 Alex Richardson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "doubledatainformation.hpp" -// KF5 +// KF #include // Qt #include #include #include #include "structureviewpreferences.h" QWidget* DoubleDataInformationMethods::staticCreateEditWidget(QWidget* parent) { auto* ret = new QDoubleSpinBox(parent); return ret; } QVariant DoubleDataInformationMethods::staticDataFromWidget(const QWidget* w) { const auto* spin = qobject_cast (w); Q_CHECK_PTR(spin); if (spin) { return spin->value(); } return {}; } void DoubleDataInformationMethods::staticSetWidgetData(double value, QWidget* w) { auto* spin = qobject_cast (w); Q_CHECK_PTR(spin); if (spin) { spin->setValue(value); } } QScriptValue DoubleDataInformationMethods::asScriptValue(double value, QScriptEngine* engine, ScriptHandlerInfo* handler) { Q_UNUSED(engine); Q_UNUSED(handler); return {value}; } QString DoubleDataInformationMethods::staticValueString(double value) { return (Kasten::StructureViewPreferences::localeAwareFloatFormatting()) ? QLocale().toString(value, 'g', Kasten::StructureViewPreferences::floatPrecision()) : QString::number(value, 'g', Kasten::StructureViewPreferences::floatPrecision()); } diff --git a/kasten/controllers/view/structures/datatypes/primitive/floatdatainformation.cpp b/kasten/controllers/view/structures/datatypes/primitive/floatdatainformation.cpp index 38ef9aa0..fb99737a 100644 --- a/kasten/controllers/view/structures/datatypes/primitive/floatdatainformation.cpp +++ b/kasten/controllers/view/structures/datatypes/primitive/floatdatainformation.cpp @@ -1,73 +1,73 @@ /* * This file is part of the Okteta Kasten Framework, made within the KDE community. * * Copyright 2009, 2010, 2011 Alex Richardson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "floatdatainformation.hpp" #include -// KF5 +// KF #include // Qt #include #include #include #include "structureviewpreferences.h" QWidget* FloatDataInformationMethods::staticCreateEditWidget(QWidget* parent) { auto* ret = new QDoubleSpinBox(parent); ret->setMinimum(std::numeric_limits::min()); ret->setMaximum(std::numeric_limits::max()); return ret; } QVariant FloatDataInformationMethods::staticDataFromWidget(const QWidget* w) { const auto* spin = qobject_cast (w); Q_CHECK_PTR(spin); if (spin) { return ((float) spin->value()); } return {}; } void FloatDataInformationMethods::staticSetWidgetData(float value, QWidget* w) { auto* spin = qobject_cast (w); Q_CHECK_PTR(spin); if (spin) { spin->setValue(value); } } QScriptValue FloatDataInformationMethods::asScriptValue(float value, QScriptEngine* engine, ScriptHandlerInfo* handler) { Q_UNUSED(engine); Q_UNUSED(handler); return {value}; } QString FloatDataInformationMethods::staticValueString(float value) { return (Kasten::StructureViewPreferences::localeAwareFloatFormatting()) ? QLocale().toString(value, 'g', Kasten::StructureViewPreferences::floatPrecision()) : QString::number(value, 'g', Kasten::StructureViewPreferences::floatPrecision()); } diff --git a/kasten/controllers/view/structures/datatypes/primitive/sintdatainformation.cpp b/kasten/controllers/view/structures/datatypes/primitive/sintdatainformation.cpp index d7005f82..b08594f4 100644 --- a/kasten/controllers/view/structures/datatypes/primitive/sintdatainformation.cpp +++ b/kasten/controllers/view/structures/datatypes/primitive/sintdatainformation.cpp @@ -1,116 +1,116 @@ /* * This file is part of the Okteta Kasten Framework, made within the KDE community. * * Copyright 2011 Alex Richardson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "sintdatainformation.hpp" #include "../poddecoder/typeeditors/sintspinbox.hpp" #include "../../structlogging.hpp" -// KF5 +// KF #include // Qt #include #include template QString SIntDataInformationMethods::staticValueString(T val, int base) { QString num; if (base == 10) { return Kasten::StructureViewPreferences::localeAwareDecimalFormatting() ? QLocale().toString(val) : QString::number(val, base); } // the absolute value of negative minimum can not be represented as a signed integer // casting it to an unsigned value yields the correct result if (val == std::numeric_limits::min()) { num = QString::number(typename QIntegerForSizeof::Unsigned(val), base); } else if (val < 0) { num = QString::number(qAbs(val), base); } else { num = QString::number(val, base); } // TODO non decimal negative values as unsigned? probably add option // add one space every 8 chars for (int i = 8; i < num.length(); i += 9) { num.insert(num.length() - i, QLatin1Char(' ')); } if (val < 0) { return QLatin1Char('-') + PrimitiveDataInformation::basePrefix(base) + num; } return PrimitiveDataInformation::basePrefix(base) + num; } template QScriptValue SIntDataInformationMethods::asScriptValue(T value, QScriptEngine* engine, ScriptHandlerInfo* handler) { Q_UNUSED(engine); Q_UNUSED(handler); return {value}; } template <> QScriptValue SIntDataInformationMethods::asScriptValue(qint64 value, QScriptEngine* engine, ScriptHandlerInfo* handler) { Q_UNUSED(engine); Q_UNUSED(handler); return {QString::number(value, 10)}; } template inline QWidget* SIntDataInformationMethods::staticCreateEditWidget(QWidget* parent) { auto* ret = new SIntSpinBox(parent, Kasten::StructureViewPreferences::signedDisplayBase()); ret->setRange(std::numeric_limits::min(), std::numeric_limits::max()); return ret; } template inline QVariant SIntDataInformationMethods::staticDataFromWidget(const QWidget* w) { const auto* spin = qobject_cast(w); Q_CHECK_PTR(spin); if (spin) { return spin->value(); } qCWarning(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "could not cast widget"; return {}; } template inline void SIntDataInformationMethods::staticSetWidgetData(T value, QWidget* w) { auto* spin = qobject_cast(w); Q_CHECK_PTR(spin); if (spin) { spin->setValue(value); } } // explicitly instantiate all valid classes (c++-faq-lite 35.12) template class SIntDataInformationMethods; template class SIntDataInformationMethods; template class SIntDataInformationMethods; template class SIntDataInformationMethods; diff --git a/kasten/controllers/view/structures/datatypes/primitive/uintdatainformation.cpp b/kasten/controllers/view/structures/datatypes/primitive/uintdatainformation.cpp index d18365ce..8aba253e 100644 --- a/kasten/controllers/view/structures/datatypes/primitive/uintdatainformation.cpp +++ b/kasten/controllers/view/structures/datatypes/primitive/uintdatainformation.cpp @@ -1,103 +1,103 @@ /* * This file is part of the Okteta Kasten Framework, made within the KDE community. * * Copyright 2011 Alex Richardson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "uintdatainformation.hpp" #include "../../structlogging.hpp" -// KF5 +// KF #include // Qt #include #include #include "../../../poddecoder/typeeditors/uintspinbox.hpp" #include "structureviewpreferences.h" template QScriptValue UIntDataInformationMethods::asScriptValue(T value, QScriptEngine* engine, ScriptHandlerInfo* handlerInfo) { Q_UNUSED(engine); Q_UNUSED(handlerInfo); return {value}; } template <> QScriptValue UIntDataInformationMethods::asScriptValue(quint64 value, QScriptEngine* engine, ScriptHandlerInfo* handlerInfo) { Q_UNUSED(engine); Q_UNUSED(handlerInfo); return {QString::number(value, 10)}; } template QString UIntDataInformationMethods::staticValueString(T value, int base) { QString num = QString::number(value, base); if (base == 10) { if (Kasten::StructureViewPreferences::localeAwareDecimalFormatting()) { num = QLocale().toString(value); } } else { // add one space every 8 chars for (int i = 8; i < num.length(); i += 9) { num.insert(num.length() - i, QLatin1Char(' ')); } } return PrimitiveDataInformation::basePrefix(base) + num; } template inline QWidget* UIntDataInformationMethods::staticCreateEditWidget(QWidget* parent) { auto* ret = new UIntSpinBox(parent, Kasten::StructureViewPreferences::unsignedDisplayBase()); ret->setMaximum(std::numeric_limits::max()); return ret; } template inline QVariant UIntDataInformationMethods::staticDataFromWidget(const QWidget* w) { const auto* spin = qobject_cast (w); Q_CHECK_PTR(spin); if (spin) { return {spin->value()}; } qCWarning(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "could not cast widget"; return {}; } template inline void UIntDataInformationMethods::staticSetWidgetData(T value, QWidget* w) { auto* spin = qobject_cast (w); Q_CHECK_PTR(spin); if (spin) { spin->setValue(value); } } // explicitly instantiate all valid classes (c++-faq-lite 35.12) template class UIntDataInformationMethods; template class UIntDataInformationMethods; template class UIntDataInformationMethods; template class UIntDataInformationMethods; diff --git a/kasten/controllers/view/structures/settings/structuresmanagerview.cpp b/kasten/controllers/view/structures/settings/structuresmanagerview.cpp index 006a80cc..1711cb76 100644 --- a/kasten/controllers/view/structures/settings/structuresmanagerview.cpp +++ b/kasten/controllers/view/structures/settings/structuresmanagerview.cpp @@ -1,199 +1,199 @@ /* This file is part of the Okteta Kasten Framework, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau Copyright 2009, 2012 Alex Richardson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "structuresmanagerview.hpp" #include "structureaddremovewidget.hpp" #include "structureviewpreferences.h" #include "../structuresmanager.hpp" #include "../structurestool.hpp" #include "../structlogging.hpp" -// KF5 +// KF #include #include #include #include #include // Qt #include #include #include #include #include #include StructuresManagerView::StructuresManagerView(Kasten::StructuresTool* tool, QWidget* parent) : QWidget(parent) , mTool(tool) , mRebuildingPluginsList(false) { mSelectedStructures = Kasten::StructureViewPreferences::loadedStructures(); auto* pageLayout = new QVBoxLayout(); pageLayout->setContentsMargins(0, 0, 0, 0); setLayout(pageLayout); rebuildPluginSelectorEntries(); auto* buttonsLayout = new QHBoxLayout(); pageLayout->addLayout(buttonsLayout); mGetNewStructuresButton = new KNS3::Button(i18n("Get New Structures..."), QStringLiteral("okteta-structures.knsrc"), this); connect(mGetNewStructuresButton, &KNS3::Button::dialogFinished, this, &StructuresManagerView::onGetNewStructuresClicked); buttonsLayout->addWidget(mGetNewStructuresButton); mAdvancedSelectionButton = new QPushButton(QIcon::fromTheme(QStringLiteral("configure")), i18n("Advanced Selection..."), this); connect(mAdvancedSelectionButton, &QPushButton::clicked, this, &StructuresManagerView::advancedSelection); buttonsLayout->addWidget(mAdvancedSelectionButton); } StructuresManagerView::~StructuresManagerView() = default; void StructuresManagerView::onGetNewStructuresClicked(const KNS3::Entry::List& changedEntries) { for (const KNS3::Entry& e : changedEntries) { qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "Changed Entry: " << e.name(); if (e.status() == KNS3::Entry::Installed) { // new element installed qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "installed files:" << e.installedFiles(); } if (e.status() == KNS3::Entry::Deleted) { // element uninstalled qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "deleted files:" << e.uninstalledFiles(); } } if (!changedEntries.isEmpty()) { qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "installed structures changed -> rebuilding list of installed structures"; mTool->manager()->reloadPaths(); rebuildPluginSelectorEntries(); } } QStringList StructuresManagerView::values() const { return mSelectedStructures; } void StructuresManagerView::advancedSelection() { auto* advancedSelectionWidget = new StructureAddRemoveWidget(mSelectedStructures, mTool, this); QPointer dlg = new QDialog(this); // the dlg-on-heap-variant dlg->setWindowTitle(i18nc("@title:window", "Advanced Structures Selection")); auto* layout = new QVBoxLayout; auto* dialogButtonBox = new QDialogButtonBox; dialogButtonBox->addButton(QDialogButtonBox::Ok); connect(dialogButtonBox, &QDialogButtonBox::accepted, dlg.data(), &QDialog::accept); dialogButtonBox->addButton(QDialogButtonBox::Cancel); connect(dialogButtonBox, &QDialogButtonBox::rejected, dlg.data(), &QDialog::reject); layout->addWidget(advancedSelectionWidget); layout->addWidget(dialogButtonBox); dlg->setLayout(layout); if (dlg->exec() == QDialog::Accepted) { QStringList newVals = advancedSelectionWidget->values(); if (newVals != mSelectedStructures) { qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "selection changed from " << mSelectedStructures << "to" << newVals; mSelectedStructures = newVals; emit changed(newVals); } } delete dlg; } void StructuresManagerView::onPluginSelectorChange(bool change) { if (mRebuildingPluginsList) { return; } qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "pluginselector changed: " << change; if (!change) { return; } mStructuresSelector->save(); reloadSelectedItems(); } void StructuresManagerView::reloadSelectedItems() { QStringList newVals; const auto structureDefs = mTool->manager()->structureDefs(); for (const Kasten::StructureDefinitionFile* def : structureDefs) { KPluginInfo info = def->pluginInfo(); if (info.isPluginEnabled()) { newVals.append(QString(QStringLiteral("\'%1\':\'*\'")).arg(info.pluginName())); } } if (newVals != mSelectedStructures) { qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "selection changed from " << mSelectedStructures << "to" << newVals; mSelectedStructures = newVals; emit changed(newVals); } else { qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "no change:" << mSelectedStructures; } } void StructuresManagerView::rebuildPluginSelectorEntries() { mRebuildingPluginsList = true; QStringList newVals; KPluginInfo::List plugins; KPluginInfo::List dynamicPlugins; const auto structureDefs = mTool->manager()->structureDefs(); for (const Kasten::StructureDefinitionFile* def : structureDefs) { KPluginInfo info = def->pluginInfo(); if (info.category() == QLatin1String("structure")) { plugins.append(info); } else if (info.category() == QLatin1String("structure/js")) { dynamicPlugins.append(info); } } // XXX is there any way to clear the plugins selector? auto* layoutObj = qobject_cast(layout()); Q_CHECK_PTR(layoutObj); if (mStructuresSelector) { layoutObj->removeWidget(mStructuresSelector); delete mStructuresSelector; } mStructuresSelector = new KPluginSelector(this); connect(mStructuresSelector, &KPluginSelector::changed, this, &StructuresManagerView::onPluginSelectorChange); layoutObj->insertWidget(0, mStructuresSelector); mStructuresSelector->addPlugins(plugins, KPluginSelector::ReadConfigFile, i18n("Structure Definitions"), QStringLiteral("structure"), mTool->manager()->config()); mStructuresSelector->addPlugins(dynamicPlugins, KPluginSelector::ReadConfigFile, i18n("Dynamic Structure Definitions"), QStringLiteral("structure/js"), mTool->manager()->config()); mStructuresSelector->load(); mStructuresSelector->updatePluginsState(); mRebuildingPluginsList = false; reloadSelectedItems(); } diff --git a/kasten/controllers/view/structures/settings/structuresmanagerview.hpp b/kasten/controllers/view/structures/settings/structuresmanagerview.hpp index 6853373b..b05c91e6 100644 --- a/kasten/controllers/view/structures/settings/structuresmanagerview.hpp +++ b/kasten/controllers/view/structures/settings/structuresmanagerview.hpp @@ -1,80 +1,80 @@ /* This file is part of the Okteta Kasten Framework, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau Copyright 2009, 2012 Alex Richardson This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_STRUCTURESMANAGERVIEW_HPP #define KASTEN_STRUCTURESMANAGERVIEW_HPP -// KF5 +// KF #include // Qt #include class StructureAddRemoveWidget; class QPushButton; class KPluginSelector; namespace KNS3 { class Button; } namespace Kasten { class StructuresManager; class StructuresTool; } class StructuresManagerView : public QWidget { Q_OBJECT public: Q_PROPERTY(QStringList values READ values NOTIFY changed USER true) explicit StructuresManagerView(Kasten::StructuresTool* manager, QWidget* parent = nullptr); ~StructuresManagerView() override; public: QStringList values() const; Q_SIGNALS: void selectedPluginsChanged(); void changed(const QStringList& newValues); private Q_SLOTS: void onGetNewStructuresClicked(const KNS3::Entry::List& changedEntries); void onPluginSelectorChange(bool change); void advancedSelection(); private: void rebuildPluginSelectorEntries(); void reloadSelectedItems(); private: Kasten::StructuresTool* mTool; QStringList mSelectedStructures; KNS3::Button* mGetNewStructuresButton; QPushButton* mAdvancedSelectionButton; KPluginSelector* mStructuresSelector = nullptr; bool mRebuildingPluginsList : 1; }; #endif diff --git a/kasten/controllers/view/structures/structuresmanager.hpp b/kasten/controllers/view/structures/structuresmanager.hpp index 955f3a34..3abe79c9 100644 --- a/kasten/controllers/view/structures/structuresmanager.hpp +++ b/kasten/controllers/view/structures/structuresmanager.hpp @@ -1,65 +1,65 @@ /* * This file is part of the Okteta Kasten Framework, made within the KDE community. * * Copyright 2009, 2010 Alex Richardson * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #ifndef KASTEN_STRUCTURESMANAGER_HPP #define KASTEN_STRUCTURESMANAGER_HPP #include "structuredefinitionfile.hpp" // Qt #include #include -// KF5 +// KF #include #include namespace Kasten { class StructuresManager : public QObject { Q_OBJECT public: explicit StructuresManager(QObject* parent = nullptr); ~StructuresManager() override; public Q_SLOTS: void reloadPaths(); public: QMap structureDefs() const; KSharedConfig::Ptr config() const; StructureDefinitionFile* definition(const QString& pluginName) const; private: void addStructDef(const KPluginInfo& info); private: QMap mDefs; QStringList mLoadedFiles; KSharedConfig::Ptr mConfig; }; } #endif diff --git a/kasten/controllers/view/structures/structurestool.cpp b/kasten/controllers/view/structures/structurestool.cpp index 8d8b329e..c2f7950e 100644 --- a/kasten/controllers/view/structures/structurestool.cpp +++ b/kasten/controllers/view/structures/structurestool.cpp @@ -1,431 +1,431 @@ /* * This file is part of the Okteta Kasten Framework, made within the KDE community. * * Copyright 2009, 2010, 2011, 2012 Alex Richardson * Copyright 2009 Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "structurestool.hpp" #include "structuredefinitionfile.hpp" #include "structuresmanager.hpp" #include "structlogging.hpp" // Okteta Kasten core #include // Okteta core #include #include #include -// KF5 +// KF #include // Qt #include #include "script/scripthandler.hpp" #include "datatypes/datainformation.hpp" #include "structureviewpreferences.h" namespace Kasten { StructuresTool::StructuresTool() : mByteOrder(StructureViewPreferences::byteOrder()) , mManager(new StructuresManager(this)) , mWritingData(false) , mCurrentItemDataChanged(false) { // leave mLoadedFiles empty for now, since otherwise loading slot will not work setObjectName(QStringLiteral("StructuresTool")); mManager->reloadPaths(); setSelectedStructuresInView(); // mUtf8Codec = QTextCodec::codecForName("UTF-8"); connect(this, &StructuresTool::byteOrderChanged, this, &StructuresTool::onByteOrderChanged); } StructuresTool::~StructuresTool() = default; void StructuresTool::onByteOrderChanged() { updateData(Okteta::ArrayChangeMetricsList()); } void StructuresTool::setByteOrder(QSysInfo::Endian order) { if (order != StructureViewPreferences::byteOrder() || order != mByteOrder) { emit byteOrderChanged(); StructureViewPreferences::setByteOrder(order); mByteOrder = order; updateData(Okteta::ArrayChangeMetricsList()); } } QString StructuresTool::title() const { return i18nc("@title:window", "Structures"); } void StructuresTool::setTargetModel(AbstractModel* model) { // just a copy of the code in poddecodertool.h if (mByteArrayView) { mByteArrayView->disconnect(this); } if (mByteArrayModel) { mByteArrayModel->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; ByteArrayDocument* document = mByteArrayView ? qobject_cast(mByteArrayView->baseModel()) : nullptr; mByteArrayModel = document ? document->content() : nullptr; if (mByteArrayModel && mByteArrayView) { mCursorIndex = mByteArrayView->cursorPosition(); connect(mByteArrayView, &ByteArrayView::cursorPositionChanged, this, &StructuresTool::onCursorPositionChange); connect(mByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, this, &StructuresTool::onContentsChange); } emit byteArrayModelChanged(mByteArrayModel); updateData(Okteta::ArrayChangeMetricsList()); } void StructuresTool::onCursorPositionChange(Okteta::Address pos) { if (mCursorIndex != pos) { mCursorIndex = pos; updateData(Okteta::ArrayChangeMetricsList()); emit cursorIndexChanged(); } } void StructuresTool::setByteOrder(int order) { if (order == QSysInfo::LittleEndian) { setByteOrder(QSysInfo::LittleEndian); } else if (order == QSysInfo::BigEndian) { setByteOrder(QSysInfo::BigEndian); } else { qCWarning(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "invalid byte order set:" << order; } } void StructuresTool::onContentsChange(const Okteta::ArrayChangeMetricsList& list) { qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "contents changed"; for (int i = 0; i < list.size(); ++i) { const Okteta::ArrayChangeMetrics& acm = list.at(i); qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "change: t=" << acm.type() << "o=" << acm.offset() << "a2=" << acm.removeLength() << "a3=" << acm.insertLength(); } updateData(list); } bool StructuresTool::setData(const QVariant& value, int role, DataInformation* item, uint row) { Q_UNUSED(row) if (!mByteArrayModel) { return false; } if (role != Qt::EditRole) { return false; } Q_CHECK_PTR(item); TopLevelDataInformation* topLevel = item->topLevelDataInformation(); const Okteta::Address structureStart = startAddress(topLevel); mWritingData = true; bool ret = false; BitCount64 position = item->positionInFile(structureStart); const quint64 remainingBits = qMax(mByteArrayModel->size() * 8 - qint64(position), qint64(0)); quint8 bitOffs = position % 8; ret = item->setData(value, mByteArrayModel, Okteta::Address(position / 8), remainingBits, bitOffs); mWritingData = false; // finished // XXX: this is inefficient, best would be to only update the changed value updateData(Okteta::ArrayChangeMetricsList()); // update once after writing return ret; } void StructuresTool::updateData(const Okteta::ArrayChangeMetricsList& list) { if (mWritingData) { qCWarning(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "currently writing data, won't update"; return; } if (!mByteArrayModel) { return; } for (int i = 0; i < mData.size(); i++) { const TopLevelDataInformation::Ptr& dat = mData.at(i); dat->read(mByteArrayModel, mCursorIndex, list, false); if (mCurrentItemDataChanged) { emit dataChanged(i, mData.at(i)->actualDataInformation()); } mCurrentItemDataChanged = false; } } // model interface: QVariant StructuresTool::headerData(int column, int role) const { if (role == Qt::DisplayRole) { switch (column) { case DataInformation::ColumnName: return i18nc("name of a data structure", "Name"); case DataInformation::ColumnType: return i18nc("type of a data structure", "Type"); case DataInformation::ColumnValue: return i18nc("value of a data structure (primitive type)", "Value"); default: return {}; } } return {}; } int StructuresTool::childCount() const { return mData.size(); } DataInformation* StructuresTool::childAt(int idx) const { if (idx >= mData.size() || idx < 0) { return nullptr; } // don't expose the topLevelDataInformation, since this may cause crashes return mData.at(idx)->actualDataInformation(); } void StructuresTool::addChildItem(TopLevelDataInformation* child) { Q_CHECK_PTR(child); child->setParent(this); if (child->isValid()) { child->setIndex(mData.size()); connect(child, &TopLevelDataInformation::dataChanged, this, &StructuresTool::onChildItemDataChanged); connect(child, &TopLevelDataInformation::childrenAboutToBeInserted, this, &StructuresTool::childrenAboutToBeInserted); connect(child, &TopLevelDataInformation::childrenInserted, this, &StructuresTool::childrenInserted); connect(child, &TopLevelDataInformation::childrenAboutToBeRemoved, this, &StructuresTool::childrenAboutToBeRemoved); connect(child, &TopLevelDataInformation::childrenRemoved, this, &StructuresTool::childrenRemoved); connect(this, &StructuresTool::byteArrayModelChanged, child, &TopLevelDataInformation::newModelActivated); mData.append(QSharedPointer(child)); // ensure that locking gets set up properly if (mByteArrayModel) { child->newModelActivated(mByteArrayModel); } } else { child->setIndex(mInvalidData.size()); mInvalidData.append(QSharedPointer(child)); } } void StructuresTool::setSelectedStructuresInView() { mData.clear(); mInvalidData.clear(); emit dataCleared(); QRegExp regex(QStringLiteral("'(.+)':'(.+)'")); QStringList loadedStructs = StructureViewPreferences::loadedStructures(); qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "loadedStructs " << loadedStructs; for (int i = 0; i < loadedStructs.size(); ++i) { const QString& s = loadedStructs.at(i); int pos = regex.indexIn(s); if (pos > -1) { QString pluginName = regex.cap(1); QString name = regex.cap(2); // qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "pluginName=" << path << " structureName=" << name; StructureDefinitionFile* def = mManager->definition(pluginName); if (!def) { continue; } if (!def->isValid()) { continue; } // should be valid now if (name == QLatin1String("*")) { // add all of them const QVector structs = def->structures(); for (auto* structure : structs) { addChildItem(structure); } } else { TopLevelDataInformation* data = def->structure(name); if (data) { addChildItem(data); } else { qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "Could not find structure with name" << name << "in" << pluginName; } } } } for (int i = 0; i < mData.count(); ++i) { emit dataChanged(i, mData.at(i)->actualDataInformation()); } updateData(Okteta::ArrayChangeMetricsList()); } Okteta::Address StructuresTool::startAddress(const TopLevelDataInformation* data) const { if (data->isLockedFor(mByteArrayModel)) { return Okteta::Address(data->lockPositionFor(mByteArrayModel)); } return mCursorIndex; } void StructuresTool::mark(const QModelIndex& idx) { if (!mByteArrayModel || !mByteArrayView || !idx.isValid()) { return; } const auto* data = static_cast(idx.internalPointer()); if (!data) { return; } Q_CHECK_PTR(data->topLevelDataInformation()); const Okteta::Address baseAddress = startAddress(data->topLevelDataInformation()); // FIXME support marking of partial bytes int length = data->size() / 8; const int maxLen = mByteArrayModel->size() - baseAddress; length = qMin(length, maxLen); const Okteta::Address startOffset = Okteta::Address(data->positionInFile(baseAddress) / 8); const Okteta::AddressRange markingRange = Okteta::AddressRange::fromWidth(startOffset, length); mByteArrayView->setMarking(markingRange, true); } void StructuresTool::unmark(/*const QModelIndex& idx*/) { if (mByteArrayView) { mByteArrayView->setMarking(Okteta::AddressRange()); } } void StructuresTool::validateAllStructures() { if (!mByteArrayModel) { return; // no point validating } const int size = mData.size(); for (int i = 0; i < size; ++i) { mData.at(i)->validate(); } } bool StructuresTool::isFileLoaded() const { return (mByteArrayModel != nullptr); } void StructuresTool::lockStructure(const QModelIndex& idx) { if (!mByteArrayModel) { // no point without ByteArrayModel return; } if (!idx.isValid() || !idx.internalPointer()) { return; } auto* data = static_cast(idx.internalPointer()); TopLevelDataInformation* top = data->topLevelDataInformation(); Q_ASSERT(top); if (top) { top->lockPositionToOffset(mCursorIndex, mByteArrayModel); } } void StructuresTool::unlockStructure(const QModelIndex& idx) { if (!mByteArrayModel) { // no point without ByteArrayModel return; } if (!idx.isValid() || !idx.internalPointer()) { return; } auto* data = static_cast(idx.internalPointer()); TopLevelDataInformation* top = data->topLevelDataInformation(); Q_CHECK_PTR(top); unmark(); top->unlockPosition(mByteArrayModel); // now read from the current position: top->read(mByteArrayModel, mCursorIndex, Okteta::ArrayChangeMetricsList(), true); mark(idx); // we have to change the marked range, otherwise it stays at the previous locked offset } bool StructuresTool::isStructureLocked(const QModelIndex& idx) const { if (!mByteArrayModel) { // no point without ByteArrayModel return false; } if (!idx.isValid() || !idx.internalPointer()) { return false; } auto* data = static_cast(idx.internalPointer()); TopLevelDataInformation* top = data->topLevelDataInformation(); Q_ASSERT(top); if (top) { return top->isLockedFor(mByteArrayModel); } return false; } bool StructuresTool::canStructureBeLocked(const QModelIndex& idx) const { // we need a valid model and a valid index return mByteArrayModel && idx.isValid() && idx.internalPointer(); } void StructuresTool::onChildItemDataChanged() { mCurrentItemDataChanged = true; } Okteta::AbstractByteArrayModel* StructuresTool::byteArrayModel() const { return mByteArrayModel; } StructuresManager* StructuresTool::manager() const { return mManager.data(); } QSysInfo::Endian StructuresTool::byteOrder() const { return mByteOrder; } TopLevelDataInformation::List StructuresTool::allData() const { TopLevelDataInformation::List ret; ret << mData << mInvalidData; return ret; } } diff --git a/kasten/controllers/view/structures/structurestoolviewfactory.cpp b/kasten/controllers/view/structures/structurestoolviewfactory.cpp index 75529ee7..df9b8b87 100644 --- a/kasten/controllers/view/structures/structurestoolviewfactory.cpp +++ b/kasten/controllers/view/structures/structurestoolviewfactory.cpp @@ -1,59 +1,59 @@ /* * This file is part of the Okteta Kasten Framework, made within the KDE community. * * Copyright 2010 Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "structurestoolviewfactory.hpp" // lib #include "structurestoolview.hpp" #include "structurestool.hpp" -// KF5 +// KF #include namespace Kasten { StructuresToolViewFactory::StructuresToolViewFactory() = default; StructuresToolViewFactory::~StructuresToolViewFactory() = default; QString StructuresToolViewFactory::iconName() const { return QStringLiteral("okteta"); } QString StructuresToolViewFactory::title() const { return i18nc("@title:window", "Structures"); } QString StructuresToolViewFactory::id() const { return QStringLiteral("org.kde.okteta.StructuresToolView"); } SidePosition StructuresToolViewFactory::defaultPosition() const { return RightSidePosition; } AbstractToolView* StructuresToolViewFactory::create(AbstractTool* tool) const { return new StructuresToolView(qobject_cast (tool)); } } diff --git a/kasten/controllers/view/structures/structureview.cpp b/kasten/controllers/view/structures/structureview.cpp index 261fbb27..70069eab 100644 --- a/kasten/controllers/view/structures/structureview.cpp +++ b/kasten/controllers/view/structures/structureview.cpp @@ -1,308 +1,308 @@ /* * This file is part of the Okteta Kasten Framework, made within the KDE community. * * Copyright 2009, 2010, 2012 Alex Richardson * Copyright 2009 Friedrich W. H. Kossebau * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3, or any * later version accepted by the membership of KDE e.V. (or its * successor approved by the membership of KDE e.V.), which shall * act as a proxy defined in Section 6 of version 3 of the license. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see . */ #include "structureview.hpp" // controller #include "structuretreemodel.hpp" #include "structurestool.hpp" #include "structuresmanager.hpp" #include "structureviewitemdelegate.hpp" #include "structlogging.hpp" // settings #include "structureviewpreferences.h" #include "settings/structureviewsettingswidget.hpp" #include "settings/structuresmanagerview.hpp" #include "settings/structureaddremovewidget.hpp" #include "script/scriptutils.hpp" #include "script/scriptloggerview.hpp" // #include "modeltest.hpp" -// KF5 +// KF #include #include #include // Qt #include #include #include #include #include #include #include #include namespace Kasten { StructureView::StructureView(StructuresTool* tool, QWidget* parent) : QWidget(parent) , mTool(tool) , mDelegate(new StructureViewItemDelegate(this)) , mStructTreeViewFocusChild(nullptr) { QBoxLayout* baseLayout = new QVBoxLayout(this); setLayout(baseLayout); baseLayout->setContentsMargins(0, 0, 0, 0); // table mStructureTreeModel = new StructureTreeModel(mTool, this); // mModeltest = new ModelTest(mStructureTreeModel, this); mStructTreeView = new QTreeView(this); mStructTreeView->setObjectName(QStringLiteral("StructTree")); mStructTreeView->setRootIsDecorated(true); mStructTreeView->setAlternatingRowColors(true); mStructTreeView->setItemsExpandable(true); mStructTreeView->setUniformRowHeights(true); mStructTreeView->setAllColumnsShowFocus(true); mStructTreeView->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed); mStructTreeView->setItemDelegate(mDelegate); mStructTreeView->setDragEnabled(false); mStructTreeView->setSortingEnabled(false); mStructTreeView->setModel(mStructureTreeModel); mStructTreeView->setHeaderHidden(false); mStructTreeView->setSortingEnabled(false); mStructTreeView->installEventFilter(this); QHeaderView* header = mStructTreeView->header(); header->setSectionResizeMode(QHeaderView::Interactive); baseLayout->addWidget(mStructTreeView, 10); // settings QBoxLayout* settingsLayout = new QHBoxLayout(); settingsLayout->setContentsMargins(0, 0, 0, 0); baseLayout->addLayout(settingsLayout); QIcon validateIcon = QIcon::fromTheme(QStringLiteral("document-sign")); mValidateButton = new QPushButton(validateIcon, i18nc("@action:button", "Validate"), this); const QString validationToolTip = i18nc("@info:tooltip", "Validate all structures."); mValidateButton->setToolTip(validationToolTip); mValidateButton->setEnabled(false); // no point validating without file open connect(mValidateButton, &QPushButton::clicked, mTool, &StructuresTool::validateAllStructures); connect(mTool, &StructuresTool::byteArrayModelChanged, this, &StructureView::onByteArrayModelChanged); // TODO also disable the button if the structure has no validatable members settingsLayout->addWidget(mValidateButton); mLockStructureButton = new QPushButton(this); mLockStructureButton->setCheckable(true); setLockButtonState(false); mLockStructureButton->setEnabled(false); // won't work at beginning connect(mLockStructureButton, &QPushButton::toggled, this, &StructureView::lockButtonToggled); settingsLayout->addWidget(mLockStructureButton); settingsLayout->addStretch(); // stretch before the settings button QIcon console = QIcon::fromTheme(QStringLiteral("utilities-terminal")); mScriptConsoleButton = new QPushButton(console, i18nc("@action:button", "Script console"), this); mScriptConsoleButton->setToolTip(i18nc("@info:tooltip", "Open script console.")); connect(mScriptConsoleButton, &QPushButton::pressed, this, &StructureView::openScriptConsole); settingsLayout->addWidget(mScriptConsoleButton); QIcon settings = QIcon::fromTheme(QStringLiteral("configure")); mSettingsButton = new QPushButton(settings, i18nc("@action:button", "Settings"), this); const QString settingsTooltip = i18nc("@info:tooltip", "Open settings."); mSettingsButton->setToolTip(settingsTooltip); connect(mSettingsButton, &QPushButton::pressed, this, &StructureView::openSettingsDlg); settingsLayout->addWidget(mSettingsButton); connect(mStructTreeView->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &StructureView::onCurrentRowChanged); connect(mTool, &StructuresTool::cursorIndexChanged, this, &StructureView::onCursorIndexChange); } StructureView::~StructureView() = default; StructuresTool* StructureView::tool() const { return mTool; } void StructureView::onCursorIndexChange() { QModelIndex idx = mStructTreeView->currentIndex(); if (idx.isValid()) { mTool->mark(idx); } } void StructureView::openSettingsDlg() { // An instance of your dialog could be already created and could be cached, // in which case you want to display the cached dialog instead of creating // another one if (KConfigDialog::showDialog(QStringLiteral("Structures Tool Settings"))) { return; } // KConfigDialog didn't find an instance of this dialog, so lets create it : KConfigDialog* dialog = new KConfigDialog(this, QStringLiteral("Structures Tool Settings"), StructureViewPreferences::self()); auto* displaySettings = new StructureViewSettingsWidget(); KPageWidgetItem* displ = dialog->addPage(displaySettings, i18n("Value Display"), QStringLiteral("configure")); // cannot use StructuresManagerView directly as page even if the only element // because KConfigDialogManager only scans the children of the page for kcfg_ elements QWidget* structSelectionPage = new QWidget(); auto* hbox = new QHBoxLayout(); hbox->setContentsMargins(0, 0, 0, 0); structSelectionPage->setLayout(hbox); auto* structureSettings = new StructuresManagerView(mTool, this); structureSettings->setObjectName(QStringLiteral("kcfg_LoadedStructures")); hbox->addWidget(structureSettings); dialog->addPage(structSelectionPage, i18n("Structures management"), QStringLiteral("preferences-plugin")); // User edited the configuration - update your local copies of the configuration data connect(dialog, &KConfigDialog::settingsChanged, mTool, &StructuresTool::setSelectedStructuresInView); // TODO: kconfig_compiler signals work now, use those signals and not the generic KConfigDialog::settingsChanged dialog->setCurrentPage(displ); dialog->show(); } bool StructureView::eventFilter(QObject* object, QEvent* event) { if (object == mStructTreeView) { if (event->type() == QEvent::FocusIn) { const QModelIndex current = mStructTreeView->selectionModel()->currentIndex(); if (current.isValid()) { mTool->mark(current); } else { mTool->unmark(); } setLockButtonState(current); } else if (event->type() == QEvent::FocusOut) { QWidget* treeViewFocusWidget = mStructTreeView->focusWidget(); const bool subChildHasFocus = (treeViewFocusWidget != mStructTreeView); if (subChildHasFocus) { mStructTreeViewFocusChild = treeViewFocusWidget; mStructTreeViewFocusChild->installEventFilter(this); } else { mTool->unmark(); } } } else if (object == mStructTreeViewFocusChild) { // TODO: it is only assumed the edit widget will be removed if it loses the focus if (event->type() == QEvent::FocusOut) { if (!mStructTreeView->hasFocus()) { mTool->unmark(); } mStructTreeViewFocusChild->removeEventFilter(this); mStructTreeViewFocusChild = nullptr; } } return QWidget::eventFilter(object, event); } void StructureView::setLockButtonState(const QModelIndex& current) { // qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "setLockButtonState() for" << current; // we don't want the toggled signal here, only when the user clicks the button! QSignalBlocker block(mLockStructureButton); setLockButtonState(mTool->isStructureLocked(current)); mLockStructureButton->setEnabled(mTool->canStructureBeLocked(current)); } void StructureView::onCurrentRowChanged(const QModelIndex& current, const QModelIndex& previous) { Q_UNUSED(previous) if (current.isValid() && mTool->byteArrayModel()) { mTool->mark(current); setLockButtonState(current); } else { mTool->unmark(); } } void StructureView::lockButtonToggled() { // qCDebug(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "Lock button toggled"; setLockButtonState(mLockStructureButton->isChecked()); const QModelIndex current = mStructTreeView->selectionModel()->currentIndex(); if (!current.isValid()) { qCWarning(LOG_KASTEN_OKTETA_CONTROLLERS_STRUCTURES) << "it should not be possible to toggle this button when current index is invalid!"; return; } if (mLockStructureButton->isChecked()) { mTool->lockStructure(current); } else { mTool->unlockStructure(current); } } void StructureView::setLockButtonState(bool structureLocked) { if (structureLocked) { mLockStructureButton->setIcon(QIcon::fromTheme(QStringLiteral("object-locked"))); mLockStructureButton->setText(i18nc("@action:button" " unlock the starting offset of the current structure", "Unlock")); mLockStructureButton->setToolTip(i18nc("@info:tooltip", "Unlock selected structure, i.e. the starting offset is" " always set to the current cursor position.")); } else { mLockStructureButton->setIcon(QIcon::fromTheme(QStringLiteral("object-unlocked"))); mLockStructureButton->setText(i18nc("@action:button" " unlock the starting offset of the current structure", "Lock")); mLockStructureButton->setToolTip(i18nc("@info:tooltip", "Lock selected structure to current offset.")); } mLockStructureButton->setChecked(structureLocked); } void StructureView::openScriptConsole() { QDialog* dialog = new QDialog(this); dialog->setWindowTitle(i18nc("@title:window", "Structures Script Console")); auto* layout = new QVBoxLayout; auto* dialogButtonBox = new QDialogButtonBox; QPushButton* closeButton = dialogButtonBox->addButton(QDialogButtonBox::Close); connect(closeButton, &QPushButton::clicked, dialog, &QDialog::accept); layout->addWidget(new ScriptLoggerView(mTool->allData())); layout->addWidget(dialogButtonBox); dialog->setLayout(layout); dialog->show(); } void StructureView::onByteArrayModelChanged(Okteta::AbstractByteArrayModel* model) { const bool validModel = (model != nullptr); QModelIndex current = mStructTreeView->currentIndex(); mLockStructureButton->setEnabled(mTool->canStructureBeLocked(current)); setLockButtonState(mTool->isStructureLocked(current)); mValidateButton->setEnabled(validModel); } } diff --git a/kasten/controllers/view/viewconfig/bytespergroupdialog.cpp b/kasten/controllers/view/viewconfig/bytespergroupdialog.cpp index 34a68fbd..40afd5f7 100644 --- a/kasten/controllers/view/viewconfig/bytespergroupdialog.cpp +++ b/kasten/controllers/view/viewconfig/bytespergroupdialog.cpp @@ -1,75 +1,75 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010,2014 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytespergroupdialog.hpp" -// KF5 +// KF #include // Qt #include #include #include #include namespace Kasten { BytesPerGroupDialog::BytesPerGroupDialog(QWidget* parent) : QDialog(parent) { auto* pageLayout = new QFormLayout(); mGroupedBytesCountEdit = new QSpinBox(this); mGroupedBytesCountEdit->setRange(0, INT_MAX); const QString noGroupingText = i18nc("@label", "No grouping."); mGroupedBytesCountEdit->setSpecialValueText(noGroupingText); const QString groupedBytesCountLabel = i18nc("@label:spinbox number of bytes which are grouped", "Bytes per Group:"); pageLayout->addRow(groupedBytesCountLabel, mGroupedBytesCountEdit); auto* dialogButtonBox = new QDialogButtonBox; dialogButtonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(dialogButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); auto* layout = new QVBoxLayout; layout->addLayout(pageLayout); layout->addWidget(dialogButtonBox); setLayout(layout); const QString caption = i18nc("@title:window", "Bytes per Group"); setWindowTitle(caption); } BytesPerGroupDialog::~BytesPerGroupDialog() = default; int BytesPerGroupDialog::groupedBytesCount() const { return mGroupedBytesCountEdit->value(); } void BytesPerGroupDialog::setGroupedBytesCount(int groupedBytesCount) { mGroupedBytesCountEdit->setValue(groupedBytesCount); } } diff --git a/kasten/controllers/view/viewconfig/bytesperlinedialog.cpp b/kasten/controllers/view/viewconfig/bytesperlinedialog.cpp index a5cfe537..2ed4f2ed 100644 --- a/kasten/controllers/view/viewconfig/bytesperlinedialog.cpp +++ b/kasten/controllers/view/viewconfig/bytesperlinedialog.cpp @@ -1,72 +1,72 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010,2014 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytesperlinedialog.hpp" -// KF5 +// KF #include // Qt #include #include #include #include namespace Kasten { BytesPerLineDialog::BytesPerLineDialog(QWidget* parent) : QDialog(parent) { auto* pageLayout = new QFormLayout(); mBytesPerLineEdit = new QSpinBox(this); mBytesPerLineEdit->setRange(1, INT_MAX); const QString bytesPerLineLabel = i18nc("@label:spinbox number of bytes which are shown per line", "Bytes per Line:"); pageLayout->addRow(bytesPerLineLabel, mBytesPerLineEdit); auto* dialogButtonBox = new QDialogButtonBox; dialogButtonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); connect(dialogButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); connect(dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); auto* layout = new QVBoxLayout; layout->addLayout(pageLayout); layout->addWidget(dialogButtonBox); setLayout(layout); const QString caption = i18nc("@title:window", "Bytes per Line"); setWindowTitle(caption); } BytesPerLineDialog::~BytesPerLineDialog() = default; int BytesPerLineDialog::bytesPerLine() const { return mBytesPerLineEdit->value(); } void BytesPerLineDialog::setBytesPerLine(int bytesPerLine) { mBytesPerLineEdit->setValue(bytesPerLine); } } diff --git a/kasten/controllers/view/viewconfig/viewconfigcontroller.cpp b/kasten/controllers/view/viewconfig/viewconfigcontroller.cpp index 07c1bbcb..ce781ef3 100644 --- a/kasten/controllers/view/viewconfig/viewconfigcontroller.cpp +++ b/kasten/controllers/view/viewconfig/viewconfigcontroller.cpp @@ -1,278 +1,278 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2010,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewconfigcontroller.hpp" // lib #include "bytesperlinedialog.hpp" #include "bytespergroupdialog.hpp" // Okteta Kasten gui #include // Okteta core #include -// KF5 +// KF #include #include #include #include #include namespace Kasten { ViewConfigController::ViewConfigController(KXMLGUIClient* guiClient) { KActionCollection* actionCollection = guiClient->actionCollection(); // Offset coding mOffsetCodingAction = new KSelectAction(i18nc("@title:menu", "&Offset Coding"), this); mOffsetCodingAction->setObjectName(QStringLiteral("view_offsetcoding")); mOffsetCodingAction->setItems(QStringList { i18nc("@item:inmenu offset in the hexadecimal format", "&Hexadecimal"), i18nc("@item:inmenu offset in the decimal format", "&Decimal"), }); connect(mOffsetCodingAction, QOverload::of(&KSelectAction::triggered), this, &ViewConfigController::setOffsetCoding); // value valueCoding mCodingAction = new KSelectAction(i18nc("@title:menu", "&Value Coding"), this); mCodingAction->setObjectName(QStringLiteral("view_valuecoding")); mCodingAction->setItems(QStringList { i18nc("@item:inmenu encoding of the bytes as values in the hexadecimal format", "&Hexadecimal"), i18nc("@item:inmenu encoding of the bytes as values in the decimal format", "&Decimal"), i18nc("@item:inmenu encoding of the bytes as values in the octal format", "&Octal"), i18nc("@item:inmenu encoding of the bytes as values in the binary format", "&Binary"), }); connect(mCodingAction, QOverload::of(&KSelectAction::triggered), this, &ViewConfigController::setValueCoding); // char valueCoding mEncodingAction = new KSelectAction(i18nc("@title:menu", "&Char Coding"), this); mEncodingAction->setObjectName(QStringLiteral("view_charencoding")); mEncodingAction->setItems(Okteta::CharCodec::codecNames()); connect(mEncodingAction, QOverload::of(&KSelectAction::triggered), this, &ViewConfigController::setCharCoding); mShowsNonprintingAction = new KToggleAction(i18nc("@option:check", "Show &Non-printing Chars"), this); mShowsNonprintingAction->setObjectName(QStringLiteral("view_showsnonprinting")); connect(mShowsNonprintingAction, &KToggleAction::triggered, this, &ViewConfigController::setShowsNonprinting); // bytes per line mSetBytesPerLineAction = new QAction(i18nc("@action:inmenu", "Set Bytes per Line..."), this); mSetBytesPerLineAction->setObjectName(QStringLiteral("view_bytesperline")); connect(mSetBytesPerLineAction, &QAction::triggered, this, &ViewConfigController::setBytesPerLine); // byte groups size mSetBytesPerGroupAction = new QAction(i18nc("@action:inmenu", "Set Bytes per Group..."), this); mSetBytesPerGroupAction->setObjectName(QStringLiteral("view_bytespergroup")); connect(mSetBytesPerGroupAction, &QAction::triggered, this, &ViewConfigController::setBytesPerGroup); // resize style mResizeStyleAction = new KSelectAction(i18nc("@title:menu", "&Dynamic Layout"), this); mResizeStyleAction->setObjectName(QStringLiteral("resizestyle")); mResizeStyleAction->setItems(QStringList { i18nc("@item:inmenu The layout will not change on size changes.", "&Off"), i18nc("@item:inmenu The layout will adapt to the size, but only with complete groups of bytes.", "&Wrap Only Complete Byte Groups"), i18nc("@item:inmenu The layout will adapt to the size and fit in as much bytes per line as possible.", "&On"), }); connect(mResizeStyleAction, QOverload::of(&KSelectAction::triggered), this, &ViewConfigController::setLayoutStyle); mShowOffsetColumnAction = new KToggleAction(i18nc("@option:check", "Show &Line Offset"), this); mShowOffsetColumnAction->setObjectName(QStringLiteral("view_lineoffset")); actionCollection->setDefaultShortcut(mShowOffsetColumnAction, Qt::Key_F11); connect(mShowOffsetColumnAction, &KToggleAction::triggered, this, &ViewConfigController::toggleOffsetColumn); // show buffer columns mToggleColumnsAction = new KSelectAction(i18nc("@title:menu", "&Show Values or Chars"), this); mToggleColumnsAction->setObjectName(QStringLiteral("togglecolumns")); mToggleColumnsAction->setItems(QStringList { i18nc("@item:inmenu", "&Values"), i18nc("@item:inmenu", "&Chars"), i18nc("@item:inmenu", "Values && Chars"), }); connect(mToggleColumnsAction, QOverload::of(&KSelectAction::triggered), this, &ViewConfigController::toggleValueCharColumns); actionCollection->addActions({ mCodingAction, mEncodingAction, // mShowsNonprintingAction, TODOSHOWNONPRINTING hide from UI for now mSetBytesPerLineAction, mSetBytesPerGroupAction, mResizeStyleAction, mShowOffsetColumnAction, mOffsetCodingAction, mToggleColumnsAction, }); setTargetModel(nullptr); } void ViewConfigController::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; const bool hasView = (mByteArrayView != nullptr); if (hasView) { onOffsetColumnVisibleChanged(mByteArrayView->offsetColumnVisible()); onOffsetCodingChanged(mByteArrayView->offsetCoding()); onShowsNonprintingChanged(mByteArrayView->showsNonprinting()); onValueCodingChanged(mByteArrayView->valueCoding()); onCharCodecChanged(mByteArrayView->charCodingName()); onLayoutStyleChanged(mByteArrayView->layoutStyle()); onVisibleByteArrayCodingsChanged(mByteArrayView->visibleByteArrayCodings()); connect(mByteArrayView, &ByteArrayView::offsetColumnVisibleChanged, this, &ViewConfigController::onOffsetColumnVisibleChanged); connect(mByteArrayView, &ByteArrayView::offsetCodingChanged, this, &ViewConfigController::onOffsetCodingChanged); connect(mByteArrayView, &ByteArrayView::showsNonprintingChanged, this, &ViewConfigController::onShowsNonprintingChanged); connect(mByteArrayView, &ByteArrayView::valueCodingChanged, this, &ViewConfigController::onValueCodingChanged); connect(mByteArrayView, &ByteArrayView::charCodecChanged, this, &ViewConfigController::onCharCodecChanged); connect(mByteArrayView, &ByteArrayView::layoutStyleChanged, this, &ViewConfigController::onLayoutStyleChanged); connect(mByteArrayView, &ByteArrayView::visibleByteArrayCodingsChanged, this, &ViewConfigController::onVisibleByteArrayCodingsChanged); } mOffsetCodingAction->setEnabled(hasView); mCodingAction->setEnabled(hasView); mEncodingAction->setEnabled(hasView); mShowsNonprintingAction->setEnabled(hasView); mSetBytesPerLineAction->setEnabled(hasView); mSetBytesPerGroupAction->setEnabled(hasView); mResizeStyleAction->setEnabled(hasView); mShowOffsetColumnAction->setEnabled(hasView); mToggleColumnsAction->setEnabled(hasView); } void ViewConfigController::setValueCoding(int valueCoding) { mByteArrayView->setValueCoding(valueCoding); } void ViewConfigController::setShowsNonprinting(bool on) { mByteArrayView->setShowsNonprinting(on); } void ViewConfigController::toggleOffsetColumn(bool on) { mByteArrayView->toggleOffsetColumn(on); } void ViewConfigController::setOffsetCoding(int offsetCoding) { mByteArrayView->setOffsetCoding(offsetCoding); } void ViewConfigController::setBytesPerLine() { BytesPerLineDialog dialog; dialog.setBytesPerLine(mByteArrayView->noOfBytesPerLine()); if (dialog.exec() != 0) { mByteArrayView->setNoOfBytesPerLine(dialog.bytesPerLine()); // TODO: change should be signalled and the action listen to that mResizeStyleAction->setCurrentItem(mByteArrayView->layoutStyle()); } } void ViewConfigController::setBytesPerGroup() { BytesPerGroupDialog dialog; dialog.setGroupedBytesCount(mByteArrayView->noOfGroupedBytes()); if (dialog.exec() != 0) { mByteArrayView->setNoOfGroupedBytes(dialog.groupedBytesCount()); } } void ViewConfigController::setLayoutStyle(int layoutStyle) { mByteArrayView->setLayoutStyle(layoutStyle); } void ViewConfigController::setCharCoding(int charCoding) { mByteArrayView->setCharCoding(Okteta::CharCodec::codecNames()[charCoding]); } void ViewConfigController::toggleValueCharColumns(int visibleColumns) { mByteArrayView->setVisibleByteArrayCodings(visibleColumns + 1); } void ViewConfigController::onOffsetColumnVisibleChanged(bool offsetColumnVisible) { mShowOffsetColumnAction->setChecked(offsetColumnVisible); } void ViewConfigController::onOffsetCodingChanged(int offsetCoding) { mOffsetCodingAction->setCurrentItem(offsetCoding); } void ViewConfigController::onShowsNonprintingChanged(bool showsNonprinting) { mShowsNonprintingAction->setChecked(showsNonprinting); } void ViewConfigController::onValueCodingChanged(int valueCoding) { mCodingAction->setCurrentItem(valueCoding); } void ViewConfigController::onCharCodecChanged(const QString& charCodecName) { const int charCodingIndex = Okteta::CharCodec::codecNames().indexOf(charCodecName); mEncodingAction->setCurrentItem(charCodingIndex); } void ViewConfigController::onLayoutStyleChanged(int layoutStyle) { mResizeStyleAction->setCurrentItem(layoutStyle); } void ViewConfigController::onVisibleByteArrayCodingsChanged(int visibleByteArrayCodings) { mToggleColumnsAction->setCurrentItem(visibleByteArrayCodings - 1); } } diff --git a/kasten/controllers/view/viewcontextmenu/viewcontextmenucontroller.cpp b/kasten/controllers/view/viewcontextmenu/viewcontextmenucontroller.cpp index 2936e7fd..fa8363af 100644 --- a/kasten/controllers/view/viewcontextmenu/viewcontextmenucontroller.cpp +++ b/kasten/controllers/view/viewcontextmenu/viewcontextmenucontroller.cpp @@ -1,66 +1,66 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2019 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewcontextmenucontroller.hpp" // Okteta Kasten gui #include -// KF5 +// KF #include #include #include // Qt #include namespace Kasten { ViewContextMenuController::ViewContextMenuController(KXMLGUIClient* guiClient) : mGuiClient(guiClient) { setTargetModel(nullptr); } void ViewContextMenuController::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; if (mByteArrayView) { connect(mByteArrayView, &ByteArrayView::viewContextMenuRequested, this, &ViewContextMenuController::showContextMenu); } } void ViewContextMenuController::showContextMenu(const QPoint& pos) { QWidget* w = mGuiClient->factory()->container(QStringLiteral("viewContextMenu"), mGuiClient); auto* popup = static_cast(w); const auto popupPoint = mByteArrayView->widget()->mapToGlobal(pos); popup->popup(popupPoint); } } diff --git a/kasten/controllers/view/viewmode/viewmodecontroller.cpp b/kasten/controllers/view/viewmode/viewmodecontroller.cpp index 2d130901..fa77bccf 100644 --- a/kasten/controllers/view/viewmode/viewmodecontroller.cpp +++ b/kasten/controllers/view/viewmode/viewmodecontroller.cpp @@ -1,79 +1,79 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewmodecontroller.hpp" // Okteta Kasten gui #include -// KF5 +// KF #include #include #include #include namespace Kasten { ViewModeController::ViewModeController(KXMLGUIClient* guiClient) { // view style mViewModeAction = new KSelectAction(i18nc("@title:menu", "&View Mode"), this); mViewModeAction->setItems(QStringList { i18nc("@item:inmenu", "&Columns"), i18nc("@item:inmenu", "&Rows"), }); connect(mViewModeAction, QOverload::of(&KSelectAction::triggered), this, &ViewModeController::setViewMode); guiClient->actionCollection()->addAction(QStringLiteral("viewmode"), mViewModeAction); setTargetModel(nullptr); } void ViewModeController::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; const bool hasView = (mByteArrayView != nullptr); if (hasView) { onViewModusChanged((int)mByteArrayView->viewModus()); connect(mByteArrayView, &ByteArrayView::viewModusChanged, this, &ViewModeController::onViewModusChanged); } mViewModeAction->setEnabled(hasView); } void ViewModeController::setViewMode(int viewMode) { mByteArrayView->setViewModus(viewMode); } void ViewModeController::onViewModusChanged(int viewModus) { mViewModeAction->setCurrentItem(viewModus); } } diff --git a/kasten/controllers/view/viewprofiles/viewprofilecontroller.cpp b/kasten/controllers/view/viewprofiles/viewprofilecontroller.cpp index 749178c4..c665dfb6 100644 --- a/kasten/controllers/view/viewprofiles/viewprofilecontroller.cpp +++ b/kasten/controllers/view/viewprofiles/viewprofilecontroller.cpp @@ -1,236 +1,236 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewprofilecontroller.hpp" // controller #include "viewprofileeditdialog.hpp" // Okteta Gui Kasten #include #include #include -// KF5 +// KF #include #include #include #include #include // Qt #include namespace Kasten { ViewProfileController::ViewProfileController(ByteArrayViewProfileManager* viewProfileManager, QWidget* parentWidget, KXMLGUIClient* guiClient) : mGuiClient(guiClient) , mViewProfileManager(viewProfileManager) , mParentWidget(parentWidget) { mViewProfileActionMenu = new KActionMenu(i18nc("@title:menu submenu to select the view profile or change it", "View Profile"), this); mViewProfileActionMenu->setDelayed(false); mCreateNewAction = new QAction(QIcon::fromTheme(QStringLiteral("document-new")), i18nc("@action:inmenu create a new view profile", "Create New..."), this); connect(mCreateNewAction, &QAction::triggered, this, &ViewProfileController::onCreateNewActionTriggered); mSaveChangesAction = new QAction(QIcon::fromTheme(QStringLiteral("document-save")), i18nc("@action:inmenu save changed to the view profile to the base profile", "Save Changes"), this); connect(mSaveChangesAction, &QAction::triggered, this, &ViewProfileController::onSaveChangesActionTriggered); mResetChangesAction = new QAction(QIcon::fromTheme(QStringLiteral("document-revert")), i18nc("@action:inmenu reset settings back to those of the saved base profile", "Reset Changes"), this); connect(mResetChangesAction, &QAction::triggered, this, &ViewProfileController::onResetChangesActionTriggered); mViewProfileActionMenu->addAction(mCreateNewAction); mViewProfileActionMenu->addSeparator(); mViewProfileActionMenu->addAction(mSaveChangesAction); mViewProfileActionMenu->addAction(mResetChangesAction); mViewProfilesActionGroup = new QActionGroup(this); mViewProfilesActionGroup->setExclusive(true); connect(mViewProfilesActionGroup, &QActionGroup::triggered, this, &ViewProfileController::onViewProfileTriggered); guiClient->actionCollection()->addAction(QStringLiteral("view_profile"), mViewProfileActionMenu); connect(mViewProfileManager, &ByteArrayViewProfileManager::viewProfilesChanged, this, &ViewProfileController::onViewProfilesChanged); connect(mViewProfileManager, &ByteArrayViewProfileManager::viewProfilesRemoved, this, &ViewProfileController::onViewProfilesChanged); onViewProfilesChanged(); setTargetModel(nullptr); } void ViewProfileController::setTargetModel(AbstractModel* model) { if (mByteArrayViewProfileSynchronizer) { mByteArrayViewProfileSynchronizer->disconnect(this); } mByteArrayView = model ? model->findBaseModel() : nullptr; mByteArrayViewProfileSynchronizer = mByteArrayView ? mByteArrayView->synchronizer() : nullptr; const bool hasSynchronizer = (mByteArrayViewProfileSynchronizer != nullptr); if (hasSynchronizer) { onViewProfileChanged(mByteArrayViewProfileSynchronizer->viewProfileId()); connect(mByteArrayViewProfileSynchronizer, &ByteArrayViewProfileSynchronizer::viewProfileChanged, this, &ViewProfileController::onViewProfileChanged); onLocalSyncStateChanged(mByteArrayViewProfileSynchronizer->localSyncState()); connect(mByteArrayViewProfileSynchronizer, &ByteArrayViewProfileSynchronizer::localSyncStateChanged, this, &ViewProfileController::onLocalSyncStateChanged); } else { mSaveChangesAction->setEnabled(false); mResetChangesAction->setEnabled(false); } mCreateNewAction->setEnabled(hasSynchronizer); mViewProfileActionMenu->setEnabled(hasSynchronizer); } void ViewProfileController::onViewProfileChanged(const Kasten::ByteArrayViewProfile::Id& viewProfileId) { const QList actions = mViewProfilesActionGroup->actions(); for (QAction* action : actions) { if (action->data().toString() == viewProfileId) { action->setChecked(true); break; } } } void ViewProfileController::onViewProfilesChanged() { qDeleteAll(mViewProfilesActionGroup->actions()); const QVector viewProfiles = mViewProfileManager->viewProfiles(); const ByteArrayViewProfile::Id currentViewProfileId = mByteArrayViewProfileSynchronizer ? mByteArrayViewProfileSynchronizer->viewProfileId() : ByteArrayViewProfile::Id(); if (!viewProfiles.isEmpty()) { mViewProfileActionMenu->addSeparator(); } bool isCurrentViewProfileExisting = false; for (const ByteArrayViewProfile& viewProfile : viewProfiles) { const QString title = viewProfile.viewProfileTitle(); auto* action = new QAction(title, mViewProfilesActionGroup); action->setCheckable(true); const ByteArrayViewProfile::Id viewProfileId = viewProfile.id(); action->setData(viewProfileId); const bool isCurrentViewProfile = (viewProfileId == currentViewProfileId); action->setChecked(isCurrentViewProfile); if (isCurrentViewProfile) { isCurrentViewProfileExisting = true; } mViewProfilesActionGroup->addAction(action); mViewProfileActionMenu->addAction(action); } // reset id if no longer existing if (!isCurrentViewProfileExisting && mByteArrayViewProfileSynchronizer) { mByteArrayViewProfileSynchronizer->setViewProfileId(ByteArrayViewProfile::Id()); } } void ViewProfileController::onViewProfileTriggered(QAction* action) { mByteArrayViewProfileSynchronizer->setViewProfileId(action->data().toString()); } void ViewProfileController::onLocalSyncStateChanged(Kasten::LocalSyncState localSyncState) { const bool hasDifference = (localSyncState == LocalHasChanges); mSaveChangesAction->setEnabled(hasDifference); mResetChangesAction->setEnabled(hasDifference); } void ViewProfileController::onCreateNewActionTriggered() { auto* dialog = new ViewProfileEditDialog(mParentWidget); const QString dialogTitle = i18nc("@window:title", "New View Profile"); dialog->setWindowTitle(dialogTitle); ByteArrayViewProfile viewProfile; viewProfile.setId(QString()); // const QString modifiedTitle = i18n( "Modification of %1", newByteArrayViewProfile.viewProfileTitle() ); // viewProfile.setViewProfileTitle( modifiedTitle ); viewProfile.setOffsetColumnVisible(mByteArrayView->offsetColumnVisible()); viewProfile.setVisibleByteArrayCodings(mByteArrayView->visibleByteArrayCodings()); viewProfile.setViewModus(mByteArrayView->viewModus()); viewProfile.setLayoutStyle(mByteArrayView->layoutStyle()); viewProfile.setNoOfGroupedBytes(mByteArrayView->noOfGroupedBytes()); viewProfile.setNoOfBytesPerLine(mByteArrayView->noOfBytesPerLine()); viewProfile.setValueCoding(mByteArrayView->valueCoding()); viewProfile.setCharCoding(mByteArrayView->charCodingName()); viewProfile.setShowsNonprinting(mByteArrayView->showsNonprinting()); viewProfile.setUndefinedChar(mByteArrayView->undefinedChar()); viewProfile.setSubstituteChar(mByteArrayView->substituteChar()); dialog->setViewProfile(viewProfile); const int answer = dialog->exec(); if (answer == QDialog::Accepted) { QVector viewProfiles { dialog->viewProfile() }; mViewProfileManager->saveViewProfiles(viewProfiles); mByteArrayViewProfileSynchronizer->setViewProfileId(viewProfiles.at(0).id()); } delete dialog; } void ViewProfileController::onResetChangesActionTriggered() { mByteArrayViewProfileSynchronizer->syncFromRemote(); } void ViewProfileController::onSaveChangesActionTriggered() { mByteArrayViewProfileSynchronizer->syncToRemote(); } } diff --git a/kasten/controllers/view/viewprofiles/viewprofileedit.cpp b/kasten/controllers/view/viewprofiles/viewprofileedit.cpp index e95b9570..49a0b488 100644 --- a/kasten/controllers/view/viewprofiles/viewprofileedit.cpp +++ b/kasten/controllers/view/viewprofiles/viewprofileedit.cpp @@ -1,251 +1,251 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewprofileedit.hpp" // Okteta Gui Kasten #include // Okteta core #include -// KF5 +// KF #include #include // Qt #include #include #include #include #include #include namespace Kasten { static constexpr int listIndexFromByteArrayCodingsFlags(int byteArrayCodingsFlags) { return byteArrayCodingsFlags - 1; } static constexpr int byteArrayCodingsFlagsFromListIndex(int listIndex) { return listIndex + 1; } ViewProfileEdit::ViewProfileEdit(QWidget* parent) : QWidget(parent) { auto* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); // titel auto* titleFormLayout = new QFormLayout; // char for non-printable bytes mTitleEdit = new QLineEdit(this); mTitleEdit->setClearButtonEnabled(true); connect(mTitleEdit, &QLineEdit::textChanged, this, &ViewProfileEdit::profileTitleChanged); titleFormLayout->addRow(i18n("Title:"), mTitleEdit); // display settings auto* displayBox = new QGroupBox(this); displayBox->setTitle(i18n("Display")); auto* displayBoxFormLayout = new QFormLayout(displayBox); // line offset shown mLineOffsetShownCheckBox = new QCheckBox(displayBox); displayBoxFormLayout->addRow(i18n("Show Line Offset:"), mLineOffsetShownCheckBox); // offset coding mOffsetCodingComboBox = new KComboBox(displayBox); const QStringList offsetCodingList { i18nc("@item:inmenu offset in the hexadecimal format", "Hexadecimal"), i18nc("@item:inmenu offset in the decimal format", "Decimal"), }; mOffsetCodingComboBox->addItems(offsetCodingList); displayBoxFormLayout->addRow(i18n("Offset Coding:"), mOffsetCodingComboBox); // values or char shown mValuesCharsShownComboBox = new KComboBox(displayBox); const QStringList valuesCharsList { i18nc("@item:", "Values"), i18nc("@item:", "Chars"), i18nc("@item:", "Values & Chars"), }; mValuesCharsShownComboBox->addItems(valuesCharsList); displayBoxFormLayout->addRow(i18n("Show Values or Chars:"), mValuesCharsShownComboBox); // display mode const QString displayModeLabel = i18nc("@label:listbox ", "Show with Rows or Columns:"); mDisplayModeComboBox = new KComboBox(displayBox); const QStringList displayModeList { i18nc("@item:", "Columns"), i18nc("@item:", "Rows"), }; mDisplayModeComboBox->addItems(displayModeList); displayBoxFormLayout->addRow(displayModeLabel, mDisplayModeComboBox); // layout settings auto* layoutBox = new QGroupBox(this); layoutBox->setTitle(i18n("Layout")); auto* layoutBoxFormLayout = new QFormLayout(layoutBox); // line break mLineBreakComboBox = new KComboBox(layoutBox); const QStringList lineBreakList { i18nc("@item:inmenu The layout will not change on size changes.", "Off"), i18nc("@item:inmenu The layout will adapt to the size, but only with complete groups of bytes.", "Wrap Only Complete Byte Groups"), i18nc("@item:inmenu The layout will adapt to the size and fit in as much bytes per line as possible.", "On"), }; mLineBreakComboBox->addItems(lineBreakList); connect(mLineBreakComboBox, QOverload::of(&KComboBox::currentIndexChanged), this, &ViewProfileEdit::onLineBreakIndexChanged); layoutBoxFormLayout->addRow(i18n("Break lines:"), mLineBreakComboBox); // bytes per group mGroupedBytesCountEdit = new QSpinBox(this); mGroupedBytesCountEdit->setRange(0, INT_MAX); const QString noGroupingText = i18nc("@label", "No grouping."); mGroupedBytesCountEdit->setSpecialValueText(noGroupingText); const QString groupedBytesCountLabel = i18nc("@label:spinbox number of bytes which are grouped", "Bytes per Group:"); layoutBoxFormLayout->addRow(groupedBytesCountLabel, mGroupedBytesCountEdit); // bytes per group mBytesPerLineEdit = new QSpinBox(this); mBytesPerLineEdit->setRange(1, INT_MAX); const QString bytesPerLineLabel = i18nc("@label:spinbox number of bytes which are shown per line", "Bytes per Line:"); layoutBoxFormLayout->addRow(bytesPerLineLabel, mBytesPerLineEdit); // value settings auto* valuesBox = new QGroupBox(this); valuesBox->setTitle(i18n("Values")); auto* valuesBoxFormLayout = new QFormLayout(valuesBox); // coding mValueCodingComboBox = new KComboBox(valuesBox); const QStringList valueCodingList { i18nc("@item:inmenu encoding of the bytes as values in the hexadecimal format", "Hexadecimal"), i18nc("@item:inmenu encoding of the bytes as values in the decimal format", "Decimal"), i18nc("@item:inmenu encoding of the bytes as values in the octal format", "Octal"), i18nc("@item:inmenu encoding of the bytes as values in the binary format", "Binary"), }; mValueCodingComboBox->addItems(valueCodingList); valuesBoxFormLayout->addRow(i18n("Coding:"), mValueCodingComboBox); // char settings auto* charsBox = new QGroupBox(this); charsBox->setTitle(i18n("Chars")); auto* charsBoxFormLayout = new QFormLayout(charsBox); // coding mCharCodingComboBox = new KComboBox(charsBox); mCharCodingComboBox->addItems(Okteta::CharCodec::codecNames()); charsBoxFormLayout->addRow(i18n("Coding:"), mCharCodingComboBox); // line offset shown mNonPrintableShownCheckBox = new QCheckBox(charsBox); // TODOSHOWNONPRINTING hide from UI for now mNonPrintableShownCheckBox->hide(); // charsBoxFormLayout->addRow(i18n("Show Non-printable:"), mNonPrintableShownCheckBox); // char for non-printable bytes mNonPrintableCharEdit = new QLineEdit(charsBox); // TODO: use a validator to ensure always one char mNonPrintableCharEdit->setClearButtonEnabled(true); mNonPrintableCharEdit->setMaxLength(1); charsBoxFormLayout->addRow(i18n("Char for non-printable bytes:"), mNonPrintableCharEdit); // char for undefined bytes mUndefinedCharEdit = new QLineEdit(charsBox); // TODO: use a validator to ensure always one char mUndefinedCharEdit->setClearButtonEnabled(true); mUndefinedCharEdit->setMaxLength(1); charsBoxFormLayout->addRow(i18n("Char for undefined bytes:"), mUndefinedCharEdit); layout->addLayout(titleFormLayout); layout->addWidget(displayBox); layout->addWidget(layoutBox); layout->addWidget(valuesBox); layout->addWidget(charsBox); mTitleEdit->setFocus(); } ViewProfileEdit::~ViewProfileEdit() = default; ByteArrayViewProfile ViewProfileEdit::viewProfile() const { ByteArrayViewProfile viewProfile; viewProfile.setViewProfileTitle(mTitleEdit->text()); viewProfile.setOffsetColumnVisible(mLineOffsetShownCheckBox->isChecked()); viewProfile.setOffsetCoding(mOffsetCodingComboBox->currentIndex()); const int visibleByteArrayCodings = byteArrayCodingsFlagsFromListIndex(mValuesCharsShownComboBox->currentIndex()); viewProfile.setVisibleByteArrayCodings(visibleByteArrayCodings); viewProfile.setViewModus(mDisplayModeComboBox->currentIndex()); viewProfile.setLayoutStyle(mLineBreakComboBox->currentIndex()); viewProfile.setNoOfGroupedBytes(mGroupedBytesCountEdit->value()); viewProfile.setNoOfBytesPerLine(mBytesPerLineEdit->value()); viewProfile.setValueCoding(mValueCodingComboBox->currentIndex()); viewProfile.setCharCoding(mCharCodingComboBox->currentText()); viewProfile.setShowsNonprinting(mNonPrintableShownCheckBox->isChecked()); viewProfile.setSubstituteChar(mNonPrintableCharEdit->text().at(0)); // TODO: need make sure is one char viewProfile.setUndefinedChar(mUndefinedCharEdit->text().at(0)); // TODO: need make sure is one char return viewProfile; } void ViewProfileEdit::setViewProfile(const ByteArrayViewProfile& viewProfile) { mTitleEdit->setText(viewProfile.viewProfileTitle()); mLineOffsetShownCheckBox->setChecked(viewProfile.offsetColumnVisible()); mOffsetCodingComboBox->setCurrentIndex(viewProfile.offsetCoding()); const int valuesCharsShownListIndex = listIndexFromByteArrayCodingsFlags(viewProfile.visibleByteArrayCodings()); mValuesCharsShownComboBox->setCurrentIndex(valuesCharsShownListIndex); mDisplayModeComboBox->setCurrentIndex(viewProfile.viewModus()); mLineBreakComboBox->setCurrentIndex(viewProfile.layoutStyle()); mGroupedBytesCountEdit->setValue(viewProfile.noOfGroupedBytes()); mBytesPerLineEdit->setValue(viewProfile.noOfBytesPerLine()); mValueCodingComboBox->setCurrentIndex(viewProfile.valueCoding()); mCharCodingComboBox->setCurrentItem(viewProfile.charCodingName()); mNonPrintableShownCheckBox->setChecked(viewProfile.showsNonprinting()); mNonPrintableCharEdit->setText(viewProfile.substituteChar()); mUndefinedCharEdit->setText(viewProfile.undefinedChar()); } void ViewProfileEdit::onLineBreakIndexChanged(int lineBreakIndex) { const bool isLineBreakByByte = (lineBreakIndex == 0); mBytesPerLineEdit->setEnabled(isLineBreakByByte); } } diff --git a/kasten/controllers/view/viewprofiles/viewprofileedit.hpp b/kasten/controllers/view/viewprofiles/viewprofileedit.hpp index 9896193b..1f38b48a 100644 --- a/kasten/controllers/view/viewprofiles/viewprofileedit.hpp +++ b/kasten/controllers/view/viewprofiles/viewprofileedit.hpp @@ -1,86 +1,86 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_VIEWPROFILEEDIT_HPP #define KASTEN_VIEWPROFILEEDIT_HPP // Qt #include -// KF5 +// KF class KComboBox; // Qt class QCheckBox; class QSpinBox; class QLineEdit; namespace Kasten { class ByteArrayViewProfile; class ViewProfileEdit : public QWidget { Q_OBJECT public: explicit ViewProfileEdit(QWidget* parent = nullptr); ~ViewProfileEdit() override; public: ByteArrayViewProfile viewProfile() const; public: void setViewProfile(const ByteArrayViewProfile& viewProfile); Q_SIGNALS: void profileTitleChanged(const QString& title); private Q_SLOTS: void onLineBreakIndexChanged(int lineBreakIndex); private: // title QLineEdit* mTitleEdit; private: // display QCheckBox* mLineOffsetShownCheckBox; KComboBox* mOffsetCodingComboBox; KComboBox* mValuesCharsShownComboBox; KComboBox* mDisplayModeComboBox; private: // layout KComboBox* mLineBreakComboBox; QSpinBox* mGroupedBytesCountEdit; QSpinBox* mBytesPerLineEdit; private: // value KComboBox* mValueCodingComboBox; private: // char KComboBox* mCharCodingComboBox; QCheckBox* mNonPrintableShownCheckBox; QLineEdit* mUndefinedCharEdit; QLineEdit* mNonPrintableCharEdit; }; } #endif diff --git a/kasten/controllers/view/viewprofiles/viewprofilesmanagecontroller.cpp b/kasten/controllers/view/viewprofiles/viewprofilesmanagecontroller.cpp index b1484783..3676475e 100644 --- a/kasten/controllers/view/viewprofiles/viewprofilesmanagecontroller.cpp +++ b/kasten/controllers/view/viewprofiles/viewprofilesmanagecontroller.cpp @@ -1,65 +1,65 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewprofilesmanagecontroller.hpp" // Okteta Gui Kasten #include // controller #include "viewprofilesmanagedialog.hpp" -// KF5 +// KF #include #include #include // Qt #include namespace Kasten { ViewProfilesManageController::ViewProfilesManageController(KXMLGUIClient* guiClient, ByteArrayViewProfileManager* viewProfileManager, QWidget* parentWidget) : mParentWidget(parentWidget) , mViewProfileManager(viewProfileManager) { mManageAction = new QAction(QIcon::fromTheme(QStringLiteral("configure")), i18nc("@action:inmenu", "Manage View Profiles..."), this); connect(mManageAction, &QAction::triggered, this, &ViewProfilesManageController::manageProfiles); guiClient->actionCollection()->addAction(QStringLiteral("settings_viewprofiles_manage"), mManageAction); } void ViewProfilesManageController::setTargetModel(AbstractModel* model) { Q_UNUSED(model); } void ViewProfilesManageController::manageProfiles() { auto* dialog = new ViewProfilesManageDialog(mViewProfileManager, mParentWidget); dialog->exec(); delete dialog; } } diff --git a/kasten/controllers/view/viewprofiles/viewprofilesmanagedialog.cpp b/kasten/controllers/view/viewprofiles/viewprofilesmanagedialog.cpp index d6790e88..a1c1e5a7 100644 --- a/kasten/controllers/view/viewprofiles/viewprofilesmanagedialog.cpp +++ b/kasten/controllers/view/viewprofiles/viewprofilesmanagedialog.cpp @@ -1,329 +1,329 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010,2012-2013 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewprofilesmanagedialog.hpp" // this #include "viewprofileeditdialog.hpp" #include "viewprofiletablemodel.hpp" // Okteta Gui Kasten #include #include -// KF5 +// KF #include #include // Qt #include #include #include #include #include namespace Kasten { ViewProfilesManageDialog::ViewProfilesManageDialog(ByteArrayViewProfileManager* viewProfileManager, QWidget* parent) : QDialog(parent) , mViewProfileManager(viewProfileManager) { setWindowTitle(i18nc("@title:window", "View Profiles")); auto* pageLayout = new QHBoxLayout; // profile list mViewProfileTableView = new QTreeView; mViewProfileTableModel = new ViewProfileTableModel(mViewProfileManager, this); mViewProfileTableView->setObjectName(QStringLiteral("ViewProfileTableView")); mViewProfileTableView->setHeaderHidden(true); mViewProfileTableView->setRootIsDecorated(false); mViewProfileTableView->setItemsExpandable(false); mViewProfileTableView->setUniformRowHeights(true); mViewProfileTableView->setAllColumnsShowFocus(true); mViewProfileTableView->setModel(mViewProfileTableModel); connect(mViewProfileTableView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ViewProfilesManageDialog::onViewProfileSelectionChanged); connect(mViewProfileTableModel, &ViewProfileTableModel::modelReset, this, &ViewProfilesManageDialog::onModelReset); // buttons auto* buttonLayout = new QVBoxLayout; auto* createButton = // copy from selected new QPushButton; KGuiItem::assign(createButton, KGuiItem(i18nc("@action:button", "&Create new..."), QStringLiteral("document-new"), i18nc("@info:tooltip", "Opens an editor for a new view profile."), xi18nc("@info:whatsthis", "If you press the Create new... button, " "an editor is opened where you can create and edit a new view profile. " "The values will be based on the ones of the view profile you selected " "in the list."))); connect(createButton, &QPushButton::clicked, this, &ViewProfilesManageDialog::onCreateNewButtonClicked); buttonLayout->addWidget(createButton); mEditButton = new QPushButton; KGuiItem::assign(mEditButton, KGuiItem(i18nc("@action:button", "&Edit..."), QStringLiteral("document-edit"), i18nc("@info:tooltip", "Opens an editor for the view profile."), xi18nc("@info:whatsthis", "If you press the Edit... button, " "an editor will be opened for the view profile you selected " "in the list."))); connect(mEditButton, &QPushButton::clicked, this, &ViewProfilesManageDialog::onEditButtonClicked); buttonLayout->addWidget(mEditButton); mSetDefaultButton = new QPushButton; KGuiItem::assign(mSetDefaultButton, KGuiItem(i18nc("@action:button", "&Set as Default"), QString(), i18nc("@info:tooltip", "Sets the selected view profile as default for all views."), xi18nc("@info:whatsthis", "If you press the Set as Default button, " "the view profile you selected in the list is set as default for all views."))); connect(mSetDefaultButton, &QPushButton::clicked, this, &ViewProfilesManageDialog::onSetDefaultButtonClicked); buttonLayout->addWidget(mSetDefaultButton); mDeleteButton = new QPushButton; KGuiItem::assign(mDeleteButton, KGuiItem(i18nc("@action:button", "&Delete"), QStringLiteral("edit-delete"), i18nc("@info:tooltip", "Deletes the selected view profile."), xi18nc("@info:whatsthis", "If you press the Delete button, " "the view profile you selected in the list is deleted."))); connect(mDeleteButton, &QPushButton::clicked, this, &ViewProfilesManageDialog::onDeleteButtonClicked); buttonLayout->addWidget(mDeleteButton); buttonLayout->addStretch(); pageLayout->addWidget(mViewProfileTableView); pageLayout->addLayout(buttonLayout); // dialog buttons auto* dialogButtonBox = new QDialogButtonBox; mCloseButton = dialogButtonBox->addButton(QDialogButtonBox::Close); connect(mCloseButton, &QAbstractButton::clicked, this, &QDialog::accept); // main layout auto* layout = new QVBoxLayout; layout->addLayout(pageLayout); layout->addWidget(dialogButtonBox); setLayout(layout); mCloseButton->setDefault(true); connect(mViewProfileManager, &ByteArrayViewProfileManager::viewProfilesLocked, this, &ViewProfilesManageDialog::onViewProfilesLocked); connect(mViewProfileManager, &ByteArrayViewProfileManager::viewProfilesLocked, this, &ViewProfilesManageDialog::onViewProfilesUnlocked); connect(mViewProfileManager, &ByteArrayViewProfileManager::defaultViewProfileChanged, this, &ViewProfilesManageDialog::onDefaultViewProfileChanged); // select first by default onModelReset(); } ViewProfilesManageDialog::~ViewProfilesManageDialog() = default; void ViewProfilesManageDialog::onViewProfileSelectionChanged() { const QItemSelectionModel* selectionModel = mViewProfileTableView->selectionModel(); const QModelIndexList selectedIndexes = selectionModel->selectedIndexes(); const bool hasSelection = (!selectedIndexes.isEmpty()); mCurrentViewProfileId = hasSelection ? mViewProfileTableModel->viewProfileId(selectedIndexes.at(0)) : ByteArrayViewProfile::Id(); const bool isEditable = hasSelection && !mViewProfileManager->isViewProfileLocked(mCurrentViewProfileId); mEditButton->setEnabled(isEditable); mDeleteButton->setEnabled(isEditable); mSetDefaultButton->setEnabled(isEditable && mCurrentViewProfileId != mViewProfileManager->defaultViewProfileId()); } void ViewProfilesManageDialog::onCreateNewButtonClicked() { auto* dialog = new ViewProfileEditDialog(this); { const bool isBasedOnExisting = (!mCurrentViewProfileId.isEmpty()); ByteArrayViewProfile newByteArrayViewProfile = isBasedOnExisting ? mViewProfileManager->viewProfile(mCurrentViewProfileId) : ByteArrayViewProfile(); if (isBasedOnExisting) { // reset id newByteArrayViewProfile.setId(QString()); // twist title const QString modifiedTitle = i18n("Modification of %1", newByteArrayViewProfile.viewProfileTitle()); newByteArrayViewProfile.setViewProfileTitle(modifiedTitle); } dialog->setViewProfile(newByteArrayViewProfile); const QString dialogTitle = i18nc("@window:title", "New View Profile"); dialog->setWindowTitle(dialogTitle); } const int answer = dialog->exec(); if (answer == QDialog::Accepted) { QVector viewProfiles { dialog->viewProfile() }; mViewProfileManager->saveViewProfiles(viewProfiles); } delete dialog; mCloseButton->setDefault(true); } void ViewProfilesManageDialog::onEditButtonClicked() { if (mCurrentViewProfileId.isEmpty()) { return; } ByteArrayViewProfileLock viewProfileLock = mViewProfileManager->createLock(mCurrentViewProfileId); if (!viewProfileLock.isLocked()) { return; } const ByteArrayViewProfile viewProfile = mViewProfileManager->viewProfile(mCurrentViewProfileId); auto* dialog = new ViewProfileEditDialog(this); dialog->setViewProfile(viewProfile); const QString dialogTitle = i18nc("@window:title", "\"%1\" View Profile", viewProfile.viewProfileTitle()); dialog->setWindowTitle(dialogTitle); const int answer = dialog->exec(); if (answer == QDialog::Accepted) { QVector viewProfiles { dialog->viewProfile() }; mViewProfileManager->saveViewProfiles(viewProfiles); } delete dialog; mCloseButton->setDefault(true); } void ViewProfilesManageDialog::onSetDefaultButtonClicked() { if (mCurrentViewProfileId.isEmpty()) { return; } mViewProfileManager->setDefaultViewProfile(mCurrentViewProfileId); mCloseButton->setDefault(true); } void ViewProfilesManageDialog::onDeleteButtonClicked() { if (mCurrentViewProfileId.isEmpty()) { return; } // TODO: ask user if she really wants to delete const QVector viewProfileIds { mCurrentViewProfileId }; mViewProfileManager->removeViewProfiles(viewProfileIds); mCloseButton->setDefault(true); } void ViewProfilesManageDialog::onModelReset() { int row = mViewProfileTableModel->row(mCurrentViewProfileId); // no longer exists? set current to first if there is one if ((row < 0) && (0 < mViewProfileManager->viewProfilesCount())) { row = 0; } const bool isViewProfileSelected = (0 <= row); if (isViewProfileSelected) { const QItemSelection selection = QItemSelection(mViewProfileTableModel->index(row, ViewProfileTableModel::CurrentColumnId), mViewProfileTableModel->index(row, ViewProfileTableModel::NameColumnId)); mViewProfileTableView->selectionModel()->select(selection, QItemSelectionModel::Select); } else { mCurrentViewProfileId.clear(); } // TODO: show a ghost profile with the built-in parameters if there is none mEditButton->setEnabled(isViewProfileSelected); mSetDefaultButton->setEnabled(isViewProfileSelected); mDeleteButton->setEnabled(isViewProfileSelected); } void ViewProfilesManageDialog::onViewProfilesLocked(const QVector& viewProfileIds) { // find if any locked profile is the currently selected, then disable all buttons if (viewProfileIds.contains(mCurrentViewProfileId)) { mEditButton->setEnabled(false); mDeleteButton->setEnabled(false); mSetDefaultButton->setEnabled(false); } } void ViewProfilesManageDialog::onViewProfilesUnlocked(const QVector& viewProfileIds) { // find if any locked profile is the currently selected, then enable all buttons if (viewProfileIds.contains(mCurrentViewProfileId)) { mEditButton->setEnabled(true); mDeleteButton->setEnabled(true); if (mCurrentViewProfileId != mViewProfileManager->defaultViewProfileId()) { mSetDefaultButton->setEnabled(true); } } } void ViewProfilesManageDialog::onDefaultViewProfileChanged(const ByteArrayViewProfile::Id& viewProfileId) { mSetDefaultButton->setEnabled((!mCurrentViewProfileId.isEmpty()) && (mCurrentViewProfileId != viewProfileId)); } } diff --git a/kasten/controllers/view/viewprofiles/viewprofiletablemodel.cpp b/kasten/controllers/view/viewprofiles/viewprofiletablemodel.cpp index a4fcc19a..7a843499 100644 --- a/kasten/controllers/view/viewprofiles/viewprofiletablemodel.cpp +++ b/kasten/controllers/view/viewprofiles/viewprofiletablemodel.cpp @@ -1,174 +1,174 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewprofiletablemodel.hpp" // Okteta Gui Kasten #include -// KF5 +// KF #include #include // Qt #include #include #include namespace Kasten { ViewProfileTableModel::ViewProfileTableModel(const ByteArrayViewProfileManager* viewProfileManager, QObject* parent) : QAbstractTableModel(parent) , mViewProfileManager(viewProfileManager) { connect(viewProfileManager, &ByteArrayViewProfileManager::viewProfilesChanged, this, &ViewProfileTableModel::onViewProfilesChanged); connect(viewProfileManager, &ByteArrayViewProfileManager::viewProfilesRemoved, this, &ViewProfileTableModel::onViewProfilesChanged); connect(viewProfileManager, &ByteArrayViewProfileManager::defaultViewProfileChanged, this, &ViewProfileTableModel::onDefaultIndexChanged); connect(viewProfileManager, &ByteArrayViewProfileManager::viewProfilesLocked, this, &ViewProfileTableModel::onViewProfilesChanged); connect(viewProfileManager, &ByteArrayViewProfileManager::viewProfilesUnlocked, this, &ViewProfileTableModel::onViewProfileLocksChanged); } ViewProfileTableModel::~ViewProfileTableModel() = default; int ViewProfileTableModel::rowCount(const QModelIndex& parent) const { return (!parent.isValid()) ? mViewProfileManager->viewProfilesCount() : 0; } int ViewProfileTableModel::columnCount(const QModelIndex& parent) const { return (!parent.isValid()) ? NoOfColumnIds : 0; } QVariant ViewProfileTableModel::data(const QModelIndex& index, int role) const { QVariant result; switch (role) { case Qt::DisplayRole: { const int viewProfileIndex = index.row(); const int tableColumn = index.column(); switch (tableColumn) { case NameColumnId: { result = mViewProfileManager->viewProfiles().at(viewProfileIndex).viewProfileTitle(); break; } default: ; } break; } case Qt::DecorationRole: { const int tableColumn = index.column(); if (tableColumn == CurrentColumnId) { const int viewProfileIndex = index.row(); const ByteArrayViewProfile::Id viewProfileId = mViewProfileManager->viewProfiles().at(viewProfileIndex).id(); if (mViewProfileManager->defaultViewProfileId() == viewProfileId) { result = QIcon::fromTheme(QStringLiteral("arrow-right")); } } break; } case Qt::ForegroundRole: { const int viewProfileIndex = index.row(); const ByteArrayViewProfile::Id viewProfileId = mViewProfileManager->viewProfiles().at(viewProfileIndex).id(); if (mViewProfileManager->isViewProfileLocked(viewProfileId)) { const QPalette& palette = QApplication::palette(); const KColorScheme colorScheme(palette.currentColorGroup(), KColorScheme::View); result = colorScheme.foreground(KColorScheme::InactiveText); } break; } } return result; } ByteArrayViewProfile::Id ViewProfileTableModel::viewProfileId(const QModelIndex& index) const { const int viewProfileIndex = index.row(); const bool isValidIndex = (0 <= viewProfileIndex) && (viewProfileIndex < mViewProfileManager->viewProfilesCount()); return isValidIndex ? mViewProfileManager->viewProfiles().at(viewProfileIndex).id() : ByteArrayViewProfile::Id(); } int ViewProfileTableModel::row(const ByteArrayViewProfile::Id& viewProfileId) const { int result = -1; const QVector viewProfiles = mViewProfileManager->viewProfiles(); const int viewProfilesCount = viewProfiles.count(); for (int i = 0; i < viewProfilesCount; ++i) { if (viewProfileId == viewProfiles.at(i).id()) { result = i; break; } } return result; } void ViewProfileTableModel::onDefaultIndexChanged() { // simply reset the whole column, does not happen often and not worth to cache the old default emit dataChanged(index(CurrentColumnId, 0), index(CurrentColumnId, mViewProfileManager->viewProfiles().count() - 1)); } void ViewProfileTableModel::onViewProfilesChanged() { beginResetModel(); endResetModel(); } void ViewProfileTableModel::onViewProfileLocksChanged(const QVector& viewProfileIds) { const QVector viewProfiles = mViewProfileManager->viewProfiles(); const int viewProfilesCount = viewProfiles.count(); for (int i = 0; i < viewProfilesCount; ++i) { const ByteArrayViewProfile::Id viewProfileId = viewProfiles.at(i).id(); if (viewProfileIds.contains(viewProfileId)) { emit dataChanged(index(CurrentColumnId, i), index(NameColumnId, i)); } } } } diff --git a/kasten/controllers/view/viewstatus/viewstatuscontroller.cpp b/kasten/controllers/view/viewstatus/viewstatuscontroller.cpp index a9e045f5..df52fcc4 100644 --- a/kasten/controllers/view/viewstatus/viewstatuscontroller.cpp +++ b/kasten/controllers/view/viewstatus/viewstatuscontroller.cpp @@ -1,263 +1,263 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewstatuscontroller.hpp" // Okteta Kasten gui #include // Kasten ui #include #include // Okteta core #include #include -// KF5 +// KF #include #include #include // Qt #include #include #include // TODO: make status bar capable to hide entries if size is too small, use priorisation namespace Kasten { ViewStatusController::ViewStatusController(StatusBar* statusBar) : mStatusBar(statusBar) { mPrintFunction = Okteta::OffsetFormat::printFunction(Okteta::OffsetFormat::Hexadecimal); mOffsetLabel = new QLabel(statusBar); statusBar->addWidget(mOffsetLabel); mSelectionLabel = new QLabel(statusBar); statusBar->addWidget(mSelectionLabel); const QString insertModeText = i18nc("@info:status short for: Insert mode", "INS"); const QString overwriteModeText = i18nc("@info:status short for: Overwrite mode", "OVR"); const QString insertModeTooltip = i18nc("@info:tooltip", "Insert mode"); const QString overwriteModeTooltip = i18nc("@info:tooltip", "Overwrite mode"); mOverwriteModeToggleButton = new ToggleButton(insertModeText, insertModeTooltip, statusBar); mOverwriteModeToggleButton->setCheckedState(overwriteModeText, overwriteModeTooltip); statusBar->addWidget(mOverwriteModeToggleButton); connect(mOverwriteModeToggleButton, &ToggleButton::clicked, this, &ViewStatusController::setOverwriteMode); mValueCodingComboBox = new KComboBox(statusBar); const QStringList list { i18nc("@item:inmenu encoding of the bytes as values in the hexadecimal format", "Hexadecimal"), i18nc("@item:inmenu encoding of the bytes as values in the decimal format", "Decimal"), i18nc("@item:inmenu encoding of the bytes as values in the octal format", "Octal"), i18nc("@item:inmenu encoding of the bytes as values in the binary format", "Binary"), }; mValueCodingComboBox->addItems(list); mValueCodingComboBox->setToolTip( i18nc("@info:tooltip", "Coding of the value interpretation in the current view.")); connect(mValueCodingComboBox, QOverload::of(&KComboBox::activated), this, &ViewStatusController::setValueCoding); statusBar->addWidget(mValueCodingComboBox); mCharCodingComboBox = new KComboBox(statusBar); mCharCodingComboBox->addItems(Okteta::CharCodec::codecNames()); mCharCodingComboBox->setToolTip( i18nc("@info:tooltip", "Encoding in the character column of the current view.")); connect(mCharCodingComboBox, QOverload::of(&KComboBox::activated), this, &ViewStatusController::setCharCoding); statusBar->addWidget(mCharCodingComboBox); fixWidths(Okteta::OffsetFormat::Hexadecimal); setTargetModel(nullptr); } // the letter C can be very wide, that is why with proportional fonts there seems too much space used, but isn't // see https://frinring.wordpress.com/2008/10/14/better-width-with-open-sources/ void ViewStatusController::fixWidths(int offsetCoding) { const QFontMetrics metrics = mStatusBar->fontMetrics(); // mOffsetLabel constexpr int hexDigitsCount = 16; constexpr int decimalDigitsCount = 10; constexpr int firstLetterIndex = 10; constexpr char digits[hexDigitsCount] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; int largestOffsetWidth = 0; int largestSelectionWidth = 0; int widestDigitIndex = 0; const int digitsCount = (offsetCoding == Okteta::OffsetFormat::Hexadecimal) ? hexDigitsCount : decimalDigitsCount; for (int i = 0; i < digitsCount; ++i) { QString offset; if (offsetCoding == Okteta::OffsetFormat::Hexadecimal) { offset = QString(9, QLatin1Char(digits[i])); offset[4] = QLatin1Char(':'); } else { offset = QString(10, QLatin1Char(digits[i])); } const QString offsetText = i18n("Offset: %1", offset); const int offsetWidth = metrics.boundingRect(offsetText).width(); if (largestOffsetWidth < offsetWidth) { largestOffsetWidth = offsetWidth; } const char countDigit = (i < firstLetterIndex) ? digits[i] : digits[widestDigitIndex]; const int maxNumber = QByteArray('1' + QByteArray(9, countDigit)).toInt(); const QString bytesCount = i18n("%1 bytes", maxNumber); const QString selectionString = i18nc("@info:status selection: start offset - end offset ()", "Selection: %1 - %2 (%3)", offset, offset, bytesCount); const int selectionWidth = metrics.boundingRect(selectionString).width(); if (largestSelectionWidth < selectionWidth) { if (i < firstLetterIndex) { widestDigitIndex = i; } largestSelectionWidth = selectionWidth; } } mOffsetLabel->setFixedWidth(largestOffsetWidth); mSelectionLabel->setFixedWidth(largestSelectionWidth); mStatusBar->updateLayout(); } void ViewStatusController::setTargetModel(AbstractModel* model) { if (mByteArrayView) { mByteArrayView->disconnect(this); mByteArrayView->disconnect(mOverwriteModeToggleButton); } mByteArrayView = model ? model->findBaseModel() : nullptr; const bool hasView = (mByteArrayView != nullptr); if (hasView) { mStartOffset = mByteArrayView->startOffset(); onCursorPositionChanged(mByteArrayView->cursorPosition()); onSelectedDataChanged(mByteArrayView->modelSelection()); mOverwriteModeToggleButton->setChecked(mByteArrayView->isOverwriteMode()); onOffsetCodingChanged(mByteArrayView->offsetCoding()); onValueCodingChanged(mByteArrayView->valueCoding()); onCharCodecChanged(mByteArrayView->charCodingName()); connect(mByteArrayView, &ByteArrayView::cursorPositionChanged, this, &ViewStatusController::onCursorPositionChanged); connect(mByteArrayView, &ByteArrayView::selectedDataChanged, this, &ViewStatusController::onSelectedDataChanged); connect(mByteArrayView, &ByteArrayView::overwriteModeChanged, mOverwriteModeToggleButton, &ToggleButton::setChecked); connect(mByteArrayView, &ByteArrayView::offsetCodingChanged, this, &ViewStatusController::onOffsetCodingChanged); connect(mByteArrayView, &ByteArrayView::valueCodingChanged, this, &ViewStatusController::onValueCodingChanged); connect(mByteArrayView, &ByteArrayView::charCodecChanged, this, &ViewStatusController::onCharCodecChanged); } else { mOffsetLabel->setText(i18nc("@info:status offset value not available", "Offset: -")); mSelectionLabel->setText(i18nc("@info:status offset value not available", "Selection: -")); mOverwriteModeToggleButton->setChecked(false); mValueCodingComboBox->setCurrentIndex(0); mCharCodingComboBox->setCurrentIndex(0); } mOffsetLabel->setEnabled(hasView); mSelectionLabel->setEnabled(hasView); mOverwriteModeToggleButton->setEnabled(hasView); mValueCodingComboBox->setEnabled(hasView); mCharCodingComboBox->setEnabled(hasView); } void ViewStatusController::setOverwriteMode(bool overwrite) { mByteArrayView->setOverwriteMode(overwrite); } void ViewStatusController::setValueCoding(int valueCoding) { mByteArrayView->setValueCoding(valueCoding); mByteArrayView->setFocus(); } void ViewStatusController::setCharCoding(int charCoding) { mByteArrayView->setCharCoding(Okteta::CharCodec::codecNames()[charCoding]); mByteArrayView->setFocus(); } void ViewStatusController::onCursorPositionChanged(Okteta::Address offset) { char codedOffset[Okteta::OffsetFormat::MaxFormatWidth + 1]; mPrintFunction(codedOffset, mStartOffset + offset); mOffsetLabel->setText(i18n("Offset: %1", QString::fromUtf8(codedOffset))); } // TODO: fix selection by cursor not sending updates void ViewStatusController::onSelectedDataChanged(const Kasten::AbstractModelSelection* modelSelection) { const auto* byteArraySelection = static_cast(modelSelection); const Okteta::AddressRange selection = byteArraySelection->range(); QString selectionString; if (!selection.isEmpty()) { char codedSelectionStart[Okteta::OffsetFormat::MaxFormatWidth + 1]; char codedSelectionEnd[Okteta::OffsetFormat::MaxFormatWidth + 1]; mPrintFunction(codedSelectionStart, mStartOffset + selection.start()); mPrintFunction(codedSelectionEnd, mStartOffset + selection.end()); const QString bytesCount = i18np("1 byte", "%1 bytes", selection.width()); selectionString = i18nc("@info:status selection: start offset - end offset (number of bytes)", "Selection: %1 - %2 (%3)", QString::fromUtf8(codedSelectionStart), QString::fromUtf8(codedSelectionEnd), bytesCount); } else { selectionString = i18nc("@info:status offset value not available", "Selection: -"); } mSelectionLabel->setText(selectionString); } void ViewStatusController::onOffsetCodingChanged(int offsetCoding) { mPrintFunction = Okteta::OffsetFormat::printFunction((Okteta::OffsetFormat::Format)offsetCoding); fixWidths(offsetCoding); // trigger updates of offset printing labels onCursorPositionChanged(mByteArrayView->cursorPosition()); onSelectedDataChanged(mByteArrayView->modelSelection()); } void ViewStatusController::onValueCodingChanged(int valueCoding) { mValueCodingComboBox->setCurrentIndex(valueCoding); } void ViewStatusController::onCharCodecChanged(const QString& charCodecName) { const int charCodingIndex = Okteta::CharCodec::codecNames().indexOf(charCodecName); mCharCodingComboBox->setCurrentIndex(charCodingIndex); } } diff --git a/kasten/core/document/bytearraydocument.cpp b/kasten/core/document/bytearraydocument.cpp index ef008713..9a4131ca 100644 --- a/kasten/core/document/bytearraydocument.cpp +++ b/kasten/core/document/bytearraydocument.cpp @@ -1,105 +1,105 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraydocument.hpp" // Okteta core #include -// KF5 +// KF #include using Okteta::PieceTableByteArrayModel; namespace Kasten { ByteArrayDocument::ByteArrayDocument(const QString& initDescription) : mByteArray(new Okteta::PieceTableByteArrayModel()) , mInitDescription(initDescription) { connect(mByteArray, &PieceTableByteArrayModel::modifiedChanged, this, &ByteArrayDocument::onModelModified); connect(mByteArray, &PieceTableByteArrayModel::readOnlyChanged, this, &ByteArrayDocument::readOnlyChanged); connect(mByteArray, &PieceTableByteArrayModel::revertedToVersionIndex, this, &ByteArrayDocument::revertedToVersionIndex); connect(mByteArray, &PieceTableByteArrayModel::headVersionChanged, this, &ByteArrayDocument::headVersionChanged); connect(mByteArray, &PieceTableByteArrayModel::headVersionDescriptionChanged, this, &ByteArrayDocument::onHeadVersionDescriptionChanged); } ByteArrayDocument::~ByteArrayDocument() { delete mByteArray; } ByteArrayDocument::ByteArrayDocument(Okteta::PieceTableByteArrayModel* byteArray, const QString& initDescription) : mByteArray(byteArray) , mInitDescription(initDescription) { connect(mByteArray, &PieceTableByteArrayModel::modifiedChanged, this, &ByteArrayDocument::onModelModified); connect(mByteArray, &PieceTableByteArrayModel::readOnlyChanged, this, &ByteArrayDocument::readOnlyChanged); connect(mByteArray, &PieceTableByteArrayModel::revertedToVersionIndex, this, &ByteArrayDocument::revertedToVersionIndex); connect(mByteArray, &PieceTableByteArrayModel::headVersionChanged, this, &ByteArrayDocument::headVersionChanged); connect(mByteArray, &PieceTableByteArrayModel::headVersionDescriptionChanged, this, &ByteArrayDocument::onHeadVersionDescriptionChanged); } Okteta::AbstractByteArrayModel* ByteArrayDocument::content() const { return mByteArray; } QString ByteArrayDocument::title() const { return mTitle; } QString ByteArrayDocument::mimeType() const { return QStringLiteral("ByteArrayDocument"); } QString ByteArrayDocument::typeName() const { return i18nc("name of the data type", "Byte Array"); } bool ByteArrayDocument::isModifiable() const { return true; } bool ByteArrayDocument::isReadOnly() const { return mByteArray->isReadOnly(); } void ByteArrayDocument::setReadOnly(bool isReadOnly) { mByteArray->setReadOnly(isReadOnly); } ContentFlags ByteArrayDocument::contentFlags() const { return (mByteArray->isModified() ? ContentHasUnstoredChanges : ContentStateNormal); } void ByteArrayDocument::setTitle(const QString& title) { mTitle = title; emit titleChanged(mTitle); } int ByteArrayDocument::versionIndex() const { return mByteArray->versionIndex(); } int ByteArrayDocument::versionCount() const { return mByteArray->versionCount(); } DocumentVersionData ByteArrayDocument::versionData(int versionIndex) const { const QString changeComment = (versionIndex == 0) ? mInitDescription : mByteArray->versionDescription(versionIndex); return DocumentVersionData(versionIndex, changeComment); } void ByteArrayDocument::revertToVersionByIndex(int versionIndex) { mByteArray->revertToVersionByIndex(versionIndex); } void ByteArrayDocument::onModelModified(bool isModified) { emit contentFlagsChanged((isModified ? ContentHasUnstoredChanges : ContentStateNormal)); } void ByteArrayDocument::onHeadVersionDescriptionChanged(const QString& newDescription) { const DocumentVersionData data(mByteArray->versionIndex(), newDescription); emit headVersionDataChanged(data); } } diff --git a/kasten/core/document/bytearraydocumentfactory.cpp b/kasten/core/document/bytearraydocumentfactory.cpp index ef3a3b30..48e524f6 100644 --- a/kasten/core/document/bytearraydocumentfactory.cpp +++ b/kasten/core/document/bytearraydocumentfactory.cpp @@ -1,101 +1,101 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2006-2007 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraydocumentfactory.hpp" // lib #include "bytearraydocument.hpp" // Okteta core #include // Kasten core // #include -// KF5 +// KF #include // Qt #include namespace Kasten { static int newByteArrayDocumentCounter = 0; bool ByteArrayDocumentFactory::canCreateFromData(const QMimeData* mimeData) { Q_UNUSED(mimeData); // we currently take everything, see createFromData() return true; } AbstractDocument* ByteArrayDocumentFactory::create() { ByteArrayDocument* document = new ByteArrayDocument(i18nc("The byte array was new created.", "New created.")); ++newByteArrayDocumentCounter; // TODO: use document->typeName() ? document->setTitle( i18ncp("numbered title for a created document without a filename", "[New Byte Array]", "[New Byte Array %1]", newByteArrayDocumentCounter)); // document->setOwner(Person::createEgo()); return document; } AbstractDocument* ByteArrayDocumentFactory::createFromData(const QMimeData* mimeData, bool setModified) { if (!mimeData || mimeData->formats().isEmpty()) { return create(); } // SYNC: with abstractbytearrayview_p.cpp // if there is a octet stream, use it, otherwise take the dump of the format // with the highest priority // TODO: this may not be, what is expected, think about it, if we just // take byte array descriptions, like encodings in chars or values // would need the movement of the encoders into the core library const QString octetStreamFormatName = QStringLiteral("application/octet-stream"); const QString dataFormatName = (mimeData->hasFormat(octetStreamFormatName)) ? octetStreamFormatName : mimeData->formats()[0]; const QByteArray data = mimeData->data(dataFormatName); auto* byteArray = new Okteta::PieceTableByteArrayModel(data); byteArray->setModified(setModified); // TODO: pass name of generator ByteArrayDocument* document = new ByteArrayDocument(byteArray, i18nc("origin of the byte array", "Created from data.")); ++newByteArrayDocumentCounter; // TODO: use document->typeName() ? document->setTitle( i18ncp("numbered title for a created document without a filename", "[New Byte Array]", "[New Byte Array %1]", newByteArrayDocumentCounter)); // document->setOwner(Person::createEgo()); return document; } } diff --git a/kasten/core/io/filesystem/bytearrayrawfileloadthread.cpp b/kasten/core/io/filesystem/bytearrayrawfileloadthread.cpp index fdb63044..82dfcfa0 100644 --- a/kasten/core/io/filesystem/bytearrayrawfileloadthread.cpp +++ b/kasten/core/io/filesystem/bytearrayrawfileloadthread.cpp @@ -1,91 +1,91 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009,2011-2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayrawfileloadthread.hpp" // lib #include "bytearraydocument.hpp" // Kasten core // #include // Okteta core #include -// KF5 +// KF #include // Qt #include #include #include // C++ #include namespace Kasten { ByteArrayRawFileLoadThread::~ByteArrayRawFileLoadThread() = default; void ByteArrayRawFileLoadThread::run() { const qint64 fileSize = mFile->size(); // check if the file content can be addressed with Okteta::Address const Okteta::Address maxAddress = std::numeric_limits::max(); bool success = (fileSize <= maxAddress); if (success) { // allocate working memory QByteArray data; data.resize(fileSize); bool success = (data.size() == fileSize); if (success) { QDataStream inStream(mFile); inStream.readRawData(data.data(), fileSize); success = (inStream.status() == QDataStream::Ok); if (success) { auto* byteArray = new Okteta::PieceTableByteArrayModel(data); byteArray->setModified(false); mDocument = new ByteArrayDocument(byteArray, i18nc("destination of the byte array", "Loaded from file.")); // mDocument->setOwner(Person::createEgo()); // TODO: make PieceTableByteArrayModel a child by constructor argument parent byteArray->moveToThread(QCoreApplication::instance()->thread()); mDocument->moveToThread(QCoreApplication::instance()->thread()); } else { mErrorString = mFile->errorString(); } } else { mErrorString = i18n("There is not enough free working memory to load this file."); } } else { mErrorString = i18n("Support to load files larger than 2 GiB has not yet been implemented."); } if (!success) { mDocument = nullptr; } emit documentRead(mDocument); } } diff --git a/kasten/core/io/filesystem/bytearrayrawfilereloadthread.cpp b/kasten/core/io/filesystem/bytearrayrawfilereloadthread.cpp index 8d3f9680..a4c536c2 100644 --- a/kasten/core/io/filesystem/bytearrayrawfilereloadthread.cpp +++ b/kasten/core/io/filesystem/bytearrayrawfilereloadthread.cpp @@ -1,78 +1,78 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayrawfilereloadthread.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include #include // C++ #include namespace Kasten { ByteArrayRawFileReloadThread::ByteArrayRawFileReloadThread(QObject* parent, QFile* file) : QThread(parent) , mFile(file) { } ByteArrayRawFileReloadThread::~ByteArrayRawFileReloadThread() = default; void ByteArrayRawFileReloadThread::run() { const qint64 fileSize = mFile->size(); // check if the file content can be addressed with int // check if the file content can be addressed with Okteta::Address const Okteta::Address maxAddress = std::numeric_limits::max(); mSuccess = (fileSize <= maxAddress); if (mSuccess) { mData.resize(fileSize); mSuccess = (mData.size() == fileSize); if (mSuccess) { QDataStream inStream(mFile); inStream.readRawData(mData.data(), fileSize); mSuccess = (inStream.status() == QDataStream::Ok); if (!mSuccess) { mErrorString = mFile->errorString(); } } else { mErrorString = i18n("There is not enough free working memory to load this file."); } } else { mErrorString = i18n("Support to load files larger than 2 GiB has not yet been implemented."); } emit documentReloaded(mSuccess); } } diff --git a/kasten/core/io/filesystem/bytearrayrawfilewritetojob.cpp b/kasten/core/io/filesystem/bytearrayrawfilewritetojob.cpp index d29ba7d0..79b40c12 100644 --- a/kasten/core/io/filesystem/bytearrayrawfilewritetojob.cpp +++ b/kasten/core/io/filesystem/bytearrayrawfilewritetojob.cpp @@ -1,62 +1,61 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayrawfilewritetojob.hpp" // lib // #include "externalbookmarkstorage.hpp" #include "bytearrayrawfilesynchronizer.hpp" #include "bytearrayrawfilewritethread.hpp" #include "bytearraydocument.hpp" -// KF5 // Qt #include #include namespace Kasten { ByteArrayRawFileWriteToJob::ByteArrayRawFileWriteToJob(ByteArrayRawFileSynchronizer* synchronizer, const QUrl& url, AbstractModelSynchronizer::ConnectOption option) : AbstractFileSystemSyncWithRemoteJob(synchronizer, url, option) {} ByteArrayRawFileWriteToJob::~ByteArrayRawFileWriteToJob() = default; void ByteArrayRawFileWriteToJob::startSyncWithRemote() { auto* document = qobject_cast(synchronizer()->document()); auto* writeThread = new ByteArrayRawFileWriteThread(this, document, file()); writeThread->start(); while (!writeThread->wait(100)) { QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); } const bool success = writeThread->success(); delete writeThread; // if( success ) // ExternalBookmarkStorage().writeBookmarks( document, synchronizer()->url() ); completeSync(success); } } diff --git a/kasten/core/io/filesystem/externalbookmarkstorage.cpp b/kasten/core/io/filesystem/externalbookmarkstorage.cpp index 102704b7..90c68112 100644 --- a/kasten/core/io/filesystem/externalbookmarkstorage.cpp +++ b/kasten/core/io/filesystem/externalbookmarkstorage.cpp @@ -1,128 +1,128 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "externalbookmarkstorage.hpp" // lib #include "bytearraydocument.hpp" // Okteta core #include #include #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { ExternalBookmarkStorage::ExternalBookmarkStorage() { const QString bookmarksFileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QLatin1String("/okteta/bookmarks.xml"); mBookmarkManager = KBookmarkManager::managerForFile(bookmarksFileName, QStringLiteral("okteta")); } ExternalBookmarkStorage::~ExternalBookmarkStorage() = default; void ExternalBookmarkStorage::readBookmarks(ByteArrayDocument* document, const QUrl& url) { Okteta::AbstractByteArrayModel* byteArray = document->content(); Okteta::Bookmarkable* bookmarkable = qobject_cast(byteArray); bookmarkable->removeAllBookmarks(); const QString urlString = url.toDisplayString(QUrl::PrettyDecoded | QUrl::PreferLocalFile); KBookmarkGroup root = mBookmarkManager->root(); for (KBookmark bm = root.first(); !bm.isNull(); bm = root.next(bm)) { if (bm.isSeparator() || !bm.isGroup()) { continue; } if (bm.fullText() == urlString) { KBookmarkGroup bmGroup = bm.toGroup(); QVector bookmarksToBeCreated; Okteta::Bookmark bookmark; for (bm = bmGroup.first(); !bm.isNull(); bm = bmGroup.next(bm)) { if (bm.isSeparator() || bm.isGroup()) { continue; } bookmark.setOffset(bm.url().fragment().toULongLong()); bookmark.setName(bm.fullText()); bookmarksToBeCreated.append(bookmark); } bookmarkable->addBookmarks(bookmarksToBeCreated); break; } } } void ExternalBookmarkStorage::writeBookmarks(ByteArrayDocument* document, const QUrl& url) { Okteta::AbstractByteArrayModel* byteArray = document->content(); Okteta::Bookmarkable* bookmarkable = qobject_cast(byteArray); if (!bookmarkable) { return; } const QString urlString = url.toDisplayString(QUrl::PrettyDecoded | QUrl::PreferLocalFile); KBookmarkGroup root = mBookmarkManager->root(); // rm old bookmarkable KBookmark bm = root.first(); while (!bm.isNull()) { if (bm.isSeparator() || !bm.isGroup()) { continue; } if (bm.fullText() == urlString) { root.deleteBookmark(bm); break; } bm = root.next(bm); } // store current bookmarks KBookmarkGroup bookmarkGroup = root.createNewFolder(urlString); Okteta::BookmarksConstIterator bit = bookmarkable->createBookmarksConstIterator(); while (bit.hasNext()) { const Okteta::Bookmark& bookmark = bit.next(); QUrl bookmarkUrl = url; bookmarkUrl.setFragment(QString::number(bookmark.offset())); bookmarkGroup.addBookmark(bookmark.name(), bookmarkUrl, QString()); } mBookmarkManager->save(false); } } diff --git a/kasten/gui/io/generator/pattern/bytearraypatterngenerator.cpp b/kasten/gui/io/generator/pattern/bytearraypatterngenerator.cpp index e58da15a..4c91f91e 100644 --- a/kasten/gui/io/generator/pattern/bytearraypatterngenerator.cpp +++ b/kasten/gui/io/generator/pattern/bytearraypatterngenerator.cpp @@ -1,86 +1,86 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraypatterngenerator.hpp" -// KF5 +// KF #include // Qt #include #include namespace Kasten { ByteArrayPatternGeneratorSettings::ByteArrayPatternGeneratorSettings() = default; // TODO: support insert to selection, cmp. fill in painting program // there are two kinds of generated datam fixed size (e.g. sequence) and endless size? // perhaps by option fill selection? or a separate menu entry fill, which only works on selections? ByteArrayPatternGenerator::ByteArrayPatternGenerator() : AbstractModelDataGenerator( i18nc("name of the generated data", "Pattern..."), QStringLiteral("application/octet-stream"), DynamicGeneration) {} ByteArrayPatternGenerator::~ByteArrayPatternGenerator() = default; // TODO: optimize and check if pattern is just one byte, so memset can be used // TODO: see if copying larger chunks with memcpy is faster, so QMimeData* ByteArrayPatternGenerator::generateData() { const int patternSize = mSettings.pattern.size(); const int insertDataSize = mSettings.count * patternSize; QByteArray insertData(insertDataSize, '\0'); char* rawInsertData = insertData.data(); const char* rawPatternData = mSettings.pattern.constData(); for (int i = 0; i < insertDataSize; i += patternSize) { memcpy(&rawInsertData[i], rawPatternData, patternSize); } auto* mimeData = new QMimeData; mimeData->setData(mimeType(), insertData); // TODO: a method to get the description of the change, e.g. #if 0 Okteta::ChangesDescribable* changesDescribable = qobject_cast(mByteArrayModel); if (changesDescribable) { changesDescribable->openGroupedChange(i18n("Pattern inserted.")); } mByteArrayView->insert(insertData); // mByteArrayModel->replace( filteredSection, filterResult ); if (changesDescribable) { changesDescribable->closeGroupedChange(); } #endif return mimeData; } } diff --git a/kasten/gui/io/generator/pattern/bytearraypatterngeneratorconfigeditor.cpp b/kasten/gui/io/generator/pattern/bytearraypatterngeneratorconfigeditor.cpp index 93510afb..466f2525 100644 --- a/kasten/gui/io/generator/pattern/bytearraypatterngeneratorconfigeditor.cpp +++ b/kasten/gui/io/generator/pattern/bytearraypatterngeneratorconfigeditor.cpp @@ -1,106 +1,106 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraypatterngeneratorconfigeditor.hpp" // lib #include -// KF5 +// KF #include // Qt #include #include namespace Kasten { ByteArrayPatternGeneratorConfigEditor::ByteArrayPatternGeneratorConfigEditor(ByteArrayPatternGenerator* generator, QWidget* parent) : AbstractModelDataGeneratorConfigEditor(parent) , mGenerator(generator) { mSettings = mGenerator->settings(); auto* pageLayout = new QFormLayout(this); pageLayout->setContentsMargins(0, 0, 0, 0); // pattern const QString patternEditLabel = i18nc("@label:textbox", "Pattern:"); mPatternEdit = new Okteta::ByteArrayComboBox(this); mPatternEdit->setByteArray(mSettings.pattern); connect(mPatternEdit, &Okteta::ByteArrayComboBox::byteArrayChanged, this, &ByteArrayPatternGeneratorConfigEditor::onSettingsChanged); connect(mPatternEdit, &Okteta::ByteArrayComboBox::byteArrayChanged, this, &ByteArrayPatternGeneratorConfigEditor::onPatternChanged); const QString inputWhatsThis = i18nc("@info:whatsthis", "Enter a pattern to search for, or select a previous pattern from the list."); mPatternEdit->setWhatsThis(inputWhatsThis); pageLayout->addRow(patternEditLabel, mPatternEdit); // number const QString numberInputLabel = i18nc("@label:spinbox number of times to insert the pattern", "&Number:"); mNumberInput = new QSpinBox(this); mNumberInput->setRange(1, INT_MAX); mNumberInput->setValue(mSettings.count); connect(mNumberInput, QOverload::of(&QSpinBox::valueChanged), this, &ByteArrayPatternGeneratorConfigEditor::onSettingsChanged); const QString numberWhatsThis = i18nc("@info:whatsthis", "Enter the number of times the pattern should be inserted."); mNumberInput->setWhatsThis(numberWhatsThis); pageLayout->addRow(numberInputLabel, mNumberInput); } ByteArrayPatternGeneratorConfigEditor::~ByteArrayPatternGeneratorConfigEditor() = default; bool ByteArrayPatternGeneratorConfigEditor::isValid() const { return (!mSettings.pattern.isEmpty()); } QString ByteArrayPatternGeneratorConfigEditor::name() const { return i18nc("@item name of the generated data", "Pattern"); } // TODO: get char codec #if 0 void InsertPatternDialog::setCharCodec(const QString& codecName) { mPatternEdit->setCharCodec(codecName); } #endif void ByteArrayPatternGeneratorConfigEditor::onSettingsChanged() { mSettings.pattern = mPatternEdit->byteArray(); mSettings.count = mNumberInput->value(); mGenerator->setSettings(mSettings); } void ByteArrayPatternGeneratorConfigEditor::onPatternChanged(const QByteArray& pattern) { emit validityChanged(!pattern.isEmpty()); } } diff --git a/kasten/gui/io/generator/randomdata/bytearrayrandomdatagenerator.cpp b/kasten/gui/io/generator/randomdata/bytearrayrandomdatagenerator.cpp index a8d01500..dd85f9dd 100644 --- a/kasten/gui/io/generator/randomdata/bytearrayrandomdatagenerator.cpp +++ b/kasten/gui/io/generator/randomdata/bytearrayrandomdatagenerator.cpp @@ -1,86 +1,86 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayrandomdatagenerator.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include #include // Std #include namespace Kasten { ByteArrayRandomDataGeneratorSettings::ByteArrayRandomDataGeneratorSettings() = default; // TODO: support insert to selection, cmp. fill in painting program // there are two kinds of generated datam fixed size (e.g. sequence) and endless size? // perhaps by option fill selection? or a separate menu entry fill, which only works on selections? ByteArrayRandomDataGenerator::ByteArrayRandomDataGenerator() : AbstractModelDataGenerator( i18nc("name of the generated data", "Random Data..."), QStringLiteral("application/octet-stream"), DynamicGeneration) {} ByteArrayRandomDataGenerator::~ByteArrayRandomDataGenerator() = default; // TODO: use different RNG, with multiple characteristics and offer them in the config QMimeData* ByteArrayRandomDataGenerator::generateData() { qsrand((unsigned int)time(nullptr)); const int insertDataSize = mSettings.size; QByteArray insertData(insertDataSize, '\0'); for (int i = 0; i < insertDataSize; ++i) { insertData[i] = qrand() % 256; // TODO: modulo is expensive, even if easy to use } auto* mimeData = new QMimeData; mimeData->setData(mimeType(), insertData); // TODO: a method to get the description of the change, e.g. #if 0 Okteta::ChangesDescribable* changesDescribable = qobject_cast(mByteArrayModel); if (changesDescribable) { changesDescribable->openGroupedChange(i18n("RandomData inserted.")); } mByteArrayView->insert(insertData); // mByteArrayModel->replace( filteredSection, filterResult ); if (changesDescribable) { changesDescribable->closeGroupedChange(); } #endif return mimeData; } } diff --git a/kasten/gui/io/generator/randomdata/bytearrayrandomdatageneratorconfigeditor.cpp b/kasten/gui/io/generator/randomdata/bytearrayrandomdatageneratorconfigeditor.cpp index c86652c7..886dc7f2 100644 --- a/kasten/gui/io/generator/randomdata/bytearrayrandomdatageneratorconfigeditor.cpp +++ b/kasten/gui/io/generator/randomdata/bytearrayrandomdatageneratorconfigeditor.cpp @@ -1,81 +1,81 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayrandomdatageneratorconfigeditor.hpp" -// KF5 +// KF #include // Qt #include #include namespace Kasten { ByteArrayRandomDataGeneratorConfigEditor::ByteArrayRandomDataGeneratorConfigEditor(ByteArrayRandomDataGenerator* generator, QWidget* parent) : AbstractModelDataGeneratorConfigEditor(parent) , mGenerator(generator) { mSettings = mGenerator->settings(); auto* pageLayout = new QFormLayout(this); pageLayout->setContentsMargins(0, 0, 0, 0); // number const QString numberInputLabel = i18nc("@label:spinbox size of the bytearray to generate", "&Size (bytes):"); mSizeInput = new QSpinBox(this); mSizeInput->setRange(1, INT_MAX); mSizeInput->setValue(mSettings.size); connect(mSizeInput, QOverload::of(&QSpinBox::valueChanged), this, &ByteArrayRandomDataGeneratorConfigEditor::onSettingsChanged); const QString numberWhatsThis = i18nc("@info:whatsthis", "Enter the size of the bytearray to generate."); mSizeInput->setWhatsThis(numberWhatsThis); pageLayout->addRow(numberInputLabel, mSizeInput); } ByteArrayRandomDataGeneratorConfigEditor::~ByteArrayRandomDataGeneratorConfigEditor() = default; QString ByteArrayRandomDataGeneratorConfigEditor::name() const { return i18nc("@item name of the generated data", "Random Data"); } // TODO: get char codec #if 0 void InsertRandomDataDialog::setCharCodec(const QString& codecName) { mRandomDataEdit->setCharCodec(codecName); } #endif void ByteArrayRandomDataGeneratorConfigEditor::onSettingsChanged() { mSettings.size = mSizeInput->value(); mGenerator->setSettings(mSettings); } } diff --git a/kasten/gui/io/generator/sequence/bytearraysequencegenerator.cpp b/kasten/gui/io/generator/sequence/bytearraysequencegenerator.cpp index 280a058e..3ead3c43 100644 --- a/kasten/gui/io/generator/sequence/bytearraysequencegenerator.cpp +++ b/kasten/gui/io/generator/sequence/bytearraysequencegenerator.cpp @@ -1,86 +1,86 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraysequencegenerator.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include #include namespace Kasten { ByteArraySequenceGeneratorSettings::ByteArraySequenceGeneratorSettings() = default; // TODO: support insert to selection, cmp. fill in painting program // there are two kinds of generated datam fixed size (e.g. sequence) and endless size? // perhaps by option fill selection? or a separate menu entry fill, which only works on selections? ByteArraySequenceGenerator::ByteArraySequenceGenerator() : AbstractModelDataGenerator( i18nc("name of the generated data", "Sequence"), QStringLiteral("application/octet-stream"), StaticGeneration) {} ByteArraySequenceGenerator::~ByteArraySequenceGenerator() = default; // TODO: optimize and check if pattern is just one byte, so memset can be used // TODO: see if copying larger chunks with memcpy is faster, so QMimeData* ByteArraySequenceGenerator::generateData() { const Okteta::Byte firstByte = 0; const Okteta::Byte lastByte = 255; const int insertDataSize = lastByte - firstByte + 1; QByteArray insertData(insertDataSize, '\0'); Okteta::Byte byte = firstByte; for (int i = 0; i < insertDataSize; ++i, ++byte) { insertData[i] = byte; } auto* mimeData = new QMimeData; mimeData->setData(mimeType(), insertData); // TODO: a method to get the description of the change, e.g. #if 0 Okteta::ChangesDescribable* changesDescribable = qobject_cast(mByteArrayModel); if (changesDescribable) { changesDescribable->openGroupedChange(i18n("Sequence inserted.")); } mByteArrayView->insert(insertData); // mByteArrayModel->replace( filteredSection, filterResult ); if (changesDescribable) { changesDescribable->closeGroupedChange(); } #endif return mimeData; } } diff --git a/kasten/gui/io/streamencoder/base32/bytearraybase32streamencoder.cpp b/kasten/gui/io/streamencoder/base32/bytearraybase32streamencoder.cpp index a4920dba..44c4e3a7 100644 --- a/kasten/gui/io/streamencoder/base32/bytearraybase32streamencoder.cpp +++ b/kasten/gui/io/streamencoder/base32/bytearraybase32streamencoder.cpp @@ -1,177 +1,177 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraybase32streamencoder.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include namespace Kasten { static constexpr char base32ClassicEncodeMap[32] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7' }; static constexpr char base32HexEncodeMap[32] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V' }; static constexpr char base32ZHexEncodeMap[32] = { 'y', 'b', 'n', 'd', 'r', 'f', 'g', '8', 'e', 'j', 'k', 'm', 'c', 'p', 'q', 'x', 'o', 't', '1', 'u', 'w', 'i', 's', 'z', 'a', '3', '4', '5', 'h', '7', '6', '9' }; static constexpr const char* base32PaddingData[4] = { "======", "====", "===", "=" }; static inline constexpr const char* base32Padding(ByteArrayBase32StreamEncoder::InputByteIndex index) { return base32PaddingData[static_cast(index) - 1]; } static inline constexpr const char* noPadding(ByteArrayBase32StreamEncoder::InputByteIndex /*index*/) { return ""; } struct Base32EncodingData { const char* const encodeMap; const char* (* padding)(ByteArrayBase32StreamEncoder::InputByteIndex); }; static constexpr Base32EncodingData base32EncodingData[3] = { {base32ClassicEncodeMap, &base32Padding}, {base32HexEncodeMap, &base32Padding}, {base32ZHexEncodeMap, &noPadding} }; Base32StreamEncoderSettings::Base32StreamEncoderSettings() = default; ByteArrayBase32StreamEncoder::ByteArrayBase32StreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "Base32"), QStringLiteral("text/x-base32")) {} ByteArrayBase32StreamEncoder::~ByteArrayBase32StreamEncoder() = default; bool ByteArrayBase32StreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { Q_UNUSED(byteArrayView); bool success = true; // encode QTextStream textStream(device); // prepare const auto& algorithmEncodingData = base32EncodingData[static_cast(mSettings.algorithmId)]; const char* const base32EncodeMap = algorithmEncodingData.encodeMap; const char* (* base32Padding)(InputByteIndex) = algorithmEncodingData.padding; InputByteIndex inputByteIndex = InputByteIndex::First; int outputGroupsPerLine = 0; unsigned char bitsFromLastByte; for (Okteta::Address i = range.start(); i <= range.end(); ++i) { const Okteta::Byte byte = byteArrayModel->byte(i); switch (inputByteIndex) { case InputByteIndex::First: // bits 7..3 textStream << base32EncodeMap[(byte >> 3)]; // bits 2..0 -> 4..2 for next bitsFromLastByte = (byte & 0x7) << 2; inputByteIndex = InputByteIndex::Second; break; case InputByteIndex::Second: // from last and bits 7..6 as 1..0 from this textStream << base32EncodeMap[(bitsFromLastByte | byte >> 6)]; // bits 5..1 as 4..0 textStream << base32EncodeMap[(byte & 0x3E) >> 1]; // bits 0 -> 4 for next bitsFromLastByte = (byte & 0x1) << 4; inputByteIndex = InputByteIndex::Third; break; case InputByteIndex::Third: // from last and bits 7..4 as 3..0 from this textStream << base32EncodeMap[(bitsFromLastByte | byte >> 4)]; // bits 3..0 -> 4..1 for next bitsFromLastByte = (byte & 0xF) << 1; inputByteIndex = InputByteIndex::Fourth; break; case InputByteIndex::Fourth: // from last and bit 7 as 0 from this textStream << base32EncodeMap[(bitsFromLastByte | byte >> 7)]; // bits 6..2 as 4..0 textStream << base32EncodeMap[(byte & 0x7C) >> 2]; // bits 1..0 -> 4..3 for next bitsFromLastByte = (byte & 0x3) << 3; inputByteIndex = InputByteIndex::Fifth; break; case InputByteIndex::Fifth: // from last and bits 7..5 as 2..0 from this textStream << base32EncodeMap[(bitsFromLastByte | byte >> 5)]; // bits 4..0 textStream << base32EncodeMap[(byte & 0x1F)]; inputByteIndex = InputByteIndex::First; ++outputGroupsPerLine; if (outputGroupsPerLine >= maxOutputGroupsPerLine && i < range.end()) { textStream << "\r\n"; outputGroupsPerLine = 0; } break; } } const bool hasBitsLeft = (inputByteIndex != InputByteIndex::First); if (hasBitsLeft) { textStream << base32EncodeMap[bitsFromLastByte] << base32Padding(inputByteIndex); } return success; } } diff --git a/kasten/gui/io/streamencoder/base32/bytearraybase32streamencoderconfigeditor.cpp b/kasten/gui/io/streamencoder/base32/bytearraybase32streamencoderconfigeditor.cpp index 224737b2..418dd3dd 100644 --- a/kasten/gui/io/streamencoder/base32/bytearraybase32streamencoderconfigeditor.cpp +++ b/kasten/gui/io/streamencoder/base32/bytearraybase32streamencoderconfigeditor.cpp @@ -1,80 +1,80 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraybase32streamencoderconfigeditor.hpp" // lib #include "bytearraytextstreamencoderpreview.hpp" -// KF5 +// KF #include #include // Qt #include #include namespace Kasten { ByteArrayBase32StreamEncoderConfigEditor::ByteArrayBase32StreamEncoderConfigEditor(ByteArrayBase32StreamEncoder* encoder, QWidget* parent) : AbstractModelStreamEncoderConfigEditor(parent) , mEncoder(encoder) { mSettings = mEncoder->settings(); auto* pageLayout = new QFormLayout(this); pageLayout->setContentsMargins(0, 0, 0, 0); // data type const QString encodingTypeLabel = i18nc("@label:listbox the type of the used encoding: Classic, Base32hex or z-base-32.", "Encoding:"); mEncodingSelect = new KComboBox(this); const QStringList list { i18nc("@item:inmenu Doing the base32 using the classical encoding", "Classic"), i18nc("@item:inmenu Doing the base32 using the Base32hex encoding", "Base32hex"), i18nc("@item:inmenu Doing the base32 using the z-base-32 encoding", "z-base-32"), }; mEncodingSelect->addItems(list); mEncodingSelect->setCurrentIndex(static_cast(mSettings.algorithmId)); connect(mEncodingSelect, QOverload::of(&KComboBox::activated), this, &ByteArrayBase32StreamEncoderConfigEditor::onSettingsChanged); pageLayout->addRow(encodingTypeLabel, mEncodingSelect); } ByteArrayBase32StreamEncoderConfigEditor::~ByteArrayBase32StreamEncoderConfigEditor() = default; AbstractSelectionView* ByteArrayBase32StreamEncoderConfigEditor::createPreviewView() const { return new ByteArrayTextStreamEncoderPreview(mEncoder); } void ByteArrayBase32StreamEncoderConfigEditor::onSettingsChanged() { mSettings.algorithmId = static_cast(mEncodingSelect->currentIndex()); mEncoder->setSettings(mSettings); } } diff --git a/kasten/gui/io/streamencoder/base64/bytearraybase64streamencoder.cpp b/kasten/gui/io/streamencoder/base64/bytearraybase64streamencoder.cpp index d5ce8d2f..08ec4d29 100644 --- a/kasten/gui/io/streamencoder/base64/bytearraybase64streamencoder.cpp +++ b/kasten/gui/io/streamencoder/base64/bytearraybase64streamencoder.cpp @@ -1,120 +1,120 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009-2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraybase64streamencoder.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include namespace Kasten { const char base64EncodeMap[64] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; static constexpr const char* base64PaddingData[2] = { "==", "=" }; static inline constexpr const char* base64Padding(ByteArrayBase64StreamEncoder::InputByteIndex index) { return base64PaddingData[static_cast(index) - 1]; } ByteArrayBase64StreamEncoder::ByteArrayBase64StreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "Base64"), QStringLiteral("application/base64")) {} ByteArrayBase64StreamEncoder::~ByteArrayBase64StreamEncoder() = default; bool ByteArrayBase64StreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { Q_UNUSED(byteArrayView); bool success = true; // encode QTextStream textStream(device); // prepare InputByteIndex inputByteIndex = InputByteIndex::First; int outputGroupsPerLine = 0; unsigned char bitsFromLastByte; for (Okteta::Address i = range.start(); i <= range.end(); ++i) { const Okteta::Byte byte = byteArrayModel->byte(i); switch (inputByteIndex) { case InputByteIndex::First: // bits 7..2 textStream << base64EncodeMap[(byte >> 2)]; // bits 1..0 -> 5..4 for next bitsFromLastByte = (byte & 0x3) << 4; inputByteIndex = InputByteIndex::Second; break; case InputByteIndex::Second: // from last and bits 7..4 as 3..0 from this textStream << base64EncodeMap[(bitsFromLastByte | byte >> 4)]; // bits 3..0 -> 5..2 for next bitsFromLastByte = (byte & 0xf) << 2; inputByteIndex = InputByteIndex::Third; break; case InputByteIndex::Third: // from last and bits 7..6 as 1..0 from this textStream << base64EncodeMap[(bitsFromLastByte | byte >> 6)]; // bits 5..0 textStream << base64EncodeMap[(byte & 0x3F)]; inputByteIndex = InputByteIndex::First; ++outputGroupsPerLine; if (outputGroupsPerLine >= maxOutputGroupsPerLine && i < range.end()) { textStream << "\r\n"; outputGroupsPerLine = 0; } break; } } const bool hasBitsLeft = (inputByteIndex != InputByteIndex::First); if (hasBitsLeft) { textStream << base64EncodeMap[bitsFromLastByte] << base64Padding(inputByteIndex); } return success; } } diff --git a/kasten/gui/io/streamencoder/base85/bytearraybase85streamencoder.cpp b/kasten/gui/io/streamencoder/base85/bytearraybase85streamencoder.cpp index 3bd2b1ef..1e01244a 100644 --- a/kasten/gui/io/streamencoder/base85/bytearraybase85streamencoder.cpp +++ b/kasten/gui/io/streamencoder/base85/bytearraybase85streamencoder.cpp @@ -1,134 +1,134 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraybase85streamencoder.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include namespace Kasten { static inline void streamEncoded(QTextStream& textStream, int& outputBytesPerLine, quint32 tuple, int inputByteCount) { // radix85 values, most significant first char data[5]; for (int i = 4; i >= 0; --i) { // TODO: find an efficient bit manipulating algorithm data[i] = tuple % 85; tuple /= 85; } // output inputByteCount+1 from radix85 values for (int i = 0; i <= inputByteCount; ++i) { textStream << (char)(data[i] + 33); ++outputBytesPerLine; if (outputBytesPerLine >= ByteArrayBase85StreamEncoder::maxOutputBytesPerLine) { textStream << '\n'; outputBytesPerLine = 0; } } } // TODO: for now this is just the Adobe/Ascii85 implementation, so present as that // later also add btoa with different version, e.g. 4.2 added a "y" for 4 spaces ByteArrayBase85StreamEncoder::ByteArrayBase85StreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "Ascii85"), QStringLiteral("text/x-ascii85")) {} ByteArrayBase85StreamEncoder::~ByteArrayBase85StreamEncoder() = default; bool ByteArrayBase85StreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { Q_UNUSED(byteArrayView); bool success = true; // encode QTextStream textStream(device); // prepare InputByteIndex inputByteIndex = InputByteIndex::First; quint32 tuple = 0; // header int outputBytesPerLine = 2; textStream << "<~"; for (Okteta::Address i = range.start(); i <= range.end(); ++i) { const Okteta::Byte byte = byteArrayModel->byte(i); switch (inputByteIndex) { case InputByteIndex::First: tuple |= (byte << 24); inputByteIndex = InputByteIndex::Second; break; case InputByteIndex::Second: tuple |= (byte << 16); inputByteIndex = InputByteIndex::Third; break; case InputByteIndex::Third: tuple |= (byte << 8); inputByteIndex = InputByteIndex::Fourth; break; case InputByteIndex::Fourth: tuple |= byte; if (tuple == 0) { textStream << 'z'; ++outputBytesPerLine; if (outputBytesPerLine >= maxOutputBytesPerLine) { textStream << '\n'; outputBytesPerLine = 0; } } else { streamEncoded(textStream, outputBytesPerLine, tuple, static_cast(inputByteIndex) + 1); } tuple = 0; inputByteIndex = InputByteIndex::First; break; } } const bool hasBitsLeft = (inputByteIndex != InputByteIndex::First); if (hasBitsLeft) { streamEncoded(textStream, outputBytesPerLine, tuple, static_cast(inputByteIndex)); } // footer if (outputBytesPerLine + 2 > maxOutputBytesPerLine) { textStream << '\n'; } textStream << "~>\n"; return success; } } diff --git a/kasten/gui/io/streamencoder/bytearraytextstreamencoderpreview.cpp b/kasten/gui/io/streamencoder/bytearraytextstreamencoderpreview.cpp index ae1f0e86..3e580e1f 100644 --- a/kasten/gui/io/streamencoder/bytearraytextstreamencoderpreview.cpp +++ b/kasten/gui/io/streamencoder/bytearraytextstreamencoderpreview.cpp @@ -1,78 +1,78 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraytextstreamencoderpreview.hpp" // lib #include "abstractbytearraystreamencoder.hpp" -// KF5 +// KF #include // Qt #include #include namespace Kasten { ByteArrayTextStreamEncoderPreview::ByteArrayTextStreamEncoderPreview(AbstractByteArrayStreamEncoder* encoder) : mEncoder(encoder) { mWidget = new QTextEdit(); // TODO: use Kate for syntax highlighting mWidget->setReadOnly(true); mWidget->setLineWrapMode(QTextEdit::NoWrap); mWidget->setToolTip(i18n("The preview uses maximal the first 100 bytes.")); // TODO: find a signal/event emitted when fixedfont changes // connect( KGlobalSettings::self(), &KGlobalSettings::kdisplayFontChanged, // this, &ByteArrayTextStreamEncoderPreview::setFixedFontByGlobalSettings ); setFixedFontByGlobalSettings(); connect(mEncoder, &AbstractByteArrayStreamEncoder::settingsChanged, this, &ByteArrayTextStreamEncoderPreview::update); } ByteArrayTextStreamEncoderPreview::~ByteArrayTextStreamEncoderPreview() { delete mWidget; } QWidget* ByteArrayTextStreamEncoderPreview::widget() const { return mWidget; } void ByteArrayTextStreamEncoderPreview::setData(AbstractModel* model, const AbstractModelSelection* selection) { mModel = model; mSelection = selection; update(); } void ByteArrayTextStreamEncoderPreview::update() { if (mModel) { mWidget->setText(mEncoder->previewData(mModel, mSelection)); } } void ByteArrayTextStreamEncoderPreview::setFixedFontByGlobalSettings() { mWidget->setFont(QFontDatabase::systemFont(QFontDatabase::FixedFont)); } } diff --git a/kasten/gui/io/streamencoder/chars/bytearraycharsstreamencoder.cpp b/kasten/gui/io/streamencoder/chars/bytearraycharsstreamencoder.cpp index 76848202..b4a10a68 100644 --- a/kasten/gui/io/streamencoder/chars/bytearraycharsstreamencoder.cpp +++ b/kasten/gui/io/streamencoder/chars/bytearraycharsstreamencoder.cpp @@ -1,82 +1,82 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraycharsstreamencoder.hpp" // lib #include // Okteta core #include #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { CharsStreamEncoderSettings::CharsStreamEncoderSettings() = default; ByteArrayCharsStreamEncoder::ByteArrayCharsStreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "Characters"), QStringLiteral("text/plain")) {} ByteArrayCharsStreamEncoder::~ByteArrayCharsStreamEncoder() = default; bool ByteArrayCharsStreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { bool success = true; // settings mSettings.codecName = byteArrayView->charCodingName(); mSettings.undefinedChar = byteArrayView->undefinedChar(); mSettings.substituteChar = byteArrayView->substituteChar(); // encode QTextStream textStream(device); Okteta::CharCodec* charCodec = Okteta::CharCodec::createCodec(mSettings.codecName); const QChar tabChar = QLatin1Char('\t'); const QChar returnChar = QLatin1Char('\n'); for (Okteta::Address i = range.start(); i <= range.end(); ++i) { const Okteta::Character byteChar = charCodec->decode(byteArrayModel->byte(i)); const QChar streamChar = byteChar.isUndefined() ? mSettings.undefinedChar : (!byteChar.isPrint() || byteChar == tabChar || byteChar == returnChar) ? mSettings.substituteChar : (QChar)byteChar; textStream << streamChar; } // clean up delete charCodec; return success; } } diff --git a/kasten/gui/io/streamencoder/ihex/bytearrayihexstreamencoder.cpp b/kasten/gui/io/streamencoder/ihex/bytearrayihexstreamencoder.cpp index ed60c44c..6b849ee8 100644 --- a/kasten/gui/io/streamencoder/ihex/bytearrayihexstreamencoder.cpp +++ b/kasten/gui/io/streamencoder/ihex/bytearrayihexstreamencoder.cpp @@ -1,195 +1,195 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayihexstreamencoder.hpp" // lib #include // Okteta gui #include // Okteta core #include -// KF5 +// KF #include // Qt #include namespace Kasten { IHexStreamEncoderSettings::IHexStreamEncoderSettings() = default; const char ByteArrayIHexStreamEncoder::hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; void ByteArrayIHexStreamEncoder::streamLine(QTextStream& textStream, const unsigned char* line) { // checksum is two's complement of sum of the values in the line unsigned char checksum = 0; textStream << startCode; const uint length = byteCountLineSize + addressLineSize + recordTypeLineSize + line[0]; for (uint i = 0; i < length; ++i) { const unsigned char byte = line[i]; textStream << hexValueOfNibble(byte >> 4) << hexValueOfNibble(byte); checksum += byte; } checksum = (checksum ^ 0xFF) + 1; textStream << hexValueOfNibble(checksum >> 4) << hexValueOfNibble(checksum) << '\n'; } void ByteArrayIHexStreamEncoder::streamExtendedSegmentAddress(QTextStream& textStream, unsigned char* line, quint16 upperSegmentBaseAddress) { constexpr int nullAddress = 0; constexpr int upperSegmentBaseAddressSize = 2; line[byteCountLineOffset] = upperSegmentBaseAddressSize; writeBigEndian(&line[addressLineOffset], nullAddress, addressLineSize); line[recordTypeLineOffset] = extendedSegmentAddressRecordCode; line[dataLineOffset] = upperSegmentBaseAddress >> 8; line[dataLineOffset + 1] = upperSegmentBaseAddress; streamLine(textStream, line); } void ByteArrayIHexStreamEncoder::streamExtendedLinearAddress(QTextStream& textStream, unsigned char* line, quint16 upperLinearBaseAddress) { constexpr int nullAddress = 0; constexpr int upperLinearBaseAddressSize = 2; line[byteCountLineOffset] = upperLinearBaseAddressSize; writeBigEndian(&line[addressLineOffset], nullAddress, addressLineSize); line[recordTypeLineOffset] = extendedLinearAddressRecordCode; line[dataLineOffset] = upperLinearBaseAddress >> 8; line[dataLineOffset + 1] = upperLinearBaseAddress; streamLine(textStream, line); } void ByteArrayIHexStreamEncoder::streamEndOfFile(QTextStream& textStream, unsigned char* line, quint16 startAddress) { constexpr int endOfFileByteCount = 0; line[byteCountLineOffset] = endOfFileByteCount; writeBigEndian(&line[addressLineOffset], startAddress, addressLineSize); line[recordTypeLineOffset] = endOfFileRecordCode; streamLine(textStream, line); } ByteArrayIHexStreamEncoder::ByteArrayIHexStreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "Intel Hex"), QStringLiteral("text/x-ihex")) {} ByteArrayIHexStreamEncoder::~ByteArrayIHexStreamEncoder() = default; bool ByteArrayIHexStreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { Q_UNUSED(byteArrayView); bool success = true; // encode QTextStream textStream(device); // prepare constexpr int maxDataPerLineCount = 255; constexpr int maxLineLength = maxDataPerLineCount + byteCountLineSize + addressLineSize + recordTypeLineSize; const Okteta::ByteArrayTableLayout layout(byteArrayView->noOfBytesPerLine(), byteArrayView->firstLineOffset(), byteArrayView->startOffset(), 0, byteArrayModel->size()); const Okteta::Coord startCoord = layout.coordOfIndex(range.start()); const int lastLinePosition = layout.lastLinePosition(startCoord.line()); const int dataPerLineCount = qMin(byteArrayView->noOfBytesPerLine(), maxDataPerLineCount); unsigned char line[maxLineLength]; unsigned char* lineData = &line[dataLineOffset]; Okteta::Address lineOffset = range.start(); const int firstDataEnd = lastLinePosition - startCoord.pos() + 1; int nextUpperAddressChangeDataEnd = 0x10000 - (range.start() & 0xFFFF); int d = 0; int nextDataEnd = qMin(dataPerLineCount, qMin(firstDataEnd, nextUpperAddressChangeDataEnd)); // data if (mSettings.addressSizeId == IHexStreamEncoderSettings::AddressSizeId::Bits32) { const quint16 upperLinearBaseAddress = (range.start() >> 16); streamExtendedLinearAddress(textStream, line, upperLinearBaseAddress); } else if (mSettings.addressSizeId == IHexStreamEncoderSettings::AddressSizeId::Bits16) { const quint16 upperSegmentBaseAddress = (range.start() >> 4) & 0xF000; streamExtendedSegmentAddress(textStream, line, upperSegmentBaseAddress); } Okteta::Address i = range.start(); while (i <= range.end()) { const Okteta::Byte byte = byteArrayModel->byte(i); lineData[d] = byte; ++d; ++i; if (d == nextDataEnd) { line[byteCountLineOffset] = d; writeBigEndian(&line[addressLineOffset], lineOffset, addressLineSize); line[recordTypeLineOffset] = dataRecordCode; streamLine(textStream, line); lineOffset = i; if (d == nextUpperAddressChangeDataEnd) { if (mSettings.addressSizeId == IHexStreamEncoderSettings::AddressSizeId::Bits32) { const quint16 upperLinearBaseAddress = (i >> 16); streamExtendedLinearAddress(textStream, line, upperLinearBaseAddress); } else if (mSettings.addressSizeId == IHexStreamEncoderSettings::AddressSizeId::Bits16) { const quint16 upperSegmentBaseAddress = (i >> 4) & 0xF000; streamExtendedSegmentAddress(textStream, line, upperSegmentBaseAddress); } } nextUpperAddressChangeDataEnd = 0x10000 - (i & 0xFFFF); nextDataEnd = qMin(dataPerLineCount, qMin(range.end() - i + 1, nextUpperAddressChangeDataEnd)); d = 0; } } // footer streamEndOfFile(textStream, line); return success; } } diff --git a/kasten/gui/io/streamencoder/ihex/bytearrayihexstreamencoderconfigeditor.cpp b/kasten/gui/io/streamencoder/ihex/bytearrayihexstreamencoderconfigeditor.cpp index 008d1014..75318511 100644 --- a/kasten/gui/io/streamencoder/ihex/bytearrayihexstreamencoderconfigeditor.cpp +++ b/kasten/gui/io/streamencoder/ihex/bytearrayihexstreamencoderconfigeditor.cpp @@ -1,81 +1,81 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayihexstreamencoderconfigeditor.hpp" // lib #include "bytearraytextstreamencoderpreview.hpp" -// KF5 +// KF #include #include // Qt #include #include namespace Kasten { ByteArrayIHexStreamEncoderConfigEditor::ByteArrayIHexStreamEncoderConfigEditor(ByteArrayIHexStreamEncoder* encoder, QWidget* parent) : AbstractModelStreamEncoderConfigEditor(parent) , mEncoder(encoder) { mSettings = mEncoder->settings(); auto* pageLayout = new QFormLayout(this); pageLayout->setContentsMargins(0, 0, 0, 0); // data type const QString addressSizeLabel = i18nc("@label:listbox the size in bits of the addresses.", "Address size:"); mAddressSizeSelect = new KComboBox(this); // keep order in sync with IHexStreamEncoderSettings::AddressSizeId const QStringList addressSizeList { i18nc("@item:inmenu address size", "32-bit"), i18nc("@item:inmenu address size", "16-bit"), i18nc("@item:inmenu address size", "8-bit"), }; mAddressSizeSelect->addItems(addressSizeList); mAddressSizeSelect->setCurrentIndex(static_cast(mSettings.addressSizeId)); connect(mAddressSizeSelect, QOverload::of(&KComboBox::activated), this, &ByteArrayIHexStreamEncoderConfigEditor::onSettingsChanged); pageLayout->addRow(addressSizeLabel, mAddressSizeSelect); } ByteArrayIHexStreamEncoderConfigEditor::~ByteArrayIHexStreamEncoderConfigEditor() = default; AbstractSelectionView* ByteArrayIHexStreamEncoderConfigEditor::createPreviewView() const { return new ByteArrayTextStreamEncoderPreview(mEncoder); } void ByteArrayIHexStreamEncoderConfigEditor::onSettingsChanged() { mSettings.addressSizeId = static_cast(mAddressSizeSelect->currentIndex()); mEncoder->setSettings(mSettings); } } diff --git a/kasten/gui/io/streamencoder/sourcecode/bytearraysourcecodestreamencoder.cpp b/kasten/gui/io/streamencoder/sourcecode/bytearraysourcecodestreamencoder.cpp index b7f04b71..e9a29c17 100644 --- a/kasten/gui/io/streamencoder/sourcecode/bytearraysourcecodestreamencoder.cpp +++ b/kasten/gui/io/streamencoder/sourcecode/bytearraysourcecodestreamencoder.cpp @@ -1,209 +1,209 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraysourcecodestreamencoder.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include namespace Kasten { static constexpr const char* PrimitiveDataTypeName[] = { "char", "unsigned char", "short", "unsigned short", "int", "unsigned int", "float", "double" }; static constexpr int SizeOfPrimitiveDataType[] = { sizeof(char), sizeof(unsigned char), sizeof(short), sizeof(unsigned short), sizeof(int), sizeof(unsigned int), sizeof(float), sizeof(double) }; static constexpr int NoOfPrimitiveDataTypes = 8; inline QString decimalFormattedNumberPlaceHolder() { return QStringLiteral("%1"); } inline QString hexadecimalFormattedNumberPlaceHolder() { return QStringLiteral("0x%1"); } SourceCodeStreamEncoderSettings::SourceCodeStreamEncoderSettings() : variableName(QStringLiteral("array")) {} ByteArraySourceCodeStreamEncoder::ByteArraySourceCodeStreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "C Array"), QStringLiteral("text/x-csrc")) {} ByteArraySourceCodeStreamEncoder::~ByteArraySourceCodeStreamEncoder() = default; const char* const* ByteArraySourceCodeStreamEncoder::dataTypeNames() const { return PrimitiveDataTypeName; } int ByteArraySourceCodeStreamEncoder::dataTypesCount() const { return NoOfPrimitiveDataTypes; } bool ByteArraySourceCodeStreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { Q_UNUSED(byteArrayView) bool success = true; // encode QTextStream textStream(device); // textStream << "// from File , selection \n"; const int size = range.width(); const int dataTypeSize = SizeOfPrimitiveDataType[static_cast(mSettings.dataType)]; const int sizeOfArray = (size + dataTypeSize - 1) / dataTypeSize; textStream << "const " << QLatin1String(PrimitiveDataTypeName[static_cast(mSettings.dataType)]) << ' ' << mSettings.variableName << '[' << sizeOfArray << "] =" << endl << '{' << endl; int elementAddedOnLine = 0; for (Okteta::Address i = range.start(); i <= range.end(); i += dataTypeSize) { if (elementAddedOnLine == 0) { textStream << " "; // just 3, one space before every datum } textStream << ' ' << printFormatted(byteArrayModel, i, range.end() - i + 1); if (i + dataTypeSize <= range.end()) { textStream << ','; } if (++elementAddedOnLine >= mSettings.elementsPerLine) { textStream << endl; elementAddedOnLine = 0; } } if (elementAddedOnLine > 0) { textStream << endl; } textStream << "};" << endl; return success; } QString ByteArraySourceCodeStreamEncoder::printFormatted(const Okteta::AbstractByteArrayModel* byteArrayModel, Okteta::Address offset, unsigned int dataSize) const { QString result; switch (mSettings.dataType) { case SourceCodeStreamEncoderSettings::PrimitiveDataType::Char: { char e = 0; byteArrayModel->copyTo(reinterpret_cast(&e), offset, qMin(sizeof(e), dataSize)); constexpr int fieldWidth = 4; result = decimalFormattedNumberPlaceHolder().arg((int)e, fieldWidth); break; } case SourceCodeStreamEncoderSettings::PrimitiveDataType::UnsignedChar: { unsigned char e = 0; byteArrayModel->copyTo(reinterpret_cast(&e), offset, qMin(uint(sizeof(e)), dataSize)); const int base = mSettings.unsignedAsHexadecimal ? 16 : 10; const int fieldWidth = mSettings.unsignedAsHexadecimal ? 2 : 3; const QString formattedNumberPlaceHolder = mSettings.unsignedAsHexadecimal ? hexadecimalFormattedNumberPlaceHolder() : decimalFormattedNumberPlaceHolder(); const QChar stuffChar = QLatin1Char(mSettings.unsignedAsHexadecimal ? '0' : ' '); result = formattedNumberPlaceHolder.arg(e, fieldWidth, base, stuffChar); break; } case SourceCodeStreamEncoderSettings::PrimitiveDataType::Short: { short e = 0; byteArrayModel->copyTo(reinterpret_cast(&e), offset, qMin(uint(sizeof(e)), dataSize)); constexpr int fieldWidth = 6; result = decimalFormattedNumberPlaceHolder().arg(e, fieldWidth); break; } case SourceCodeStreamEncoderSettings::PrimitiveDataType::UnsignedShort: { unsigned short e = 0; byteArrayModel->copyTo(reinterpret_cast(&e), offset, qMin(uint(sizeof(e)), dataSize)); const int base = mSettings.unsignedAsHexadecimal ? 16 : 10; const int fieldWidth = mSettings.unsignedAsHexadecimal ? 4 : 5; const QString formattedNumberPlaceHolder = mSettings.unsignedAsHexadecimal ? hexadecimalFormattedNumberPlaceHolder() : decimalFormattedNumberPlaceHolder(); const QChar stuffChar = QLatin1Char(mSettings.unsignedAsHexadecimal ? '0' : ' '); result = formattedNumberPlaceHolder.arg(e, fieldWidth, base, stuffChar); break; } case SourceCodeStreamEncoderSettings::PrimitiveDataType::Integer: { int e = 0; byteArrayModel->copyTo(reinterpret_cast(&e), offset, qMin(uint(sizeof(e)), dataSize)); constexpr int fieldWidth = 11; result = decimalFormattedNumberPlaceHolder().arg(e, fieldWidth); break; } case SourceCodeStreamEncoderSettings::PrimitiveDataType::UnsignedInteger: { unsigned int e = 0; byteArrayModel->copyTo(reinterpret_cast(&e), offset, qMin(uint(sizeof(e)), dataSize)); const int base = mSettings.unsignedAsHexadecimal ? 16 : 10; const int fieldWidth = mSettings.unsignedAsHexadecimal ? 8 : 10; const QString formattedNumberPlaceHolder = mSettings.unsignedAsHexadecimal ? hexadecimalFormattedNumberPlaceHolder() : decimalFormattedNumberPlaceHolder(); const QChar stuffChar = QLatin1Char(mSettings.unsignedAsHexadecimal ? '0' : ' '); result = formattedNumberPlaceHolder.arg(e, fieldWidth, base, stuffChar); break; } case SourceCodeStreamEncoderSettings::PrimitiveDataType::Float: { float e = 0; byteArrayModel->copyTo(reinterpret_cast(&e), offset, qMin(uint(sizeof(e)), dataSize)); constexpr int fieldWidth = 13; result = decimalFormattedNumberPlaceHolder().arg(e, fieldWidth); break; } case SourceCodeStreamEncoderSettings::PrimitiveDataType::Double: { double e = 0; byteArrayModel->copyTo(reinterpret_cast(&e), offset, qMin(uint(sizeof(e)), dataSize)); constexpr int fieldWidth = 13; result = decimalFormattedNumberPlaceHolder().arg(e, fieldWidth); break; } } return result; } } diff --git a/kasten/gui/io/streamencoder/sourcecode/bytearraysourcecodestreamencoderconfigeditor.cpp b/kasten/gui/io/streamencoder/sourcecode/bytearraysourcecodestreamencoderconfigeditor.cpp index f554f6ea..90d59380 100644 --- a/kasten/gui/io/streamencoder/sourcecode/bytearraysourcecodestreamencoderconfigeditor.cpp +++ b/kasten/gui/io/streamencoder/sourcecode/bytearraysourcecodestreamencoderconfigeditor.cpp @@ -1,123 +1,123 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraysourcecodestreamencoderconfigeditor.hpp" // lib #include "bytearraytextstreamencoderpreview.hpp" -// KF5 +// KF #include #include // Qt #include #include #include #include namespace Kasten { ByteArraySourceCodeStreamEncoderConfigEditor::ByteArraySourceCodeStreamEncoderConfigEditor(ByteArraySourceCodeStreamEncoder* encoder, QWidget* parent) : AbstractModelStreamEncoderConfigEditor(parent) , mEncoder(encoder) { mSettings = mEncoder->settings(); auto* pageLayout = new QFormLayout(this); pageLayout->setContentsMargins(0, 0, 0, 0); // variable name const QString variableNameLabel = i18nc("@label:textbox name of the created variable", "Name of variable:"); mVariableNameEdit = new QLineEdit(this); mVariableNameEdit->setClearButtonEnabled(true); mVariableNameEdit->setText(mSettings.variableName); connect(mVariableNameEdit, &QLineEdit::textChanged, this, &ByteArraySourceCodeStreamEncoderConfigEditor::onSettingsChanged); pageLayout->addRow(variableNameLabel, mVariableNameEdit); // items per line const QString itemsPerLineLabel = i18nc("@label:textbox to define after how many items the list is wrapped", "Items per line:"); mItemsPerLineEdit = new QSpinBox(this); mItemsPerLineEdit->setMinimum(1); mItemsPerLineEdit->setValue(mSettings.elementsPerLine); connect(mItemsPerLineEdit, QOverload::of(&QSpinBox::valueChanged), this, &ByteArraySourceCodeStreamEncoderConfigEditor::onSettingsChanged); pageLayout->addRow(itemsPerLineLabel, mItemsPerLineEdit); // data type const QString dataTypeLabel = i18nc("@label:listbox the type of the data: char, integer, etc.", "Data type:"); mDataTypeSelect = new KComboBox(this); const char* const* dataTypeNames = mEncoder->dataTypeNames(); const int dataTypesCount = mEncoder->dataTypesCount(); QStringList dataTypeNameStrings; dataTypeNameStrings.reserve(dataTypesCount); for (int i = 0; i < dataTypesCount; ++i) { dataTypeNameStrings << QLatin1String(dataTypeNames[i]); } mDataTypeSelect->addItems(dataTypeNameStrings); mDataTypeSelect->setCurrentIndex(static_cast(mSettings.dataType)); connect(mDataTypeSelect, QOverload::of(&KComboBox::activated), this, &ByteArraySourceCodeStreamEncoderConfigEditor::onSettingsChanged); pageLayout->addRow(dataTypeLabel, mDataTypeSelect); // unsigned as hexadezimal const QString unsignedAsHexadecimalLabel = i18nc("@option:check Encode the values in hexadecimal instead of decimal, " "if the datatype has the property Unsigned", "Unsigned as hexadecimal:"); mUnsignedAsHexadecimalCheck = new QCheckBox(this); mUnsignedAsHexadecimalCheck->setChecked(mSettings.unsignedAsHexadecimal); connect(mUnsignedAsHexadecimalCheck, &QCheckBox::toggled, this, &ByteArraySourceCodeStreamEncoderConfigEditor::onSettingsChanged); pageLayout->addRow(unsignedAsHexadecimalLabel, mUnsignedAsHexadecimalCheck); } ByteArraySourceCodeStreamEncoderConfigEditor::~ByteArraySourceCodeStreamEncoderConfigEditor() = default; bool ByteArraySourceCodeStreamEncoderConfigEditor::isValid() const { return true; // TODO: warn if not all selected bytes are used due to the data type length } AbstractSelectionView* ByteArraySourceCodeStreamEncoderConfigEditor::createPreviewView() const { return new ByteArrayTextStreamEncoderPreview(mEncoder); } void ByteArraySourceCodeStreamEncoderConfigEditor::onSettingsChanged() { mSettings.variableName = mVariableNameEdit->text(); mSettings.elementsPerLine = mItemsPerLineEdit->value(); mSettings.dataType = static_cast(mDataTypeSelect->currentIndex()); mSettings.unsignedAsHexadecimal = mUnsignedAsHexadecimalCheck->isChecked(); mEncoder->setSettings(mSettings); } } diff --git a/kasten/gui/io/streamencoder/srec/bytearraysrecstreamencoder.cpp b/kasten/gui/io/streamencoder/srec/bytearraysrecstreamencoder.cpp index 3cf6d87d..7056edee 100644 --- a/kasten/gui/io/streamencoder/srec/bytearraysrecstreamencoder.cpp +++ b/kasten/gui/io/streamencoder/srec/bytearraysrecstreamencoder.cpp @@ -1,203 +1,203 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraysrecstreamencoder.hpp" // lib #include // Okteta gui #include // Okteta core #include -// KF5 +// KF #include // Qt #include namespace Kasten { static inline constexpr int addressSize(SRecStreamEncoderSettings::AddressSizeId id) { return 4 - static_cast(id); } SRecStreamEncoderSettings::SRecStreamEncoderSettings() = default; const char ByteArraySRecStreamEncoder::hexDigits[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; void ByteArraySRecStreamEncoder::streamLine(QTextStream& textStream, RecordType recordType, const unsigned char* line) { // checksum is ones' complement of sum of the values in the line unsigned char checksum = 0; textStream << startCode << charOfRecordType(recordType); const uint length = line[0]; for (uint i = 0; i < length; ++i) { const unsigned char byte = line[i]; textStream << hexValueOfNibble(byte >> 4) << hexValueOfNibble(byte); checksum += byte; } checksum = ~checksum; textStream << hexValueOfNibble(checksum >> 4) << hexValueOfNibble(checksum) << '\n'; } void ByteArraySRecStreamEncoder::streamBlockHeader(QTextStream& textStream, unsigned char* line) // const char* moduleName = 0, const char* description = 0, // quint8 version = 0, quint8 revision = 0 ) { // cmp. https://linux.die.net/man/1/srec_cat // WP says: vendor specific data rather than program data // constexpr int moduleNameLineOffset = 3; // constexpr int moduleNameLength = 10; // constexpr int versionLineOffset = moduleNameLineOffset + moduleNameLength; // constexpr int versionLength = 1; // constexpr int revisionLineOffset = versionLineOffset + versionLength; // constexpr int revisionLength = 1; // constexpr int descriptionLineOffset = revisionLineOffset + revisionLength; // constexpr int descriptionLength = 18; constexpr int headerByteCount = 3; line[addressLineOffset] = 0; // address unused line[addressLineOffset + 1] = 0; // address unused // leave data empty for now line[byteCountLineOffset] = headerByteCount; streamLine(textStream, RecordType::BlockHeader, line); } void ByteArraySRecStreamEncoder::streamRecordCount(QTextStream& textStream, unsigned char* line, quint16 recordCount) { constexpr int recordCountLineSize = 2; constexpr int recordCountByteCount = byteCountLineSize + recordCountLineSize; line[byteCountLineOffset] = recordCountByteCount; writeBigEndian(&line[addressLineOffset], recordCount, recordCountLineSize); streamLine(textStream, RecordType::RecordCount, line); } // from M68000PRM.pdf: // comp. with tty 28 bytes are max (with 3b address) // terminated with CR if downloading // s-record may have some initial field, e.g. for line-number // end of x-block: The address field may optionally contain the x-byte address of the instruction to which control is to be passed. // Under VERSAdos, the resident linkerOs ENTRY command can be used to // specify this address. If this address is not specified, the first entry point speci- // fication encountered in the object module input will be used. There is no code/ // data field. // TODO: recordType is not limited to valid values, also brings recalculation of addressLineSize void ByteArraySRecStreamEncoder::streamBlockEnd(QTextStream& textStream, unsigned char* line, RecordType recordType, quint32 startAddress) { const int addressLineSize = endOfBlockAddressSize(recordType); const int blockEndByteCount = byteCountLineSize + addressLineSize; line[byteCountLineOffset] = blockEndByteCount; writeBigEndian(&line[addressLineOffset], startAddress, addressLineSize); streamLine(textStream, recordType, line); } ByteArraySRecStreamEncoder::ByteArraySRecStreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "S-Record"), QStringLiteral("text/x-srecord")) {} ByteArraySRecStreamEncoder::~ByteArraySRecStreamEncoder() = default; bool ByteArraySRecStreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { Q_UNUSED(byteArrayView); bool success = true; // encode QTextStream textStream(device); // prepare constexpr int maxLineLength = 64 / 2; const int addressLineSize = addressSize(mSettings.addressSizeId); const int maxDataPerLineCount = maxLineLength - byteCountLineSize - addressLineSize; const int dataLineOffset = addressLineOffset + addressLineSize; const Okteta::ByteArrayTableLayout layout(byteArrayView->noOfBytesPerLine(), byteArrayView->firstLineOffset(), byteArrayView->startOffset(), 0, byteArrayModel->size()); const Okteta::Coord startCoord = layout.coordOfIndex(range.start()); const int lastLinePosition = layout.lastLinePosition(startCoord.line()); const int dataPerLineCount = qMin(byteArrayView->noOfBytesPerLine(), maxDataPerLineCount); const RecordType dataSequenceType = dataSequenceRecordType(mSettings.addressSizeId); const RecordType endOfBlockType = endOfBlockRecordType(mSettings.addressSizeId); unsigned char line[maxLineLength]; unsigned char* const lineData = &line[dataLineOffset]; const int firstDataEnd = lastLinePosition - startCoord.pos() + 1; int d = 0; int nextDataEnd = qMin(firstDataEnd, dataPerLineCount); Okteta::Address recordOffset = range.start(); int recordCount = 0; // header streamBlockHeader(textStream, line); Okteta::Address i = range.start(); while (i <= range.end()) { const Okteta::Byte byte = byteArrayModel->byte(i); lineData[d] = byte; ++d; ++i; if (d == nextDataEnd) { line[byteCountLineOffset] = d + 1 + addressLineSize; writeBigEndian(&line[addressLineOffset], recordOffset, addressLineSize); streamLine(textStream, dataSequenceType, line); ++recordCount; recordOffset = i; d = 0; nextDataEnd = qMin(range.end() - i + 1, dataPerLineCount); } } // footer streamRecordCount(textStream, line, recordCount); streamBlockEnd(textStream, line, endOfBlockType); return success; } } diff --git a/kasten/gui/io/streamencoder/srec/bytearraysrecstreamencoderconfigeditor.cpp b/kasten/gui/io/streamencoder/srec/bytearraysrecstreamencoderconfigeditor.cpp index 7e2657c0..8f3f4a01 100644 --- a/kasten/gui/io/streamencoder/srec/bytearraysrecstreamencoderconfigeditor.cpp +++ b/kasten/gui/io/streamencoder/srec/bytearraysrecstreamencoderconfigeditor.cpp @@ -1,80 +1,80 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraysrecstreamencoderconfigeditor.hpp" // lib #include "bytearraytextstreamencoderpreview.hpp" -// KF5 +// KF #include #include // Qt #include #include namespace Kasten { ByteArraySRecStreamEncoderConfigEditor::ByteArraySRecStreamEncoderConfigEditor(ByteArraySRecStreamEncoder* encoder, QWidget* parent) : AbstractModelStreamEncoderConfigEditor(parent) , mEncoder(encoder) { mSettings = mEncoder->settings(); auto* pageLayout = new QFormLayout(this); pageLayout->setContentsMargins(0, 0, 0, 0); // data type const QString addressSizeLabel = i18nc("@label:listbox the size in bits of the addresses.", "Address size:"); mAddressSizeSelect = new KComboBox(this); const QStringList list { i18nc("@item:inmenu address size", "32-bit"), i18nc("@item:inmenu address size", "24-bit"), i18nc("@item:inmenu address size", "16-bit"), }; mAddressSizeSelect->addItems(list); mAddressSizeSelect->setCurrentIndex(static_cast(mSettings.addressSizeId)); connect(mAddressSizeSelect, QOverload::of(&KComboBox::activated), this, &ByteArraySRecStreamEncoderConfigEditor::onSettingsChanged); pageLayout->addRow(addressSizeLabel, mAddressSizeSelect); } ByteArraySRecStreamEncoderConfigEditor::~ByteArraySRecStreamEncoderConfigEditor() = default; AbstractSelectionView* ByteArraySRecStreamEncoderConfigEditor::createPreviewView() const { return new ByteArrayTextStreamEncoderPreview(mEncoder); } void ByteArraySRecStreamEncoderConfigEditor::onSettingsChanged() { mSettings.addressSizeId = static_cast(mAddressSizeSelect->currentIndex()); mEncoder->setSettings(mSettings); } } diff --git a/kasten/gui/io/streamencoder/uuencoding/bytearrayuuencodingstreamencoder.cpp b/kasten/gui/io/streamencoder/uuencoding/bytearrayuuencodingstreamencoder.cpp index 744dc38d..15f7d9d4 100644 --- a/kasten/gui/io/streamencoder/uuencoding/bytearrayuuencodingstreamencoder.cpp +++ b/kasten/gui/io/streamencoder/uuencoding/bytearrayuuencodingstreamencoder.cpp @@ -1,170 +1,170 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayuuencodingstreamencoder.hpp" // lib #include "../base64/bytearraybase64streamencoder.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include namespace Kasten { static constexpr int defaultUuInputLineLength = 45; static constexpr int uuInputLineLength = defaultUuInputLineLength; static constexpr int uuInputGroupLength = 3; static constexpr int maxInputGroupsPerLine = uuInputLineLength / uuInputGroupLength; static inline constexpr char uumapByteHistorical(char byte) { return (byte > 0) ? (byte + 32) : '`'; } static inline char uumapByteBase64(char byte) { return base64EncodeMap[(int)byte]; } struct UumapEncodeData { char (* mapByte)(char); const char* header; const char* footer; const char* paddingData[2]; bool hasLength; inline const char* padding(ByteArrayUuencodingStreamEncoder::InputByteIndex index) const { return paddingData[static_cast(index) - 1]; } }; static constexpr UumapEncodeData historicalUumapEncodeData = { &uumapByteHistorical, "begin", "\n`\nend\n", {"``", "`"}, true }; static constexpr UumapEncodeData base64UumapEncodeData = { &uumapByteBase64, "begin-base64", "\n====\n", {"==", "="}, false }; UuencodingStreamEncoderSettings::UuencodingStreamEncoderSettings() : fileName(QStringLiteral("okteta-export")) {} ByteArrayUuencodingStreamEncoder::ByteArrayUuencodingStreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "Uuencoding"), QStringLiteral("text/x-uuencode")) {} ByteArrayUuencodingStreamEncoder::~ByteArrayUuencodingStreamEncoder() = default; bool ByteArrayUuencodingStreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { Q_UNUSED(byteArrayView); bool success = true; // encode QTextStream textStream(device); // prepare InputByteIndex inputByteIndex = InputByteIndex::First; int inputGroupsPerLine = 0; unsigned char bitsFromLastByte; const UumapEncodeData* encodeData = (mSettings.algorithmId == UuencodingStreamEncoderSettings::AlgorithmId::Historical) ? &historicalUumapEncodeData : /* else */ &base64UumapEncodeData; // header textStream << encodeData->header << " 644 " << mSettings.fileName.toLatin1(); const int firstLineLength = qMin(range.width(), uuInputLineLength); if (firstLineLength > 0) { textStream << '\n'; if (encodeData->hasLength) { textStream << encodeData->mapByte(firstLineLength); } } for (Okteta::Address i = range.start(); i <= range.end(); ++i) { const Okteta::Byte byte = byteArrayModel->byte(i); switch (inputByteIndex) { case InputByteIndex::First: // bits 7..2 textStream << encodeData->mapByte(byte >> 2); // bits 1..0 -> 5..4 for next bitsFromLastByte = (byte & 0x3) << 4; inputByteIndex = InputByteIndex::Second; break; case InputByteIndex::Second: // from last and bits 7..4 as 3..0 from this textStream << encodeData->mapByte(bitsFromLastByte | byte >> 4); // bits 3..0 -> 5..2 for next bitsFromLastByte = (byte & 0xf) << 2; inputByteIndex = InputByteIndex::Third; break; case InputByteIndex::Third: // from last and bits 7..6 as 1..0 from this textStream << encodeData->mapByte(bitsFromLastByte | byte >> 6); // bits 5..0 textStream << encodeData->mapByte(byte & 0x3F); inputByteIndex = InputByteIndex::First; ++inputGroupsPerLine; if (inputGroupsPerLine >= maxInputGroupsPerLine && i < range.end()) { const int remainsCount = range.end() - i; const int nextLineLength = qMin(remainsCount, uuInputLineLength); textStream << '\n'; if (encodeData->hasLength) { textStream << encodeData->mapByte(nextLineLength); } inputGroupsPerLine = 0; } break; } } const bool hasBitsLeft = (inputByteIndex != InputByteIndex::First); if (hasBitsLeft) { textStream << encodeData->mapByte(bitsFromLastByte) << encodeData->padding(inputByteIndex); } // footer textStream << encodeData->footer; return success; } } diff --git a/kasten/gui/io/streamencoder/uuencoding/bytearrayuuencodingstreamencoderconfigeditor.cpp b/kasten/gui/io/streamencoder/uuencoding/bytearrayuuencodingstreamencoderconfigeditor.cpp index 18745ca4..1cb8cbb9 100644 --- a/kasten/gui/io/streamencoder/uuencoding/bytearrayuuencodingstreamencoderconfigeditor.cpp +++ b/kasten/gui/io/streamencoder/uuencoding/bytearrayuuencodingstreamencoderconfigeditor.cpp @@ -1,91 +1,91 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayuuencodingstreamencoderconfigeditor.hpp" // lib #include "bytearraytextstreamencoderpreview.hpp" -// KF5 +// KF #include #include // Qt #include #include #include namespace Kasten { ByteArrayUuencodingStreamEncoderConfigEditor::ByteArrayUuencodingStreamEncoderConfigEditor(ByteArrayUuencodingStreamEncoder* encoder, QWidget* parent) : AbstractModelStreamEncoderConfigEditor(parent) , mEncoder(encoder) { mSettings = mEncoder->settings(); auto* pageLayout = new QFormLayout(this); pageLayout->setContentsMargins(0, 0, 0, 0); // internal file name const QString fileNameLabel = i18nc("@label:textbox file name internally given to the encoded data", "Internal name of file:"); mFileNameEdit = new QLineEdit(this); mFileNameEdit->setClearButtonEnabled(true); mFileNameEdit->setText(mSettings.fileName); connect(mFileNameEdit, &QLineEdit::textChanged, this, &ByteArrayUuencodingStreamEncoderConfigEditor::onSettingsChanged); pageLayout->addRow(fileNameLabel, mFileNameEdit); // data type const QString encodingTypeLabel = i18nc("@label:listbox the type of the used encoding: historical or Base64.", "Encoding:"); mEncodingSelect = new KComboBox(this); const QStringList list { i18nc("@item:inmenu Doing the uuencoding using the historical encoding", "Historical"), i18nc("@item:inmenu Doing the uuencoding using the base64 encoding", "Base64"), }; mEncodingSelect->addItems(list); mEncodingSelect->setCurrentIndex(static_cast(mSettings.algorithmId)); connect(mEncodingSelect, QOverload::of(&KComboBox::activated), this, &ByteArrayUuencodingStreamEncoderConfigEditor::onSettingsChanged); pageLayout->addRow(encodingTypeLabel, mEncodingSelect); } ByteArrayUuencodingStreamEncoderConfigEditor::~ByteArrayUuencodingStreamEncoderConfigEditor() = default; AbstractSelectionView* ByteArrayUuencodingStreamEncoderConfigEditor::createPreviewView() const { return new ByteArrayTextStreamEncoderPreview(mEncoder); } void ByteArrayUuencodingStreamEncoderConfigEditor::onSettingsChanged() { mSettings.algorithmId = static_cast(mEncodingSelect->currentIndex()); mSettings.fileName = mFileNameEdit->text(); mEncoder->setSettings(mSettings); } } diff --git a/kasten/gui/io/streamencoder/values/bytearrayvaluesstreamencoder.cpp b/kasten/gui/io/streamencoder/values/bytearrayvaluesstreamencoder.cpp index b39db0fe..e3f09899 100644 --- a/kasten/gui/io/streamencoder/values/bytearrayvaluesstreamencoder.cpp +++ b/kasten/gui/io/streamencoder/values/bytearrayvaluesstreamencoder.cpp @@ -1,84 +1,84 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayvaluesstreamencoder.hpp" // lib #include // Okteta core #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { ValuesStreamEncoderSettings::ValuesStreamEncoderSettings() : separation(QStringLiteral(" ")) {} ByteArrayValuesStreamEncoder::ByteArrayValuesStreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "Values"), QStringLiteral("text/plain")) {} ByteArrayValuesStreamEncoder::~ByteArrayValuesStreamEncoder() = default; bool ByteArrayValuesStreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { bool success = true; // settings mSettings.undefinedChar = byteArrayView->undefinedChar(); mSettings.substituteChar = byteArrayView->substituteChar(); mSettings.valueCoding = (Okteta::ValueCoding)byteArrayView->valueCoding(); // encode QTextStream textStream(device); Okteta::ValueCodec* valueCodec = Okteta::ValueCodec::createCodec(mSettings.valueCoding); // prepare QString valueString; valueString.resize(valueCodec->encodingWidth()); for (Okteta::Address i = range.start(); i <= range.end(); ++i) { if (i > range.start()) { textStream << mSettings.separation; } valueCodec->encode(&valueString, 0, byteArrayModel->byte(i)); textStream << valueString; } // clean up delete valueCodec; return success; } } diff --git a/kasten/gui/io/streamencoder/values/bytearrayvaluesstreamencoderconfigeditor.cpp b/kasten/gui/io/streamencoder/values/bytearrayvaluesstreamencoderconfigeditor.cpp index eed040c8..59f19ae7 100644 --- a/kasten/gui/io/streamencoder/values/bytearrayvaluesstreamencoderconfigeditor.cpp +++ b/kasten/gui/io/streamencoder/values/bytearrayvaluesstreamencoderconfigeditor.cpp @@ -1,93 +1,93 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayvaluesstreamencoderconfigeditor.hpp" // lib #include "bytearraytextstreamencoderpreview.hpp" -// KF5 +// KF #include // #include // Qt #include #include #include namespace Kasten { ByteArrayValuesStreamEncoderConfigEditor::ByteArrayValuesStreamEncoderConfigEditor(ByteArrayValuesStreamEncoder* encoder, QWidget* parent) : AbstractModelStreamEncoderConfigEditor(parent) , mEncoder(encoder) { mSettings = mEncoder->settings(); auto* pageLayout = new QGridLayout(this); // unknown rows pageLayout->setContentsMargins(0, 0, 0, 0); pageLayout->setColumnStretch(0, 0); pageLayout->setColumnStretch(1, 0); #if 0 // data type QLabel* label = new QLabel(i18n("Value coding:"), this); pageLayout->addWidget(label, 0, 0, Qt::AlignRight); mValueCodingSelect = new KComboBox(this); QStringList list; list.append(i18nc("@item:inmenu encoding of the bytes as values in the hexadecimal format", "Hexadecimal")); list.append(i18nc("@item:inmenu encoding of the bytes as values in the decimal format", "Decimal")); list.append(i18nc("@item:inmenu encoding of the bytes as values in the octal format", "Octal")); list.append(i18nc("@item:inmenu encoding of the bytes as values in the binary format", "Binary")); mValueCodingSelect->addItems(list); mValueCodingSelect->setCurrentIndex(mSettings.valueCoding); connect(mValueCodingSelect, SIGNAL(activated(int)), SLOT(onSettingsChanged())); pageLayout->addWidget(mValueCodingSelect, 0, 1); #endif // separation string QLabel* label = new QLabel(i18nc("@label:textbox substring which separates the values", "Separation:"), this); pageLayout->addWidget(label, 0, 0, Qt::AlignRight); mSeparationEdit = new QLineEdit(this); mSeparationEdit->setClearButtonEnabled(true); mSeparationEdit->setText(mSettings.separation); connect(mSeparationEdit, &QLineEdit::textChanged, this, &ByteArrayValuesStreamEncoderConfigEditor::onSettingsChanged); pageLayout->addWidget(mSeparationEdit, 0, 1); // finish pageLayout->setRowStretch(2, 10); } ByteArrayValuesStreamEncoderConfigEditor::~ByteArrayValuesStreamEncoderConfigEditor() = default; AbstractSelectionView* ByteArrayValuesStreamEncoderConfigEditor::createPreviewView() const { return new ByteArrayTextStreamEncoderPreview(mEncoder); } void ByteArrayValuesStreamEncoderConfigEditor::onSettingsChanged() { // mSettings.valueCoding = (Okteta::ValueCoding) mValueCodingSelect->currentIndex(); mSettings.separation = mSeparationEdit->text(); mEncoder->setSettings(mSettings); } } diff --git a/kasten/gui/io/streamencoder/viewtext/bytearrayviewtextstreamencoder.cpp b/kasten/gui/io/streamencoder/viewtext/bytearrayviewtextstreamencoder.cpp index 4418450d..5734d99a 100644 --- a/kasten/gui/io/streamencoder/viewtext/bytearrayviewtextstreamencoder.cpp +++ b/kasten/gui/io/streamencoder/viewtext/bytearrayviewtextstreamencoder.cpp @@ -1,162 +1,162 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayviewtextstreamencoder.hpp" // lib #include "offsetcolumntextrenderer.hpp" #include "bordercolumntextrenderer.hpp" #include "valuebytearraycolumntextrenderer.hpp" #include "charbytearraycolumntextrenderer.hpp" #include "bytearrayrowscolumntextrenderer.hpp" #include // Okteta gui #include #include // Okteta core #include #include -// KF5 +// KF #include // Qt #include namespace Kasten { // static constexpr Okteta::OffsetFormat::Format DefaultOffsetFormat = Okteta::OffsetFormat::Hexadecimal; ByteArrayViewTextStreamEncoderSettings::ByteArrayViewTextStreamEncoderSettings() // : offsetFormat(DefaultOffsetFormat) : separation(QStringLiteral(" ")) {} ByteArrayViewTextStreamEncoder::ByteArrayViewTextStreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "View in Plain Text"), QStringLiteral("text/plain")) {} ByteArrayViewTextStreamEncoder::~ByteArrayViewTextStreamEncoder() = default; bool ByteArrayViewTextStreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { bool success = true; // settings mSettings.codecName = byteArrayView->charCodingName(); mSettings.valueCoding = (Okteta::ValueCoding)byteArrayView->valueCoding(); mSettings.undefinedChar = byteArrayView->undefinedChar(); mSettings.substituteChar = byteArrayView->substituteChar(); mSettings.firstLineOffset = byteArrayView->firstLineOffset(); mSettings.startOffset = byteArrayView->startOffset(); mSettings.delta = byteArrayView->noOfBytesPerLine(); const int viewModus = byteArrayView->viewModus(); // setup Okteta::ByteArrayTableLayout layout(byteArrayView->noOfBytesPerLine(), mSettings.firstLineOffset, mSettings.startOffset, 0, byteArrayModel->size()); Okteta::CoordRange coordRange; coordRange.set(layout.coordRangeOfIndizes(range)); const int noOfBytesPerLine = byteArrayView->noOfBytesPerLine(); const int byteSpacingWidth = byteArrayView->byteSpacingWidth(); const int noOfGroupedBytes = byteArrayView->noOfGroupedBytes(); const int visibleByteArrayCodings = byteArrayView->visibleByteArrayCodings(); QVector columnTextRendererList; if (byteArrayView->offsetColumnVisible()) { columnTextRendererList.append( new OffsetColumnTextRenderer(Okteta::OffsetFormat::Hexadecimal, mSettings.firstLineOffset, mSettings.delta)); columnTextRendererList.append(new BorderColumnTextRenderer()); } if (viewModus == 0) { if (visibleByteArrayCodings & Okteta::AbstractByteArrayView::ValueCodingId) { columnTextRendererList.append( new ValueByteArrayColumnTextRenderer(byteArrayModel, range.start(), coordRange, noOfBytesPerLine, byteSpacingWidth, noOfGroupedBytes, mSettings.valueCoding)); } if (visibleByteArrayCodings & Okteta::AbstractByteArrayView::CharCodingId) { if (visibleByteArrayCodings & Okteta::AbstractByteArrayView::ValueCodingId) { columnTextRendererList.append(new BorderColumnTextRenderer()); } columnTextRendererList.append( new CharByteArrayColumnTextRenderer(byteArrayModel, range.start(), coordRange, noOfBytesPerLine, 0, 0, mSettings.codecName, mSettings.substituteChar, mSettings.undefinedChar)); } } else { columnTextRendererList.append( new ByteArrayRowsColumnTextRenderer(byteArrayModel, range.start(), coordRange, noOfBytesPerLine, byteSpacingWidth, noOfGroupedBytes, visibleByteArrayCodings, mSettings.valueCoding, mSettings.codecName, mSettings.substituteChar, mSettings.undefinedChar)); } int subLinesCount = 1; for (const AbstractColumnTextRenderer* renderer : qAsConst(columnTextRendererList)) { if (renderer->noOfSublinesNeeded() > subLinesCount) { subLinesCount = renderer->noOfSublinesNeeded(); } } // encode QTextStream textStream(device); int l = coordRange.start().line(); for (const AbstractColumnTextRenderer* renderer : qAsConst(columnTextRendererList)) { renderer->renderFirstLine(&textStream, l); } textStream << endl; int subLine = 1; while (true) { if (subLine == subLinesCount) { ++l; if (l > coordRange.end().line()) { break; } subLine = 0; } const bool isSubline = (subLine > 0); for (const AbstractColumnTextRenderer* renderer : qAsConst(columnTextRendererList)) { renderer->renderNextLine(&textStream, isSubline); } textStream << endl; ++subLine; } // clean up qDeleteAll(columnTextRendererList); return success; } } diff --git a/kasten/gui/io/streamencoder/xxencoding/bytearrayxxencodingstreamencoder.cpp b/kasten/gui/io/streamencoder/xxencoding/bytearrayxxencodingstreamencoder.cpp index 8799eddc..b6133d01 100644 --- a/kasten/gui/io/streamencoder/xxencoding/bytearrayxxencodingstreamencoder.cpp +++ b/kasten/gui/io/streamencoder/xxencoding/bytearrayxxencodingstreamencoder.cpp @@ -1,146 +1,146 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayxxencodingstreamencoder.hpp" // Okteta core #include -// KF5 +// KF #include // Qt #include namespace Kasten { static constexpr char xxencodeMap[64] = { '+', '-', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; static constexpr const char* paddingData[2] = {"++", "+"}; static constexpr int defaultxxInputLineLength = 45; static constexpr int xxInputLineLength = defaultxxInputLineLength; static constexpr int xxInputGroupLength = 3; static constexpr int maxXxInputGroupsPerLine = xxInputLineLength / xxInputGroupLength; static inline constexpr char xxmapByte(char byte) { return xxencodeMap[static_cast(byte)]; } static inline constexpr const char* xxpadding(ByteArrayXxencodingStreamEncoder::InputByteIndex index) { return paddingData[static_cast(index) - 1]; } XxencodingStreamEncoderSettings::XxencodingStreamEncoderSettings() : fileName(QStringLiteral("okteta-export")) {} ByteArrayXxencodingStreamEncoder::ByteArrayXxencodingStreamEncoder() : AbstractByteArrayStreamEncoder(i18nc("name of the encoding target", "Xxencoding"), QStringLiteral("text/x-xxencode")) {} ByteArrayXxencodingStreamEncoder::~ByteArrayXxencodingStreamEncoder() = default; // TODO: make this algorithm shared with ByteArrayUuencodingStreamEncoder again bool ByteArrayXxencodingStreamEncoder::encodeDataToStream(QIODevice* device, const ByteArrayView* byteArrayView, const Okteta::AbstractByteArrayModel* byteArrayModel, const Okteta::AddressRange& range) { Q_UNUSED(byteArrayView); const char header[] = "begin"; const char footer[] = "\n+\nend\n"; bool success = true; // encode QTextStream textStream(device); // prepare InputByteIndex inputByteIndex = InputByteIndex::First; int inputGroupsPerLine = 0; unsigned char bitsFromLastByte; // header textStream << header << " 644 " << mSettings.fileName.toLatin1(); const int firstLineLength = qMin(range.width(), xxInputLineLength); if (firstLineLength > 0) { textStream << '\n'; textStream << xxmapByte(firstLineLength); } for (Okteta::Address i = range.start(); i <= range.end(); ++i) { const Okteta::Byte byte = byteArrayModel->byte(i); switch (inputByteIndex) { case InputByteIndex::First: // bits 7..2 textStream << xxmapByte(byte >> 2); // bits 1..0 -> 5..4 for next bitsFromLastByte = (byte & 0x3) << 4; inputByteIndex = InputByteIndex::Second; break; case InputByteIndex::Second: // from last and bits 7..4 as 3..0 from this textStream << xxmapByte(bitsFromLastByte | byte >> 4); // bits 3..0 -> 5..2 for next bitsFromLastByte = (byte & 0xf) << 2; inputByteIndex = InputByteIndex::Third; break; case InputByteIndex::Third: // from last and bits 7..6 as 1..0 from this textStream << xxmapByte(bitsFromLastByte | byte >> 6); // bits 5..0 textStream << xxmapByte(byte & 0x3F); inputByteIndex = InputByteIndex::First; ++inputGroupsPerLine; if (inputGroupsPerLine >= maxXxInputGroupsPerLine && i < range.end()) { const int remainsCount = range.end() - i; const int nextLineLength = qMin(remainsCount, xxInputLineLength); textStream << '\n'; textStream << xxmapByte(nextLineLength); inputGroupsPerLine = 0; } break; } } const bool hasBitsLeft = (inputByteIndex != InputByteIndex::First); if (hasBitsLeft) { textStream << xxmapByte(bitsFromLastByte) << xxpadding(inputByteIndex); } // footer textStream << footer; return success; } } diff --git a/kasten/gui/io/streamencoder/xxencoding/bytearrayxxencodingstreamencoderconfigeditor.cpp b/kasten/gui/io/streamencoder/xxencoding/bytearrayxxencodingstreamencoderconfigeditor.cpp index 14a8ffe3..dfd63c0c 100644 --- a/kasten/gui/io/streamencoder/xxencoding/bytearrayxxencodingstreamencoderconfigeditor.cpp +++ b/kasten/gui/io/streamencoder/xxencoding/bytearrayxxencodingstreamencoderconfigeditor.cpp @@ -1,71 +1,71 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayxxencodingstreamencoderconfigeditor.hpp" // lib #include "bytearraytextstreamencoderpreview.hpp" -// KF5 +// KF #include // Qt #include #include #include namespace Kasten { ByteArrayXxencodingStreamEncoderConfigEditor::ByteArrayXxencodingStreamEncoderConfigEditor(ByteArrayXxencodingStreamEncoder* encoder, QWidget* parent) : AbstractModelStreamEncoderConfigEditor(parent) , mEncoder(encoder) { mSettings = mEncoder->settings(); auto* pageLayout = new QFormLayout(this); pageLayout->setContentsMargins(0, 0, 0, 0); // internal file name const QString fileNameLabel = i18nc("@label:textbox file name internally given to the encoded data", "Internal name of file:"); mFileNameEdit = new QLineEdit(this); mFileNameEdit->setClearButtonEnabled(true); mFileNameEdit->setText(mSettings.fileName); connect(mFileNameEdit, &QLineEdit::textChanged, this, &ByteArrayXxencodingStreamEncoderConfigEditor::onSettingsChanged); pageLayout->addRow(fileNameLabel, mFileNameEdit); } ByteArrayXxencodingStreamEncoderConfigEditor::~ByteArrayXxencodingStreamEncoderConfigEditor() = default; AbstractSelectionView* ByteArrayXxencodingStreamEncoderConfigEditor::createPreviewView() const { return new ByteArrayTextStreamEncoderPreview(mEncoder); } void ByteArrayXxencodingStreamEncoderConfigEditor::onSettingsChanged() { mSettings.fileName = mFileNameEdit->text(); mEncoder->setSettings(mSettings); } } diff --git a/kasten/gui/liboktetawidgets/addresscombobox_p.cpp b/kasten/gui/liboktetawidgets/addresscombobox_p.cpp index 65683525..9b1e5be7 100644 --- a/kasten/gui/liboktetawidgets/addresscombobox_p.cpp +++ b/kasten/gui/liboktetawidgets/addresscombobox_p.cpp @@ -1,172 +1,172 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "addresscombobox_p.hpp" #include "addresscombobox.hpp" -// KF5 +// KF #include // Qt #include #include #include /* Problem: what to do if the format is changed for which the current string is not valid? Solution: we always convert the string to the new format, so there is never such a situation */ namespace Okteta { static const QStringList& formatStrings() { static QStringList list = QStringList { // i18nc("@item:inlistbox guessing the format of the address by the input", "Auto"), i18nc("@item:inlistbox coding of offset in the hexadecimal format", "Hex"), i18nc("@item:inlistbox coding of offset in the decimal format", "Dec"), i18nc("@item:inlistbox coding of offset in the expression format", "Expr"), }; return list; } void AddressComboBoxPrivate::init() { Q_Q(AddressComboBox); auto* baseLayout = new QHBoxLayout(q); baseLayout->setContentsMargins(0, 0, 0, 0); baseLayout->setSpacing(0); mFormatComboBox = new KComboBox(q); mFormatComboBox->addItems(formatStrings()); QObject::connect(mFormatComboBox, QOverload::of(&QComboBox::activated), q, [&](int index) { onFormatChanged(index); }); mValueComboBox = new KComboBox(q); mValueComboBox->setEditable(true); mValueComboBox->setMaxCount(10); mValueComboBox->setInsertPolicy(QComboBox::NoInsert); mValueComboBox->setDuplicatesEnabled(false); q->setFocusProxy(mValueComboBox); QObject::connect(mValueComboBox->lineEdit(), &QLineEdit::textEdited, q, [&](const QString& text) { onValueEdited(text); }); QAbstractItemView* formatComboBoxListView = mFormatComboBox->view(); QObject::connect(formatComboBoxListView, &QAbstractItemView::activated, mValueComboBox, QOverload<>::of(&KComboBox::setFocus)); // TODO: is a workaround for Qt 4.5.1 which doesn't emit activated() for mouse clicks QObject::connect(formatComboBoxListView, &QAbstractItemView::pressed, mValueComboBox, QOverload<>::of(&KComboBox::setFocus)); mValidator = new AddressValidator(mValueComboBox, AddressValidator::HexadecimalCoding); const AddressValidator::Coding coding = static_cast(mFormatComboBox->currentIndex()); mValidator->setCodec(coding); mValueComboBox->setValidator(mValidator); QObject::connect(mValueComboBox, QOverload::of(&QComboBox::activated), q, [&](int index) { onValueActivated(index); }); baseLayout->addWidget(mFormatComboBox); baseLayout->addWidget(mValueComboBox, 1); QWidget::setTabOrder(mFormatComboBox, mValueComboBox); } void AddressComboBoxPrivate::rememberCurrentAddress() { // don't insert same value multiple times in a row if (mValueComboBox->itemText(0) != mValueComboBox->currentText()) { mValueComboBox->insertItem(-1, mValueComboBox->currentText(), mFormatComboBox->currentIndex()); } } void AddressComboBoxPrivate::onFormatChanged(int formatIndex) { Q_Q(AddressComboBox); const QString currentValueText = mValueComboBox->currentText(); const bool isCurrentValueTextEmpty = currentValueText.isEmpty(); AddressValidator::AddressType addressType; Address address; if (isCurrentValueTextEmpty) { address = -1; addressType = mAddressType; } else { address = mValidator->toAddress(currentValueText, &addressType); } mValidator->setCodec(static_cast(formatIndex)); if (!isCurrentValueTextEmpty) { const QString convertedValueText = mValidator->toString(address, addressType); mValueComboBox->setEditText(convertedValueText); } if (mAddressType != addressType) { mAddressType = addressType; emit q->addressTypeChanged(mAddressType); } emit q->formatChanged(formatIndex); } void AddressComboBoxPrivate::onValueEdited(const QString& value) { Q_Q(AddressComboBox); AddressValidator::AddressType addressType; const Address address = mValidator->toAddress(value, &addressType); if (mAddressType != addressType) { mAddressType = addressType; emit q->addressTypeChanged(mAddressType); } emit q->addressChanged(address); } void AddressComboBoxPrivate::onValueActivated(int index) { Q_Q(AddressComboBox); if (index != -1) { const int oldFormatIndex = mFormatComboBox->currentIndex(); const int itemFormatIndex = mValueComboBox->itemData(index).toInt(); const bool isOtherFormat = (oldFormatIndex != itemFormatIndex); if (isOtherFormat) { mFormatComboBox->setCurrentIndex(itemFormatIndex); mValidator->setCodec(static_cast(itemFormatIndex)); } const QString currentValueText = mValueComboBox->currentText(); AddressValidator::AddressType addressType; const Address address = mValidator->toAddress(currentValueText, &addressType); if (mAddressType != addressType) { mAddressType = addressType; emit q->addressTypeChanged(mAddressType); } emit q->addressChanged(address); if (isOtherFormat) { emit q->formatChanged(itemFormatIndex); } } } } diff --git a/kasten/gui/liboktetawidgets/addresscombobox_p.hpp b/kasten/gui/liboktetawidgets/addresscombobox_p.hpp index 0d30154d..97cce1b3 100644 --- a/kasten/gui/liboktetawidgets/addresscombobox_p.hpp +++ b/kasten/gui/liboktetawidgets/addresscombobox_p.hpp @@ -1,81 +1,81 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_ADDRESSCOMBOBOX_P_HPP #define KASTEN_ADDRESSCOMBOBOX_P_HPP // lib #include "addresscombobox.hpp" #include "addressvalidator.hpp" -// KF5 +// KF #include namespace Okteta { class AddressComboBoxPrivate { public: explicit AddressComboBoxPrivate(AddressComboBox* parent); public: Address address() const; int format() const; AddressValidator::AddressType addressType() const; public: void init(); void rememberCurrentAddress(); void onFormatChanged(int index); void onValueEdited(const QString& value); void onValueActivated(int index); private: AddressComboBox* const q_ptr; Q_DECLARE_PUBLIC(AddressComboBox) KComboBox * mFormatComboBox; KComboBox* mValueComboBox; AddressValidator::AddressType mAddressType; AddressValidator* mValidator; }; inline AddressComboBoxPrivate::AddressComboBoxPrivate(AddressComboBox* parent) : q_ptr(parent) {} inline Address AddressComboBoxPrivate::address() const { return mValidator->toAddress(mValueComboBox->currentText()); } inline int AddressComboBoxPrivate::format() const { return mFormatComboBox->currentIndex(); } inline AddressValidator::AddressType AddressComboBoxPrivate::addressType() const { return mAddressType; } } #endif diff --git a/kasten/gui/liboktetawidgets/addressvalidator.cpp b/kasten/gui/liboktetawidgets/addressvalidator.cpp index 58e25f6c..fcf881e4 100644 --- a/kasten/gui/liboktetawidgets/addressvalidator.cpp +++ b/kasten/gui/liboktetawidgets/addressvalidator.cpp @@ -1,157 +1,157 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "addressvalidator.hpp" // lib #include // Okteta core #include -// KF5 +// KF #include // Qt #include #include #include #include namespace Okteta { AddressValidator::AddressValidator(QObject* parent, Coding codecId) : QValidator(parent) , mCodecId(InvalidCoding) , mValueCodec(nullptr) { setCodec(codecId); } AddressValidator::~AddressValidator() { delete mValueCodec; } void AddressValidator::setCodec(Coding codecId) { if (codecId == mCodecId) { return; } mCodecId = codecId; delete mValueCodec; mValueCodec = ValueCodec::createCodec((Okteta::ValueCoding)mCodecId); } const QRegExp AddressValidator::expressionRegex = QRegExp(QStringLiteral("[0-9a-fx\\+/\\s\\-\\*]+"), Qt::CaseInsensitive, QRegExp::RegExp2); // FIXME this is way too simple, only there to test QValidator::State AddressValidator::validate(QString& string, int& pos) const { Q_UNUSED(pos) State result = QValidator::Acceptable; if (mCodecId == ExpressionCoding) { string = string.trimmed(); if (!expressionRegex.exactMatch(string)) { result = QValidator::Invalid; } // only prefix has been typed: if (string == QLatin1String("+") || string == QLatin1String("-") || string.endsWith(QLatin1Char('x'))) { // 0x at end result = QValidator::Intermediate; } } else { const int stringLength = string.length(); for (int i = 0; i < stringLength; ++i) { const QChar c = string.at(i); if (!mValueCodec->isValidDigit(c.toLatin1()) && !c.isSpace()) { result = QValidator::Invalid; break; } } } if (string.isEmpty()) { result = QValidator::Intermediate; } return result; } Address AddressValidator::toAddress(const QString& string, AddressType* addressType) const { Address address; QString expression = string.trimmed(); if (addressType) { const AddressType type = expression.startsWith(QLatin1Char('+')) ? RelativeForwards : expression.startsWith(QLatin1Char('-')) ? RelativeBackwards : /* else */ AbsoluteAddress; if (type != AbsoluteAddress) { expression.remove(0, 1); } *addressType = type; } if (mCodecId == ExpressionCoding) { QJSEngine evaluator; QJSValue value = evaluator.evaluate(expression); address = value.toInt(); qCDebug(LOG_KASTEN_OKTETA_GUI) << "expression " << expression << " evaluated to: " << address; if (value.isError()) { qCWarning(LOG_KASTEN_OKTETA_GUI) << "evaluation error: " << value.toString(); if (addressType) { *addressType = InvalidAddressType; } } } else { const bool isHexadecimal = (mCodecId == HexadecimalCoding); const int base = isHexadecimal ? 16 : 10; address = expression.toInt(nullptr, base); } return address; } QString AddressValidator::toString(Address address, AddressType addressType) const { // ExpressionCoding just uses base 10 so no need to adjust this code const bool isHexadecimal = (mCodecId == HexadecimalCoding); const int base = isHexadecimal ? 16 : 10; QString string = QString::number(address, base); if (addressType == RelativeForwards) { string.prepend(QLatin1Char('+')); } else if (addressType == RelativeBackwards) { string.prepend(QLatin1Char('-')); } return string; } } diff --git a/kasten/gui/liboktetawidgets/bytearraycombobox_p.cpp b/kasten/gui/liboktetawidgets/bytearraycombobox_p.cpp index ee30df7f..5ab84d14 100644 --- a/kasten/gui/liboktetawidgets/bytearraycombobox_p.cpp +++ b/kasten/gui/liboktetawidgets/bytearraycombobox_p.cpp @@ -1,214 +1,214 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearraycombobox_p.hpp" #include "bytearraycombobox.hpp" -// KF5 +// KF #include // Qt #include #include #include namespace Okteta { const QStringList& formatNames() { static QStringList list = QStringList { // i18nc("@item:inlistbox guessing the coding of the bytes by the input", "Auto"), i18nc("@item:inlistbox coding of the bytes as values in the hexadecimal format", "Hex"), i18nc("@item:inlistbox coding of the bytes as values in the decimal format", "Dec"), i18nc("@item:inlistbox coding of the bytes as values in the octal format", "Oct"), i18nc("@item:inlistbox coding of the bytes as values in the binary format", "Bin"), i18nc("@item:inlistbox coding of the bytes as characters with the values", "Char"), i18nc("@item:inlistbox coding of the bytes as UTF-8 characters with the values", "UTF-8"), }; return list; } void ByteArrayComboBoxPrivate::init() { Q_Q(ByteArrayComboBox); auto* baseLayout = new QHBoxLayout(q); baseLayout->setContentsMargins(0, 0, 0, 0); baseLayout->setSpacing(0); mFormatComboBox = new KComboBox(q); mFormatComboBox->addItems(formatNames()); QObject::connect(mFormatComboBox, QOverload::of(&QComboBox::activated), q, [&](int index) { onFormatChanged(index); }); mValueComboBox = new KComboBox(q); mValueComboBox->setEditable(true); mValueComboBox->setMaxCount(10); mValueComboBox->setInsertPolicy(QComboBox::NoInsert); mValueComboBox->setDuplicatesEnabled(false); q->setFocusProxy(mValueComboBox); QObject::connect(mValueComboBox->lineEdit(), &QLineEdit::textEdited, q, [&](const QString& text) { onValueEdited(text); }); QAbstractItemView* formatComboBoxListView = mFormatComboBox->view(); QObject::connect(formatComboBoxListView, &QAbstractItemView::activated, mValueComboBox, QOverload<>::of(&KComboBox::setFocus)); // TODO: is a workaround for Qt 4.5.1 which doesn't emit activated() for mouse clicks QObject::connect(formatComboBoxListView, &QAbstractItemView::pressed, mValueComboBox, QOverload<>::of(&KComboBox::setFocus)); mValidator = new ByteArrayValidator(mValueComboBox); const ByteArrayValidator::Coding coding = static_cast(mFormatComboBox->currentIndex()); mValidator->setCodec(coding); mValueComboBox->setValidator(mValidator); QObject::connect(mValueComboBox, QOverload::of(&QComboBox::activated), q, [&](int index) { onValueActivated(index); }); baseLayout->addWidget(mFormatComboBox); baseLayout->addWidget(mValueComboBox, 1); QWidget::setTabOrder(mFormatComboBox, mValueComboBox); } void ByteArrayComboBoxPrivate::setByteArray(const QByteArray& byteArray) { mValueComboBox->setEditText(mValidator->toString(byteArray)); } void ByteArrayComboBoxPrivate::setCharCodec(const QString& charCodecName) { const bool isChar8Visible = (mFormatComboBox->currentIndex() == ByteArrayValidator::CharCoding); // update the char string if shown QByteArray currentByteArray; if (isChar8Visible) { const QString currentChar8String = mValueComboBox->currentText(); currentByteArray = mValidator->toByteArray(currentChar8String); } mValidator->setCharCodec(charCodecName); if (isChar8Visible) { const QString char8String = mValidator->toString(currentByteArray); mValueComboBox->setEditText(char8String); } } void ByteArrayComboBoxPrivate::setMaxLength(int maxLength) { const int oldMaxLength = mValidator->maxLength(); if (oldMaxLength == maxLength) { return; } mValidator->setMaxLength(maxLength); if (oldMaxLength > maxLength) { QString currentText = mValueComboBox->currentText(); int dummyPos; mValidator->validate(currentText, dummyPos); mValueComboBox->setEditText(currentText); } } void ByteArrayComboBoxPrivate::setMinLength(int minLength) { const int oldMinLength = mValidator->minLength(); if (oldMinLength == minLength) { return; } mValidator->setMinLength(minLength); if (oldMinLength < minLength) { QString currentText = mValueComboBox->currentText(); int dummyPos; mValidator->validate(currentText, dummyPos); mValueComboBox->setEditText(currentText); } } void ByteArrayComboBoxPrivate::rememberCurrentByteArray() { mValueComboBox->insertItem(-1, mValueComboBox->currentText(), mFormatComboBox->currentIndex()); } int ByteArrayComboBoxPrivate::maxLength() const { return mValidator->maxLength(); } int ByteArrayComboBoxPrivate::minLength() const { return mValidator->minLength(); } void ByteArrayComboBoxPrivate::onFormatChanged(int index) { Q_Q(ByteArrayComboBox); const QString currentValueText = mValueComboBox->currentText(); const bool isCurrentValueTextEmpty = currentValueText.isEmpty(); const QByteArray byteArray = isCurrentValueTextEmpty ? QByteArray() : mValidator->toByteArray(currentValueText); mValidator->setCodec(static_cast(index)); if (!isCurrentValueTextEmpty) { const QString convertedValueText = mValidator->toString(byteArray); mValueComboBox->setEditText(convertedValueText); } emit q->formatChanged(index); } void ByteArrayComboBoxPrivate::onValueEdited(const QString& value) { Q_Q(ByteArrayComboBox); const QByteArray byteArray = mValidator->toByteArray(value); emit q->byteArrayChanged(byteArray); } void ByteArrayComboBoxPrivate::onValueActivated(int index) { Q_Q(ByteArrayComboBox); if (index != -1) { const int oldFormatIndex = mFormatComboBox->currentIndex(); const int itemFormatIndex = mValueComboBox->itemData(index).toInt(); const bool isOtherFormat = (oldFormatIndex != itemFormatIndex); if (isOtherFormat) { mFormatComboBox->setCurrentIndex(itemFormatIndex); mValidator->setCodec(static_cast(itemFormatIndex)); } const QString currentValueText = mValueComboBox->currentText(); const QByteArray byteArray = mValidator->toByteArray(currentValueText); emit q->byteArrayChanged(byteArray); if (isOtherFormat) { emit q->formatChanged(itemFormatIndex); } } } } diff --git a/kasten/gui/liboktetawidgets/bytearraycombobox_p.hpp b/kasten/gui/liboktetawidgets/bytearraycombobox_p.hpp index d9bce860..b9676ae7 100644 --- a/kasten/gui/liboktetawidgets/bytearraycombobox_p.hpp +++ b/kasten/gui/liboktetawidgets/bytearraycombobox_p.hpp @@ -1,84 +1,84 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_BYTEARRAYCOMBOBOX_P_HPP #define KASTEN_BYTEARRAYCOMBOBOX_P_HPP // lib #include "bytearraycombobox.hpp" #include "bytearrayvalidator.hpp" -// KF5 +// KF #include // Qt #include namespace Okteta { class ByteArrayComboBoxPrivate { public: explicit ByteArrayComboBoxPrivate(ByteArrayComboBox* parent); public: QByteArray byteArray() const; int format() const; int maxLength() const; int minLength() const; public: void init(); void setByteArray(const QByteArray& byteArray); void setCharCodec(const QString& charCodecName); void setMaxLength(int maxLength); void setMinLength(int minLength); void rememberCurrentByteArray(); void onFormatChanged(int index); void onValueEdited(const QString& value); void onValueActivated(int index); private: ByteArrayComboBox* const q_ptr; Q_DECLARE_PUBLIC(ByteArrayComboBox) KComboBox * mFormatComboBox; KComboBox* mValueComboBox; ByteArrayValidator* mValidator; }; inline ByteArrayComboBoxPrivate::ByteArrayComboBoxPrivate(ByteArrayComboBox* parent) : q_ptr(parent) {} inline QByteArray ByteArrayComboBoxPrivate::byteArray() const { return mValidator->toByteArray(mValueComboBox->currentText()); } inline int ByteArrayComboBoxPrivate::format() const { return mFormatComboBox->currentIndex(); } } #endif diff --git a/kasten/gui/system/bytearrayviewprofilemanager.cpp b/kasten/gui/system/bytearrayviewprofilemanager.cpp index a47f7fa6..809d68b8 100644 --- a/kasten/gui/system/bytearrayviewprofilemanager.cpp +++ b/kasten/gui/system/bytearrayviewprofilemanager.cpp @@ -1,570 +1,570 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2010,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "bytearrayviewprofilemanager.hpp" // library #include "bytearrayviewprofilelock.hpp" #include -// KF5 +// KF #include #include #include // Qt #include #include #include namespace Kasten { QStringList viewProfileFileNameFilter() { return QStringList { QStringLiteral("*.obavp"), QStringLiteral("*.olock") }; } inline QLatin1String viewProfileFileSuffix() { return QLatin1String(".obavp"); } inline QLatin1String viewProfileDirSubPath() { return QLatin1String("/okteta/viewprofiles"); } inline QLatin1String defaultViewProfileFileSubPath() { return QLatin1String("/okteta/defaultviewprofile"); } static constexpr int DefaultNoOfBytesPerLine = 16; static constexpr int DefaultNoOfBytesPerGroup = 4; static constexpr int DefaultLayoutStyle = 0; static constexpr int DefaultViewModus = 0; static constexpr int DefaultVisibleByteArrayCodings = 3; static constexpr int DefaultOffsetCoding = 0; static constexpr int DefaultValueCoding = 0; QString DefaultCharCoding() { return {}; } static QVector lockedViewProfileIds(const ByteArrayViewProfileFileInfoLookup& viewProfileFileInfoLookup) { QVector result; ByteArrayViewProfileFileInfoLookup::ConstIterator end = viewProfileFileInfoLookup.constEnd(); for (ByteArrayViewProfileFileInfoLookup::ConstIterator it = viewProfileFileInfoLookup.constBegin(); it != end; ++it) { if (it.value().isLocked()) { result.append(it.key()); } } return result; } static void updateLockStatus(ByteArrayViewProfileFileInfoLookup& viewProfileFileInfoLookup, const QVector& lockedViewProfileIds, const QVector& unlockedViewProfileIds) { if (lockedViewProfileIds.isEmpty() && unlockedViewProfileIds.isEmpty()) { return; } ByteArrayViewProfileFileInfoLookup::Iterator end = viewProfileFileInfoLookup.end(); for (ByteArrayViewProfileFileInfoLookup::Iterator it = viewProfileFileInfoLookup.begin(); it != end; ++it) { bool isLocked; if (lockedViewProfileIds.contains(it.key())) { isLocked = true; } else if (unlockedViewProfileIds.contains(it.key())) { isLocked = false; } else { continue; } it.value().setLocked(isLocked); } } static QString defaultViewProfileFilePath() { return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + defaultViewProfileFileSubPath(); } static QString viewProfileFilePath(const ByteArrayViewProfile::Id& viewProfileId) { return QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + viewProfileDirSubPath() + QLatin1Char('/') + viewProfileId + viewProfileFileSuffix(); } static QString viewProfileFileName(const ByteArrayViewProfile::Id& viewProfileId) { return viewProfileId + viewProfileFileSuffix(); } // TODO: add global lock // TODO: make calls async // TODO: only load view profiles on demand ByteArrayViewProfileManager::ByteArrayViewProfileManager() { mViewProfileFileWatcher = new KDirWatch(this); connect(mViewProfileFileWatcher, &KDirWatch::dirty, this, &ByteArrayViewProfileManager::onViewProfilesFolderChanged); // get all folder where viewProfiles could be stored const QStringList dataFolderPaths = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); for (const QString& dataFolderPath : dataFolderPaths) { const QString viewProfileFolderPath = dataFolderPath + viewProfileDirSubPath(); // watch folder for changes mViewProfileFileWatcher->addDir(viewProfileFolderPath, KDirWatch::WatchDirOnly); // read current files onViewProfilesFolderChanged(viewProfileFolderPath); } // default view profile // While there is no proper config syncing offer in the used frameworks, use a // single file with the id as content as workaround and watch for it changing auto* defaultViewProfileWatcher = new KDirWatch(this); connect(defaultViewProfileWatcher, &KDirWatch::created, this, &ByteArrayViewProfileManager::onDefaultViewProfileChanged); connect(defaultViewProfileWatcher, &KDirWatch::dirty, this, &ByteArrayViewProfileManager::onDefaultViewProfileChanged); const QString _defaultViewProfileFilePath = defaultViewProfileFilePath(); defaultViewProfileWatcher->addFile(_defaultViewProfileFilePath); onDefaultViewProfileChanged(_defaultViewProfileFilePath); // report any problems with existing view profiles? } ByteArrayViewProfileManager::~ByteArrayViewProfileManager() = default; int ByteArrayViewProfileManager::viewProfilesCount() const { return mViewProfiles.count(); } QVector ByteArrayViewProfileManager::viewProfiles() const { return mViewProfiles; } ByteArrayViewProfile ByteArrayViewProfileManager::viewProfile(const ByteArrayViewProfile::Id& viewProfileId) const { ByteArrayViewProfile result; for (const ByteArrayViewProfile& viewProfile : mViewProfiles) { if (viewProfile.id() == viewProfileId) { result = viewProfile; break; } } return result; } ByteArrayViewProfile::Id ByteArrayViewProfileManager::defaultViewProfileId() const { return mDefaultViewProfileId; } ByteArrayViewProfile ByteArrayViewProfileManager::defaultViewProfile() const { return viewProfile(mDefaultViewProfileId); } bool ByteArrayViewProfileManager::isViewProfileLocked(const ByteArrayViewProfile::Id& viewProfileId) const { bool result = false; // search in all folders for the info for (const ByteArrayViewProfileFileInfoLookup& viewProfileFileInfoLookup : mViewProfileFileInfoLookupPerFolder) { ByteArrayViewProfileFileInfoLookup::ConstIterator it = viewProfileFileInfoLookup.find(viewProfileId); if (it != viewProfileFileInfoLookup.constEnd()) { result = it->isLocked(); break; } } return result; } void ByteArrayViewProfileManager::saveViewProfiles(QVector& viewProfiles) { // TODO: do not save if locked by someone else -> needs passing of our lock? or just registering our own and check? // create and set unique id std::for_each(viewProfiles.begin(), viewProfiles.end(), [this](ByteArrayViewProfile& viewProfile) { const ByteArrayViewProfile::Id viewProfileId = viewProfile.id(); bool needsId = true; if (!viewProfileId.isEmpty()) { // already existing? auto hasViewProfileId = [&viewProfileId] (const ByteArrayViewProfile& existingProfile) { return (viewProfileId == existingProfile.id()); }; if (std::any_of(mViewProfiles.constBegin(), mViewProfiles.constEnd(), hasViewProfileId)) { needsId = false; } } // set new uuid for non-existing if (needsId) { viewProfile.setId(QUuid::createUuid().toString()); } saveViewProfile(viewProfile); }); } void ByteArrayViewProfileManager::removeViewProfiles(const QVector& viewProfileIds) { for (const ByteArrayViewProfile::Id& viewProfileId : viewProfileIds) { removeViewProfile(viewProfileId); } } void ByteArrayViewProfileManager::setDefaultViewProfile(const ByteArrayViewProfile::Id& viewProfileId) { QFile defaultViewProfileFile(defaultViewProfileFilePath()); defaultViewProfileFile.open(QIODevice::WriteOnly); defaultViewProfileFile.write(viewProfileId.toUtf8()); defaultViewProfileFile.close(); } ByteArrayViewProfileLock ByteArrayViewProfileManager::createLock(const ByteArrayViewProfile::Id& viewProfileId) { const QString viewProfileFilePath = filePathOfViewProfile(viewProfileId); return ByteArrayViewProfileLock(viewProfileFilePath, viewProfileId); } /* bool ByteArrayViewProfileManager::lockViewProfile( const Kasten::ByteArrayViewProfile::Id& viewProfileId ) { bool isSuccessfull; const QString viewProfileFilePath = filePathOfViewProfile( viewProfileId ); // viewProfile known if( not viewProfileFilePath.isEmpty() ) { const QString lockFilePath = viewProfileFileLockPath( viewProfileFilePath ); KLockFile::Ptr lock = new KLockFile( lockFilePath ); const KLockFile::LockResult lockResult = lock->lock(KLockFile::NoBlockFlag | KLockFile::ForceFlag); isSuccessfull = (lockResult == KLockFile::LockOK ); } // if found // try to create lock file return isSuccessfull; } */ // bool // ByteArrayViewProfileManager::unlockViewProfile( const Kasten::ByteArrayViewProfile::Id& viewProfileId ) // { // const QString filePath = filePathOfViewProfile( viewProfileId ); // // if( filePath.isEmpty() ) // return false; // } ByteArrayViewProfile ByteArrayViewProfileManager::loadViewProfile(const QString& absoluteFilePath) const { ByteArrayViewProfile result; KConfig configFile(absoluteFilePath, KConfig::SimpleConfig); // check version KConfigGroup formatConfigGroup = configFile.group("OBAVP"); const QString formatVersion = formatConfigGroup.readEntry("Version"); if (!formatVersion.startsWith(QLatin1String("1."))) { return result; } result.setId(QFileInfo(absoluteFilePath).baseName()); KConfigGroup generalConfigGroup = configFile.group("General"); result.setViewProfileTitle(generalConfigGroup.readEntry("Title")); KConfigGroup layoutConfigGroup = configFile.group("Layout"); result.setNoOfBytesPerLine(layoutConfigGroup.readEntry("NoOfBytesPerLine", DefaultNoOfBytesPerLine)); result.setNoOfGroupedBytes(layoutConfigGroup.readEntry("NoOfBytesPerGroup", DefaultNoOfBytesPerGroup)); result.setLayoutStyle(layoutConfigGroup.readEntry("LayoutStyle", DefaultLayoutStyle)); KConfigGroup displayConfigGroup = configFile.group("Display"); result.setOffsetColumnVisible(displayConfigGroup.readEntry("OffsetColumnVisible", true)); result.setOffsetCoding(displayConfigGroup.readEntry("OffsetCoding", DefaultOffsetCoding)); result.setViewModus(displayConfigGroup.readEntry("ViewModus", DefaultViewModus)); result.setVisibleByteArrayCodings(displayConfigGroup.readEntry("VisibleByteArrayCodings", DefaultVisibleByteArrayCodings)); KConfigGroup interpretationConfigGroup = configFile.group("Interpretation"); KConfigGroup valuesConfigGroup = interpretationConfigGroup.group("Values"); result.setValueCoding(valuesConfigGroup.readEntry("Coding", DefaultValueCoding)); KConfigGroup charsConfigGroup = interpretationConfigGroup.group("Chars"); result.setCharCoding(charsConfigGroup.readEntry("Coding", DefaultCharCoding())); result.setShowsNonprinting(charsConfigGroup.readEntry("NonprintingShown", false)); result.setSubstituteChar(charsConfigGroup.readEntry("SubstituteChar", ".").at(0)); result.setUndefinedChar(charsConfigGroup.readEntry("UndefinedChar", "?").at(0)); return result; } void ByteArrayViewProfileManager::saveViewProfile(const ByteArrayViewProfile& viewProfile) const { const QString fileName = viewProfileFilePath(viewProfile.id()); KConfig configFile(fileName, KConfig::SimpleConfig); KConfigGroup formatConfigGroup = configFile.group("OBAVP"); formatConfigGroup.writeEntry("Version", "1.1"); KConfigGroup generalConfigGroup = configFile.group("General"); generalConfigGroup.writeEntry("Title", viewProfile.viewProfileTitle()); KConfigGroup layoutConfigGroup = configFile.group("Layout"); layoutConfigGroup.writeEntry("NoOfBytesPerLine", viewProfile.noOfBytesPerLine()); layoutConfigGroup.writeEntry("NoOfBytesPerGroup", viewProfile.noOfGroupedBytes()); layoutConfigGroup.writeEntry("LayoutStyle", viewProfile.layoutStyle()); KConfigGroup displayConfigGroup = configFile.group("Display"); displayConfigGroup.writeEntry("OffsetColumnVisible", viewProfile.offsetColumnVisible()); displayConfigGroup.writeEntry("OffsetCoding", viewProfile.offsetCoding()); displayConfigGroup.writeEntry("ViewModus", viewProfile.viewModus()); displayConfigGroup.writeEntry("VisibleByteArrayCodings", viewProfile.visibleByteArrayCodings()); KConfigGroup interpretationConfigGroup = configFile.group("Interpretation"); KConfigGroup valuesConfigGroup = interpretationConfigGroup.group("Values"); valuesConfigGroup.writeEntry("Coding", viewProfile.valueCoding()); KConfigGroup charsConfigGroup = interpretationConfigGroup.group("Chars"); charsConfigGroup.writeEntry("Coding", viewProfile.charCodingName()); charsConfigGroup.writeEntry("NonprintingShown", viewProfile.showsNonprinting()); charsConfigGroup.writeEntry("SubstituteChar", QString(viewProfile.substituteChar())); charsConfigGroup.writeEntry("UndefinedChar", QString(viewProfile.undefinedChar())); } void ByteArrayViewProfileManager::removeViewProfile(const ByteArrayViewProfile::Id& viewProfileId) { const QString filePath = filePathOfViewProfile(viewProfileId); if (!filePath.isEmpty()) { QFile::remove(filePath); } } QString ByteArrayViewProfileManager::filePathOfViewProfile(const ByteArrayViewProfile::Id& viewProfileId) const { QString result; for (QHash::ConstIterator foldersIt = mViewProfileFileInfoLookupPerFolder.constBegin(); foldersIt != mViewProfileFileInfoLookupPerFolder.constEnd() && result.isEmpty(); ++foldersIt) { const ByteArrayViewProfileFileInfoLookup& fileInfoList = foldersIt.value(); for (ByteArrayViewProfileFileInfoLookup::ConstIterator folderIt = fileInfoList.constBegin(); folderIt != fileInfoList.constEnd(); ++folderIt) { if (folderIt.key() == viewProfileId) { result = foldersIt.key() + QLatin1Char('/') + viewProfileFileName(viewProfileId); break; } } } return result; } void ByteArrayViewProfileManager::onViewProfilesFolderChanged(const QString& viewProfileFolderPath) { ByteArrayViewProfileFileInfoLookup& viewProfileFileInfoLookup = mViewProfileFileInfoLookupPerFolder[viewProfileFolderPath]; // TODO: reparse for new, removed and changed files // assume all are removed and unlocked in the beginning QVector removedViewProfileIds = viewProfileFileInfoLookup.keys().toVector(); QVector newViewProfiles; QVector changedViewProfiles; QVector newUnlockedViewProfileIds = lockedViewProfileIds(viewProfileFileInfoLookup); QVector newLockedViewProfileIds; // iterate all files in folder const QFileInfoList viewProfileFileInfoList = QDir(viewProfileFolderPath).entryInfoList(viewProfileFileNameFilter(), QDir::Files); for (const QFileInfo& viewProfileFileInfo : viewProfileFileInfoList) { // a lock file ? if (viewProfileFileInfo.suffix() == QLatin1String("olock")) { const ByteArrayViewProfile::Id lockedViewProfileId = viewProfileFileInfo.baseName(); // if not in old locks, is a new lock if (!newUnlockedViewProfileIds.removeOne(lockedViewProfileId)) { newLockedViewProfileIds.append(lockedViewProfileId); } continue; } // not a viewprofile file ? if (viewProfileFileInfo.suffix() != QLatin1String("obavp")) { continue; } // all other files assumed to be viewProfile files const ByteArrayViewProfile::Id viewProfileId = viewProfileFileInfo.baseName(); // load file const ByteArrayViewProfile viewProfile = loadViewProfile(viewProfileFileInfo.absoluteFilePath()); // loading failed? Treat as not existing if (viewProfile.id().isEmpty()) { continue; } const ByteArrayViewProfileFileInfoLookup::Iterator infoIt = viewProfileFileInfoLookup.find(viewProfileId); const bool isKnown = (infoIt != viewProfileFileInfoLookup.end()); const QDateTime fileInfoLastModified = viewProfileFileInfo.lastModified(); // is known? if (isKnown) { removedViewProfileIds.removeOne(viewProfileId); // check timestamp if (fileInfoLastModified == infoIt->lastModified()) { continue; } // update timestamp infoIt->setLastModified(fileInfoLastModified); } else { ByteArrayViewProfileFileInfo info(fileInfoLastModified, false); viewProfileFileInfoLookup.insert(viewProfileId, info); } if (isKnown) { auto it = std::find_if(mViewProfiles.begin(), mViewProfiles.end(), [&viewProfileId](const ByteArrayViewProfile& existingProfile) { return (existingProfile.id() == viewProfileId); }); if (it != mViewProfiles.end()) { *it = viewProfile; } } else { newViewProfiles.append(viewProfile); } changedViewProfiles.append(viewProfile); } // remove all removed viewprofiles { auto isProfileToRemove = [&removedViewProfileIds](const ByteArrayViewProfile& profile) { return removedViewProfileIds.contains(profile.id()); }; mViewProfiles.erase(std::remove_if(mViewProfiles.begin(), mViewProfiles.end(), isProfileToRemove), mViewProfiles.end()); } for (const ByteArrayViewProfile::Id& viewProfileId : qAsConst(removedViewProfileIds)) { viewProfileFileInfoLookup.remove(viewProfileId); if (viewProfileId == mDefaultViewProfileId) { mDefaultViewProfileId.clear(); } // TODO: how to select new one? } // add new viewprofiles mViewProfiles.append(newViewProfiles); // if there was no default viewprofile before, set default to first const bool isDefaultViewProfileChanged = (mDefaultViewProfileId.isEmpty() && !mViewProfiles.isEmpty()); if (isDefaultViewProfileChanged) { mDefaultViewProfileId = mViewProfiles.at(0).id(); } // update lock info updateLockStatus(viewProfileFileInfoLookup, newLockedViewProfileIds, newUnlockedViewProfileIds); // signal changes if (!changedViewProfiles.isEmpty()) { emit viewProfilesChanged(changedViewProfiles); } if (!removedViewProfileIds.isEmpty()) { emit viewProfilesRemoved(removedViewProfileIds); } if (!newUnlockedViewProfileIds.isEmpty()) { emit viewProfilesUnlocked(newUnlockedViewProfileIds); } if (!newLockedViewProfileIds.isEmpty()) { emit viewProfilesLocked(newLockedViewProfileIds); } if (isDefaultViewProfileChanged) { emit defaultViewProfileChanged(mDefaultViewProfileId); } } void ByteArrayViewProfileManager::onDefaultViewProfileChanged(const QString& path) { QFile defaultViewProfileFile(path); if (!defaultViewProfileFile.open(QIODevice::ReadOnly)) { qCDebug(LOG_KASTEN_OKTETA_GUI) << "Failed to open view profiles file " << path; return; } const QByteArray fileContent = defaultViewProfileFile.readAll(); const QString viewProfileId = QString::fromUtf8(fileContent); defaultViewProfileFile.close(); // no id set? if (viewProfileId.isEmpty()) { return; } // no change? if (mDefaultViewProfileId == viewProfileId) { return; } bool isExisting = false; for (const ByteArrayViewProfile& viewProfile : qAsConst(mViewProfiles)) { if (viewProfile.id() == viewProfileId) { isExisting = true; break; } } if (isExisting) { mDefaultViewProfileId = viewProfileId; emit defaultViewProfileChanged(mDefaultViewProfileId); } } } diff --git a/libs/framesprint/headerfooterframerenderer.cpp b/libs/framesprint/headerfooterframerenderer.cpp index 8d685392..2c5c5246 100644 --- a/libs/framesprint/headerfooterframerenderer.cpp +++ b/libs/framesprint/headerfooterframerenderer.cpp @@ -1,162 +1,162 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2007 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "headerfooterframerenderer.hpp" -// KF5 +// KF #include #include // Qt #include #include #include #include #include HeaderFooterFrameRenderer::HeaderFooterFrameRenderer(const PrintInfo* info) : mInfo(info) { calculateHeight(); } HeaderFooterFrameRenderer::~HeaderFooterFrameRenderer() = default; int HeaderFooterFrameRenderer::height() const { return mHeight; } int HeaderFooterFrameRenderer::width() const { return mWidth; } void HeaderFooterFrameRenderer::setWidth(int width) { mWidth = width; } void HeaderFooterFrameRenderer::setTexts(const QString& leftText, const QString& centerText, const QString& rightText) { mOriginalTextList.clear(); mOriginalTextList << leftText << centerText << rightText; } void HeaderFooterFrameRenderer::setBoxStyle(int boxStyle) { if (mBoxStyle == boxStyle) { return; } mBoxStyle = boxStyle; calculateHeight(); } void HeaderFooterFrameRenderer::calculateHeight() { const QFontMetrics fontMetrics(mFont); mHeight = fontMetrics.height(); // const bool hasSpaceAbove = ( mBoxStyle & (BackgroundDrawn|LineAbove) ); // const bool hasSpacedBelow = ( mBoxStyle & (BackgroundDrawn|LineBelow) ); // if( !(hasSpaceAbove||hasSpacedBelow) ) mHeight += fontMetrics.leading(); // else // { // if( hasSpaceAbove ) // { // mHeight += mBoxMargin * 2; // // } // } } void HeaderFooterFrameRenderer::prepare() { const QDateTime dateTime = QDateTime::currentDateTime(); const KUser user(KUser::UseRealUserID); const QUrl url = mInfo->url(); // create list of replacements QHash tagReplacements; QLocale locale; tagReplacements['d'] = locale.toString(dateTime, QLocale::ShortFormat); tagReplacements['D'] = locale.toString(dateTime, QLocale::LongFormat); tagReplacements['h'] = locale.toString(dateTime.time(), QLocale::ShortFormat); tagReplacements['y'] = locale.toString(dateTime.date(), QLocale::ShortFormat); tagReplacements['Y'] = locale.toString(dateTime.date(), QLocale::LongFormat); tagReplacements['u'] = user.loginName(); tagReplacements['U'] = user.property(KUser::FullName).toString(); // tagReplacements['f'] = isSelection ? i18n("(Selection of) %1", url.fileName()) : url.fileName(); tagReplacements['f'] = url.fileName(); tagReplacements['F'] = url.toDisplayString(QUrl::PrettyDecoded | QUrl::PreferLocalFile); tagReplacements['P'] = QString::number(mInfo->noOfPages()); // create text with globally replaced tags const int sizeOfTag = 2; QRegExp tagsPattern(QStringLiteral("%([dDhyYuUfFP])")); mGloballyReplacedTextList.clear(); for (int i = 0; i < 3; ++i) { QString text = mOriginalTextList.at(i); int pos = 0; while (true) { pos = tagsPattern.indexIn(text, pos); if (pos < 0) { break; } QString replacement = tagReplacements[text[pos + 1].toLatin1()]; text.replace((uint)pos, sizeOfTag, replacement); pos += replacement.length(); } mGloballyReplacedTextList << text; } } void HeaderFooterFrameRenderer::renderFrame(QPainter* painter, int frameIndex) { painter->setPen(mFgColor); painter->setFont(mFont); // if( mBoxStyle & BackgroundDrawn ) // painter->fillRect( 0, 0, mWidth, mHeight, mBgColor ); const bool isTextFramed = false;// ( mBoxStyle & (Box|BackgroundDrawn) ); const int horizontalAlign[3] = { Qt::AlignLeft, Qt::AlignHCenter, Qt::AlignRight }; int verticalAlign = isTextFramed ? Qt::AlignVCenter : Qt::AlignTop; int margin = 0;// ( mBoxStyle & (mBoxDrawn || mBackgroundDrawn ) ? mBoxMargin : 0; // if ( mBoxStyle & LinesAtSide ) // margin += mLineWidth; const int rightEnd = mWidth - (margin * 2); for (int i = 0; i < 3; i++) { QString text = mGloballyReplacedTextList[i]; // substitute locally const QString pageNumberTag = QStringLiteral("%p"); if (text.indexOf(pageNumberTag) != -1) { text.replace(pageNumberTag, QString::number(frameIndex + 1)); // TODO: frameIndex != pageNumber in general } int align = verticalAlign | horizontalAlign[i]; painter->drawText(margin, 0, rightEnd, mHeight, align, text); } // if ( !isTextFramed ) { // painter->drawLine( 0, mHeight-mLineWidth, mWidth, mHeight-mLineWidth ); // painter->drawLine( 0, maxHeight + mBoxMargin - 1, headerWidth, maxHeight + mBoxMargin - 1 ); // painter->drawRect( 0, 0, pdmWidth, pdmHeight); // paint.drawLine(0, headerHeight, headerWidth, headerHeight); } } diff --git a/libs/kasten/controllers/document/modified/modifiedbarcontroller.cpp b/libs/kasten/controllers/document/modified/modifiedbarcontroller.cpp index 0a2ca931..42dfe11b 100644 --- a/libs/kasten/controllers/document/modified/modifiedbarcontroller.cpp +++ b/libs/kasten/controllers/document/modified/modifiedbarcontroller.cpp @@ -1,184 +1,184 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009-2010,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "modifiedbarcontroller.hpp" // Kasten ui #include // Kasten core #include #include -// KF5 +// KF #include // Qt #include #include namespace Kasten { static constexpr int modifiedPixmapWidth = 16; ModifiedBarController::ModifiedBarController(StatusBar* statusBar) { // TODO: depend an statusbar height const QSize modifiedPixmapSize = QSize(modifiedPixmapWidth, modifiedPixmapWidth); mLocalStateLabel = new QLabel(statusBar); mLocalStateLabel->setAlignment(Qt::AlignCenter); mLocalStateLabel->setFixedSize(modifiedPixmapSize); statusBar->addWidget(mLocalStateLabel); mRemoteStateLabel = new QLabel(statusBar); mRemoteStateLabel->setAlignment(Qt::AlignCenter); mRemoteStateLabel->setFixedSize(modifiedPixmapSize); statusBar->addWidget(mRemoteStateLabel); setTargetModel(nullptr); } void ModifiedBarController::setTargetModel(AbstractModel* model) { AbstractDocument* newDocument = model ? model->findBaseModel() : nullptr; if (mDocument == newDocument) { return; } if (mDocument) { mDocument->disconnect(this); } mDocument = newDocument; if (mDocument) { connect(mDocument, &Kasten::AbstractDocument::synchronizerChanged, this, &ModifiedBarController::onSynchronizerChanged); } mLocalStateLabel->setEnabled(mDocument != nullptr); mRemoteStateLabel->setEnabled(mDocument != nullptr); onSynchronizerChanged(mDocument ? mDocument->synchronizer() : nullptr); } void ModifiedBarController::onContentFlagsChanged(ContentFlags contentFlags) { const bool hasChanges = (contentFlags & ContentHasUnstoredChanges); onLocalSyncStateChanged(hasChanges ? LocalHasChanges : LocalInSync); } void ModifiedBarController::onLocalSyncStateChanged(LocalSyncState localSyncState) { const bool isModified = (localSyncState == LocalHasChanges); // TODO: depend an statusbar height const QPixmap pixmap = isModified ? QIcon::fromTheme(QStringLiteral("document-save")).pixmap(modifiedPixmapWidth) : QPixmap(); mLocalStateLabel->setPixmap(pixmap); mLocalStateLabel->setToolTip(isModified ? i18nc("@tooltip the document is modified", "Modified.") : i18nc("@tooltip the document is not modified", "Not modified.")); } void ModifiedBarController::onRemoteSyncStateChanged(RemoteSyncState remoteSyncState) { const char* const iconName = (!mSynchronizer) ? "document-new" : (remoteSyncState == RemoteHasChanges) ? "document-save" : (remoteSyncState == RemoteDeleted) ? "edit-delete" : (remoteSyncState == RemoteUnknown) ? "flag-yellow" : (remoteSyncState == RemoteUnreachable) ? "network-disconnect" : /* else */ nullptr; // TODO: depend an statusbar height const QPixmap pixmap = iconName ? QIcon::fromTheme(QLatin1String(iconName)).pixmap(modifiedPixmapWidth) : QPixmap(); mRemoteStateLabel->setPixmap(pixmap); // TODO: tooltips } void ModifiedBarController::onSynchronizerChanged(AbstractModelSynchronizer* newSynchronizer) { if (mSynchronizer) { mSynchronizer->disconnect(this); } AbstractModelSynchronizer* oldSynchronizer = mSynchronizer; mSynchronizer = newSynchronizer; LocalSyncState localState; RemoteSyncState remoteState; if (mSynchronizer) { if (!oldSynchronizer) { disconnect(mDocument, &Kasten::AbstractDocument::contentFlagsChanged, this, &ModifiedBarController::onContentFlagsChanged); } localState = mSynchronizer->localSyncState(); remoteState = mSynchronizer->remoteSyncState(); connect(mSynchronizer, &Kasten::AbstractModelSynchronizer::localSyncStateChanged, this, &ModifiedBarController::onLocalSyncStateChanged); connect(mSynchronizer, &Kasten::AbstractModelSynchronizer::remoteSyncStateChanged, this, &ModifiedBarController::onRemoteSyncStateChanged); connect(mSynchronizer, &QObject::destroyed, this, &ModifiedBarController::onSynchronizerDeleted); } else if (mDocument) { const bool hasChanges = (mDocument->contentFlags() & ContentHasUnstoredChanges); localState = (hasChanges ? LocalHasChanges : LocalInSync); // TODO: onRemoteSyncStateChanged(...) checks for mSynchronizer and ignores this remoteState = RemoteInSync; connect(mDocument, &Kasten::AbstractDocument::contentFlagsChanged, this, &ModifiedBarController::onContentFlagsChanged); } else { localState = LocalInSync; // TODO: onRemoteSyncStateChanged(...) checks for mSynchronizer and ignores this remoteState = RemoteInSync; } onLocalSyncStateChanged(localState); onRemoteSyncStateChanged(remoteState); } void ModifiedBarController::onSynchronizerDeleted(QObject* synchronizer) { if (synchronizer != mSynchronizer) { return; } mSynchronizer = nullptr; // switch to document state connect(mDocument, &Kasten::AbstractDocument::contentFlagsChanged, this, &ModifiedBarController::onContentFlagsChanged); onContentFlagsChanged(mDocument->contentFlags()); // TODO: onRemoteSyncStateChanged(...) checks for mSynchronizer and ignores the parameter onRemoteSyncStateChanged(RemoteInSync); } } diff --git a/libs/kasten/controllers/document/readonly/readonlybarcontroller.cpp b/libs/kasten/controllers/document/readonly/readonlybarcontroller.cpp index d6edbc98..ea3b1de2 100644 --- a/libs/kasten/controllers/document/readonly/readonlybarcontroller.cpp +++ b/libs/kasten/controllers/document/readonly/readonlybarcontroller.cpp @@ -1,75 +1,75 @@ /* This file is part of the Okteta Kasten module, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "readonlybarcontroller.hpp" // Kasten core #include // Kasten ui #include #include -// KF5 +// KF #include namespace Kasten { ReadOnlyBarController::ReadOnlyBarController(StatusBar* statusBar) { const QString readWriteText = i18nc("@option:check the document is read-write", "Read-write"); const QString readOnlyText = i18nc("@option:check the document is read-only", "Read-only"); mReadOnlyButton = new ToggleButton(QIcon::fromTheme(QStringLiteral("object-unlocked")), QString(), readWriteText, statusBar); mReadOnlyButton->setCheckedState(QIcon::fromTheme(QStringLiteral("object-locked")), QString(), readOnlyText); statusBar->addWidget(mReadOnlyButton); connect(mReadOnlyButton, &QAbstractButton::clicked, this, &ReadOnlyBarController::setReadOnly); setTargetModel(nullptr); } void ReadOnlyBarController::setTargetModel(AbstractModel* model) { if (mDocument) { mDocument->disconnect(mReadOnlyButton); } mDocument = model ? model->findBaseModel() : nullptr; if (mDocument) { mReadOnlyButton->setChecked(mDocument->isReadOnly()); connect(mDocument, &AbstractModel::readOnlyChanged, mReadOnlyButton, &QAbstractButton::setChecked); connect(mDocument, &AbstractModel::modifiableChanged, mReadOnlyButton, &QWidget::setEnabled); } else { mReadOnlyButton->setChecked(false); } mReadOnlyButton->setEnabled(mDocument ? mDocument->isModifiable() : false); } void ReadOnlyBarController::setReadOnly(bool isReadOnly) { mDocument->setReadOnly(isReadOnly); } } diff --git a/libs/kasten/controllers/document/readonly/readonlycontroller.cpp b/libs/kasten/controllers/document/readonly/readonlycontroller.cpp index 2a1513ff..9ff9c8c3 100644 --- a/libs/kasten/controllers/document/readonly/readonlycontroller.cpp +++ b/libs/kasten/controllers/document/readonly/readonlycontroller.cpp @@ -1,77 +1,77 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "readonlycontroller.hpp" // Kasten core #include -// KF5 +// KF #include #include #include #include #include namespace Kasten { ReadOnlyController::ReadOnlyController(KXMLGUIClient* guiClient) { mSetReadOnlyAction = new KToggleAction(QIcon::fromTheme(QStringLiteral("object-unlocked")), i18nc("@option:check set the document to read-only", "Set Read-only"), this); const QString checkedText = i18nc("@option:check set the document to read-write", "Set Read-write"); const KGuiItem checkedState(checkedText, QIcon::fromTheme(QStringLiteral("object-locked"))); mSetReadOnlyAction->setCheckedState(checkedState); connect(mSetReadOnlyAction, &QAction::triggered, this, &ReadOnlyController::setReadOnly); guiClient->actionCollection()->addAction(QStringLiteral("isreadonly"), mSetReadOnlyAction); setTargetModel(nullptr); } void ReadOnlyController::setTargetModel(AbstractModel* model) { if (mDocument) { mDocument->disconnect(mSetReadOnlyAction); } mDocument = model ? model->findBaseModel() : nullptr; if (mDocument) { mSetReadOnlyAction->setChecked(mDocument->isReadOnly()); connect(mDocument, &AbstractModel::readOnlyChanged, mSetReadOnlyAction, &QAction::setChecked); connect(mDocument, &AbstractModel::modifiableChanged, mSetReadOnlyAction, &QAction::setEnabled); } mSetReadOnlyAction->setEnabled(mDocument ? mDocument->isModifiable() : false); } void ReadOnlyController::setReadOnly(bool isReadOnly) { mDocument->setReadOnly(isReadOnly); } } diff --git a/libs/kasten/controllers/document/terminal/terminaltool.cpp b/libs/kasten/controllers/document/terminal/terminaltool.cpp index 733a540f..18b9fc34 100644 --- a/libs/kasten/controllers/document/terminal/terminaltool.cpp +++ b/libs/kasten/controllers/document/terminal/terminaltool.cpp @@ -1,72 +1,72 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010-2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "terminaltool.hpp" // Kasten core #include #include #include -// KF5 +// KF #include #include // Qt #include namespace Kasten { TerminalTool::TerminalTool(DocumentSyncManager* documentSyncManager) : mDocumentSyncManager(documentSyncManager) { setObjectName(QStringLiteral("Terminal")); } TerminalTool::~TerminalTool() = default; QString TerminalTool::title() const { return i18nc("@title:window", "Terminal"); } QUrl TerminalTool::currentUrl() const { QUrl result; if (mDocument) { result = KIO::upUrl(mDocumentSyncManager->urlOf(mDocument)); } return result; } void TerminalTool::setTargetModel(AbstractModel* model) { const QUrl oldCurrentUrl = currentUrl(); mDocument = model ? model->findBaseModel() : nullptr; const QUrl newCurrentUrl = currentUrl(); if (oldCurrentUrl != newCurrentUrl) { emit currentUrlChanged(newCurrentUrl); } } } diff --git a/libs/kasten/controllers/document/terminal/terminaltoolviewfactory.cpp b/libs/kasten/controllers/document/terminal/terminaltoolviewfactory.cpp index bff867d4..64144b10 100644 --- a/libs/kasten/controllers/document/terminal/terminaltoolviewfactory.cpp +++ b/libs/kasten/controllers/document/terminal/terminaltoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "terminaltoolviewfactory.hpp" // lib #include "terminaltoolview.hpp" #include "terminaltool.hpp" -// KF5 +// KF #include namespace Kasten { TerminalToolViewFactory::TerminalToolViewFactory() = default; TerminalToolViewFactory::~TerminalToolViewFactory() = default; QString TerminalToolViewFactory::iconName() const { return QStringLiteral("utilities-terminal"); } QString TerminalToolViewFactory::title() const { return i18nc("@title:window", "Terminal"); } QString TerminalToolViewFactory::id() const { return QStringLiteral("org.kde.kasten.TerminalToolView"); } SidePosition TerminalToolViewFactory::defaultPosition() const { return BottomSidePosition; } AbstractToolView* TerminalToolViewFactory::create(AbstractTool* tool) const { return new TerminalToolView(qobject_cast(tool)); } } diff --git a/libs/kasten/controllers/document/terminal/terminalview.cpp b/libs/kasten/controllers/document/terminal/terminalview.cpp index acc8a868..502328e4 100644 --- a/libs/kasten/controllers/document/terminal/terminalview.cpp +++ b/libs/kasten/controllers/document/terminal/terminalview.cpp @@ -1,108 +1,108 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "terminalview.hpp" // lib #include "terminaltool.hpp" -// KF5 +// KF #include #include #include #include // Qt #include #include #include #include namespace Kasten { TerminalView::TerminalView(TerminalTool* tool, QWidget* parent) : QWidget(parent) , mTool(tool) { auto* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); connect(mTool, &TerminalTool::currentUrlChanged, this, &TerminalView::onCurrentUrlChanged); QMetaObject::invokeMethod(this, "createTerminalPart", Qt::QueuedConnection); } TerminalView::~TerminalView() { if (mTerminalPart) { disconnect(mTerminalPart, &QObject::destroyed, this, &TerminalView::onTerminalPartDestroyed); } } void TerminalView::createTerminalPart() { mTerminalPart = KServiceTypeTrader::createInstanceFromQuery( QStringLiteral("TerminalEmulator"), this, this); if (mTerminalPart) { connect(mTerminalPart, &QObject::destroyed, this, &TerminalView::onTerminalPartDestroyed); QWidget* terminalWidget = mTerminalPart->widget(); terminalWidget->setFocusPolicy(Qt::WheelFocus); terminalWidget->setFocus(); setFocusProxy(terminalWidget); auto* frame = qobject_cast(terminalWidget); if (frame) { frame->setFrameStyle(QFrame::Panel | QFrame::Sunken); } auto* layout = static_cast(this->layout()); layout->addWidget(terminalWidget); terminalWidget->show(); mTerminalInterface = qobject_cast(mTerminalPart); QUrl currentUrl = mTool->currentUrl(); if (currentUrl.isEmpty()) { currentUrl = QUrl::fromLocalFile(QDir::homePath()); } onCurrentUrlChanged(currentUrl); } } void TerminalView::onCurrentUrlChanged(const QUrl& currentUrl) { if (mTerminalInterface && currentUrl.isLocalFile()) { mTerminalInterface->showShellInDir(currentUrl.path()); } // TODO: Konsole currently seems to ignore this call if shell is running? } void TerminalView::onTerminalPartDestroyed() { mTerminalPart = nullptr; mTerminalInterface = nullptr; createTerminalPart(); } } diff --git a/libs/kasten/controllers/document/versionview/versiontablemodel.cpp b/libs/kasten/controllers/document/versionview/versiontablemodel.cpp index 908b9cf8..4bb584c2 100644 --- a/libs/kasten/controllers/document/versionview/versiontablemodel.cpp +++ b/libs/kasten/controllers/document/versionview/versiontablemodel.cpp @@ -1,167 +1,167 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "versiontablemodel.hpp" // Kasten core #include #include -// KF5 +// KF #include #include namespace Kasten { VersionTableModel::VersionTableModel(AbstractModel* model, If::Versionable* versionControl, QObject* parent) : QAbstractTableModel(parent) , mModel(model) , mVersionControl(versionControl) , mVersionIndex(versionControl ? versionControl->versionIndex() : 0) { if (mModel) { connect(mModel, SIGNAL(revertedToVersionIndex(int)), SLOT(onRevertedToVersionIndex(int))); connect(mModel, SIGNAL(headVersionChanged(int)), SLOT(onHeadVersionChanged(int))); connect(mModel, SIGNAL(headVersionDataChanged(Kasten::DocumentVersionData)), SLOT(onHeadVersionDataChanged(Kasten::DocumentVersionData))); } } VersionTableModel::~VersionTableModel() = default; void VersionTableModel::setModel(AbstractModel* model, If::Versionable* versionControl) { if (mModel) { mModel->disconnect(this); } mModel = model; mVersionControl = versionControl; if (mModel) { connect(mModel, SIGNAL(revertedToVersionIndex(int)), SLOT(onRevertedToVersionIndex(int))); connect(mModel, SIGNAL(headVersionChanged(int)), SLOT(onHeadVersionChanged(int))); connect(mModel, SIGNAL(headVersionDataChanged(Kasten::DocumentVersionData)), SLOT(onHeadVersionDataChanged(Kasten::DocumentVersionData))); } mVersionIndex = versionControl ? versionControl->versionIndex() : 0; beginResetModel(); endResetModel(); } int VersionTableModel::rowCount(const QModelIndex& parent) const { return (!parent.isValid() && mVersionControl) ? mVersionControl->versionCount() : 0; } int VersionTableModel::columnCount(const QModelIndex& parent) const { return (!parent.isValid()) ? NoOfColumnIds : 0; } QVariant VersionTableModel::data(const QModelIndex& index, int role) const { QVariant result; if (role == Qt::DisplayRole) { const int versionIndex = index.row(); const DocumentVersionData version = mVersionControl->versionData(versionIndex); const int tableColumn = index.column(); switch (tableColumn) { case IdColumnId: { result = version.id(); break; } case ChangeDescriptionColumnId: result = version.changeComment(); break; default: ; } } else if (role == Qt::DecorationRole) { const int tableColumn = index.column(); if (tableColumn == CurrentColumnId) { const int versionIndex = index.row(); if (mVersionControl->versionIndex() == versionIndex) { result = QIcon::fromTheme(QStringLiteral("arrow-right")); } } } return result; } QVariant VersionTableModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant result; if (role == Qt::DisplayRole) { const QString titel = section == IdColumnId ? i18nc("@title:column Id of the version", "Id") : section == ChangeDescriptionColumnId ? i18nc("@title:column description of the change", "Changes") : QString(); result = titel; } else if (role == Qt::ToolTipRole) { const QString titel = section == IdColumnId ? i18nc("@info:tooltip", "Id of the version") : section == ChangeDescriptionColumnId ? i18nc("@info:tooltip", "Description of what changed") : QString(); result = titel; } else { result = QAbstractTableModel::headerData(section, orientation, role); } return result; } void VersionTableModel::onRevertedToVersionIndex(int versionIndex) { if (mVersionIndex == versionIndex) { return; } const int oldVersionIndex = mVersionIndex; mVersionIndex = versionIndex; emit dataChanged(index(versionIndex, CurrentColumnId), index(versionIndex, CurrentColumnId)); emit dataChanged(index(oldVersionIndex, CurrentColumnId), index(oldVersionIndex, CurrentColumnId)); } void VersionTableModel::onHeadVersionChanged(int newHeadVersionIndex) { mVersionIndex = newHeadVersionIndex; // TODO: try to understand how this would be done with {begin,end}{Insert,Remove}Columns beginResetModel(); endResetModel(); } void VersionTableModel::onHeadVersionDataChanged(const DocumentVersionData& versionData) { Q_UNUSED(versionData) const int headVersionIndex = mVersionControl->versionCount() - 1; emit dataChanged(index(headVersionIndex, CurrentColumnId), index(headVersionIndex, ChangeDescriptionColumnId)); } } diff --git a/libs/kasten/controllers/document/versionview/versionviewtool.cpp b/libs/kasten/controllers/document/versionview/versionviewtool.cpp index ca35d526..8549af4d 100644 --- a/libs/kasten/controllers/document/versionview/versionviewtool.cpp +++ b/libs/kasten/controllers/document/versionview/versionviewtool.cpp @@ -1,48 +1,48 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "versionviewtool.hpp" // Kasten core #include #include -// KF5 +// KF #include namespace Kasten { VersionViewTool::VersionViewTool() { setObjectName(QStringLiteral("Versions")); } VersionViewTool::~VersionViewTool() = default; QString VersionViewTool::title() const { return i18nc("@title:window", "Versions"); } void VersionViewTool::setTargetModel(AbstractModel* model) { mModel = model ? model->findBaseModelWithInterface() : nullptr; emit modelChanged(mModel); } } diff --git a/libs/kasten/controllers/document/versionview/versionviewtoolviewfactory.cpp b/libs/kasten/controllers/document/versionview/versionviewtoolviewfactory.cpp index 02425751..be029184 100644 --- a/libs/kasten/controllers/document/versionview/versionviewtoolviewfactory.cpp +++ b/libs/kasten/controllers/document/versionview/versionviewtoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "versionviewtoolviewfactory.hpp" // lib #include "versionviewtoolview.hpp" #include "versionviewtool.hpp" -// KF5 +// KF #include namespace Kasten { VersionViewToolViewFactory::VersionViewToolViewFactory() = default; VersionViewToolViewFactory::~VersionViewToolViewFactory() = default; QString VersionViewToolViewFactory::iconName() const { return QStringLiteral("view-history"); } QString VersionViewToolViewFactory::title() const { return i18nc("@title:window", "Versions"); } QString VersionViewToolViewFactory::id() const { return QStringLiteral("org.kde.kasten.VersionViewToolView"); } SidePosition VersionViewToolViewFactory::defaultPosition() const { return RightSidePosition; } AbstractToolView* VersionViewToolViewFactory::create(AbstractTool* tool) const { return new VersionViewToolView(qobject_cast(tool)); } } diff --git a/libs/kasten/controllers/documentsystem/close/closecontroller.cpp b/libs/kasten/controllers/documentsystem/close/closecontroller.cpp index 1c9538c2..62576d8c 100644 --- a/libs/kasten/controllers/documentsystem/close/closecontroller.cpp +++ b/libs/kasten/controllers/documentsystem/close/closecontroller.cpp @@ -1,120 +1,120 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2006-2009,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "closecontroller.hpp" // Kasten gui #include // Kasten core #include -// KF5 +// KF #include #include #include #include // Qt #include namespace Kasten { CloseController::CloseController(AbstractDocumentStrategy* documentStrategy, KXMLGUIClient* guiClient, bool supportMultiple) : mDocumentStrategy(documentStrategy) { KActionCollection* actionCollection = guiClient->actionCollection(); const QIcon documentCloseIcon = QIcon::fromTheme(QStringLiteral("document-close")); mCloseAction = KStandardAction::close(this, &CloseController::close, this); mCloseAction->setEnabled(false); actionCollection->addAction(mCloseAction->objectName(), mCloseAction); if (supportMultiple) { mCloseAllAction = new QAction(documentCloseIcon, i18nc("@action:inmenu", "Close All"), this); mCloseAllAction->setObjectName(QStringLiteral("file_close_all")); connect(mCloseAllAction, &QAction::triggered, this, &CloseController::closeAll); mCloseAllAction->setEnabled(false); mCloseAllOtherAction = new QAction(documentCloseIcon, i18nc("@action:inmenu", "Close All Other"), this); mCloseAllOtherAction->setObjectName(QStringLiteral("file_close_all_other")); connect(mCloseAllOtherAction, &QAction::triggered, this, &CloseController::closeAllOther); mCloseAllOtherAction->setEnabled(false); actionCollection->addAction(mCloseAllAction->objectName(), mCloseAllAction); actionCollection->addAction(mCloseAllOtherAction->objectName(), mCloseAllOtherAction); connect(mDocumentStrategy, &Kasten::AbstractDocumentStrategy::added, this, &CloseController::onDocumentsChanged); connect(mDocumentStrategy, &Kasten::AbstractDocumentStrategy::closing, this, &CloseController::onDocumentsChanged); } } CloseController::~CloseController() = default; void CloseController::setTargetModel(AbstractModel* model) { mDocument = model ? model->findBaseModel() : nullptr; const bool hasDocument = (mDocument != nullptr); mCloseAction->setEnabled(hasDocument); } void CloseController::close() { if (mDocumentStrategy->canClose(mDocument)) { mDocumentStrategy->closeDocument(mDocument); } } void CloseController::closeAll() { if (mDocumentStrategy->canCloseAll()) { mDocumentStrategy->closeAll(); } } void CloseController::closeAllOther() { if (mDocumentStrategy->canCloseAllOther(mDocument)) { mDocumentStrategy->closeAllOther(mDocument); } } void CloseController::onDocumentsChanged() { const QVector documents = mDocumentStrategy->documents(); const bool hasDocuments = !documents.isEmpty(); // TODO: there could be just one, but not set for this tool? const bool hasOtherDocuments = (documents.size() > 1); mCloseAllAction->setEnabled(hasDocuments); mCloseAllOtherAction->setEnabled(hasOtherDocuments); } } diff --git a/libs/kasten/controllers/documentsystem/creator/creatorcontroller.cpp b/libs/kasten/controllers/documentsystem/creator/creatorcontroller.cpp index 08d4a807..50724e4f 100644 --- a/libs/kasten/controllers/documentsystem/creator/creatorcontroller.cpp +++ b/libs/kasten/controllers/documentsystem/creator/creatorcontroller.cpp @@ -1,140 +1,140 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2006-2009,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "creatorcontroller.hpp" // Kasten gui #include #include // Kasten core #include #include -// KF5 +// KF #include #include #include #include #include // Qt #include #include #ifndef KASTEN_ABSTRACTMODELDATAGENERATOR_METATYPE #define KASTEN_ABSTRACTMODELDATAGENERATOR_METATYPE Q_DECLARE_METATYPE(Kasten::AbstractModelDataGenerator*) #endif namespace Kasten { CreatorController::CreatorController(ModelCodecManager* modelCodecManager, AbstractDocumentStrategy* documentStrategy, KXMLGUIClient* guiClient) : mModelCodecManager(modelCodecManager) , mDocumentStrategy(documentStrategy) { KActionCollection* actionCollection = guiClient->actionCollection(); KActionMenu* newMenuAction = new KActionMenu(QIcon::fromTheme(QStringLiteral("document-new")), i18nc("@title:menu create new byte arrays from different sources", "New"), this); newMenuAction->setStickyMenu(false); newMenuAction->setDelayed(false); actionCollection->setDefaultShortcuts(newMenuAction, KStandardShortcut::openNew()); connect(newMenuAction, &QAction::triggered, this, &CreatorController::onNewActionTriggered); QAction* newEmptyDocumentAction = new QAction(QIcon::fromTheme(QStringLiteral("document-new")), i18nc("@item:inmenu create a new empty document", "Empty"), this); // newEmptyDocumentAction->setToolTip( factory-toolTip() ); // i18nc( "@info:tooltip", "Create an empty document" ) ); // newEmptyDocumentAction->setHelpText( factory->helpText() ); // i18nc( "@info:status", "Create an new, empty document" ) ); // newEmptyDocumentAction->setWhatsThis( factory->whatsThis() ); // i18nc( "@info:whatsthis", "." ) ); connect(newEmptyDocumentAction, &QAction::triggered, this, &CreatorController::onNewActionTriggered); QAction* newFromClipboardDocumentAction = new QAction(QIcon::fromTheme(QStringLiteral("edit-paste")), i18nc("@item:inmenu create a new document from data in the clipboard", "From Clipboard"), this); connect(newFromClipboardDocumentAction, &QAction::triggered, this, &CreatorController::onNewFromClipboardActionTriggered); newMenuAction->addAction(newEmptyDocumentAction); newMenuAction->addSeparator(); newMenuAction->addAction(newFromClipboardDocumentAction); // generators const QVector generatorList = mModelCodecManager->generatorList(); const bool hasGenerators = (!generatorList.isEmpty()); if (hasGenerators) { newMenuAction->addSeparator(); // TODO: ask factory which mimetypes it can read // AbstractDocumentFactory->canCreateFromData( QMimeData() ) needs already data for (AbstractModelDataGenerator* generator : generatorList) { const QString title = generator->typeName(); const QString iconName = QStringLiteral("document-new"); // generator->iconName(); QAction* action = new QAction(QIcon::fromTheme(iconName), title, this); action->setData(QVariant::fromValue(generator)); connect(action, &QAction::triggered, this, &CreatorController::onNewFromGeneratorActionTriggered); newMenuAction->addAction(action); } } actionCollection->addAction(QStringLiteral("file_new"), newMenuAction); } CreatorController::~CreatorController() = default; void CreatorController::setTargetModel(AbstractModel* model) { Q_UNUSED(model) } void CreatorController::onNewActionTriggered() { mDocumentStrategy->createNew(); } void CreatorController::onNewFromClipboardActionTriggered() { mDocumentStrategy->createNewFromClipboard(); } void CreatorController::onNewFromGeneratorActionTriggered() { auto* action = static_cast(sender()); auto* generator = action->data().value(); mDocumentStrategy->createNewWithGenerator(generator); } } diff --git a/libs/kasten/controllers/documentsystem/documentsbrowser/documentlistmodel.cpp b/libs/kasten/controllers/documentsystem/documentsbrowser/documentlistmodel.cpp index 28b329b8..0e175645 100644 --- a/libs/kasten/controllers/documentsystem/documentsbrowser/documentlistmodel.cpp +++ b/libs/kasten/controllers/documentsystem/documentsbrowser/documentlistmodel.cpp @@ -1,208 +1,208 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009,2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "documentlistmodel.hpp" // lib #include "documentstool.hpp" // Kasten core #include #include -// KF5 +// KF #include #include namespace Kasten { DocumentListModel::DocumentListModel(DocumentsTool* documentsTool, QObject* parent) : QAbstractTableModel(parent) , mDocumentsTool(documentsTool) { connect(mDocumentsTool, &DocumentsTool::documentsAdded, this, &DocumentListModel::onDocumentsAdded); connect(mDocumentsTool, &DocumentsTool::documentsClosing, this, &DocumentListModel::onDocumentsClosing); connect(mDocumentsTool, &DocumentsTool::focussedDocumentChanged, this, &DocumentListModel::onFocussedDocumentChanged); } DocumentListModel::~DocumentListModel() = default; int DocumentListModel::rowCount(const QModelIndex& parent) const { return (!parent.isValid()) ? mDocumentsTool->documents().size() : 0; } int DocumentListModel::columnCount(const QModelIndex& parent) const { return (!parent.isValid()) ? NoOfColumnIds : 0; } QVariant DocumentListModel::data(const QModelIndex& index, int role) const { QVariant result; if (role == Qt::DisplayRole) { const int documentIndex = index.row(); const AbstractDocument* document = mDocumentsTool->documents().at(documentIndex); const int tableColumn = index.column(); switch (tableColumn) { case TitleColumnId: result = document->title(); break; default: ; } } else if (role == Qt::DecorationRole) { const int documentIndex = index.row(); const AbstractDocument* document = mDocumentsTool->documents().at(documentIndex); const AbstractModelSynchronizer* synchronizer = document ? document->synchronizer() : nullptr; const int tableColumn = index.column(); switch (tableColumn) { case CurrentColumnId: if (document == mDocumentsTool->focussedDocument()) { result = QIcon::fromTheme(QStringLiteral("arrow-right")); } break; case LocalStateColumnId: if (synchronizer && synchronizer->localSyncState() == LocalHasChanges) { result = QIcon::fromTheme(QStringLiteral("document-save")); } break; case RemoteStateColumnId: // TODO: use static map, syncState int -> iconname if (!synchronizer) { result = QIcon::fromTheme(QStringLiteral("document-new")); } else { const RemoteSyncState remoteSyncState = synchronizer->remoteSyncState(); if (remoteSyncState == RemoteHasChanges) { result = QIcon::fromTheme(QStringLiteral("document-save")); } else if (remoteSyncState == RemoteDeleted) { result = QIcon::fromTheme(QStringLiteral("edit-delete")); } else if (remoteSyncState == RemoteUnknown) { result = QIcon::fromTheme(QStringLiteral("flag-yellow")); } else if (remoteSyncState == RemoteUnreachable) { result = QIcon::fromTheme(QStringLiteral("network-disconnect")); } } break; default: ; } } return result; } QVariant DocumentListModel::headerData(int section, Qt::Orientation orientation, int role) const { QVariant result; if (role == Qt::DisplayRole) { const QString titel = // section == LocalStateColumnId ? i18nc("@title:column Id of the version", "Id") : section == TitleColumnId ? i18nc("@title:column description of the change", "Title") : QString(); result = titel; } else if (role == Qt::ToolTipRole) { const QString titel = // section == LocalStateColumnId ? i18nc("@info:tooltip","Id of the version") : section == TitleColumnId ? i18nc("@info:tooltip", "Title of the document") : QString(); result = titel; } else { result = QAbstractTableModel::headerData(section, orientation, role); } return result; } void DocumentListModel::onFocussedDocumentChanged(AbstractDocument* document) { Q_UNUSED(document) beginResetModel(); endResetModel(); // TODO: store current focused document, then only emit for changed #if 0 const int oldVersionIndex = mVersionIndex; mVersionIndex = versionIndex; emit dataChanged(index(versionIndex, CurrentColumnId), index(versionIndex, CurrentColumnId)); emit dataChanged(index(oldVersionIndex, CurrentColumnId), index(oldVersionIndex, CurrentColumnId)); #endif } void DocumentListModel::onDocumentsAdded(const QVector& documents) { for (AbstractDocument* document : documents) { connect(document, &AbstractDocument::synchronizerChanged, this, &DocumentListModel::onSynchronizerChanged); AbstractModelSynchronizer* synchronizer = document->synchronizer(); if (synchronizer) { connect(synchronizer, &AbstractModelSynchronizer::localSyncStateChanged, this, &DocumentListModel::onSyncStatesChanged); connect(synchronizer, &AbstractModelSynchronizer::remoteSyncStateChanged, this, &DocumentListModel::onSyncStatesChanged); } } // TODO: try to understand how this would be done with {begin,end}{Insert,Remove}Columns beginResetModel(); endResetModel(); } void DocumentListModel::onDocumentsClosing(const QVector& documents) { Q_UNUSED(documents) // TODO: try to understand how this would be done with {begin,end}{Insert,Remove}Columns beginResetModel(); endResetModel(); } void DocumentListModel::onSynchronizerChanged(AbstractModelSynchronizer* synchronizer) { // TODO: what about the old synchronizer? assume it is deleted and that way disconnects? if (synchronizer) { connect(synchronizer, &AbstractModelSynchronizer::localSyncStateChanged, this, &DocumentListModel::onSyncStatesChanged); connect(synchronizer, &AbstractModelSynchronizer::remoteSyncStateChanged, this, &DocumentListModel::onSyncStatesChanged); } // TODO: try to understand how this would be done with {begin,end}{Insert,Remove}Columns beginResetModel(); endResetModel(); } void DocumentListModel::onSyncStatesChanged() { // TODO: try to understand how this would be done with {begin,end}{Insert,Remove}Columns beginResetModel(); endResetModel(); } } diff --git a/libs/kasten/controllers/documentsystem/documentsbrowser/documentstool.cpp b/libs/kasten/controllers/documentsystem/documentsbrowser/documentstool.cpp index ef17d03d..7d2d73eb 100644 --- a/libs/kasten/controllers/documentsystem/documentsbrowser/documentstool.cpp +++ b/libs/kasten/controllers/documentsystem/documentsbrowser/documentstool.cpp @@ -1,62 +1,62 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "documentstool.hpp" // Kasten core #include #include -// KF5 +// KF #include namespace Kasten { DocumentsTool::DocumentsTool(DocumentManager* documentManager) : mDocumentManager(documentManager) { setObjectName(QStringLiteral("Documents")); connect(mDocumentManager, &DocumentManager::added, this, &DocumentsTool::documentsAdded); connect(mDocumentManager, &DocumentManager::closing, this, &DocumentsTool::documentsClosing); } DocumentsTool::~DocumentsTool() = default; QVector DocumentsTool::documents() const { return mDocumentManager->documents(); } QString DocumentsTool::title() const { return i18nc("@title:window", "Documents"); } // TODO: this is an abuse of setTargetModel. Find other way to get focused model void DocumentsTool::setTargetModel(AbstractModel* model) { mFocussedDocument = model ? model->findBaseModel() : nullptr; emit focussedDocumentChanged(mFocussedDocument); } void DocumentsTool::setFocussedDocument(AbstractDocument* document) { mDocumentManager->requestFocus(document); } } diff --git a/libs/kasten/controllers/documentsystem/documentsbrowser/documentstoolviewfactory.cpp b/libs/kasten/controllers/documentsystem/documentsbrowser/documentstoolviewfactory.cpp index 4c2a27cb..5657bf45 100644 --- a/libs/kasten/controllers/documentsystem/documentsbrowser/documentstoolviewfactory.cpp +++ b/libs/kasten/controllers/documentsystem/documentsbrowser/documentstoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "documentstoolviewfactory.hpp" // lib #include "documentstoolview.hpp" #include "documentstool.hpp" -// KF5 +// KF #include namespace Kasten { DocumentsToolViewFactory::DocumentsToolViewFactory() = default; DocumentsToolViewFactory::~DocumentsToolViewFactory() = default; QString DocumentsToolViewFactory::iconName() const { return QStringLiteral("view-history"); } QString DocumentsToolViewFactory::title() const { return i18nc("@title:window", "Documents"); } QString DocumentsToolViewFactory::id() const { return QStringLiteral("org.kde.kasten.DocumentsToolView"); } SidePosition DocumentsToolViewFactory::defaultPosition() const { return LeftSidePosition; } AbstractToolView* DocumentsToolViewFactory::create(AbstractTool* tool) const { return new DocumentsToolView(qobject_cast(tool)); } } diff --git a/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowsertool.cpp b/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowsertool.cpp index f9438c87..7ce43d6f 100644 --- a/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowsertool.cpp +++ b/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowsertool.cpp @@ -1,83 +1,83 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "filesystembrowsertool.hpp" // Kasten core #include #include #include #include -// KF5 +// KF #include #include #include namespace Kasten { FileSystemBrowserTool::FileSystemBrowserTool(DocumentSyncManager* documentSyncManager) : mDocumentSyncManager(documentSyncManager) { setObjectName(QStringLiteral("FileSystemBrowser")); } FileSystemBrowserTool::~FileSystemBrowserTool() = default; QString FileSystemBrowserTool::title() const { return i18nc("@title:window", "Filesystem"); } QUrl FileSystemBrowserTool::currentUrl() const { QUrl result; if (mDocument) { result = KIO::upUrl(mDocumentSyncManager->urlOf(mDocument)); } return result; } bool FileSystemBrowserTool::hasCurrentUrl() const { return (mDocument && mDocument->synchronizer()); } void FileSystemBrowserTool::setTargetModel(AbstractModel* model) { const bool oldHasCurrentUrl = hasCurrentUrl(); mDocument = model ? model->findBaseModel() : nullptr; const bool newHasCurrentUrl = hasCurrentUrl(); if (oldHasCurrentUrl != newHasCurrentUrl) { emit hasCurrentUrlChanged(newHasCurrentUrl); } } void FileSystemBrowserTool::open(const QUrl& url) { mDocumentSyncManager->load(url); } } diff --git a/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowsertoolviewfactory.cpp b/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowsertoolviewfactory.cpp index 7eb2132a..e15d84f7 100644 --- a/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowsertoolviewfactory.cpp +++ b/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowsertoolviewfactory.cpp @@ -1,47 +1,47 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2010 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "filesystembrowsertoolviewfactory.hpp" // lib #include "filesystembrowsertoolview.hpp" #include "filesystembrowsertool.hpp" -// KF5 +// KF #include namespace Kasten { FileSystemBrowserToolViewFactory::FileSystemBrowserToolViewFactory() = default; FileSystemBrowserToolViewFactory::~FileSystemBrowserToolViewFactory() = default; QString FileSystemBrowserToolViewFactory::iconName() const { return QStringLiteral("folder"); } QString FileSystemBrowserToolViewFactory::title() const { return i18nc("@title:window", "Filesystem"); } QString FileSystemBrowserToolViewFactory::id() const { return QStringLiteral("org.kde.kasten.FileSystemBrowserToolView"); } SidePosition FileSystemBrowserToolViewFactory::defaultPosition() const { return LeftSidePosition; } AbstractToolView* FileSystemBrowserToolViewFactory::create(AbstractTool* tool) const { return new FileSystemBrowserToolView(qobject_cast(tool)); } } diff --git a/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowserview.cpp b/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowserview.cpp index be07d636..4dade68d 100644 --- a/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowserview.cpp +++ b/libs/kasten/controllers/documentsystem/filesystembrowser/filesystembrowserview.cpp @@ -1,123 +1,123 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "filesystembrowserview.hpp" // lib #include "filesystembrowsertool.hpp" -// KF5 +// KF #include #include #include #include #include #include // Qt #include #include #include namespace Kasten { FileSystemBrowserView::FileSystemBrowserView(FileSystemBrowserTool* tool, QWidget* parent) : QWidget(parent) , mTool(tool) { QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection); } FileSystemBrowserView::~FileSystemBrowserView() = default; void FileSystemBrowserView::init() { auto* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); // tool bar mToolbar = new KToolBar(this); mToolbar->setMovable(false); mToolbar->setToolButtonStyle(Qt::ToolButtonIconOnly); mToolbar->setIconDimensions(16); mToolbar->setContextMenuPolicy(Qt::NoContextMenu); layout->addWidget(mToolbar); // url bar auto* filePlacesModel = new KFilePlacesModel(this); mUrlNavigator = new KUrlNavigator(filePlacesModel, QUrl::fromLocalFile(QDir::homePath()), this); connect(mUrlNavigator, &KUrlNavigator::urlChanged, this, &FileSystemBrowserView::setDirOperatorUrl); layout->addWidget(mUrlNavigator); // view mDirOperator = new KDirOperator(QUrl::fromLocalFile(QDir::homePath()), this); mDirOperator->setView(KFile::Detail); connect(mDirOperator, &KDirOperator::urlEntered, this, &FileSystemBrowserView::setNavigatorUrl); connect(mDirOperator, &KDirOperator::fileSelected, this, &FileSystemBrowserView::openFile); layout->addWidget(mDirOperator); // fill toolbar constexpr const char* ToolbarActionNames[] = { "back", "forward", "up", "home", "short view", "detailed view", "tree view" }; const KActionCollection* dirOperatorActionCollection = mDirOperator->actionCollection(); for (auto* actionName : ToolbarActionNames) { QAction* action = dirOperatorActionCollection->action(QLatin1String(actionName)); if (action) { mToolbar->addAction(action); } } mActionCollection = new KActionCollection(this); QAction* syncDirAction = mActionCollection->addAction(QStringLiteral("sync_dir"), this, &FileSystemBrowserView::syncCurrentDocumentDirectory); syncDirAction->setIcon(QIcon::fromTheme(QStringLiteral("go-parent-folder"))); syncDirAction->setText(i18nc("@action:intoolbar", "Folder of Current Document")); connect(mTool, &FileSystemBrowserTool::hasCurrentUrlChanged, syncDirAction, &QAction::setEnabled); syncDirAction->setEnabled(mTool->hasCurrentUrl()); mToolbar->addAction(syncDirAction); } void FileSystemBrowserView::setDirOperatorUrl(const QUrl& url) { mDirOperator->setUrl(url, true); } void FileSystemBrowserView::setNavigatorUrl(const QUrl& url) { mUrlNavigator->setLocationUrl(url); } void FileSystemBrowserView::syncCurrentDocumentDirectory() { const QUrl url = mTool->currentUrl(); if (!url.isEmpty()) { setNavigatorUrl(url); } } void FileSystemBrowserView::openFile(const KFileItem& fileItem) { mTool->open(fileItem.url()); } } diff --git a/libs/kasten/controllers/documentsystem/loader/loadercontroller.cpp b/libs/kasten/controllers/documentsystem/loader/loadercontroller.cpp index 8100ab55..648c3cbd 100644 --- a/libs/kasten/controllers/documentsystem/loader/loadercontroller.cpp +++ b/libs/kasten/controllers/documentsystem/loader/loadercontroller.cpp @@ -1,94 +1,94 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2006-2008,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "loadercontroller.hpp" // Kasten Gui #include -// KF5 +// KF #include #include #include #include #include #include // Qt #include #include #include namespace Kasten { static constexpr char CreatorConfigGroupId[] = "Recent Files"; LoaderController::LoaderController(AbstractDocumentStrategy* documentStrategy, KXMLGUIClient* guiClient) : mDocumentStrategy(documentStrategy) { auto* openAction = KStandardAction::open(this, &LoaderController::load, this); mOpenRecentAction = KStandardAction::openRecent(this, &LoaderController::loadRecent, this); KActionCollection* const actionCollection = guiClient->actionCollection(); actionCollection->addAction(openAction->objectName(), openAction); actionCollection->addAction(mOpenRecentAction->objectName(), mOpenRecentAction); KConfigGroup configGroup(KSharedConfig::openConfig(), CreatorConfigGroupId); mOpenRecentAction->loadEntries(configGroup); connect(mDocumentStrategy, &AbstractDocumentStrategy::urlUsed, this, &LoaderController::onUrlUsed); } LoaderController::~LoaderController() { KConfigGroup configGroup(KSharedConfig::openConfig(), CreatorConfigGroupId); mOpenRecentAction->saveEntries(configGroup); } void LoaderController::setTargetModel(AbstractModel* model) { Q_UNUSED(model) } void LoaderController::load() { QFileDialog dialog; dialog.setMimeTypeFilters(mDocumentStrategy->supportedRemoteTypes()); if (dialog.exec() != 0) { const QList urls = dialog.selectedUrls(); for (const QUrl& url : urls) { mDocumentStrategy->load(url); } } } void LoaderController::loadRecent(const QUrl& url) { mDocumentStrategy->load(url); } void LoaderController::onUrlUsed(const QUrl& url) { mOpenRecentAction->addUrl(url); } } diff --git a/libs/kasten/controllers/io/clipboard/clipboardcontroller.cpp b/libs/kasten/controllers/io/clipboard/clipboardcontroller.cpp index d26b9717..e172cb61 100644 --- a/libs/kasten/controllers/io/clipboard/clipboardcontroller.cpp +++ b/libs/kasten/controllers/io/clipboard/clipboardcontroller.cpp @@ -1,150 +1,150 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2006-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "clipboardcontroller.hpp" // Kasten gui #include #include // Kasten core #include -// KF5 +// KF #include #include #include #include // Qt #include #include #include #include namespace Kasten { ClipboardController::ClipboardController(KXMLGUIClient* guiClient) { mCutAction = KStandardAction::cut( this, &ClipboardController::cut, this); mCopyAction = KStandardAction::copy( this, &ClipboardController::copy, this); mPasteAction = KStandardAction::paste(this, &ClipboardController::paste, this); guiClient->actionCollection()->addActions({ mCutAction, mCopyAction, mPasteAction, }); connect(QApplication::clipboard(), &QClipboard::dataChanged, this, &ClipboardController::onClipboardDataChanged); setTargetModel(nullptr); } void ClipboardController::setTargetModel(AbstractModel* model) { if (mModel) { mModel->disconnect(this); } mModel = model ? model->findBaseModelWithInterface() : nullptr; mSelectionControl = mModel ? qobject_cast(mModel) : nullptr; if (mSelectionControl) { connect(mModel, SIGNAL(hasSelectedDataChanged(bool)), SLOT(onHasSelectedDataChanged(bool))); mMimeDataControl = qobject_cast(mModel); if (mMimeDataControl) { connect(mModel, &AbstractModel::readOnlyChanged, this, &ClipboardController::onReadOnlyChanged); } } else { mMimeDataControl = nullptr; } const QMimeData* mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard); const bool hasSelectedData = mSelectionControl ? mSelectionControl->hasSelectedData() : false; const bool isWriteable = (mMimeDataControl && !mModel->isReadOnly()); const bool isPastable = isWriteable && !mimeData->formats().isEmpty() && mMimeDataControl->canReadData(mimeData); mCopyAction->setEnabled(hasSelectedData); mCutAction->setEnabled(hasSelectedData && isWriteable); mPasteAction->setEnabled(isPastable); } void ClipboardController::cut() { QMimeData* data = mMimeDataControl->cutSelectedData(); if (!data) { return; } QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard); } void ClipboardController::copy() { QMimeData* data = mSelectionControl->copySelectedData(); if (!data) { return; } QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard); } void ClipboardController::paste() { const QMimeData* data = QApplication::clipboard()->mimeData(QClipboard::Clipboard); mMimeDataControl->insertData(data); } void ClipboardController::onReadOnlyChanged(bool isReadOnly) { const QMimeData* mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard); const bool hasSelectedData = mSelectionControl ? mSelectionControl->hasSelectedData() : false; const bool isWriteable = !isReadOnly; const bool isPastable = isWriteable && !mimeData->formats().isEmpty() && mMimeDataControl->canReadData(mimeData); mCutAction->setEnabled(hasSelectedData && isWriteable); mPasteAction->setEnabled(isPastable); } void ClipboardController::onHasSelectedDataChanged(bool hasSelectedData) { const bool isWriteable = (mMimeDataControl && !mModel->isReadOnly()); mCopyAction->setEnabled(hasSelectedData); mCutAction->setEnabled(hasSelectedData && isWriteable); } void ClipboardController::onClipboardDataChanged() { const QMimeData* mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard); const bool isWriteable = (mMimeDataControl && !mModel->isReadOnly()); const bool isPastable = isWriteable && !mimeData->formats().isEmpty() && mMimeDataControl->canReadData(mimeData); mPasteAction->setEnabled(isPastable); } } diff --git a/libs/kasten/controllers/io/copyas/copyascontroller.cpp b/libs/kasten/controllers/io/copyas/copyascontroller.cpp index 2e7e013e..9b618482 100644 --- a/libs/kasten/controllers/io/copyas/copyascontroller.cpp +++ b/libs/kasten/controllers/io/copyas/copyascontroller.cpp @@ -1,155 +1,155 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2007-2008,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "copyascontroller.hpp" // lib #include "copyasdialog.hpp" // Kasten gui #include #include #include // Kasten core #include #include #include #include -// KF5 +// KF #include #include #include #include #include // Qt #include #include #include #include Q_DECLARE_METATYPE(Kasten::AbstractModelStreamEncoder*) namespace Kasten { CopyAsController::CopyAsController(ModelCodecViewManager* modelCodecViewManager, ModelCodecManager* modelCodecManager, KXMLGUIClient* guiClient) : mModelCodecViewManager(modelCodecViewManager) , mModelCodecManager(modelCodecManager) { mCopyAsSelectAction = new KSelectAction(QIcon::fromTheme(QStringLiteral("edit-copy")), i18nc("@title:menu", "Copy As"), this); mCopyAsSelectAction->setToolBarMode(KSelectAction::MenuMode); connect(mCopyAsSelectAction, QOverload::of(&KSelectAction::triggered), this, &CopyAsController::onActionTriggered); guiClient->actionCollection()->addAction(QStringLiteral("copy_as"), mCopyAsSelectAction); setTargetModel(nullptr); } void CopyAsController::setTargetModel(AbstractModel* model) { if (mModel) { mModel->disconnect(this); } mModel = model ? model->findBaseModelWithInterface() : nullptr; mSelectionControl = mModel ? qobject_cast(mModel) : nullptr; if (mSelectionControl) { // TODO: only fill the list on menu call... connect(mModel, SIGNAL(hasSelectedDataChanged(bool)), SLOT(updateActions())); } updateActions(); } void CopyAsController::updateActions() { mCopyAsSelectAction->removeAllActions(); const AbstractModelSelection* selection = mSelectionControl ? mSelectionControl->modelSelection() : nullptr; const QVector encoderList = mModelCodecManager->encoderList(mModel, selection); const bool hasEncoders = (!encoderList.isEmpty()); if (hasEncoders) { for (auto* encoder : encoderList) { const QString title = encoder->remoteTypeName(); auto* action = new QAction(title, mCopyAsSelectAction); action->setData(QVariant::fromValue(encoder)); mCopyAsSelectAction->addAction(action); } } else { QAction* noneAction = new QAction(i18nc("@item There are no encoders.", "Not available."), mCopyAsSelectAction); noneAction->setEnabled(false); mCopyAsSelectAction->addAction(noneAction); } // TODO: need a call AbstractModelSelection::isEmpty mCopyAsSelectAction->setEnabled(mSelectionControl && mSelectionControl->hasSelectedData()); } void CopyAsController::onActionTriggered(QAction* action) { auto* encoder = action->data().value(); const AbstractModelSelection* selection = mSelectionControl->modelSelection(); AbstractModelStreamEncoderConfigEditor* configEditor = mModelCodecViewManager->createConfigEditor(encoder); if (configEditor) { CopyAsDialog* dialog = new CopyAsDialog(encoder->remoteTypeName(), configEditor); dialog->setData(mModel, selection); if (dialog->exec() == 0) { return; } } QApplication::setOverrideCursor(Qt::WaitCursor); QByteArray exportData; QBuffer exportDataBuffer(&exportData); exportDataBuffer.open(QIODevice::WriteOnly); auto* encodeThread = new ModelStreamEncodeThread(this, &exportDataBuffer, mModel, selection, encoder); encodeThread->start(); while (!encodeThread->wait(100)) { QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); } delete encodeThread; exportDataBuffer.close(); auto* mimeData = new QMimeData; mimeData->setData(encoder->remoteClipboardMimeType(), exportData); QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); QApplication::restoreOverrideCursor(); } } diff --git a/libs/kasten/controllers/io/copyas/copyasdialog.cpp b/libs/kasten/controllers/io/copyas/copyasdialog.cpp index a3a3d78e..403fda85 100644 --- a/libs/kasten/controllers/io/copyas/copyasdialog.cpp +++ b/libs/kasten/controllers/io/copyas/copyasdialog.cpp @@ -1,119 +1,119 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008,2013 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "copyasdialog.hpp" // Kasten gui #include #include -// KF5 +// KF #include // Qt #include #include #include #include #include #include #include #include namespace Kasten { CopyAsDialog::CopyAsDialog(const QString& remoteTypeName, AbstractModelStreamEncoderConfigEditor* configEditor, QWidget* parent) : QDialog(parent) , mConfigEditor(configEditor) { setWindowTitle(i18nc("@title:window", "Copy As")); auto* splitter = new QSplitter(this); // config editor QWidget* editorPage = new QWidget(splitter); auto* editorPageLayout = new QVBoxLayout(editorPage); QLabel* editorLabel = new QLabel(remoteTypeName); QFont font = editorLabel->font(); font.setBold(true); editorLabel->setFont(font); editorPageLayout->addWidget(editorLabel); editorPageLayout->addWidget(mConfigEditor); editorPageLayout->addStretch(); splitter->addWidget(editorPage); splitter->setCollapsible(0, false); mPreviewView = configEditor->createPreviewView(); if (mPreviewView) { QGroupBox* previewBox = new QGroupBox(i18nc("@title:group", "Preview"), this); splitter->addWidget(previewBox); auto* previewBoxLayout = new QHBoxLayout(previewBox); previewBoxLayout->addWidget(mPreviewView->widget()); } // dialog buttons auto* dialogButtonBox = new QDialogButtonBox; QPushButton* exportButton = new QPushButton(QIcon::fromTheme(QStringLiteral("edit-copy")), i18nc("@action:button", "&Copy to clipboard")); exportButton->setToolTip(i18nc("@info:tooltip", "Copy the selected data to the clipboard.")); exportButton->setWhatsThis(xi18nc("@info:whatsthis", "If you press the Copy to clipboard " "button, the selected data will be copied to the clipboard " "with the settings you entered above.")); dialogButtonBox->addButton(exportButton, QDialogButtonBox::AcceptRole); connect(dialogButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); dialogButtonBox->addButton(QDialogButtonBox::Cancel); connect(dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); exportButton->setEnabled(configEditor->isValid()); connect(configEditor, &AbstractModelStreamEncoderConfigEditor::validityChanged, exportButton, &QWidget::setEnabled); // main layout auto* layout = new QVBoxLayout; layout->addWidget(splitter); layout->addStretch(); layout->addWidget(dialogButtonBox); setLayout(layout); } CopyAsDialog::~CopyAsDialog() { delete mPreviewView; } void CopyAsDialog::setData(AbstractModel* model, const AbstractModelSelection* selection) { if (mPreviewView) { mPreviewView->setData(model, selection); } } } diff --git a/libs/kasten/controllers/io/export/exportcontroller.cpp b/libs/kasten/controllers/io/export/exportcontroller.cpp index 4a3c7de3..4d1d24db 100644 --- a/libs/kasten/controllers/io/export/exportcontroller.cpp +++ b/libs/kasten/controllers/io/export/exportcontroller.cpp @@ -1,128 +1,128 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "exportcontroller.hpp" // lib #include "exportdialog.hpp" // Kasten gui #include #include #include // Kasten core #include #include #include -// KF5 +// KF #include #include #include #include #include Q_DECLARE_METATYPE(Kasten::AbstractModelExporter*) namespace Kasten { ExportController::ExportController(ModelCodecViewManager* modelCodecViewManager, ModelCodecManager* modelCodecManager, KXMLGUIClient* guiClient) : mModelCodecViewManager(modelCodecViewManager) , mModelCodecManager(modelCodecManager) { mExportSelectAction = new KSelectAction(QIcon::fromTheme(QStringLiteral("document-export")), i18nc("@title:menu", "Export"), this); mExportSelectAction->setToolBarMode(KSelectAction::MenuMode); connect(mExportSelectAction, QOverload::of(&KSelectAction::triggered), this, &ExportController::onActionTriggered); guiClient->actionCollection()->addAction(QStringLiteral("export"), mExportSelectAction); setTargetModel(nullptr); } void ExportController::setTargetModel(AbstractModel* model) { if (mModel) { mModel->disconnect(this); } mModel = model ? model->findBaseModelWithInterface() : nullptr; mSelectionControl = mModel ? qobject_cast(mModel) : nullptr; if (mSelectionControl) { // TODO: only fill the list on menu call... connect(mModel, SIGNAL(hasSelectedDataChanged(bool)), SLOT(updateActions())); } updateActions(); } void ExportController::updateActions() { mExportSelectAction->removeAllActions(); const AbstractModelSelection* selection = mSelectionControl ? mSelectionControl->modelSelection() : nullptr; const QVector exporterList = mModelCodecManager->exporterList(mModel, selection); const bool hasExporters = (!exporterList.isEmpty()); if (hasExporters) { for (auto* exporter : exporterList) { const QString title = exporter->remoteTypeName(); auto* action = new QAction(title, mExportSelectAction); action->setData(QVariant::fromValue(exporter)); mExportSelectAction->addAction(action); } } else { QAction* noneAction = new QAction(i18nc("@item There are no exporters.", "Not available."), mExportSelectAction); noneAction->setEnabled(false); mExportSelectAction->addAction(noneAction); } mExportSelectAction->setEnabled(mModel != nullptr); } void ExportController::onActionTriggered(QAction* action) { auto* exporter = action->data().value(); const AbstractModelSelection* selection = mSelectionControl ? mSelectionControl->modelSelection() : nullptr; AbstractModelExporterConfigEditor* configEditor = mModelCodecViewManager->createConfigEditor(exporter); if (configEditor) { ExportDialog* dialog = new ExportDialog(exporter->remoteTypeName(), configEditor); dialog->setData(mModel, selection); if (dialog->exec() == 0) { return; } } mModelCodecManager->exportDocument(exporter, mModel, selection); } } diff --git a/libs/kasten/controllers/io/export/exportdialog.cpp b/libs/kasten/controllers/io/export/exportdialog.cpp index dee47a4e..0b5c9bfa 100644 --- a/libs/kasten/controllers/io/export/exportdialog.cpp +++ b/libs/kasten/controllers/io/export/exportdialog.cpp @@ -1,119 +1,119 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008,2013 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "exportdialog.hpp" // Kasten gui #include #include -// KF5 +// KF #include // Qt #include #include #include #include #include #include #include #include namespace Kasten { ExportDialog::ExportDialog(const QString& remoteTypeName, AbstractModelExporterConfigEditor* configEditor, QWidget* parent) : QDialog(parent) , mConfigEditor(configEditor) { setWindowTitle(i18nc("@title:window", "Export")); auto* splitter = new QSplitter(this); // config editor QWidget* editorPage = new QWidget(splitter); auto* editorPageLayout = new QVBoxLayout(editorPage); QLabel* editorLabel = new QLabel(remoteTypeName); QFont font = editorLabel->font(); font.setBold(true); editorLabel->setFont(font); editorPageLayout->addWidget(editorLabel); editorPageLayout->addWidget(mConfigEditor); editorPageLayout->addStretch(); splitter->addWidget(editorPage); splitter->setCollapsible(0, false); mPreviewView = configEditor->createPreviewView(); if (mPreviewView) { QGroupBox* previewBox = new QGroupBox(i18nc("@title:group", "Preview"), this); splitter->addWidget(previewBox); auto* previewBoxLayout = new QHBoxLayout(previewBox); previewBoxLayout->addWidget(mPreviewView->widget()); } // dialog buttons auto* dialogButtonBox = new QDialogButtonBox; QPushButton* exportButton = new QPushButton(QIcon::fromTheme(QStringLiteral("document-export")), i18nc("@action:button", "&Export to File...")); exportButton->setToolTip(i18nc("@info:tooltip", "Export the selected data to a file.")); exportButton->setWhatsThis(xi18nc("@info:whatsthis", "If you press the Export to file " "button, the selected data will be copied to a file " "with the settings you entered above.")); dialogButtonBox->addButton(exportButton, QDialogButtonBox::AcceptRole); connect(dialogButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); dialogButtonBox->addButton(QDialogButtonBox::Cancel); connect(dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); exportButton->setEnabled(configEditor->isValid()); connect(configEditor, &AbstractModelExporterConfigEditor::validityChanged, exportButton, &QWidget::setEnabled); // main layout auto* layout = new QVBoxLayout; layout->addWidget(splitter); layout->addStretch(); layout->addWidget(dialogButtonBox); setLayout(layout); } ExportDialog::~ExportDialog() { delete mPreviewView; } void ExportDialog::setData(AbstractModel* model, const AbstractModelSelection* selection) { if (mPreviewView) { mPreviewView->setData(model, selection); } } } diff --git a/libs/kasten/controllers/io/insert/insertcontroller.cpp b/libs/kasten/controllers/io/insert/insertcontroller.cpp index 96c2c99b..4330b85b 100644 --- a/libs/kasten/controllers/io/insert/insertcontroller.cpp +++ b/libs/kasten/controllers/io/insert/insertcontroller.cpp @@ -1,158 +1,158 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "insertcontroller.hpp" // lib #include "insertdialog.hpp" // Kasten gui #include #include #include // Kasten core #include #include #include #include -// KF5 +// KF #include #include #include #include #include // Qt #include #include #ifndef KASTEN_ABSTRACTMODELDATAGENERATOR_METATYPE #define KASTEN_ABSTRACTMODELDATAGENERATOR_METATYPE Q_DECLARE_METATYPE(Kasten::AbstractModelDataGenerator*) #endif namespace Kasten { InsertController::InsertController(ModelCodecViewManager* modelCodecViewManager, ModelCodecManager* modelCodecManager, KXMLGUIClient* guiClient) : mModelCodecViewManager(modelCodecViewManager) , mModelCodecManager(modelCodecManager) { mInsertSelectAction = new KSelectAction(i18nc("@title:menu", "Insert"), this); // mInsertSelectAction->setIcon( QIcon::fromTheme( QStringLiteral("insert-text") ) ); mInsertSelectAction->setToolBarMode(KSelectAction::MenuMode); connect(mInsertSelectAction, QOverload::of(&KSelectAction::triggered), this, &InsertController::onActionTriggered); // TODO: find better id guiClient->actionCollection()->addAction(QStringLiteral("insert"), mInsertSelectAction); setTargetModel(nullptr); } void InsertController::setTargetModel(AbstractModel* model) { if (mModel) { mModel->disconnect(this); } mModel = model ? model->findBaseModelWithInterface() : nullptr; mSelectedDataWriteableControl = mModel ? qobject_cast(mModel) : nullptr; if (mSelectedDataWriteableControl) { // TODO: only fill the list on menu call... connect(mModel, &AbstractModel::readOnlyChanged, this, &InsertController::onReadOnlyChanged); } updateActions(); } void InsertController::updateActions() { mInsertSelectAction->removeAllActions(); // TODO: pass model to find which mimetypes it can read // mSelectedDataWriteableControl->canReadData( QMimeData() ) needs already data // TODO: it this depend on the current selection/focus? So it needs to be updated on every change? const QVector generatorList = mModelCodecManager->generatorList(); const bool hasGenerators = (!generatorList.isEmpty()); if (hasGenerators) { for (AbstractModelDataGenerator* generator : generatorList) { const QString title = generator->typeName(); auto* action = new QAction(title, mInsertSelectAction); action->setData(QVariant::fromValue(generator)); mInsertSelectAction->addAction(action); } } else { QAction* noneAction = new QAction(i18nc("@item There are no generators.", "Not available."), mInsertSelectAction); noneAction->setEnabled(false); mInsertSelectAction->addAction(noneAction); } // TODO: need a call AbstractModelSelection::isEmpty const bool isWriteable = (mSelectedDataWriteableControl && !mModel->isReadOnly()); mInsertSelectAction->setEnabled(isWriteable); } void InsertController::onActionTriggered(QAction* action) { auto* generator = action->data().value(); AbstractModelDataGeneratorConfigEditor* configEditor = mModelCodecViewManager->createConfigEditor(generator); if (configEditor) { auto* dialog = new InsertDialog(configEditor); // dialog->setData( mModel, selection ); TODO if (dialog->exec() == 0) { return; } } QApplication::setOverrideCursor(Qt::WaitCursor); auto* generateThread = new ModelDataGenerateThread(this, generator); generateThread->start(); while (!generateThread->wait(100)) { QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); } QMimeData* mimeData = generateThread->data(); delete generateThread; mSelectedDataWriteableControl->insertData(mimeData); QApplication::restoreOverrideCursor(); } void InsertController::onReadOnlyChanged(bool isReadOnly) { const bool isWriteable = (!isReadOnly); mInsertSelectAction->setEnabled(isWriteable); } } diff --git a/libs/kasten/controllers/io/insert/insertdialog.cpp b/libs/kasten/controllers/io/insert/insertdialog.cpp index 99514ea3..25913a86 100644 --- a/libs/kasten/controllers/io/insert/insertdialog.cpp +++ b/libs/kasten/controllers/io/insert/insertdialog.cpp @@ -1,81 +1,81 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009,2013 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "insertdialog.hpp" // Kasten gui #include -// KF5 +// KF #include // Qt #include #include #include #include #include namespace Kasten { InsertDialog::InsertDialog(AbstractModelDataGeneratorConfigEditor* configEditor, QWidget* parent) : QDialog(parent) , mConfigEditor(configEditor) { setWindowTitle(i18nc("@title:window", "Insert")); // editor QLabel* editorLabel = new QLabel(mConfigEditor->name()); QFont font = editorLabel->font(); font.setBold(true); editorLabel->setFont(font); // dialog buttons auto* dialogButtonBox = new QDialogButtonBox; QPushButton* insertButton = new QPushButton(i18nc("@action:button", "&Insert")); insertButton->setToolTip(i18nc("@info:tooltip", "Insert the generated data into the document.")); insertButton->setWhatsThis(xi18nc("@info:whatsthis", "If you press the Insert button, " "the data will be generated with the settings you entered above " "and inserted into the document at the cursor position.")); dialogButtonBox->addButton(insertButton, QDialogButtonBox::AcceptRole); connect(dialogButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); dialogButtonBox->addButton(QDialogButtonBox::Cancel); connect(dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); insertButton->setEnabled(configEditor->isValid()); connect(configEditor, &AbstractModelDataGeneratorConfigEditor::validityChanged, insertButton, &QWidget::setEnabled); // main layout auto* layout = new QVBoxLayout; layout->addWidget(editorLabel); layout->addWidget(mConfigEditor); layout->addStretch(); layout->addWidget(dialogButtonBox); setLayout(layout); } InsertDialog::~InsertDialog() = default; } diff --git a/libs/kasten/controllers/io/setremote/setremotecontroller.cpp b/libs/kasten/controllers/io/setremote/setremotecontroller.cpp index 43d2c911..00dcfa2b 100644 --- a/libs/kasten/controllers/io/setremote/setremotecontroller.cpp +++ b/libs/kasten/controllers/io/setremote/setremotecontroller.cpp @@ -1,64 +1,64 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2007-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "setremotecontroller.hpp" // Kasten core #include #include -// KF5 +// KF #include #include #include // Qt #include namespace Kasten { SetRemoteController::SetRemoteController(DocumentSyncManager* syncManager, KXMLGUIClient* guiClient) : mSyncManager(syncManager) { mSaveAsAction = KStandardAction::saveAs(this, &SetRemoteController::saveAs, this); guiClient->actionCollection()->addAction(mSaveAsAction->objectName(), mSaveAsAction); setTargetModel(nullptr); } void SetRemoteController::setTargetModel(AbstractModel* model) { mDocument = model ? model->findBaseModel() : nullptr; const bool canBeSaved = mDocument ? (mDocument->synchronizer() || mSyncManager->hasSynchronizerForLocal(mDocument->mimeType())) : false; mSaveAsAction->setEnabled(canBeSaved); } void SetRemoteController::saveAs() { mSyncManager->setSynchronizer(mDocument); } } diff --git a/libs/kasten/controllers/io/synchronize/synchronizecontroller.cpp b/libs/kasten/controllers/io/synchronize/synchronizecontroller.cpp index e4bfa06c..7cba3f13 100644 --- a/libs/kasten/controllers/io/synchronize/synchronizecontroller.cpp +++ b/libs/kasten/controllers/io/synchronize/synchronizecontroller.cpp @@ -1,138 +1,138 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2007-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "synchronizecontroller.hpp" // Kasten core #include #include #include -// KF5 +// KF #include #include #include #include // Qt #include #include namespace Kasten { SynchronizeController::SynchronizeController(DocumentSyncManager* syncManager, KXMLGUIClient* guiClient) : mSyncManager(syncManager) { KActionCollection* actionCollection = guiClient->actionCollection(); mSaveAction = KStandardAction::save(this, &SynchronizeController::save, this); mReloadAction = new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")), i18nc("@action:inmenu", "Reloa&d"), this); actionCollection->setDefaultShortcuts(mReloadAction, KStandardShortcut::reload()); connect(mReloadAction, &QAction::triggered, this, &SynchronizeController::reload); actionCollection->addAction(mSaveAction->objectName(), mSaveAction); actionCollection->addAction(QStringLiteral("file_reload"), mReloadAction); setTargetModel(nullptr); } void SynchronizeController::setTargetModel(AbstractModel* model) { if (mDocument) { mDocument->disconnect(this); } mDocument = model ? model->findBaseModel() : nullptr; if (mDocument) { connect(mDocument, &AbstractDocument::synchronizerChanged, this, &SynchronizeController::onSynchronizerChanged); } onSynchronizerChanged(mDocument ? mDocument->synchronizer() : nullptr); } void SynchronizeController::save() { mSyncManager->save(mDocument); } void SynchronizeController::reload() { mSyncManager->reload(mDocument); } void SynchronizeController::onSynchronizerChanged(AbstractModelSynchronizer* newSynchronizer) { if (mSynchronizer) { mSynchronizer->disconnect(this); } mSynchronizer = qobject_cast(newSynchronizer); // TODO: Storable interface should be used by Synchronizer // synchronizer should report about possible activities // TODO: check for access rights, may not write bool canSync = false; if (mSynchronizer) { const LocalSyncState localSyncState = mSynchronizer->localSyncState(); const RemoteSyncState remoteSyncState = mSynchronizer->remoteSyncState(); canSync = (localSyncState == LocalHasChanges) || (remoteSyncState == RemoteHasChanges) || (remoteSyncState == RemoteUnknown); connect(mSynchronizer, &AbstractModelSynchronizer::localSyncStateChanged, this, &SynchronizeController::onSyncStateChanged); connect(mSynchronizer, &AbstractModelSynchronizer::remoteSyncStateChanged, this, &SynchronizeController::onSyncStateChanged); connect(mSynchronizer, &QObject::destroyed, this, &SynchronizeController::onSynchronizerDeleted); } mSaveAction->setEnabled(canSync); mReloadAction->setEnabled(canSync); } void SynchronizeController::onSynchronizerDeleted(QObject* synchronizer) { if (synchronizer != mSynchronizer) { return; } mSynchronizer = nullptr; mSaveAction->setEnabled(false); mReloadAction->setEnabled(false); } void SynchronizeController::onSyncStateChanged() { const LocalSyncState localSyncState = mSynchronizer->localSyncState(); const RemoteSyncState remoteSyncState = mSynchronizer->remoteSyncState(); const bool canSync = (localSyncState == LocalHasChanges) || (remoteSyncState == RemoteHasChanges) || (remoteSyncState == RemoteUnknown); mSaveAction->setEnabled(canSync); mReloadAction->setEnabled(canSync); } } diff --git a/libs/kasten/controllers/program/quit/quitcontroller.cpp b/libs/kasten/controllers/program/quit/quitcontroller.cpp index 3f9b3105..e9ef8924 100644 --- a/libs/kasten/controllers/program/quit/quitcontroller.cpp +++ b/libs/kasten/controllers/program/quit/quitcontroller.cpp @@ -1,51 +1,51 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2006-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "quitcontroller.hpp" -// KF5 +// KF #include #include #include namespace Kasten { QuitController::QuitController(KXmlGuiWindow* window) : mMainWindow(window) { auto* quitAction = KStandardAction::quit(this, &QuitController::quit, this); mMainWindow->actionCollection()->addAction(quitAction->objectName(), quitAction); } void QuitController::setTargetModel(AbstractModel* model) { Q_UNUSED(model) } void QuitController::quit() { mMainWindow->close(); // Program->quit(); // TODO: think about a base program } } diff --git a/libs/kasten/controllers/shellwindow/fullscreen/fullscreencontroller.cpp b/libs/kasten/controllers/shellwindow/fullscreen/fullscreencontroller.cpp index f3f788a9..6e394987 100644 --- a/libs/kasten/controllers/shellwindow/fullscreen/fullscreencontroller.cpp +++ b/libs/kasten/controllers/shellwindow/fullscreen/fullscreencontroller.cpp @@ -1,52 +1,52 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2007-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "fullscreencontroller.hpp" -// KF5 +// KF #include #include #include #include namespace Kasten { FullScreenController::FullScreenController(KXmlGuiWindow* window) : mMainWindow(window) { auto* fullScreenAction = KStandardAction::fullScreen(this, &FullScreenController::switchFullScreen, window, this); mMainWindow->actionCollection()->addAction(fullScreenAction->objectName(), fullScreenAction); } void FullScreenController::setTargetModel(AbstractModel* model) { Q_UNUSED(model) } void FullScreenController::switchFullScreen(bool toFullScreen) { KToggleFullScreenAction::setFullScreen(mMainWindow, toFullScreen); } } diff --git a/libs/kasten/controllers/shellwindow/switchview/switchviewcontroller.cpp b/libs/kasten/controllers/shellwindow/switchview/switchviewcontroller.cpp index 50324d20..2abb2d7e 100644 --- a/libs/kasten/controllers/shellwindow/switchview/switchviewcontroller.cpp +++ b/libs/kasten/controllers/shellwindow/switchview/switchviewcontroller.cpp @@ -1,101 +1,101 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "switchviewcontroller.hpp" // Kasten gui #include #include -// KF5 +// KF #include #include // Qt #include namespace Kasten { SwitchViewController::SwitchViewController(AbstractGroupedViews* groupedViews, KXMLGUIClient* guiClient) : mGroupedViews(groupedViews) { mForwardAction = KStandardAction::forward(this, &SwitchViewController::forward, this); mBackwardAction = KStandardAction::back(this, &SwitchViewController::backward, this); KActionCollection* actionCollection = guiClient->actionCollection(); actionCollection->addAction(QStringLiteral("window_next"), mForwardAction); actionCollection->addAction(QStringLiteral("window_previous"), mBackwardAction); connect(groupedViews, &AbstractGroupedViews::added, this, &SwitchViewController::updateActions); connect(groupedViews, &AbstractGroupedViews::removing, this, &SwitchViewController::updateActions); connect(groupedViews, &AbstractGroupedViews::viewFocusChanged, this, &SwitchViewController::updateActions); updateActions(); } void SwitchViewController::setTargetModel(AbstractModel* model) { Q_UNUSED(model) } // TODO: think about moving this properties/abilities (hasNext/Previous,switchToNext/Previous) into a interface for the groupedview void SwitchViewController::updateActions() { bool hasNext; bool hasPrevious; const QVector viewList = mGroupedViews->viewList(); if (viewList.isEmpty()) { hasNext = false; hasPrevious = false; } else { AbstractView* focussedView = mGroupedViews->viewFocus(); const int indexOfFocussedView = viewList.indexOf(focussedView); hasNext = (indexOfFocussedView + 1 < viewList.count()); hasPrevious = (indexOfFocussedView > 0); } mForwardAction->setEnabled(hasNext); mBackwardAction->setEnabled(hasPrevious); } void SwitchViewController::forward() { const QVector viewList = mGroupedViews->viewList(); AbstractView* focussedView = mGroupedViews->viewFocus(); const int indexOfFocussedView = viewList.indexOf(focussedView); AbstractView* nextView = viewList.at(indexOfFocussedView + 1); mGroupedViews->setViewFocus(nextView); } void SwitchViewController::backward() { const QVector viewList = mGroupedViews->viewList(); AbstractView* focussedView = mGroupedViews->viewFocus(); const int indexOfFocussedView = viewList.indexOf(focussedView); AbstractView* previousView = viewList.at(indexOfFocussedView - 1); mGroupedViews->setViewFocus(previousView); } } diff --git a/libs/kasten/controllers/shellwindow/toollistmenu/toollistmenucontroller.cpp b/libs/kasten/controllers/shellwindow/toollistmenu/toollistmenucontroller.cpp index d72015b9..b2f40457 100644 --- a/libs/kasten/controllers/shellwindow/toollistmenu/toollistmenucontroller.cpp +++ b/libs/kasten/controllers/shellwindow/toollistmenu/toollistmenucontroller.cpp @@ -1,72 +1,72 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "toollistmenucontroller.hpp" // Kasten gui #include #include -// KF5 +// KF #include #include // Qt #include namespace Kasten { static constexpr char ToolListActionListId[] = "tools_list"; ToolListMenuController::ToolListMenuController(If::WidgetsDockable* widgetsDockable, KXMLGUIClient* guiClient) : mWidgetsDockable(widgetsDockable) , mGuiClient(guiClient) { // TODO: for now this is only called on start, so first create all tools/views before this controller updateActions(); } void ToolListMenuController::setTargetModel(AbstractModel* model) { Q_UNUSED(model) } void ToolListMenuController::updateActions() { mGuiClient->unplugActionList(QLatin1String(ToolListActionListId)); qDeleteAll(mToolActionList); mToolActionList.clear(); const QVector dockWidgets = mWidgetsDockable->dockWidgets(); mToolActionList.reserve(dockWidgets.size()); for (const ToolViewDockWidget* dockWidget : dockWidgets) { QAction* action = dockWidget->toggleViewAction(); action->setText(dockWidget->windowTitle()); // action->setText( mToolView->title() ); mToolActionList.append(action); } mGuiClient->plugActionList(QLatin1String(ToolListActionListId), mToolActionList); } } diff --git a/libs/kasten/controllers/shellwindow/viewareasplit/viewareasplitcontroller.cpp b/libs/kasten/controllers/shellwindow/viewareasplit/viewareasplitcontroller.cpp index aa330c3c..a8d5f4e7 100644 --- a/libs/kasten/controllers/shellwindow/viewareasplit/viewareasplitcontroller.cpp +++ b/libs/kasten/controllers/shellwindow/viewareasplit/viewareasplitcontroller.cpp @@ -1,153 +1,153 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewareasplitcontroller.hpp" // Kasten gui #include #include #include #include -// KF5 +// KF #include #include #include // Qt #include namespace Kasten { ViewAreaSplitController::ViewAreaSplitController(ViewManager* viewManager, AbstractGroupedViews* groupedViews, KXMLGUIClient* guiClient) : mViewManager(viewManager) , mGroupedViews(groupedViews) { mViewAreaSplitable = mGroupedViews ? qobject_cast(mGroupedViews) : nullptr; if (mViewAreaSplitable) { connect(mGroupedViews, SIGNAL(viewAreaFocusChanged(Kasten::AbstractViewArea*)), SLOT(onViewAreaFocusChanged(Kasten::AbstractViewArea*))); connect(mGroupedViews, SIGNAL(viewAreasAdded(QVector)), SLOT(onViewAreasChanged())); connect(mGroupedViews, SIGNAL(viewAreasRemoved(QVector)), SLOT(onViewAreasChanged())); } KActionCollection* actionCollection = guiClient->actionCollection(); mSplitVerticallyAction = new QAction(QIcon::fromTheme(QStringLiteral("view-split-left-right")), i18nc("@action:inmenu", "Split Vertically"), this); mSplitVerticallyAction->setObjectName(QStringLiteral("view_area_split_vertically")); actionCollection->setDefaultShortcut(mSplitVerticallyAction, Qt::CTRL + Qt::SHIFT + Qt::Key_L); mSplitVerticallyAction->setEnabled(mViewAreaSplitable != nullptr); connect(mSplitVerticallyAction, &QAction::triggered, this, &ViewAreaSplitController::splitVertically); mSplitHorizontallyAction = new QAction(QIcon::fromTheme(QStringLiteral("split")), i18nc("@action:inmenu", "Split Horizontal"), this); mSplitHorizontallyAction->setObjectName(QStringLiteral("view_area_split_horizontally")); actionCollection->setDefaultShortcut(mSplitHorizontallyAction, Qt::CTRL + Qt::SHIFT + Qt::Key_T); mSplitHorizontallyAction->setEnabled(mViewAreaSplitable != nullptr); connect(mSplitHorizontallyAction, &QAction::triggered, this, &ViewAreaSplitController::splitHorizontally); mCloseAction = new QAction(QIcon::fromTheme(QStringLiteral("view-close")), i18nc("@action:inmenu", "Close View Area"), this); mCloseAction->setObjectName(QStringLiteral("view_area_close")); actionCollection->setDefaultShortcut(mCloseAction, Qt::CTRL + Qt::SHIFT + Qt::Key_R); connect(mCloseAction, &QAction::triggered, this, &ViewAreaSplitController::close); actionCollection->addActions({ mSplitVerticallyAction, mSplitHorizontallyAction, mCloseAction, }); onViewAreaFocusChanged(mViewAreaSplitable ? mViewAreaSplitable->viewAreaFocus() : nullptr); onViewAreasChanged(); } void ViewAreaSplitController::setTargetModel(AbstractModel* model) { Q_UNUSED(model) } void ViewAreaSplitController::splitVertically() { splitViewArea(Qt::Vertical); } void ViewAreaSplitController::splitHorizontally() { splitViewArea(Qt::Horizontal); } void ViewAreaSplitController::close() { mViewAreaSplitable->closeViewArea(mCurrentViewArea); } void ViewAreaSplitController::splitViewArea(Qt::Orientation orientation) { AbstractView* currentView = mCurrentViewArea->viewFocus(); mViewAreaSplitable->splitViewArea(mCurrentViewArea, orientation); // TODO: ideal would be a new view which copies the existing one // and starts visually where the old one stops after the resize const Qt::Alignment alignment = (orientation == Qt::Horizontal) ? Qt::AlignBottom : Qt::AlignRight; mViewManager->createCopyOfView(currentView, alignment); } void ViewAreaSplitController::onViewAreaFocusChanged(AbstractViewArea* viewArea) { if (mCurrentViewArea) { mCurrentViewArea->disconnect(this); } // TODO: how to handle single view areas? examples, signals? mCurrentViewArea = qobject_cast(viewArea); if (mCurrentViewArea) { connect(mCurrentViewArea, &AbstractGroupedViews::added, this, &ViewAreaSplitController::onViewsChanged); connect(mCurrentViewArea, &AbstractGroupedViews::removing, this, &ViewAreaSplitController::onViewsChanged); } onViewsChanged(); } void ViewAreaSplitController::onViewAreasChanged() { const bool hasMultipleViewArea = mViewAreaSplitable ? (mViewAreaSplitable->viewAreasCount() > 1) : false; mCloseAction->setEnabled(hasMultipleViewArea); } void ViewAreaSplitController::onViewsChanged() { const bool hasViews = mCurrentViewArea ? (mCurrentViewArea->viewCount() > 0) : false; mSplitVerticallyAction->setEnabled(hasViews); mSplitHorizontallyAction->setEnabled(hasViews); } } diff --git a/libs/kasten/controllers/shellwindow/viewlistmenu/viewlistmenucontroller.cpp b/libs/kasten/controllers/shellwindow/viewlistmenu/viewlistmenucontroller.cpp index 41c79aa7..7f65882c 100644 --- a/libs/kasten/controllers/shellwindow/viewlistmenu/viewlistmenucontroller.cpp +++ b/libs/kasten/controllers/shellwindow/viewlistmenu/viewlistmenucontroller.cpp @@ -1,107 +1,107 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2006-2007 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "viewlistmenucontroller.hpp" // Kasten gui #include #include // Kasten core #include -// KF5 +// KF #include #include #include #include #include // Qt #include Q_DECLARE_METATYPE(Kasten::AbstractView*) namespace Kasten { static constexpr int MaxEntryLength = 150; static constexpr char WindowsListActionListId[] = "windows_list"; ViewListMenuController::ViewListMenuController(ViewManager* viewManager, AbstractGroupedViews* groupedViews, KXMLGUIClient* guiClient) : mViewManager(viewManager) , mGroupedViews(groupedViews) , mGuiClient(guiClient) { mWindowsActionGroup = new QActionGroup(this); // TODO: do we use this only for the signal mapping? // mWindowsActionGroup->setExclusive( true ); connect(mWindowsActionGroup, &QActionGroup::triggered, this, &ViewListMenuController::onActionTriggered); connect(mViewManager, &ViewManager::opened, this, &ViewListMenuController::updateActions); connect(mViewManager, &ViewManager::closing, this, &ViewListMenuController::updateActions); updateActions(); } void ViewListMenuController::setTargetModel(AbstractModel* model) { Q_UNUSED(model) } void ViewListMenuController::updateActions() { mGuiClient->unplugActionList(QLatin1String(WindowsListActionListId)); qDeleteAll(mWindowsActionGroup->actions()); const QVector views = mViewManager->views(); const bool hasViews = (!views.isEmpty()); if (hasViews) { // TODO: sortieren nach namen und erste 10 mit Zahl, siehe unten for (int v = 0; v < views.size(); ++v) { AbstractView* view = views.at(v); const QString title = KStringHandler::rsqueeze(view->title(), MaxEntryLength); QAction* action = new QAction(v < 9 ? QStringLiteral("&%1 %2").arg(v + 1).arg(title) : title, mWindowsActionGroup); // action->setCheckable( true ); // if(m_viewManager->activeView() && doc == m_viewManager->activeView()->document()) // action->setChecked(true); action->setData(QVariant::fromValue(view)); mWindowsActionGroup->addAction(action); } } else { QAction* noneAction = new QAction(i18nc("@item There are no windows.", "None."), mWindowsActionGroup); mWindowsActionGroup->addAction(noneAction); } mWindowsActionGroup->setEnabled(hasViews); mGuiClient->plugActionList(QLatin1String(WindowsListActionListId), mWindowsActionGroup->actions()); } void ViewListMenuController::onActionTriggered(QAction* action) { auto* view = action->data().value(); mGroupedViews->setViewFocus(view); } } diff --git a/libs/kasten/controllers/view/select/selectcontroller.cpp b/libs/kasten/controllers/view/select/selectcontroller.cpp index 4a090c8b..80041032 100644 --- a/libs/kasten/controllers/view/select/selectcontroller.cpp +++ b/libs/kasten/controllers/view/select/selectcontroller.cpp @@ -1,83 +1,83 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2006-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "selectcontroller.hpp" // Kasten gui #include #include -// KF5 +// KF #include #include #include #include // Qt #include namespace Kasten { SelectController::SelectController(KXMLGUIClient* guiClient) { mSelectAllAction = KStandardAction::selectAll(this, &SelectController::selectAll, this); mDeselectAction = KStandardAction::deselect( this, &SelectController::unselect, this); KActionCollection* actionCollection = guiClient->actionCollection(); actionCollection->addAction(mSelectAllAction->objectName(), mSelectAllAction); actionCollection->addAction(mDeselectAction->objectName(), mDeselectAction); setTargetModel(nullptr); } void SelectController::setTargetModel(AbstractModel* model) { if (mModel) { mModel->disconnect(this); } mModel = model ? model->findBaseModelWithInterface() : nullptr; mSelectControl = mModel ? qobject_cast(mModel) : nullptr; const bool hasSelectionControl = (mSelectControl != nullptr); if (hasSelectionControl) { connect(mModel, SIGNAL(hasSelectedDataChanged(bool)), SLOT(onHasSelectedDataChanged(bool))); } mSelectAllAction->setEnabled(hasSelectionControl); mDeselectAction->setEnabled(hasSelectionControl ? mSelectControl->hasSelectedData() : false); } void SelectController::onHasSelectedDataChanged(bool hasSelectedData) { mDeselectAction->setEnabled(hasSelectedData); } void SelectController::selectAll() { mSelectControl->selectAllData(true); } void SelectController::unselect() { mSelectControl->selectAllData(false); } } diff --git a/libs/kasten/controllers/view/version/versioncontroller.cpp b/libs/kasten/controllers/view/version/versioncontroller.cpp index 4327a948..4cba8b05 100644 --- a/libs/kasten/controllers/view/version/versioncontroller.cpp +++ b/libs/kasten/controllers/view/version/versioncontroller.cpp @@ -1,193 +1,193 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "versioncontroller.hpp" // Kasten core #include #include #include -// KF5 +// KF #include #include #include #include #include // Qt #include namespace Kasten { static constexpr int MaxMenuEntries = 10; VersionController::VersionController(KXMLGUIClient* guiClient) { KActionCollection* actionCollection = guiClient->actionCollection(); mSetToOlderVersionAction = new KToolBarPopupAction(QIcon::fromTheme(QStringLiteral("edit-undo")), i18nc("@action:inmenu", "Undo"), this); actionCollection->addAction(QStringLiteral("edit_undo"), mSetToOlderVersionAction); actionCollection->setDefaultShortcuts(mSetToOlderVersionAction, KStandardShortcut::undo()); connect(mSetToOlderVersionAction, &QAction::triggered, this, &VersionController::onSetToOlderVersionTriggered); connect(mSetToOlderVersionAction->menu(), &QMenu::aboutToShow, this, &VersionController::onOlderVersionMenuAboutToShow); connect(mSetToOlderVersionAction->menu(), &QMenu::triggered, this, &VersionController::onOlderVersionMenuTriggered); mSetToNewerVersionAction = new KToolBarPopupAction(QIcon::fromTheme(QStringLiteral("edit-redo")), i18nc("@action:inmenu", "Redo"), this); actionCollection->addAction(QStringLiteral("edit_redo"), mSetToNewerVersionAction); actionCollection->setDefaultShortcuts(mSetToNewerVersionAction, KStandardShortcut::redo()); connect(mSetToNewerVersionAction, &QAction::triggered, this, &VersionController::onSetToNewerVersionTriggered); connect(mSetToNewerVersionAction->menu(), &QMenu::aboutToShow, this, &VersionController::onNewerVersionMenuAboutToShow); connect(mSetToNewerVersionAction->menu(), &QMenu::triggered, this, &VersionController::onNewerVersionMenuTriggered); setTargetModel(nullptr); } void VersionController::setTargetModel(AbstractModel* model) { if (mModel) { mModel->disconnect(this); AbstractModel* versionedModel = mModel->findBaseModelWithInterface(); if (versionedModel) { versionedModel->disconnect(this); } } mModel = model; AbstractModel* versionedModel = mModel ? mModel->findBaseModelWithInterface() : nullptr; mVersionControl = versionedModel ? qobject_cast(versionedModel) : nullptr; if (mVersionControl) { connect(versionedModel, SIGNAL(revertedToVersionIndex(int)), SLOT(onVersionIndexChanged(int))); connect(versionedModel, SIGNAL(headVersionChanged(int)), SLOT(onVersionIndexChanged(int))); connect(mModel, &AbstractModel::readOnlyChanged, this, &VersionController::onReadOnlyChanged); } else { mModel = nullptr; } const bool isVersionable = (mVersionControl && !mModel->isReadOnly()); if (isVersionable) { onVersionIndexChanged(mVersionControl->versionIndex()); } else { mSetToOlderVersionAction->setEnabled(false); mSetToNewerVersionAction->setEnabled(false); } } void VersionController::onVersionIndexChanged(int versionIndex) { const bool hasOlderVersions = (versionIndex > 0); mSetToOlderVersionAction->setEnabled(hasOlderVersions); if (hasOlderVersions) { mSetToOlderVersionAction->setData(versionIndex - 1); } const bool hasNewerVersions = (versionIndex < (mVersionControl->versionCount() - 1)); mSetToNewerVersionAction->setEnabled(hasNewerVersions); if (hasNewerVersions) { mSetToNewerVersionAction->setData(versionIndex + 1); } } void VersionController::onSetToOlderVersionTriggered() { const int versionIndex = mSetToOlderVersionAction->data().toInt(); mVersionControl->revertToVersionByIndex(versionIndex); } void VersionController::onSetToNewerVersionTriggered() { const int versionIndex = mSetToNewerVersionAction->data().toInt(); mVersionControl->revertToVersionByIndex(versionIndex); } void VersionController::onOlderVersionMenuAboutToShow() { QMenu* menu = mSetToOlderVersionAction->menu(); menu->clear(); int menuEntries = 0; for (int versionIndex = mVersionControl->versionIndex(); versionIndex > 0 && menuEntries < MaxMenuEntries; --versionIndex, ++menuEntries) { DocumentVersionData versionData = mVersionControl->versionData(versionIndex); const QString changeComment = versionData.changeComment(); const QString actionText = i18nc("@action Undo: [change]", "Undo: %1", changeComment); QAction* action = menu->addAction(actionText); action->setData(versionIndex - 1); } } void VersionController::onNewerVersionMenuAboutToShow() { QMenu* menu = mSetToNewerVersionAction->menu(); menu->clear(); int menuEntries = 0; for (int versionIndex = mVersionControl->versionIndex() + 1; versionIndex < mVersionControl->versionCount() && menuEntries < MaxMenuEntries; ++versionIndex, ++menuEntries) { DocumentVersionData versionData = mVersionControl->versionData(versionIndex); const QString changeComment = versionData.changeComment(); const QString actionText = i18nc("@action Redo: [change]", "Redo: %1", changeComment); QAction* action = menu->addAction(actionText); action->setData(versionIndex); } } void VersionController::onOlderVersionMenuTriggered(QAction* action) { const int versionIndex = action->data().toInt(); mVersionControl->revertToVersionByIndex(versionIndex); } void VersionController::onNewerVersionMenuTriggered(QAction* action) { const int versionIndex = action->data().toInt(); mVersionControl->revertToVersionByIndex(versionIndex); } void VersionController::onReadOnlyChanged(bool isReadOnly) { if (isReadOnly) { mSetToOlderVersionAction->setEnabled(false); mSetToNewerVersionAction->setEnabled(false); } else { onVersionIndexChanged(mVersionControl->versionIndex()); } } } diff --git a/libs/kasten/controllers/view/zoom/zoomcontroller.cpp b/libs/kasten/controllers/view/zoom/zoomcontroller.cpp index 917358b9..df532253 100644 --- a/libs/kasten/controllers/view/zoom/zoomcontroller.cpp +++ b/libs/kasten/controllers/view/zoom/zoomcontroller.cpp @@ -1,150 +1,150 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2006-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "zoomcontroller.hpp" // Kasten gui #include // Kasten core #include -// KF5 +// KF #include #include #include #include // Qt #include namespace Kasten { ZoomController::ZoomController(KXMLGUIClient* guiClient) { mZoomInAction = KStandardAction::zoomIn( this, &ZoomController::zoomIn, this); mZoomOutAction = KStandardAction::zoomOut(this, &ZoomController::zoomOut, this); guiClient->actionCollection()->addActions({ mZoomInAction, mZoomOutAction }); #if 0 ZoomToAction = new KSelectAction(i18n("Zoom"), "viewmag", 0, ActionCollection, "zoomTo"); ZoomToAction->setEditable(true); QList mags = DisplayOptions::normalMagnificationValues(); QStringList translated; int idx = 0; int cur = 0; for (QList::iterator first = mags.begin(), last = mags.end(); first != last; ++first) { translated << i18nc("zoom-factor (percentage)", "%1%", *first * 100.0); if (*first == 1.0) { idx = cur; } ++cur; } ZoomToAction->setItems(translated); ZoomToAction->setCurrentItem(idx); connect(ZoomToAction, SIGNAL(triggered(QString)), SLOT(zoomTo(QString))); // TODO: name size relative to object or view? name object(variable) or view? // TODO: is this a sticking parameter? FitToWidthAction = new KAction(i18n("&Fit to Width"), ActionCollection, "fit_to_width"); connect(FitWidthAction, SIGNAL(triggered(bool)), SLOT(fitToWidth())); FitToHeightAction = new KAction(i18n("&Fit to Height"), ActionCollection, "fit_to_height"); connect(FitWidthAction, SIGNAL(triggered(bool)), SLOT(fitToHeight())); FitToSizeAction = new KAction(i18n("&Fit to Size"), ActionCollection, "fit_to_size"); connect(FitToSizeAction, SIGNAL(triggered(bool)), SLOT(fitToSize())); #endif setTargetModel(nullptr); } void ZoomController::setTargetModel(AbstractModel* model) { if (mModel) { mModel->disconnect(this); } mModel = model ? model->findBaseModelWithInterface() : nullptr; mZoomControl = mModel ? qobject_cast(mModel) : nullptr; if (mZoomControl) { mZoomLevel = mZoomControl->zoomLevel(); connect(mModel, SIGNAL(zoomLevelChanged(double)), SLOT(onZoomLevelChange(double))); } const bool hasView = (mZoomControl != nullptr); mZoomInAction->setEnabled(hasView); mZoomOutAction->setEnabled(hasView); } void ZoomController::zoomIn() { mZoomControl->setZoomLevel(mZoomLevel * 1.10); } void ZoomController::zoomOut() { mZoomControl->setZoomLevel(mZoomLevel / 1.10); } #if 0 void ZoomController::zoomTo(const QString& nz) { QString z = nz; double zoom; z.remove(z.indexOf('%'), 1); zoom = KLocale::global()->readNumber(z) / 100; qCDebug(LOG_KASTEN_CONTROLLERS) << "ZOOM = " << nz << ", setting zoom = " << zoom << endl; DisplayOptions options = miniWidget()->displayOptions(); options.setMagnification(zoom); miniWidget()->setDisplayOptions(options); miniWidget()->redisplay(); _mainWidget->setFocus(); updateZoomActions(); } void ZoomController::fitToWidth() { if (pageView()->page()) { miniWidget()->fitWidth(pageView()->viewport()->width() - 16); } // We subtract 16 pixels because of the page decoration. updateZoomActions(); } void ZoomController::fitToSize() { if (pageView()->page()) { miniWidget()->fitWidthHeight(pageView()->viewport()->width() - 16, pageView()->viewport()->height() - 16); } updateZoomActions(); } #endif void ZoomController::onZoomLevelChange(double level) { mZoomLevel = level; } } diff --git a/libs/kasten/controllers/view/zoom/zoomslider.cpp b/libs/kasten/controllers/view/zoom/zoomslider.cpp index 61e8377f..ef14fd5c 100644 --- a/libs/kasten/controllers/view/zoom/zoomslider.cpp +++ b/libs/kasten/controllers/view/zoom/zoomslider.cpp @@ -1,178 +1,178 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "zoomslider.hpp" // Kasten gui #include // Kasten core #include -// KF5 +// KF #include // Qt #include #include #include #include #include namespace Kasten { static constexpr int ZoomSliderWidth = 150; // TODO: look at Dolphin/Krita/KOffice zoom tool // TODO: different zoom strategies: fixed step size, relative step size // where to put this, behind interface? or better into a zoomtool? ZoomSlider::ZoomSlider(QWidget* parent) : QWidget(parent) { mZoomOutButton = new QToolButton(this); mZoomOutButton->setIcon(QIcon::fromTheme(QStringLiteral("zoom-out"))); mZoomOutButton->setAutoRaise(true); mSlider = new QSlider(Qt::Horizontal, this); mZoomInButton = new QToolButton(this); mZoomInButton->setIcon(QIcon::fromTheme(QStringLiteral("zoom-in"))); mZoomInButton->setAutoRaise(true); auto* layout = new QHBoxLayout(this); layout->setSpacing(0); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(mZoomOutButton); layout->addWidget(mSlider); layout->addWidget(mZoomInButton); connect(mZoomOutButton, &QAbstractButton::clicked, this, &ZoomSlider::zoomOut); connect(mZoomInButton, &QAbstractButton::clicked, this, &ZoomSlider::zoomIn); connect(mSlider, &QSlider::valueChanged, this, &ZoomSlider::onSliderValueChanged); connect(mSlider, &QSlider::sliderMoved, this, &ZoomSlider::onSliderMoved); setFixedWidth(ZoomSliderWidth); setTargetModel(nullptr); } ZoomSlider::~ZoomSlider() = default; void ZoomSlider::setTargetModel(AbstractModel* model) { if (mModel) { mModel->disconnect(this); } mModel = model ? model->findBaseModelWithInterface() : nullptr; mZoomControl = mModel ? qobject_cast(mModel) : nullptr; const bool hasView = (mZoomControl != nullptr); if (hasView) { mSlider->setSingleStep(1); // mZoomControl->zoomLevelSingleStep()? mSlider->setPageStep(5); // mZoomControl->zoomLevelPageStep()? const int min = 0; // mZoomControl->minimumZoomLevel(); const int max = 99; // mZoomControl->maximumZoomLevel(); mSlider->setRange(min, max); onZoomLevelChange(mZoomControl->zoomLevel()); const int sliderValue = mSlider->value(); mZoomOutButton->setEnabled(sliderValue > mSlider->minimum()); mZoomInButton->setEnabled(sliderValue < mSlider->maximum()); connect(mModel, SIGNAL(zoomLevelChanged(double)), SLOT(onZoomLevelChange(double))); } else { mZoomOutButton->setEnabled(false); mZoomInButton->setEnabled(false); // put slider in the middle mSlider->setRange(0, 99); mSlider->setValue(50); } mSlider->setEnabled(hasView); } void ZoomSlider::updateToolTip(int sliderValue) { const float zoomLevel = 50.0 / (100 - sliderValue); const int zoomPercent = static_cast(zoomLevel * 100 + 0.5); mSlider->setToolTip(i18nc("@info:tooltip", "Zoom: %1%", zoomPercent)); // TODO: get the text by a signal toolTipNeeded( int zoomLevel, QString* toolTipText ); ? } void ZoomSlider::zoomOut() { const int newValue = mSlider->value() - mSlider->singleStep(); mSlider->setValue(newValue); } void ZoomSlider::zoomIn() { const int newValue = mSlider->value() + mSlider->singleStep(); mSlider->setValue(newValue); } void ZoomSlider::onSliderValueChanged(int sliderValue) { updateToolTip(sliderValue); mZoomOutButton->setEnabled(sliderValue > mSlider->minimum()); mZoomInButton->setEnabled(sliderValue < mSlider->maximum()); if (mZoomControl) { mZoomControl->setZoomLevel(50.0 / (100 - sliderValue)); } } // TODO: which signal comes first, valueChanged or sliderMoved? // ensure correct calculation of zoomLevel, best by model // but can be timeconsuming? // use timer to delay resize, so that sliding is not delayed by resizing void ZoomSlider::onSliderMoved(int sliderValue) { Q_UNUSED(sliderValue) QPoint toolTipPoint = mSlider->rect().topLeft(); toolTipPoint.ry() += mSlider->height() / 2; toolTipPoint = mSlider->mapToGlobal(toolTipPoint); QHelpEvent toolTipEvent(QEvent::ToolTip, QPoint(0, 0), toolTipPoint); QApplication::sendEvent(mSlider, &toolTipEvent); } void ZoomSlider::onZoomLevelChange(double level) { mZoomLevel = level; const int newSliderValue = 100 - static_cast(50.0 / mZoomLevel + 0.5); if (newSliderValue != mSlider->value()) { disconnect(mSlider, &QSlider::valueChanged, this, &ZoomSlider::onSliderValueChanged); mSlider->setSliderPosition(newSliderValue); updateToolTip(mSlider->value()); connect(mSlider, &QSlider::valueChanged, this, &ZoomSlider::onSliderValueChanged); } } } diff --git a/libs/kasten/controllers/viewsystem/close/closecontroller.cpp b/libs/kasten/controllers/viewsystem/close/closecontroller.cpp index d9ce8d83..502b8c92 100644 --- a/libs/kasten/controllers/viewsystem/close/closecontroller.cpp +++ b/libs/kasten/controllers/viewsystem/close/closecontroller.cpp @@ -1,60 +1,60 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2006-2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "closecontroller.hpp" // Kasten gui #include -// KF5 +// KF #include #include #include // Qt #include namespace Kasten { CloseController::CloseController(ViewManager* viewManager, KXMLGUIClient* guiClient) : mViewManager(viewManager) { mCloseAction = KStandardAction::close(this, &CloseController::close, this); guiClient->actionCollection()->addAction(mCloseAction->objectName(), mCloseAction); setTargetModel(0); } void CloseController::setTargetModel(AbstractModel* model) { mView = model ? model->findBaseModel() : 0; const bool hasView = (mView != 0); mCloseAction->setEnabled(hasView); } void CloseController::close() { mViewManager->closeView(mView); } } diff --git a/libs/kasten/core/io/abstractconnectjob.hpp b/libs/kasten/core/io/abstractconnectjob.hpp index 18313e12..65421fb3 100644 --- a/libs/kasten/core/io/abstractconnectjob.hpp +++ b/libs/kasten/core/io/abstractconnectjob.hpp @@ -1,57 +1,57 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_ABSTRACTCONNECTJOB_HPP #define KASTEN_ABSTRACTCONNECTJOB_HPP // lib #include -// KF5 +// KF #include namespace Kasten { class AbstractConnectJobPrivate; class KASTENCORE_EXPORT AbstractConnectJob : public KJob { Q_OBJECT protected: explicit AbstractConnectJob(AbstractConnectJobPrivate* d); public: AbstractConnectJob(); ~AbstractConnectJob() override; protected: // emits documentLoaded() // TODO: or better name property LoadedDocument? protected: const QScopedPointer d_ptr; }; } #endif diff --git a/libs/kasten/core/io/abstractexportjob.hpp b/libs/kasten/core/io/abstractexportjob.hpp index 981f3459..ff3f9a78 100644 --- a/libs/kasten/core/io/abstractexportjob.hpp +++ b/libs/kasten/core/io/abstractexportjob.hpp @@ -1,69 +1,69 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_ABSTRACTEXPORTJOB_HPP #define KASTEN_ABSTRACTEXPORTJOB_HPP // lib #include -// KF5 +// KF #include namespace Kasten { class AbstractDocument; class AbstractExportJobPrivate; class KASTENCORE_EXPORT AbstractExportJob : public KJob { Q_OBJECT protected: explicit AbstractExportJob(AbstractExportJobPrivate* d); public: AbstractExportJob(); ~AbstractExportJob() override; public: AbstractDocument* document() const; Q_SIGNALS: void documentLoaded(Kasten::AbstractDocument* document); protected: // emits documentLoaded() // TODO: or better name property LoadedDocument? virtual void setDocument(AbstractDocument* document); protected: const QScopedPointer d_ptr; private: Q_DECLARE_PRIVATE(AbstractExportJob) }; } #endif diff --git a/libs/kasten/core/io/abstractloadjob.hpp b/libs/kasten/core/io/abstractloadjob.hpp index 5e021d45..068ae10a 100644 --- a/libs/kasten/core/io/abstractloadjob.hpp +++ b/libs/kasten/core/io/abstractloadjob.hpp @@ -1,69 +1,69 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_ABSTRACTLOADJOB_HPP #define KASTEN_ABSTRACTLOADJOB_HPP // lib #include -// KF5 +// KF #include namespace Kasten { class AbstractDocument; class AbstractLoadJobPrivate; class KASTENCORE_EXPORT AbstractLoadJob : public KJob { Q_OBJECT protected: explicit AbstractLoadJob(AbstractLoadJobPrivate* d); public: AbstractLoadJob(); ~AbstractLoadJob() override; public: AbstractDocument* document() const; Q_SIGNALS: void documentLoaded(Kasten::AbstractDocument* document); protected: // emits documentLoaded() // TODO: or better name property LoadedDocument? virtual void setDocument(AbstractDocument* document); protected: const QScopedPointer d_ptr; private: Q_DECLARE_PRIVATE(AbstractLoadJob) }; } #endif diff --git a/libs/kasten/core/io/abstractsyncfromremotejob.hpp b/libs/kasten/core/io/abstractsyncfromremotejob.hpp index 12849a19..1e255613 100644 --- a/libs/kasten/core/io/abstractsyncfromremotejob.hpp +++ b/libs/kasten/core/io/abstractsyncfromremotejob.hpp @@ -1,53 +1,53 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_ABSTRACTSYNCFROMREMOTEJOB_HPP #define KASTEN_ABSTRACTSYNCFROMREMOTEJOB_HPP // lib #include -// KF5 +// KF #include namespace Kasten { class AbstractSyncFromRemoteJobPrivate; class KASTENCORE_EXPORT AbstractSyncFromRemoteJob : public KJob { Q_OBJECT protected: explicit AbstractSyncFromRemoteJob(AbstractSyncFromRemoteJobPrivate* parent); public: AbstractSyncFromRemoteJob(); ~AbstractSyncFromRemoteJob() override; protected: const QScopedPointer d_ptr; }; } #endif diff --git a/libs/kasten/core/io/abstractsynctoremotejob.hpp b/libs/kasten/core/io/abstractsynctoremotejob.hpp index 1d279a04..73489db7 100644 --- a/libs/kasten/core/io/abstractsynctoremotejob.hpp +++ b/libs/kasten/core/io/abstractsynctoremotejob.hpp @@ -1,52 +1,52 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_ABSTRACTSYNCTOREMOTEJOB_HPP #define KASTEN_ABSTRACTSYNCTOREMOTEJOB_HPP // lib #include -// KF5 +// KF #include namespace Kasten { class AbstractSyncToRemoteJobPrivate; class KASTENCORE_EXPORT AbstractSyncToRemoteJob : public KJob { Q_OBJECT protected: explicit AbstractSyncToRemoteJob(AbstractSyncToRemoteJobPrivate* d); public: AbstractSyncToRemoteJob(); ~AbstractSyncToRemoteJob() override; protected: const QScopedPointer d_ptr; }; } #endif diff --git a/libs/kasten/core/io/abstractsyncwithremotejob.hpp b/libs/kasten/core/io/abstractsyncwithremotejob.hpp index 975e00d3..e5a563c1 100644 --- a/libs/kasten/core/io/abstractsyncwithremotejob.hpp +++ b/libs/kasten/core/io/abstractsyncwithremotejob.hpp @@ -1,53 +1,53 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_ABSTRACTSYNCWITHREMOTEJOB_HPP #define KASTEN_ABSTRACTSYNCWITHREMOTEJOB_HPP // lib #include -// KF5 +// KF #include namespace Kasten { class AbstractSyncWithRemoteJobPrivate; class KASTENCORE_EXPORT AbstractSyncWithRemoteJob : public KJob { Q_OBJECT protected: explicit AbstractSyncWithRemoteJob(AbstractSyncWithRemoteJobPrivate* d); public: AbstractSyncWithRemoteJob(); ~AbstractSyncWithRemoteJob() override; protected: const QScopedPointer d_ptr; }; } #endif diff --git a/libs/kasten/core/io/filesystem/abstractfilesystemconnectjob_p.cpp b/libs/kasten/core/io/filesystem/abstractfilesystemconnectjob_p.cpp index 92103a5a..6dcf18fa 100644 --- a/libs/kasten/core/io/filesystem/abstractfilesystemconnectjob_p.cpp +++ b/libs/kasten/core/io/filesystem/abstractfilesystemconnectjob_p.cpp @@ -1,150 +1,150 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009,2011,2014 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "abstractfilesystemconnectjob_p.hpp" // library #include "abstractmodelfilesystemsynchronizer.hpp" #include -// KF5 +// KF #include #include // Qt #include #include #include namespace Kasten { void AbstractFileSystemConnectJobPrivate::connectWithFile() { Q_Q(AbstractFileSystemConnectJob); bool isWorkFileOk; if (mOption == AbstractModelSynchronizer::ReplaceRemote) { if (mUrl.isLocalFile()) { mWorkFilePath = mUrl.toLocalFile(); mFile = new QFile(mWorkFilePath); isWorkFileOk = mFile->open(QIODevice::WriteOnly); } else { auto* temporaryFile = new QTemporaryFile; isWorkFileOk = temporaryFile->open(); mWorkFilePath = temporaryFile->fileName(); mTempFilePath = mWorkFilePath; mFile = temporaryFile; } if (!isWorkFileOk) { q->setErrorText(mFile->errorString()); } } else { if (mUrl.isLocalFile()) { // file protocol. We do not need the network mWorkFilePath = mUrl.toLocalFile(); isWorkFileOk = true; } else { QTemporaryFile tmpFile; tmpFile.setAutoRemove(false); tmpFile.open(); mWorkFilePath = tmpFile.fileName(); mTempFilePath = mWorkFilePath; KIO::FileCopyJob* fileCopyJob = KIO::file_copy(mUrl, QUrl::fromLocalFile(mWorkFilePath), -1, KIO::Overwrite); KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr); isWorkFileOk = fileCopyJob->exec(); if (!isWorkFileOk) { q->setErrorText(fileCopyJob->errorString()); } } if (isWorkFileOk) { mFile = new QFile(mWorkFilePath); isWorkFileOk = mFile->open(QIODevice::ReadOnly); if (!isWorkFileOk) { q->setErrorText(mFile->errorString()); } } } if (isWorkFileOk) { q->startConnectWithFile(); } else { q->setError(KJob::KilledJobError); delete mFile; // TODO: should we rather skip setDocument in the API? q->emitResult(); } } void AbstractFileSystemConnectJobPrivate::complete(bool success) { Q_Q(AbstractFileSystemConnectJob); if (success) { mFile->close(); // TODO: when is new time written, on close? QFileInfo fileInfo(*mFile); mSynchronizer->setFileDateTimeOnSync(fileInfo.lastModified()); mSynchronizer->setUrl(mUrl); if (!mUrl.isLocalFile()) { KIO::FileCopyJob* fileCopyJob = KIO::file_copy(QUrl::fromLocalFile(mWorkFilePath), mUrl, -1, KIO::Overwrite); KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr); const bool uploaded = fileCopyJob->exec(); if (!uploaded) { q->setError(KJob::KilledJobError); q->setErrorText(fileCopyJob->errorString()); } else { mSynchronizer->startNetworkWatching(); mSynchronizer->setRemoteState(RemoteUnknown); } } else { mSynchronizer->startFileWatching(); mSynchronizer->setRemoteState(RemoteInSync); } // TODO; in path of both constructor by url and synchWithRemote // only needed for the first, so constructor writers can forget about this // for now we just check in setSynchronizer that new != old before deleting old mDocument->setSynchronizer(mSynchronizer); } else { delete mSynchronizer; // TODO: these reports should go to a notification system, for log or popup q->setError(KJob::KilledJobError); q->setErrorText(mFile->errorString()); } delete mFile; if (!mTempFilePath.isEmpty()) { QFile::remove(mTempFilePath); } q->emitResult(); } } diff --git a/libs/kasten/core/io/filesystem/abstractfilesystemexportjob_p.cpp b/libs/kasten/core/io/filesystem/abstractfilesystemexportjob_p.cpp index 49019913..6c5b3ad5 100644 --- a/libs/kasten/core/io/filesystem/abstractfilesystemexportjob_p.cpp +++ b/libs/kasten/core/io/filesystem/abstractfilesystemexportjob_p.cpp @@ -1,87 +1,87 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009,2011,2014 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "abstractfilesystemexportjob_p.hpp" -// KF5 +// KF #include #include // Qt #include namespace Kasten { void AbstractFileSystemExportJobPrivate::exportToFile() { Q_Q(AbstractFileSystemExportJob); bool isWorkFileOk; if (mUrl.isLocalFile()) { mWorkFilePath = mUrl.toLocalFile(); mFile = new QFile(mWorkFilePath); isWorkFileOk = mFile->open(QIODevice::WriteOnly); } else { auto* temporaryFile = new QTemporaryFile(); isWorkFileOk = temporaryFile->open(); mWorkFilePath = temporaryFile->fileName(); mFile = temporaryFile; } if (isWorkFileOk) { q->startExportToFile(); } else { q->setError(KJob::KilledJobError); q->setErrorText(mFile->errorString()); q->completeExport(false); } } void AbstractFileSystemExportJobPrivate::completeExport(bool success) { Q_Q(AbstractFileSystemExportJob); if (success) { if (!mUrl.isLocalFile()) { KIO::FileCopyJob* fileCopyJob = KIO::file_copy(QUrl::fromLocalFile(mWorkFilePath), mUrl, -1, KIO::Overwrite); KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr); success = fileCopyJob->exec(); if (!success) { q->setError(KJob::KilledJobError); q->setErrorText(fileCopyJob->errorString()); } } } else { q->setError(KJob::KilledJobError); q->setErrorText(mFile->errorString()); } delete mFile; q->emitResult(); } } diff --git a/libs/kasten/core/io/filesystem/abstractfilesystemloadjob_p.cpp b/libs/kasten/core/io/filesystem/abstractfilesystemloadjob_p.cpp index 23270a83..f2abcefd 100644 --- a/libs/kasten/core/io/filesystem/abstractfilesystemloadjob_p.cpp +++ b/libs/kasten/core/io/filesystem/abstractfilesystemloadjob_p.cpp @@ -1,118 +1,118 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009,2011,2014 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "abstractfilesystemloadjob_p.hpp" // library #include "abstractmodelfilesystemsynchronizer.hpp" #include -// KF5 +// KF #include #include // Qt #include #include #include namespace Kasten { void AbstractFileSystemLoadJobPrivate::load() { Q_Q(AbstractFileSystemLoadJob); bool isWorkFileOk; if (mUrl.isLocalFile()) { // file protocol. We do not need the network mWorkFilePath = mUrl.toLocalFile(); isWorkFileOk = true; } else { QTemporaryFile tmpFile; tmpFile.setAutoRemove(false); tmpFile.open(); mWorkFilePath = tmpFile.fileName(); mTempFilePath = mWorkFilePath; KIO::FileCopyJob* fileCopyJob = KIO::file_copy(mUrl, QUrl::fromLocalFile(mWorkFilePath), -1, KIO::Overwrite); KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr); isWorkFileOk = fileCopyJob->exec(); if (!isWorkFileOk) { q->setErrorText(fileCopyJob->errorString()); } } if (isWorkFileOk) { mFile = new QFile(mWorkFilePath); isWorkFileOk = mFile->open(QIODevice::ReadOnly); if (!isWorkFileOk) { q->setErrorText(mFile->errorString()); } } if (isWorkFileOk) { q->startLoadFromFile(); } else { q->setError(KJob::KilledJobError); // TODO: should we rather skip setDocument in the API? q->AbstractLoadJob::setDocument(nullptr); } } void AbstractFileSystemLoadJobPrivate::setDocument(AbstractDocument* document) { Q_Q(AbstractFileSystemLoadJob); if (document) { const bool isLocalFile = mUrl.isLocalFile(); mFile->close(); // TODO: when is new time written, on close? // TODO: reading the fileinfo here separated from the content reading without a lock // asks for a race-condition to happen where the file is modified in between // TODO: how to handle remote+temp? QFileInfo fileInfo(*mFile); mSynchronizer->setFileDateTimeOnSync(fileInfo.lastModified()); mSynchronizer->setUrl(mUrl); if (isLocalFile) { mSynchronizer->startFileWatching(); } else { mSynchronizer->startNetworkWatching(); } mSynchronizer->setRemoteState(isLocalFile ? RemoteInSync : RemoteUnknown); document->setSynchronizer(mSynchronizer); } else { delete mSynchronizer; } delete mFile; if (!mTempFilePath.isEmpty()) { QFile::remove(mTempFilePath); } q->AbstractLoadJob::setDocument(document); } } diff --git a/libs/kasten/core/io/filesystem/abstractfilesystemsyncfromremotejob_p.cpp b/libs/kasten/core/io/filesystem/abstractfilesystemsyncfromremotejob_p.cpp index 32fe300e..13f9005a 100644 --- a/libs/kasten/core/io/filesystem/abstractfilesystemsyncfromremotejob_p.cpp +++ b/libs/kasten/core/io/filesystem/abstractfilesystemsyncfromremotejob_p.cpp @@ -1,107 +1,107 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009,2014 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "abstractfilesystemsyncfromremotejob_p.hpp" // library #include "abstractmodelfilesystemsynchronizer.hpp" -// KF5 +// KF #include #include // Qt #include #include #include #include namespace Kasten { void AbstractFileSystemSyncFromRemoteJobPrivate::syncFromRemote() { Q_Q(AbstractFileSystemSyncFromRemoteJob); const QUrl url = mSynchronizer->url(); bool isWorkFileOk; if (url.isLocalFile()) { // file protocol. We do not need the network mWorkFilePath = url.toLocalFile(); isWorkFileOk = true; } else { QTemporaryFile tmpFile; tmpFile.setAutoRemove(false); tmpFile.open(); mWorkFilePath = tmpFile.fileName(); mTempFilePath = mWorkFilePath; KIO::FileCopyJob* fileCopyJob = KIO::file_copy(url, QUrl::fromLocalFile(mWorkFilePath), -1, KIO::Overwrite); KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr); isWorkFileOk = fileCopyJob->exec(); if (!isWorkFileOk) { q->setErrorText(fileCopyJob->errorString()); } } if (isWorkFileOk) { mFile = new QFile(mWorkFilePath); isWorkFileOk = mFile->open(QIODevice::ReadOnly); if (!isWorkFileOk) { q->setErrorText(mFile->errorString()); } } if (isWorkFileOk) { q->startReadFromFile(); } else { q->setError(KJob::KilledJobError); delete mFile; q->emitResult(); } } void AbstractFileSystemSyncFromRemoteJobPrivate::completeRead(bool success) { Q_Q(AbstractFileSystemSyncFromRemoteJob); if (success) { const QUrl url = mSynchronizer->url(); const bool isLocalFile = url.isLocalFile(); QFileInfo fileInfo(mWorkFilePath); mSynchronizer->setFileDateTimeOnSync(fileInfo.lastModified()); mSynchronizer->setRemoteState(isLocalFile ? RemoteInSync : RemoteUnknown); } delete mFile; if (!mTempFilePath.isEmpty()) { QFile::remove(mTempFilePath); } q->emitResult(); } } diff --git a/libs/kasten/core/io/filesystem/abstractfilesystemsyncfromremotejob_p.hpp b/libs/kasten/core/io/filesystem/abstractfilesystemsyncfromremotejob_p.hpp index e1e16d26..16c196f2 100644 --- a/libs/kasten/core/io/filesystem/abstractfilesystemsyncfromremotejob_p.hpp +++ b/libs/kasten/core/io/filesystem/abstractfilesystemsyncfromremotejob_p.hpp @@ -1,93 +1,93 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_ABSTRACTFILESYSTEMSYNCFROMREMOTEJOB_P_HPP #define KASTEN_ABSTRACTFILESYSTEMSYNCFROMREMOTEJOB_P_HPP // library #include "abstractfilesystemsyncfromremotejob.hpp" #include -// KF5 +// KF #include namespace Kasten { class AbstractModelFileSystemSynchronizer; class AbstractFileSystemSyncFromRemoteJobPrivate : public AbstractSyncFromRemoteJobPrivate { public: AbstractFileSystemSyncFromRemoteJobPrivate(AbstractFileSystemSyncFromRemoteJob* parent, AbstractModelFileSystemSynchronizer* synchronizer); AbstractFileSystemSyncFromRemoteJobPrivate() = delete; ~AbstractFileSystemSyncFromRemoteJobPrivate() override; public: // KJob API void start(); public: AbstractModelFileSystemSynchronizer* synchronizer() const; QFile* file() const; public: void completeRead(bool success); public: // slots void syncFromRemote(); protected: AbstractModelFileSystemSynchronizer* mSynchronizer; QString mWorkFilePath; QString mTempFilePath; QFile* mFile = nullptr; private: Q_DECLARE_PUBLIC(AbstractFileSystemSyncFromRemoteJob) }; inline AbstractFileSystemSyncFromRemoteJobPrivate::AbstractFileSystemSyncFromRemoteJobPrivate(AbstractFileSystemSyncFromRemoteJob* parent, AbstractModelFileSystemSynchronizer* synchronizer) : AbstractSyncFromRemoteJobPrivate(parent) , mSynchronizer(synchronizer) { } inline AbstractFileSystemSyncFromRemoteJobPrivate::~AbstractFileSystemSyncFromRemoteJobPrivate() = default; inline QFile* AbstractFileSystemSyncFromRemoteJobPrivate::file() const { return mFile; } // TODO: setup a notification system inline AbstractModelFileSystemSynchronizer* AbstractFileSystemSyncFromRemoteJobPrivate::synchronizer() const { return mSynchronizer; } inline void AbstractFileSystemSyncFromRemoteJobPrivate::start() { Q_Q(AbstractFileSystemSyncFromRemoteJob); QMetaObject::invokeMethod(q, "syncFromRemote", Qt::QueuedConnection); } } #endif diff --git a/libs/kasten/core/io/filesystem/abstractfilesystemsynctoremotejob_p.cpp b/libs/kasten/core/io/filesystem/abstractfilesystemsynctoremotejob_p.cpp index 82615e18..ec38f5f6 100644 --- a/libs/kasten/core/io/filesystem/abstractfilesystemsynctoremotejob_p.cpp +++ b/libs/kasten/core/io/filesystem/abstractfilesystemsynctoremotejob_p.cpp @@ -1,105 +1,105 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009,2011,2014 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "abstractfilesystemsynctoremotejob_p.hpp" -// KF5 +// KF #include #include // Qt #include #include namespace Kasten { AbstractFileSystemSyncToRemoteJobPrivate::~AbstractFileSystemSyncToRemoteJobPrivate() = default; void AbstractFileSystemSyncToRemoteJobPrivate::syncToRemote() { Q_Q(AbstractFileSystemSyncToRemoteJob); bool isWorkFileOk; const QUrl url = mSynchronizer->url(); if (url.isLocalFile()) { mWorkFilePath = url.toLocalFile(); mFile = new QFile(mWorkFilePath); isWorkFileOk = mFile->open(QIODevice::WriteOnly); mSynchronizer->pauseFileWatching(); } else { auto* temporaryFile = new QTemporaryFile; isWorkFileOk = temporaryFile->open(); mWorkFilePath = temporaryFile->fileName(); mFile = temporaryFile; } if (isWorkFileOk) { q->startWriteToFile(); } else { q->setError(KJob::KilledJobError); q->setErrorText(mFile->errorString()); delete mFile; q->emitResult(); } } void AbstractFileSystemSyncToRemoteJobPrivate::completeWrite(bool success) { Q_Q(AbstractFileSystemSyncToRemoteJob); if (success) { mFile->close(); // TODO: when is new time written, on close? QFileInfo fileInfo(*mFile); mSynchronizer->setFileDateTimeOnSync(fileInfo.lastModified()); const QUrl url = mSynchronizer->url(); const bool isLocalFile = url.isLocalFile(); if (!isLocalFile) { KIO::FileCopyJob* fileCopyJob = KIO::file_copy(QUrl::fromLocalFile(mWorkFilePath), url, -1, KIO::Overwrite); KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr); success = fileCopyJob->exec(); if (!success) { q->setError(KJob::KilledJobError); q->setErrorText(fileCopyJob->errorString()); } else { mSynchronizer->setRemoteState(RemoteUnknown); } } else { mSynchronizer->unpauseFileWatching(); mSynchronizer->setRemoteState(RemoteInSync); } } else { q->setError(KJob::KilledJobError); q->setErrorText(mFile->errorString()); } delete mFile; q->emitResult(); } } diff --git a/libs/kasten/core/io/filesystem/abstractfilesystemsyncwithremotejob_p.cpp b/libs/kasten/core/io/filesystem/abstractfilesystemsyncwithremotejob_p.cpp index 1bf6ca1d..f9245e87 100644 --- a/libs/kasten/core/io/filesystem/abstractfilesystemsyncwithremotejob_p.cpp +++ b/libs/kasten/core/io/filesystem/abstractfilesystemsyncwithremotejob_p.cpp @@ -1,151 +1,151 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008-2009,2011,2014 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "abstractfilesystemsyncwithremotejob_p.hpp" // library #include "abstractmodelfilesystemsynchronizer.hpp" #include -// KF5 +// KF #include #include // Qt #include #include #include namespace Kasten { void AbstractFileSystemSyncWithRemoteJobPrivate::syncWithRemote() { Q_Q(AbstractFileSystemSyncWithRemoteJob); bool isWorkFileOk; if (mOption == AbstractModelSynchronizer::ReplaceRemote) { if (mUrl.isLocalFile()) { mWorkFilePath = mUrl.toLocalFile(); mFile = new QFile(mWorkFilePath); isWorkFileOk = mFile->open(QIODevice::WriteOnly); } else { auto* temporaryFile = new QTemporaryFile; isWorkFileOk = temporaryFile->open(); mWorkFilePath = temporaryFile->fileName(); mTempFilePath = mWorkFilePath; mFile = temporaryFile; } if (!isWorkFileOk) { q->setErrorText(mFile->errorString()); } } else { if (mUrl.isLocalFile()) { // file protocol. We do not need the network mWorkFilePath = mUrl.toLocalFile(); isWorkFileOk = true; } else { QTemporaryFile tmpFile; tmpFile.setAutoRemove(false); tmpFile.open(); mWorkFilePath = tmpFile.fileName(); mTempFilePath = mWorkFilePath; KIO::FileCopyJob* fileCopyJob = KIO::file_copy(mUrl, QUrl::fromLocalFile(mWorkFilePath), -1, KIO::Overwrite); KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr); isWorkFileOk = fileCopyJob->exec(); if (!isWorkFileOk) { q->setErrorText(fileCopyJob->errorString()); } } if (isWorkFileOk) { mFile = new QFile(mWorkFilePath); isWorkFileOk = mFile->open(QIODevice::ReadWrite); if (!isWorkFileOk) { q->setErrorText(mFile->errorString()); } } } if (isWorkFileOk) { const QUrl oldUrl = mSynchronizer->url(); if (oldUrl.isLocalFile()) { mSynchronizer->stopFileWatching(); } else { mSynchronizer->stopNetworkWatching(); } q->startSyncWithRemote(); } else { q->setError(KJob::KilledJobError); delete mFile; // TODO: should we rather skip completeSync in success API? q->emitResult(); } } void AbstractFileSystemSyncWithRemoteJobPrivate::completeSync(bool success) { Q_Q(AbstractFileSystemSyncWithRemoteJob); if (success) { mFile->close(); // TODO: when is new time written, on close? QFileInfo fileInfo(*mFile); mSynchronizer->setFileDateTimeOnSync(fileInfo.lastModified()); mSynchronizer->setUrl(mUrl); if (!mUrl.isLocalFile()) { KIO::FileCopyJob* fileCopyJob = KIO::file_copy(QUrl::fromLocalFile(mWorkFilePath), mUrl, -1, KIO::Overwrite); KJobWidgets::setWindow(fileCopyJob, /*mWidget*/ nullptr); const bool uploaded = fileCopyJob->exec(); if (!uploaded) { q->setError(KJob::KilledJobError); q->setErrorText(fileCopyJob->errorString()); } else { mSynchronizer->startNetworkWatching(); mSynchronizer->setRemoteState(RemoteUnknown); } } else { mSynchronizer->startFileWatching(); mSynchronizer->setRemoteState(RemoteInSync); } } else { q->setError(KJob::KilledJobError); q->setErrorText(mFile->errorString()); } delete mFile; if (!mTempFilePath.isEmpty()) { QFile::remove(mTempFilePath); } q->emitResult(); } } diff --git a/libs/kasten/core/io/filesystem/abstractmodelfilesystemsynchronizer_p.cpp b/libs/kasten/core/io/filesystem/abstractmodelfilesystemsynchronizer_p.cpp index e5fd3db8..8a85e9be 100644 --- a/libs/kasten/core/io/filesystem/abstractmodelfilesystemsynchronizer_p.cpp +++ b/libs/kasten/core/io/filesystem/abstractmodelfilesystemsynchronizer_p.cpp @@ -1,125 +1,125 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2007-2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "abstractmodelfilesystemsynchronizer_p.hpp" -// KF5 +// KF #include // Qt #include namespace Kasten { AbstractModelFileSystemSynchronizerPrivate::~AbstractModelFileSystemSynchronizerPrivate() { delete mNetworkConfigurationManager; } void AbstractModelFileSystemSynchronizerPrivate::startFileWatching() { Q_Q(AbstractModelFileSystemSynchronizer); if (!mDirWatch) { mDirWatch = new KDirWatch(q); QObject::connect(mDirWatch, &KDirWatch::dirty, q, [&](const QString& path) { onFileDirty(path); }); QObject::connect(mDirWatch, &KDirWatch::created, q, [&](const QString& path) { onFileCreated(path); }); QObject::connect(mDirWatch, &KDirWatch::deleted, q, [&](const QString& path) { onFileDeleted(path); }); } mDirWatch->addFile(mUrl.toLocalFile()); } void AbstractModelFileSystemSynchronizerPrivate::stopFileWatching() { if (!mDirWatch) { return; } mDirWatch->removeFile(mUrl.toLocalFile()); } void AbstractModelFileSystemSynchronizerPrivate::pauseFileWatching() { if (!mDirWatch) { return; } mDirWatch->stopScan(); } void AbstractModelFileSystemSynchronizerPrivate::unpauseFileWatching() { if (!mDirWatch) { return; } mDirWatch->startScan(); } void AbstractModelFileSystemSynchronizerPrivate::startNetworkWatching() { Q_Q(AbstractModelFileSystemSynchronizer); mNetworkConfigurationManager = new QNetworkConfigurationManager(); QObject::connect(mNetworkConfigurationManager, &QNetworkConfigurationManager::onlineStateChanged, q, [&](bool online) { onOnlineStateChanged(online); }); } void AbstractModelFileSystemSynchronizerPrivate::stopNetworkWatching() { delete mNetworkConfigurationManager; mNetworkConfigurationManager = nullptr; } void AbstractModelFileSystemSynchronizerPrivate::onFileDirty(const QString& fileName) { Q_UNUSED(fileName) qCDebug(LOG_KASTEN_CORE) << fileName; setRemoteState(RemoteHasChanges); } void AbstractModelFileSystemSynchronizerPrivate::onFileCreated(const QString& fileName) { Q_UNUSED(fileName) qCDebug(LOG_KASTEN_CORE) << fileName; // TODO: could happen after a delete, what to do? setRemoteState(RemoteHasChanges); } void AbstractModelFileSystemSynchronizerPrivate::onFileDeleted(const QString& fileName) { Q_UNUSED(fileName) qCDebug(LOG_KASTEN_CORE) << fileName; setRemoteState(RemoteDeleted); } void AbstractModelFileSystemSynchronizerPrivate::onOnlineStateChanged(bool isOnline) { qCDebug(LOG_KASTEN_CORE); setRemoteState(isOnline ? RemoteUnknown : RemoteUnreachable); } } diff --git a/libs/kasten/core/system/documentsyncmanager_p.cpp b/libs/kasten/core/system/documentsyncmanager_p.cpp index e6efed16..824585bf 100644 --- a/libs/kasten/core/system/documentsyncmanager_p.cpp +++ b/libs/kasten/core/system/documentsyncmanager_p.cpp @@ -1,279 +1,279 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2007-2009,2011,2019 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "documentsyncmanager_p.hpp" // lib #include "abstractoverwritedialog.hpp" #include "abstractsavediscarddialog.hpp" #include "jobmanager.hpp" #include "documentmanager.hpp" #include #include #include #include #include #include #include -// KF5 +// KF #include #include #include // Qt #include #include #include namespace Kasten { DocumentSyncManagerPrivate::DocumentSyncManagerPrivate(DocumentSyncManager* q, DocumentManager* manager) : q_ptr(q) , mManager(manager) {} DocumentSyncManagerPrivate::~DocumentSyncManagerPrivate() { delete mSynchronizerFactory; } void DocumentSyncManagerPrivate::setSaveDiscardDialog(AbstractSaveDiscardDialog* saveDiscardDialog) { mSaveDiscardDialog = saveDiscardDialog; } void DocumentSyncManagerPrivate::setOverwriteDialog(AbstractOverwriteDialog* overwriteDialog) { mOverwriteDialog = overwriteDialog; } // TODO: make a difference between stream/storage formats and work/live formats? QStringList DocumentSyncManagerPrivate::supportedRemoteTypes() const { return {mSynchronizerFactory->supportedRemoteType()}; } bool DocumentSyncManagerPrivate::hasSynchronizerForLocal(const QString& workDocumentType) const { // TODO: need synchronizerfactory classes to query for this or a local datastructure return (mSynchronizerFactory->supportedWorkType() == workDocumentType); } QUrl DocumentSyncManagerPrivate::urlOf(AbstractDocument* document) const { AbstractModelSynchronizer* synchronizer = document->synchronizer(); return synchronizer ? synchronizer->url() : QUrl(); } void DocumentSyncManagerPrivate::setDocumentSynchronizerFactory(AbstractModelSynchronizerFactory* synchronizerFactory) { mSynchronizerFactory = synchronizerFactory; } void DocumentSyncManagerPrivate::load(const QUrl& url) { Q_Q(DocumentSyncManager); const auto loadedDocuments = mManager->documents(); for (AbstractDocument* document : loadedDocuments) { if (url == urlOf(document)) { // TODO: query if file should be reloaded/synched from disk emit mManager->focusRequested(document); return; } } AbstractModelSynchronizer* synchronizer = mSynchronizerFactory->createSynchronizer(); AbstractLoadJob* loadJob = synchronizer->startLoad(url); QObject::connect(loadJob, &AbstractLoadJob::documentLoaded, q, [this](AbstractDocument* document) { onDocumentLoaded(document); }); JobManager::executeJob(loadJob); // TODO: pass a ui handler to jobmanager // store path // mWorkingUrl = url.upUrl(); emit q->urlUsed(url); } bool DocumentSyncManagerPrivate::setSynchronizer(AbstractDocument* document) { Q_Q(DocumentSyncManager); bool storingDone = false; AbstractModelSynchronizer* currentSynchronizer = document->synchronizer(); // TODO: warn if there were updates in the second before saveAs was activated // if( currentSynchronizer ) // currentSynchronizer->pauseSynchronization(); also unpause below const QString processTitle = i18nc("@title:window", "Save As"); do { QFileDialog dialog(/*mWidget*/ nullptr, processTitle, /*mWorkingUrl.url()*/ QString()); dialog.setMimeTypeFilters(supportedRemoteTypes()); dialog.setAcceptMode(QFileDialog::AcceptSave); const QUrl newUrl = (dialog.exec() != 0) ? dialog.selectedUrls().value(0) : QUrl(); if (newUrl.isValid()) { const bool isNewUrl = (!currentSynchronizer) || (newUrl != currentSynchronizer->url()); if (isNewUrl) { KIO::StatJob* statJob = KIO::stat(newUrl); statJob->setSide(KIO::StatJob::DestinationSide); KJobWidgets::setWindow(statJob, /*mWidget*/ nullptr); const bool isUrlInUse = statJob->exec(); if (isUrlInUse) { // TODO: care for case that file from url is already loaded by (only?) this program // const bool otherFileLoaded = mManager->documentByUrl( newUrl ); // TODO: replace "file" with synchronizer->storageTypeName() or such // TODO: offer "Synchronize" as alternative, if supported, see below // ask synchronizer for capabilities, as some can only overwrite const Answer answer = mOverwriteDialog ? mOverwriteDialog->queryOverwrite(newUrl, processTitle) : Cancel; if (answer == Cancel) { break; } if (answer == PreviousQuestion) { continue; } } // switch url and synchronizer if (currentSynchronizer && true) {// TODO: same remote mimetype // TODO: overwrite for now AbstractSyncWithRemoteJob* syncJob = currentSynchronizer->startSyncWithRemote(newUrl, AbstractModelSynchronizer::ReplaceRemote); const bool syncSucceeded = JobManager::executeJob(syncJob); // currentSynchronizer->unpauseSynchronization(); also pause above storingDone = syncSucceeded; } else { // TODO: is overwrite for now, is this useful? AbstractModelSynchronizer* synchronizer = mSynchronizerFactory->createSynchronizer(); AbstractConnectJob* connectJob = synchronizer->startConnect(document, newUrl, AbstractModelSynchronizer::ReplaceRemote); const bool connectSucceeded = JobManager::executeJob(connectJob); storingDone = connectSucceeded; } if (storingDone) { emit q->urlUsed(newUrl); } #if 0 // mWorkingUrl = Url.upUrl(); OpenRecentAction->addUrl(Url); #endif } // same url else { // TODO: what to do? synchTo? synchWith? synchFrom? Or does the synchronizer care for this? // By e.g. warning that we might be overwriting something? // synchTo might be the intention, after all the user wanted a new storage // AbstractSyncToRemoteJob* syncJob = document->synchronizer()->startSyncToRemote(); const bool syncFailed = JobManager::executeJob(syncJob); storingDone = !syncFailed; } } else { break; } } while (!storingDone); return storingDone; } bool DocumentSyncManagerPrivate::canClose(AbstractDocument* document) { bool canClose = true; if (document->contentFlags() & ContentHasUnstoredChanges) { AbstractModelSynchronizer* synchronizer = document->synchronizer(); const bool couldSynchronize = hasSynchronizerForLocal(document->mimeType()); const QString processTitle = i18nc("@title:window", "Close"); if ((synchronizer && synchronizer->localSyncState() == LocalHasChanges) || couldSynchronize) { const Answer answer = mSaveDiscardDialog ? mSaveDiscardDialog->querySaveDiscard(document, processTitle) : Cancel; if (answer == Save) { if (synchronizer) { AbstractSyncToRemoteJob* syncJob = synchronizer->startSyncToRemote(); const bool isSynced = JobManager::executeJob(syncJob); canClose = isSynced; } else { canClose = setSynchronizer(document); } } else { canClose = (answer == Discard); } } else { const Answer answer = mSaveDiscardDialog ? mSaveDiscardDialog->queryDiscard(document, processTitle) : Cancel; canClose = (answer == Discard); } } return canClose; } void DocumentSyncManagerPrivate::reload(AbstractDocument* document) { AbstractModelSynchronizer* synchronizer = document->synchronizer(); if (synchronizer->localSyncState() == LocalHasChanges) { const QString processTitle = i18nc("@title:window", "Reload"); const Answer answer = mSaveDiscardDialog ? mSaveDiscardDialog->queryDiscardOnReload(document, processTitle) : Cancel; if (answer == Cancel) { return; } } AbstractSyncFromRemoteJob* syncJob = synchronizer->startSyncFromRemote(); JobManager::executeJob(syncJob); } void DocumentSyncManagerPrivate::save(AbstractDocument* document) { AbstractModelSynchronizer* synchronizer = document->synchronizer(); AbstractSyncToRemoteJob* syncJob = synchronizer->startSyncToRemote(); JobManager::executeJob(syncJob); } void DocumentSyncManagerPrivate::onDocumentLoaded(AbstractDocument* document) { if (document) { mManager->addDocument(document); } } } diff --git a/libs/kasten/core/system/jobmanager.cpp b/libs/kasten/core/system/jobmanager.cpp index b2466902..36e29634 100644 --- a/libs/kasten/core/system/jobmanager.cpp +++ b/libs/kasten/core/system/jobmanager.cpp @@ -1,53 +1,53 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "jobmanager.hpp" -// KF5 +// KF #include #include // Qt #include namespace Kasten { bool JobManager::executeJob(KJob* job) { if (!job) { return false; } QGuiApplication::setOverrideCursor(Qt::WaitCursor); job->exec(); const bool success = (job->error() == KJob::NoError); QGuiApplication::restoreOverrideCursor(); if (!success) { KMessageBox::error(nullptr, job->errorText()); // TODO: feed into notification system } return success; } } diff --git a/libs/kasten/core/system/modelcodecmanager_p.cpp b/libs/kasten/core/system/modelcodecmanager_p.cpp index 5228479b..3fc40186 100644 --- a/libs/kasten/core/system/modelcodecmanager_p.cpp +++ b/libs/kasten/core/system/modelcodecmanager_p.cpp @@ -1,165 +1,165 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2007-2009,2019 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "modelcodecmanager_p.hpp" // lib #include "modelencoderfilesystemexporter.hpp" #include "abstractmodelstreamencoder.hpp" // #include "abstractmodelstreamdecoder.hpp" #include "abstractmodeldatagenerator.hpp" #include "abstractoverwritedialog.hpp" #include "jobmanager.hpp" #include "abstractexportjob.hpp" -// KF5 +// KF #include #include #include // Qt #include #include namespace Kasten { ModelCodecManagerPrivate::~ModelCodecManagerPrivate() { qDeleteAll(mExporterList); qDeleteAll(mEncoderList); // qDeleteAll( mDecoderList ); qDeleteAll(mGeneratorList); } QVector ModelCodecManagerPrivate::encoderList(AbstractModel* model, const AbstractModelSelection* selection) const { Q_UNUSED(selection) return model ? mEncoderList : QVector(); } QVector ModelCodecManagerPrivate::decoderList() const { return mDecoderList; } QVector ModelCodecManagerPrivate::generatorList() const { return mGeneratorList; } QVector ModelCodecManagerPrivate::exporterList(AbstractModel* model, const AbstractModelSelection* selection) const { Q_UNUSED(selection) return model ? mExporterList : QVector(); } void ModelCodecManagerPrivate::setOverwriteDialog(AbstractOverwriteDialog* overwriteDialog) { mOverwriteDialog = overwriteDialog; } void ModelCodecManagerPrivate::setEncoders(const QVector& encoderList) { mEncoderList = encoderList; qDeleteAll(mExporterList); mExporterList.clear(); mExporterList.reserve(mEncoderList.size()); for (AbstractModelStreamEncoder* encoder : qAsConst(mEncoderList)) { mExporterList << new ModelEncoderFileSystemExporter(encoder); } } void ModelCodecManagerPrivate::setDecoders(const QVector& decoderList) { mDecoderList = decoderList; } void ModelCodecManagerPrivate::setGenerators(const QVector& generatorList) { mGeneratorList = generatorList; } void ModelCodecManagerPrivate::encodeToStream(AbstractModelStreamEncoder* encoder, AbstractModel* model, const AbstractModelSelection* selection) { Q_UNUSED(selection) Q_UNUSED(model) Q_UNUSED(encoder) // AbstractDocument* model = mFactory->create(); // mManager->addDocument( model ); } void ModelCodecManagerPrivate::exportDocument(AbstractModelExporter* exporter, AbstractModel* model, const AbstractModelSelection* selection) { bool exportDone = false; const QString dialogTitle = i18nc("@title:window", "Export"); do { QFileDialog exportFileDialog(/*mWidget*/ nullptr, dialogTitle); exportFileDialog.setAcceptMode(QFileDialog::AcceptSave); exportFileDialog.setFileMode(QFileDialog::AnyFile); const QStringList mimeTypes = QStringList { exporter->remoteMimeType() }; exportFileDialog.setMimeTypeFilters(mimeTypes); exportFileDialog.setLabelText(QFileDialog::Accept, i18nc("@action:button", "&Export")); exportFileDialog.exec(); const QList exportUrls = exportFileDialog.selectedUrls(); if (!exportUrls.isEmpty()) { const QUrl& exportUrl = exportUrls.at(0); KIO::StatJob* statJob = KIO::stat(exportUrl); statJob->setSide(KIO::StatJob::DestinationSide); KJobWidgets::setWindow(statJob, /*mWidget*/ nullptr); const bool isUrlInUse = statJob->exec(); if (isUrlInUse) { // TODO: care for case that file from url is already loaded by (only?) this program // const bool otherFileLoaded = mManager->documentByUrl( exportUrl ); // TODO: replace "file" with synchronizer->storageTypeName() or such // TODO: offer "Synchronize" as alternative, if supported, see below const Answer answer = mOverwriteDialog ? mOverwriteDialog->queryOverwrite(exportUrl, dialogTitle) : Cancel; if (answer == Cancel) { break; } if (answer == PreviousQuestion) { continue; } } AbstractExportJob* exportJob = exporter->startExport(model, selection, exportUrl); exportDone = JobManager::executeJob(exportJob); // if( exportDone ) // emit urlUsed( exportUrl ); } else { break; } } while (!exportDone); } } diff --git a/libs/kasten/core/tests/testdocumentfileloadthread.cpp b/libs/kasten/core/tests/testdocumentfileloadthread.cpp index 7f404d67..09433db3 100644 --- a/libs/kasten/core/tests/testdocumentfileloadthread.cpp +++ b/libs/kasten/core/tests/testdocumentfileloadthread.cpp @@ -1,72 +1,72 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "testdocumentfileloadthread.hpp" // lib #include "testdocument.hpp" -// KF5 +// KF #include // Qt #include #include #include #include #include namespace Kasten { TestDocumentFileLoadThread::~TestDocumentFileLoadThread() = default; void TestDocumentFileLoadThread::run() { QDataStream inStream(mFile); const int fileSize = mFile->size(); // test header const int headerSize = mHeader.size(); QByteArray header(headerSize, ' '); const int headerResult = inStream.readRawData(header.data(), headerSize); if (headerResult == -1 || header != mHeader) { mDocument = nullptr; } else { QByteArray byteArray(fileSize, ' '); inStream.readRawData(byteArray.data(), fileSize); // registerDiskModifyTime( file ); TODO move into synchronizer const bool streamIsOk = (inStream.status() == QDataStream::Ok); // if( success ) // *success = streamIsOk ? 0 : 1; if (streamIsOk) { mDocument = new TestDocument(byteArray); mDocument->moveToThread(QCoreApplication::instance()->thread()); } else { mDocument = nullptr; } } emit documentRead(mDocument); } } diff --git a/libs/kasten/core/tests/testdocumentfilereloadthread.cpp b/libs/kasten/core/tests/testdocumentfilereloadthread.cpp index 63a61991..bc0a013f 100644 --- a/libs/kasten/core/tests/testdocumentfilereloadthread.cpp +++ b/libs/kasten/core/tests/testdocumentfilereloadthread.cpp @@ -1,71 +1,71 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2008 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "testdocumentfilereloadthread.hpp" // lib #include "testdocument.hpp" -// KF5 +// KF #include // Qt #include #include #include namespace Kasten { TestDocumentFileReloadThread::TestDocumentFileReloadThread(QObject* parent, const QByteArray& header, /*TestDocument* document,*/ QFile* file) : QThread(parent) // , mDocument(document) , mHeader(header) , mFile(file) { // mDocument->content()->moveToThread( this ); // mDocument->moveToThread( this ); } TestDocumentFileReloadThread::~TestDocumentFileReloadThread() = default; void TestDocumentFileReloadThread::run() { QDataStream inStream(mFile); const int fileSize = mFile->size(); // test header const int headerSize = mHeader.size(); QByteArray header(headerSize, ' '); const int headerResult = inStream.readRawData(header.data(), headerSize); if (headerResult == -1 || header != mHeader) { mSuccess = false; } else { mByteArray = QByteArray(fileSize, ' '); inStream.readRawData(mByteArray.data(), fileSize); mSuccess = (inStream.status() == QDataStream::Ok); } emit documentReloaded(mSuccess); } } diff --git a/libs/kasten/gui/shell/shellwindow.hpp b/libs/kasten/gui/shell/shellwindow.hpp index fe983857..b71598ea 100644 --- a/libs/kasten/gui/shell/shellwindow.hpp +++ b/libs/kasten/gui/shell/shellwindow.hpp @@ -1,78 +1,78 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2007-2008,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_SHELLWINDOW_HPP #define KASTEN_SHELLWINDOW_HPP // Kasten gui #include #include -// KF5 +// KF #include namespace Kasten { class ShellWindowPrivate; class ViewManager; class MultiViewAreas; class AbstractXmlGuiController; class AbstractToolView; class AbstractView; class AbstractDocument; class KASTENGUI_EXPORT ShellWindow : public KXmlGuiWindow , public If::WidgetsDockable { Q_OBJECT Q_INTERFACES( Kasten::If::WidgetsDockable ) public: explicit ShellWindow(ViewManager* viewManager); ~ShellWindow() override; public Q_SLOTS: void showDocument(Kasten::AbstractDocument* document); // TODO: better name public: void updateControllers(AbstractView* view); void addXmlGuiController(AbstractXmlGuiController* controller); void addTool(AbstractToolView* toolView); public: // If::WidgetsDockable API QVector dockWidgets() const override; protected: MultiViewAreas* viewArea() const; ViewManager* viewManager() const; protected: const QScopedPointer d_ptr; private: Q_DECLARE_PRIVATE(ShellWindow) }; } #endif diff --git a/libs/kasten/gui/shell/singleviewwindow.hpp b/libs/kasten/gui/shell/singleviewwindow.hpp index d398caf5..4d356b2b 100644 --- a/libs/kasten/gui/shell/singleviewwindow.hpp +++ b/libs/kasten/gui/shell/singleviewwindow.hpp @@ -1,77 +1,77 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2011-2012 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef KASTEN_SINGLEVIEWWINDOW_HPP #define KASTEN_SINGLEVIEWWINDOW_HPP // lib #include #include -// KF5 +// KF #include class QMimeData; namespace Kasten { class SingleViewWindowPrivate; class AbstractView; class AbstractToolView; class AbstractXmlGuiController; class SingleViewArea; class KASTENGUI_EXPORT SingleViewWindow : public KXmlGuiWindow , public If::WidgetsDockable { Q_OBJECT Q_INTERFACES( Kasten::If::WidgetsDockable ) public: explicit SingleViewWindow(AbstractView* view); ~SingleViewWindow() override; public: void addXmlGuiController(AbstractXmlGuiController* controller); void addTool(AbstractToolView* toolView); void setView(AbstractView* view); public: // If::WidgetsDockable API QVector dockWidgets() const override; protected: AbstractView* view() const; SingleViewArea* viewArea() const; protected: const QScopedPointer d_ptr; private: Q_DECLARE_PRIVATE(SingleViewWindow) }; } #endif diff --git a/libs/kasten/gui/system/createdialog.cpp b/libs/kasten/gui/system/createdialog.cpp index a6d01c0a..fdd027df 100644 --- a/libs/kasten/gui/system/createdialog.cpp +++ b/libs/kasten/gui/system/createdialog.cpp @@ -1,83 +1,83 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009,2013 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "createdialog.hpp" // Kasten gui #include -// KF5 +// KF #include // Qt #include #include #include #include #include #include namespace Kasten { CreateDialog::CreateDialog(AbstractModelDataGeneratorConfigEditor* configEditor, QWidget* parent) : QDialog(parent) , mConfigEditor(configEditor) { setWindowTitle(i18nc("@title:window", "Create")); // editor QLabel* editorLabel = new QLabel(mConfigEditor->name()); QFont font = editorLabel->font(); font.setBold(true); editorLabel->setFont(font); // dialog buttons auto* dialogButtonBox = new QDialogButtonBox; QPushButton* createButton = new QPushButton(QIcon::fromTheme(QStringLiteral("document-new")), i18nc("@action:button create the new document", "&Create")); createButton->setToolTip(i18nc("@info:tooltip", "Create a new document with the generated data.")); createButton->setWhatsThis(xi18nc("@info:whatsthis", "If you press the Create button, " "the data will be generated with the settings you entered above " "and inserted in a new document.")); dialogButtonBox->addButton(createButton, QDialogButtonBox::AcceptRole); connect(dialogButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept); dialogButtonBox->addButton(QDialogButtonBox::Cancel); connect(dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); createButton->setEnabled(configEditor->isValid()); connect(configEditor, &AbstractModelDataGeneratorConfigEditor::validityChanged, createButton, &QWidget::setEnabled); // main layout auto* layout = new QVBoxLayout; layout->addWidget(editorLabel); layout->addWidget(mConfigEditor); layout->addStretch(); layout->addWidget(dialogButtonBox); setLayout(layout); } CreateDialog::~CreateDialog() = default; } diff --git a/libs/kasten/gui/system/dialoghandler.cpp b/libs/kasten/gui/system/dialoghandler.cpp index 8172d9f6..efeff20b 100644 --- a/libs/kasten/gui/system/dialoghandler.cpp +++ b/libs/kasten/gui/system/dialoghandler.cpp @@ -1,97 +1,97 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2009,2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "dialoghandler.hpp" // Kasten core #include -// KF5 +// KF #include #include // Qt #include namespace Kasten { DialogHandler::DialogHandler(QWidget* widget) : mWidget(widget) {} DialogHandler::~DialogHandler() = default; void DialogHandler::setWidget(QWidget* widget) { mWidget = widget; } Answer DialogHandler::queryOverwrite(const QUrl& url, const QString& title) const { const QString message = xi18nc("@info", "There is already a file at%1." "Overwrite?", url.url()); const int answer = KMessageBox::warningYesNoCancel(mWidget, message, title, KStandardGuiItem::overwrite(), KStandardGuiItem::back()); return (answer == KMessageBox::Yes) ? Overwrite : (answer == KMessageBox::No) ? PreviousQuestion : Cancel; } Answer DialogHandler::queryDiscardOnReload(const AbstractDocument* document, const QString& title) const { const QString message = xi18nc("@info \"%title\" has been modified.", "There are unsaved modifications to %1. " "They will be lost if you reload the document." "Do you want to discard them?", document->title()); const int answer = KMessageBox::warningContinueCancel(mWidget, message, title, KStandardGuiItem::discard()); return (answer == KMessageBox::Cancel) ? Cancel : Discard; } Answer DialogHandler::querySaveDiscard(const AbstractDocument* document, const QString& title) const { const QString message = xi18nc("@info \"%title\" has been modified.", "%1 has been modified." "Do you want to save your changes or discard them?", document->title()); const int answer = KMessageBox::warningYesNoCancel(mWidget, message, title, KStandardGuiItem::save(), KStandardGuiItem::discard()); return (answer == KMessageBox::Yes) ? Save : (answer == KMessageBox::No) ? Discard : Cancel; } Answer DialogHandler::queryDiscard(const AbstractDocument* document, const QString& title) const { const QString message = xi18nc("@info \"%title\" has been modified.", "%1 has been modified." "Do you want to discard your changes?", document->title()); const int answer = KMessageBox::warningContinueCancel(mWidget, message, title, KStandardGuiItem::discard()); return (answer == KMessageBox::Cancel) ? Cancel : Discard; } } diff --git a/libs/kasten/gui/system/singledocumentstrategy_p.cpp b/libs/kasten/gui/system/singledocumentstrategy_p.cpp index fa365ebc..1e577e18 100644 --- a/libs/kasten/gui/system/singledocumentstrategy_p.cpp +++ b/libs/kasten/gui/system/singledocumentstrategy_p.cpp @@ -1,159 +1,159 @@ /* This file is part of the Kasten Framework, made within the KDE community. Copyright 2011 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "singledocumentstrategy_p.hpp" // lib #include "createdialog.hpp" // Kasten gui #include #include #include // Kasten core #include #include #include #include #include -// KF5 +// KF #include // Qt #include #include #include #include namespace Kasten { void SingleDocumentStrategyPrivate::init() { Q_Q(SingleDocumentStrategy); // setup QObject::connect(mDocumentManager, &DocumentManager::added, mViewManager, &ViewManager::createViewsFor); QObject::connect(mDocumentManager, &DocumentManager::closing, mViewManager, &ViewManager::removeViewsFor); QObject::connect(mDocumentManager, &DocumentManager::added, q, &SingleDocumentStrategy::added); QObject::connect(mDocumentManager, &DocumentManager::closing, q, &SingleDocumentStrategy::closing); QObject::connect(mDocumentManager->syncManager(), &DocumentSyncManager::urlUsed, q, &SingleDocumentStrategy::urlUsed); } void SingleDocumentStrategyPrivate::createNew() { if (mDocumentManager->isEmpty()) { mDocumentManager->createManager()->createNew(); } else { const QString executable = QCoreApplication::applicationFilePath(); // TODO: get parameters from common place with KCmdLineOptions // TODO: forward also interesting parameters passed to this program const QStringList parameters { QStringLiteral("-c") }; KProcess::startDetached(executable, parameters); } } void SingleDocumentStrategyPrivate::createNewFromClipboard() { if (mDocumentManager->isEmpty()) { const QMimeData* mimeData = QApplication::clipboard()->mimeData(QClipboard::Clipboard); mDocumentManager->createManager()->createNewFromData(mimeData, true); } else { const QString executable = QCoreApplication::applicationFilePath(); // TODO: get parameters from common place with KCmdLineOptions // TODO: forward also interesting parameters passed to this program const QStringList parameters { QStringLiteral("-c"), QStringLiteral("-g"), QStringLiteral("FromClipboard"), }; KProcess::startDetached(executable, parameters); } } void SingleDocumentStrategyPrivate::createNewWithGenerator(AbstractModelDataGenerator* generator) { Q_Q(SingleDocumentStrategy); // TODO: show dialog in this process, meanwhile start other process, but hidden, // on result of dialog pass on the parameters if (!mDocumentManager->isEmpty()) { const QString executable = QCoreApplication::applicationFilePath(); // TODO: get parameters from common place with KCmdLineOptions // TODO: forward also interesting parameters passed to this program // TODO: add id to AbstractModelDataGenerator, to use instead of className const QStringList parameters { QStringLiteral("-c"), QStringLiteral("-g"), QLatin1String(generator->metaObject()->className()), }; KProcess::startDetached(executable, parameters); return; } AbstractModelDataGeneratorConfigEditor* configEditor = mViewManager->codecViewManager()->createConfigEditor(generator); if (configEditor) { // TODO: make dialog abstract for different UIs auto* dialog = new CreateDialog(configEditor); // dialog->setData( mModel, selection ); TODO if (dialog->exec() == 0) { return; } } QApplication::setOverrideCursor(Qt::WaitCursor); auto* generateThread = new ModelDataGenerateThread(q, generator); generateThread->start(); while (!generateThread->wait(100)) { QCoreApplication::processEvents(QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers); } QMimeData* mimeData = generateThread->data(); delete generateThread; const bool setModified = (generator->flags() & AbstractModelDataGenerator::DynamicGeneration); mDocumentManager->createManager()->createNewFromData(mimeData, setModified); QApplication::restoreOverrideCursor(); } void SingleDocumentStrategyPrivate::load(const QUrl& url) { if (mDocumentManager->isEmpty()) { mDocumentManager->syncManager()->load(url); } else { const QString executable = QCoreApplication::applicationFilePath(); // TODO: get parameters from common place with KCmdLineOptions // TODO: forward also interesting parameters passed to this program const QStringList parameters { url.url() }; KProcess::startDetached(executable, parameters); } } } diff --git a/parts/kpart/browserextension.cpp b/parts/kpart/browserextension.cpp index 28659f85..3601beef 100644 --- a/parts/kpart/browserextension.cpp +++ b/parts/kpart/browserextension.cpp @@ -1,181 +1,181 @@ /* This file is part of the Okteta KPart module, made within the KDE community. Copyright 2004,2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "browserextension.hpp" // part #include "part.hpp" // Okteta Kasten #include #include #include -// KF5 +// KF #include // Qt #include #include #include #include OktetaBrowserExtension::OktetaBrowserExtension(OktetaPart* part) : KParts::BrowserExtension(part) , mPart(part) { setObjectName(QStringLiteral("oktetapartbrowserextension")); connect(mPart, SIGNAL(hasSelectedDataChanged(bool)), SLOT(onSelectionChanged(bool))); emit enableAction("copy", false); emit enableAction("print", true); } void OktetaBrowserExtension::copy() { QMimeData* data = mPart->byteArrayView()->copySelectedData(); if (!data) { return; } QApplication::clipboard()->setMimeData(data, QClipboard::Clipboard); } void OktetaBrowserExtension::print() { auto printAction = mPart->actionCollection()->action(QStringLiteral("file_print")); if (printAction) { printAction->trigger(); } } void OktetaBrowserExtension::onSelectionChanged(bool hasSelection) { emit enableAction("copy", hasSelection); } void OktetaBrowserExtension::saveState(QDataStream& stream) { KParts::BrowserExtension::saveState(stream); Kasten::ByteArrayView* view = mPart->byteArrayView(); Kasten::ByteArrayViewProfileSynchronizer* viewProfileSynchronizer = view->synchronizer(); const QString viewProfileId = viewProfileSynchronizer ? viewProfileSynchronizer->viewProfileId() : QString(); stream << view->zoomLevel() << (int)view->offsetColumnVisible() << view->offsetCoding() << view->visibleByteArrayCodings() << (int)view->layoutStyle() << view->noOfBytesPerLine() << view->noOfGroupedBytes() << (int)view->valueCoding() << view->charCodingName() << (int)view->showsNonprinting() // << view->xOffset() << view->yOffset() << view->cursorPosition() // << (int)view->isCursorBehind() // << view->activeCoding() << view->viewModus() << viewProfileId ; } void OktetaBrowserExtension::restoreState(QDataStream& stream) { KParts::BrowserExtension::restoreState(stream); double zoomLevel; int offsetColumnVisible; int offsetCoding; int visibleCodings; int layoutStyle; int noOfBytesPerLine; int noOfGroupedBytes; int valueCoding; QString charCodingName; int showsNonprinting; // int x, y; int position; // int cursorBehind; // int activeCoding; int viewModus; QString viewProfileId; stream >> zoomLevel >> offsetColumnVisible >> offsetCoding >> visibleCodings >> layoutStyle >> noOfBytesPerLine >> noOfGroupedBytes >> valueCoding >> charCodingName >> showsNonprinting >> position // >> cursorBehind // >> activeCoding >> viewModus >> viewProfileId ; Kasten::ByteArrayView* view = mPart->byteArrayView(); Kasten::ByteArrayViewProfileSynchronizer* viewProfileSynchronizer = view->synchronizer(); if (viewProfileSynchronizer) { viewProfileSynchronizer->setViewProfileId(viewProfileId); } view->setZoomLevel(zoomLevel); view->setViewModus(viewModus); view->toggleOffsetColumn(offsetColumnVisible != 0); view->setOffsetCoding(offsetCoding); view->setVisibleByteArrayCodings(visibleCodings); view->setLayoutStyle(layoutStyle); view->setNoOfBytesPerLine(noOfBytesPerLine); view->setNoOfGroupedBytes(noOfGroupedBytes); view->setValueCoding(valueCoding); view->setCharCoding(charCodingName); view->setShowsNonprinting(showsNonprinting != 0); // view->setColumnsPos( x, y ); view->setCursorPosition(position); // , cursorBehind ); // view->setActiveCoding( (Okteta::ByteArrayColumnView::CodingTypeId)activeCoding ); } diff --git a/parts/kpart/browserextension.hpp b/parts/kpart/browserextension.hpp index d51b2e44..3729e3e8 100644 --- a/parts/kpart/browserextension.hpp +++ b/parts/kpart/browserextension.hpp @@ -1,59 +1,59 @@ /* This file is part of the Okteta KPart module, made within the KDE community. Copyright 2004,2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef OKTETABROWSEREXTENSION_HPP #define OKTETABROWSEREXTENSION_HPP -// KF5 +// KF #include class OktetaPart; /** * @short Extension for better support for embedding in browsers * @author Friedrich W. H. Kossebau */ class OktetaBrowserExtension : public KParts::BrowserExtension { Q_OBJECT public: explicit OktetaBrowserExtension(OktetaPart* part); public: // KParts::BrowserExtension API void saveState(QDataStream& stream) override; void restoreState(QDataStream& stream) override; public Q_SLOTS: /** copy text to clipboard */ void copy(); void print(); private Q_SLOTS: /** selection has changed */ void onSelectionChanged(bool hasSelection); private: OktetaPart* mPart; }; #endif diff --git a/parts/kpart/part.hpp b/parts/kpart/part.hpp index e176c431..49847ed9 100644 --- a/parts/kpart/part.hpp +++ b/parts/kpart/part.hpp @@ -1,108 +1,108 @@ /* This file is part of the Okteta KPart module, made within the KDE community. Copyright 2003,2007,2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef OKTETAPART_HPP #define OKTETAPART_HPP // Kasten #include -// KF5 +// KF #include // Qt #include namespace Kasten { class ByteArrayViewProfileManager; class ByteArrayView; class ByteArrayDocument; class SingleViewArea; class ModelCodecViewManager; class ModelCodecManager; class AbstractXmlGuiController; class AbstractXmlGuiControllerFactory; class AbstractDocument; } class QVBoxLayout; class OktetaPart : public KParts::ReadWritePart { Q_OBJECT friend class OktetaBrowserExtension; public: enum Modus { ReadOnly = 0, BrowserView = 1, ReadWrite = 2 }; public: OktetaPart(QObject* parent, const KAboutData& componentData, Modus modus, Kasten::ByteArrayViewProfileManager* viewProfileManager, Kasten::ModelCodecManager* modelCodecManager, Kasten::ModelCodecViewManager* modelCodecViewManager); ~OktetaPart() override; public: // KParts::ReadWritePart API void setReadWrite(bool readWrite = true) override; Q_SIGNALS: void hasSelectedDataChanged(bool hasSelectedData); protected: // KParts::ReadWritePart API bool saveFile() override; protected: // KParts::ReadOnlyPart API bool openFile() override; private: void setupActions(bool browserViewWanted); void addController(const Kasten::AbstractXmlGuiControllerFactory& factory); private: Kasten::ByteArrayView* byteArrayView() const; private Q_SLOTS: void onDocumentLoaded(Kasten::AbstractDocument* document); void onModified(Kasten::LocalSyncState state); private: const Modus mModus; QVBoxLayout* mLayout; Kasten::ByteArrayDocument* mDocument; Kasten::ByteArrayView* mByteArrayView; Kasten::SingleViewArea* mSingleViewArea; QVector mControllers; Kasten::ByteArrayViewProfileManager* mViewProfileManager; }; inline Kasten::ByteArrayView* OktetaPart::byteArrayView() const { return mByteArrayView; } #endif diff --git a/parts/kpart/partfactory.cpp b/parts/kpart/partfactory.cpp index dd648731..63ebf8e5 100644 --- a/parts/kpart/partfactory.cpp +++ b/parts/kpart/partfactory.cpp @@ -1,98 +1,98 @@ /* This file is part of the Okteta KPart module, made within the KDE community. Copyright 2003,2007,2009,2019 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #include "partfactory.hpp" // part #include "part.hpp" // Okteta Kasten #include #include #include #include #include // Kasten #include #include -// KF5 +// KF #include OktetaPartFactory::OktetaPartFactory() : mAboutData(QStringLiteral("oktetapart"), i18n("OktetaPart"), QStringLiteral(OKTETA_VERSION), i18n("Embedded hex editor"), KAboutLicense::GPL_V2, i18n("2003-2019 Friedrich W. H. Kossebau")) { mAboutData.addAuthor(i18n("Friedrich W. H. Kossebau"), i18n("Author"), QStringLiteral("kossebau@kde.org")); mByteArrayViewProfileManager = new Kasten::ByteArrayViewProfileManager(); mModelCodecViewManager = new Kasten::ModelCodecViewManager(); mModelCodecManager = new Kasten::ModelCodecManager(); const QVector encoderList = Kasten::ByteArrayStreamEncoderFactory::createStreamEncoders(); const QVector generatorList = Kasten::ByteArrayDataGeneratorFactory::createDataGenerators(); const QVector encoderConfigEditorFactoryList = Kasten::ByteArrayStreamEncoderConfigEditorFactoryFactory::createFactorys(); const QVector generatorConfigEditorFactoryList = Kasten::ByteArrayDataGeneratorConfigEditorFactoryFactory::createFactorys(); mModelCodecManager->setEncoders( encoderList ); mModelCodecManager->setGenerators( generatorList ); mModelCodecViewManager->setEncoderConfigEditorFactories(encoderConfigEditorFactoryList); mModelCodecViewManager->setGeneratorConfigEditorFactories(generatorConfigEditorFactoryList); } OktetaPartFactory::~OktetaPartFactory() { delete mByteArrayViewProfileManager; delete mModelCodecViewManager; delete mModelCodecManager; } QObject* OktetaPartFactory::create(const char* iface, QWidget* parentWidget, QObject* parent, const QVariantList& args, const QString& keyword) { Q_UNUSED(parentWidget) Q_UNUSED(keyword); const OktetaPart::Modus modus = (args.contains(QStringLiteral("Browser/View")) || (strcmp(iface, "Browser/View") == 0)) ? OktetaPart::Modus::BrowserView : (strcmp(iface, "KParts::ReadOnlyPart") == 0) ? OktetaPart::Modus::ReadOnly : /* else */ OktetaPart::Modus::ReadWrite; auto* part = new OktetaPart(parent, mAboutData, modus, mByteArrayViewProfileManager, mModelCodecManager, mModelCodecViewManager); return part; } diff --git a/parts/kpart/partfactory.hpp b/parts/kpart/partfactory.hpp index 521947e9..68d8f9ff 100644 --- a/parts/kpart/partfactory.hpp +++ b/parts/kpart/partfactory.hpp @@ -1,65 +1,65 @@ /* This file is part of the Okteta KPart module, made within the KDE community. Copyright 2003,2007,2009 Friedrich W. H. Kossebau This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) version 3, or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 6 of version 3 of the license. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library. If not, see . */ #ifndef OKTETAPARTFACTORY_HPP #define OKTETAPARTFACTORY_HPP -// KF5 +// KF #include #include namespace Kasten { class ByteArrayViewProfileManager; class ModelCodecViewManager; class ModelCodecManager; } class OktetaPartFactory : public KPluginFactory { Q_OBJECT Q_PLUGIN_METADATA(IID KPluginFactory_iid FILE "oktetapart.json") Q_INTERFACES( KPluginFactory ) public: OktetaPartFactory(); ~OktetaPartFactory() override; public: // KPluginFactory API QObject* create(const char* iface, QWidget* parentWidget, QObject* parent, const QVariantList& args, const QString& keyword) override; private: KAboutData mAboutData; Kasten::ByteArrayViewProfileManager* mByteArrayViewProfileManager; Kasten::ModelCodecViewManager* mModelCodecViewManager; Kasten::ModelCodecManager* mModelCodecManager; }; #endif diff --git a/program/about.cpp b/program/about.cpp index d384f7dd..e8945d42 100644 --- a/program/about.cpp +++ b/program/about.cpp @@ -1,47 +1,47 @@ /* This file is part of the Okteta program, made within the KDE community. Copyright 2006-2014 Friedrich W. H. Kossebau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "about.hpp" -// KF5 +// KF #include OktetaAboutData::OktetaAboutData() : KAboutData(QStringLiteral("okteta"), i18n("Okteta"), // name QStringLiteral(OKTETA_VERSION), i18n("Hex editor"), // description KAboutLicense::GPL_V2, i18n("Copyright 2006-2019 Friedrich W. H. Kossebau"), // copyright i18n("Edit the raw data of files"), // comment QStringLiteral("https://userbase.kde.org/Okteta")) { addLicense(KAboutLicense::GPL_V3); setOrganizationDomain("kde.org"); addAuthor(i18n("Friedrich W. H. Kossebau"), // name i18n("Author"), // task QStringLiteral("kossebau@kde.org")); addAuthor(i18nc("Author", "Alexander Richardson"), // name i18nc("Task description", "Structures tool"), // task QStringLiteral("alex.richardson@gmx.de")); setDesktopFileName(QStringLiteral("org.kde.okteta")); } diff --git a/program/about.hpp b/program/about.hpp index f54da702..d5a683e2 100644 --- a/program/about.hpp +++ b/program/about.hpp @@ -1,35 +1,35 @@ /* This file is part of the Okteta program, made within the KDE community. Copyright 2006-2007 Friedrich W. H. Kossebau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef OKTETAABOUT_HPP #define OKTETAABOUT_HPP -// KF5 +// KF #include class OktetaAboutData : public KAboutData { public: OktetaAboutData(); }; #endif diff --git a/program/mainwindow.cpp b/program/mainwindow.cpp index 9c57e699..cb19f666 100644 --- a/program/mainwindow.cpp +++ b/program/mainwindow.cpp @@ -1,346 +1,346 @@ /* This file is part of the Okteta program, made within the KDE community. Copyright 2006-2011 Friedrich W. H. Kossebau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "mainwindow.hpp" // program #include "program.hpp" // tmp #include // tools #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Kasten tools #include #include #include #include #include #include #include #include // controllers // #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Kasten controllers #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Kasten gui #include #include #include #include #include // Kasten core #include #include #include #include -// KF5 +// KF #include #include // Qt #include #include namespace Kasten { static constexpr char LoadedUrlsKey[] = "LoadedUrls"; OktetaMainWindow::OktetaMainWindow(OktetaProgram* program) : ShellWindow(program->viewManager()) , mProgram(program) { setObjectName(QStringLiteral("Shell")); // there is only one mainwindow, so have this show the document if requested connect(mProgram->documentManager(), &DocumentManager::focusRequested, this, &OktetaMainWindow::showDocument); connect(viewArea(), &MultiViewAreas::dataOffered, this, &OktetaMainWindow::onDataOffered); connect(viewArea(), &MultiViewAreas::dataDropped, this, &OktetaMainWindow::onDataDropped); connect(viewArea(), &AbstractGroupedViews::closeRequest, this, &OktetaMainWindow::onCloseRequest); // XXX: Workaround for Qt 4.4's lacking of proper handling of the initial layout of dock widgets // This state is taken from an oktetarc where the docker constellation was configured by hand. // Setting this state if none is present seems to work, but there's // still the versioning problem to be accounted for. // Hack borrowed from trunk/koffice/krita/ui/kis_view2.cpp: const QString mainWindowState = QStringLiteral( "AAAA/wAAAAD9AAAAAwAAAAAAAADPAAACg/wCAAAAAvsAAAAiAEYAaQBsAGUAUwB5AHMAdABlAG0AQgByAG8AdwBzAGUAcgAAAABJAAACgwAAAB4BAAAF+wAAABIARABvAGMAdQBtAGUAbgB0AHMAAAAASQAAAmMAAABeAQAABQAAAAEAAAGcAAACXPwCAAAACPsAAAAUAFAATwBEAEQAZQBjAG8AZABlAHIAAAAAQgAAARMAAAB9AQAABfsAAAAUAFMAdAByAHUAYwB0AFQAbwBvAGwAAAAAQgAAAlwAAAB9AQAABfsAAAAQAFYAZQByAHMAaQBvAG4AcwAAAABNAAAAVgAAAF4BAAAF+wAAABgAQgBpAG4AYQByAHkARgBpAGwAdABlAHIAAAABegAAAM0AAAC8AQAABfsAAAAQAEMAaABlAGMAawBzAHUAbQAAAAF8AAAAywAAAL0BAAAF/AAAAREAAADlAAAAAAD////6AAAAAAEAAAAE+wAAABAAQwBoAGUAYwBrAFMAdQBtAQAAAAD/////AAAAAAAAAAD7AAAAEgBCAG8AbwBrAG0AYQByAGsAcwIAAALBAAAAPQAAAT8AAAFk+wAAAA4AUwB0AHIAaQBuAGcAcwAAAAAA/////wAAAQ8BAAAF+wAAAAgASQBuAGYAbwAAAAGRAAABTAAAAIUBAAAF+wAAABIAQgB5AHQAZQBUAGEAYgBsAGUAAAAAUwAAAjkAAAB9AQAABfsAAAAYAEQAbwBjAHUAbQBlAG4AdABJAG4AZgBvAAAAAEkAAAJjAAAA+wEAAAUAAAADAAAAAAAAAAD8AQAAAAH7AAAAEABUAGUAcgBtAGkAbgBhAGwAAAAAAP////8AAABPAQAABQAABBUAAAGLAAAABAAAAAQAAAAIAAAACPwAAAABAAAAAgAAAAEAAAAWAG0AYQBpAG4AVABvAG8AbABCAGEAcgEAAAAAAAAEBgAAAAAAAAAA"); const char mainWindowStateKey[] = "State"; KConfigGroup group(KSharedConfig::openConfig(), QStringLiteral("MainWindow")); if (!group.hasKey(mainWindowStateKey)) { group.writeEntry(mainWindowStateKey, mainWindowState); } setStatusBar(new Kasten::StatusBar(this)); setupControllers(); setupGUI(); // all controllers which use plugActionList have to do so after(!) setupGUI() or their entries will be removed // TODO: why is this so? // tmp addXmlGuiControllerFromFactory(ToolListMenuControllerFactory(this)); addXmlGuiControllerFromFactory(ViewListMenuControllerFactory(viewManager(), viewArea())); } OktetaMainWindow::~OktetaMainWindow() = default; void OktetaMainWindow::setupControllers() { MultiDocumentStrategy* const documentStrategy = mProgram->documentStrategy(); ViewManager* const viewManager = this->viewManager(); MultiViewAreas* const viewArea = this->viewArea(); ModelCodecViewManager* const codecViewManager = viewManager->codecViewManager(); DocumentManager* const documentManager = mProgram->documentManager(); ModelCodecManager* const codecManager = documentManager->codecManager(); DocumentSyncManager* const syncManager = documentManager->syncManager(); // tmp ByteArrayViewProfileManager* const byteArrayViewProfileManager = mProgram->byteArrayViewProfileManager(); // general, part of Kasten addXmlGuiControllerFromFactory(CreatorControllerFactory(codecManager, documentStrategy)); addXmlGuiControllerFromFactory(LoaderControllerFactory(documentStrategy)); addXmlGuiControllerFromFactory(SetRemoteControllerFactory(syncManager)); addXmlGuiControllerFromFactory(SynchronizeControllerFactory(syncManager)); addXmlGuiControllerFromFactory(ExportControllerFactory(codecViewManager, codecManager)); addXmlGuiControllerFromFactory(CloseControllerFactory(documentStrategy)); addXmlGuiControllerFromFactory(VersionControllerFactory()); addXmlGuiControllerFromFactory(ReadOnlyControllerFactory()); addXmlGuiControllerFromFactory(SwitchViewControllerFactory(viewArea)); addXmlGuiControllerFromFactory(ViewAreaSplitControllerFactory(viewManager, viewArea)); addXmlGuiControllerFromFactory(FullScreenControllerFactory(this)); addXmlGuiControllerFromFactory(QuitControllerFactory(this)); addXmlGuiControllerFromFactory(ZoomControllerFactory()); addXmlGuiControllerFromFactory(SelectControllerFactory()); addXmlGuiControllerFromFactory(ClipboardControllerFactory()); addXmlGuiControllerFromFactory(InsertControllerFactory(codecViewManager, codecManager)); addXmlGuiControllerFromFactory(CopyAsControllerFactory(codecViewManager, codecManager)); addToolFromFactory(FileSystemBrowserToolViewFactory(), FileSystemBrowserToolFactory(syncManager)); addToolFromFactory(DocumentsToolViewFactory(), DocumentsToolFactory(documentManager)); addToolFromFactory(TerminalToolViewFactory(), TerminalToolFactory(syncManager)); #ifndef NDEBUG addToolFromFactory(VersionViewToolViewFactory(), VersionViewToolFactory()); #endif // Okteta specific // addXmlGuiControllerFromFactory(OverwriteOnlyControllerFactory() ); addXmlGuiControllerFromFactory(OverwriteModeControllerFactory()); addXmlGuiControllerFromFactory(SearchControllerFactory(this)); addXmlGuiControllerFromFactory(ReplaceControllerFactory(this)); addXmlGuiControllerFromFactory(GotoOffsetControllerFactory(viewArea)); addXmlGuiControllerFromFactory(SelectRangeControllerFactory(viewArea)); addXmlGuiControllerFromFactory(BookmarksControllerFactory()); addXmlGuiControllerFromFactory(PrintControllerFactory()); addXmlGuiControllerFromFactory(ViewConfigControllerFactory()); addXmlGuiControllerFromFactory(ViewModeControllerFactory()); addXmlGuiControllerFromFactory(ViewContextMenuControllerFactory()); addXmlGuiControllerFromFactory(ViewProfileControllerFactory(byteArrayViewProfileManager, this)); addXmlGuiControllerFromFactory(ViewProfilesManageControllerFactory(byteArrayViewProfileManager, this)); auto* const bottomBar = static_cast(statusBar()); addXmlGuiControllerFromFactory(ViewStatusControllerFactory(bottomBar)); addXmlGuiControllerFromFactory(ModifiedBarControllerFactory(bottomBar)); addXmlGuiControllerFromFactory(ReadOnlyBarControllerFactory(bottomBar)); addXmlGuiControllerFromFactory(ZoomBarControllerFactory(bottomBar)); addToolFromFactory(DocumentInfoToolViewFactory(), DocumentInfoToolFactory(syncManager)); addToolFromFactory(ChecksumToolViewFactory(), ChecksumToolFactory()); addToolFromFactory(FilterToolViewFactory(), FilterToolFactory()); addToolFromFactory(CharsetConversionToolViewFactory(), CharsetConversionToolFactory()); addToolFromFactory(StringsExtractToolViewFactory(), StringsExtractToolFactory()); addToolFromFactory(ByteTableToolViewFactory(), ByteTableToolFactory()); addToolFromFactory(InfoToolViewFactory(), InfoToolFactory()); addToolFromFactory(PodDecoderToolViewFactory(), PodDecoderToolFactory()); addToolFromFactory(StructuresToolViewFactory(), StructuresToolFactory()); addToolFromFactory(BookmarksToolViewFactory(), BookmarksToolFactory()); } void OktetaMainWindow::addToolFromFactory(const AbstractToolViewFactory& toolViewFactory, const AbstractToolFactory& toolFactory) { AbstractTool* tool = toolFactory.create(); AbstractToolView* toolView = toolViewFactory.create(tool); addTool(toolView); } void OktetaMainWindow::addXmlGuiControllerFromFactory(const AbstractXmlGuiControllerFactory& factory) { AbstractXmlGuiController* controller = factory.create(this); addXmlGuiController(controller); } bool OktetaMainWindow::queryClose() { // TODO: query the document manager or query the view manager? return mProgram->documentManager()->canCloseAll(); } void OktetaMainWindow::saveProperties(KConfigGroup& configGroup) { DocumentManager* const documentManager = mProgram->documentManager(); DocumentSyncManager* const syncManager = documentManager->syncManager(); const QVector documents = documentManager->documents(); QStringList urls; urls.reserve(documents.size()); for (AbstractDocument* document : documents) { urls.append(syncManager->urlOf(document).url()); } configGroup.writePathEntry(LoadedUrlsKey, urls); } void OktetaMainWindow::readProperties(const KConfigGroup& configGroup) { const QStringList urls = configGroup.readPathEntry(LoadedUrlsKey, QStringList()); DocumentManager* const documentManager = mProgram->documentManager(); DocumentSyncManager* const syncManager = documentManager->syncManager(); DocumentCreateManager* const createManager = documentManager->createManager(); for (const QString& url : urls) { if (url.isEmpty()) { createManager->createNew(); } else { syncManager->load(QUrl(url, QUrl::TolerantMode)); } // TODO: set view to offset // if( offset != -1 ) } } void OktetaMainWindow::onDataOffered(const QMimeData* mimeData, bool& accept) { accept = mimeData->hasUrls() || mProgram->documentManager()->createManager()->canCreateNewFromData(mimeData); } void OktetaMainWindow::onDataDropped(const QMimeData* mimeData) { const QList urls = mimeData->urls(); DocumentManager* const documentManager = mProgram->documentManager(); if (!urls.isEmpty()) { DocumentSyncManager* const syncManager = documentManager->syncManager(); for (const QUrl& url : urls) { syncManager->load(url); } } else { documentManager->createManager()->createNewFromData(mimeData, true); } } void OktetaMainWindow::onCloseRequest(const QVector& views) { // group views per document QHash> viewsToClosePerDocument; for (AbstractView* view : views) { auto* document = view->findBaseModel(); viewsToClosePerDocument[document].append(view); } // find documents which lose all views const QVector allViews = viewManager()->views(); for (AbstractView* view : allViews) { auto* document = view->findBaseModel(); QHash>::Iterator it = viewsToClosePerDocument.find(document); if (it != viewsToClosePerDocument.end()) { const QVector& viewsOfDocument = it.value(); const bool isAnotherView = !viewsOfDocument.contains(view); if (isAnotherView) { viewsToClosePerDocument.erase(it); } } } const QVector documentsWithoutViews = viewsToClosePerDocument.keys().toVector(); DocumentManager* const documentManager = mProgram->documentManager(); if (documentManager->canClose(documentsWithoutViews)) { viewManager()->removeViews(views); documentManager->closeDocuments(documentsWithoutViews); } } } diff --git a/program/program.cpp b/program/program.cpp index c92b4e1e..a16717e7 100644 --- a/program/program.cpp +++ b/program/program.cpp @@ -1,174 +1,174 @@ /* This file is part of the Okteta program, made within the KDE community. Copyright 2006-2009,2011,2014 Friedrich W. H. Kossebau This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License or (at your option) version 3 or any later version accepted by the membership of KDE e.V. (or its successor approved by the membership of KDE e.V.), which shall act as a proxy defined in Section 14 of version 3 of the license. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "program.hpp" // program #include "about.hpp" #include "mainwindow.hpp" // Okteta Kasten #include #include #include #include #include #include #include // tmp #include // Kasten gui #include #include #include #include // Kasten core #include #include #include #include -// KF5 +// KF #include #include #include // Qt #include #include #include #include #include namespace Kasten { // static constexpr char OffsetOptionId[] = "offset"; // static constexpr char OffsetOptionShortId[] = "o"; static int& preConstructionHookHack(int& argc) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); return argc; } OktetaProgram::OktetaProgram(int& argc, char* argv[]) : mApp(preConstructionHookHack(argc), argv) { QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true); KLocalizedString::setApplicationDomain("okteta"); KCrash::initialize(); } OktetaProgram::~OktetaProgram() { delete mDocumentStrategy; delete mDocumentManager; delete mViewManager; delete mDialogHandler; delete mByteArrayViewProfileManager; } int OktetaProgram::execute() { mDocumentManager = new DocumentManager(); mViewManager = new ViewManager(); mDocumentStrategy = new MultiDocumentStrategy(mDocumentManager, mViewManager); mDialogHandler = new DialogHandler(); OktetaAboutData aboutData; KAboutData::setApplicationData(aboutData); QApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("okteta"))); QCommandLineParser parser; aboutData.setupCommandLine(&parser); // urls to open parser.addPositionalArgument(QStringLiteral("urls"), i18n("File(s) to load."), QStringLiteral("[urls...]")); // offset option // programOptions.add( OffsetOptionShortId ); // programOptions.add( OffsetOptionId, ki18n("Offset to set the cursor to"), 0 ); parser.process(mApp); aboutData.processCommandLine(&parser); KDBusService programDBusService(KDBusService::Multiple | KDBusService::NoExitOnFailure); // TODO: mByteArrayViewProfileManager = new ByteArrayViewProfileManager(); // mModelManagerManager->addModelManager( byteArrayViewProfileManager ); const QVector encoderList = ByteArrayStreamEncoderFactory::createStreamEncoders(); const QVector generatorList = ByteArrayDataGeneratorFactory::createDataGenerators(); const QVector encoderConfigEditorFactoryList = ByteArrayStreamEncoderConfigEditorFactoryFactory::createFactorys(); const QVector generatorConfigEditorFactoryList = ByteArrayDataGeneratorConfigEditorFactoryFactory::createFactorys(); mDocumentManager->codecManager()->setEncoders(encoderList); mDocumentManager->codecManager()->setGenerators(generatorList); mDocumentManager->codecManager()->setOverwriteDialog(mDialogHandler); mDocumentManager->createManager()->setDocumentFactory(new ByteArrayDocumentFactory()); mDocumentManager->syncManager()->setDocumentSynchronizerFactory(new ByteArrayRawFileSynchronizerFactory()); mDocumentManager->syncManager()->setOverwriteDialog(mDialogHandler); mDocumentManager->syncManager()->setSaveDiscardDialog(mDialogHandler); mViewManager->setViewFactory(new ByteArrayViewFactory(mByteArrayViewProfileManager)); mViewManager->codecViewManager()->setEncoderConfigEditorFactories(encoderConfigEditorFactoryList); mViewManager->codecViewManager()->setGeneratorConfigEditorFactories(generatorConfigEditorFactoryList); auto* mainWindow = new OktetaMainWindow(this); mDialogHandler->setWidget(mainWindow); // started by session management? if (mApp.isSessionRestored() && KMainWindow::canBeRestored(1)) { mainWindow->restore(1); } else { // no session.. just start up normally const QStringList urls = parser.positionalArguments(); // take arguments if (!urls.isEmpty()) { const QString currentPath = QDir::currentPath(); for (const QString& url : urls) { mDocumentStrategy->load(QUrl::fromUserInput(url, currentPath, QUrl::AssumeLocalFile)); } } mainWindow->show(); } return QApplication::exec(); } void OktetaProgram::quit() { qApp->quit(); } }