diff --git a/CHANGELOG.md b/CHANGELOG.md index 06c4ce1..bf90231 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,10 +6,14 @@ - requesting the history of the current chat after reconnection - global availability (in drop down list) gets restored after reconnection - status icon in active chat changes when presence of the pen pal changes +- infinite progress when open the dialogue with something that has no history to show ### Improvements - slightly reduced the traffic on the startup by not requesting history of all MUCs - +- completely rewritten message feed, now it works way faster +- OPTIONAL RUNTIME dependency: "KIO Widgets" that is supposed to allow you to open a file in your default file manager +- show in folder now is supposed to try it's best to show file in folder, even you don't have KIO installed +- once uploaded local files don't get second time uploaded - the remote URL is reused ## Squawk 0.1.5 (Jul 29, 2020) ### Bug fixes diff --git a/CMakeLists.txt b/CMakeLists.txt index 0db5693..d4caf91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -67,6 +67,7 @@ qt5_add_resources(RCC resources/resources.qrc) option(SYSTEM_QXMPP "Use system qxmpp lib" ON) option(WITH_KWALLET "Build KWallet support module" ON) +option(WITH_KIO "Build KIO support module" ON) if (SYSTEM_QXMPP) find_package(QXmpp CONFIG) @@ -98,8 +99,21 @@ endif() add_executable(squawk ${squawk_SRC} ${squawk_HEAD} ${RCC}) target_link_libraries(squawk Qt5::Widgets) +if (WITH_KIO) + find_package(KF5KIO CONFIG) + + if (NOT KF5KIO_FOUND) + set(WITH_KIO OFF) + message("KIO package wasn't found, KIO support modules wouldn't be built") + else() + add_definitions(-DWITH_KIO) + message("Building with support of KIO") + endif() +endif() + add_subdirectory(ui) add_subdirectory(core) +add_subdirectory(plugins) add_subdirectory(external/simpleCrypt) @@ -107,6 +121,8 @@ target_link_libraries(squawk squawkUI) target_link_libraries(squawk squawkCORE) target_link_libraries(squawk uuid) + + add_dependencies(${CMAKE_PROJECT_NAME} translations) # Install the executable diff --git a/README.md b/README.md index 30c6473..84c114a 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ Here is the list of keys you can pass to configuration phase of `cmake ..`. - `CMAKE_BUILD_TYPE` - `Debug` just builds showing all warnings, `Release` builds with no warnings and applies optimizations (default is `Debug`) - `SYSTEM_QXMPP` - `True` tries to link against `qxmpp` installed in the system, `False` builds bundled `qxmpp` library (default is `True`) - `WITH_KWALLET` - `True` builds the `KWallet` capability module if `KWallet` is installed and if not goes to `False`. `False` disables `KWallet` support (default is `True`) +- `WITH_KIO` - `True` builds the `KIO` capability module if `KIO` is installed and if not goes to `False`. `False` disables `KIO` support (default is `True`) ## License diff --git a/core/passwordStorageEngines/CMakeLists.txt b/core/passwordStorageEngines/CMakeLists.txt index e824f77..ec750d9 100644 --- a/core/passwordStorageEngines/CMakeLists.txt +++ b/core/passwordStorageEngines/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.0) +cmake_minimum_required(VERSION 3.3) project(pse) if (WITH_KWALLET) diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt new file mode 100644 index 0000000..69a5e94 --- /dev/null +++ b/plugins/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.3) +project(plugins) + +if (WITH_KIO) + set(CMAKE_AUTOMOC ON) + + find_package(Qt5Core CONFIG REQUIRED) + + set(openFileManagerWindowJob_SRC + openfilemanagerwindowjob.cpp + ) + + add_library(openFileManagerWindowJob SHARED ${openFileManagerWindowJob_SRC}) + + get_target_property(Qt5CORE_INTERFACE_INCLUDE_DIRECTORIES Qt5::Core INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(KIO_WIDGETS_INTERFACE_INCLUDE_DIRECTORIES KF5::KIOWidgets INTERFACE_INCLUDE_DIRECTORIES) + get_target_property(CORE_ADDONS_INTERFACE_INCLUDE_DIRECTORIES KF5::CoreAddons INTERFACE_INCLUDE_DIRECTORIES) + target_include_directories(openFileManagerWindowJob PUBLIC ${KIO_WIDGETS_INTERFACE_INCLUDE_DIRECTORIES}) + target_include_directories(openFileManagerWindowJob PUBLIC ${CORE_ADDONS_INTERFACE_INCLUDE_DIRECTORIES}) + target_include_directories(openFileManagerWindowJob PUBLIC ${Qt5CORE_INTERFACE_INCLUDE_DIRECTORIES}) + + target_link_libraries(openFileManagerWindowJob KF5::KIOWidgets) + target_link_libraries(openFileManagerWindowJob Qt5::Core) + + install(TARGETS openFileManagerWindowJob DESTINATION ${CMAKE_INSTALL_LIBDIR}) +endif() diff --git a/plugins/openfilemanagerwindowjob.cpp b/plugins/openfilemanagerwindowjob.cpp new file mode 100644 index 0000000..904fbcf --- /dev/null +++ b/plugins/openfilemanagerwindowjob.cpp @@ -0,0 +1,8 @@ +#include +#include +#include + +extern "C" void highlightInFileManager(const QUrl& url) { + KIO::OpenFileManagerWindowJob* job = KIO::highlightInFileManager({url}); + QObject::connect(job, &KIO::OpenFileManagerWindowJob::result, job, &KIO::OpenFileManagerWindowJob::deleteLater); +} diff --git a/resources/images/fallback/dark/big/document-preview.svg b/resources/images/fallback/dark/big/document-preview.svg new file mode 100644 index 0000000..49a3feb --- /dev/null +++ b/resources/images/fallback/dark/big/document-preview.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/resources/images/fallback/dark/big/folder.svg b/resources/images/fallback/dark/big/folder.svg new file mode 100644 index 0000000..2acb4ab --- /dev/null +++ b/resources/images/fallback/dark/big/folder.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/fallback/dark/small/document-preview.svg b/resources/images/fallback/dark/small/document-preview.svg new file mode 100644 index 0000000..43d19bf --- /dev/null +++ b/resources/images/fallback/dark/small/document-preview.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/resources/images/fallback/dark/small/folder.svg b/resources/images/fallback/dark/small/folder.svg new file mode 100644 index 0000000..1061f4d --- /dev/null +++ b/resources/images/fallback/dark/small/folder.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/resources/images/fallback/light/big/document-preview.svg b/resources/images/fallback/light/big/document-preview.svg new file mode 100644 index 0000000..6f6e346 --- /dev/null +++ b/resources/images/fallback/light/big/document-preview.svg @@ -0,0 +1,11 @@ + + + + + + + diff --git a/resources/images/fallback/light/big/folder.svg b/resources/images/fallback/light/big/folder.svg new file mode 100644 index 0000000..2acb4ab --- /dev/null +++ b/resources/images/fallback/light/big/folder.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/images/fallback/light/small/document-preview.svg b/resources/images/fallback/light/small/document-preview.svg new file mode 100644 index 0000000..f40fcdf --- /dev/null +++ b/resources/images/fallback/light/small/document-preview.svg @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/resources/images/fallback/light/small/folder.svg b/resources/images/fallback/light/small/folder.svg new file mode 100644 index 0000000..a5f66cd --- /dev/null +++ b/resources/images/fallback/light/small/folder.svg @@ -0,0 +1,13 @@ + + + + + + diff --git a/resources/resources.qrc b/resources/resources.qrc index 4fb3e5b..58565fc 100644 --- a/resources/resources.qrc +++ b/resources/resources.qrc @@ -40,6 +40,8 @@ images/fallback/dark/big/favorite.svg images/fallback/dark/big/unfavorite.svg images/fallback/dark/big/add.svg + images/fallback/dark/big/folder.svg + images/fallback/dark/big/document-preview.svg images/fallback/dark/small/absent.svg @@ -80,6 +82,8 @@ images/fallback/dark/small/favorite.svg images/fallback/dark/small/unfavorite.svg images/fallback/dark/small/add.svg + images/fallback/dark/small/folder.svg + images/fallback/dark/small/document-preview.svg images/fallback/light/big/absent.svg @@ -120,6 +124,8 @@ images/fallback/light/big/favorite.svg images/fallback/light/big/unfavorite.svg images/fallback/light/big/add.svg + images/fallback/light/big/folder.svg + images/fallback/light/big/document-preview.svg images/fallback/light/small/absent.svg @@ -160,5 +166,7 @@ images/fallback/light/small/favorite.svg images/fallback/light/small/unfavorite.svg images/fallback/light/small/add.svg + images/fallback/light/small/folder.svg + images/fallback/light/small/document-preview.svg diff --git a/shared/global.cpp b/shared/global.cpp index 981dd60..62843ed 100644 --- a/shared/global.cpp +++ b/shared/global.cpp @@ -23,6 +23,11 @@ Shared::Global* Shared::Global::instance = 0; const std::set Shared::Global::supportedImagesExts = {"png", "jpg", "webp", "jpeg", "gif", "svg"}; +#ifdef WITH_KIO +QLibrary Shared::Global::openFileManagerWindowJob("openFileManagerWindowJob"); +Shared::Global::HighlightInFileManager Shared::Global::hfm = 0; +#endif + Shared::Global::Global(): availability({ tr("Online", "Availability"), @@ -80,7 +85,8 @@ Shared::Global::Global(): tr("Your password is going to be stored in KDE wallet storage (KWallet). You're going to be queried for permissions", "AccountPasswordDescription") }), pluginSupport({ - {"KWallet", false} + {"KWallet", false}, + {"openFileManagerWindowJob", false} }), fileCache() { @@ -89,6 +95,21 @@ Shared::Global::Global(): } instance = this; + +#ifdef WITH_KIO + openFileManagerWindowJob.load(); + if (openFileManagerWindowJob.isLoaded()) { + hfm = (HighlightInFileManager) openFileManagerWindowJob.resolve("highlightInFileManager"); + if (hfm) { + setSupported("openFileManagerWindowJob", true); + qDebug() << "KIO::OpenFileManagerWindow support enabled"; + } else { + qDebug() << "KIO::OpenFileManagerWindow support disabled: couldn't resolve required methods in the library"; + } + } else { + qDebug() << "KIO::OpenFileManagerWindow support disabled: couldn't load the library" << openFileManagerWindowJob.errorString(); + } +#endif } Shared::Global::FileInfo Shared::Global::getFileInfo(const QString& path) @@ -181,6 +202,69 @@ QString Shared::Global::getDescription(Shared::AccountPassword ap) return instance->accountPasswordDescription[static_cast(ap)]; } + +static const QStringList query = {"query", "default", "inode/directory"}; +static const QRegularExpression dolphinReg("[Dd]olphin"); +static const QRegularExpression nautilusReg("[Nn]autilus"); +static const QRegularExpression cajaReg("[Cc]aja"); +static const QRegularExpression nemoReg("[Nn]emo"); +static const QRegularExpression konquerorReg("kfmclient"); +static const QRegularExpression pcmanfmQtReg("pcmanfm-qt"); +static const QRegularExpression pcmanfmReg("pcmanfm"); +static const QRegularExpression thunarReg("thunar"); + +void Shared::Global::highlightInFileManager(const QString& path) +{ +#ifdef WITH_KIO + if (supported("openFileManagerWindowJob")) { + hfm(path); + return; + } else { + qDebug() << "requested to highlight in file manager url" << path << "but it's not supported: KIO plugin isn't loaded, trying fallback"; + } +#else + qDebug() << "requested to highlight in file manager url" << path << "but it's not supported: squawk wasn't compiled to support it, trying fallback"; +#endif + + QFileInfo info = path; + if (info.exists()) { + QProcess proc; + proc.start("xdg-mime", query); + proc.waitForFinished(); + QString output = proc.readLine().simplified(); + + QString folder; + if (info.isDir()) { + folder = info.canonicalFilePath(); + } else { + folder = info.canonicalPath(); + } + + if (output.contains(dolphinReg)) { + //there is a bug on current (21.04.0) dolphin, it works correct only if you already have dolphin launched + proc.startDetached("dolphin", QStringList() << "--select" << info.canonicalFilePath()); + //KIO::highlightInFileManager({QUrl(info.canonicalFilePath())}); + } else if (output.contains(nautilusReg)) { + proc.startDetached("nautilus", QStringList() << "--select" << info.canonicalFilePath()); //this worked on nautilus + } else if (output.contains(cajaReg)) { + proc.startDetached("caja", QStringList() << folder); //caja doesn't seem to support file selection command line, gonna just open directory + } else if (output.contains(nemoReg)) { + proc.startDetached("nemo", QStringList() << info.canonicalFilePath()); //nemo supports selecting files without keys + } else if (output.contains(konquerorReg)) { + proc.startDetached("konqueror", QStringList() << "--select" << info.canonicalFilePath()); //this worked on konqueror + } else if (output.contains(pcmanfmQtReg)) { + proc.startDetached("pcmanfm-qt", QStringList() << folder); //pcmanfm-qt doesn't seem to support open with selection, gonna just open directory + } else if (output.contains(pcmanfmReg)) { + proc.startDetached("pcmanfm", QStringList() << folder); //pcmanfm also doesn't seem to support open with selection, gonna just open directory + } else if (output.contains(thunarReg)) { + proc.startDetached("thunar", QStringList() << folder); //thunar doesn't seem to support open with selection, gonna just open directory + } else { + QDesktopServices::openUrl(QUrl::fromLocalFile(folder)); + } + } +} + + #define FROM_INT_INPL(Enum) \ template<> \ Enum Shared::Global::fromInt(int src) \ diff --git a/shared/global.h b/shared/global.h index bb9e5b7..b6bbe37 100644 --- a/shared/global.h +++ b/shared/global.h @@ -34,6 +34,12 @@ #include #include #include +#include +#include +#include +#include +#include +#include namespace Shared { @@ -83,6 +89,7 @@ namespace Shared { static const std::set supportedImagesExts; static FileInfo getFileInfo(const QString& path); + static void highlightInFileManager(const QString& path); template static T fromInt(int src); @@ -108,6 +115,14 @@ namespace Shared { std::map pluginSupport; std::map fileCache; + +#ifdef WITH_KIO + static QLibrary openFileManagerWindowJob; + + typedef void (*HighlightInFileManager)(const QUrl &); + + static HighlightInFileManager hfm; +#endif }; } diff --git a/shared/icons.h b/shared/icons.h index 48ecc37..540d3e9 100644 --- a/shared/icons.h +++ b/shared/icons.h @@ -170,6 +170,8 @@ static const std::map> icons = { {"favorite", {"favorite", "favorite"}}, {"unfavorite", {"draw-star", "unfavorite"}}, {"list-add", {"list-add", "add"}}, + {"folder", {"folder", "folder"}}, + {"document-preview", {"document-preview", "document-preview"}} }; } diff --git a/shared/utils.cpp b/shared/utils.cpp index f5f7fa5..924be85 100644 --- a/shared/utils.cpp +++ b/shared/utils.cpp @@ -46,40 +46,3 @@ QString Shared::processMessageBody(const QString& msg) processed.replace(urlReg, "\\1"); return "

" + processed + "

"; } - -static const QStringList query = {"query", "default", "inode/directory"}; -static const QRegularExpression dolphinReg("[Dd]olphin"); -static const QRegularExpression nautilusReg("[Nn]autilus"); -static const QRegularExpression cajaReg("[Cc]aja"); -static const QRegularExpression nemoReg("[Nn]emo"); -static const QRegularExpression konquerorReg("kfmclient"); - -void Shared::showInDirectory(const QString& path) -{ - QFileInfo info = path; - if (info.exists()) { - QProcess proc; - proc.start("xdg-mime", query); - proc.waitForFinished(); - QString output = proc.readLine().simplified(); - if (output.contains(dolphinReg)) { - proc.startDetached("dolphin", QStringList() << "--select" << info.canonicalFilePath()); - } else if (output.contains(nautilusReg)) { - proc.startDetached("nautilus", QStringList() << "--no-desktop" << info.canonicalFilePath()); - } else if (output.contains(cajaReg)) { - proc.startDetached("caja", QStringList() << "--no-desktop" << info.canonicalFilePath()); - } else if (output.contains(nemoReg)) { - proc.startDetached("nemo", QStringList() << "--no-desktop" << info.canonicalFilePath()); - } else if (output.contains(konquerorReg)) { - proc.startDetached("konqueror", QStringList() << "--select" << info.canonicalFilePath()); - } else { - QString folder; - if (info.isDir()) { - folder = info.canonicalFilePath(); - } else { - folder = info.canonicalPath(); - } - QDesktopServices::openUrl(QUrl::fromLocalFile(folder)); - } - } -} diff --git a/shared/utils.h b/shared/utils.h index 6bbe978..a8a17d5 100644 --- a/shared/utils.h +++ b/shared/utils.h @@ -23,19 +23,16 @@ #include #include #include -#include -#include -#include -#include + +//#include "KIO/OpenFileManagerWindowJob" #include -#include +#include namespace Shared { QString generateUUID(); QString processMessageBody(const QString& msg); -void showInDirectory(const QString& path); static const std::vector colorPalette = { QColor(244, 27, 63), diff --git a/ui/utils/CMakeLists.txt b/ui/utils/CMakeLists.txt index e656bde..0c33521 100644 --- a/ui/utils/CMakeLists.txt +++ b/ui/utils/CMakeLists.txt @@ -25,7 +25,7 @@ set(squawkUIUtils_SRC ) # Tell CMake to create the helloworld executable -add_library(squawkUIUtils ${squawkUIUtils_SRC}) +add_library(squawkUIUtils STATIC ${squawkUIUtils_SRC}) # Use the Widgets module from Qt 5. target_link_libraries(squawkUIUtils squawkWidgets) diff --git a/ui/widgets/CMakeLists.txt b/ui/widgets/CMakeLists.txt index abf238c..78b4f1a 100644 --- a/ui/widgets/CMakeLists.txt +++ b/ui/widgets/CMakeLists.txt @@ -21,7 +21,7 @@ set(squawkWidgets_SRC joinconference.cpp ) -add_library(squawkWidgets ${squawkWidgets_SRC}) +add_library(squawkWidgets STATIC ${squawkWidgets_SRC}) # Use the Widgets module from Qt 5. target_link_libraries(squawkWidgets vCardUI) diff --git a/ui/widgets/conversation.cpp b/ui/widgets/conversation.cpp index db6a92e..45ce2c5 100644 --- a/ui/widgets/conversation.cpp +++ b/ui/widgets/conversation.cpp @@ -417,14 +417,14 @@ void Conversation::onFeedContext(const QPoint& pos) QString path = item->getAttachPath(); if (path.size() > 0) { showMenu = true; - QAction* open = contextMenu->addAction(Shared::icon("document-new-from-template"), tr("Open")); + QAction* open = contextMenu->addAction(Shared::icon("document-preview"), tr("Open")); connect(open, &QAction::triggered, [path]() { QDesktopServices::openUrl(QUrl::fromLocalFile(path)); }); - QAction* show = contextMenu->addAction(Shared::icon("document-new-from-template"), tr("Show in folder")); + QAction* show = contextMenu->addAction(Shared::icon("folder"), tr("Show in folder")); connect(show, &QAction::triggered, [path]() { - Shared::showInDirectory(path); + Shared::Global::highlightInFileManager(path); }); }