mirror of https://gitee.com/openkylin/peony.git
315 lines
8.5 KiB
C++
315 lines
8.5 KiB
C++
/*
|
|
* Peony-Qt's Library
|
|
*
|
|
* Copyright (C) 2020, KylinSoft Co., Ltd.
|
|
*
|
|
* 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 3 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 General Public License
|
|
* along with this library. If not, see <https://www.gnu.org/licenses/>.
|
|
*
|
|
* Authors: Yue Lan <lanyue@kylinos.cn>
|
|
*
|
|
*/
|
|
#include <gio/gunixmounts.h>
|
|
#include "file-info.h"
|
|
|
|
#include "file-info-manager.h"
|
|
#include "file-info-job.h"
|
|
#include "file-meta-info.h"
|
|
#include "file-utils.h"
|
|
#include "thumbnail-manager.h"
|
|
#include "emblem-provider.h"
|
|
|
|
#include <QUrl>
|
|
#include <QDir>
|
|
#include <QDebug>
|
|
|
|
using namespace Peony;
|
|
|
|
FileInfo::FileInfo(QObject *parent) : QObject (parent)
|
|
{
|
|
m_cancellable = g_cancellable_new();
|
|
}
|
|
|
|
FileInfo::FileInfo(const QString &uri, QObject *parent) : QObject (parent)
|
|
{
|
|
m_cancellable = g_cancellable_new();
|
|
/*!
|
|
* \note
|
|
* In qt program we alwas handle file's uri format as unicode,
|
|
* but in glib/gio it might be not.
|
|
* I want to keep the uri strings format in peony-qt,
|
|
* this would help me avoid some problem, such as the uri path completion
|
|
* bug in PathBarModel enumeration.
|
|
*/
|
|
m_uri = uri;
|
|
m_file = g_file_new_for_uri(uri.toUtf8().constData());
|
|
m_parent = g_file_get_parent(m_file);
|
|
m_is_remote = !g_file_is_native(m_file);
|
|
m_is_dir = false;
|
|
m_is_volume = false;
|
|
m_meta_info = FileMetaInfo::fromGFileInfo(uri, nullptr);
|
|
GFileType type = g_file_query_file_type(m_file, G_FILE_QUERY_INFO_NONE, nullptr);
|
|
switch (type) {
|
|
case G_FILE_TYPE_DIRECTORY:
|
|
//qDebug()<<"dir";
|
|
m_is_dir = true;
|
|
break;
|
|
case G_FILE_TYPE_MOUNTABLE:
|
|
//qDebug()<<"mountable";
|
|
m_is_volume = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
FileInfo::~FileInfo()
|
|
{
|
|
ThumbnailManager::getInstance()->releaseThumbnail(m_uri);
|
|
EmblemProviderManager::getInstance()->cancelQuery(m_uri);
|
|
//qDebug()<<"~FileInfo"<<m_uri;
|
|
disconnect();
|
|
|
|
g_object_unref(m_cancellable);
|
|
g_object_unref(m_file);
|
|
|
|
if (m_parent)
|
|
g_object_unref(m_parent);
|
|
|
|
m_uri = nullptr;
|
|
}
|
|
|
|
std::shared_ptr<FileInfo> FileInfo::fromUri(QString uri)
|
|
{
|
|
FileInfoManager *info_manager = FileInfoManager::getInstance();
|
|
// avoid using binding mount original uri. link to: #48982.
|
|
if (info_manager->isAutoParted()) {
|
|
if (uri.contains("file:///data/home")) {
|
|
uri.replace("file:///data/home", "file:///home");
|
|
}
|
|
}
|
|
info_manager->lock();
|
|
std::shared_ptr<FileInfo> info = info_manager->findFileInfoByUri(uri);
|
|
if (info != nullptr) {
|
|
info_manager->unlock();
|
|
return info;
|
|
} else {
|
|
std::shared_ptr<FileInfo> newly_info = std::make_shared<FileInfo>();
|
|
|
|
newly_info->m_uri = uri;
|
|
newly_info->m_file = g_file_new_for_uri(uri.toUtf8().constData());
|
|
|
|
newly_info->m_parent = g_file_get_parent(newly_info->m_file);
|
|
newly_info->m_is_remote = ! g_file_is_native(newly_info->m_file);
|
|
newly_info->m_is_dir = false;
|
|
newly_info->m_is_volume = false;
|
|
newly_info->m_meta_info = FileMetaInfo::fromGFileInfo(uri, nullptr);
|
|
if (! newly_info->m_is_remote && false) {
|
|
GFileType type = g_file_query_file_type(newly_info->m_file, G_FILE_QUERY_INFO_NONE, nullptr);
|
|
switch (type) {
|
|
case G_FILE_TYPE_DIRECTORY:
|
|
//qDebug()<<"dir";
|
|
newly_info->m_is_dir = true;
|
|
break;
|
|
case G_FILE_TYPE_MOUNTABLE:
|
|
//qDebug()<<"mountable";
|
|
newly_info->m_is_volume = true;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
newly_info = info_manager->insertFileInfo(newly_info);
|
|
info_manager->unlock();
|
|
return newly_info;
|
|
}
|
|
}
|
|
|
|
std::shared_ptr<FileInfo> FileInfo::fromPath(QString path)
|
|
{
|
|
QString uri = "file://" + path;
|
|
return fromUri(uri);
|
|
}
|
|
|
|
std::shared_ptr<FileInfo> FileInfo::fromGFile(GFile *file)
|
|
{
|
|
char *uri_str = g_file_get_uri(file);
|
|
QString uri = uri_str;
|
|
g_free(uri_str);
|
|
return fromUri(uri);
|
|
}
|
|
|
|
/*******
|
|
函数功能:判断文件是否是视频文件
|
|
一般的视频文件都是 video/*,但是有些视频文件比较特殊
|
|
比如:
|
|
asf : application/vnd.ms-asf
|
|
rmvb: application/vnd.rn-realmedia
|
|
swf : application/vnd.adobe.flash.movie
|
|
ts : text/vnd.trolltech.linguist
|
|
h264: application/octet-stream
|
|
目前上面这些是已经测试到的视频文件类型,如果有没有覆盖到的情况后面再补充
|
|
**/
|
|
bool FileInfo::isVideoFile()
|
|
{
|
|
if (nullptr != m_mime_type_string)
|
|
{
|
|
if (m_mime_type_string.startsWith("video")
|
|
|| m_mime_type_string.endsWith("vnd.trolltech.linguist")
|
|
|| m_mime_type_string.endsWith("vnd.adobe.flash.movie")
|
|
|| m_mime_type_string.endsWith("vnd.rn-realmedia")
|
|
|| m_mime_type_string.endsWith("vnd.ms-asf")
|
|
|| m_mime_type_string.endsWith("octet-stream"))
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
bool FileInfo::isOfficeFile()
|
|
{
|
|
int idx = 0;
|
|
QString mtype = nullptr;
|
|
|
|
for (idx = 0; office_mime_types[idx] != "end"; idx++)
|
|
{
|
|
mtype = office_mime_types[idx];
|
|
if (m_mime_type_string.contains(mtype))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
const QString FileInfo::targetUri()
|
|
{
|
|
return m_target_uri;
|
|
}
|
|
|
|
const QString FileInfo::symlinkTarget()
|
|
{
|
|
if (m_symlink_target == ".")
|
|
return "";
|
|
|
|
//fix soft link use relative path issue, link to bug#73529
|
|
if (! m_symlink_target.startsWith("/"))
|
|
{
|
|
QString parentUri = FileUtils::getParentUri(m_uri);
|
|
m_symlink_target = QUrl(parentUri).path() + "/" + m_symlink_target;
|
|
}
|
|
return m_symlink_target;
|
|
}
|
|
|
|
const QString FileInfo::customIcon()
|
|
{
|
|
if (!m_meta_info)
|
|
return nullptr;
|
|
return m_meta_info.get()->getMetaInfoString("custom-icon");
|
|
}
|
|
|
|
quint64 FileInfo::getDeletionDateUInt64()
|
|
{
|
|
return m_deletion_date_uint64;
|
|
}
|
|
|
|
const QString FileInfo::unixDeviceFile()
|
|
{
|
|
GFile* file;
|
|
const char *path;
|
|
bool isMountPoint;
|
|
GUnixMountEntry* entry;
|
|
char* device = nullptr;
|
|
QString unixDevice = nullptr;
|
|
|
|
isMountPoint = FileUtils::isMountPoint(m_uri);
|
|
//return from here if @m_uri is like "computer:///xxx"
|
|
if(!isMountPoint)
|
|
return m_unix_device_file;
|
|
|
|
//query device path if @m_uri is like "file:///media/user/xxx"
|
|
file = g_file_new_for_uri(m_uri.toUtf8().constData());
|
|
if(!file)
|
|
return unixDevice;
|
|
|
|
path = g_file_peek_path(file);
|
|
if(path){
|
|
entry = g_unix_mount_at(path,NULL);
|
|
if(!entry)
|
|
entry = g_unix_mount_for(path,NULL);
|
|
|
|
if(entry){
|
|
device = g_strescape(g_unix_mount_get_device_path(entry),NULL);
|
|
g_unix_mount_free(entry);
|
|
}
|
|
}
|
|
|
|
unixDevice = device;
|
|
g_object_unref(file);
|
|
if(device)
|
|
g_free(device);
|
|
|
|
return unixDevice;
|
|
}
|
|
|
|
const QString FileInfo::displayName()
|
|
{
|
|
if (isEmptyInfo())
|
|
return nullptr;
|
|
bool isMountPoint;
|
|
QString unixDevice,deviceName;
|
|
|
|
unixDevice = unixDeviceFile();
|
|
isMountPoint = FileUtils::isMountPoint(m_uri);
|
|
|
|
QString targetUri = FileUtils::getTargetUri(m_uri);
|
|
if(m_uri == "file:///DATA"
|
|
|| m_uri == "file:///data"
|
|
|| targetUri == "file:///data")
|
|
{
|
|
return tr("data");
|
|
}
|
|
|
|
if((nullptr != m_display_name)
|
|
&& (!isMountPoint
|
|
|| unixDevice.isEmpty() /*@m_uri is like "computer:///xxx"*/
|
|
|| !unixDevice.contains("/dev") /*audio-cd*/
|
|
|| unixDevice.contains("/dev/sr"))) { /*blank-cd or blank-dvd*/
|
|
return m_display_name;
|
|
}
|
|
|
|
if (m_uri.endsWith("/")) {
|
|
QString uri = m_uri;
|
|
if (!m_uri.endsWith(":///") && !m_uri.endsWith("://")) {
|
|
uri.chop(1);
|
|
}
|
|
return uri.split("/").last();
|
|
}
|
|
|
|
//@deviceName transcoding
|
|
deviceName = m_display_name;
|
|
FileUtils::handleVolumeLabelForFat32(deviceName,unixDevice);
|
|
return deviceName;
|
|
}
|