File indexing completed on 2025-01-05 05:23:24
0001 /* 0002 This file is part of the Okteta Kasten module, made within the KDE community. 0003 0004 SPDX-FileCopyrightText: 2008, 2010, 2012 Friedrich W. H. Kossebau <kossebau@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0007 */ 0008 0009 #include "documentinfotool.hpp" 0010 0011 // lib 0012 #include "bytearraymodeliodevice.hpp" 0013 // Okteta Kasten core 0014 #include <Kasten/Okteta/ByteArrayDocument> 0015 // Kasten core 0016 #include <Kasten/DocumentSyncManager> 0017 #include <Kasten/AbstractModelSynchronizer> 0018 0019 // Okteta core 0020 #include <Okteta/AbstractByteArrayModel> 0021 #include <Okteta/ArrayChangeMetricsList> 0022 // KF 0023 #include <KLocalizedString> 0024 // Qt 0025 #include <QApplication> 0026 #include <QTimer> 0027 #include <QUrl> 0028 #include <QMimeDatabase> 0029 0030 namespace Kasten { 0031 0032 static constexpr int mimeTypeUpdateTimeInterval = 500; // msec 0033 0034 DocumentInfoTool::DocumentInfoTool(DocumentSyncManager* syncManager) 0035 : mDocumentSyncManager(syncManager) 0036 , mMimeTypeUpdateTimer(new QTimer(this)) 0037 { 0038 setObjectName(QStringLiteral("DocumentInfo")); 0039 0040 mMimeTypeUpdateTimer->setInterval(mimeTypeUpdateTimeInterval); 0041 mMimeTypeUpdateTimer->setSingleShot(true); 0042 connect(mMimeTypeUpdateTimer, &QTimer::timeout, this, &DocumentInfoTool::updateMimeType); 0043 } 0044 0045 DocumentInfoTool::~DocumentInfoTool() = default; 0046 0047 // TODO: file or document or ...? 0048 QString DocumentInfoTool::title() const { return i18nc("@title:window", "File Info"); } 0049 QString DocumentInfoTool::documentTitle() const 0050 { 0051 return mDocument ? mDocument->title() : QString(); 0052 } 0053 0054 QString DocumentInfoTool::location() const 0055 { 0056 QString result; 0057 if (mDocument) { 0058 const QUrl url = mDocumentSyncManager->urlOf(mDocument); 0059 result = url.toDisplayString(QUrl::PrettyDecoded | QUrl::PreferLocalFile); 0060 } 0061 return result; 0062 } 0063 0064 int DocumentInfoTool::documentSize() const 0065 { 0066 int documentSize = -1; 0067 if (mByteArrayModel) { 0068 documentSize = mByteArrayModel->size(); 0069 } 0070 0071 return documentSize; 0072 } 0073 0074 void DocumentInfoTool::setTargetModel(AbstractModel* model) 0075 { 0076 if (mSynchronizer) { 0077 mSynchronizer->disconnect(this); 0078 } 0079 if (mDocument) { 0080 mDocument->disconnect(this); 0081 } 0082 if (mByteArrayModel) { 0083 mByteArrayModel->disconnect(this); 0084 } 0085 0086 mDocument = model ? model->findBaseModel<ByteArrayDocument*>() : nullptr; 0087 mByteArrayModel = mDocument ? mDocument->content() : nullptr; 0088 0089 const bool hasDocument = (mDocument != nullptr); 0090 AbstractModelSynchronizer* synchronizer = nullptr; 0091 QString documentTitle; 0092 int documentSize = -1; 0093 if (hasDocument) { 0094 documentTitle = mDocument->title(); 0095 documentSize = mByteArrayModel->size(); 0096 synchronizer = mDocument->synchronizer(); 0097 0098 connect(mDocument, &ByteArrayDocument::titleChanged, 0099 this, &DocumentInfoTool::documentTitleChanged); 0100 connect(mDocument, &ByteArrayDocument::synchronizerChanged, 0101 this, &DocumentInfoTool::onSynchronizerChanged); 0102 connect(mByteArrayModel, &Okteta::AbstractByteArrayModel::contentsChanged, 0103 this, &DocumentInfoTool::onContentsChanged); 0104 } 0105 0106 onSynchronizerChanged(synchronizer); 0107 0108 Q_EMIT documentTitleChanged(documentTitle); 0109 Q_EMIT documentSizeChanged(documentSize); 0110 } 0111 0112 // TODO: should this be done in a worker thread, to not block the UI? 0113 void DocumentInfoTool::updateMimeType() 0114 { 0115 QMimeType currentMimeType; 0116 0117 if (mDocument) { 0118 // TODO: also get file mode, if available, for findByNameAndContent() 0119 const QString filename = mDocumentSyncManager->urlOf(mDocument).fileName(); 0120 0121 Okteta::ByteArrayModelIoDevice byteArrayModelIoDevice(mByteArrayModel); 0122 QMimeDatabase db; 0123 currentMimeType = filename.isEmpty() ? 0124 db.mimeTypeForData(&byteArrayModelIoDevice) : 0125 db.mimeTypeForFileNameAndData(filename, &byteArrayModelIoDevice); 0126 } 0127 0128 if (mMimeType != currentMimeType) { 0129 mMimeType = currentMimeType; 0130 Q_EMIT documentMimeTypeChanged(currentMimeType); 0131 } 0132 } 0133 0134 void DocumentInfoTool::onContentsChanged() 0135 { 0136 if (!mMimeTypeUpdateTimer->isActive()) { 0137 mMimeTypeUpdateTimer->start(); 0138 } 0139 0140 Q_EMIT documentSizeChanged(mByteArrayModel->size()); 0141 } 0142 0143 void DocumentInfoTool::onSynchronizerChanged(AbstractModelSynchronizer* synchronizer) 0144 { 0145 // do an instant update, no need to delay 0146 if (mMimeTypeUpdateTimer->isActive()) { 0147 mMimeTypeUpdateTimer->stop(); 0148 } 0149 updateMimeType(); 0150 0151 if (mSynchronizer) { 0152 mSynchronizer->disconnect(this); 0153 } 0154 mSynchronizer = synchronizer; 0155 0156 if (mSynchronizer) { 0157 connect(mSynchronizer, &AbstractModelSynchronizer::urlChanged, 0158 this, &DocumentInfoTool::onUrlChanged); 0159 } 0160 0161 Q_EMIT locationChanged(location()); 0162 } 0163 0164 void DocumentInfoTool::onUrlChanged(const QUrl& url) 0165 { 0166 Q_UNUSED(url); 0167 0168 Q_EMIT locationChanged(location()); 0169 } 0170 0171 } 0172 0173 #include "moc_documentinfotool.cpp"