Remove reverse-applicable patches.

ubuntu/disco
Simon Quigley 5 years ago
parent 03320d44ae
commit 88d19f7ee1

1
debian/changelog vendored

@ -1,6 +1,7 @@
libfm-qt (0.14.0-0ubuntu1) UNRELEASED; urgency=medium
* New upstream release.
- Remove reverse-applicable patches.
-- Simon Quigley <tsimonq2@ubuntu.com> Fri, 25 Jan 2019 22:54:43 -0600

@ -1,18 +0,0 @@
Description: Add integration for LXQt Archiver
Author: "Hong Jen Yee (PCMan)" <pcman.tw@gmail.com>
Origin: upstream
Applied-Upstream: commit:9a3bf23
Last-Update: 2018-07-14
--- a/data/archivers.list
+++ b/data/archivers.list
@@ -1,3 +1,10 @@
+[lxqt-archiver]
+create=lxqt-archiver --add %U
+extract=lxqt-archiver --extract %U
+extract_to=lxqt-archiver --extract-to %d %U
+mime_types=application/x-7z-compressed;application/x-7z-compressed-tar;application/x-ace;application/x-alz;application/x-ar;application/x-arj;application/x-bzip;application/x-bzip-compressed-tar;application/x-bzip1;application/x-bzip1-compressed-tar;application/x-cabinet;application/x-cbr;application/x-cbz;application/x-cd-image;application/x-compress;application/x-compressed-tar;application/x-cpio;application/x-deb;application/x-ear;application/x-ms-dos-executable;application/x-gtar;application/x-gzip;application/x-gzpostscript;application/x-java-archive;application/x-lha;application/x-lhz;application/x-lzip;application/x-lzip-compressed-tar;application/x-lzma;application/x-lzma-compressed-tar;application/x-lzop;application/x-lzop-compressed-tar;application/x-rar;application/x-rar-compressed;application/vnd.rar;application/x-rpm;application/x-rzip;application/x-tar;application/x-tarz;application/x-stuffit;application/x-war;application/x-xz;application/x-xz-compressed-tar;application/x-zip;application/x-zip-compressed;application/x-zoo;application/zip;multipart/x-zip;
+supports_uris=true
+
[file-roller]
create=file-roller --add %U
extract=file-roller --extract %U

@ -1,166 +0,0 @@
Description: Support adding metadata for trusting executables.
Author: Tsu Jan <tsujan2000@gmail.com>
Applied-Upstream: https://github.com/lxqt/libfm-qt/pull/242/commits/9c2f00c2e22b8054bcaedad89ef74f0432b9f7fe
Last-Update: 2018-10-15
--- a/src/core/basicfilelauncher.cpp
+++ b/src/core/basicfilelauncher.cpp
@@ -176,7 +176,7 @@ bool BasicFileLauncher::launchDesktopEnt
const char* desktopEntryName = nullptr;
FilePathList shortcutTargetPaths;
if(fileInfo->isExecutableType()) {
- auto act = quickExec_ ? ExecAction::DIRECT_EXEC : askExecFile(fileInfo);
+ auto act = (quickExec_ || fileInfo->isTrustable()) ? ExecAction::DIRECT_EXEC : askExecFile(fileInfo);
switch(act) {
case ExecAction::EXEC_IN_TERMINAL:
case ExecAction::DIRECT_EXEC: {
@@ -275,7 +275,7 @@ bool BasicFileLauncher::launchExecutable
auto filename = fileInfo->path().localPath();
/* FIXME: we need to use eaccess/euidaccess here. */
if(g_file_test(filename.get(), G_FILE_TEST_IS_EXECUTABLE)) {
- auto act = quickExec_ ? ExecAction::DIRECT_EXEC : askExecFile(fileInfo);
+ auto act = (quickExec_ || fileInfo->isTrustable()) ? ExecAction::DIRECT_EXEC : askExecFile(fileInfo);
int flags = G_APP_INFO_CREATE_NONE;
switch(act) {
case ExecAction::EXEC_IN_TERMINAL:
--- a/src/core/fileinfo.cpp
+++ b/src/core/fileinfo.cpp
@@ -9,7 +9,8 @@ const char defaultGFileInfoQueryAttribs[
"time::*,"
"access::*,"
"id::filesystem,"
- "metadata::emblems";
+ "metadata::emblems,"
+ "metadata::trusted";
FileInfo::FileInfo() {
// FIXME: initialize numeric data members
@@ -23,6 +24,7 @@ FileInfo::~FileInfo() {
}
void FileInfo::setFromGFileInfo(const GObjectPtr<GFileInfo>& inf, const FilePath& parentDirPath) {
+ inf_ = inf;
dirPath_ = parentDirPath;
const char* tmp, *uri;
GIcon* gicon;
@@ -377,6 +379,37 @@ bool FileInfo::isExecutableType() const
return mimeType_->canBeExecutable();
}
+bool FileInfo::isTrustable() const {
+ if(isExecutableType()) {
+ /* to avoid GIO assertion warning: */
+ if(g_file_info_get_attribute_type(inf_.get(), "metadata::trusted") == G_FILE_ATTRIBUTE_TYPE_STRING) {
+ if(const auto data = g_file_info_get_attribute_string(inf_.get(), "metadata::trusted")) {
+ return (strcmp(data, "true") == 0);
+ }
+ }
+ }
+ return false;
+}
+
+void FileInfo::setTrustable(bool trust) const {
+ if(!isExecutableType()) {
+ return; // "metadata::trusted" is only for executables
+ }
+ GObjectPtr<GFileInfo> info {g_file_info_new()}; // used to set only this attribute
+ if(trust) {
+ g_file_info_set_attribute_string(info.get(), "metadata::trusted", "true");
+ g_file_info_set_attribute_string(inf_.get(), "metadata::trusted", "true");
+ }
+ else {
+ g_file_info_set_attribute(info.get(), "metadata::trusted", G_FILE_ATTRIBUTE_TYPE_INVALID, nullptr);
+ g_file_info_set_attribute(inf_.get(), "metadata::trusted", G_FILE_ATTRIBUTE_TYPE_INVALID, nullptr);
+ }
+ g_file_set_attributes_from_info(path().gfile().get(),
+ info.get(),
+ G_FILE_QUERY_INFO_NONE,
+ nullptr, nullptr);
+}
+
bool FileInfoList::isSameType() const {
if(!empty()) {
--- a/src/core/fileinfo.h
+++ b/src/core/fileinfo.h
@@ -214,7 +214,12 @@ public:
return emblems_;
}
+ bool isTrustable() const;
+
+ void setTrustable(bool trust) const;
+
private:
+ GObjectPtr<GFileInfo> inf_;
std::string name_;
QString dispName_;
--- a/src/filemenu.cpp
+++ b/src/filemenu.cpp
@@ -245,6 +245,18 @@ FileMenu::FileMenu(Fm::FileInfoList file
FileMenu::~FileMenu() {
}
+void FileMenu::addTrustAction() {
+ if(info_->isExecutableType() && (!fileLauncher_ || !fileLauncher_->quickExec())) {
+ QAction* trustAction = new QAction(files_.size() > 1
+ ? tr("Trust selected executables")
+ : tr("Trust this executable"),
+ this);
+ trustAction->setCheckable(true);
+ trustAction->setChecked(info_->isTrustable());
+ connect(trustAction, &QAction::toggled, this, &FileMenu::onTrustToggled);
+ insertAction(propertiesAction_, trustAction);
+ }
+}
void FileMenu::addCustomActionItem(QMenu* menu, std::shared_ptr<const FileActionItem> item) {
if(!item) { // separator
@@ -329,6 +341,12 @@ void FileMenu::onCustomActionTrigerred()
}
}
+void FileMenu::onTrustToggled(bool checked) {
+ for(auto& file: files_) {
+ file->setTrustable(checked);
+ }
+}
+
void FileMenu::onFilePropertiesTriggered() {
FilePropsDialog::showForFiles(files_);
}
--- a/src/filemenu.h
+++ b/src/filemenu.h
@@ -41,6 +41,8 @@ public:
explicit FileMenu(Fm::FileInfoList files, std::shared_ptr<const Fm::FileInfo> info, Fm::FilePath cwd, bool isWritableDir = true, const QString& title = QString(), QWidget* parent = nullptr);
~FileMenu();
+ void addTrustAction();
+
bool useTrash() {
return useTrash_;
}
@@ -162,6 +164,7 @@ protected:
protected Q_SLOTS:
void onOpenTriggered();
void onOpenWithTriggered();
+ void onTrustToggled(bool checked);
void onFilePropertiesTriggered();
void onApplicationTriggered();
void onCustomActionTrigerred();
--- a/src/folderview.cpp
+++ b/src/folderview.cpp
@@ -1318,11 +1318,11 @@ void FolderView::onFileClicked(int type,
// show context menu
auto files = selectedFiles();
if(!files.empty()) {
- QModelIndexList selIndexes = mode == DetailedListMode ? selectedRows() : selectedIndexes();
- Fm::FileMenu* fileMenu = (view && selIndexes.size() == 1)
+ Fm::FileMenu* fileMenu = (view && files.size() == 1)
? new Fm::FileMenu(files, fileInfo, folderPath, isWritableDir, QString(), view)
: new Fm::FileMenu(files, fileInfo, folderPath, isWritableDir);
fileMenu->setFileLauncher(fileLauncher_);
+ fileMenu->addTrustAction();
prepareFileMenu(fileMenu);
menu = fileMenu;
}

@ -1,251 +0,0 @@
Description: Fix failure to open smb:// caused by incorrect file info handling
Author: "Hong Jen Yee (PCMan)" <pcman.tw@gmail.com>
Origin: upstream
Applied-Upstream: commit:1a6fa26
Last-Update: 2018-07-14
--- a/src/core/basicfilelauncher.cpp
+++ b/src/core/basicfilelauncher.cpp
@@ -27,11 +27,13 @@ bool BasicFileLauncher::launchFiles(cons
FilePathList pathsToLaunch;
// classify files according to different mimetypes
for(auto& fileInfo : fileInfos) {
- // qDebug("path: %s, target: %s", fileInfo->path().toString().get(), fileInfo->target().c_str());
- if(fileInfo->isDir()) {
- folderInfos.emplace_back(fileInfo);
- }
- else if(fileInfo->isMountable()) {
+ /*
+ qDebug("path: %s, type: %s, target: %s, isDir: %i, isDesktopEntry: %i",
+ fileInfo->path().toString().get(), fileInfo->mimeType()->name(), fileInfo->target().c_str(),
+ fileInfo->isDir(), fileInfo->isDesktopEntry());
+ */
+
+ if(fileInfo->isMountable()) {
if(fileInfo->target().empty()) {
// the mountable is not yet mounted so we have no target URI.
GErrorPtr err{G_IO_ERROR, G_IO_ERROR_NOT_MOUNTED,
@@ -65,6 +67,9 @@ bool BasicFileLauncher::launchFiles(cons
pathsToLaunch.emplace_back(path);
}
}
+ else if(fileInfo->isDir()) {
+ folderInfos.emplace_back(fileInfo);
+ }
else {
auto& mimeType = fileInfo->mimeType();
mimeTypeToFiles[mimeType->name()].emplace_back(fileInfo);
@@ -101,16 +106,27 @@ bool BasicFileLauncher::launchFiles(cons
bool BasicFileLauncher::launchPaths(FilePathList paths, GAppLaunchContext* ctx) {
// FIXME: blocking with an event loop is not a good design :-(
QEventLoop eventLoop;
-
auto job = new FileInfoJob{paths};
job->setAutoDelete(false); // do not automatically delete the job since we want its results later.
GObjectPtr<GAppLaunchContext> ctxPtr{ctx};
+
+ // error handling (for example: handle path not mounted error)
+ QObject::connect(job, &FileInfoJob::error,
+ &eventLoop, [this, job, ctx](const GErrorPtr & err, Job::ErrorSeverity /* severity */ , Job::ErrorAction &act) {
+ auto path = job->currentPath();
+ if(showError(ctx, err, path, nullptr)) {
+ // the user handled the error and ask for retry
+ act = Job::ErrorAction::RETRY;
+ }
+ }, Qt::BlockingQueuedConnection); // BlockingQueuedConnection is required here to pause the job and wait for user response
+
QObject::connect(job, &FileInfoJob::finished,
[&eventLoop]() {
// exit the event loop when the job is done
eventLoop.exit();
});
+
// run the job in another thread to not block the UI
job->runAsync();
@@ -143,7 +159,7 @@ BasicFileLauncher::ExecAction BasicFileL
return ExecAction::DIRECT_EXEC;
}
-bool BasicFileLauncher::showError(GAppLaunchContext* /* ctx */, GErrorPtr& /* err */, const FilePath& /* path */, const FileInfoPtr& /* info */) {
+bool BasicFileLauncher::showError(GAppLaunchContext* /* ctx */, const GErrorPtr & /* err */, const FilePath& /* path */, const FileInfoPtr& /* info */) {
return false;
}
@@ -247,13 +263,21 @@ bool BasicFileLauncher::launchDesktopEnt
FilePath BasicFileLauncher::handleShortcut(const FileInfoPtr& fileInfo, GAppLaunchContext* ctx) {
auto target = fileInfo->target();
+
+ // if we know the target is a dir, we are not going to open it using other apps
+ // for example: `network:///smb-root' is a shortcut targeting `smb:///' and it's also a dir
+ if(fileInfo->isDir()) {
+ return FilePath::fromPathStr(target.c_str());
+ }
+
auto scheme = CStrPtr{g_uri_parse_scheme(target.c_str())};
if(scheme) {
// collect the uri schemes we support
if(strcmp(scheme.get(), "file") == 0
|| strcmp(scheme.get(), "trash") == 0
|| strcmp(scheme.get(), "network") == 0
- || strcmp(scheme.get(), "computer") == 0) {
+ || strcmp(scheme.get(), "computer") == 0
+ || strcmp(scheme.get(), "menu") == 0) {
return FilePath::fromUri(fileInfo->target().c_str());
}
else {
--- a/src/core/basicfilelauncher.h
+++ b/src/core/basicfilelauncher.h
@@ -53,7 +53,7 @@ protected:
virtual bool openFolder(GAppLaunchContext* ctx, const FileInfoList& folderInfos, GErrorPtr& err);
- virtual bool showError(GAppLaunchContext* ctx, GErrorPtr& err, const FilePath& path = FilePath{}, const FileInfoPtr& info = FileInfoPtr{});
+ virtual bool showError(GAppLaunchContext* ctx, const GErrorPtr& err, const FilePath& path = FilePath{}, const FileInfoPtr& info = FileInfoPtr{});
virtual ExecAction askExecFile(const FileInfoPtr& file);
--- a/src/core/fileinfo.cpp
+++ b/src/core/fileinfo.cpp
@@ -36,10 +36,9 @@ void FileInfo::setFromGFileInfo(const GO
size_ = g_file_info_get_size(inf.get());
tmp = g_file_info_get_content_type(inf.get());
- if(!tmp) {
- tmp = "application/octet-stream";
+ if(tmp) {
+ mimeType_ = MimeType::fromName(tmp);
}
- mimeType_ = MimeType::fromName(tmp);
mode_ = g_file_info_get_attribute_uint32(inf.get(), G_FILE_ATTRIBUTE_UNIX_MODE);
@@ -196,6 +195,10 @@ _file_is_symlink:
}
}
+ if(!mimeType_) {
+ mimeType_ = MimeType::fromName("application/octet-stream");
+ }
+
/* if there is a custom folder icon, use it */
if(isNative() && type == G_FILE_TYPE_DIRECTORY) {
auto local_path = path().localPath();
--- a/src/core/fileinfojob.cpp
+++ b/src/core/fileinfojob.cpp
@@ -13,31 +13,41 @@ FileInfoJob::FileInfoJob(FilePathList pa
void FileInfoJob::exec() {
for(const auto& path: paths_) {
- if(!isCancelled()) {
+ if(isCancelled()) {
+ break;
+ }
+ currentPath_ = path;
+
+ bool retry;
+ do {
+ retry = false;
GErrorPtr err;
GFileInfoPtr inf{
g_file_query_info(path.gfile().get(), defaultGFileInfoQueryAttribs,
G_FILE_QUERY_INFO_NONE, cancellable().get(), &err),
false
};
- if(!inf) {
- continue;
- }
-
- // Reuse the same dirPath object when the path remains the same (optimize for files in the same dir)
- auto dirPath = commonDirPath_.isValid() ? commonDirPath_ : path.parent();
- FileInfo fileInfo(inf, dirPath);
+ if(inf) {
+ // Reuse the same dirPath object when the path remains the same (optimize for files in the same dir)
+ auto dirPath = commonDirPath_.isValid() ? commonDirPath_ : path.parent();
+ auto fileInfoPtr = std::make_shared<FileInfo>(inf, dirPath);
+
+ // FIXME: this is not elegant
+ if(cutFilesHashSet_
+ && cutFilesHashSet_->count(path.hash())) {
+ fileInfoPtr->bindCutFiles(cutFilesHashSet_);
+ }
- if(cutFilesHashSet_
- && cutFilesHashSet_->count(fileInfo.path().hash())) {
- fileInfo.bindCutFiles(cutFilesHashSet_);
+ results_.push_back(fileInfoPtr);
+ Q_EMIT gotInfo(path, results_.back());
}
-
- auto fileInfoPtr = std::make_shared<const FileInfo>(fileInfo);
-
- results_.push_back(fileInfoPtr);
- Q_EMIT gotInfo(path, fileInfoPtr);
- }
+ else {
+ auto act = emitError(err);
+ if(act == Job::ErrorAction::RETRY) {
+ retry = true;
+ }
+ }
+ } while(retry && !isCancelled());
}
}
--- a/src/core/fileinfojob.h
+++ b/src/core/fileinfojob.h
@@ -27,6 +27,10 @@ public:
return results_;
}
+ const FilePath& currentPath() const {
+ return currentPath_;
+ }
+
Q_SIGNALS:
void gotInfo(const FilePath& path, std::shared_ptr<const FileInfo>& info);
@@ -39,6 +43,7 @@ private:
FileInfoList results_;
FilePath commonDirPath_;
const std::shared_ptr<const HashSet> cutFilesHashSet_;
+ FilePath currentPath_;
};
} // namespace Fm
--- a/src/core/gioptrs.h
+++ b/src/core/gioptrs.h
@@ -112,6 +112,10 @@ public:
return err_;
}
+ const GError* operator->() const {
+ return err_;
+ }
+
bool operator == (const GErrorPtr& other) const {
return err_ == other.err_;
}
--- a/src/filelauncher.cpp
+++ b/src/filelauncher.cpp
@@ -76,7 +76,7 @@ bool FileLauncher::openFolder(GAppLaunch
return BasicFileLauncher::openFolder(ctx, folderInfos, err);
}
-bool FileLauncher::showError(GAppLaunchContext* /*ctx*/, GErrorPtr &err, const FilePath &path, const FileInfoPtr &info) {
+bool FileLauncher::showError(GAppLaunchContext* /*ctx*/, const GErrorPtr &err, const FilePath &path, const FileInfoPtr &info) {
/* ask for mount if trying to launch unmounted path */
if(err->domain == G_IO_ERROR) {
if(path && err->code == G_IO_ERROR_NOT_MOUNTED) {
--- a/src/filelauncher.h
+++ b/src/filelauncher.h
@@ -43,7 +43,7 @@ protected:
bool openFolder(GAppLaunchContext* ctx, const FileInfoList& folderInfos, GErrorPtr& err) override;
- bool showError(GAppLaunchContext* ctx, GErrorPtr& err, const FilePath& path = FilePath{}, const FileInfoPtr& info = FileInfoPtr{}) override;
+ bool showError(GAppLaunchContext* ctx, const GErrorPtr &err, const FilePath& path = FilePath{}, const FileInfoPtr& info = FileInfoPtr{}) override;
ExecAction askExecFile(const FileInfoPtr& file) override;

@ -1,68 +0,0 @@
Description: Correctly handle mountable types
Author: "Hong Jen Yee (PCMan)" <pcman.tw@gmail.com>
Origin: upstream
Applied-Upstream: commit:dc7a575
Last-Update: 2018-07-14
--- a/src/core/basicfilelauncher.cpp
+++ b/src/core/basicfilelauncher.cpp
@@ -28,11 +28,10 @@ bool BasicFileLauncher::launchFiles(cons
// classify files according to different mimetypes
for(auto& fileInfo : fileInfos) {
/*
- qDebug("path: %s, type: %s, target: %s, isDir: %i, isDesktopEntry: %i",
+ qDebug("path: %s, type: %s, target: %s, isDir: %i, isShortcut: %i, isMountable: %i, isDesktopEntry: %i",
fileInfo->path().toString().get(), fileInfo->mimeType()->name(), fileInfo->target().c_str(),
- fileInfo->isDir(), fileInfo->isDesktopEntry());
+ fileInfo->isDir(), fileInfo->isShortcut(), fileInfo->isMountable(), fileInfo->isDesktopEntry());
*/
-
if(fileInfo->isMountable()) {
if(fileInfo->target().empty()) {
// the mountable is not yet mounted so we have no target URI.
@@ -267,6 +266,7 @@ FilePath BasicFileLauncher::handleShortc
// if we know the target is a dir, we are not going to open it using other apps
// for example: `network:///smb-root' is a shortcut targeting `smb:///' and it's also a dir
if(fileInfo->isDir()) {
+ qDebug("shortcut is dir: %s", target.c_str());
return FilePath::fromPathStr(target.c_str());
}
--- a/src/core/fileinfo.cpp
+++ b/src/core/fileinfo.cpp
@@ -118,7 +118,8 @@ void FileInfo::setFromGFileInfo(const GO
isDeletable_ = true;
}
- isShortcut_ = false;
+ isShortcut_ = (type == G_FILE_TYPE_SHORTCUT);
+ isMountable_ = (type == G_FILE_TYPE_MOUNTABLE);
/* special handling for symlinks */
if(g_file_info_get_is_symlink(inf.get())) {
@@ -129,7 +130,6 @@ void FileInfo::setFromGFileInfo(const GO
switch(type) {
case G_FILE_TYPE_SHORTCUT:
- isShortcut_ = true;
/* Falls through. */
case G_FILE_TYPE_MOUNTABLE:
uri = g_file_info_get_attribute_string(inf.get(), G_FILE_ATTRIBUTE_STANDARD_TARGET_URI);
--- a/src/core/fileinfo.h
+++ b/src/core/fileinfo.h
@@ -151,7 +151,7 @@ public:
}
bool isMountable() const {
- return mimeType_->isMountable();
+ return isMountable_;
}
bool isShortcut() const {
@@ -239,6 +239,7 @@ private:
std::string target_; /* target of shortcut or mountable. */
bool isShortcut_ : 1; /* TRUE if file is shortcut type */
+ bool isMountable_ : 1; /* TRUE if file is mountable type */
bool isAccessible_ : 1; /* TRUE if can be read by user */
bool isWritable_ : 1; /* TRUE if can be written to by user */
bool isDeletable_ : 1; /* TRUE if can be deleted by user */

@ -1,29 +0,0 @@
Description: Fix launching desktop files
Author: Tsu Jan <tsujan2000@gmail.com>
Applied-Upstream: https://github.com/lxqt/libfm-qt/commit/9af480812bdef4a7cca7db7416b24d96b179ebf1
Last-Update: 2018-11-21
--- a/src/core/basicfilelauncher.cpp
+++ b/src/core/basicfilelauncher.cpp
@@ -250,7 +250,21 @@ bool BasicFileLauncher::launchDesktopEnt
it cannot be launched in fact */
if(app) {
- return launchWithApp(app, paths, ctx);
+ // don't call launchWithApp() because it calls g_app_info_launch_uris(),
+ // which uses the hard-coded terminal list of GLib -> gdesktopappinfo.c
+ GList* uris = nullptr;
+ for(auto& path : paths) {
+ auto uri = path.uri();
+ uris = g_list_prepend(uris, uri.release());
+ }
+ GErrorPtr err;
+ ret = bool(fm_app_info_launch(app, uris, ctx, &err));
+ g_list_foreach(uris, reinterpret_cast<GFunc>(g_free), nullptr);
+ g_list_free(uris);
+ if(!ret) {
+ // FIXME: show error for all files
+ showError(ctx, err, paths[0]);
+ }
}
else {
QString msg = QObject::tr("Invalid desktop entry file: '%1'").arg(desktopEntryName);

@ -1,52 +0,0 @@
Description: Use window text color for places view
Author: tsujan <tsujan2000@gmail.com>
Origin: upstream
Bug: https://github.com/lxqt/pcmanfm-qt/issues/696
Applied-Upstream: commit:87df010
Last-Update: 2018-07-14
--- a/src/folderitemdelegate.cpp
+++ b/src/folderitemdelegate.cpp
@@ -361,7 +361,8 @@ QWidget* FolderItemDelegate::createEdito
// ensure that its background isn't transparent (on the side-pane)
QWidget* editor = QStyledItemDelegate::createEditor(parent, option, index);
QPalette p = editor->palette();
- p.setColor(QPalette::Base, QApplication::palette().color(QPalette::Base));
+ p.setColor(QPalette::Text, qApp->palette().text().color());
+ p.setColor(QPalette::Base, qApp->palette().color(QPalette::Base));
editor->setPalette(p);
return editor;
}
--- a/src/placesview.cpp
+++ b/src/placesview.cpp
@@ -131,13 +131,6 @@ PlacesView::PlacesView(QWidget* parent):
setHeaderHidden(true);
setIndentation(12);
- /* merge with the surroundings */
- setFrameShape(QFrame::NoFrame);
- QPalette p = palette();
- p.setColor(QPalette::Base, QColor(Qt::transparent));
- setPalette(p);
- viewport()->setAutoFillBackground(false);
-
connect(this, &QTreeView::clicked, this, &PlacesView::onClicked);
connect(this, &QTreeView::pressed, this, &PlacesView::onPressed);
--- a/src/sidepane.cpp
+++ b/src/sidepane.cpp
@@ -158,6 +158,15 @@ void SidePane::setMode(Mode mode) {
switch(mode) {
case ModePlaces: {
PlacesView* placesView = new Fm::PlacesView(this);
+
+ // visually merge it with its surroundings
+ placesView->setFrameShape(QFrame::NoFrame);
+ QPalette p = placesView->palette();
+ p.setColor(QPalette::Base, QColor(Qt::transparent));
+ p.setColor(QPalette::Text, p.color(QPalette::WindowText));
+ placesView->setPalette(p);
+ placesView->viewport()->setAutoFillBackground(false);
+
view_ = placesView;
placesView->restoreHiddenItems(restorableHiddenPlaces_);
placesView->setIconSize(iconSize_);

@ -1,373 +0,0 @@
Description: Move the Qt file dialog helper into libfm-qt.
Author: Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
Origin: upstream
Applied-Upstream: commit:cc63bc7
Last-Update: 2018-07-30
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -83,6 +83,7 @@ set(libfm_SRCS
filedialog.cpp
fm-search.c # might be moved to libfm later
xdndworkaround.cpp
+ filedialoghelper.cpp
)
set(libfm_UIS
--- /dev/null
+++ b/src/filedialoghelper.cpp
@@ -0,0 +1,290 @@
+#include "filedialoghelper.h"
+
+#include "libfmqt.h"
+#include "filedialog.h"
+
+#include <QWindow>
+#include <QDebug>
+#include <QTimer>
+#include <QSettings>
+#include <QtGlobal>
+
+#include <memory>
+
+namespace Fm {
+
+inline static const QString viewModeToString(Fm::FolderView::ViewMode value);
+inline static Fm::FolderView::ViewMode viewModeFromString(const QString& str);
+
+FileDialogHelper::FileDialogHelper() {
+ // can only be used after libfm-qt initialization
+ dlg_ = std::unique_ptr<Fm::FileDialog>(new Fm::FileDialog());
+ connect(dlg_.get(), &Fm::FileDialog::accepted, [this]() {
+ saveSettings();
+ accept();
+ });
+ connect(dlg_.get(), &Fm::FileDialog::rejected, [this]() {
+ saveSettings();
+ reject();
+ });
+
+ connect(dlg_.get(), &Fm::FileDialog::fileSelected, this, &FileDialogHelper::fileSelected);
+ connect(dlg_.get(), &Fm::FileDialog::filesSelected, this, &FileDialogHelper::filesSelected);
+ connect(dlg_.get(), &Fm::FileDialog::currentChanged, this, &FileDialogHelper::currentChanged);
+ connect(dlg_.get(), &Fm::FileDialog::directoryEntered, this, &FileDialogHelper::directoryEntered);
+ connect(dlg_.get(), &Fm::FileDialog::filterSelected, this, &FileDialogHelper::filterSelected);
+}
+
+FileDialogHelper::~FileDialogHelper() {
+}
+
+void FileDialogHelper::exec() {
+ dlg_->exec();
+}
+
+bool FileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow* parent) {
+ dlg_->setAttribute(Qt::WA_NativeWindow, true); // without this, sometimes windowHandle() will return nullptr
+
+ dlg_->setWindowFlags(windowFlags);
+ dlg_->setWindowModality(windowModality);
+
+ // Reference: KDE implementation
+ // https://github.com/KDE/plasma-integration/blob/master/src/platformtheme/kdeplatformfiledialoghelper.cpp
+ dlg_->windowHandle()->setTransientParent(parent);
+
+ applyOptions();
+
+ loadSettings();
+ // central positioning with respect to the parent window
+ if(parent && parent->isVisible()) {
+ dlg_->move(parent->x() + (parent->width() - dlg_->width()) / 2,
+ parent->y() + (parent->height() - dlg_->height()) / 2);
+ }
+
+ // NOTE: the timer here is required as a workaround borrowed from KDE. Without this, the dialog UI will be blocked.
+ // QFileDialog calls our platform plugin to show our own native file dialog instead of showing its widget.
+ // However, it still creates a hidden dialog internally, and then make it modal.
+ // So user input from all other windows that are not the children of the QFileDialog widget will be blocked.
+ // This includes our own dialog. After the return of this show() method, QFileDialog creates its own window and
+ // then make it modal, which blocks our UI. The timer schedule a delayed popup of our file dialog, so we can
+ // show again after QFileDialog and override the modal state. Then our UI can be unblocked.
+ QTimer::singleShot(0, dlg_.get(), &QDialog::show);
+ dlg_->setFocus();
+ return true;
+}
+
+void FileDialogHelper::hide() {
+ dlg_->hide();
+}
+
+bool FileDialogHelper::defaultNameFilterDisables() const {
+ return false;
+}
+
+void FileDialogHelper::setDirectory(const QUrl& directory) {
+ dlg_->setDirectory(directory);
+}
+
+QUrl FileDialogHelper::directory() const {
+ return dlg_->directory();
+}
+
+void FileDialogHelper::selectFile(const QUrl& filename) {
+ dlg_->selectFile(filename);
+}
+
+QList<QUrl> FileDialogHelper::selectedFiles() const {
+ return dlg_->selectedFiles();
+}
+
+void FileDialogHelper::setFilter() {
+ // FIXME: what's this?
+ // The gtk+ 3 file dialog helper in Qt5 update options in this method.
+ applyOptions();
+}
+
+void FileDialogHelper::selectNameFilter(const QString& filter) {
+ dlg_->selectNameFilter(filter);
+}
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+QString FileDialogHelper::selectedMimeTypeFilter() const {
+ return dlg_->selectedMimeTypeFilter();
+}
+
+void FileDialogHelper::selectMimeTypeFilter(const QString& filter) {
+ dlg_->selectMimeTypeFilter(filter);
+}
+#endif
+
+QString FileDialogHelper::selectedNameFilter() const {
+ return dlg_->selectedNameFilter();
+}
+
+bool FileDialogHelper::isSupportedUrl(const QUrl& url) const {
+ return dlg_->isSupportedUrl(url);
+}
+
+void FileDialogHelper::applyOptions() {
+ auto& opt = options();
+
+ // set title
+ if(opt->windowTitle().isEmpty()) {
+ dlg_->setWindowTitle(opt->acceptMode() == QFileDialogOptions::AcceptOpen ? tr("Open File")
+ : tr("Save File"));
+ }
+ else {
+ dlg_->setWindowTitle(opt->windowTitle());
+ }
+
+ dlg_->setFilter(opt->filter());
+ dlg_->setFileMode(QFileDialog::FileMode(opt->fileMode()));
+ dlg_->setAcceptMode(QFileDialog::AcceptMode(opt->acceptMode())); // also sets a default label for accept button
+ // bool useDefaultNameFilters() const;
+ dlg_->setNameFilters(opt->nameFilters());
+ if(!opt->mimeTypeFilters().empty()) {
+ dlg_->setMimeTypeFilters(opt->mimeTypeFilters());
+ }
+
+ dlg_->setDefaultSuffix(opt->defaultSuffix());
+ // QStringList history() const;
+
+ // explicitly set labels
+ for(int i = 0; i < QFileDialogOptions::DialogLabelCount; ++i) {
+ auto label = static_cast<QFileDialogOptions::DialogLabel>(i);
+ if(opt->isLabelExplicitlySet(label)) {
+ dlg_->setLabelText(static_cast<QFileDialog::DialogLabel>(label), opt->labelText(label));
+ }
+ }
+
+ auto url = opt->initialDirectory();
+ if(url.isValid()) {
+ dlg_->setDirectory(url);
+ }
+
+
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+ auto filter = opt->initiallySelectedMimeTypeFilter();
+ if(!filter.isEmpty()) {
+ selectMimeTypeFilter(filter);
+ }
+ else {
+ filter = opt->initiallySelectedNameFilter();
+ if(!filter.isEmpty()) {
+ selectNameFilter(opt->initiallySelectedNameFilter());
+ }
+ }
+#else
+ auto filter = opt->initiallySelectedNameFilter();
+ if(!filter.isEmpty()) {
+ selectNameFilter(filter);
+ }
+#endif
+
+ auto selectedFiles = opt->initiallySelectedFiles();
+ for(const auto& selectedFile: selectedFiles) {
+ selectFile(selectedFile);
+ }
+ // QStringList supportedSchemes() const;
+}
+
+static const QString viewModeToString(Fm::FolderView::ViewMode value) {
+ QString ret;
+ switch(value) {
+ case Fm::FolderView::DetailedListMode:
+ default:
+ ret = QLatin1String("Detailed");
+ break;
+ case Fm::FolderView::CompactMode:
+ ret = QLatin1String("Compact");
+ break;
+ case Fm::FolderView::IconMode:
+ ret = QLatin1String("Icon");
+ break;
+ case Fm::FolderView::ThumbnailMode:
+ ret = QLatin1String("Thumbnail");
+ break;
+ }
+ return ret;
+}
+
+Fm::FolderView::ViewMode viewModeFromString(const QString& str) {
+ Fm::FolderView::ViewMode ret;
+ if(str == QLatin1String("Detailed")) {
+ ret = Fm::FolderView::DetailedListMode;
+ }
+ else if(str == QLatin1String("Compact")) {
+ ret = Fm::FolderView::CompactMode;
+ }
+ else if(str == QLatin1String("Icon")) {
+ ret = Fm::FolderView::IconMode;
+ }
+ else if(str == QLatin1String("Thumbnail")) {
+ ret = Fm::FolderView::ThumbnailMode;
+ }
+ else {
+ ret = Fm::FolderView::DetailedListMode;
+ }
+ return ret;
+}
+
+void FileDialogHelper::loadSettings() {
+ QSettings settings(QSettings::UserScope, "lxqt", "filedialog");
+ settings.beginGroup ("Sizes");
+ dlg_->resize(settings.value("WindowSize", QSize(700, 500)).toSize());
+ dlg_->setSplitterPos(settings.value("SplitterPos", 200).toInt());
+ settings.endGroup();
+
+ settings.beginGroup ("View");
+ dlg_->setViewMode(viewModeFromString(settings.value("Mode", "Detailed").toString()));
+ settings.endGroup();
+}
+
+void FileDialogHelper::saveSettings() {
+ QSettings settings(QSettings::UserScope, "lxqt", "filedialog");
+ settings.beginGroup ("Sizes");
+ QSize windowSize = dlg_->size();
+ if(settings.value("WindowSize") != windowSize) { // no redundant write
+ settings.setValue("WindowSize", windowSize);
+ }
+ int splitterPos = dlg_->splitterPos();
+ if(settings.value("SplitterPos") != splitterPos) {
+ settings.setValue("SplitterPos", splitterPos);
+ }
+ settings.endGroup();
+
+ settings.beginGroup ("View");
+ QString mode = viewModeToString(dlg_->viewMode());
+ if(settings.value("Mode") != mode) {
+ settings.setValue("Mode", mode);
+ }
+ settings.endGroup();
+}
+
+/*
+FileDialogPlugin::FileDialogPlugin() {
+
+}
+
+QPlatformFileDialogHelper *FileDialogPlugin::createHelper() {
+ return new FileDialogHelper();
+}
+*/
+
+} // namespace Fm
+
+
+QPlatformFileDialogHelper *createFileDialogHelper() {
+ // When a process has this environment set, that means glib event loop integration is disabled.
+ // In this case, libfm just won't work. So let's disable the file dialog helper and return nullptr.
+ if(qgetenv("QT_NO_GLIB") == "1") {
+ return nullptr;
+ }
+
+ static std::unique_ptr<Fm::LibFmQt> libfmQtContext_;
+ if(!libfmQtContext_) {
+ // initialize libfm-qt only once
+ libfmQtContext_ = std::unique_ptr<Fm::LibFmQt>{new Fm::LibFmQt()};
+ }
+ return new Fm::FileDialogHelper{};
+}
--- /dev/null
+++ b/src/filedialoghelper.h
@@ -0,0 +1,62 @@
+#ifndef FILEDIALOGHELPER_H
+#define FILEDIALOGHELPER_H
+
+#include "libfmqtglobals.h"
+#include <qpa/qplatformdialoghelper.h> // this private header is subject to changes
+#include <memory>
+
+namespace Fm {
+
+class FileDialog;
+
+class LIBFM_QT_API FileDialogHelper : public QPlatformFileDialogHelper {
+ Q_OBJECT
+
+public:
+ FileDialogHelper();
+
+ virtual ~FileDialogHelper();
+
+ // QPlatformDialogHelper
+ void exec() override;
+ bool show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow *parent) override;
+ void hide() override;
+
+ // QPlatformFileDialogHelper
+ bool defaultNameFilterDisables() const override;
+ void setDirectory(const QUrl &directory) override;
+ QUrl directory() const override;
+ void selectFile(const QUrl &filename) override;
+ QList<QUrl> selectedFiles() const override;
+ void setFilter() override;
+ void selectNameFilter(const QString &filter) override;
+#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
+ QString selectedMimeTypeFilter() const override;
+ void selectMimeTypeFilter(const QString &filter) override;
+#endif
+ QString selectedNameFilter() const override;
+
+ bool isSupportedUrl(const QUrl &url) const override;
+
+private:
+ void applyOptions();
+ void loadSettings();
+ void saveSettings();
+
+private:
+ std::unique_ptr<Fm::FileDialog> dlg_;
+};
+
+} // namespace Fm
+
+// export a C API without C++ name mangling so others can dynamically load libfm-qt at runtime
+// to call this API and get a new QPlatformFileDialogHelper object.
+
+extern "C" {
+
+// if the process calling this API fail to load libfm-qt, nullptr will be returned instead.
+LIBFM_QT_API QPlatformFileDialogHelper* createFileDialogHelper();
+
+}
+
+#endif // FILEDIALOGHELPER_H

@ -1,7 +0,0 @@
add-lxqt-archiver-integration.patch
fix-incorrect-file-info-handling-1.patch
fix-incorrect-file-info-handling-2.patch
fix-places-font-color.patch
move-in-file-dialog.patch
add-metadata-for-trusting-executables.patch
fix-launching-desktop-files.patch
Loading…
Cancel
Save