Solved How to open directory in file manager and highlight specific item in it ?
-
Hi everyone,
I want to implement "Open Containing Folder" kinda thing. If someone doesn't know, it's like I want to open a directory in filemanager in which specific file/folder would be highlighted.
In linux, freedesktop dbus specification[0] has "ShowItems" method to attain such behaviour but I don't have any idea about other operating systems.Does anyone has any idea about it ? I tried to find but wasn't able to find any Qt API which performs such action.
[0] http://www.freedesktop.org/wiki/Specifications/file-manager-interface/
Regards,
Ashish Bansal -
@ashishbansal Apparently QtCreator does such a thing, so have a look around its code to find how it does that and just copy it to your project.
-
@raf924 said:
@ashishbansal Apparently QtCreator does such a thing, so have a look around its code to find how it does that and just copy it to your project.
But it only opens up directory doesn't highlight that item on which I pressed "Show Containing folder".
-
@ashishbansal I just tried it on Qt Creator 3.4.2 on Windows and it does highlight the item.
-
@raf924 said:
@ashishbansal I just tried it on Qt Creator 3.4.2 on Windows and it does highlight the item.
But not on linux :|
-
@ashishbansal Oh but you already have a solution for Linux don't you?
-
@raf924 said:
@ashishbansal Oh but you already have a solution for Linux don't you?
Yeah I have that but I was looking for better alternative if possible like something in-built API in Qt.
BTW what about Mac OS. -
@ashishbansal FOund this in the source of qBittorent:
void Utils::Misc::openFolderSelect(const QString& absolutePath) { const QString path = Utils::Fs::fromNativePath(absolutePath); #ifdef Q_OS_WIN if (QFileInfo(path).exists()) { // Syntax is: explorer /select, "C:\Folder1\Folder2\file_to_select" // Dir separators MUST be win-style slashes // QProcess::startDetached() has an obscure bug. If the path has // no spaces and a comma(and maybe other special characters) it doesn't // get wrapped in quotes. So explorer.exe can't find the correct path and // displays the default one. If we wrap the path in quotes and pass it to // QProcess::startDetached() explorer.exe still shows the default path. In // this case QProcess::startDetached() probably puts its own quotes around ours. STARTUPINFO startupInfo; ::ZeroMemory(&startupInfo, sizeof(startupInfo)); startupInfo.cb = sizeof(startupInfo); PROCESS_INFORMATION processInfo; ::ZeroMemory(&processInfo, sizeof(processInfo)); QString cmd = QString("explorer.exe /select,\"%1\"").arg(Utils::Fs::toNativePath(absolutePath)); LPWSTR lpCmd = new WCHAR[cmd.size() + 1]; cmd.toWCharArray(lpCmd); lpCmd[cmd.size()] = 0; bool ret = ::CreateProcessW(NULL, lpCmd, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo); delete [] lpCmd; if (ret) { ::CloseHandle(processInfo.hProcess); ::CloseHandle(processInfo.hThread); } } else { // If the item to select doesn't exist, try to open its parent openPath(path.left(path.lastIndexOf("/"))); } #elif defined(Q_OS_UNIX) && !defined(Q_OS_MAC) if (QFileInfo(path).exists()) { QProcess proc; QString output; proc.start("xdg-mime", QStringList() << "query" << "default" << "inode/directory"); proc.waitForFinished(); output = proc.readLine().simplified(); if (output == "dolphin.desktop" || output == "org.kde.dolphin.desktop") proc.startDetached("dolphin", QStringList() << "--select" << Utils::Fs::toNativePath(path)); else if (output == "nautilus.desktop" || output == "org.gnome.Nautilus.desktop" || output == "nautilus-folder-handler.desktop") proc.startDetached("nautilus", QStringList() << "--no-desktop" << Utils::Fs::toNativePath(path)); else if (output == "caja-folder-handler.desktop") proc.startDetached("caja", QStringList() << "--no-desktop" << Utils::Fs::toNativePath(path)); else if (output == "nemo.desktop") proc.startDetached("nemo", QStringList() << "--no-desktop" << Utils::Fs::toNativePath(path)); else if (output == "kfmclient_dir.desktop") proc.startDetached("konqueror", QStringList() << "--select" << Utils::Fs::toNativePath(path)); else openPath(path.left(path.lastIndexOf("/"))); } else { // If the item to select doesn't exist, try to open its parent openPath(path.left(path.lastIndexOf("/"))); } #else openPath(path.left(path.lastIndexOf("/"))); #endif }
-
@raf924 said:
@ashishbansal FOund this in the source of qBittorent:
void Utils::Misc::openFolderSelect(const QString& absolutePath) { const QString path = Utils::Fs::fromNativePath(absolutePath); #ifdef Q_OS_WIN if (QFileInfo(path).exists()) { // Syntax is: explorer /select, "C:\Folder1\Folder2\file_to_select" // Dir separators MUST be win-style slashes // QProcess::startDetached() has an obscure bug. If the path has // no spaces and a comma(and maybe other special characters) it doesn't // get wrapped in quotes. So explorer.exe can't find the correct path and // displays the default one. If we wrap the path in quotes and pass it to // QProcess::startDetached() explorer.exe still shows the default path. In // this case QProcess::startDetached() probably puts its own quotes around ours. STARTUPINFO startupInfo; ::ZeroMemory(&startupInfo, sizeof(startupInfo)); startupInfo.cb = sizeof(startupInfo); PROCESS_INFORMATION processInfo; ::ZeroMemory(&processInfo, sizeof(processInfo)); QString cmd = QString("explorer.exe /select,\"%1\"").arg(Utils::Fs::toNativePath(absolutePath)); LPWSTR lpCmd = new WCHAR[cmd.size() + 1]; cmd.toWCharArray(lpCmd); lpCmd[cmd.size()] = 0; bool ret = ::CreateProcessW(NULL, lpCmd, NULL, NULL, FALSE, 0, NULL, NULL, &startupInfo, &processInfo); delete [] lpCmd; if (ret) { ::CloseHandle(processInfo.hProcess); ::CloseHandle(processInfo.hThread); } } else { // If the item to select doesn't exist, try to open its parent openPath(path.left(path.lastIndexOf("/"))); } #elif defined(Q_OS_UNIX) && !defined(Q_OS_MAC) if (QFileInfo(path).exists()) { QProcess proc; QString output; proc.start("xdg-mime", QStringList() << "query" << "default" << "inode/directory"); proc.waitForFinished(); output = proc.readLine().simplified(); if (output == "dolphin.desktop" || output == "org.kde.dolphin.desktop") proc.startDetached("dolphin", QStringList() << "--select" << Utils::Fs::toNativePath(path)); else if (output == "nautilus.desktop" || output == "org.gnome.Nautilus.desktop" || output == "nautilus-folder-handler.desktop") proc.startDetached("nautilus", QStringList() << "--no-desktop" << Utils::Fs::toNativePath(path)); else if (output == "caja-folder-handler.desktop") proc.startDetached("caja", QStringList() << "--no-desktop" << Utils::Fs::toNativePath(path)); else if (output == "nemo.desktop") proc.startDetached("nemo", QStringList() << "--no-desktop" << Utils::Fs::toNativePath(path)); else if (output == "kfmclient_dir.desktop") proc.startDetached("konqueror", QStringList() << "--select" << Utils::Fs::toNativePath(path)); else openPath(path.left(path.lastIndexOf("/"))); } else { // If the item to select doesn't exist, try to open its parent openPath(path.left(path.lastIndexOf("/"))); } #else openPath(path.left(path.lastIndexOf("/"))); #endif }
Thanks. It seems that it would solve the problem :)