/*
* Copyright (C) 2013 Open Education Foundation
*
* Copyright (C) 2010-2013 Groupement d'Intérêt Public pour
* l'Education Numérique en Afrique (GIP ENA)
*
* This file is part of OpenBoard.
*
* OpenBoard 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, version 3 of the License,
* with a specific linking exception for the OpenSSL project's
* "OpenSSL" library (or with modified versions of it that use the
* same license as the "OpenSSL" library).
*
* OpenBoard 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 OpenBoard. If not, see .
*/
#include
#include
#include
#include "core/UBApplication.h"
#include "board/UBBoardController.h"
#include "UBFeaturesController.h"
#include "core/UBSettings.h"
#include "tools/UBToolsManager.h"
#include "frameworks/UBFileSystemUtils.h"
#include "frameworks/UBPlatformUtils.h"
#include "core/UBDownloadManager.h"
#include "domain/UBGraphicsScene.h"
#include "domain/UBGraphicsSvgItem.h"
#include "domain/UBGraphicsPixmapItem.h"
#include "domain/UBGraphicsWidgetItem.h"
#include "gui/UBFeaturesWidget.h"
const QString UBFeaturesController::virtualRootName = "root";
const QString UBFeaturesController::rootPath = "/" + virtualRootName;
const QString UBFeaturesController::appPath = rootPath + "/Applications";
const QString UBFeaturesController::audiosPath = rootPath + "/Audios";
const QString UBFeaturesController::moviesPath = rootPath + "/Movies";
const QString UBFeaturesController::picturesPath = rootPath + "/Pictures";
const QString UBFeaturesController::flashPath = rootPath + "/Animations";
const QString UBFeaturesController::interactPath = rootPath + "/Interactivities";
const QString UBFeaturesController::shapesPath = rootPath + "/Shapes";
const QString UBFeaturesController::trashPath = rootPath + "/Trash";
const QString UBFeaturesController::favoritePath = rootPath + "/Favorites";
const QString UBFeaturesController::webSearchPath = rootPath + "/Web search";
void UBFeaturesComputingThread::scanFS(const QUrl & currentPath, const QString & currVirtualPath, const QSet &pFavoriteSet)
{
// Q_ASSERT(QFileInfo(currentPath.toLocalFile()).exists());
// if(QFileInfo(currentPath.toLocalFile()).exists())
// return;
QFileInfoList fileInfoList = UBFileSystemUtils::allElementsInDirectory(currentPath.toLocalFile());
QFileInfoList::iterator fileInfo;
for ( fileInfo = fileInfoList.begin(); fileInfo != fileInfoList.end(); fileInfo += 1) {
if (abort) {
return;
}
QString fullFileName = fileInfo->absoluteFilePath();
UBFeatureElementType featureType = UBFeaturesController::fileTypeFromUrl(fullFileName);
QString fileName = fileInfo->fileName();
QImage icon = UBFeaturesController::getIcon(fullFileName, featureType);
if ( fullFileName.contains(".thumbnail."))
continue;
UBFeature testFeature(currVirtualPath + "/" + fileName, icon, fileName, QUrl::fromLocalFile(fullFileName), featureType);
emit sendFeature(testFeature);
emit featureSent();
emit scanPath(fullFileName);
if ( pFavoriteSet.find(QUrl::fromLocalFile(fullFileName)) != pFavoriteSet.end()) {
//TODO send favoritePath from the controller or make favoritePath public and static
emit sendFeature(UBFeature( UBFeaturesController::favoritePath + "/" + fileName, icon, fileName, QUrl::fromLocalFile(fullFileName), featureType));
}
if (featureType == FEATURE_FOLDER) {
scanFS(QUrl::fromLocalFile(fullFileName), currVirtualPath + "/" + fileName, pFavoriteSet);
}
}
}
void UBFeaturesComputingThread::scanAll(QList > pScanningData, const QSet &pFavoriteSet)
{
for (int i = 0; i < pScanningData.count(); i++) {
if (abort) {
return;
}
QPair curPair = pScanningData.at(i);
emit scanCategory(curPair.second.getDisplayName());
scanFS(curPair.first, curPair.second.getFullVirtualPath(), pFavoriteSet);
}
}
int UBFeaturesComputingThread::featuresCount(const QUrl &pPath)
{
int noItems = 0;
QFileInfoList fileInfoList = UBFileSystemUtils::allElementsInDirectory(pPath.toLocalFile());
QFileInfoList::iterator fileInfo;
for ( fileInfo = fileInfoList.begin(); fileInfo != fileInfoList.end(); fileInfo += 1) {
QString fullFileName = fileInfo->absoluteFilePath();
UBFeatureElementType featureType = UBFeaturesController::fileTypeFromUrl(fullFileName);
if (featureType != FEATURE_INVALID && !fullFileName.contains(".thumbnail.")) {
noItems++;
}
if (featureType == FEATURE_FOLDER) {
noItems += featuresCount(QUrl::fromLocalFile(fullFileName));
}
}
return noItems;
}
int UBFeaturesComputingThread::featuresCountAll(QList > pScanningData)
{
int noItems = 0;
for (int i = 0; i < pScanningData.count(); i++) {
QPair curPair = pScanningData.at(i);
noItems += featuresCount(curPair.first);
}
return noItems;
}
UBFeaturesComputingThread::UBFeaturesComputingThread(QObject *parent) :
QThread(parent)
{
restart = false;
abort = false;
}
void UBFeaturesComputingThread::compute(const QList > &pScanningData, QSet *pFavoritesSet)
{
QMutexLocker curLocker(&mMutex);
mScanningData = pScanningData;
mFavoriteSet = *pFavoritesSet;
if (!isRunning()) {
start(LowPriority);
} else {
restart = true;
mWaitCondition.wakeOne();
}
}
void UBFeaturesComputingThread::run()
{
forever {
// qDebug() << "Custom thread started execution";
mMutex.lock();
QList > searchData = mScanningData;
QSet favoriteSet = mFavoriteSet;
mMutex.unlock();
if (abort) {
return;
}
if (restart) {
break;
}
// QTime curTime = QTime::currentTime();
int fsCnt = featuresCountAll(searchData);
// int msecsto = curTime.msecsTo(QTime::currentTime());
// qDebug() << "time on evaluation" << msecsto;
emit maxFilesCountEvaluated(fsCnt);
emit scanStarted();
// curTime = QTime::currentTime();
scanAll(searchData, favoriteSet);
// qDebug() << "Time on finishing" << curTime.msecsTo(QTime::currentTime());
emit scanFinished();
mMutex.lock();
if (!abort) {
mWaitCondition.wait(&mMutex);
}
restart = false;
mMutex.unlock();
}
}
UBFeaturesComputingThread::~UBFeaturesComputingThread()
{
// qDebug() << "thread destructor catched";
mMutex.lock();
abort = true;
mWaitCondition.wakeOne();
mMutex.unlock();
wait();
}
UBFeature::UBFeature(const QString &url, const QImage &icon, const QString &name, const QUrl &realPath, UBFeatureElementType type)
: mThumbnail(icon), mDisplayName(name), mPath(realPath), elementType(type)
{
mName = getNameFromVirtualPath(url);
virtualDir = getVirtualDirFromVirtualPath(url);
}
UBFeature::~UBFeature()
{
}
QString UBFeature::getNameFromVirtualPath(const QString &pVirtPath)
{
QString result;
int slashPos = pVirtPath.lastIndexOf("/");
if (slashPos != -1) {
result = pVirtPath.right(pVirtPath.count() - slashPos - 1);
} else {
qDebug() << "UBFeature: incorrect virtual path parameter specified";
}
return result;
}
QString UBFeature::getVirtualDirFromVirtualPath(const QString &pVirtPath)
{
QString result;
int slashPos = pVirtPath.lastIndexOf("/");
if (slashPos != -1) {
result = pVirtPath.left(slashPos);
} else {
qDebug() << "UBFeature: incorrect virtual path parameter specified";
}
return result;
}
QString UBFeature::getUrl() const
{
if ( elementType == FEATURE_INTERNAL )
return getFullPath().toString();
return getFullPath().toLocalFile();
}
bool UBFeature::operator ==( const UBFeature &f )const
{
return virtualDir == f.getVirtualPath() && mName == f.getName() && mPath == f.getFullPath() && elementType == f.getType();
}
bool UBFeature::operator !=( const UBFeature &f )const
{
return !(*this == f);
}
bool UBFeature::isFolder() const
{
return elementType == FEATURE_CATEGORY || elementType == FEATURE_TRASH || elementType == FEATURE_FAVORITE
|| elementType == FEATURE_FOLDER || elementType == FEATURE_SEARCH;
}
bool UBFeature::allowedCopy() const
{
return isFolder()
&& elementType != FEATURE_CATEGORY
&& elementType != FEATURE_SEARCH;
}
bool UBFeature::isDeletable() const
{
return elementType == FEATURE_ITEM
|| elementType == FEATURE_AUDIO
|| elementType == FEATURE_VIDEO
|| elementType == FEATURE_IMAGE
|| elementType == FEATURE_FLASH
|| elementType == FEATURE_FOLDER
//Ilia. Just a hotfix. Permission mechanism for UBFeatures should be reworked
|| getVirtualPath().startsWith("/root/Applications/Web");
}
bool UBFeature::inTrash() const
{
return getFullPath().toLocalFile().startsWith(QUrl::fromLocalFile(UBSettings::userTrashDirPath()).toLocalFile() );
}
UBFeaturesController::UBFeaturesController(QWidget *pParentWidget) :
QObject(pParentWidget)
,featuresList(0)
,mLastItemOffsetIndex(0)
{
//Initializing physical directories from UBSettings
mUserAudioDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->userAudioDirectory());
mUserVideoDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->userVideoDirectory());
mUserPicturesDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->userImageDirectory());
mUserInteractiveDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->userInteractiveDirectory());
mUserAnimationDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->userAnimationDirectory());
mLibPicturesDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->applicationImageLibraryDirectory());
mLibAudiosDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->applicationAudiosLibraryDirectory());
mLibVideosDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->applicationVideosLibraryDirectory());
mLibAnimationsDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->applicationAnimationsLibraryDirectory());
mLibInteractiveDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->applicationInteractivesDirectory());
mLibApplicationsDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->applicationApplicationsLibraryDirectory());
mLibShapesDirectoryPath = QUrl::fromLocalFile(UBSettings::settings()->applicationShapeLibraryDirectory());
mLibSearchDirectoryPath =QUrl::fromLocalFile(UBSettings::settings()->userSearchDirectory());
trashDirectoryPath = QUrl::fromLocalFile(UBSettings::userTrashDirPath());
rootElement = UBFeature(rootPath, QImage( ":images/libpalette/home.png" ), "root", QUrl());
audiosElement = UBFeature( audiosPath, QImage(":images/libpalette/AudiosCategory.svg"), tr("Audios") , mUserAudioDirectoryPath, FEATURE_CATEGORY);
moviesElement = UBFeature( moviesPath, QImage(":images/libpalette/MoviesCategory.svg"), tr("Movies") , mUserVideoDirectoryPath, FEATURE_CATEGORY);
picturesElement = UBFeature( picturesPath, QImage(":images/libpalette/PicturesCategory.svg"), tr("Pictures") , mUserPicturesDirectoryPath, FEATURE_CATEGORY);
flashElement = UBFeature( flashPath, QImage(":images/libpalette/FlashCategory.svg"), tr("Animations") , mUserAnimationDirectoryPath, FEATURE_CATEGORY);
interactElement = UBFeature( interactPath, QImage(":images/libpalette/InteractivesCategory.svg"), tr("Interactivities") , mLibInteractiveDirectoryPath, FEATURE_CATEGORY);
applicationsElement = UBFeature( appPath, QImage(":images/libpalette/ApplicationsCategory.svg"), tr("Applications") , mUserInteractiveDirectoryPath, FEATURE_CATEGORY);
shapesElement = UBFeature( shapesPath, QImage(":images/libpalette/ShapesCategory.svg"), tr("Shapes") , mLibShapesDirectoryPath, FEATURE_CATEGORY );
favoriteElement = UBFeature( favoritePath, QImage(":images/libpalette/FavoritesCategory.svg"), tr("Favorites"), QUrl("favorites"), FEATURE_FAVORITE );
webSearchElement = UBFeature( webSearchPath, QImage(":images/libpalette/WebSearchCategory.svg"), tr("Web search"), mLibSearchDirectoryPath, FEATURE_CATEGORY);
trashElement = UBFeature( trashPath, QImage(":images/libpalette/TrashCategory.svg"), tr("Trash"), trashDirectoryPath, FEATURE_TRASH);
featuresList = new QList ();
scanFS();
featuresModel = new UBFeaturesModel(featuresList, this);
featuresModel->setSupportedDragActions(Qt::CopyAction | Qt::MoveAction);
featuresProxyModel = new UBFeaturesProxyModel(this);
featuresProxyModel->setFilterFixedString(rootPath);
featuresProxyModel->setSourceModel(featuresModel);
featuresProxyModel->setFilterCaseSensitivity( Qt::CaseInsensitive );
featuresSearchModel = new UBFeaturesSearchProxyModel(this);
featuresSearchModel->setSourceModel(featuresModel);
featuresSearchModel->setFilterCaseSensitivity( Qt::CaseInsensitive );
featuresPathModel = new UBFeaturesPathProxyModel(this);
featuresPathModel->setPath(rootPath);
featuresPathModel->setSourceModel(featuresModel);
connect(featuresModel, SIGNAL(dataRestructured()), featuresProxyModel, SLOT(invalidate()));
connect(&mCThread, SIGNAL(sendFeature(UBFeature)), featuresModel, SLOT(addItem(UBFeature)));
connect(&mCThread, SIGNAL(featureSent()), this, SIGNAL(featureAddedFromThread()));
connect(&mCThread, SIGNAL(scanStarted()), this, SIGNAL(scanStarted()));
connect(&mCThread, SIGNAL(scanFinished()), this, SIGNAL(scanFinished()));
connect(&mCThread, SIGNAL(maxFilesCountEvaluated(int)), this, SIGNAL(maxFilesCountEvaluated(int)));
connect(&mCThread, SIGNAL(scanCategory(QString)), this, SIGNAL(scanCategory(QString)));
connect(&mCThread, SIGNAL(scanPath(QString)), this, SIGNAL(scanPath(QString)));
connect(UBApplication::boardController, SIGNAL(npapiWidgetCreated(QString)), this, SLOT(createNpApiFeature(QString)));
QTimer::singleShot(0, this, SLOT(startThread()));
}
void UBFeaturesController::startThread()
{
QList > computingData;
computingData << QPair(mLibAudiosDirectoryPath, audiosElement)
<< QPair(mLibVideosDirectoryPath, moviesElement)
<< QPair(mLibAnimationsDirectoryPath, flashElement)
<< QPair(mLibPicturesDirectoryPath, picturesElement)
<< QPair(mUserInteractiveDirectoryPath, applicationsElement)
<< QPair(mUserAudioDirectoryPath, audiosElement)
<< QPair(mUserPicturesDirectoryPath, picturesElement)
<< QPair(mUserVideoDirectoryPath, moviesElement)
<< QPair(mUserAnimationDirectoryPath, flashElement)
<< QPair(mLibApplicationsDirectoryPath, applicationsElement)
<< QPair(mLibShapesDirectoryPath, shapesElement)
<< QPair(mLibInteractiveDirectoryPath, interactElement)
<< QPair(trashDirectoryPath, trashElement)
<< QPair(mLibSearchDirectoryPath, webSearchElement);
mCThread.compute(computingData, favoriteSet);
}
void UBFeaturesController::createNpApiFeature(const QString &str)
{
Q_ASSERT(QFileInfo(str).exists() && QFileInfo(str).isDir());
QString widgetName = QFileInfo(str).fileName();
featuresModel->addItem(UBFeature(QString(appPath + "/Web/" + widgetName), QImage(UBGraphicsWidgetItem::iconFilePath(QUrl::fromLocalFile(str))), widgetName, QUrl::fromLocalFile(str), FEATURE_INTERACTIVE));
}
void UBFeaturesController::scanFS()
{
featuresList->clear();
featuresList->append(rootElement);
*featuresList << audiosElement
<< moviesElement
<< picturesElement
<< flashElement
<< interactElement
<< applicationsElement
<< shapesElement
<< favoriteElement
<< webSearchElement
<< trashElement;
//filling favoriteList
loadFavoriteList();
QList tools = UBToolsManager::manager()->allTools();
foreach (UBToolsManager::UBToolDescriptor tool, tools) {
featuresList->append(UBFeature(appPath + "/" + tool.label, tool.icon.toImage(), tool.label, QUrl(tool.id), FEATURE_INTERNAL));
if (favoriteSet->find(QUrl(tool.id)) != favoriteSet->end()) {
featuresList->append(UBFeature(favoritePath + "/" + tool.label, tool.icon.toImage(), tool.label, QUrl(tool.id), FEATURE_INTERNAL));
}
}
}
void UBFeaturesController::fileSystemScan(const QUrl & currentPath, const QString & currVirtualPath)
{
QFileInfoList fileInfoList = UBFileSystemUtils::allElementsInDirectory(currentPath.toLocalFile());
QFileInfoList::iterator fileInfo;
for ( fileInfo = fileInfoList.begin(); fileInfo != fileInfoList.end(); fileInfo += 1) {
QString fullFileName = fileInfo->absoluteFilePath();
UBFeatureElementType featureType = fileTypeFromUrl(fullFileName);
QString fileName = fileInfo->fileName();
QImage icon = getIcon(fullFileName, featureType);
if ( fullFileName.contains(".thumbnail."))
continue;
UBFeature testFeature(currVirtualPath + "/" + fileName, icon, fileName, QUrl::fromLocalFile(fullFileName), featureType);
featuresList->append(testFeature);
if ( favoriteSet->find( QUrl::fromLocalFile( fullFileName ) ) != favoriteSet->end() ) {
featuresList->append( UBFeature( favoritePath + "/" + fileName, icon, fileName, QUrl::fromLocalFile( fullFileName ), featureType ) );
}
if (featureType == FEATURE_FOLDER) {
fileSystemScan(QUrl::fromLocalFile(fullFileName), currVirtualPath + "/" + fileName);
}
}
}
int UBFeaturesController::featuresCount(const QUrl &currPath)
{
int noItems = 0;
QFileInfoList fileInfoList = UBFileSystemUtils::allElementsInDirectory(currPath.toLocalFile());
QFileInfoList::iterator fileInfo;
for ( fileInfo = fileInfoList.begin(); fileInfo != fileInfoList.end(); fileInfo += 1) {
QString fullFileName = fileInfo->absoluteFilePath();
UBFeatureElementType featureType = fileTypeFromUrl(fullFileName);
if (featureType != FEATURE_INVALID && !fullFileName.contains(".thumbnail.")) {
noItems++;
} else {
continue;
}
if (featureType == FEATURE_FOLDER) {
noItems += featuresCount(QUrl::fromLocalFile(fullFileName));
}
}
return noItems;
}
void UBFeaturesController::loadFavoriteList()
{
favoriteSet = new QSet();
QFile file( UBSettings::userDataDirectory() + "/favorites.dat" );
if ( file.exists() )
{
file.open(QIODevice::ReadOnly);
QDataStream in(&file);
int elementsNumber;
in >> elementsNumber;
for ( int i = 0; i < elementsNumber; ++i)
{
QUrl path;
in >> path;
favoriteSet->insert( path );
}
}
}
void UBFeaturesController::saveFavoriteList()
{
QFile file( UBSettings::userDataDirectory() + "/favorites.dat" );
file.resize(0);
file.open(QIODevice::WriteOnly);
QDataStream out(&file);
out << favoriteSet->size();
for ( QSet::iterator it = favoriteSet->begin(); it != favoriteSet->end(); ++it )
{
out << (*it);
}
file.close();
}
QString UBFeaturesController::uniqNameForFeature(const UBFeature &feature, const QString &pName, const QString &pExtention) const
{
Q_ASSERT(featuresList);
QStringList resultList;
QString parentVirtualPath = feature.getFullVirtualPath();
QString resultName;
qDebug() << "start";
foreach (UBFeature curFeature, *featuresList) {
if (curFeature.getFullVirtualPath().startsWith(feature.getFullVirtualPath())) {
QString curResultName = curFeature.getFullVirtualPath();
if (!parentVirtualPath.endsWith("/")) {
parentVirtualPath.append("/");
}
//Cut virtual path prevfix
int i = curResultName.indexOf(feature.getFullVirtualPath());
if (i != -1) {
curResultName = curResultName.right(curFeature.getFullVirtualPath().count() - i - parentVirtualPath.count());
}
//if directory has children, emptying the name;
i = curResultName.indexOf("/");
if (i != -1) {
curResultName = "";
}
if (!curResultName.isEmpty()) {
resultList.append(curResultName);
}
qDebug() << curResultName;
}
}
if (!resultList.contains(pName + pExtention, Qt::CaseInsensitive)) {
resultName = pName + pExtention;
} else {
for (int i = 0; i < 16777215; i++) {
QString probeName = pName + "_" + QString::number(i) + pExtention;
if (!resultList.contains(probeName, Qt::CaseInsensitive)) {
resultName = probeName;
break;
}
}
}
qDebug() << "result name is " << resultName;
return resultName;
}
QString UBFeaturesController::adjustName(const QString &str)
{
if (str.isNull()) {
return QString();
}
QString resultStr = str;
QRegExp invalidSymbols("[\\/\\s\\:\\?\\*\\|\\<\\>\\\"]+");
return resultStr.replace(invalidSymbols, "_");
}
void UBFeaturesController::addToFavorite( const QUrl &path )
{
QString filePath = fileNameFromUrl( path );
if ( favoriteSet->find( path ) == favoriteSet->end() )
{
QFileInfo fileInfo( filePath );
QString fileName = fileInfo.fileName();
UBFeatureElementType type = fileTypeFromUrl(filePath);
UBFeature elem(favoritePath + "/" + fileName, getIcon(filePath, type), fileName, path, fileTypeFromUrl(filePath) );
favoriteSet->insert( path );
saveFavoriteList();
if ( !elem.getVirtualPath().isEmpty() && !elem.getVirtualPath().isNull())
featuresModel->addItem( elem );
}
}
void UBFeaturesController::removeFromFavorite( const QUrl &path, bool deleteManualy)
{
// QString filePath = fileNameFromUrl( path );
if ( favoriteSet->find( path ) != favoriteSet->end() )
{
favoriteSet->erase( favoriteSet->find( path ) );
saveFavoriteList();
}
if (deleteManualy) {
featuresModel->deleteFavoriteItem(path.toString());
}
}
QString UBFeaturesController::fileNameFromUrl( const QUrl &url )
{
QString fileName = url.toString();
if ( fileName.contains( "uniboardTool://" ) )
return fileName;
return url.toLocalFile();
}
UBFeatureElementType UBFeaturesController::fileTypeFromUrl(const QString &path)
{
QFileInfo fileInfo(path);
if ( path.contains("uniboardTool://"))
return FEATURE_INTERNAL;
if (!fileInfo.exists()) {
return FEATURE_INVALID;
}
UBFeatureElementType fileType = FEATURE_INVALID;
QString fileName = fileInfo.fileName();
QString mimeString = UBFileSystemUtils::mimeTypeFromFileName(fileName);
if ( mimeString.contains("application")) {
if (mimeString.contains("application/search")) {
fileType = FEATURE_SEARCH;
} else if (mimeString.contains("application/x-shockwave-flash")) {
fileType = FEATURE_FLASH;
} else {
fileType = FEATURE_INTERACTIVE;
}
} else if (mimeString.contains("audio")) {
fileType = FEATURE_AUDIO;
} else if (mimeString.contains("video")) {
fileType = FEATURE_VIDEO;
} else if (mimeString.contains("image")) {
fileType = FEATURE_IMAGE;
} else if (fileInfo.isDir()) {
fileType = FEATURE_FOLDER;
} else {
fileType = FEATURE_INVALID;
}
return fileType;
}
QImage UBFeaturesController::getIcon(const QString &path, UBFeatureElementType pFType = FEATURE_INVALID)
{
if (pFType == FEATURE_FOLDER) {
return QImage(":images/libpalette/folder.svg");
} else if (pFType == FEATURE_INTERACTIVE || pFType == FEATURE_SEARCH) {
return QImage(UBGraphicsWidgetItem::iconFilePath(QUrl::fromLocalFile(path)));
} else if (pFType == FEATURE_INTERNAL) {
return QImage(UBToolsManager::manager()->iconFromToolId(path));
} else if (pFType == FEATURE_FLASH) {
return QImage(":images/libpalette/FlashIcon.svg");
} else if (pFType == FEATURE_AUDIO) {
return QImage(":images/libpalette/soundIcon.svg");
} else if (pFType == FEATURE_VIDEO) {
return QImage(":images/libpalette/movieIcon.svg");
} else if (pFType == FEATURE_IMAGE) {
QImage pix(path);
if (pix.isNull()) {
pix = QImage(":images/libpalette/notFound.png");
} else {
pix = pix.scaledToWidth(qMin(UBSettings::maxThumbnailWidth, pix.width()));
}
return pix;
}
return QImage(":images/libpalette/notFound.png");
}
bool UBFeaturesController::isDeletable( const QUrl &url )
{
UBFeatureElementType type = fileTypeFromUrl(fileNameFromUrl(url));
return type == FEATURE_AUDIO
|| type == FEATURE_VIDEO
|| type == FEATURE_IMAGE
|| type == FEATURE_ITEM;
}
QString UBFeaturesController::categoryNameForVirtualPath(const QString &str)
{
QString result;
int ind = str.lastIndexOf("/");
if (ind != -1) {
result = str.right(str.count() - ind - 1);
}
return result;
}
QImage UBFeaturesController::createThumbnail(const QString &path)
{
QString thumbnailPath = path;
QString mimetype = UBFileSystemUtils::mimeTypeFromFileName(path);
if ( mimetype.contains("audio" )) {
thumbnailPath = ":images/libpalette/soundIcon.svg";
} else if ( mimetype.contains("video")) {
thumbnailPath = ":images/libpalette/movieIcon.svg";
} else {
QImage pix(path);
if (!pix.isNull()) {
pix = pix.scaledToWidth(qMin(UBSettings::maxThumbnailWidth, pix.width()), Qt::SmoothTransformation);
return pix;
} else {
thumbnailPath = ":images/libpalette/notFound.png";
}
}
return QImage(thumbnailPath);
}
void UBFeaturesController::importImage(const QImage &image, const QString &fileName)
{
importImage(image, currentElement, fileName);
}
void UBFeaturesController::importImage( const QImage &image, const UBFeature &destination, const QString &fileName )
{
QString mFileName = fileName;
QString filePath;
UBFeature dest = destination;
if (mFileName.isNull()) {
QDateTime now = QDateTime::currentDateTime();
static int imageCounter = 0;
mFileName = tr("ImportedImage") + "-" + now.toString("dd-MM-yyyy hh-mm-ss");
filePath = dest.getFullPath().toLocalFile() + "/" + mFileName;
if (QFile::exists(filePath+".png"))
mFileName += QString("-[%1]").arg(++imageCounter);
else
imageCounter = 0;
mFileName += ".png";
}
if ( !destination.getFullVirtualPath().startsWith( picturesElement.getFullVirtualPath(), Qt::CaseInsensitive ) )
{
dest = picturesElement;
}
filePath = dest.getFullPath().toLocalFile() + "/" + mFileName;
image.save(filePath);
QImage thumb = createThumbnail( filePath );
UBFeature resultItem = UBFeature( dest.getFullVirtualPath() + "/" + mFileName, thumb, mFileName,
QUrl::fromLocalFile( filePath ), FEATURE_ITEM );
featuresModel->addItem(resultItem);
}
QStringList UBFeaturesController::getFileNamesInFolders()
{
QStringList strList;
Q_ASSERT(curListModel);
for (int i = 0; i < curListModel->rowCount(QModelIndex()); i++) {
QModelIndex ind = curListModel->index(i, 0);
if (!ind.isValid()) {
qDebug() << "incorrect model index catched";
continue;
}
UBFeature curFeature = curListModel->data(ind, Qt::UserRole + 1).value();
if (curFeature.getType() == FEATURE_FOLDER) {
strList << QFileInfo(curFeature.getFullPath().toLocalFile()).fileName();
}
}
return strList;
}
void UBFeaturesController::addNewFolder(QString name)
{
QString path = currentElement.getFullPath().toLocalFile() + "/" + name;
if ("/root" == currentElement.getFullVirtualPath())
{
return;
}
if(!QFileInfo(path).exists()) {
QDir().mkpath(path);
}
UBFeature newFeatureFolder = UBFeature( currentElement.getFullVirtualPath() + "/" + name, QImage(":images/libpalette/folder.svg"),
name, QUrl::fromLocalFile( path ), FEATURE_FOLDER );
featuresModel->addItem(newFeatureFolder);
featuresProxyModel->invalidate();
}
void UBFeaturesController::addItemToPage(const UBFeature &item)
{
UBApplication::boardController->downloadURL( item.getFullPath() );
}
void UBFeaturesController::addItemAsBackground(const UBFeature &item)
{
UBApplication::boardController->downloadURL( item.getFullPath(), QString(), QPointF(), QSize(), true );
}
UBFeature UBFeaturesController::getDestinationFeatureForUrl( const QUrl &url )
{
QString mimetype = UBFileSystemUtils::mimeTypeFromFileName( url.toString() );
return getDestinationFeatureForMimeType(mimetype);
}
UBFeature UBFeaturesController::getDestinationFeatureForMimeType(const QString &pMmimeType)
{
if ( pMmimeType.contains("audio") )
return audiosElement;
if ( pMmimeType.contains("video") )
return moviesElement;
else if ( pMmimeType.contains("image") || pMmimeType.isEmpty())
return picturesElement;
else if ( pMmimeType.contains("application") )
{
if ( pMmimeType.contains( "x-shockwave-flash") )
return flashElement;
else
return interactElement;
}
return UBFeature();
}
void UBFeaturesController::addDownloadedFile(const QUrl &sourceUrl, const QByteArray &pData, const QString pContentSource, const QString pTitle)
{
UBFeature dest = getDestinationFeatureForMimeType(pContentSource);
if (dest == UBFeature())
return;
QString fileName;
QString filePath;
//Audio item
if(dest == picturesElement) {
QString UniqName = uniqNameForFeature(dest, adjustName(pTitle), ".jpg");
fileName = !UniqName.isNull()
? UniqName
: tr("ImportedImage") + "-" + QDateTime::currentDateTime().toString("dd-MM-yyyy hh-mm-ss")+ ".jpg";
filePath = dest.getFullPath().toLocalFile() + "/" + fileName;
QImage::fromData(pData).save(filePath);
UBFeature downloadedFeature = UBFeature(dest.getFullVirtualPath() + "/" + fileName, getIcon( filePath, fileTypeFromUrl(filePath)),
fileName, QUrl::fromLocalFile(filePath), FEATURE_ITEM);
if (downloadedFeature != UBFeature()) {
featuresModel->addItem(downloadedFeature);
}
} else {
fileName = QFileInfo( sourceUrl.toString() ).fileName();
filePath = dest.getFullPath().toLocalFile() + "/" + fileName;
QFile file( filePath );
if ( file.open(QIODevice::WriteOnly ))
{
file.write(pData);
file.close();
UBFeature downloadedFeature = UBFeature(dest.getFullVirtualPath() + "/" + fileName, getIcon( filePath, fileTypeFromUrl(filePath)),
fileName, QUrl::fromLocalFile(filePath), FEATURE_ITEM);
if (downloadedFeature != UBFeature()) {
featuresModel->addItem(downloadedFeature);
}
}
}
}
UBFeature UBFeaturesController::moveItemToFolder( const QUrl &url, const UBFeature &destination )
{
/*UBFeature newElement = copyItemToFolder( url, destination );
deleteItem( url );
return newElement;*/
QString sourcePath = url.toLocalFile();
Q_ASSERT( QFileInfo( sourcePath ).exists() );
UBFeature possibleDest = getDestinationFeatureForUrl(url);
UBFeature dest = destination;
if ( destination != trashElement &&
!destination.getFullVirtualPath().startsWith( possibleDest.getFullVirtualPath(), Qt::CaseInsensitive ) )
{
dest = possibleDest;
}
QString name = QFileInfo( sourcePath ).fileName();
QString destPath = dest.getFullPath().toLocalFile();
QString destVirtualPath = dest.getFullVirtualPath();
QString newFullPath = destPath + "/" + name;
if ( sourcePath.compare( newFullPath, Qt::CaseInsensitive ) )
{
QFile( sourcePath ).copy( newFullPath );
deleteItem( url );
}
QImage thumb = getIcon( newFullPath );
UBFeatureElementType type = FEATURE_ITEM;
if ( UBFileSystemUtils::mimeTypeFromFileName( newFullPath ).contains("application") )
type = FEATURE_INTERACTIVE;
UBFeature newElement( destVirtualPath + "/" + name, thumb, name, QUrl::fromLocalFile( newFullPath ), type );
return newElement;
}
void UBFeaturesController::rescanModel()
{
featuresModel->removeRows(0, featuresList->count());
//Could implement infolder scanning for better perfomance
scanFS();
refreshModels();
}
void UBFeaturesController::siftElements(const QString &pSiftValue)
{
featuresProxyModel->setFilterFixedString(pSiftValue);
featuresProxyModel->invalidate();
featuresPathModel->setPath(pSiftValue);
featuresPathModel->invalidate();
}
UBFeature UBFeaturesController::getFeature(const QModelIndex &index, const QString &listName)
{
// QSortFilterProxyModel *model = qobject_cast(pOnView->model());
QAbstractItemModel *model = 0;
if (listName == UBFeaturesWidget::objNamePathList) {
model = featuresPathModel;
} else if (listName == UBFeaturesWidget::objNameFeatureList) {
model = curListModel;
}
if (model) {
return model->data(index, Qt::UserRole + 1).value();
}
return UBFeature();
// return pOnView->model()->data(index, Qt::UserRole + 1).value(); /*featuresSearchModel->data(index, Qt::UserRole + 1).value()*/;
}
void UBFeaturesController::searchStarted(const QString &pattern, QListView *pOnView)
{
if (pattern.isEmpty()) {
pOnView->setModel(featuresProxyModel);
featuresProxyModel->invalidate();
curListModel = featuresProxyModel;
} else if ( pattern.size() > 1 ) {
// featuresSearchModel->setFilterPrefix(currentElement.getFullVirtualPath());
featuresSearchModel->setFilterWildcard( "*" + pattern + "*" );
pOnView->setModel(featuresSearchModel );
featuresSearchModel->invalidate();
curListModel = featuresSearchModel;
}
}
void UBFeaturesController::refreshModels()
{
featuresProxyModel->invalidate();
featuresSearchModel->invalidate();
featuresPathModel->invalidate();
}
UBFeature UBFeaturesController::copyItemToFolder( const QUrl &url, const UBFeature &destination )
{
QString sourcePath = url.toLocalFile();
Q_ASSERT( QFileInfo( sourcePath ).exists() );
UBFeature possibleDest = getDestinationFeatureForUrl( url );
UBFeature dest = destination;
if ( destination != trashElement &&
!destination.getFullVirtualPath().startsWith( possibleDest.getFullVirtualPath(), Qt::CaseInsensitive ) )
{
dest = possibleDest;
}
QString name = QFileInfo(sourcePath).fileName();
QString destPath = dest.getFullPath().toLocalFile();
QString destVirtualPath = dest.getFullVirtualPath();
QString newFullPath = destPath + "/" + name;
if (!sourcePath.compare(newFullPath, Qt::CaseInsensitive))
QFile(sourcePath).copy(newFullPath);
QImage thumb = getIcon(newFullPath);
UBFeatureElementType type = FEATURE_ITEM;
if (UBFileSystemUtils::mimeTypeFromFileName(newFullPath).contains("application"))
type = FEATURE_INTERACTIVE;
UBFeature newElement( destVirtualPath + "/" + name, thumb, name, QUrl::fromLocalFile( newFullPath ), type );
return newElement;
}
void UBFeaturesController::moveExternalData(const QUrl &url, const UBFeature &destination)
{
QString sourcePath = url.toLocalFile();
Q_ASSERT( QFileInfo( sourcePath ).exists() );
UBFeature possibleDest = getDestinationFeatureForUrl(url);
UBFeature dest = destination;
if ( destination != trashElement && destination != UBFeature()
/*&& !destination.getFullVirtualPath().startsWith( possibleDest.getFullVirtualPath(), Qt::CaseInsensitive )*/ )
{
dest = possibleDest;
}
UBFeatureElementType type = fileTypeFromUrl(sourcePath);
if (type == FEATURE_FOLDER) {
return;
}
QString name = QFileInfo(sourcePath).fileName();
QString destPath = dest.getFullPath().toLocalFile();
QString destVirtualPath = dest.getFullVirtualPath();
QString newFullPath = destPath + "/" + name;
if (!sourcePath.compare(newFullPath, Qt::CaseInsensitive) || !UBFileSystemUtils::copy(sourcePath, newFullPath)) {
return;
}
Q_ASSERT(QFileInfo(newFullPath).exists());
QImage thumb = getIcon(newFullPath, type);
UBFeature newElement(destVirtualPath + "/" + name, thumb, name, QUrl::fromLocalFile(newFullPath), type);
featuresModel->addItem(newElement);
}
void UBFeaturesController::deleteItem(const QUrl &url)
{
QString path = url.toLocalFile();
Q_ASSERT( QFileInfo( path ).exists() );
QString thumbnailPath = UBFileSystemUtils::thumbnailPath( path );
if ( thumbnailPath.length() && QFileInfo( thumbnailPath ).exists()) {
if (QFileInfo(thumbnailPath).isFile()) {
QFile::remove(thumbnailPath);
} else if (QFileInfo(thumbnailPath).isDir()){
if (!UBFileSystemUtils::deleteDir(thumbnailPath)) {
qDebug() << "Not able to delete directory";
}
}
}
if (QFileInfo(path).isFile()) {
QFile::remove( path );
} else if (QFileInfo(path).isDir()) {
UBFileSystemUtils::deleteDir(path);
}
}
void UBFeaturesController::deleteItem(const UBFeature &pFeature)
{
QUrl sourceUrl = pFeature.getFullPath();
featuresModel->deleteItem(pFeature);
deleteItem(sourceUrl);
}
bool UBFeaturesController::isTrash( const QUrl &url )
{
return url.toLocalFile().startsWith( trashDirectoryPath.toLocalFile() );
}
void UBFeaturesController::moveToTrash(UBFeature feature, bool deleteManualy)
{
featuresModel->moveData(feature, trashElement, Qt::MoveAction, deleteManualy);
removeFromFavorite(feature.getFullPath());
featuresModel->deleteFavoriteItem(UBFeaturesController::fileNameFromUrl(feature.getFullPath()));
}
UBFeaturesController::~UBFeaturesController()
{
if (featuresList) {
delete featuresList;
}
}
void UBFeaturesController::assignFeaturesListView(UBFeaturesListView *pList)
{
pList->setDragDropMode( QAbstractItemView::DragDrop );
pList->setSelectionMode( QAbstractItemView::ContiguousSelection );
pList->setResizeMode( QListView::Adjust );
pList->setViewMode( QListView::IconMode );
pList->setIconSize(QSize(UBFeaturesWidget::defaultThumbnailSize, UBFeaturesWidget::defaultThumbnailSize));
pList->setGridSize(QSize(UBFeaturesWidget::defaultThumbnailSize + 20, UBFeaturesWidget::defaultThumbnailSize + 20));
itemDelegate = new UBFeaturesItemDelegate(this, pList);
pList->setItemDelegate(itemDelegate);
pList->setModel(featuresProxyModel);
curListModel = featuresProxyModel;
}
void UBFeaturesController::assignPathListView(UBFeaturesListView *pList)
{
pList->setViewMode(QListView::IconMode );
pList->setIconSize(QSize(UBFeaturesWidget::defaultThumbnailSize - 10, UBFeaturesWidget::defaultThumbnailSize - 10));
pList->setGridSize(QSize(UBFeaturesWidget::defaultThumbnailSize + 10, UBFeaturesWidget::defaultThumbnailSize - 10));
pList->setFixedHeight(60);
pList->setSelectionMode(QAbstractItemView::NoSelection);
pList->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
pList->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
pList->setFlow(QListView::LeftToRight);
pList->setWrapping(false);
pList->setDragDropMode(QAbstractItemView::DropOnly);
pList->setModel( featuresPathModel);
pathItemDelegate = new UBFeaturesPathItemDelegate(this);
pList->setItemDelegate(pathItemDelegate);
}