diff --git a/CMakeLists.txt b/CMakeLists.txt index c793ece..998d954 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,78 +1,77 @@ cmake_minimum_required(VERSION 3.0) # KDE Application Version, managed by release script set (KDE_APPLICATIONS_VERSION_MAJOR "19") set (KDE_APPLICATIONS_VERSION_MINOR "07") set (KDE_APPLICATIONS_VERSION_MICRO "70") set (KDE_APPLICATIONS_VERSION "${KDE_APPLICATIONS_VERSION_MAJOR}.${KDE_APPLICATIONS_VERSION_MINOR}.${KDE_APPLICATIONS_VERSION_MICRO}") project(baloo-widgets VERSION ${KDE_APPLICATIONS_VERSION}) set(QT_MIN_VERSION "5.8.0") set(KF5_MIN_VERSION "5.58.0") find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ${ECM_MODULE_PATH}) find_package(Qt5 ${QT_MIN_VERSION} REQUIRED NO_MODULE COMPONENTS Core Widgets Test) find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS Config KIO I18n FileMetaData Baloo) include(ECMSetupVersion) include(ECMInstallIcons) include(GenerateExportHeader) include(FeatureSummary) include(KDEInstallDirs) include(KDECMakeSettings) include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) include(ECMGenerateHeaders) include(ECMAddTests) include(CMakePackageConfigHelpers) #TODO remove these -remove_definitions(-DQT_NO_CAST_FROM_ASCII) remove_definitions(-DQT_NO_CAST_FROM_BYTEARRAY) ecm_setup_version(PROJECT VARIABLE_PREFIX BALOO_WIDGETS SOVERSION 5 VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/baloowidgets_version.h" PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5BalooWidgetsConfigVersion.cmake") include_directories( ${CMAKE_SOURCE_DIR}/src ${CMAKE_BINARY_DIR}/src ) add_subdirectory(src) if (BUILD_TESTING) add_subdirectory(test) add_subdirectory(autotests) endif() # Config files set(CMAKECONFIG_INSTALL_DIR "${CMAKECONFIG_INSTALL_PREFIX}/KF5BalooWidgets") configure_package_config_file( "${CMAKE_CURRENT_SOURCE_DIR}/KF5BalooWidgetsConfig.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/KF5BalooWidgetsConfig.cmake" INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/KF5BalooWidgetsConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/KF5BalooWidgetsConfigVersion.cmake" DESTINATION ${CMAKECONFIG_INSTALL_DIR} COMPONENT devel ) install(EXPORT KF5BalooWidgetsTargets NAMESPACE KF5:: DESTINATION ${CMAKECONFIG_INSTALL_DIR} FILE KF5BalooWidgetsTargets.cmake ) feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES ) diff --git a/autotests/filemetadatadatedisplaytest.cpp b/autotests/filemetadatadatedisplaytest.cpp index 932c881..dc035b0 100644 --- a/autotests/filemetadatadatedisplaytest.cpp +++ b/autotests/filemetadatadatedisplaytest.cpp @@ -1,137 +1,137 @@ /* * This file is part of the KDE Baloo Project * Copyright 2018 Michael Heidelbach * * 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 "filemetadatadatedisplaytest.h" #include #include #include #include #include #include #include #include #include #include #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) #include #include #include #endif void initLocale() { - QLocale::setDefault(QLocale("en_US")); + QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); } Q_CONSTRUCTOR_FUNCTION(initLocale) QTEST_MAIN(FileMetadataDateDisplayTest) bool FileMetadataDateDisplayTest::setFileTime(const QString& filePath, const QDateTime& fileTime) { bool ret; #if QT_VERSION < QT_VERSION_CHECK(5, 10, 0) struct stat fileStat; struct utimbuf newTimes; const QByteArray file = QFile::encodeName(filePath); stat(file, &fileStat); newTimes.actime = fileStat.st_atime; newTimes.modtime = fileTime.toTime_t(); ret = (utime(file, &newTimes) == 0); #else QScopedPointer file{new QFile(filePath)}; file->open(QIODevice::ReadOnly); ret = file->setFileTime(fileTime, QFileDevice::FileModificationTime); file->close(); #endif return ret; } void FileMetadataDateDisplayTest::initTestCase() { qRegisterMetaType("KFileItemList"); QStandardPaths::setTestModeEnabled(true); QVERIFY( setFileTime(QFINDTESTDATA("samplefiles/testtagged.m4a"), QDateTime::currentDateTime().addDays(-1)) ); QVERIFY( setFileTime(QFINDTESTDATA("samplefiles/testtagged.mp3"), QDateTime::currentDateTime().addYears(-10)) ); } void FileMetadataDateDisplayTest::shouldDisplayLongAndShortDates_data() { QTest::addColumn("format"); QTest::addColumn("file"); QTest::addColumn("regex"); QTest::addRow("Short date, long ago") << Baloo::DateFormats::ShortFormat << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.mp3")) - << QRegularExpression("(?:[1-3][0-9]|[1-9]) (?:[1-2][0-9]|[1-9]):[0-5][0-9] [AP]M") + << QRegularExpression(QStringLiteral("(?:[1-3][0-9]|[1-9]) (?:[1-2][0-9]|[1-9]):[0-5][0-9] [AP]M")) ; QTest::addRow("Short date, yesterday") << Baloo::DateFormats::ShortFormat << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.m4a")) - << QRegularExpression("Yesterday, (?:[1-2][0-9]|[1-9]):[0-5][0-9] [AP]M") + << QRegularExpression(QStringLiteral("Yesterday, (?:[1-2][0-9]|[1-9]):[0-5][0-9] [AP]M")) ; QTest::addRow("Long date, long ago") << Baloo::DateFormats::LongFormat << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.mp3")) - << QRegularExpression("[A-Z][a-z]+, [A-Z][a-z]+ (?:[1-3][0-9]|[1-9]), 20[0-9]{2} (?:1[0-2]|[1-9]):[0-5][0-9]:[0-5][0-9] [AP]M [A-Z]{3,4}") + << QRegularExpression(QStringLiteral("[A-Z][a-z]+, [A-Z][a-z]+ (?:[1-3][0-9]|[1-9]), 20[0-9]{2} (?:1[0-2]|[1-9]):[0-5][0-9]:[0-5][0-9] [AP]M [A-Z]{3,4}")) ; QTest::addRow("Long date, yesterday") << Baloo::DateFormats::LongFormat << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.m4a")) - << QRegularExpression("Yesterday, (?:1[0-2]|[1-9]):[0-5][0-9]:[0-5][0-9] [AP]M [A-Z]{3,4}") + << QRegularExpression(QStringLiteral("Yesterday, (?:1[0-2]|[1-9]):[0-5][0-9]:[0-5][0-9] [AP]M [A-Z]{3,4}")) ; } void FileMetadataDateDisplayTest::shouldDisplayLongAndShortDates() { QFETCH(Baloo::DateFormats, format); QFETCH(QUrl, file); QFETCH(QRegularExpression, regex); const auto widget = new Baloo::FileMetaDataWidget(); widget->setDateFormat(format); QSignalSpy spy(widget, &Baloo::FileMetaDataWidget::metaDataRequestFinished); widget->setItems(KFileItemList() << file); QVERIFY(spy.wait()); QLabel* dateWidget = widget->findChild(QStringLiteral("kfileitem#modified"), Qt::FindDirectChildrenOnly); QVERIFY2(dateWidget, "Date widget not found"); QVERIFY2(regex.match(dateWidget->text()).hasMatch(), qPrintable(QStringLiteral("\"%1\" did not match %2").arg(dateWidget->text(), regex.pattern())) ); } diff --git a/autotests/filemetadataitemcounttest.cpp b/autotests/filemetadataitemcounttest.cpp index 5598927..acca074 100644 --- a/autotests/filemetadataitemcounttest.cpp +++ b/autotests/filemetadataitemcounttest.cpp @@ -1,91 +1,91 @@ /* * This file is part of the KDE Baloo Project * Copyright 2018 Michael Heidelbach * * 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 "filemetadataitemcounttest.h" #include #include #include #include #include #include #include #include #include #include #include #include #include QTEST_MAIN(FileMetadataItemCountTest) void FileMetadataItemCountTest::initTestCase() { qRegisterMetaType("KFileItemList"); QStandardPaths::setTestModeEnabled(true); - KConfig balooConfig("baloofilerc", KConfig::NoGlobals); + KConfig balooConfig(QStringLiteral("baloofilerc"), KConfig::NoGlobals); KConfigGroup balooSettings = balooConfig.group("General"); // If we use .writePathEntry here, the test will fail. balooSettings.writeEntry(QStringLiteral("folders"), QString()); // Ensure show configuration - KConfig config("baloofileinformationrc", KConfig::NoGlobals); + KConfig config(QStringLiteral("baloofileinformationrc"), KConfig::NoGlobals); KConfigGroup settings = config.group("Show"); const auto keys = settings.keyList(); for (const auto &key: keys) { settings.writeEntry(key, true); } } void FileMetadataItemCountTest::init() { m_widget = new Baloo::FileMetaDataWidget; } void FileMetadataItemCountTest::cleanup() { delete m_widget; } void FileMetadataItemCountTest::testItemCount() { // the number of items will increase in the future adding the file creation time field // when the system has KIO 5.58, glibc 2.28, linux 4.11 and a filesystem storing file creation times (btrfs, ext4...) // The expectedItems count will need to be updated const int expectedItems = 20; const int widgetsPerItem = 2; QSignalSpy spy(m_widget, &Baloo::FileMetaDataWidget::metaDataRequestFinished); m_widget->setItems(KFileItemList() << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.mp3")) ); QVERIFY(spy.wait()); QCOMPARE(spy.count(), 1); QList items = m_widget->findChildren(QString(), Qt::FindDirectChildrenOnly); QCOMPARE(items.count(), expectedItems * widgetsPerItem); } diff --git a/autotests/filemetadatawidgettest.cpp b/autotests/filemetadatawidgettest.cpp index 9202081..2a8b233 100644 --- a/autotests/filemetadatawidgettest.cpp +++ b/autotests/filemetadatawidgettest.cpp @@ -1,209 +1,209 @@ /* * This file is part of the KDE Baloo Project * Copyright 2018 Michael Heidelbach * * 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 "filemetadatawidgettest.h" #include #include #include #include #include #include #include #include #include #include #include #include #include void initLocale() { - QLocale::setDefault(QLocale("en_US")); + QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); } Q_CONSTRUCTOR_FUNCTION(initLocale) QTEST_MAIN(FileMetadataWidgetTest) void FileMetadataWidgetTest::initTestCase() { qRegisterMetaType("KFileItemList"); QStandardPaths::setTestModeEnabled(true); - KConfig balooConfig("baloofilerc", KConfig::NoGlobals); + KConfig balooConfig(QStringLiteral("baloofilerc"), KConfig::NoGlobals); KConfigGroup balooSettings = balooConfig.group("General"); // If we use .writePathEntry here, the test will fail. balooSettings.writeEntry(QStringLiteral("folders"), QString()); // Ensure show configuration - KConfig config("baloofileinformationrc", KConfig::NoGlobals); + KConfig config(QStringLiteral("baloofileinformationrc"), KConfig::NoGlobals); KConfigGroup settings = config.group("Show"); const auto keys = settings.keyList(); for (const auto &key: keys) { settings.writeEntry(key, true); } const QString exe = QStandardPaths::findExecutable(QStringLiteral("setfattr")); if (exe.isEmpty()) { return; } const QStringList args = {QStringLiteral("--name=user.baloo.rating"), QStringLiteral("--value=5") , QFINDTESTDATA("samplefiles/testtagged.mp3"), QFINDTESTDATA("samplefiles/testtagged.m4a")}; QProcess process; process.start(exe, args); if (!process.waitForFinished(10000)) { qDebug() << "setfattr timed out"; return; } if (process.exitStatus() == QProcess::NormalExit) { m_mayTestRating = true; } else { qDebug() << "setfattr err:" << process.readAllStandardError(); } } void FileMetadataWidgetTest::init() { m_widget = new Baloo::FileMetaDataWidget; } void FileMetadataWidgetTest::cleanup() { delete m_widget; } void FileMetadataWidgetTest::shouldSignalOnceWithoutFile() { QSignalSpy spy(m_widget, &Baloo::FileMetaDataWidget::metaDataRequestFinished); m_widget->setItems(KFileItemList()); QCOMPARE(spy.count(), 1); QCOMPARE(m_widget->items().count(), 0); } void FileMetadataWidgetTest::shouldSignalOnceFile() { QSignalSpy spy(m_widget, &Baloo::FileMetaDataWidget::metaDataRequestFinished); m_widget->setItems(KFileItemList() << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.m4a")) ); QVERIFY(spy.wait()); QCOMPARE(spy.count(), 1); QCOMPARE(m_widget->items().count(), 1); } void FileMetadataWidgetTest::shouldSignalOnceFiles() { QSignalSpy spy(m_widget, &Baloo::FileMetaDataWidget::metaDataRequestFinished); m_widget->setItems(KFileItemList() << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/test.mp3")) << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.mp3")) << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.m4a")) ); QVERIFY(spy.wait()); QCOMPARE(spy.count(), 1); QCOMPARE(m_widget->items().count(), 3); } void FileMetadataWidgetTest::shouldShowProperties() { QSignalSpy spy(m_widget, &Baloo::FileMetaDataWidget::metaDataRequestFinished); m_widget->setItems(KFileItemList() << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.mp3")) ); QVERIFY(spy.wait()); QCOMPARE(spy.count(), 1); // simple property - QLabel* valueWidget = m_widget->findChild("kfileitem#type"); + QLabel* valueWidget = m_widget->findChild(QStringLiteral("kfileitem#type")); QVERIFY2(valueWidget, "Type data missing"); QCOMPARE(valueWidget->text(), QLatin1String("MP3 audio")); if (m_mayTestRating) { // editable property - KRatingWidget* ratingWidget = m_widget->findChild("rating"); + KRatingWidget* ratingWidget = m_widget->findChild(QStringLiteral("rating")); QVERIFY2(ratingWidget, "Rating data missing"); QCOMPARE(ratingWidget->rating(), 5u); } else { qDebug() << "Skipped 'Rating' test"; } // async property - valueWidget = m_widget->findChild("albumArtist"); + valueWidget = m_widget->findChild(QStringLiteral("albumArtist")); QVERIFY2(valueWidget, "albumArtist data was not found"); QCOMPARE(valueWidget->text(), QLatin1String("Bill Laswell")); } void FileMetadataWidgetTest::shouldShowCommonProperties() { QSignalSpy spy(m_widget, &Baloo::FileMetaDataWidget::metaDataRequestFinished); m_widget->setItems(KFileItemList() << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.mp3")) << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/testtagged.m4a")) ); QVERIFY(spy.wait()); QCOMPARE(spy.count(), 1); // simple property - QLabel* valueWidget = m_widget->findChild("kfileitem#type"); + QLabel* valueWidget = m_widget->findChild(QStringLiteral("kfileitem#type")); QVERIFY(!valueWidget); - valueWidget = m_widget->findChild("kfileitem#totalSize"); + valueWidget = m_widget->findChild(QStringLiteral("kfileitem#totalSize")); // circumvent i18n formatting QCOMPARE(valueWidget->text().left(3), QLatin1String("153")); // editable property if (m_mayTestRating) { - KRatingWidget* ratingWidget = m_widget->findChild("rating"); + KRatingWidget* ratingWidget = m_widget->findChild(QStringLiteral("rating")); QVERIFY2(ratingWidget, "Rating data missing"); QCOMPARE(ratingWidget->rating(), 5u); } else { qDebug() << "Skipped 'Rating' test"; } // async property // FIXME: Make this pass // QCOMPARE( map->value("Album Artist:"), QLatin1String("Bill Laswell")); } void FileMetadataWidgetTest::shouldShowMultiValueProperties() { QSignalSpy spy(m_widget, &Baloo::FileMetaDataWidget::metaDataRequestFinished); m_widget->setItems(KFileItemList() << QUrl::fromLocalFile(QFINDTESTDATA("samplefiles/test_multivalue.ogg")) ); QVERIFY(spy.wait()); QCOMPARE(spy.count(), 1); auto artistWidget = m_widget->findChild(QStringLiteral("artist")); QVERIFY2(artistWidget, "artist not found"); - QCOMPARE(artistWidget->text(), "Artist1 and Artist2"); + QCOMPARE(artistWidget->text(), QStringLiteral("Artist1 and Artist2")); auto genreWidget = m_widget->findChild(QStringLiteral("genre")); QVERIFY2(genreWidget, "genre not found"); - QCOMPARE(genreWidget->text(), "Genre1, Genre2, and Genre3"); + QCOMPARE(genreWidget->text(), QStringLiteral("Genre1, Genre2, and Genre3")); } diff --git a/src/filemetadataconfigwidget.cpp b/src/filemetadataconfigwidget.cpp index cb43f15..f43158e 100644 --- a/src/filemetadataconfigwidget.cpp +++ b/src/filemetadataconfigwidget.cpp @@ -1,202 +1,202 @@ /***************************************************************************** * Copyright (C) 2013 by Vishesh Handa * * Copyright (C) 2009 by Peter Penz * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * 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 * * Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public License * * along with this library; see the file COPYING.LIB. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * *****************************************************************************/ #include "filemetadataconfigwidget.h" #include "filemetadataprovider.h" #include #include #include #include #include #include using namespace Baloo; class FileMetaDataConfigWidget::Private { public: Private(FileMetaDataConfigWidget* parent); ~Private(); void init(); void loadMetaData(); void addItem(const QString& property); /** * Is invoked after the meta data model has finished the loading of * meta data. The meta data labels will be added to the configuration * list. */ void slotLoadingFinished(); int m_visibleDataTypes; KFileItemList m_fileItems; FileMetaDataProvider* m_provider; QListWidget* m_metaDataList; private: FileMetaDataConfigWidget* const q; }; FileMetaDataConfigWidget::Private::Private(FileMetaDataConfigWidget* parent) : m_visibleDataTypes(0), m_fileItems(), m_provider(nullptr), m_metaDataList(nullptr), q(parent) { m_metaDataList = new QListWidget(q); m_metaDataList->setSelectionMode(QAbstractItemView::NoSelection); m_metaDataList->setSortingEnabled(true); QVBoxLayout* layout = new QVBoxLayout(q); layout->addWidget(m_metaDataList); m_provider = new FileMetaDataProvider(q); m_provider->setReadOnly(true); connect(m_provider, SIGNAL(loadingFinished()), q, SLOT(slotLoadingFinished())); } FileMetaDataConfigWidget::Private::~Private() { } void FileMetaDataConfigWidget::Private::loadMetaData() { m_metaDataList->clear(); m_provider->setItems(m_fileItems); } void FileMetaDataConfigWidget::Private::addItem(const QString& key) { // Meta information provided by Baloo that is already // available from KFileItem as "fixed item" (see above) // should not be shown as second entry. static const char* const hiddenProperties[] = { "comment", // = fixed item kfileitem#comment "contentSize", // = fixed item kfileitem#size nullptr // mandatory last entry }; int i = 0; while (hiddenProperties[i] != nullptr) { if (key == QLatin1String(hiddenProperties[i])) { // the item is hidden return; } ++i; } // the item is not hidden, add it to the list - KConfig config("baloofileinformationrc", KConfig::NoGlobals); + KConfig config(QStringLiteral("baloofileinformationrc"), KConfig::NoGlobals); KConfigGroup settings = config.group("Show"); const QString label = m_provider->label(key); QListWidgetItem* item = new QListWidgetItem(label, m_metaDataList); item->setData(Qt::UserRole, key); const bool show = settings.readEntry(key, true); item->setCheckState(show ? Qt::Checked : Qt::Unchecked); } void FileMetaDataConfigWidget::Private::slotLoadingFinished() { // Get all meta information labels that are available for // the currently shown file item and add them to the list. Q_ASSERT(m_provider != nullptr); m_metaDataList->clear(); QVariantMap data = m_provider->data(); // Always show these 3 - data.remove("rating"); - data.remove("tags"); - data.remove("userComment"); + data.remove(QStringLiteral("rating")); + data.remove(QStringLiteral("tags")); + data.remove(QStringLiteral("userComment")); QVariantMap::const_iterator it = data.constBegin(); while (it != data.constEnd()) { addItem(it.key()); ++it; } - addItem("rating"); - addItem("tags"); - addItem("userComment"); + addItem(QStringLiteral("rating")); + addItem(QStringLiteral("tags")); + addItem(QStringLiteral("userComment")); } FileMetaDataConfigWidget::FileMetaDataConfigWidget(QWidget* parent) : QWidget(parent), d(new Private(this)) { } FileMetaDataConfigWidget::~FileMetaDataConfigWidget() { delete d; } void FileMetaDataConfigWidget::setItems(const KFileItemList& items) { d->m_fileItems = items; d->loadMetaData(); } KFileItemList FileMetaDataConfigWidget::items() const { return d->m_fileItems; } void FileMetaDataConfigWidget::save() { - KConfig config("baloofileinformationrc", KConfig::NoGlobals); + KConfig config(QStringLiteral("baloofileinformationrc"), KConfig::NoGlobals); KConfigGroup showGroup = config.group("Show"); const int count = d->m_metaDataList->count(); for (int i = 0; i < count; ++i) { QListWidgetItem* item = d->m_metaDataList->item(i); const bool show = (item->checkState() == Qt::Checked); const QString key = item->data(Qt::UserRole).toString(); showGroup.writeEntry(key, show); } showGroup.sync(); } bool FileMetaDataConfigWidget::event(QEvent* event) { if (event->type() == QEvent::Polish) { qDebug() << "GOT POLISH EVENT!!!"; // loadMetaData() must be invoked asynchronously, as the list // must finish it's initialization first QMetaObject::invokeMethod(this, "loadMetaData", Qt::QueuedConnection); } return QWidget::event(event);; } QSize FileMetaDataConfigWidget::sizeHint() const { return d->m_metaDataList->sizeHint(); } #include "moc_filemetadataconfigwidget.cpp" diff --git a/src/filemetadataprovider.cpp b/src/filemetadataprovider.cpp index acc5be9..9629467 100644 --- a/src/filemetadataprovider.cpp +++ b/src/filemetadataprovider.cpp @@ -1,541 +1,525 @@ /***************************************************************************** * Copyright (C) 2010 by Peter Penz * * Copyright (C) 2012 by Vishesh Handa * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * 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 * * Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public License * * along with this library; see the file COPYING.LIB. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * *****************************************************************************/ #include "filemetadataprovider.h" #include "indexeddataretriever.h" #include "filefetchjob.h" #include #include #include #include #include // Required includes for subDirectoriesCount(): #ifdef Q_OS_WIN #include #else #include #include #endif using namespace Baloo; namespace { QVariant intersect(const QVariant& v1, const QVariant& v2) { if (!v1.isValid() || !v2.isValid()) { return QVariant(); } // List and String if (v1.type() == QVariant::StringList && v2.type() == QVariant::String) { QStringList list = v1.toStringList(); QString str = v2.toString(); if (!list.contains(str)) { list << str; } return QVariant(list); } // String and List if (v1.type() == QVariant::String && v2.type() == QVariant::StringList) { QStringList list = v2.toStringList(); QString str = v1.toString(); if (!list.contains(str)) { list << str; } return QVariant(list); } // List and List if (v1.type() == QVariant::StringList && v2.type() == QVariant::StringList) { QSet s1 = v1.toStringList().toSet(); QSet s2 = v2.toStringList().toSet(); return QVariant(s1.intersect(s2).toList()); } if (v1 == v2) { return v1; } return QVariant(); } /** * The standard QMap::unite will contain the key multiple times if both \p v1 and \p v2 * contain the same key. * * This will only take the key from \p v2 into account */ QVariantMap unite(const QVariantMap& v1, const QVariantMap& v2) { QVariantMap v(v1); QMapIterator it(v2); while (it.hasNext()) { it.next(); v[it.key()] = it.value(); } return v; } } // anonymous namespace void FileMetaDataProvider::totalPropertyAndInsert(const QString& prop, const QList& resources, QSet& allProperties) { if (allProperties.contains(prop)) { int total = 0; foreach (const QVariantMap& map, resources) { QVariantMap::const_iterator it = map.constFind(prop); if (it == map.constEnd()) { total = 0; break; } else { total += it.value().toInt(); } } if (total) { m_data.insert (prop, QVariant(total)); } allProperties.remove(prop); } } void FileMetaDataProvider::slotFileFetchFinished(KJob* job) { FileFetchJob* fetchJob = static_cast(job); QList files = fetchJob->data(); Q_ASSERT(!files.isEmpty()); if (files.size() > 1) { insertCommonData(files); } else { m_data = files.first(); insertSingleFileBasicData(); } m_readOnly = !fetchJob->canEditAll(); insertEditableData(); emit loadingFinished(); } void FileMetaDataProvider::slotLoadingFinished(KJob* job) { IndexedDataRetriever* ret = dynamic_cast(job); m_data = unite(m_data, ret->data()); m_readOnly = !ret->canEdit(); emit loadingFinished(); } void FileMetaDataProvider::insertSingleFileBasicData() { // TODO: Handle case if remote URLs are used properly. isDir() does // not work, the modification date needs also to be adjusted... Q_ASSERT(m_fileItems.count() <= 1); if (m_fileItems.count() == 1) { const KFileItem& item = m_fileItems.first(); if (item.isDir()) { const int count = subDirectoriesCount(item.url().path()); if (count == -1) { - m_data.insert("kfileitem#size", i18nc("unknown file size", "Unknown")); + m_data.insert(QStringLiteral("kfileitem#size"), i18nc("unknown file size", "Unknown")); } else { const QString itemCountString = i18ncp("@item:intable", "%1 item", "%1 items", count); - m_data.insert("kfileitem#size", itemCountString); + m_data.insert(QStringLiteral("kfileitem#size"), itemCountString); } } else { KFormat format; - m_data.insert("kfileitem#size", format.formatByteSize(item.size())); + m_data.insert(QStringLiteral("kfileitem#size"), format.formatByteSize(item.size())); } - m_data.insert("kfileitem#type", item.mimeComment()); - m_data.insert("kfileitem#modified", item.time(KFileItem::ModificationTime)); + m_data.insert(QStringLiteral("kfileitem#type"), item.mimeComment()); + m_data.insert(QStringLiteral("kfileitem#modified"), item.time(KFileItem::ModificationTime)); QDateTime creationTime = item.time(KFileItem::CreationTime); if (creationTime.isValid()) { - m_data.insert("kfileitem#created", creationTime); + m_data.insert(QStringLiteral("kfileitem#created"), creationTime); } - m_data.insert("kfileitem#accessed", item.time(KFileItem::AccessTime)); - m_data.insert("kfileitem#owner", item.user()); - m_data.insert("kfileitem#group", item.group()); - m_data.insert("kfileitem#permissions", item.permissionsString()); + m_data.insert(QStringLiteral("kfileitem#accessed"), item.time(KFileItem::AccessTime)); + m_data.insert(QStringLiteral("kfileitem#owner"), item.user()); + m_data.insert(QStringLiteral("kfileitem#group"), item.group()); + m_data.insert(QStringLiteral("kfileitem#permissions"), item.permissionsString()); } } void FileMetaDataProvider::insertFilesListBasicData() { // If all directories Q_ASSERT(m_fileItems.count() > 1); bool allDirectories = true; for (const KFileItem& item : qAsConst(m_fileItems)) { allDirectories &= item.isDir(); if (!allDirectories) { break; } } if (allDirectories) { int count = 0; for (const KFileItem& item : qAsConst(m_fileItems)) { count += subDirectoriesCount(item.url().path()); } const QString itemCountString = i18ncp("@item:intable", "%1 item", "%1 items", count); - m_data.insert("kfileitem#totalSize", itemCountString); + m_data.insert(QStringLiteral("kfileitem#totalSize"), itemCountString); } else { // Calculate the size of all items quint64 totalSize = 0; for (const KFileItem& item : qAsConst(m_fileItems)) { if (!item.isDir() && !item.isLink()) { totalSize += item.size(); } } KFormat format; - m_data.insert("kfileitem#totalSize", format.formatByteSize(totalSize)); + m_data.insert(QStringLiteral("kfileitem#totalSize"), format.formatByteSize(totalSize)); } } void FileMetaDataProvider::insertEditableData() { if (!m_readOnly) { - if (!m_data.contains("tags")) { - m_data.insert("tags", QVariant()); + if (!m_data.contains(QStringLiteral("tags"))) { + m_data.insert(QStringLiteral("tags"), QVariant()); } - if (!m_data.contains("rating")) { - m_data.insert("rating", 0); + if (!m_data.contains(QStringLiteral("rating"))) { + m_data.insert(QStringLiteral("rating"), 0); } - if (!m_data.contains("userComment")) { - m_data.insert("userComment", QVariant()); + if (!m_data.contains(QStringLiteral("userComment"))) { + m_data.insert(QStringLiteral("userComment"), QVariant()); } } } void FileMetaDataProvider::insertCommonData(const QList& files) { // // Only report the stuff that is common to all the files // QSet allProperties; QList propertyList; foreach (const QVariantMap& fileData, files) { propertyList << fileData; allProperties.unite(fileData.uniqueKeys().toSet()); } // Special handling for certain properties - totalPropertyAndInsert("duration", propertyList, allProperties); - totalPropertyAndInsert("characterCount", propertyList, allProperties); - totalPropertyAndInsert("wordCount", propertyList, allProperties); - totalPropertyAndInsert("lineCount", propertyList, allProperties); + totalPropertyAndInsert(QStringLiteral("duration"), propertyList, allProperties); + totalPropertyAndInsert(QStringLiteral("characterCount"), propertyList, allProperties); + totalPropertyAndInsert(QStringLiteral("wordCount"), propertyList, allProperties); + totalPropertyAndInsert(QStringLiteral("lineCount"), propertyList, allProperties); foreach (const QString& propUri, allProperties) { foreach (const QVariantMap& map, propertyList) { QVariantMap::const_iterator it = map.find(propUri); if (it == map.constEnd()) { m_data.remove(propUri); break; } QVariantMap::iterator dit = m_data.find(it.key()); if (dit == m_data.end()) { m_data.insert(propUri, it.value()); } else { QVariant finalValue = intersect(it.value(), dit.value()); if (finalValue.isValid()) { m_data[propUri] = finalValue; } else { m_data.remove(propUri); break; } } } } } FileMetaDataProvider::FileMetaDataProvider(QObject* parent) : QObject(parent) , m_readOnly(false) , m_realTimeIndexing(false) { } FileMetaDataProvider::~FileMetaDataProvider() { } void FileMetaDataProvider::setFileItem() { // There are 3 code paths - // Remote file // Single local file - // * Not Indexed // * Indexed // const QUrl url = m_fileItems.first().targetUrl(); if (!url.isLocalFile()) { // FIXME - are extended attributes supported for remote files? m_readOnly = true; insertSingleFileBasicData(); emit loadingFinished(); return; } // Not indexed or only basic file indexing (no content) const QString filePath = url.toLocalFile(); if (!m_config.fileIndexingEnabled() || !m_config.shouldBeIndexed(filePath) || m_config.onlyBasicIndexing()) { m_realTimeIndexing = true; insertSingleFileBasicData(); insertEditableData(); IndexedDataRetriever *ret = new IndexedDataRetriever(filePath, this); connect(ret, &IndexedDataRetriever::finished, this, &FileMetaDataProvider::slotLoadingFinished); ret->start(); // Fully indexed by Baloo } else { FileFetchJob* job = new FileFetchJob(QStringList{filePath}, true, this); connect(job, &FileFetchJob::finished, this, &FileMetaDataProvider::slotFileFetchFinished); job->start(); } } void FileMetaDataProvider::setFileItems() { // Multiple Files - // * Not Indexed // * Indexed QStringList urls; urls.reserve(m_fileItems.size()); // Only extract data from indexed files, // it would be too expensive otherwise. for (const KFileItem& item : qAsConst(m_fileItems)) { const QUrl url = item.targetUrl(); if (url.isLocalFile()) { urls << url.toLocalFile(); } } insertFilesListBasicData(); if (!urls.isEmpty()) { // Editing only if all URLs are local bool canEdit = (urls.size() == m_fileItems.size()); FileFetchJob* job = new FileFetchJob(urls, canEdit, this); connect(job, &FileFetchJob::finished, this, &FileMetaDataProvider::slotFileFetchFinished); job->start(); } else { // FIXME - are extended attributes supported for remote files? m_readOnly = true; emit loadingFinished(); } } void FileMetaDataProvider::setItems(const KFileItemList& items) { m_fileItems = items; m_data.clear(); m_realTimeIndexing = false; if (items.isEmpty()) { emit loadingFinished(); } else if (items.size() == 1) { setFileItem(); } else { setFileItems(); } } QString FileMetaDataProvider::label(const QString& metaDataLabel) const { - struct TranslationItem { - const char* const key; - const char* const context; - const char* const value; + static QHash hash = { + { QStringLiteral("kfileitem#comment"), i18nc("@label", "Comment") }, + { QStringLiteral("kfileitem#created"), i18nc("@label", "Created") }, + { QStringLiteral("kfileitem#accessed"), i18nc("@label", "Accessed") }, + { QStringLiteral("kfileitem#modified"), i18nc("@label", "Modified") }, + { QStringLiteral("kfileitem#owner"), i18nc("@label", "Owner") }, + { QStringLiteral("kfileitem#group"), i18nc("@label", "Group") }, + { QStringLiteral("kfileitem#permissions"), i18nc("@label", "Permissions") }, + { QStringLiteral("kfileitem#rating"), i18nc("@label", "Rating") }, + { QStringLiteral("kfileitem#size"), i18nc("@label", "Size") }, + { QStringLiteral("kfileitem#tags"), i18nc("@label", "Tags") }, + { QStringLiteral("kfileitem#totalSize"), i18nc("@label", "Total Size") }, + { QStringLiteral("kfileitem#type"), i18nc("@label", "Type") }, + { QStringLiteral("tags"), i18nc("@label", "Tags") }, + { QStringLiteral("rating"), i18nc("@label", "Rating") }, + { QStringLiteral("userComment"), i18nc("@label", "Comment") }, + { QStringLiteral("originUrl"), i18nc("@label", "Downloaded From") }, }; - static const TranslationItem translations[] = { - { "kfileitem#comment", I18N_NOOP2_NOSTRIP("@label", "Comment") }, - { "kfileitem#created", I18N_NOOP2_NOSTRIP("@label", "Created") }, - { "kfileitem#accessed", I18N_NOOP2_NOSTRIP("@label", "Accessed") }, - { "kfileitem#modified", I18N_NOOP2_NOSTRIP("@label", "Modified") }, - { "kfileitem#owner", I18N_NOOP2_NOSTRIP("@label", "Owner") }, - { "kfileitem#group", I18N_NOOP2_NOSTRIP("@label", "Group") }, - { "kfileitem#permissions", I18N_NOOP2_NOSTRIP("@label", "Permissions") }, - { "kfileitem#rating", I18N_NOOP2_NOSTRIP("@label", "Rating") }, - { "kfileitem#size", I18N_NOOP2_NOSTRIP("@label", "Size") }, - { "kfileitem#tags", I18N_NOOP2_NOSTRIP("@label", "Tags") }, - { "kfileitem#totalSize", I18N_NOOP2_NOSTRIP("@label", "Total Size") }, - { "kfileitem#type", I18N_NOOP2_NOSTRIP("@label", "Type") }, - { "tags", I18N_NOOP2_NOSTRIP("@label", "Tags") }, - { "rating", I18N_NOOP2_NOSTRIP("@label", "Rating") }, - { "userComment", I18N_NOOP2_NOSTRIP("@label", "Comment") }, - { "originUrl", I18N_NOOP2_NOSTRIP("@label", "Downloaded From") }, - { nullptr, nullptr, nullptr} // Mandatory last entry - }; - - static QHash hash; - if (hash.isEmpty()) { - const TranslationItem* item = &translations[0]; - while (item->key != nullptr) { - hash.insert(item->key, i18nc(item->context, item->value)); - ++item; - } - } - QString value = hash.value(metaDataLabel); if (value.isEmpty()) { value = KFileMetaData::PropertyInfo::fromName(metaDataLabel).displayName(); } return value; } QString FileMetaDataProvider::group(const QString& label) const { - static QHash uriGrouper; - if (uriGrouper.isEmpty()) { + static QHash uriGrouper = { + // KFileItem Data - uriGrouper.insert(QLatin1String("kfileitem#type"), QLatin1String("0FileItemA")); - uriGrouper.insert(QLatin1String("kfileitem#size"), QLatin1String("0FileItemB")); - uriGrouper.insert(QLatin1String("kfileitem#totalSize"), QLatin1String("0FileItemB")); - uriGrouper.insert(QLatin1String("kfileitem#modified"), QLatin1String("0FileItemC")); - uriGrouper.insert(QLatin1String("kfileitem#accessed"), QLatin1String("0FileItemD")); - uriGrouper.insert(QLatin1String("kfileitem#created"), QLatin1String("0FileItemE")); - uriGrouper.insert(QLatin1String("kfileitem#owner"), QLatin1String("0FileItemF")); - uriGrouper.insert(QLatin1String("kfileitem#group"), QLatin1String("0FileItemG")); - uriGrouper.insert(QLatin1String("kfileitem#permissions"), QLatin1String("0FileItemH")); + { QStringLiteral("kfileitem#type"), QStringLiteral("0FileItemA") }, + { QStringLiteral("kfileitem#size"), QStringLiteral("0FileItemB") }, + { QStringLiteral("kfileitem#totalSize"), QStringLiteral("0FileItemB") }, + { QStringLiteral("kfileitem#modified"), QStringLiteral("0FileItemC") }, + { QStringLiteral("kfileitem#accessed"), QStringLiteral("0FileItemD") }, + { QStringLiteral("kfileitem#created"), QStringLiteral("0FileItemE") }, + { QStringLiteral("kfileitem#owner"), QStringLiteral("0FileItemF") }, + { QStringLiteral("kfileitem#group"), QStringLiteral("0FileItemG") }, + { QStringLiteral("kfileitem#permissions"), QStringLiteral("0FileItemH") }, // Editable Data - uriGrouper.insert(QLatin1String("tags"), QLatin1String("1EditableDataA")); - uriGrouper.insert(QLatin1String("rating"), QLatin1String("1EditableDataB")); - uriGrouper.insert(QLatin1String("userComment"), QLatin1String("1EditableDataC")); + { QStringLiteral("tags"), QStringLiteral("1EditableDataA") }, + { QStringLiteral("rating"), QStringLiteral("1EditableDataB") }, + { QStringLiteral("userComment"), QStringLiteral("1EditableDataC") }, // Image Data - uriGrouper.insert(QLatin1String("width"), QLatin1String("2ImageA")); - uriGrouper.insert(QLatin1String("height"), QLatin1String("2ImageB")); - uriGrouper.insert(QLatin1String("photoFNumber"), QLatin1String("2ImageC")); - uriGrouper.insert(QLatin1String("photoExposureTime"), QLatin1String("2ImageD")); - uriGrouper.insert(QLatin1String("photoExposureBiasValue"), QLatin1String("2ImageE")); - uriGrouper.insert(QLatin1String("photoISOSpeedRatings"), QLatin1String("2ImageF")); - uriGrouper.insert(QLatin1String("photoFocalLength"), QLatin1String("2ImageG")); - uriGrouper.insert(QLatin1String("photoFocalLengthIn35mmFilm"), QLatin1String("2ImageH")); - uriGrouper.insert(QLatin1String("photoFlash"), QLatin1String("2ImageI")); - uriGrouper.insert(QLatin1String("imageOrientation"), QLatin1String("2ImageJ")); - uriGrouper.insert(QLatin1String("photoGpsLatitude"), QLatin1String("2ImageK")); - uriGrouper.insert(QLatin1String("photoGpsLongitude"), QLatin1String("2ImageL")); - uriGrouper.insert(QLatin1String("photoGpsAltitude"), QLatin1String("2ImageM")); - uriGrouper.insert(QLatin1String("manufacturer"), QLatin1String("2ImageN")); - uriGrouper.insert(QLatin1String("model"), QLatin1String("2ImageO")); + { QStringLiteral("width"), QStringLiteral("2ImageA") }, + { QStringLiteral("height"), QStringLiteral("2ImageB") }, + { QStringLiteral("photoFNumber"), QStringLiteral("2ImageC") }, + { QStringLiteral("photoExposureTime"), QStringLiteral("2ImageD") }, + { QStringLiteral("photoExposureBiasValue"), QStringLiteral("2ImageE") }, + { QStringLiteral("photoISOSpeedRatings"), QStringLiteral("2ImageF") }, + { QStringLiteral("photoFocalLength"), QStringLiteral("2ImageG") }, + { QStringLiteral("photoFocalLengthIn35mmFilm"), QStringLiteral("2ImageH") }, + { QStringLiteral("photoFlash"), QStringLiteral("2ImageI") }, + { QStringLiteral("imageOrientation"), QStringLiteral("2ImageJ") }, + { QStringLiteral("photoGpsLatitude"), QStringLiteral("2ImageK") }, + { QStringLiteral("photoGpsLongitude"), QStringLiteral("2ImageL") }, + { QStringLiteral("photoGpsAltitude"), QStringLiteral("2ImageM") }, + { QStringLiteral("manufacturer"), QStringLiteral("2ImageN") }, + { QStringLiteral("model"), QStringLiteral("2ImageO") }, // Media Data - uriGrouper.insert("title", QLatin1String("3MediaA")); - uriGrouper.insert("artist", QLatin1String("3MediaB")); - uriGrouper.insert("album", QLatin1String("3MediaC")); - uriGrouper.insert("albumArtist", QLatin1String("3MediaD")); - uriGrouper.insert("genre", QLatin1String("3MediaE")); - uriGrouper.insert("trackNumber", QLatin1String("3MediaF")); - uriGrouper.insert("discNumber", QLatin1String("3MediaG")); - uriGrouper.insert("releaseYear", QLatin1String("3MediaH")); - uriGrouper.insert("duration", QLatin1String("3MediaI")); - uriGrouper.insert("sampleRate", QLatin1String("3MediaJ")); - uriGrouper.insert("bitRate", QLatin1String("3MediaK")); + { QStringLiteral("title"), QStringLiteral("3MediaA") }, + { QStringLiteral("artist"), QStringLiteral("3MediaB") }, + { QStringLiteral("album"), QStringLiteral("3MediaC") }, + { QStringLiteral("albumArtist"), QStringLiteral("3MediaD") }, + { QStringLiteral("genre"), QStringLiteral("3MediaE") }, + { QStringLiteral("trackNumber"), QStringLiteral("3MediaF") }, + { QStringLiteral("discNumber"), QStringLiteral("3MediaG") }, + { QStringLiteral("releaseYear"), QStringLiteral("3MediaH") }, + { QStringLiteral("duration"), QStringLiteral("3MediaI") }, + { QStringLiteral("sampleRate"), QStringLiteral("3MediaJ") }, + { QStringLiteral("bitRate"), QStringLiteral("3MediaK") }, // Miscellaneous Data - uriGrouper.insert("originUrl", QLatin1String("4MiscA")); - } + { QStringLiteral("originUrl"), QStringLiteral("4MiscA") }, + }; const QString val = uriGrouper.value(label); if (val.isEmpty()) { - return "lastGroup"; + return QStringLiteral("lastGroup"); } return val; } KFileItemList FileMetaDataProvider::items() const { return m_fileItems; } void FileMetaDataProvider::setReadOnly(bool readOnly) { m_readOnly = readOnly; } bool FileMetaDataProvider::isReadOnly() const { return m_readOnly; } QVariantMap FileMetaDataProvider::data() const { return m_data; } int FileMetaDataProvider::subDirectoriesCount(const QString& path) { #ifdef Q_OS_WIN QDir dir(path); return dir.entryList(QDir::AllEntries|QDir::NoDotAndDotDot|QDir::System).count(); #else // Taken from kdelibs/kio/kio/kdirmodel.cpp // Copyright (C) 2006 David Faure int count = -1; DIR* dir = ::opendir(QFile::encodeName(path)); if (dir) { count = 0; struct dirent *dirEntry = nullptr; while ((dirEntry = ::readdir(dir))) { // krazy:exclude=syscalls if (dirEntry->d_name[0] == '.') { if (dirEntry->d_name[1] == '\0') { // Skip "." continue; } if (dirEntry->d_name[1] == '.' && dirEntry->d_name[2] == '\0') { // Skip ".." continue; } } ++count; } ::closedir(dir); } return count; #endif } bool FileMetaDataProvider::realTimeIndexing() { return m_realTimeIndexing; } diff --git a/src/filemetadatawidget.cpp b/src/filemetadatawidget.cpp index eb53ec6..1885ba7 100644 --- a/src/filemetadatawidget.cpp +++ b/src/filemetadatawidget.cpp @@ -1,391 +1,391 @@ /* Copyright (C) 2012-2013 Vishesh Handa Adapted from KFileMetadataWidget Copyright (C) 2008 by Sebastian Trueg Copyright (C) 2009-2010 by Peter Penz 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) any later version. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "filemetadatawidget.h" #include "metadatafilter.h" #include "widgetfactory.h" #include "filemetadataprovider.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Baloo; class Baloo::FileMetaDataWidget::Private { public: struct Row { QCheckBox* checkBox; QLabel* label; QWidget* value; }; Private(FileMetaDataWidget* parent); ~Private(); void deleteRows(); void slotLoadingFinished(); void slotLinkActivated(const QString& link); void slotDataChangeStarted(); void slotDataChangeFinished(); QStringList sortedKeys(const QVariantMap& data) const; QLabel* createLabel(const QString &key, const QString& itemLabel, FileMetaDataWidget* parent); void saveConfig(); QList m_rows; FileMetaDataProvider* m_provider; QGridLayout* m_gridLayout; MetadataFilter* m_filter; WidgetFactory* m_widgetFactory; QMap m_visibilityChanged; bool m_configureVisibleProperties = false; private: FileMetaDataWidget* const q; }; FileMetaDataWidget::Private::Private(FileMetaDataWidget* parent) : m_rows() , m_provider(nullptr) , m_gridLayout(nullptr) , q(parent) { m_filter = new MetadataFilter(q); m_widgetFactory = new WidgetFactory(q); connect(m_widgetFactory, &WidgetFactory::urlActivated, q, &FileMetaDataWidget::urlActivated); // TODO: If KFileMetaDataProvider might get a public class in future KDE releases, // the following code should be moved into KFileMetaDataWidget::setModel(): m_provider = new FileMetaDataProvider(q); connect(m_provider, &FileMetaDataProvider::loadingFinished, q, [this](){ slotLoadingFinished(); }); } FileMetaDataWidget::Private::~Private() { } void FileMetaDataWidget::Private::deleteRows() { foreach (const Row& row, m_rows) { delete row.label; row.value->deleteLater(); if (row.checkBox) { row.checkBox->deleteLater(); } } m_rows.clear(); } QLabel* FileMetaDataWidget::Private::createLabel(const QString &key, const QString& itemLabel, FileMetaDataWidget* parent) { QLabel* label = new QLabel(itemLabel + QLatin1Char(':'), parent); label->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); label->setForegroundRole(parent->foregroundRole()); label->setFont(parent->font()); label->setWordWrap(true); label->setAlignment(Qt::AlignTop | Qt::AlignRight); label->setObjectName(QStringLiteral("L_%1").arg(key)); return label; } void FileMetaDataWidget::Private::slotLoadingFinished() { deleteRows(); if (m_gridLayout == nullptr) { m_gridLayout = new QGridLayout(q); m_gridLayout->setContentsMargins(0, 0, 0, 0); m_gridLayout->setSpacing(q->fontMetrics().height() / 4); } QVariantMap data = m_provider->data(); QStringList active; if (m_configureVisibleProperties) { active = m_filter->filter(data).keys(); auto changedIt = m_visibilityChanged.constBegin(); while (changedIt != m_visibilityChanged.constEnd()) { if (changedIt.value()) { active.append(changedIt.key()); } else { active.removeAll(changedIt.key()); } changedIt++; } m_widgetFactory->setNoLinks(true); m_widgetFactory->setReadOnly(true); m_gridLayout->setColumnStretch(0, 1); m_gridLayout->setColumnStretch(1, 3); m_gridLayout->setColumnStretch(2, 0); m_gridLayout->setColumnStretch(3, 6); } else { data = m_filter->filter(data); m_widgetFactory->setNoLinks( m_provider->realTimeIndexing() ); m_widgetFactory->setReadOnly(m_provider->isReadOnly()); m_gridLayout->setColumnStretch(0, 4); m_gridLayout->setColumnStretch(1, 0); m_gridLayout->setColumnStretch(2, 6); m_gridLayout->setColumnStretch(3, 0); } int rowIndex = 0; // Iterate through all remaining items. // Embed the label and the value as new row in the widget const QStringList keys = sortedKeys(data); - const int spacerWidth = QFontMetrics(q->font()).size(Qt::TextSingleLine, " ").width(); + const int spacerWidth = QFontMetrics(q->font()).size(Qt::TextSingleLine, QStringLiteral(" ")).width(); const int labelColumn = m_configureVisibleProperties ? 1 : 0; for (const auto& key : keys) { Row row; if (m_configureVisibleProperties) { row.checkBox = new QCheckBox(q); if (active.contains(key)) { row.checkBox->setChecked(true); } m_gridLayout->addWidget(row.checkBox, rowIndex, 0, Qt::AlignTop | Qt::AlignRight); connect(row.checkBox, &QCheckBox::stateChanged, q, [this, key](int state) { this->m_visibilityChanged[key] = (state == Qt::Checked); }); } else { row.checkBox = nullptr; } row.label = createLabel(key, m_provider->label(key), q); m_gridLayout->addWidget(row.label, rowIndex, labelColumn + 0, Qt::AlignRight); m_gridLayout->addItem(new QSpacerItem(spacerWidth, 1), rowIndex, labelColumn + 1); row.value = m_widgetFactory->createWidget(key, data[key], q); m_gridLayout->addWidget(row.value, rowIndex, labelColumn + 2, Qt::AlignLeft); m_gridLayout->setRowStretch(rowIndex, 0); // Remember the label and value-widget as row m_rows.append(row); ++rowIndex; } // Add vertical stretch - when the widget is embedded with extra vertical // space, it should be added at the bottom, not distributed between the // items. m_gridLayout->addItem(new QSpacerItem(0, 0), rowIndex, 0, 1, -1); m_gridLayout->setRowStretch(rowIndex, 1); q->updateGeometry(); emit q->metaDataRequestFinished(m_provider->items()); } void FileMetaDataWidget::Private::slotLinkActivated(const QString& link) { const QUrl url = QUrl::fromUserInput(link); if (url.isValid()) { emit q->urlActivated(url); } } void FileMetaDataWidget::Private::slotDataChangeStarted() { q->setEnabled(false); } void FileMetaDataWidget::Private::slotDataChangeFinished() { q->setEnabled(true); } QStringList FileMetaDataWidget::Private::sortedKeys(const QVariantMap& data) const { // Create a map, where the translated label prefixed with the // sort priority acts as key. The data of each entry is the URI // of the data. By this the all URIs are sorted by the sort priority // and sub sorted by the translated labels. QMap map; QVariantMap::const_iterator hashIt = data.constBegin(); while (hashIt != data.constEnd()) { const QString propName = hashIt.key(); QString key = m_provider->group(propName); key += m_provider->label(propName); map.insertMulti(key, propName); ++hashIt; } // Apply the URIs from the map to the list that will get returned. // The list will then be alphabetically ordered by the translated labels of the URIs. QStringList list; QMap::const_iterator mapIt = map.constBegin(); while (mapIt != map.constEnd()) { list.append(mapIt.value()); ++mapIt; } return list; } void FileMetaDataWidget::Private::saveConfig() { if (m_visibilityChanged.isEmpty()) { return; } - KConfig config("baloofileinformationrc", KConfig::NoGlobals); + KConfig config(QStringLiteral("baloofileinformationrc"), KConfig::NoGlobals); KConfigGroup showGroup = config.group("Show"); auto changedIt = m_visibilityChanged.constBegin(); while (changedIt != m_visibilityChanged.constEnd()) { showGroup.writeEntry(changedIt.key(), changedIt.value()); changedIt++; } showGroup.sync(); } FileMetaDataWidget::FileMetaDataWidget(QWidget* parent) : QWidget(parent) , d(new Private(this)) { } FileMetaDataWidget::~FileMetaDataWidget() { delete d; } void FileMetaDataWidget::setItems(const KFileItemList& items) { d->m_provider->setItems(items); d->m_widgetFactory->setItems(items); } KFileItemList FileMetaDataWidget::items() const { return d->m_provider->items(); } void FileMetaDataWidget::setReadOnly(bool readOnly) { d->m_provider->setReadOnly(readOnly); d->m_widgetFactory->setReadOnly(readOnly); } bool FileMetaDataWidget::isReadOnly() const { return d->m_provider->isReadOnly(); } void FileMetaDataWidget::setDateFormat(const DateFormats format) { d->m_widgetFactory->setDateFormat(format); } DateFormats FileMetaDataWidget::dateFormat() const { return d->m_widgetFactory->dateFormat(); } QSize FileMetaDataWidget::sizeHint() const { if (d->m_gridLayout == nullptr) { return QWidget::sizeHint(); } // Calculate the required width for the labels and values int leftWidthMax = 0; int rightWidthMax = 0; int rightWidthAverage = 0; foreach (const Private::Row& row, d->m_rows) { const QWidget* valueWidget = row.value; const int rightWidth = valueWidget->sizeHint().width(); rightWidthAverage += rightWidth; if (rightWidth > rightWidthMax) { rightWidthMax = rightWidth; } const int leftWidth = row.label->sizeHint().width(); if (leftWidth > leftWidthMax) { leftWidthMax = leftWidth; } } // Some value widgets might return a very huge width for the size hint. // Limit the maximum width to the double width of the overall average // to assure a less messed layout. if (d->m_rows.count() > 1) { rightWidthAverage /= d->m_rows.count(); if (rightWidthMax > rightWidthAverage * 2) { rightWidthMax = rightWidthAverage * 2; } } // Based on the available width calculate the required height int height = d->m_gridLayout->margin() * 2 + d->m_gridLayout->spacing() * (d->m_rows.count() - 1); foreach (const Private::Row& row, d->m_rows) { const QWidget* valueWidget = row.value; const int rowHeight = qMax(row.label->heightForWidth(leftWidthMax), valueWidget->heightForWidth(rightWidthMax)); height += rowHeight; } const int width = d->m_gridLayout->margin() * 2 + leftWidthMax + d->m_gridLayout->spacing() + rightWidthMax; return QSize(width, height); } void FileMetaDataWidget::setConfigurationMode(ConfigurationMode mode) { if (mode == ConfigurationMode::ReStart) { d->m_configureVisibleProperties = true; } else if (mode == ConfigurationMode::Accept) { d->saveConfig(); d->m_configureVisibleProperties = false; } else if (mode == ConfigurationMode::Cancel) { d->m_configureVisibleProperties = false; } d->m_visibilityChanged.clear(); d->slotLoadingFinished(); } #include "moc_filemetadatawidget.cpp" diff --git a/src/kcommentwidget.cpp b/src/kcommentwidget.cpp index 0733988..3a91959 100644 --- a/src/kcommentwidget.cpp +++ b/src/kcommentwidget.cpp @@ -1,142 +1,142 @@ /***************************************************************************** * Copyright (C) 2008 by Sebastian Trueg * * Copyright (C) 2009 by Peter Penz * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * 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 * * Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public License * * along with this library; see the file COPYING.LIB. If not, write to * * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301, USA. * *****************************************************************************/ #include "kcommentwidget_p.h" #include "keditcommentdialog.h" #include #include #include #include #include #include #include #include KCommentWidget::KCommentWidget(QWidget* parent) : QWidget(parent), m_readOnly(false), m_label(nullptr), m_sizeHintHelper(nullptr), m_comment() { m_label = new QLabel(this); m_label->setWordWrap(true); m_label->setAlignment(Qt::AlignTop); connect(m_label, &QLabel::linkActivated, this, &KCommentWidget::slotLinkActivated); m_sizeHintHelper = new QLabel(this); m_sizeHintHelper->hide(); QVBoxLayout* layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->addWidget(m_label); setText(m_comment); } KCommentWidget::~KCommentWidget() { } void KCommentWidget::setText(const QString& comment) { QString text; if (comment.isEmpty()) { if (m_readOnly) { - text = "-"; + text = QStringLiteral("-"); } else { - text = "" + i18nc("@label", "Add...") + ""; + text = QStringLiteral("") + i18nc("@label", "Add...") + QStringLiteral(""); } } else { if (m_readOnly) { - text = QString(comment).toHtmlEscaped(); + text = comment.toHtmlEscaped(); } else { - text = "

" + QString(comment).toHtmlEscaped() + " " + i18nc("@label", "Edit...") + "

"; + text = QStringLiteral("

") + comment.toHtmlEscaped() + QStringLiteral(" ") + i18nc("@label", "Edit...") + QStringLiteral("

"); } } m_label->setText(text); m_sizeHintHelper->setText(text); m_comment = comment; } QString KCommentWidget::text() const { return m_comment; } void KCommentWidget::setReadOnly(bool readOnly) { m_readOnly = readOnly; setText(m_comment); } bool KCommentWidget::isReadOnly() const { return m_readOnly; } QSize KCommentWidget::sizeHint() const { // Per default QLabel tries to provide a square size hint. This // does not work well for complex layouts that rely on a heightForWidth() // functionality with unclipped content. Use an unwrapped text label // as layout helper instead, that returns the preferred size of // the rich-text line. return m_sizeHintHelper->sizeHint(); } bool KCommentWidget::event(QEvent* event) { if (event->type() == QEvent::Polish) { m_label->setForegroundRole(foregroundRole()); } return QWidget::event(event); } void KCommentWidget::slotLinkActivated(const QString& link) { - const QString caption = (link == "editComment") ? + const QString caption = (link == QLatin1String("editComment")) ? i18nc("@title:window", "Edit Comment") : i18nc("@title:window", "Add Comment"); QPointer dialog = new KEditCommentDialog(this, m_comment, caption); KConfigGroup dialogConfig(KSharedConfig::openConfig(), "Baloo KEditCommentDialog"); KWindowConfig::restoreWindowSize(dialog->windowHandle(), dialogConfig); if (dialog->exec() == QDialog::Accepted) { const QString oldText = m_comment; if (dialog != nullptr) { setText(dialog->getCommentText()); } if (oldText != m_comment) { emit commentChanged(m_comment); } } if (dialog != nullptr) { KWindowConfig::saveWindowSize(dialog->windowHandle(), dialogConfig); delete dialog; dialog = nullptr; } } diff --git a/src/kedittagsdialog.cpp b/src/kedittagsdialog.cpp index 07c1b48..e9b5fe2 100644 --- a/src/kedittagsdialog.cpp +++ b/src/kedittagsdialog.cpp @@ -1,228 +1,228 @@ /***************************************************************************** * Copyright (C) 2009 by Peter Penz * * Copyright (C) 2014 by Vishesh Handa * * Copyright (C) 2017 by James D. Smith #include #include #include #include #include #include #include #include #include #include #include #include KEditTagsDialog::KEditTagsDialog(const QStringList& tags, QWidget *parent) : QDialog(parent), m_tags(tags), m_tagTree(nullptr), m_newTagEdit(nullptr) { const QString captionText = (tags.count() > 0) ? i18nc("@title:window", "Edit Tags") : i18nc("@title:window", "Add Tags"); setWindowTitle(captionText); QDialogButtonBox* buttonBox = new QDialogButtonBox(this); buttonBox->addButton(i18n("Save"), QDialogButtonBox::AcceptRole); buttonBox->addButton(QDialogButtonBox::Cancel); connect(buttonBox, &QDialogButtonBox::accepted, this, &KEditTagsDialog::slotAcceptedButtonClicked); connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject); QVBoxLayout* topLayout = new QVBoxLayout; setLayout(topLayout); QLabel* label = new QLabel(i18nc("@label:textbox", "Configure which tags should " "be applied."), this); m_tagTree = new QTreeWidget(); m_tagTree->setSortingEnabled(true); m_tagTree->setSelectionMode(QAbstractItemView::NoSelection); m_tagTree->setHeaderHidden(true); QLabel* newTagLabel = new QLabel(i18nc("@label", "Create new tag:")); m_newTagEdit = new QLineEdit(this); m_newTagEdit->setClearButtonEnabled(true); m_newTagEdit->setFocus(); connect(m_newTagEdit, &QLineEdit::textEdited, this, &KEditTagsDialog::slotTextEdited); connect(m_tagTree, &QTreeWidget::itemActivated, this, &KEditTagsDialog::slotItemActivated); QHBoxLayout* newTagLayout = new QHBoxLayout(); newTagLayout->addWidget(newTagLabel); newTagLayout->addWidget(m_newTagEdit, 1); topLayout->addWidget(label); topLayout->addWidget(m_tagTree); topLayout->addLayout(newTagLayout); topLayout->addWidget(buttonBox); resize(sizeHint()); Baloo::TagListJob* job = new Baloo::TagListJob(); connect(job, &Baloo::TagListJob::finished, [this] (KJob* job) { Baloo::TagListJob* tjob = static_cast(job); m_allTags = tjob->tags(); loadTagWidget(); }); job->start(); } KEditTagsDialog::~KEditTagsDialog() { } QStringList KEditTagsDialog::tags() const { return m_tags; } void KEditTagsDialog::slotAcceptedButtonClicked() { m_tags.clear(); for (const QTreeWidgetItem* item : m_allTagTreeItems.values()) { if (item->checkState(0) == Qt::Checked) { m_tags << qvariant_cast(item->data(0, Qt::UserRole)); } } accept(); } void KEditTagsDialog::slotItemActivated(const QTreeWidgetItem* item, int column) { Q_UNUSED(column) const QString tag = qvariant_cast(item->data(0, Qt::UserRole)); m_newTagEdit->setText(tag + QLatin1Char('/')); m_newTagEdit->setFocus(); } void KEditTagsDialog::slotTextEdited(const QString& text) { // Remove unnecessary spaces from a new tag is // mandatory, as the user cannot see the difference // between a tag "Test" and "Test ". QString tagText = text.simplified(); - while (tagText.endsWith("//")) { + while (tagText.endsWith(QLatin1String("//"))) { tagText.chop(1); m_newTagEdit->setText(tagText); return; } // Remove all tree items related to the previous new tag const QStringList splitTag = m_newTag.split(QLatin1Char('/'), QString::SkipEmptyParts); for (int i = splitTag.size() - 1; i >= 0 && i < splitTag.size(); --i) { QString itemTag = m_newTag.section(QLatin1Char('/'), 0, i, QString::SectionSkipEmpty); QTreeWidgetItem* item = m_allTagTreeItems.value(itemTag); if (!m_allTags.contains(m_newTag) && (item->childCount() == 0)) { if (i != 0) { QTreeWidgetItem* parentItem = item->parent(); parentItem->removeChild(item); } else { const int row = m_tagTree->indexOfTopLevelItem(item); m_tagTree->takeTopLevelItem(row); } m_allTagTreeItems.remove(itemTag); } if (!m_tags.contains(itemTag)) { item->setCheckState(0, Qt::Unchecked); } item->setExpanded(false); } if (!tagText.isEmpty()) { m_newTag = tagText; modifyTagWidget(tagText); m_tagTree->sortItems(0, Qt::SortOrder::AscendingOrder); } else { m_newTag.clear(); m_allTagTreeItems.clear(); m_tagTree->clear(); loadTagWidget(); } } void KEditTagsDialog::loadTagWidget() { for (const QString &tag : m_tags) { modifyTagWidget(tag); } for (const QString &tag : m_allTags) { modifyTagWidget(tag); } m_tagTree->sortItems(0, Qt::SortOrder::AscendingOrder); } void KEditTagsDialog::modifyTagWidget(const QString &tag) { const QStringList splitTag = tag.split(QLatin1Char('/'), QString::SkipEmptyParts); for (int i = 0; i < splitTag.size(); ++i) { QTreeWidgetItem* item = new QTreeWidgetItem(); QString itemTag = tag.section(QLatin1Char('/'), 0, i, QString::SectionSkipEmpty); if (!m_allTagTreeItems.contains(itemTag)) { item->setText(0, splitTag.at(i)); item->setIcon(0, QIcon::fromTheme(QLatin1String("tag"))); item->setData(0, Qt::UserRole, itemTag); m_allTagTreeItems.insert(itemTag, item); QString parentTag = tag.section(QLatin1Char('/'), 0, (i - 1), QString::SectionSkipEmpty); QTreeWidgetItem* parentItem = m_allTagTreeItems.value(parentTag); if (i != 0) { parentItem->addChild(item); } else { m_tagTree->addTopLevelItem(item); } } else { item = m_allTagTreeItems.value(itemTag); } if (!m_allTags.contains(tag)) { m_tagTree->scrollToItem(item, QAbstractItemView::PositionAtCenter); } if (((item->childCount() != 0) && m_tags.contains(tag)) || (m_newTag == tag)) { item->setExpanded(true); } else if (item->parent() && m_tags.contains(tag)) { item->parent()->setExpanded(true); } const bool check = (m_tags.contains(itemTag) || (m_newTag == itemTag)); item->setCheckState(0, check ? Qt::Checked : Qt::Unchecked); } } diff --git a/src/metadatafilter.cpp b/src/metadatafilter.cpp index 11dca63..5b54d0c 100644 --- a/src/metadatafilter.cpp +++ b/src/metadatafilter.cpp @@ -1,117 +1,117 @@ /* Copyright (C) 2012 Vishesh Handa Adapted from KFileMetadataWidget Copyright (C) 2008 by Sebastian Trueg Copyright (C) 2009-2010 by Peter Penz 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) any later version. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "metadatafilter.h" #include #include using namespace Baloo; MetadataFilter::MetadataFilter(QObject* parent): QObject(parent) { initMetaInformationSettings(); } MetadataFilter::~MetadataFilter() { } void MetadataFilter::initMetaInformationSettings() { const int currentVersion = 11; // increase version, if the blacklist of disabled // properties should be updated - KConfig config("baloofileinformationrc", KConfig::NoGlobals); + KConfig config(QStringLiteral("baloofileinformationrc"), KConfig::NoGlobals); if (config.group("Misc").readEntry("version", 0) < currentVersion) { // The resource file is read the first time. Assure // that some meta information is disabled per default. // clear old info config.deleteGroup("Show"); KConfigGroup settings = config.group("Show"); static const char* const disabledProperties[] = { "comment", "contentSize", "depends", "lastModified", "created", "contentCreated", "mimeType", "url", "channels", "fileName", "fileSize", "kfileitem#owner", "kfileitem#group", "kfileitem#permissions", "replayGainAlbumPeak", "replayGainAlbumGain", "replayGainTrackPeak", "replayGainTrackGain", "embeddedRating", "lyrics", "photoWhiteBalance", "photoMeteringMode", "photoSharpness", "photoSaturation", "photoPixelXDimension", "photoPixelYDimension", }; for (const auto property : disabledProperties) { settings.writeEntry(property, false); } // mark the group as initialized config.group("Misc").writeEntry("version", currentVersion); } } QVariantMap MetadataFilter::filter(const QVariantMap& data) { if( data.isEmpty() ) return data; QVariantMap finalData(data); // // Remove all items, that are marked as hidden in kmetainformationrc - KConfig config("baloofileinformationrc", KConfig::NoGlobals); + KConfig config(QStringLiteral("baloofileinformationrc"), KConfig::NoGlobals); KConfigGroup settings = config.group("Show"); QVariantMap::iterator it = finalData.begin(); while (it != finalData.end()) { const QString uriString = it.key(); if (!settings.readEntry(uriString, true)) { it = finalData.erase(it); } else { ++it; } } return finalData; } diff --git a/src/tagcheckbox.cpp b/src/tagcheckbox.cpp index fa92f64..6c4c891 100644 --- a/src/tagcheckbox.cpp +++ b/src/tagcheckbox.cpp @@ -1,111 +1,111 @@ /* This file is part of the Baloo KDE project. Copyright (C) 2013 Vishesh Handa Copyright (C) 2010 Sebastian Trueg 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 "tagcheckbox.h" #include "tagwidget.h" #include "tagwidget_p.h" #include #include #include using namespace Baloo; TagCheckBox::TagCheckBox(const QString& tag, QWidget* parent) : QWidget( parent ), m_label(nullptr), m_tag(tag), m_urlHover(false) { QHBoxLayout* layout = new QHBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); - m_label = new QLabel(tag.split('/', QString::SkipEmptyParts).last(), this); + m_label = new QLabel(tag.split(QLatin1Char('/'), QString::SkipEmptyParts).last(), this); m_label->setToolTip(tag); m_label->setMouseTracking(true); m_label->setTextFormat(Qt::PlainText); m_label->setForegroundRole(parent->foregroundRole()); m_child = m_label; m_child->installEventFilter( this ); m_child->setMouseTracking(true); layout->addWidget( m_child ); } TagCheckBox::~TagCheckBox() { } void TagCheckBox::leaveEvent( QEvent* event ) { QWidget::leaveEvent( event ); enableUrlHover( false ); } bool TagCheckBox::eventFilter( QObject* watched, QEvent* event ) { if( watched == m_child ) { switch( event->type() ) { case QEvent::MouseMove: { QMouseEvent* me = static_cast(event); enableUrlHover( tagRect().contains(me->pos()) ); break; } case QEvent::MouseButtonRelease: { QMouseEvent* me = static_cast(event); if (me->button() == Qt::LeftButton && tagRect().contains(me->pos())) { emit tagClicked( m_tag ); return true; } break; } default: // do nothing break; } } return QWidget::eventFilter( watched, event ); } QRect TagCheckBox::tagRect() const { return QRect(QPoint(0, 0), m_label->size()); } void TagCheckBox::enableUrlHover( bool enable ) { if( m_urlHover != enable ) { m_urlHover = enable; QFont f = font(); if(enable) f.setUnderline(true); m_child->setFont(f); m_child->setCursor( enable ? Qt::PointingHandCursor : Qt::ArrowCursor ); } } diff --git a/src/tagsfileitemactionplugin/tagsfileitemaction.cpp b/src/tagsfileitemactionplugin/tagsfileitemaction.cpp index d656524..8da9c22 100644 --- a/src/tagsfileitemactionplugin/tagsfileitemaction.cpp +++ b/src/tagsfileitemactionplugin/tagsfileitemaction.cpp @@ -1,124 +1,124 @@ /* * Copyright (C) 2018 Nicolas Fella * * 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 "tagsfileitemaction.h" #include #include #include #include #include #include #include #include #include #include #include #include K_PLUGIN_FACTORY_WITH_JSON(TagsFileItemActionFactory, "tagsfileitemaction.json", registerPlugin();) TagsFileItemAction::TagsFileItemAction(QObject* parent, const QVariantList&) : KAbstractFileItemActionPlugin(parent) , m_tagsLister() { m_menu = new QMenu(i18n("Assign Tags")); m_menu->setIcon(QIcon::fromTheme(QStringLiteral("tag"))); connect(&m_tagsLister, &KCoreDirLister::itemsAdded, this, [this](const QUrl&, const KFileItemList& items) { const QStringList fileTags = m_metaData->tags(); // The file may be located outside an indexed path, or is not indexed yet // Show the complete tag list, i.e. the union of file and index DB tags QStringList allTags; allTags.reserve(fileTags.size() + items.size()); allTags.append(fileTags); for (const KFileItem &item: items) { allTags.append(item.name()); } allTags.sort(Qt::CaseInsensitive); allTags.removeDuplicates(); for (const QString name : qAsConst(allTags)) { QAction* action = m_menu->addAction(QIcon::fromTheme(QStringLiteral("tag")), name); action->setCheckable(true); action->setChecked(fileTags.contains(name)); connect(action, &QAction::triggered, this, [this, name](bool isChecked) { QStringList newTags = m_metaData->tags(); if (isChecked) { newTags.append(name); } else { newTags.removeAll(name); } m_metaData->setTags(newTags); }); } }); QAction* newAction = new QAction(i18n("Create New...")); newAction->setIcon(QIcon::fromTheme(QStringLiteral("tag-new"))); connect(newAction, &QAction::triggered, this, [this] { QString newTag = QInputDialog::getText(m_menu, i18n("New tag"), i18n("New tag:"), QLineEdit::Normal); QStringList tags = m_metaData->tags(); if (!tags.contains(newTag)) { tags.append(newTag); m_metaData->setTags(tags); } }); m_menu->addAction(newAction); m_menu->addSeparator(); } TagsFileItemAction::~TagsFileItemAction() { delete m_metaData; } QList TagsFileItemAction::actions(const KFileItemListProperties& fileItemInfos, QWidget* parentWidget) { Q_UNUSED(parentWidget); if (fileItemInfos.urlList().size() > 1) { return {}; } QString filePath = fileItemInfos.urlList()[0].toLocalFile(); if (!QFileInfo(filePath).isWritable()) { return {}; } m_metaData = new KFileMetaData::UserMetaData(filePath); if (!m_metaData->isSupported()) { return {}; } - m_tagsLister.openUrl(QUrl("tags:/"), KCoreDirLister::OpenUrlFlag::Reload); + m_tagsLister.openUrl(QUrl(QStringLiteral("tags:/")), KCoreDirLister::OpenUrlFlag::Reload); return {m_menu->menuAction()}; } #include "tagsfileitemaction.moc" diff --git a/src/tagwidget.cpp b/src/tagwidget.cpp index d942f9c..c775376 100644 --- a/src/tagwidget.cpp +++ b/src/tagwidget.cpp @@ -1,190 +1,190 @@ /* * This file is part of the Baloo KDE project. * Copyright (C) 2006-2010 Sebastian Trueg * Copyright (C) 2011-2013 Vishesh Handa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #include "tagwidget.h" #include "tagwidget_p.h" #include "kblocklayout.h" #include "kedittagsdialog_p.h" #include "tagcheckbox.h" #include #include #include #include #include using namespace Baloo; void TagWidgetPrivate::init( TagWidget* parent ) { q = parent; m_readOnly = false; m_showAllLinkLabel = nullptr; m_editTagsDialog = nullptr; QGridLayout* mainLayout = new QGridLayout( q ); mainLayout->setContentsMargins(0, 0, 0, 0); //TODO spacingHint should be declared. Old code m_flowLayout = new KBlockLayout( 0, KDialog::spacingHint()*3 ); m_flowLayout = new KBlockLayout( 0 ); mainLayout->addLayout( m_flowLayout, 0, 0, 1, 2 ); mainLayout->setColumnStretch( 0, 1 ); } void TagWidgetPrivate::rebuild() { buildTagHash( q->selectedTags() ); } void TagWidgetPrivate::buildTagHash(const QStringList& tags) { qDeleteAll(m_checkBoxHash); m_checkBoxHash.clear(); foreach (const QString& tag, tags) { getTagCheckBox(tag); } delete m_showAllLinkLabel; m_showAllLinkLabel = nullptr; if (m_readOnly && !tags.isEmpty()) { return; } m_showAllLinkLabel = new QLabel( q ); m_flowLayout->addWidget( m_showAllLinkLabel ); if (m_readOnly) { - m_showAllLinkLabel->setText("-"); + m_showAllLinkLabel->setText(QStringLiteral("-")); } else { QFont f(q->font()); f.setUnderline(true); m_showAllLinkLabel->setFont(f); m_showAllLinkLabel->setText( QLatin1String("") + ( m_checkBoxHash.isEmpty() ? i18nc("@label", "Add...") : i18nc("@label", "Edit...") ) + QLatin1String("") ); q->connect( m_showAllLinkLabel, SIGNAL(linkActivated(QString)), SLOT(slotShowAll()) ); } } TagCheckBox* TagWidgetPrivate::getTagCheckBox(const QString& tag) { QMap::iterator it = m_checkBoxHash.find(tag); if( it == m_checkBoxHash.end() ) { //kDebug() << "Creating checkbox for" << tag.genericLabel(); TagCheckBox* checkBox = new TagCheckBox(tag, q); q->connect( checkBox, SIGNAL(tagClicked(QString)), SIGNAL(tagClicked(QString)) ); m_checkBoxHash.insert( tag, checkBox ); m_flowLayout->addWidget( checkBox ); return checkBox; } else { return it.value(); } } void TagWidgetPrivate::selectTags(const QStringList& tags) { buildTagHash( tags ); } TagWidget::TagWidget( QWidget* parent ) : QWidget( parent ), d( new TagWidgetPrivate() ) { setForegroundRole(parent->foregroundRole()); d->init(this); } TagWidget::~TagWidget() { delete d; } QStringList TagWidget::selectedTags() const { QStringList tags; QMapIterator it(d->m_checkBoxHash); while( it.hasNext() ) { tags << it.next().key(); } return tags; } Qt::Alignment TagWidget::alignment() const { return d->m_flowLayout->alignment(); } bool TagWidget::readOnly() const { return d->m_readOnly; } void TagWidget::setSelectedTags(const QStringList& tags) { d->selectTags(tags); } void TagWidget::setAlignment( Qt::Alignment alignment ) { d->m_flowLayout->setAlignment( alignment ); } void TagWidget::setReadyOnly(bool readOnly) { d->m_readOnly = readOnly; d->rebuild(); } void TagWidget::slotTagUpdateDone() { setEnabled( true ); } void TagWidget::slotShowAll() { d->m_editTagsDialog = new KEditTagsDialog( selectedTags(), this ); d->m_editTagsDialog->setWindowModality( Qt::ApplicationModal ); connect( d->m_editTagsDialog, SIGNAL(finished(int)), this, SLOT(slotKEditTagDialogFinished(int)) ); d->m_editTagsDialog->open(); } void TagWidget::slotKEditTagDialogFinished(int result) { if( result == QDialog::Accepted ) { setSelectedTags( d->m_editTagsDialog->tags() ); emit selectionChanged( selectedTags() ); } d->m_editTagsDialog->deleteLater(); d->m_editTagsDialog = nullptr; } diff --git a/src/widgetfactory.cpp b/src/widgetfactory.cpp index e1ba442..a437a78 100644 --- a/src/widgetfactory.cpp +++ b/src/widgetfactory.cpp @@ -1,357 +1,357 @@ /* Copyright (C) 2012-2014 Vishesh Handa Code largely copied/adapted from KFileMetadataProvider Copyright (C) 2010 by Peter Penz 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) any later version. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "widgetfactory.h" #include "tagwidget.h" #include "kcommentwidget_p.h" #include "KRatingWidget" #include #include #include #include #include #include #include #include #include #include #include namespace { static QString plainText(const QString& richText) { QString plainText; plainText.reserve(richText.length()); bool skip = false; for (int i = 0; i < richText.length(); ++i) { const QChar c = richText.at(i); if (c == QLatin1Char('<')) { skip = true; } else if (c == QLatin1Char('>')) { skip = false; } else if (!skip) { plainText.append(c); } } return plainText; } } using namespace Baloo; WidgetFactory::WidgetFactory(QObject* parent) : QObject(parent) , m_readOnly( false ) , m_noLinks( false ) , m_dateFormat(QLocale::LongFormat) { } WidgetFactory::~WidgetFactory() { } // // Widget Creation // static QString toString(const QVariant& value) { switch (value.type()) { case QVariant::Int: return QLocale().toString(value.toInt()); case QVariant::Double: return QLocale().toString(value.toDouble()); case QVariant::StringList: return value.toStringList().join(i18nc("String list separator", ", ")); case QVariant::List: { QStringList list; for (const QVariant& var : value.toList()) { list << toString(var); } return list.join(i18nc("String list separator", ", ")); } default: return value.toString(); } } QWidget* WidgetFactory::createWidget(const QString& prop, const QVariant& value, QWidget* parent) { QWidget* widget = nullptr; const int maxUrlLength = 80; if (prop == QLatin1String("rating")) { widget = createRatingWidget( value.toInt(), parent ); } else if (prop == QLatin1String("userComment")) { widget = createCommentWidget( value.toString(), parent ); } else if (prop == QLatin1String("tags")) { QStringList tags = value.toStringList(); QCollator coll; coll.setNumericMode(true); std::sort(tags.begin(), tags.end(), [&](const QString& s1, const QString& s2){ return coll.compare(s1, s2) < 0; }); widget = createTagWidget( tags, parent ); } else { QString valueString; auto pi = KFileMetaData::PropertyInfo::fromName(prop); if (pi.name() == QLatin1String("originUrl")) { //Won't make sense to shrink originUrl with noLinks, //since it would make original URL unobtainable valueString = value.toString(); if (!m_noLinks) { //Shrink link name. auto labelString = valueString; if (labelString.size() > maxUrlLength) { labelString = KStringHandler::csqueeze(labelString, maxUrlLength); } valueString = QStringLiteral("%2").arg(valueString, labelString); } } else if (pi.name() != QLatin1String("empty")) { valueString = pi.formatAsDisplayString(value); } else { // Check if Date/DateTime QDateTime dt = QDateTime::fromString(value.toString(), Qt::ISODate); if (dt.isValid()) { KFormat form; QTime time = dt.time(); if (!time.hour() && !time.minute() && !time.second()){ valueString = form.formatRelativeDate(dt.date(), m_dateFormat); } else { valueString = form.formatRelativeDateTime(dt, m_dateFormat); } } else { valueString = toString(value); } } widget = createValueWidget(valueString, parent); } widget->setForegroundRole(parent->foregroundRole()); widget->setFont(parent->font()); widget->setObjectName(prop); return widget; } QWidget* WidgetFactory::createTagWidget(const QStringList& tags, QWidget* parent) { TagWidget* tagWidget = new TagWidget(parent); tagWidget->setReadyOnly(m_readOnly); tagWidget->setSelectedTags(tags); connect(tagWidget, &TagWidget::selectionChanged, this, &WidgetFactory::slotTagsChanged); connect(tagWidget, &TagWidget::tagClicked, this, &WidgetFactory::slotTagClicked); m_tagWidget = tagWidget; m_prevTags = tags; return tagWidget; } QWidget* WidgetFactory::createCommentWidget(const QString& comment, QWidget* parent) { KCommentWidget* commentWidget = new KCommentWidget(parent); commentWidget->setText(comment); commentWidget->setReadOnly(m_readOnly); connect(commentWidget, &KCommentWidget::commentChanged, this, &WidgetFactory::slotCommentChanged); m_commentWidget = commentWidget; return commentWidget; } QWidget* WidgetFactory::createRatingWidget(int rating, QWidget* parent) { KRatingWidget* ratingWidget = new KRatingWidget(parent); const Qt::Alignment align = (ratingWidget->layoutDirection() == Qt::LeftToRight) ? Qt::AlignLeft : Qt::AlignRight; ratingWidget->setAlignment(align); ratingWidget->setRating(rating); const QFontMetrics metrics(parent->font()); ratingWidget->setPixmapSize(metrics.height()); connect(ratingWidget, static_cast(&KRatingWidget::ratingChanged), this, &WidgetFactory::slotRatingChanged); m_ratingWidget = ratingWidget; return ratingWidget; } // The default size hint of QLabel tries to return a square size. // This does not work well in combination with layouts that use // heightForWidth(): In this case it is possible that the content // of a label might get clipped. By specifying a size hint // with a maximum width that is necessary to contain the whole text, // using heightForWidth() assures having a non-clipped text. class ValueWidget : public QLabel { public: explicit ValueWidget(QWidget* parent = nullptr); QSize sizeHint() const override; }; ValueWidget::ValueWidget(QWidget* parent) : QLabel(parent) { } QSize ValueWidget::sizeHint() const { QFontMetrics metrics(font()); // TODO: QLabel internally provides already a method sizeForWidth(), // that would be sufficient. However this method is not accessible, so // as workaround the tags from a richtext are removed manually here to // have a proper size hint. return metrics.size(Qt::TextSingleLine, plainText(text())); } QWidget* WidgetFactory::createValueWidget(const QString& value, QWidget* parent) { ValueWidget* valueWidget = new ValueWidget(parent); valueWidget->setTextInteractionFlags(Qt::TextSelectableByMouse | Qt::TextSelectableByKeyboard); valueWidget->setWordWrap(true); valueWidget->setAlignment(Qt::AlignTop | Qt::AlignLeft); valueWidget->setText(m_readOnly ? plainText(value) : value); connect(valueWidget, &ValueWidget::linkActivated, this, &WidgetFactory::slotLinkActivated); return valueWidget; } // // Data Synchronization // void WidgetFactory::slotCommentChanged(const QString& comment) { for (const KFileItem& item : qAsConst(m_items)) { QUrl url = item.targetUrl(); if (!url.isLocalFile()) { continue; } KFileMetaData::UserMetaData md(url.toLocalFile()); md.setUserComment(comment); } emit dataChangeStarted(); emit dataChangeFinished(); } void WidgetFactory::slotRatingChanged(uint rating) { for (const KFileItem& item : qAsConst(m_items)) { QUrl url = item.targetUrl(); if (!url.isLocalFile()) { continue; } KFileMetaData::UserMetaData md(url.toLocalFile()); md.setRating(rating); } emit dataChangeStarted(); emit dataChangeFinished(); } void WidgetFactory::slotTagsChanged(const QStringList& tags) { if (m_tagWidget) { for (const KFileItem& item : qAsConst(m_items)) { QUrl url = item.targetUrl(); if (!url.isLocalFile()) { continue; } KFileMetaData::UserMetaData md(url.toLocalFile()); // When multiple tags are selected one doesn't want to loose the old tags // of any of the resources. Unless specifically removed. QStringList newTags = md.tags() + tags; newTags.removeDuplicates(); for (const QString& tag : m_prevTags) { if (!tags.contains(tag)) { newTags.removeAll(tag); } } md.setTags(newTags); } m_prevTags = tags; emit dataChangeStarted(); emit dataChangeFinished(); } } // // Notifications // void WidgetFactory::slotLinkActivated(const QString& url) { emit urlActivated(QUrl::fromUserInput(url)); } void WidgetFactory::slotTagClicked(const QString& tag) { QUrl url; - url.setScheme("tags"); + url.setScheme(QStringLiteral("tags")); url.setPath(tag); emit urlActivated(url); } // // Accessor Methods // void WidgetFactory::setReadOnly(bool value) { m_readOnly = value; } void WidgetFactory::setNoLinks(bool value) { m_noLinks = value; } void WidgetFactory::setItems(const KFileItemList& items) { m_items = items; } Baloo::DateFormats WidgetFactory::dateFormat() const { return static_cast(m_dateFormat); } void Baloo::WidgetFactory::setDateFormat(const Baloo::DateFormats format) { m_dateFormat = static_cast(format); } diff --git a/test/metadataconfigwidgetapp.cpp b/test/metadataconfigwidgetapp.cpp index cf815a0..5a8a3a6 100644 --- a/test/metadataconfigwidgetapp.cpp +++ b/test/metadataconfigwidgetapp.cpp @@ -1,74 +1,74 @@ /* Copyright (C) 2012 Vishesh Handa 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) any later version. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "filemetadataconfigwidget.h" #include #include #include #include #include class FileMetadataWidgetTest : public QWidget { Q_OBJECT public: explicit FileMetadataWidgetTest(QWidget* parent = nullptr, Qt::WindowFlags f = {}); private Q_SLOTS: void slotChooseFiles(); private: Baloo::FileMetaDataConfigWidget* m_metadataWidget; QPushButton* m_button; }; FileMetadataWidgetTest::FileMetadataWidgetTest(QWidget* parent, Qt::WindowFlags f) : QWidget(parent, f) { m_metadataWidget = new Baloo::FileMetaDataConfigWidget( this ); m_button = new QPushButton( QLatin1String("Select files"), this ); connect( m_button, SIGNAL(clicked(bool)), this, SLOT(slotChooseFiles()) ); QVBoxLayout* layout = new QVBoxLayout( this ); layout->addWidget( m_button ); layout->addWidget( m_metadataWidget ); } void FileMetadataWidgetTest::slotChooseFiles() { QList urlList = QFileDialog::getOpenFileUrls(); KFileItemList list; foreach(const QUrl& url, urlList) list << KFileItem( url, QString(), mode_t() ); m_metadataWidget->setItems( list ); } int main( int argc, char** argv ) { QApplication app( argc, argv ); - app.setApplicationName( "FileMetaDataConfigWidgetApp" ); + app.setApplicationName(QStringLiteral("FileMetaDataConfigWidgetApp")); FileMetadataWidgetTest test; test.show(); return app.exec(); } #include "metadataconfigwidgetapp.moc" diff --git a/test/metadatawidgetapp.cpp b/test/metadatawidgetapp.cpp index fdfe1a6..e130ad1 100644 --- a/test/metadatawidgetapp.cpp +++ b/test/metadatawidgetapp.cpp @@ -1,47 +1,47 @@ /* Copyright (C) 2012-2015 Vishesh Handa 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) any later version. 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "filemetadatawidget.h" #include #include #include #include int main(int argc, char** argv) { QApplication app(argc, argv); - app.setApplicationName("FileMetadataWidgetApp"); + app.setApplicationName(QStringLiteral("FileMetadataWidgetApp")); QCommandLineParser parser; - parser.addPositionalArgument("filename", "files"); + parser.addPositionalArgument(QStringLiteral("filename"), QStringLiteral("files")); parser.process(app); Baloo::FileMetaDataWidget* widget = new Baloo::FileMetaDataWidget(); KFileItemList list; for (const QString& path : parser.positionalArguments()) { QFileInfo fi(path); list << KFileItem(QUrl::fromLocalFile(fi.absoluteFilePath()), QString(), mode_t()); } widget->show(); widget->setItems(list); return app.exec(); } diff --git a/test/tagwidgetapp.cpp b/test/tagwidgetapp.cpp index e62f56d..a3a5df1 100644 --- a/test/tagwidgetapp.cpp +++ b/test/tagwidgetapp.cpp @@ -1,33 +1,33 @@ /* This file is part of the Baloo KDE project. Copyright (C) 2010 Sebastian Trueg 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 "tagwidgettest.h" #include #include int main( int argc, char** argv ) { QApplication app( argc, argv ); - QCoreApplication::setApplicationName("TagWidgetApp"); + QCoreApplication::setApplicationName(QStringLiteral("TagWidgetApp")); TagWidgetTest tw; tw.show(); return app.exec(); } diff --git a/test/tagwidgettest.cpp b/test/tagwidgettest.cpp index c5af84e..2b6ce9f 100644 --- a/test/tagwidgettest.cpp +++ b/test/tagwidgettest.cpp @@ -1,78 +1,78 @@ /* This file is part of the Baloo KDE project. Copyright (C) 2010 Sebastian Trueg 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 "tagwidgettest.h" #include "tagwidget.h" #include #include #include TagWidgetTest::TagWidgetTest() : QWidget() { m_tagWidget = new Baloo::TagWidget(this); QVBoxLayout* lay = new QVBoxLayout(this); lay->addWidget(m_tagWidget); connect(m_tagWidget, SIGNAL(tagClicked(QString)), this, SLOT(slotTagClicked(QString))); connect(m_tagWidget, SIGNAL(selectionChanged(QStringList)), this, SLOT(slotSelectionChanged(QStringList))); - QCheckBox* box = new QCheckBox( "Align Right", this ); + QCheckBox* box = new QCheckBox(QStringLiteral("Align Right"), this ); connect(box, SIGNAL(toggled(bool)), this, SLOT(alignRight(bool))); lay->addWidget(box); - box = new QCheckBox( "Read only", this ); + box = new QCheckBox(QStringLiteral("Read only"), this ); connect(box, SIGNAL(toggled(bool)), this, SLOT(setReadOnly(bool))); lay->addWidget(box); } TagWidgetTest::~TagWidgetTest() { } void TagWidgetTest::slotTagClicked(const QString& tag) { qDebug() << "Tag clicked:" << tag; } void TagWidgetTest::slotSelectionChanged( const QStringList& tags ) { qDebug() << "Selection changed:" << tags; } void TagWidgetTest::alignRight( bool enable ) { if( enable ) m_tagWidget->setAlignment( Qt::AlignRight ); else m_tagWidget->setAlignment( Qt::AlignLeft ); } void TagWidgetTest::setReadOnly( bool enable ) { m_tagWidget->setReadyOnly(enable); }