ports/167466: New port: x11-fm/qtfm A small, lightweight file manager based on pure Qt
Zhihao Yuan
lichray at gmail.com
Tue May 1 01:10:12 UTC 2012
>Number: 167466
>Category: ports
>Synopsis: New port: x11-fm/qtfm A small, lightweight file manager based on pure Qt
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: freebsd-ports-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Tue May 01 01:10:11 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator: Zhihao Yuan
>Release: FreeBSD 8.3-PRERELEASE amd64
>Organization:
Northern Illinois University
>Environment:
System: FreeBSD elitebook.hp 8.3-PRERELEASE FreeBSD 8.3-PRERELEASE #0 r234564: Sun Apr 22 04:30:51 CDT 2012 lichray at elitebook.hp:/usr/obj/usr/src/sys/HOUKAGO amd64
>Description:
A small file manager which only depends on QtGui and QtNetwork (no modern hal, polkit, etc.).
http://www.qtfm.org/
>How-To-Repeat:
>Fix:
1. <sys/vfs.h> -> <sys/mount.h>;
2. inotify -> QFileSystemWatcher (reported to upstream);
3. /proc/self/mtab watching -> kevent EVFILT_FS in a thread;
4. /proc/self/mtab parsing -> getmntinfo(3) (reported).
--- qtfm.shar begins here ---
# This is a shell archive. Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file". Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
# qtfm
# qtfm/files
# qtfm/files/patch-src_propertiesdlg.cpp
# qtfm/files/patch-src_mainwindow.cpp
# qtfm/files/patch-src_mymodel.cpp
# qtfm/files/patch-src_mymodel.h
# qtfm/files/patch-src_mainwindow.h
# qtfm/files/patch-src_bookmarks.cpp
# qtfm/files/patch-qtfm.pro
# qtfm/distinfo
# qtfm/pkg-plist
# qtfm/Makefile
# qtfm/pkg-descr
#
echo c - qtfm
mkdir -p qtfm > /dev/null 2>&1
echo c - qtfm/files
mkdir -p qtfm/files > /dev/null 2>&1
echo x - qtfm/files/patch-src_propertiesdlg.cpp
sed 's/^X//' >qtfm/files/patch-src_propertiesdlg.cpp << '0d9d84c92531dcafeec4d9768cc602f0'
X--- src/propertiesdlg.cpp~ 2012-03-08 20:34:27.000000000 -0600
X+++ src/propertiesdlg.cpp 2012-04-29 06:49:57.546488947 -0500
X@@ -23,7 +23,11 @@
X #include "propertiesdlg.h"
X #include "icondlg.h"
X #include "mainwindow.h"
X+#ifdef __FreeBSD__
X+#include <sys/mount.h>
X+#else
X #include <sys/vfs.h>
X+#endif
X #include <sys/stat.h>
X #include <magic.h>
X
0d9d84c92531dcafeec4d9768cc602f0
echo x - qtfm/files/patch-src_mainwindow.cpp
sed 's/^X//' >qtfm/files/patch-src_mainwindow.cpp << '44433c87ac59d95ad45b8753666563a1'
X--- src/mainwindow.cpp.orig 2012-03-11 10:11:28.000000000 -0500
X+++ src/mainwindow.cpp 2012-04-29 23:06:06.481938775 -0500
X@@ -21,7 +21,11 @@
X
X
X #include <QtGui>
X+#ifdef __FreeBSD__
X+#include <sys/mount.h>
X+#else
X #include <sys/vfs.h>
X+#endif
X #include <fcntl.h>
X
X #include "mainwindow.h"
X@@ -280,10 +284,15 @@ void MainWindow::lateStart()
X customMapper = new QSignalMapper();
X connect(customMapper, SIGNAL(mapped(QString)),this, SLOT(actionMapper(QString)));
X
X+#ifdef __FreeBSD__
X+ worker = new MountWorker();
X+ worker->setParent(this);
X+ worker->start(QThread::IdlePriority);
X+#else
X int fd = open("/proc/self/mounts",O_RDONLY,0);
X notify = new QSocketNotifier(fd,QSocketNotifier::Write);
X connect(notify, SIGNAL(activated(int)), this, SLOT(mountWatcherTriggered()),Qt::QueuedConnection);
X-
X+#endif
X
X term = settings->value("term").toString();
X progress = 0;
X@@ -336,6 +345,9 @@ void MainWindow::closeEvent(QCloseEvent
X {
X writeSettings();
X
X+#ifdef __FreeBSD__
X+ worker->close();
X+#endif
X if(isDaemon)
X {
X this->setVisible(0);
X@@ -1839,7 +1851,7 @@ void MainWindow::actionMapper(QString cm
X QString exec = temp.at(0);
X temp.removeAt(0);
X
X- temp.replaceInStrings("\\","\ ");
X+ temp.replaceInStrings("\\"," ");
X
X QProcess *customProcess = new QProcess();
X customProcess->setWorkingDirectory(pathEdit->itemText(0));
44433c87ac59d95ad45b8753666563a1
echo x - qtfm/files/patch-src_mymodel.cpp
sed 's/^X//' >qtfm/files/patch-src_mymodel.cpp << '9d571fc377e081220ac31ba2da3641ae'
X--- src/mymodel.cpp.orig 2012-03-09 05:00:54.000000000 -0600
X+++ src/mymodel.cpp 2012-04-29 16:13:57.725169164 -0500
X@@ -21,7 +21,6 @@
X
X #include <mainwindow.h>
X #include "mymodel.h"
X-#include <sys/inotify.h>
X #include <unistd.h>
X #include <sys/ioctl.h>
X
X@@ -63,9 +62,8 @@ myModel::myModel(bool realMime)
X
X iconFactory = new QFileIconProvider();
X
X- inotifyFD = inotify_init();
X- notifier = new QSocketNotifier(inotifyFD, QSocketNotifier::Read, this);
X- connect(notifier, SIGNAL(activated(int)), this, SLOT(notifyChange()));
X+ watcher = new QFileSystemWatcher(this);
X+ connect(watcher, SIGNAL(directoryChanged(QString)), this, SLOT(notifyChange(QString)));
X
X realMimeTypes = realMime;
X }
X@@ -188,28 +186,9 @@ QString myModel::getMimeType(const QMode
X }
X
X //---------------------------------------------------------------------------------------
X-void myModel::notifyChange()
X+void myModel::notifyChange(QString const& path)
X {
X- notifier->setEnabled(0);
X-
X- int buffSize = 0;
X- ioctl(inotifyFD, FIONREAD, (char *) &buffSize);
X-
X- QByteArray buffer;
X- buffer.resize(buffSize);
X- read(inotifyFD,buffer.data(),buffSize);
X- const char *at = buffer.data();
X- const char * const end = at + buffSize;
X-
X- while (at < end)
X- {
X- const inotify_event *event = reinterpret_cast<const inotify_event *>(at);
X-
X- int w = event->wd;
X-
X- if(watchers.contains(w))
X- {
X- myModelItem *parent = rootItem->matchPath(watchers.value(w).split(SEPARATOR));
X+ myModelItem *parent = rootItem->matchPath(path.split(SEPARATOR));
X
X if(parent)
X {
X@@ -230,9 +209,7 @@ void myModel::notifyChange()
X //must of been deleted, remove from model
X if(child->fileInfo().isDir())
X {
X- int wd = watchers.key(child->absoluteFilePath());
X- inotify_rm_watch(inotifyFD,wd);
X- watchers.remove(wd);
X+ watcher->removePath(child->absoluteFilePath());
X }
X beginRemoveRows(index(parent->absoluteFilePath()),child->childNumber(),child->childNumber());
X parent->removeChild(child);
X@@ -249,23 +226,17 @@ void myModel::notifyChange()
X }
X else
X {
X- inotify_rm_watch(inotifyFD,w);
X- watchers.remove(w);
X+ watcher->removePath(path);
X }
X- }
X-
X- at += sizeof(inotify_event) + event->len;
X- }
X-
X- notifier->setEnabled(1);
X }
X
X //---------------------------------------------------------------------------------
X-void myModel::addWatcher(myModelItem *item)
X+void myModel::addToWatcher(myModelItem *item)
X {
X while(item != rootItem)
X {
X- watchers.insert(inotify_add_watch(inotifyFD, item->absoluteFilePath().toLocal8Bit(), IN_MOVE | IN_CREATE | IN_DELETE),item->absoluteFilePath()); //IN_ONESHOT | IN_ALL_EVENTS)
X+ if (!watcher->directories().contains(item->absoluteFilePath()))
X+ watcher->addPath(item->absoluteFilePath());
X item->watched = 1;
X item = item->parent();
X }
X@@ -278,7 +249,7 @@ bool myModel::setRootPath(const QString&
X
X myModelItem *item = rootItem->matchPath(path.split(SEPARATOR));
X
X- if(item->watched == 0) addWatcher(item);
X+ if(item->watched == 0) addToWatcher(item);
X
X if(item->walked == 0)
X {
X@@ -352,10 +323,7 @@ void myModel::refresh()
X {
X myModelItem *item = rootItem->matchPath(QStringList("/"));
X
X- //free all inotify watches
X- foreach(int w, watchers.keys())
X- inotify_rm_watch(inotifyFD,w);
X- watchers.clear();
X+ watcher->removePaths(watcher->directories());
X
X beginResetModel();
X item->clearAll();
X@@ -811,9 +779,7 @@ bool myModel::remove(const QModelIndex &
X QFileInfo info(children.at(i));
X if(info.isDir())
X {
X- int wd = watchers.key(info.filePath());
X- inotify_rm_watch(inotifyFD,wd);
X- watchers.remove(wd);
X+ watcher->removePath(info.filePath());
X error |= QDir().rmdir(info.filePath());
X }
X else error |= QFile::remove(info.filePath());
9d571fc377e081220ac31ba2da3641ae
echo x - qtfm/files/patch-src_mymodel.h
sed 's/^X//' >qtfm/files/patch-src_mymodel.h << '348051303f98ef66c477a24b73c44bb7'
X--- src/mymodel.h.orig 2012-03-09 00:47:45.000000000 -0600
X+++ src/mymodel.h 2012-04-29 13:59:45.508571462 -0500
X@@ -83,8 +83,8 @@ public:
X bool realMimeTypes;
X
X public slots:
X- void notifyChange();
X- void addWatcher(myModelItem* path);
X+ void notifyChange(QString const& path);
X+ void addToWatcher(myModelItem* path);
X
X signals:
X void dragDropPaste(const QMimeData * data, QString newPath, QStringList cutList);
X@@ -113,9 +113,7 @@ private:
X QString currentRootPath;
X QFileIconProvider* iconFactory;
X
X- int inotifyFD;
X- QSocketNotifier *notifier;
X- QHash<int, QString> watchers;
X+ QFileSystemWatcher *watcher;
X };
X
X #endif // MYMODEL_H
348051303f98ef66c477a24b73c44bb7
echo x - qtfm/files/patch-src_mainwindow.h
sed 's/^X//' >qtfm/files/patch-src_mainwindow.h << 'e39b4aa67f496c46c3ceac79fb4fcf6e'
X--- src/mainwindow.h.orig 2012-03-08 04:46:39.000000000 -0600
X+++ src/mainwindow.h 2012-04-29 22:53:06.754026702 -0500
X@@ -146,6 +146,15 @@ private:
X void writeSettings();
X void recurseFolder(QString path, QString parent, QStringList *);
X
X+ class MountWorker : public QThread
X+ {
X+ bool ahead;
X+ protected:
X+ void run();
X+ public:
X+ void close();
X+ };
X+
X int zoom;
X int zoomTree;
X int zoomList;
X@@ -182,7 +191,11 @@ private:
X bookmarkmodel *modelBookmarks;
X QItemSelectionModel *treeSelectionModel;
X QItemSelectionModel *listSelectionModel;
X+#ifdef __FreeBSD__
X+ MountWorker *worker;
X+#else
X QSocketNotifier *notify;
X+#endif
X
X QStringList mounts;
X
e39b4aa67f496c46c3ceac79fb4fcf6e
echo x - qtfm/files/patch-src_bookmarks.cpp
sed 's/^X//' >qtfm/files/patch-src_bookmarks.cpp << '554b56483885fcf897b06e19cd7606b9'
X--- src/bookmarks.cpp.orig 2012-03-08 04:46:39.000000000 -0600
X+++ src/bookmarks.cpp 2012-04-30 14:20:26.157046128 -0500
X@@ -22,6 +22,11 @@
X #ifndef BOOKMARKS_CPP
X #define BOOKMARKS_CPP
X
X+#ifdef __FreeBSD__
X+#include <sys/event.h>
X+#include <sys/mount.h>
X+#endif
X+
X #include <QtGui>
X #include "bookmarkmodel.h"
X #include "icondlg.h"
X@@ -80,42 +85,74 @@ void MainWindow::mountWatcherTriggered()
X }
X
X //---------------------------------------------------------------------------
X+#ifdef __FreeBSD__
X+void MainWindow::MountWorker::run()
X+{
X+
X+ ahead = 1;
X+ int kq = kqueue();
X+ struct kevent ki[1];
X+ struct timespec to[1] = {{ 0, 100000 }};
X+
X+ EV_SET(ki, 0, EVFILT_FS, EV_ADD, VQ_MOUNT | VQ_UNMOUNT, 0, 0);
X+ kevent(kq, ki, 1, NULL, 0, NULL);
X+
X+ while (ahead) {
X+ switch (kevent(kq, NULL, 0, ki, 1, to)) {
X+ case -1:
X+ ::perror("kevent");
X+ break;
X+ case 0:
X+ continue;
X+ default:
X+ ((MainWindow *)parent())->MainWindow::autoBookmarkMounts();
X+ }
X+ }
X+ ::close(kq);
X+}
X+
X+void MainWindow::MountWorker::close()
X+{
X+ ahead = 0;
X+ wait();
X+}
X+#endif
X+
X+//---------------------------------------------------------------------------
X void MainWindow::autoBookmarkMounts()
X {
X QList<QStandardItem *> theBookmarks = modelBookmarks->findItems("*",Qt::MatchWildcard);
X
X QStringList autoBookmarks;
X
X+ size_t mntsize;
X+ struct statfs *mnt, *mntbuf;
X+
X foreach(QStandardItem *item, theBookmarks)
X {
X if(item->data(34).toString() == "1") //is an automount
X autoBookmarks.append(item->data(32).toString());
X }
X
X- QStringList mtabMounts;
X- QFile mtab("/etc/mtab");
X- mtab.open(QFile::ReadOnly);
X- QTextStream stream(&mtab);
X- do mtabMounts.append(stream.readLine());
X- while (!stream.atEnd());
X- mtab.close();
X+ mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
X
X QStringList dontShowList = settings->value("hideBookmarks",0).toStringList();
X mounts.clear();
X
X- foreach(QString item, mtabMounts)
X- if(item[0] == '/')
X+ for (mnt = mntbuf; mntsize > 0; mntsize--, mnt++)
X+ // XXX zpool name does not start with /
X+ if (mnt->f_mntfromname[0] == '/' or !strcmp(mnt->f_fstypename, "zfs"))
X {
X- QString path = item.split(" ").at(1);
X- path.replace("\\040"," ");
X-
X- mounts.append(path);
X- if(!dontShowList.contains(path))
X- if(!autoBookmarks.contains(path)) //add a new auto bookmark if it doesn't exist
X+ mounts.append(mnt->f_mntonname);
X+ if(!dontShowList.contains(mnt->f_mntonname))
X+ //add a new auto bookmark if it doesn't exist
X+ if(!autoBookmarks.contains(mnt->f_mntonname))
X {
X- if(item.split(" ").at(2) == "iso9660") modelBookmarks->addBookmark(path,path,"1","drive-optical");
X- else if(item.split(" ").at(2).contains("fat")) modelBookmarks->addBookmark(path,path,"1","drive-removable-media");
X- else modelBookmarks->addBookmark(path,path,"1","drive-harddisk");
X+ if(strstr(mnt->f_fstypename, "9660"))
X+ modelBookmarks->addBookmark(mnt->f_mntonname,mnt->f_mntonname,"1","drive-optical");
X+ else if(strstr(mnt->f_fstypename, "fat"))
X+ modelBookmarks->addBookmark(mnt->f_mntonname,mnt->f_mntonname,"1","drive-removable-media");
X+ else modelBookmarks->addBookmark(mnt->f_mntonname,mnt->f_mntonname,"1","drive-harddisk");
X }
X }
X
554b56483885fcf897b06e19cd7606b9
echo x - qtfm/files/patch-qtfm.pro
sed 's/^X//' >qtfm/files/patch-qtfm.pro << '539ce90923915e57a4d8da9176a33b82'
X--- qtfm.pro.orig 2012-04-30 17:08:07.093692960 -0500
X+++ qtfm.pro 2012-04-30 17:48:49.433021364 -0500
X@@ -55,7 +55,7 @@ trans.files += translations/qtfm_da.qm \
X translations/qtfm_zh.qm \
X translations/qtfm_zh_TW.qm
X
X-INSTALLS += target desktop icon docs trans
X+INSTALLS += target desktop icon trans
X
X
X
539ce90923915e57a4d8da9176a33b82
echo x - qtfm/distinfo
sed 's/^X//' >qtfm/distinfo << '2e77555e3ee02543739b10879fbce1af'
XSHA256 (qtfm-5.4.tar.gz) = 8ef4c2464502959944e1b2476aa635b2a889d2859ba62dd61d8f591779c6fd0d
XSIZE (qtfm-5.4.tar.gz) = 147293
2e77555e3ee02543739b10879fbce1af
echo x - qtfm/pkg-plist
sed 's/^X//' >qtfm/pkg-plist << '2aa18a46886aa40174f24aeaf10ceb63'
Xbin/qtfm
Xshare/applications/qtfm.desktop
Xshare/pixmaps/qtfm.png
X%%DATADIR%%/qtfm_da.qm
X%%DATADIR%%/qtfm_de.qm
X%%DATADIR%%/qtfm_es.qm
X%%DATADIR%%/qtfm_fr.qm
X%%DATADIR%%/qtfm_it.qm
X%%DATADIR%%/qtfm_pl.qm
X%%DATADIR%%/qtfm_ru.qm
X%%DATADIR%%/qtfm_sr.qm
X%%DATADIR%%/qtfm_zh.qm
X%%DATADIR%%/qtfm_zh_TW.qm
X at dirrm %%DATADIR%%
2aa18a46886aa40174f24aeaf10ceb63
echo x - qtfm/Makefile
sed 's/^X//' >qtfm/Makefile << 'def7cb58bb8db47afc7f6c9ef8ce34cd'
X# New ports collection makefile for: qtfm
X# Date created: 29 Apr 2012
X# Whom: Zhihao Yuan <lichray at gmail.com>
X#
X# $FreeBSD$
X#
X
XPORTNAME= qtfm
XDISTVERSION= 5.4
XCATEGORIES= x11-fm
XMASTER_SITES= http://www.qtfm.org/
X
XMAINTAINER= lichray at gmail.com
XCOMMENT= A small, lightweight file manager based on pure Qt
X
XLICENSE= GPLv2
XLICENSE_FILE= ${WRKSRC}/COPYING
X
XUSE_DOS2UNIX= yes
XUSE_QT_VER= 4
XQT_COMPONENTS= gui network qmake_build moc_build rcc_build
X
XMAKE_JOBS_SAFE= yes
XSTRIP_FILES= bin/qtfm
X
Xpost-patch:
X @cd ${WRKSRC} && \
X ${REINPLACE_CMD} -e s@/usr/@${PREFIX}/@g \
X qtfm.pro src/main.cpp
X @cd ${WRKSRC}/src && \
X ${REINPLACE_CMD} -e s@/usr/@${LOCALBASE}/@g \
X icondlg.cpp mainwindow.cpp mymodel.cpp
X
Xdo-configure:
X @cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${QMAKE} \
X ${QMAKEFLAGS} qtfm.pro
X
Xpost-install:
X ${STRIP_CMD} ${STRIP_FILES:S,^,${PREFIX}/,}
X
X.include <bsd.port.mk>
def7cb58bb8db47afc7f6c9ef8ce34cd
echo x - qtfm/pkg-descr
sed 's/^X//' >qtfm/pkg-descr << 'c8a167a29c6b1c2f721eaf16c674b5d9'
XqtFM is a small, lightweight file manager for Linux desktops based on pure Qt
Xand works great with minimal desktop environments like Openbox.
X
XWWW: http://www.qtfm.org/
c8a167a29c6b1c2f721eaf16c674b5d9
exit
--- qtfm.shar ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-ports-bugs
mailing list