Date: Mon, 30 Apr 2012 18:05:53 -0700 (PDT) From: Zhihao Yuan <lichray@gmail.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: ports/167466: New port: x11-fm/qtfm A small, lightweight file manager based on pure Qt Message-ID: <4f9f36f1.447ab60a.784b.ffffed55@mx.google.com> Resent-Message-ID: <201205010110.q411ABEt047038@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>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@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@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@gmail.com> X# X# $FreeBSD$ X# X XPORTNAME= qtfm XDISTVERSION= 5.4 XCATEGORIES= x11-fm XMASTER_SITES= http://www.qtfm.org/ X XMAINTAINER= lichray@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:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4f9f36f1.447ab60a.784b.ffffed55>