Cherry-picked upstream version 0.9.0+20150925.

Fixed source/options - no need to ignore .kdev4, fixed upstream
Changed symbols
 - put the arch bit at the end and comment them
 - merged new symbols
Fixed the copied pdmanfm menu file
Fixed rules --fail-missing is enough and will list missed files
Switched to experimental because of LXQt namespace change
Added minimum version for liblxqt0-dev (>= 0.9.0+20150911)
ubuntu/disco
Alf Gaida 9 years ago
parent 3875d79e68
commit b69cb453e3

14
debian/changelog vendored

@ -1,3 +1,17 @@
pcmanfm-qt (0.9.0+20150925-1) experimental; urgency=medium
* Cherry-picked upstream version 0.9.0+20150925.
* Fixed source/options - no need to ignore .kdev4, fixed upstream
* Changed symbols
- put the arch bit at the end and comment them
- put the new search symbols before the arch bits - they need a review
* Fixed the copied pdmanfm menu file
* Fixed rules --fail-missing is enough and will list missed files
* Switched to experimental because of LXQt namespace change
* Added minimum version for liblxqt0-dev (>= 0.9.0+20150911)
-- Alf Gaida <agaida@siduction.org> Fri, 25 Sep 2015 22:12:50 +0200
pcmanfm-qt (0.9.0+20150908-1) unstable; urgency=medium
[ Alf Gaida ]

2
debian/control vendored

@ -10,7 +10,7 @@ Build-Depends: cmake (>= 3.0.2),
debhelper (>= 9),
libfm-dev (>= 1.2.0),
libglib2.0-dev,
liblxqt0-dev,
liblxqt0-dev (>= 0.9.0+20150911),
libmenu-cache-dev,
libqt5x11extras5-dev,
libqt5xdg-dev,

@ -1,8 +1,4 @@
libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(arch-bits=32|c++)"Fm::MountOperation::onShowUnmountProgress(_GMountOperation*, char*, long long, long long, Fm::MountOperation*)@Base" 0.9.0+20150903
(arch-bits=32|c++)"Fm::ThumbnailLoader::readImageFromStream(_GInputStream*, unsigned long long, _GCancellable*)@Base" 0.9.0+20150903
(arch-bits=64|c++)"Fm::MountOperation::onShowUnmountProgress(_GMountOperation*, char*, long, long, Fm::MountOperation*)@Base" 0.9.0+20150903
(arch-bits=64|c++)"Fm::ThumbnailLoader::readImageFromStream(_GInputStream*, unsigned long, _GCancellable*)@Base" 0.9.0+20150903
(c++)"Fm::AppChooserComboBox::~AppChooserComboBox()@Base" 0.9.0+20150903
(c++)"Fm::AppChooserComboBox::AppChooserComboBox(QWidget*)@Base" 0.9.0+20150903
(c++)"Fm::AppChooserComboBox::isChanged()@Base" 0.9.0+20150903
@ -101,8 +97,6 @@ libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(c++)"Fm::DirTreeModelItem::childFromPath(_FmPath*, bool) const@Base" 0.9.0+20150903
(c++)"Fm::DirTreeModelItem::~DirTreeModelItem()@Base" 0.9.0+20150903
(c++)"Fm::DirTreeModelItem::DirTreeModelItem()@Base" 0.9.0+20150903
(c++)"Fm::DirTreeModelItem::DirTreeModelItem()@Base" 0.9.0+20150903
(c++)"Fm::DirTreeModelItem::DirTreeModelItem(_FmFileInfo*, Fm::DirTreeModel*, Fm::DirTreeModelItem*)@Base" 0.9.0+20150903
(c++)"Fm::DirTreeModelItem::DirTreeModelItem(_FmFileInfo*, Fm::DirTreeModel*, Fm::DirTreeModelItem*)@Base" 0.9.0+20150903
(c++)"Fm::DirTreeModelItem::freeFolder()@Base" 0.9.0+20150903
(c++)"Fm::DirTreeModel::itemFromIndex(QModelIndex const&) const@Base" 0.9.0+20150903
@ -178,8 +172,6 @@ libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(c++)"Fm::FileMenu::createMenu(_FmFileInfoList*, _FmFileInfo*, _FmPath*)@Base" 0.9.0+20150903
(c++)"Fm::FileMenu::~FileMenu()@Base" 0.9.0+20150903
(c++)"Fm::FileMenu::FileMenu(_FmFileInfoList*, _FmFileInfo*, _FmPath*, QString const&, QWidget*)@Base" 0.9.0+20150903
(c++)"Fm::FileMenu::FileMenu(_FmFileInfoList*, _FmFileInfo*, _FmPath*, QString const&, QWidget*)@Base" 0.9.0+20150903
(c++)"Fm::FileMenu::FileMenu(_FmFileInfoList*, _FmFileInfo*, _FmPath*, QWidget*)@Base" 0.9.0+20150903
(c++)"Fm::FileMenu::FileMenu(_FmFileInfoList*, _FmFileInfo*, _FmPath*, QWidget*)@Base" 0.9.0+20150903
(c++)"Fm::FileMenu::metaObject() const@Base" 0.9.0+20150903
(c++)"Fm::FileMenu::onApplicationTriggered()@Base" 0.9.0+20150903
@ -257,6 +249,11 @@ libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(c++)"Fm::FilePropsDialog::qt_metacall(QMetaObject::Call, int, void**)@Base" 0.9.0+20150903
(c++)"Fm::FilePropsDialog::qt_metacast(char const*)@Base" 0.9.0+20150903
(c++)"Fm::FilePropsDialog::staticMetaObject@Base" 0.9.0+20150903
(c++)"Fm::FileSearchDialog::accept()@Base" 0.9.0+20150925
(c++)"Fm::FileSearchDialog::~FileSearchDialog()@Base" 0.9.0+20150925
(c++)"Fm::FileSearchDialog::FileSearchDialog(QStringList, QWidget*, QFlags<Qt::WindowType>)@Base" 0.9.0+20150925
(c++)"Fm::FileSearchDialog::onAddPath()@Base" 0.9.0+20150925
(c++)"Fm::FileSearchDialog::onRemovePath()@Base" 0.9.0+20150925
(c++)"Fm::FolderItemDelegate::drawText(QPainter*, QStyleOptionViewItem&, QRectF&) const@Base" 0.9.0+20150903
(c++)"Fm::FolderItemDelegate::~FolderItemDelegate()@Base" 0.9.0+20150903
(c++)"Fm::FolderItemDelegate::FolderItemDelegate(QAbstractItemView*, QObject*)@Base" 0.9.0+20150903
@ -301,8 +298,6 @@ libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(c++)"Fm::FolderModelItem::findThumbnail(int)@Base" 0.9.0+20150903
(c++)"Fm::FolderModelItem::~FolderModelItem()@Base" 0.9.0+20150903
(c++)"Fm::FolderModelItem::FolderModelItem(_FmFileInfo*)@Base" 0.9.0+20150903
(c++)"Fm::FolderModelItem::FolderModelItem(_FmFileInfo*)@Base" 0.9.0+20150903
(c++)"Fm::FolderModelItem::FolderModelItem(Fm::FolderModelItem const&)@Base" 0.9.0+20150903
(c++)"Fm::FolderModelItem::FolderModelItem(Fm::FolderModelItem const&)@Base" 0.9.0+20150903
(c++)"Fm::FolderModel::itemFromIndex(QModelIndex const&) const@Base" 0.9.0+20150903
(c++)"Fm::FolderModelItem::removeThumbnail(int)@Base" 0.9.0+20150903
@ -446,12 +441,8 @@ libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(c++)"Fm::PlacesModel::itemFromVolume(_GVolume*)@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::~PlacesModelItem()@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::PlacesModelItem()@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::PlacesModelItem()@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::PlacesModelItem(char const*, QString, _FmPath*)@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::PlacesModelItem(char const*, QString, _FmPath*)@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::PlacesModelItem(_FmIcon*, QString, _FmPath*)@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::PlacesModelItem(_FmIcon*, QString, _FmPath*)@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::PlacesModelItem(QIcon, QString, _FmPath*)@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::PlacesModelItem(QIcon, QString, _FmPath*)@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::setFileInfo(_FmFileInfo*)@Base" 0.9.0+20150903
(c++)"Fm::PlacesModelItem::setIcon(_FmIcon*)@Base" 0.9.0+20150903
@ -596,6 +587,7 @@ libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(c++)"non-virtual thunk to Fm::FileMenu::~FileMenu()@Base" 0.9.0+20150903
(c++)"non-virtual thunk to Fm::FileOperationDialog::~FileOperationDialog()@Base" 0.9.0+20150903
(c++)"non-virtual thunk to Fm::FilePropsDialog::~FilePropsDialog()@Base" 0.9.0+20150903
(c++)"non-virtual thunk to Fm::FileSearchDialog::~FileSearchDialog()@Base" 0.9.0+20150925
(c++)"non-virtual thunk to Fm::FolderMenu::~FolderMenu()@Base" 0.9.0+20150903
(c++)"non-virtual thunk to Fm::FolderView::~FolderView()@Base" 0.9.0+20150903
(c++)"non-virtual thunk to Fm::FontButton::~FontButton()@Base" 0.9.0+20150903
@ -619,6 +611,7 @@ libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(c++)"typeinfo for Fm::FileOperation@Base" 0.9.0+20150903
(c++)"typeinfo for Fm::FileOperationDialog@Base" 0.9.0+20150903
(c++)"typeinfo for Fm::FilePropsDialog@Base" 0.9.0+20150903
(c++)"typeinfo for Fm::FileSearchDialog@Base" 0.9.0+20150925
(c++)"typeinfo for Fm::FolderItemDelegate@Base" 0.9.0+20150903
(c++)"typeinfo for Fm::FolderMenu@Base" 0.9.0+20150903
(c++)"typeinfo for Fm::FolderModel@Base" 0.9.0+20150903
@ -655,6 +648,7 @@ libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(c++)"typeinfo name for Fm::FileOperation@Base" 0.9.0+20150903
(c++)"typeinfo name for Fm::FileOperationDialog@Base" 0.9.0+20150903
(c++)"typeinfo name for Fm::FilePropsDialog@Base" 0.9.0+20150903
(c++)"typeinfo name for Fm::FileSearchDialog@Base" 0.9.0+20150925
(c++)"typeinfo name for Fm::FolderItemDelegate@Base" 0.9.0+20150903
(c++)"typeinfo name for Fm::FolderMenu@Base" 0.9.0+20150903
(c++)"typeinfo name for Fm::FolderModel@Base" 0.9.0+20150903
@ -691,6 +685,7 @@ libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(c++)"vtable for Fm::FileOperation@Base" 0.9.0+20150903
(c++)"vtable for Fm::FileOperationDialog@Base" 0.9.0+20150903
(c++)"vtable for Fm::FilePropsDialog@Base" 0.9.0+20150903
(c++)"vtable for Fm::FileSearchDialog@Base" 0.9.0+20150925
(c++)"vtable for Fm::FolderItemDelegate@Base" 0.9.0+20150903
(c++)"vtable for Fm::FolderMenu@Base" 0.9.0+20150903
(c++)"vtable for Fm::FolderModel@Base" 0.9.0+20150903
@ -712,3 +707,45 @@ libfm-qt5.so.2 libfm-qt5-2 #MINVER#
(c++)"vtable for Fm::SidePane@Base" 0.9.0+20150903
(c++)"vtable for Fm::ThumbnailLoader@Base" 0.9.0+20150903
## some new symbols i dont know
fm_search_add_dir@Base 0.9.0+20150925
fm_search_add_mime_type@Base 0.9.0+20150925
fm_search_dup_path@Base 0.9.0+20150925
fm_search_free@Base 0.9.0+20150925
fm_search_get_content_ci@Base 0.9.0+20150925
fm_search_get_content_pattern@Base 0.9.0+20150925
fm_search_get_content_regex@Base 0.9.0+20150925
fm_search_get_dirs@Base 0.9.0+20150925
fm_search_get_max_mtime@Base 0.9.0+20150925
fm_search_get_max_size@Base 0.9.0+20150925
fm_search_get_mime_types@Base 0.9.0+20150925
fm_search_get_min_mtime@Base 0.9.0+20150925
fm_search_get_min_size@Base 0.9.0+20150925
fm_search_get_name_ci@Base 0.9.0+20150925
fm_search_get_name_patterns@Base 0.9.0+20150925
fm_search_get_name_regex@Base 0.9.0+20150925
fm_search_get_recursive@Base 0.9.0+20150925
fm_search_get_show_hidden@Base 0.9.0+20150925
fm_search_new@Base 0.9.0+20150925
fm_search_remove_dir@Base 0.9.0+20150925
fm_search_remove_mime_type@Base 0.9.0+20150925
fm_search_set_content_ci@Base 0.9.0+20150925
fm_search_set_content_pattern@Base 0.9.0+20150925
fm_search_set_content_regex@Base 0.9.0+20150925
fm_search_set_max_mtime@Base 0.9.0+20150925
fm_search_set_max_size@Base 0.9.0+20150925
fm_search_set_min_mtime@Base 0.9.0+20150925
fm_search_set_min_size@Base 0.9.0+20150925
fm_search_set_name_ci@Base 0.9.0+20150925
fm_search_set_name_patterns@Base 0.9.0+20150925
fm_search_set_name_regex@Base 0.9.0+20150925
fm_search_set_recursive@Base 0.9.0+20150925
fm_search_set_show_hidden@Base 0.9.0+20150925
## arch-bits for 32 bit
(arch-bits=32|c++)"Fm::MountOperation::onShowUnmountProgress(_GMountOperation*, char*, long long, long long, Fm::MountOperation*)@Base" 0.9.0+20150903
(arch-bits=32|c++)"Fm::ThumbnailLoader::readImageFromStream(_GInputStream*, unsigned long long, _GCancellable*)@Base" 0.9.0+20150903
## arch-bits for 64 bit
(arch-bits=64|c++)"Fm::MountOperation::onShowUnmountProgress(_GMountOperation*, char*, long, long, Fm::MountOperation*)@Base" 0.9.0+20150903
(arch-bits=64|c++)"Fm::ThumbnailLoader::readImageFromStream(_GInputStream*, unsigned long, _GCancellable*)@Base" 0.9.0+20150903

@ -1,4 +1,4 @@
?package(pcmanfm):needs="X11" section="Applications/File Management"\
title="PCManFM" longtitle="Real Tabbed File Manager"\
description="PCMan File Manager is an extremely fast and lightweight GTK+ based file manager."\
command="/usr/bin/pcmanfm" hints="File manager"
?package(pcmanfm-qt):needs="X11" section="Applications/File Management"\
title="PCManFM-Qt" longtitle="Real Tabbed File Manager"\
description="PCMan File Manager is an extremely fast and lightweight Qt based file manager."\
command="/usr/bin/pcmanfm-qt" hints="File manager"

2
debian/rules vendored

@ -8,7 +8,7 @@ export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed
dh ${@} --buildsystem cmake --parallel
override_dh_install:
dh_install --exclude=pcmanfm-qt.1 --fail-missing --list-missing
dh_install --exclude=pcmanfm-qt.1 --fail-missing
override_dh_strip:
dh_strip -ppcmanfm-qt --dbg-package=pcmanfm-qt-dbg

@ -1,2 +1 @@
tar-ignore = .gitignore
tar-ignore = pcmanfm-qt.kdev4

@ -63,6 +63,8 @@ set(libfm_SRCS
appchoosercombobox.cpp
appmenuview.cpp
appchooserdialog.cpp
filesearchdialog.cpp
fm-search.c # might be moved to libfm later
)
set(libfm_UIS
@ -73,6 +75,7 @@ set(libfm_UIS
edit-bookmarks.ui
exec-file.ui
app-chooser-dialog.ui
filesearch.ui
)
qt5_wrap_ui(libfm_UIS_H ${libfm_UIS})

@ -62,6 +62,19 @@ void FileMenu::createMenu(FmFileInfoList* files, FmFileInfo* info, FmPath* cwd)
confirmDelete_ = true;
confirmTrash_ = false; // Confirm before moving files into "trash can"
openAction_ = NULL;
openWithMenuAction_ = NULL;
openWithAction_ = NULL;
separator1_ = NULL;
cutAction_ = NULL;
copyAction_ = NULL;
pasteAction_ = NULL;
deleteAction_ = NULL;
unTrashAction_ = NULL;
renameAction_ = NULL;
separator2_ = NULL;
propertiesAction_ = NULL;
files_ = fm_file_info_list_ref(files);
info_ = info ? fm_file_info_ref(info) : NULL;
cwd_ = cwd ? fm_path_ref(cwd) : NULL;
@ -346,8 +359,10 @@ void FileMenu::onRenameTriggered() {
void FileMenu::setUseTrash(bool trash) {
if(useTrash_ != trash) {
useTrash_ = trash;
deleteAction_->setText(useTrash_ ? tr("&Move to Trash") : tr("&Delete"));
deleteAction_->setIcon(useTrash_ ? QIcon::fromTheme("user-trash") : QIcon::fromTheme("edit-delete"));
if(deleteAction_) {
deleteAction_->setText(useTrash_ ? tr("&Move to Trash") : tr("&Delete"));
deleteAction_->setIcon(useTrash_ ? QIcon::fromTheme("user-trash") : QIcon::fromTheme("edit-delete"));
}
}
}

@ -0,0 +1,449 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SearchDialog</class>
<widget class="QDialog" name="SearchDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>512</width>
<height>420</height>
</rect>
</property>
<property name="windowTitle">
<string>Search Files</string>
</property>
<property name="windowIcon">
<iconset theme="system-search">
<normaloff/>
</iconset>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Name/Location</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>File Name Patterns:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QLineEdit" name="namePatterns">
<property name="text">
<string>*</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="nameCaseInsensitive">
<property name="text">
<string>Case insensitive</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="nameRegExp">
<property name="text">
<string>Use regular expression</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="title">
<string>Places to Search:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QListWidget" name="listView"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPushButton" name="addPath">
<property name="text">
<string>&amp;Add</string>
</property>
<property name="icon">
<iconset theme="list-add">
<normaloff/>
</iconset>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="removePath">
<property name="text">
<string>&amp;Remove</string>
</property>
<property name="icon">
<iconset theme="list-remove">
<normaloff/>
</iconset>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="recursiveSearch">
<property name="text">
<string>Search in sub directories</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="searchHidden">
<property name="text">
<string>Search for hidden files</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>File Type</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QGroupBox" name="groupBox_3">
<property name="title">
<string>Only search for files of following types:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QCheckBox" name="searchTextFiles">
<property name="text">
<string>Text files</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="searchImages">
<property name="text">
<string>Image files</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="searchAudio">
<property name="text">
<string>Audio files</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="searchVideo">
<property name="text">
<string>Video files</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="searchDocuments">
<property name="text">
<string>Documents</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="searchFolders">
<property name="text">
<string>Folders</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Content</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QGroupBox" name="groupBox_4">
<property name="title">
<string>File contains:</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLineEdit" name="contentPattern"/>
</item>
<item>
<widget class="QCheckBox" name="contentCaseInsensitive">
<property name="text">
<string>Case insensiti&amp;ve</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="contentRegExp">
<property name="text">
<string>&amp;Use regular expression</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>186</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_4">
<attribute name="title">
<string>Properties</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_10">
<item>
<widget class="QGroupBox" name="groupBox_5">
<property name="title">
<string>File Size:</string>
</property>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QCheckBox" name="largerThan">
<property name="text">
<string>Larger than:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="minSize"/>
</item>
<item>
<widget class="QComboBox" name="minSizeUnit">
<property name="currentIndex">
<number>2</number>
</property>
<item>
<property name="text">
<string>Bytes</string>
</property>
</item>
<item>
<property name="text">
<string>KiB</string>
</property>
</item>
<item>
<property name="text">
<string>MiB</string>
</property>
</item>
<item>
<property name="text">
<string>GiB</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="smallerThan">
<property name="text">
<string>Smaller than:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSpinBox" name="maxSize"/>
</item>
<item>
<widget class="QComboBox" name="maxSizeUnit">
<property name="currentIndex">
<number>2</number>
</property>
<item>
<property name="text">
<string>Bytes</string>
</property>
</item>
<item>
<property name="text">
<string>KiB</string>
</property>
</item>
<item>
<property name="text">
<string>MiB</string>
</property>
</item>
<item>
<property name="text">
<string>GiB</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_6">
<property name="title">
<string>Last Modified Time:</string>
</property>
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="earlierThan">
<property name="text">
<string>Earlier than:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="laterThan">
<property name="text">
<string>Later than:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDateEdit" name="maxTime">
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QDateEdit" name="minTime">
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget>
</item>
<item>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>SearchDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>SearchDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -0,0 +1,143 @@
/*
* Copyright (C) 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
*
* 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 "filesearchdialog.h"
#include <QMessageBox>
#include "fm-search.h"
#include "ui_filesearch.h"
#include <limits>
#include <QFileDialog>
namespace Fm {
FileSearchDialog::FileSearchDialog(QStringList paths, QWidget* parent, Qt::WindowFlags f):
QDialog(parent, f),
ui(new Ui::SearchDialog()) {
ui->setupUi(this);
ui->minSize->setMaximum(std::numeric_limits<int>().max());
ui->maxSize->setMaximum(std::numeric_limits<int>().max());
Q_FOREACH(const QString& path, paths) {
ui->listView->addItem(path);
}
ui->maxTime->setDate(QDate::currentDate());
ui->minTime->setDate(QDate::currentDate());
connect(ui->addPath, &QPushButton::clicked, this, &FileSearchDialog::onAddPath);
connect(ui->removePath, &QPushButton::clicked, this, &FileSearchDialog::onRemovePath);
}
FileSearchDialog::~FileSearchDialog() {
delete ui;
}
void FileSearchDialog::accept() {
// build the search:/// uri
int n = ui->listView->count();
if(n > 0) {
FmSearch* search = fm_search_new();
int i;
for(i = 0; i < n; ++i) { // add directories
QListWidgetItem* item = ui->listView->item(i);
fm_search_add_dir(search, item->text().toLocal8Bit().constData());
}
fm_search_set_recursive(search, ui->recursiveSearch->isChecked());
fm_search_set_show_hidden(search, ui->searchHidden->isChecked());
fm_search_set_name_patterns(search, ui->namePatterns->text().toUtf8().constData());
fm_search_set_name_ci(search, ui->nameCaseInsensitive->isChecked());
fm_search_set_name_regex(search, ui->nameRegExp->isChecked());
fm_search_set_content_pattern(search, ui->contentPattern->text().toUtf8().constData());
fm_search_set_content_ci(search, ui->contentCaseInsensitive->isChecked());
fm_search_set_content_regex(search, ui->contentRegExp->isChecked());
// search for the files of specific mime-types
if(ui->searchTextFiles->isChecked())
fm_search_add_mime_type(search, "text/plain");
if(ui->searchImages->isChecked())
fm_search_add_mime_type(search, "image/*");
if(ui->searchAudio->isChecked())
fm_search_add_mime_type(search, "audio/*");
if(ui->searchVideo->isChecked())
fm_search_add_mime_type(search, "video/*");
if(ui->searchFolders->isChecked())
fm_search_add_mime_type(search, "inode/directory");
if(ui->searchDocuments->isChecked()) {
const char* doc_types[] = {
"application/pdf",
/* "text/html;" */
"application/vnd.oasis.opendocument.*",
"application/vnd.openxmlformats-officedocument.*",
"application/msword;application/vnd.ms-word",
"application/msexcel;application/vnd.ms-excel"
};
for(i = 0; i < sizeof(doc_types)/sizeof(char*); ++i)
fm_search_add_mime_type(search, doc_types[i]);
}
// search based on file size
const unsigned int unit_bytes[] = {1, (1024), (1024*1024), (1024*1024*1024)};
if(ui->largerThan->isChecked()) {
guint64 size = ui->minSize->value() * unit_bytes[ui->minSizeUnit->currentIndex()];
fm_search_set_min_size(search, size);
}
if(ui->smallerThan->isChecked()) {
guint64 size = ui->maxSize->value() * unit_bytes[ui->maxSizeUnit->currentIndex()];
fm_search_set_min_size(search, size);
}
// search based on file mtime (we only support date in YYYY-MM-DD format)
if(ui->earlierThan->isChecked()) {
fm_search_set_max_mtime(search, ui->maxTime->date().toString(QStringLiteral("yyyy-MM-dd")).toUtf8().constData());
}
if(ui->laterThan->isChecked()) {
fm_search_set_min_mtime(search, ui->minTime->date().toString(QStringLiteral("yyyy-MM-dd")).toUtf8().constData());
}
searchUri_.take(fm_search_dup_path(search));
fm_search_free(search);
}
else {
QMessageBox::critical(this, tr("Error"), tr("You should add at least add one directory to search."));
return;
}
QDialog::accept();
}
void FileSearchDialog::onAddPath() {
QString dir = QFileDialog::getExistingDirectory(this, tr("Select a folder"));
if(dir.isEmpty())
return;
// avoid adding duplicated items
if(ui->listView->findItems(dir, Qt::MatchFixedString|Qt::MatchCaseSensitive).isEmpty()) {
ui->listView->addItem(dir);
}
}
void FileSearchDialog::onRemovePath() {
// remove selected items
Q_FOREACH(QListWidgetItem* item, ui->listView->selectedItems()) {
delete item;
}
}
}

@ -0,0 +1,56 @@
/*
* Copyright (C) 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
*
* 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
*
*/
#ifndef FM_FILESEARCHDIALOG_H
#define FM_FILESEARCHDIALOG_H
#include "libfmqtglobals.h"
#include <QDialog>
#include "path.h"
namespace Ui {
class SearchDialog;
}
namespace Fm {
class LIBFM_QT_API FileSearchDialog : public QDialog
{
public:
FileSearchDialog(QStringList paths = QStringList(), QWidget * parent = 0, Qt::WindowFlags f = 0);
~FileSearchDialog();
Path searchUri() const {
return searchUri_;
}
virtual void accept();
private Q_SLOTS:
void onAddPath();
void onRemovePath();
private:
Ui::SearchDialog* ui;
Path searchUri_;
};
}
#endif // FM_FILESEARCHDIALOG_H

@ -0,0 +1,317 @@
/*
* fm-search-uri.c
*
* Copyright 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
* Copyright 2012-2014 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
*
* 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) any later version.
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#include "fm-search.h"
#include <string.h>
struct _FmSearch
{
gboolean recursive;
gboolean show_hidden;
char* name_patterns;
gboolean name_ci;
gboolean name_regex;
char* content_pattern;
gboolean content_ci;
gboolean content_regex;
GList* mime_types;
GList* search_path_list;
guint64 max_size;
guint64 min_size;
char* max_mtime;
char* min_mtime;
};
FmSearch* fm_search_new (void)
{
FmSearch* search = (FmSearch*)g_slice_new0(FmSearch);
return search;
}
void fm_search_free(FmSearch* search)
{
g_list_free_full(search->mime_types, (GDestroyNotify)g_free);
g_list_free_full(search->search_path_list, (GDestroyNotify)g_free);
g_free(search->name_patterns);
g_free(search->content_pattern);
g_free(search->max_mtime);
g_free(search->min_mtime);
g_slice_free(FmSearch, search);
}
gboolean fm_search_get_recursive(FmSearch* search)
{
return search->recursive;
}
void fm_search_set_recursive(FmSearch* search, gboolean recursive)
{
search->recursive = recursive;
}
gboolean fm_search_get_show_hidden(FmSearch* search)
{
return search->show_hidden;
}
void fm_search_set_show_hidden(FmSearch* search, gboolean show_hidden)
{
search->show_hidden = show_hidden;
}
const char* fm_search_get_name_patterns(FmSearch* search)
{
return search->name_patterns;
}
void fm_search_set_name_patterns(FmSearch* search, const char* name_patterns)
{
g_free(search->name_patterns);
search->name_patterns = g_strdup(name_patterns);
}
gboolean fm_search_get_name_ci(FmSearch* search)
{
return search->name_ci;
}
void fm_search_set_name_ci(FmSearch* search, gboolean name_ci)
{
search->name_ci = name_ci;
}
gboolean fm_search_get_name_regex(FmSearch* search)
{
return search->name_regex;
}
void fm_search_set_name_regex(FmSearch* search, gboolean name_regex)
{
search->name_regex = name_regex;
}
const char* fm_search_get_content_pattern(FmSearch* search)
{
return search->content_pattern;
}
void fm_search_set_content_pattern(FmSearch* search, const char* content_pattern)
{
g_free(search->content_pattern);
search->content_pattern = g_strdup(content_pattern);
}
gboolean fm_search_get_content_ci(FmSearch* search)
{
return search->content_ci;
}
void fm_search_set_content_ci(FmSearch* search, gboolean content_ci)
{
search->content_ci = content_ci;
}
gboolean fm_search_get_content_regex(FmSearch* search)
{
return search->content_regex;
}
void fm_search_set_content_regex(FmSearch* search, gboolean content_regex)
{
search->content_regex = content_regex;
}
void fm_search_add_dir(FmSearch* search, const char* dir)
{
GList* l = g_list_find_custom(search->search_path_list, dir, (GCompareFunc)strcmp);
if(!l)
search->search_path_list = g_list_prepend(search->search_path_list, g_strdup(dir));
}
void fm_search_remove_dir(FmSearch* search, const char* dir)
{
GList* l = g_list_find_custom(search->search_path_list, dir, (GCompareFunc)strcmp);
if(G_LIKELY(l))
{
g_free(l->data);
search->search_path_list = g_list_delete_link(search->search_path_list, l);
}
}
GList* fm_search_get_dirs(FmSearch* search)
{
return search->search_path_list;
}
void fm_search_add_mime_type(FmSearch* search, const char* mime_type)
{
GList* l = g_list_find_custom(search->mime_types, mime_type, (GCompareFunc)strcmp);
if(!l)
search->mime_types = g_list_prepend(search->mime_types, g_strdup(mime_type));
}
void fm_search_remove_mime_type(FmSearch* search, const char* mime_type)
{
GList* l = g_list_find_custom(search->mime_types, mime_type, (GCompareFunc)strcmp);
if(G_LIKELY(l))
{
g_free(l->data);
search->mime_types = g_list_delete_link(search->mime_types, l);
}
}
GList* fm_search_get_mime_types(FmSearch* search)
{
return search->mime_types;
}
guint64 fm_search_get_max_size(FmSearch* search)
{
return search->max_size;
}
void fm_search_set_max_size(FmSearch* search, guint64 size)
{
search->max_size = size;
}
guint64 fm_search_get_min_size(FmSearch* search)
{
return search->min_size;
}
void fm_search_set_min_size(FmSearch* search, guint64 size)
{
search->min_size = size;
}
/* format of mtime: YYYY-MM-DD */
const char* fm_search_get_max_mtime(FmSearch* search)
{
return search->max_mtime;
}
void fm_search_set_max_mtime(FmSearch* search, const char* mtime)
{
g_free(search->max_mtime);
search->max_mtime = g_strdup(mtime);
}
/* format of mtime: YYYY-MM-DD */
const char* fm_search_get_min_mtime(FmSearch* search)
{
return search->min_mtime;
}
void fm_search_set_min_mtime(FmSearch* search, const char* mtime)
{
g_free(search->min_mtime);
search->min_mtime = g_strdup(mtime);
}
/* really build the path */
FmPath* fm_search_dup_path(FmSearch* search)
{
FmPath* search_path = NULL;
GString* search_str = g_string_sized_new(1024);
/* build the search:// URI to perform the search */
g_string_append(search_str, "search://");
if(search->search_path_list) /* we need to have at least one dir path */
{
char *escaped;
/* add paths */
GList* l;
for(l = search->search_path_list; ; )
{
char *path_str = (char*)l->data;
/* escape possible '?' and ',' */
escaped = g_uri_escape_string(path_str, "!$&'()*+:;=/@", TRUE);
g_string_append(search_str, escaped);
g_free(escaped);
l = l->next;
if(!l) /* no more items */
break;
g_string_append_c(search_str, ','); /* separator for paths */
}
g_string_append_c(search_str, '?');
g_string_append_printf(search_str, "recursive=%c", search->recursive ? '1' : '0');
g_string_append_printf(search_str, "&show_hidden=%c", search->show_hidden ? '1' : '0');
if(search->name_patterns && *search->name_patterns)
{
/* escape ampersands in pattern */
escaped = g_uri_escape_string(search->name_patterns, ":/?#[]@!$'()*+,;", TRUE);
if(search->name_regex)
g_string_append_printf(search_str, "&name_regex=%s", escaped);
else
g_string_append_printf(search_str, "&name=%s", escaped);
if(search->name_ci)
g_string_append_printf(search_str, "&name_ci=%c", search->name_ci ? '1' : '0');
g_free(escaped);
}
if(search->content_pattern && *search->content_pattern)
{
/* escape ampersands in pattern */
escaped = g_uri_escape_string(search->content_pattern, ":/?#[]@!$'()*+,;^<>{}", TRUE);
if(search->content_regex)
g_string_append_printf(search_str, "&content_regex=%s", escaped);
else
g_string_append_printf(search_str, "&content=%s", escaped);
g_free(escaped);
if(search->content_ci)
g_string_append_printf(search_str, "&content_ci=%c", search->content_ci ? '1' : '0');
}
/* search for the files of specific mime-types */
if(search->mime_types)
{
GList* l;
g_string_append(search_str, "&mime_types=");
for(l = search->mime_types; l; l=l->next)
{
const char* mime_type = (const char*)l->data;
g_string_append(search_str, mime_type);
if(l->next)
g_string_append_c(search_str, ';');
}
}
if(search->min_size)
g_string_append_printf(search_str, "&min_size=%llu", search->min_size);
if(search->max_size)
g_string_append_printf(search_str, "&max_size=%llu", search->max_size);
if(search->min_mtime)
g_string_append_printf(search_str, "&min_mtime=%s", search->min_mtime);
if(search->max_mtime)
g_string_append_printf(search_str, "&max_mtime=%s", search->max_mtime);
search_path = fm_path_new_for_uri(search_str->str);
g_string_free(search_str, TRUE);
}
return search_path;
}

@ -0,0 +1,88 @@
/*
* fm-search-uri.h
*
* Copyright 2015 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
*
* 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) any later version.
*
* 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
/* FmSearch implements a tool used to generate a search:// URI used by libfm to search for files.
* This API might become part of libfm in the future.
*/
#ifndef _FM_SEARCH_H_
#define _FM_SEARCH_H_
#include <libfm/fm.h>
G_BEGIN_DECLS
typedef struct _FmSearch FmSearch;
FmSearch* fm_search_new(void);
void fm_search_free(FmSearch* search);
FmPath* fm_search_dup_path(FmSearch* search);
gboolean fm_search_get_recursive(FmSearch* search);
void fm_search_set_recursive(FmSearch* search, gboolean recursive);
gboolean fm_search_get_show_hidden(FmSearch* search);
void fm_search_set_show_hidden(FmSearch* search, gboolean show_hidden);
const char* fm_search_get_name_patterns(FmSearch* search);
void fm_search_set_name_patterns(FmSearch* search, const char* name_patterns);
gboolean fm_search_get_name_ci(FmSearch* search);
void fm_search_set_name_ci(FmSearch* search, gboolean name_ci);
gboolean fm_search_get_name_regex(FmSearch* search);
void fm_search_set_name_regex(FmSearch* search, gboolean name_regex);
const char* fm_search_get_content_pattern(FmSearch* search);
void fm_search_set_content_pattern(FmSearch* search, const char* content_pattern);
gboolean fm_search_get_content_ci(FmSearch* search);
void fm_search_set_content_ci(FmSearch* search, gboolean content_ci);
gboolean fm_search_get_content_regex(FmSearch* search);
void fm_search_set_content_regex(FmSearch* search, gboolean content_regex);
void fm_search_add_dir(FmSearch* search, const char* dir);
void fm_search_remove_dir(FmSearch* search, const char* dir);
GList* fm_search_get_dirs(FmSearch* search);
void fm_search_add_mime_type(FmSearch* search, const char* mime_type);
void fm_search_remove_mime_type(FmSearch* search, const char* mime_type);
GList* fm_search_get_mime_types(FmSearch* search);
guint64 fm_search_get_max_size(FmSearch* search);
void fm_search_set_max_size(FmSearch* search, guint64 size);
guint64 fm_search_get_min_size(FmSearch* search);
void fm_search_set_min_size(FmSearch* search, guint64 size);
/* format of mtime: YYYY-MM-DD */
const char* fm_search_get_max_mtime(FmSearch* search);
void fm_search_set_max_mtime(FmSearch* search, const char* mtime);
/* format of mtime: YYYY-MM-DD */
const char* fm_search_get_min_mtime(FmSearch* search);
void fm_search_set_min_mtime(FmSearch* search, const char* mtime);
G_END_DECLS
#endif /* _FM_SEARCH_H_ */

@ -188,6 +188,12 @@ public:
return fm_path_hash(data_);
}
void take(FmPath* path) { // take the ownership of the "path"
if(data_)
fm_path_unref(data_);
data_ = path;
}
Path& operator = (const Path& other) {
if(data_)
fm_path_unref(data_);

@ -322,6 +322,8 @@ void PlacesView::onEjectVolume() {
void PlacesView::contextMenuEvent(QContextMenuEvent* event) {
QModelIndex index = indexAt(event->pos());
if(index.isValid() && index.parent().isValid()) {
if(index.column() != 0) // the real item is at column 0
index = index.sibling(index.row(), 0);
QMenu* menu = new QMenu(this);
QAction* action;
PlacesModelItem* item = static_cast<PlacesModelItem*>(model_->itemFromIndex(index));

@ -118,6 +118,12 @@ bool ProxyFolderModel::lessThan(const QModelIndex& left, const QModelIndex& righ
FmFileInfo* leftInfo = srcModel->fileInfoFromIndex(left);
FmFileInfo* rightInfo = srcModel->fileInfoFromIndex(right);
if(Q_UNLIKELY(!leftInfo || !rightInfo)) {
// In theory, this should not happen, but it's safer to add the null check.
// This is reported in https://github.com/lxde/pcmanfm-qt/issues/205
return false;
}
if(folderFirst_) {
bool leftIsFolder = (bool)fm_file_info_is_dir(leftInfo);
bool rightIsFolder = (bool)fm_file_info_is_dir(rightInfo);

@ -1,4 +0,0 @@
[Project]
Manager=KDevCMakeManager
Name=pcmanfm-qt
VersionControl=

@ -42,6 +42,7 @@
#include "mountoperation.h"
#include "autorundialog.h"
#include "launcher.h"
#include "filesearchdialog.h"
#include <QScreen>
#include <QWindow>
@ -113,8 +114,8 @@ Application::~Application() {
g_object_unref(volumeMonitor_);
}
if(enableDesktopManager_)
removeNativeEventFilter(this);
// if(enableDesktopManager_)
// removeNativeEventFilter(this);
}
bool Application::parseCommandLineArgs() {
@ -311,7 +312,7 @@ void Application::desktopManager(bool enabled) {
QDesktopWidget* desktopWidget = desktop();
if(enabled) {
if(!enableDesktopManager_) {
installNativeEventFilter(this);
// installNativeEventFilter(this);
Q_FOREACH(QScreen* screen, screens()) {
connect(screen, &QScreen::virtualGeometryChanged, this, &Application::onVirtualGeometryChanged);
connect(screen, &QObject::destroyed, this, &Application::onScreenDestroyed);
@ -352,7 +353,7 @@ void Application::desktopManager(bool enabled) {
disconnect(screen, &QObject::destroyed, this, &Application::onScreenDestroyed);
}
disconnect(this, &QApplication::screenAdded, this, &Application::onScreenAdded);
removeNativeEventFilter(this);
// removeNativeEventFilter(this);
}
}
enableDesktopManager_ = enabled;
@ -369,9 +370,22 @@ void Application::desktopPrefrences(QString page) {
desktopPreferencesDialog_.data()->activateWindow();
}
void Application::onFindFileAccepted() {
Fm::FileSearchDialog* dlg = static_cast<Fm::FileSearchDialog*>(sender());
Fm::Path uri = dlg->searchUri();
// FIXME: we should be able to open it in an existing window
FmPathList* paths = fm_path_list_new();
fm_path_list_push_tail(paths, uri.data());
Launcher(NULL).launchPaths(NULL, paths);
fm_path_list_unref(paths);
}
void Application::findFiles(QStringList paths) {
// TODO: add a file searching utility here.
qDebug("findFiles");
// launch file searching utility.
Fm::FileSearchDialog* dlg = new Fm::FileSearchDialog(paths);
connect(dlg, &QDialog::accepted, this, &Application::onFindFileAccepted);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
}
void Application::launchFiles(QString cwd, QStringList paths, bool inNewWindow) {
@ -635,17 +649,18 @@ void Application::onVolumeAdded(GVolumeMonitor* monitor, GVolume* volume, Applic
pThis->autoMountVolume(volume, true);
}
#if 0
bool Application::nativeEventFilter(const QByteArray & eventType, void * message, long * result) {
if(eventType == "xcb_generic_event_t") { // XCB event
// filter all native X11 events (xcb)
xcb_generic_event_t* generic_event = reinterpret_cast<xcb_generic_event_t*>(message);
// qDebug("XCB event: %d", generic_event->response_type & ~0x80);
Q_FOREACH(DesktopWindow * window, desktopWindows_) {
window->xcbEvent(generic_event);
}
}
return false;
}
#endif
void Application::onScreenAdded(QScreen* newScreen) {
if(enableDesktopManager_) {

@ -25,7 +25,6 @@
#include "settings.h"
#include "libfmqt.h"
#include "editbookmarksdialog.h"
#include <QAbstractNativeEventFilter>
#include <QVector>
#include <QPointer>
#include <QProxyStyle>
@ -49,7 +48,7 @@ public:
virtual int styleHint(StyleHint hint, const QStyleOption * option = 0, const QWidget * widget = 0, QStyleHintReturn * returnData = 0) const;
};
class Application : public QApplication, public QAbstractNativeEventFilter {
class Application : public QApplication {
Q_OBJECT
Q_PROPERTY(bool desktopManagerEnabled READ desktopManagerEnabled)
@ -75,7 +74,7 @@ public:
void desktopPrefrences(QString page);
void editBookmarks();
void desktopManager(bool enabled);
void findFiles(QStringList paths);
void findFiles(QStringList paths = QStringList());
bool desktopManagerEnabled() {
return enableDesktopManager_;
@ -91,8 +90,6 @@ public:
return profileName_;
}
virtual bool nativeEventFilter(const QByteArray & eventType, void * message, long * result);
protected Q_SLOTS:
void onAboutToQuit();
void onSigtermNotified();
@ -108,6 +105,8 @@ protected Q_SLOTS:
void onScreenAdded(QScreen* newScreen);
void reloadDesktopsAsNeeded();
void onFindFileAccepted();
protected:
virtual bool eventFilter(QObject* watched, QEvent* event);
bool parseCommandLineArgs();

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>473</width>
<height>428</height>
<width>501</width>
<height>376</height>
</rect>
</property>
<property name="windowTitle">
@ -200,6 +200,19 @@
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="advancedPage">

@ -389,49 +389,6 @@ void DesktopWindow::prepareFolderMenu(Fm::FolderMenu* menu) {
connect(action, &QAction::triggered, this, &DesktopWindow::onDesktopPreferences);
}
void DesktopWindow::xcbEvent(xcb_generic_event_t* generic_event) {
int event_type = generic_event->response_type & ~0x80;
if(showWmMenu_) {
// If we want to show the desktop menus provided by the window manager instead of ours,
// we have to forward the mouse events we received to the root window.
switch(event_type) {
case XCB_BUTTON_PRESS: {
xcb_button_press_event_t* event = reinterpret_cast<xcb_button_press_event_t*>(generic_event);
if(event->event == effectiveWinId()) {
// check if the user click on blank area
QModelIndex index = listView_->indexAt(QPoint(event->event_x, event->event_y));
if(!index.isValid()) {
xcb_ungrab_pointer(QX11Info::connection(), event->time);
// forward the event to the root window
xcb_button_press_event_t event2 = *event;
WId root = QX11Info::appRootWindow(QX11Info::appScreen());
event2.event = root;
xcb_send_event(QX11Info::connection(), 0, root, XCB_EVENT_MASK_BUTTON_PRESS, (char*)&event2);
}
}
break;
}
case XCB_BUTTON_RELEASE: {
xcb_button_release_event_t* event = reinterpret_cast<xcb_button_release_event_t*>(generic_event);
if(event->event == effectiveWinId()) {
// check if the user click on blank area
QModelIndex index = listView_->indexAt(QPoint(event->event_x, event->event_y));
if(!index.isValid()) {
// forward the event to the root window
xcb_button_release_event_t event2 = *event;
WId root = QX11Info::appRootWindow(QX11Info::appScreen());
event2.event = root;
xcb_send_event(QX11Info::connection(), 0, root, XCB_EVENT_MASK_BUTTON_RELEASE, (char*)&event2);
}
}
break;
}
default:
break;
}
}
}
void DesktopWindow::onDesktopPreferences() {
static_cast<Application* >(qApp)->desktopPrefrences(QString());
}
@ -675,6 +632,69 @@ void DesktopWindow::onFilePropertiesActivated() {
}
}
static void forwardMouseEventToRoot(QMouseEvent* event) {
xcb_ungrab_pointer(QX11Info::connection(), event->timestamp());
// forward the event to the root window
xcb_button_press_event_t xcb_event;
uint32_t mask = 0;
xcb_event.state = 0;
switch(event->type()) {
case QEvent::MouseButtonPress:
xcb_event.response_type = XCB_BUTTON_PRESS;
mask = XCB_EVENT_MASK_BUTTON_PRESS;
break;
case QEvent::MouseButtonRelease:
xcb_event.response_type = XCB_BUTTON_RELEASE;
mask = XCB_EVENT_MASK_BUTTON_RELEASE;
break;
default:
return;
}
// convert Qt button to XCB button
switch(event->button()) {
case Qt::LeftButton:
xcb_event.detail = 1;
xcb_event.state |= XCB_BUTTON_MASK_1;
break;
case Qt::MiddleButton:
xcb_event.detail = 2;
xcb_event.state |= XCB_BUTTON_MASK_2;
break;
case Qt::RightButton:
xcb_event.detail = 3;
xcb_event.state |= XCB_BUTTON_MASK_3;
break;
default:
xcb_event.detail = 0;
}
// convert Qt modifiers to XCB states
if(event->modifiers() & Qt::ShiftModifier)
xcb_event.state |= XCB_MOD_MASK_SHIFT;
if(event->modifiers() & Qt::ControlModifier)
xcb_event.state |= XCB_MOD_MASK_SHIFT;
if(event->modifiers() & Qt::AltModifier)
xcb_event.state |= XCB_MOD_MASK_1;
xcb_event.sequence = 0;
xcb_event.time = event->timestamp();
WId root = QX11Info::appRootWindow(QX11Info::appScreen());
xcb_event.event = root;
xcb_event.root = root;
xcb_event.child = 0;
xcb_event.root_x = event->globalX();
xcb_event.root_y = event->globalY();
xcb_event.event_x = event->x();
xcb_event.event_y = event->y();
xcb_event.same_screen = 1;
xcb_send_event(QX11Info::connection(), 0, root, mask, (char*)&xcb_event);
xcb_flush(QX11Info::connection());
}
bool DesktopWindow::event(QEvent* event)
{
switch(event->type()) {
@ -721,6 +741,25 @@ bool DesktopWindow::eventFilter(QObject * watched, QEvent * event) {
break;
}
}
else if(watched == listView_->viewport()) {
switch(event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
if(showWmMenu_) {
QMouseEvent* e = static_cast<QMouseEvent*>(event);
// If we want to show the desktop menus provided by the window manager instead of ours,
// we have to forward the mouse events we received to the root window.
// check if the user click on blank area
QModelIndex index = listView_->indexAt(e->pos());
if(!index.isValid() && e->button() != Qt::LeftButton) {
forwardMouseEventToRoot(e);
}
}
break;
default:
break;
}
}
return false;
}

@ -66,8 +66,6 @@ public:
void updateWallpaper();
void updateFromSettings(Settings& settings);
void xcbEvent(xcb_generic_event_t* generic_event);
void queueRelayout(int delay = 0);
int screenNum() const {

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>431</width>
<height>359</height>
<height>416</height>
</rect>
</property>
<property name="windowTitle">
@ -76,7 +76,9 @@
<string>Add</string>
</property>
<property name="icon">
<iconset theme="list-add"/>
<iconset theme="list-add">
<normaloff/>
</iconset>
</property>
</widget>
</item>
@ -86,7 +88,9 @@
<string>Remove</string>
</property>
<property name="icon">
<iconset theme="list-remove"/>
<iconset theme="list-remove">
<normaloff/>
</iconset>
</property>
</widget>
</item>
@ -125,9 +129,6 @@
</widget>
</item>
</layout>
<zorder>buttonBox</zorder>
<zorder>groupBox</zorder>
<zorder>groupBox_2</zorder>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
@ -256,7 +257,7 @@
<property name="title">
<string>File Size</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<layout class="QFormLayout" name="formLayout_3">
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_12">
<property name="text">
@ -265,18 +266,22 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QSpinBox" name="spinBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="comboBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QSpinBox" name="spinBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_13">
@ -286,18 +291,22 @@
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_2">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="comboBox_2">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QSpinBox" name="spinBox_2">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboBox_2">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
@ -307,7 +316,7 @@
<property name="title">
<string>Last Modified Time</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<layout class="QFormLayout" name="formLayout_2">
<item row="0" column="0">
<widget class="QCheckBox" name="checkBox_14">
<property name="text">
@ -315,6 +324,16 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDateTimeEdit" name="dateTimeEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="checkBox_15">
<property name="text">
@ -332,16 +351,6 @@
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QDateTimeEdit" name="dateTimeEdit">
<property name="enabled">
<bool>false</bool>
</property>
<property name="calendarPopup">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>

@ -20,7 +20,16 @@
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<property name="margin">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
@ -67,7 +76,7 @@
<x>0</x>
<y>0</y>
<width>460</width>
<height>27</height>
<height>23</height>
</rect>
</property>
<widget class="QMenu" name="menu_File">
@ -171,6 +180,7 @@
</property>
<addaction name="actionOpenTerminal"/>
<addaction name="actionOpenAsRoot"/>
<addaction name="actionFindFiles"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_Editw"/>
@ -227,7 +237,7 @@
</iconset>
</property>
<property name="text">
<string>Home</string>
<string>&amp;Home</string>
</property>
<property name="shortcut">
<string>Alt+Home</string>
@ -447,7 +457,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Ascending</string>
<string>&amp;Ascending</string>
</property>
</action>
<action name="actionDescending">
@ -455,7 +465,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Descending</string>
<string>&amp;Descending</string>
</property>
</action>
<action name="actionByFileName">
@ -463,7 +473,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>By File Name</string>
<string>&amp;By File Name</string>
</property>
</action>
<action name="actionByMTime">
@ -471,7 +481,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>By Modification Time</string>
<string>By &amp;Modification Time</string>
</property>
</action>
<action name="actionByFileType">
@ -479,7 +489,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>By File Type</string>
<string>By File &amp;Type</string>
</property>
</action>
<action name="actionByOwner">
@ -487,7 +497,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>By Owner</string>
<string>By &amp;Owner</string>
</property>
</action>
<action name="actionFolderFirst">
@ -495,7 +505,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Folder First</string>
<string>&amp;Folder First</string>
</property>
</action>
<action name="actionNewTab">
@ -598,7 +608,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Case Sensitive</string>
<string>&amp;Case Sensitive</string>
</property>
</action>
<action name="actionByFileSize">
@ -606,12 +616,12 @@
<bool>true</bool>
</property>
<property name="text">
<string>By File Size</string>
<string>By File &amp;Size</string>
</property>
</action>
<action name="actionCloseWindow">
<property name="text">
<string>Close Window</string>
<string>&amp;Close Window</string>
</property>
</action>
<action name="actionEdit_Bookmarks">
@ -639,10 +649,12 @@
</action>
<action name="actionNewFolder">
<property name="icon">
<iconset theme="folder-new"/>
<iconset theme="folder-new">
<normaloff/>
</iconset>
</property>
<property name="text">
<string>Folder</string>
<string>&amp;Folder</string>
</property>
<property name="shortcut">
<string>Ctrl+Shift+N</string>
@ -650,15 +662,25 @@
</action>
<action name="actionNewBlankFile">
<property name="icon">
<iconset theme="document-new"/>
<iconset theme="document-new">
<normaloff/>
</iconset>
</property>
<property name="text">
<string>Blank File</string>
<string>&amp;Blank File</string>
</property>
<property name="shortcut">
<string>Ctrl+Alt+N</string>
</property>
</action>
<action name="actionFindFiles">
<property name="text">
<string>&amp;Find Files</string>
</property>
<property name="shortcut">
<string>F3</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>

@ -949,6 +949,25 @@ void MainWindow::on_actionOpenAsRoot_triggered() {
}
}
void MainWindow::on_actionFindFiles_triggered() {
Application* app = static_cast<Application*>(qApp);
FmPathList* selectedPaths = currentPage()->selectedFilePaths();
QStringList paths;
if(selectedPaths) {
for(GList* l = fm_path_list_peek_head_link(selectedPaths); l; l = l->next) {
// FIXME: is it ok to use display name here?
// This might be broken on filesystems with non-UTF-8 filenames.
Fm::Path path(FM_PATH(l->data));
paths.append(path.displayName(false));
}
fm_path_list_unref(selectedPaths);
}
else {
paths.append(currentPage()->pathName());
}
app->findFiles(paths);
}
void MainWindow::on_actionOpenTerminal_triggered() {
TabPage* page = currentPage();
if(page) {

@ -109,6 +109,7 @@ protected Q_SLOTS:
void on_actionOpenTerminal_triggered();
void on_actionOpenAsRoot_triggered();
void on_actionFindFiles_triggered();
void on_actionAbout_triggered();

Loading…
Cancel
Save