diff --git a/resources/style.qss b/resources/style.qss index 4dcd73ae..31f1e671 100644 --- a/resources/style.qss +++ b/resources/style.qss @@ -4,7 +4,8 @@ QWidget#UBLibPathViewer, QWidget#UBLibNavigatorWidget, QWidget#UBLibItemProperties, QWidget#UBDownloadWidget, -QWidget#UBTeacherGuideWidget +QWidget#UBTeacherGuideWidget, +QWidget#UBFeatureProperties { background: #EEEEEE; border-radius: 10px; @@ -25,6 +26,13 @@ QWidget#UBLibWebView border: 2px solid #999999; } +QListView +{ + background: #EEEEEE; + border-radius : 10px; + border: 2px solid #999999; +} + QWebView#SearchEngineView { background:white; diff --git a/src/board/UBBoardPaletteManager.cpp b/src/board/UBBoardPaletteManager.cpp index f21c089b..25f9d1d8 100644 --- a/src/board/UBBoardPaletteManager.cpp +++ b/src/board/UBBoardPaletteManager.cpp @@ -138,6 +138,7 @@ void UBBoardPaletteManager::setupDockPaletteWidgets() mpDownloadWidget = new UBDockDownloadWidget(); mpTeacherGuideWidget = new UBDockTeacherGuideWidget(); + mpFeaturesWidget = new UBFeaturesWidget(); // Add the dock palettes mLeftPalette = new UBLeftPalette(mContainer); @@ -153,6 +154,10 @@ void UBBoardPaletteManager::setupDockPaletteWidgets() mRightPalette = new UBRightPalette(mContainer); // RIGHT palette widgets + + mRightPalette->registerWidget(mpFeaturesWidget); + mRightPalette->addTab(mpFeaturesWidget); + mRightPalette->registerWidget(mpLibWidget); mRightPalette->addTab(mpLibWidget); // The cache widget will be visible only if a cache is put on the page diff --git a/src/board/UBBoardPaletteManager.h b/src/board/UBBoardPaletteManager.h index 4e5e5d99..6a1c60a1 100644 --- a/src/board/UBBoardPaletteManager.h +++ b/src/board/UBBoardPaletteManager.h @@ -27,6 +27,7 @@ #include "gui/UBCachePropertiesWidget.h" #include "gui/UBDockDownloadWidget.h" #include "core/UBApplicationController.h" +#include "gui/UBFeaturesWidget.h" class UBStylusPalette; @@ -129,6 +130,8 @@ class UBBoardPaletteManager : public QObject /** The cache properties widget */ UBCachePropertiesWidget* mpCachePropWidget; + UBFeaturesWidget *mpFeaturesWidget; + /** The download widget */ UBDockDownloadWidget* mpDownloadWidget; // HACK: here we duplicate the lib widget for the desktop mode diff --git a/src/board/UBBoardView.cpp b/src/board/UBBoardView.cpp index 5a158b43..3dd30148 100644 --- a/src/board/UBBoardView.cpp +++ b/src/board/UBBoardView.cpp @@ -16,6 +16,7 @@ #include #include +#include #include "UBDrawingController.h" @@ -843,17 +844,17 @@ void UBBoardView::dropEvent (QDropEvent *event) QGraphicsItem* graphicsItemAtPos = itemAt(event->pos().x(),event->pos().y()); UBGraphicsWidgetItem* graphicsWidget = dynamic_cast(graphicsItemAtPos); - qDebug() << event->source(); - if (graphicsWidget && graphicsWidget->acceptDrops()) { + graphicsWidget->processDropEvent(event); event->acceptProposedAction(); - } - else if (!event->source() + } else if (!event->source() || dynamic_cast(event->source()) || dynamic_cast(event->source()) - || dynamic_cast(event->source())) { + || dynamic_cast(event->source()) + || dynamic_cast(event->source()) ) { + mController->processMimeData (event->mimeData (), mapToScene (event->pos ())); event->acceptProposedAction(); } diff --git a/src/board/UBFeaturesController.cpp b/src/board/UBFeaturesController.cpp new file mode 100644 index 00000000..863606da --- /dev/null +++ b/src/board/UBFeaturesController.cpp @@ -0,0 +1,369 @@ +#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/UBAbstractWidget.h" +#include "domain/UBGraphicsScene.h" +#include "domain/UBGraphicsSvgItem.h" +#include "domain/UBGraphicsPixmapItem.h" +#include "domain/UBGraphicsVideoItem.h" +#include "domain/UBGraphicsWidgetItem.h" + +UBFeature::UBFeature(const QString &url, const QPixmap &icon, const QString &name, const QString &realPath, UBFeatureElementType type) +: virtualPath(url), mThumbnail(icon), mName(name), mPath(realPath), elementType(type) +{ + +} + + + +bool UBFeature::isFolder() const +{ + return elementType == FEATURE_CATEGORY || elementType == FEATURE_TRASH || elementType == FEATURE_FAVORITE + || elementType == FEATURE_FOLDER; +} + + +UBFeaturesController::UBFeaturesController(QWidget *pParentWidget) : + QObject(pParentWidget), + mLastItemOffsetIndex(0) +{ + rootPath = "/root"; + initDirectoryTree(); +} + +void UBFeaturesController::initDirectoryTree() +{ + mUserAudioDirectoryPath = UBSettings::settings()->userAudioDirectory(); + mUserVideoDirectoryPath = UBSettings::settings()->userVideoDirectory(); + mUserPicturesDirectoryPath = UBSettings::settings()->userImageDirectory(); + mUserInteractiveDirectoryPath = UBSettings::settings()->userInteractiveDirectory(); + mUserAnimationDirectoryPath = UBSettings::settings()->userAnimationDirectory(); + + mLibPicturesDirectoryPath = UBSettings::settings()->applicationImageLibraryDirectory(); + mLibInteractiveDirectoryPath = UBSettings::settings()->applicationInteractivesDirectory(); + mLibApplicationsDirectoryPath = UBSettings::settings()->applicationApplicationsLibraryDirectory(); + mLibShapesDirectoryPath = UBSettings::settings()->applicationShapeLibraryDirectory() ; + trashDirectoryPath = UBSettings::userTrashDirPath(); + + featuresList = new QList (); + + QList tools = UBToolsManager::manager()->allTools(); + + featuresList->append( UBFeature( QString(), QPixmap( ":images/libpalette/home.png" ), "root", QString() ) ); + currentElement = featuresList->at(0); + + appPath = rootPath + "/Applications"; + audiosPath = rootPath + "/Audios"; + moviesPath = rootPath + "/Movies"; + picturesPath = rootPath + "/Pictures"; + flashPath = rootPath + "/Animations"; + interactPath = rootPath + "/Interactivities"; + shapesPath = rootPath + "/Shapes"; + trashPath = rootPath + "/Trash"; + favoritePath = rootPath + "/Favorites"; + + featuresList->append( UBFeature( rootPath, QPixmap(":images/libpalette/AudiosCategory.svg"), "Audios" , mUserAudioDirectoryPath ) ); + featuresList->append( UBFeature( rootPath, QPixmap(":images/libpalette/MoviesCategory.svg"), "Movies" , mUserVideoDirectoryPath ) ); + featuresList->append( UBFeature( rootPath, QPixmap(":images/libpalette/PicturesCategory.svg"), "Pictures" , mUserPicturesDirectoryPath ) ); + featuresList->append( UBFeature( rootPath, QPixmap(":images/libpalette/ApplicationsCategory.svg"), "Applications" , mUserInteractiveDirectoryPath ) ); + featuresList->append( UBFeature( rootPath, QPixmap(":images/libpalette/FlashCategory.svg"), "Animations" , mUserAnimationDirectoryPath ) ); + featuresList->append( UBFeature( rootPath, QPixmap(":images/libpalette/InteractivesCategory.svg"), "Interactivities" , mLibInteractiveDirectoryPath ) ); + featuresList->append( UBFeature( rootPath, QPixmap(":images/libpalette/ShapesCategory.svg"), "Shapes" , mLibShapesDirectoryPath ) ); + trashElement = UBFeature( rootPath, QPixmap(":images/libpalette/TrashCategory.svg"), "Trash", trashDirectoryPath, FEATURE_TRASH ); + featuresList->append( trashElement ); + favoriteElement = UBFeature( rootPath, QPixmap(":images/libpalette/FavoritesCategory.svg"), "Favorites", "favorites", FEATURE_FAVORITE ); + featuresList->append( favoriteElement ); + + loadFavoriteList(); + + foreach (UBToolsManager::UBToolDescriptor tool, tools) + { + featuresList->append( UBFeature( appPath, tool.icon, tool.label, tool.id, FEATURE_INTERNAL ) ); + if ( favoriteSet->find( tool.id ) != favoriteSet->end() ) + { + featuresList->append( UBFeature( favoritePath, tool.icon, tool.label, tool.id, FEATURE_INTERNAL ) ); + } + } + fileSystemScan( mUserInteractiveDirectoryPath, appPath ); + fileSystemScan( mUserAudioDirectoryPath, audiosPath ); + fileSystemScan( mUserPicturesDirectoryPath, picturesPath ); + fileSystemScan( mUserVideoDirectoryPath, moviesPath ); + fileSystemScan( mUserAnimationDirectoryPath, flashPath ); + + fileSystemScan( mLibApplicationsDirectoryPath, appPath ); + fileSystemScan( mLibPicturesDirectoryPath, picturesPath ); + fileSystemScan( mLibShapesDirectoryPath, shapesPath ); + fileSystemScan( mLibInteractiveDirectoryPath, interactPath ); + fileSystemScan( trashDirectoryPath, trashPath ); + + + +} + +void UBFeaturesController::fileSystemScan(const QString & currentPath, const QString & currVirtualPath) +{ + QFileInfoList fileInfoList = UBFileSystemUtils::allElementsInDirectory(currentPath); + + QFileInfoList::iterator fileInfo; + for ( fileInfo = fileInfoList.begin(); fileInfo != fileInfoList.end(); fileInfo += 1) + { + UBFeatureElementType fileType = fileInfo->isDir() ? FEATURE_FOLDER : FEATURE_ITEM; + + QString fileName = fileInfo->fileName(); + if ( UBFileSystemUtils::mimeTypeFromFileName(fileName).contains("application") ) { + fileType = FEATURE_INTERACTIVE; + } + QString itemName = (fileType != FEATURE_ITEM) ? fileName : fileInfo->completeBaseName(); + QPixmap icon = QPixmap(":images/libpalette/soundIcon.svg"); + QString fullFileName = fileInfo->filePath(); + + if ( fileType == FEATURE_FOLDER ) + { + icon = QPixmap(":images/libpalette/folder.svg"); + } + else if ( fileType == FEATURE_INTERACTIVE ) + { + icon = QPixmap( UBAbstractWidget::iconFilePath( QUrl::fromLocalFile(fullFileName) ) ); + } + else + { + if ( fullFileName.contains(".thumbnail.") ) + continue; + icon = thumbnailForFile( fullFileName ); + /*QString thumbnailPath = UBFileSystemUtils::thumbnailPath( fullFileName ); + + if (QFileInfo( thumbnailPath).exists() ) + icon = QPixmap( thumbnailPath ); + else icon = createThumbnail( fullFileName );*/ + } + featuresList->append( UBFeature( currVirtualPath, icon, fileName, fullFileName, fileType ) ); + if ( favoriteSet->find( fullFileName ) != favoriteSet->end() ) + { + featuresList->append( UBFeature( favoritePath, icon, fileName, fullFileName, fileType ) ); + } + + if ( fileType == FEATURE_FOLDER ) + { + fileSystemScan( fullFileName, currVirtualPath + "/" + fileName ); + } + + } +} + +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) + { + QString path; + in >> path; + /*QFileInfo fileInfo( path ); + QString fileName = fileInfo.fileName(); + + UBFeature elem( favoritePath, thumbnailForFile( path ), fileName, path, fileTypeFromUrl(path) ); + featuresList->append( elem );*/ + 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(); +} + +UBFeature UBFeaturesController::addToFavorite( const QUrl &path ) +{ + QString filePath = fileNameFromUrl( path ); + if ( favoriteSet->find( filePath ) == favoriteSet->end() ) + { + QFileInfo fileInfo( filePath ); + QString fileName = fileInfo.fileName(); + UBFeature elem( favoritePath, thumbnailForFile( filePath ), fileName, filePath, fileTypeFromUrl(filePath) ); + favoriteSet->insert( filePath ); + saveFavoriteList(); + return elem; + } + return UBFeature(); +} + +void UBFeaturesController::removeFromFavorite( const QUrl &path ) +{ + QString filePath = fileNameFromUrl( path ); + if ( favoriteSet->find( filePath ) != favoriteSet->end() ) + { + favoriteSet->erase( favoriteSet->find( filePath ) ); + saveFavoriteList(); + } +} + +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 ); + QString fileName = fileInfo.fileName(); + + UBFeatureElementType fileType = fileInfo.isDir() ? FEATURE_FOLDER : FEATURE_ITEM; + if ( UBFileSystemUtils::mimeTypeFromFileName(fileName).contains("application") ) + { + fileType = FEATURE_INTERACTIVE; + } + else if ( path.contains("uniboardTool://") ) + { + fileType = FEATURE_INTERNAL; + } + return fileType; +} + +QPixmap UBFeaturesController::thumbnailForFile(const QString &path) +{ + if ( path.contains("uniboardTool://") ) + { + return QPixmap( UBToolsManager::manager()->iconFromToolId(path) ); + } + if ( UBFileSystemUtils::mimeTypeFromFileName(path).contains("application") ) + { + return QPixmap( UBAbstractWidget::iconFilePath( QUrl::fromLocalFile(path) ) ); + } + + QPixmap thumb; + QString thumbnailPath = UBFileSystemUtils::thumbnailPath( path ); + + if ( QFileInfo( thumbnailPath ).exists() ) + thumb = QPixmap( thumbnailPath ); + else thumb = createThumbnail( path ); + return thumb; +} + +QPixmap UBFeaturesController::createThumbnail(const QString &path) +{ + QString thumbnailPath = UBFileSystemUtils::thumbnailPath(path); + QString mimetype = UBFileSystemUtils::mimeTypeFromFileName(path); + QString extension = QFileInfo(path).completeSuffix(); + //UBApplication::showMessage(tr("Creating image thumbnail for %1.").arg(pElement->name())); + + if ( mimetype.contains("audio" )) + thumbnailPath = ":images/libpalette/soundIcon.svg"; + else if ( mimetype.contains("video") ) + thumbnailPath = ":images/libpalette/movieIcon.svg"; + else + { + if ( extension.startsWith("svg", Qt::CaseInsensitive) || extension.startsWith("svgz", Qt::CaseInsensitive) ) + { + thumbnailPath = path; + } + else + { + QPixmap pix(path); + if (!pix.isNull()) + { + pix = pix.scaledToWidth(qMin(UBSettings::maxThumbnailWidth, pix.width()), Qt::SmoothTransformation); + pix.save(thumbnailPath); + UBPlatformUtils::hideFile(thumbnailPath); + } + else{ + thumbnailPath = ":images/libpalette/notFound.png"; + } + } + } + + return QPixmap(thumbnailPath); +} + +UBFeature UBFeaturesController::newFolder( const QString &name ) +{ + QString path = currentElement.getFullPath() + "/" + name; + if(!QFileInfo(path).exists()) + { + QDir().mkpath(path); + } + return UBFeature( currentElement.getUrl() + "/" + currentElement.getName(), QPixmap(":images/libpalette/folder.svg"), name, path, FEATURE_FOLDER ); +} + +void UBFeaturesController::addItemToPage(const UBFeature &item) +{ + UBApplication::boardController->downloadURL( QUrl::fromLocalFile( item.getFullPath() ) ); +} + +UBFeature UBFeaturesController::moveItemToFolder( const QUrl &url, const UBFeature &destination ) +{ + UBFeature newElement = copyItemToFolder( url, destination ); + deleteItem( url ); + return newElement; +} + +UBFeature UBFeaturesController::copyItemToFolder( const QUrl &url, const UBFeature &destination ) +{ + QString sourcePath = url.toLocalFile(); + + Q_ASSERT( QFileInfo( sourcePath ).exists() ); + + QString name = QFileInfo( sourcePath ).fileName(); + QString destPath = destination.getFullPath(); + QString destVirtualPath = destination.getUrl() + "/" + destination.getName(); + QString newFullPath = destPath + "/" + name; + QFile( sourcePath ).copy( newFullPath ); + + QPixmap thumb = thumbnailForFile( newFullPath ); + + UBFeatureElementType type = FEATURE_ITEM; + if ( UBFileSystemUtils::mimeTypeFromFileName( newFullPath ).contains("application") ) + type = FEATURE_INTERACTIVE; + UBFeature newElement( destVirtualPath, thumb, name, newFullPath, type ); + return 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()) + { + QFile::remove(thumbnailPath); + } + QFile::remove( path ); +} + +bool UBFeaturesController::isTrash( const QUrl &url ) +{ + return url.toLocalFile().startsWith( trashDirectoryPath ); +} + +UBFeaturesController::~UBFeaturesController() +{ +} diff --git a/src/board/UBFeaturesController.h b/src/board/UBFeaturesController.h new file mode 100644 index 00000000..a46c6e63 --- /dev/null +++ b/src/board/UBFeaturesController.h @@ -0,0 +1,124 @@ +#ifndef UBFEATURESCONTROLLER_H +#define UBFEATURESCONTROLLER_H + +#include +#include +#include +#include +#include +#include + +//#include "UBDockPaletteWidget.h" + +enum UBFeatureElementType +{ + FEATURE_CATEGORY, + FEATURE_VIRTUALFOLDER, + FEATURE_FOLDER, + FEATURE_INTERACTIVE, + FEATURE_INTERNAL, + FEATURE_ITEM, + FEATURE_TRASH, + FEATURE_FAVORITE +}; + +class UBFeature +{ +public: + UBFeature() {;} + //UBFeature(const UBFeature &f); + UBFeature(const QString &url, const QPixmap &icon, const QString &name, const QString &realPath, UBFeatureElementType type = FEATURE_CATEGORY); + virtual ~UBFeature() {;} + QString getName() const { return mName; } + QPixmap getThumbnail() const {return mThumbnail;} + QString getUrl() const { return virtualPath; } + //QString getPath() const { return mPath; }; + QString getFullPath() const { return mPath; } + UBFeatureElementType getType() const { return elementType; } + bool isFolder() const; +private: + QString virtualPath; + QPixmap mThumbnail; + QString mName; + QString mPath; + UBFeatureElementType elementType; +}; +Q_DECLARE_METATYPE( UBFeature ) + + +class UBFeaturesController : public QObject +{ +Q_OBJECT +public: + UBFeaturesController(QWidget *parentWidget); + virtual ~UBFeaturesController(); + + QList * getFeatures()const { return featuresList; } + + const QString& getRootPath()const { return rootPath; } + + void addItemToPage(const UBFeature &item); + const UBFeature& getCurrentElement()const { return currentElement; } + void setCurrentElement( const UBFeature &elem ) { currentElement = elem; } + const UBFeature & getTrashElement () const { return trashElement; } + UBFeature moveItemToFolder( const QUrl &url, const UBFeature &destination ); + UBFeature copyItemToFolder( const QUrl &url, const UBFeature &destination ); + void deleteItem( const QUrl &url ); + bool isTrash( const QUrl &url ); + UBFeature newFolder( const QString &name ); + UBFeature addToFavorite( const QUrl &path ); + void removeFromFavorite( const QUrl &path ); + + static QString fileNameFromUrl( const QUrl &url ); + static QPixmap thumbnailForFile( const QString &path ); +private: + void initDirectoryTree(); + void fileSystemScan(const QString &currPath, const QString & currVirtualPath); + static QPixmap createThumbnail(const QString &path); + //void addImageToCurrentPage( const QString &path ); + void loadFavoriteList(); + void saveFavoriteList(); + + static UBFeatureElementType fileTypeFromUrl( const QString &path ); + + QList *featuresList; + UBFeature *rootElement; + + QString mUserAudioDirectoryPath; + QString mUserVideoDirectoryPath; + QString mUserPicturesDirectoryPath; + QString mUserInteractiveDirectoryPath; + QString mUserAnimationDirectoryPath; + + QString libraryPath; + QString mLibAudioDirectoryPath; + QString mLibVideoDirectoryPath; + QString mLibPicturesDirectoryPath; + QString mLibInteractiveDirectoryPath; + QString mLibAnimationDirectoryPath; + QString mLibApplicationsDirectoryPath; + QString mLibShapesDirectoryPath; + QString trashDirectoryPath; + + QString rootPath; + QString audiosPath; + QString moviesPath; + QString picturesPath; + QString appPath; + QString flashPath; + QString shapesPath; + QString interactPath; + QString trashPath; + QString favoritePath; + + int mLastItemOffsetIndex; + UBFeature currentElement; + UBFeature trashElement; + UBFeature favoriteElement; + + QSet *favoriteSet; +}; + + + +#endif diff --git a/src/board/board.pri b/src/board/board.pri index bf934a62..1208db87 100644 --- a/src/board/board.pri +++ b/src/board/board.pri @@ -3,13 +3,15 @@ HEADERS += src/board/UBBoardController.h \ src/board/UBBoardPaletteManager.h \ src/board/UBBoardView.h \ src/board/UBLibraryController.h \ - src/board/UBDrawingController.h + src/board/UBDrawingController.h \ + src/board/UBFeaturesController.h SOURCES += src/board/UBBoardController.cpp \ src/board/UBBoardPaletteManager.cpp \ src/board/UBBoardView.cpp \ src/board/UBLibraryController.cpp \ - src/board/UBDrawingController.cpp + src/board/UBDrawingController.cpp \ + src/board/UBFeaturesController.cpp diff --git a/src/gui/UBFeaturesActionBar.cpp b/src/gui/UBFeaturesActionBar.cpp new file mode 100644 index 00000000..e9a560e1 --- /dev/null +++ b/src/gui/UBFeaturesActionBar.cpp @@ -0,0 +1,200 @@ +#include "UBFeaturesActionBar.h" + +UBFeaturesActionBar::UBFeaturesActionBar( UBFeaturesController *controller, QWidget* parent, const char* name ) : QWidget (parent) + , featuresController(controller) + , mButtonGroup(NULL) + , mSearchBar(NULL) + , mLayout(NULL) + , mpFavoriteAction(NULL) + , mpSocialAction(NULL) + , mpDeleteAction(NULL) + , mpSearchAction(NULL) + , mpCloseAction(NULL) + , mpRemoveFavorite(NULL) + , mpNewFolderAction(NULL) + , mpFavoriteBtn(NULL) + , mpSocialBtn(NULL) + , mpDeleteBtn(NULL) + , mpCloseBtn(NULL) + , mpRemoveFavoriteBtn(NULL) + , mpNewFolderBtn(NULL) +{ + setObjectName(name); + setStyleSheet(QString("background: #EEEEEE; border-radius : 10px; border : 2px solid #999999;")); + + setAcceptDrops(true); + + mButtonGroup = new QButtonGroup(this); + mSearchBar = new QLineEdit(this); + mSearchBar->setStyleSheet(QString("background-color:white; border-radius : 10px; padding : 2px;")); + //connect(mSearchBar, SIGNAL(returnPressed()), this, SLOT(onActionSearch())); + + mLayout = new QHBoxLayout(); + setLayout(mLayout); + + setMaximumHeight(ACTIONBAR_HEIGHT); + + // Create the actions + mpFavoriteAction = new QAction(QIcon(":/images/libpalette/miniFavorite.png"), tr("Add to favorites"), this); + mpSocialAction = new QAction(QIcon(":/images/libpalette/social.png"), tr("Share"), this); + mpSearchAction = new QAction(QIcon(":/images/libpalette/miniSearch.png"), tr("Search"), this); + mpDeleteAction = new QAction(QIcon(":/images/libpalette/miniTrash.png"), tr("Delete"), this); + mpCloseAction = new QAction(QIcon(":/images/close.svg"), tr("Back to folder"), this); + mpRemoveFavorite = new QAction(QIcon(":/images/libpalette/trash_favorite.svg"), tr("Remove from favorites"), this); + mpNewFolderAction = new QAction(QIcon(":/images/libpalette/miniNewFolder.png"), tr("Create new folder"), this); + + // Create the buttons + mpFavoriteBtn = new UBActionButton(this, mpFavoriteAction); + mpSocialBtn = new UBActionButton(this, mpSocialAction); + //mpSearchBtn = new UBActionButton(this, mpSearchAction); + mpDeleteBtn = new UBActionButton(this, mpDeleteAction); + mpCloseBtn = new UBActionButton(this, mpCloseAction); + mpRemoveFavoriteBtn = new UBActionButton(this, mpRemoveFavorite); + mpNewFolderBtn = new UBActionButton(this, mpNewFolderAction); + + // Initialize the buttons + //mpSearchBtn->setEnabled(false); + mpNewFolderBtn->setEnabled(false); + + // Add the buttons to the button group + mButtonGroup->addButton(mpFavoriteBtn); + mButtonGroup->addButton(mpSocialBtn); + //mButtonGroup->addButton(mpSearchBtn); + mButtonGroup->addButton(mpDeleteBtn); + mButtonGroup->addButton(mpCloseBtn); + mButtonGroup->addButton(mpRemoveFavoriteBtn); + mButtonGroup->addButton(mpNewFolderBtn); + // Connect signals & slots + /*connect(mpFavoriteAction,SIGNAL(triggered()), this, SLOT(onActionFavorite())); + connect(mpSocialAction,SIGNAL(triggered()), this, SLOT(onActionSocial())); + connect(mpSearchAction,SIGNAL(triggered()), this, SLOT(onActionSearch())); + connect(mpDeleteAction,SIGNAL(triggered()), this, SLOT(onActionTrash())); + connect(mpCloseAction, SIGNAL(triggered()), this, SLOT(onActionClose())); + connect(mpRemoveFavorite, SIGNAL(triggered()), this, SLOT(onActionRemoveFavorite())); + connect(mSearchBar, SIGNAL(textChanged(QString)), this, SLOT(onSearchTextChanged(QString))); + connect(mpNewFolderAction, SIGNAL(triggered()), this, SLOT(onActionNewFolder()));*/ + + connect(mSearchBar, SIGNAL(textChanged(QString)), this, SLOT(onSearchTextChanged(QString))); + connect(mpNewFolderAction, SIGNAL(triggered()), this, SLOT(onActionNewFolder())); + + // Build the default toolbar + mLayout->addWidget(mpFavoriteBtn); + mLayout->addWidget(mpSocialBtn); + mLayout->addWidget(mpNewFolderBtn); + mLayout->addWidget(mSearchBar); + //mLayout->addWidget(mpSearchBtn); + mLayout->addWidget(mpDeleteBtn); + mLayout->addWidget(mpCloseBtn); + mLayout->addWidget(mpRemoveFavoriteBtn); + setCurrentState( IN_ROOT ); + mpDeleteBtn->setAcceptDrops(true); + setAcceptDrops( true ); +} + +void UBFeaturesActionBar::setCurrentState( UBFeaturesActionBarState state ) +{ + currentState = state; + setButtons(); +} + +void UBFeaturesActionBar::setButtons() +{ + switch( currentState ) + { + case IN_FOLDER: + mpFavoriteBtn->show(); + mpSocialBtn->hide(); + mSearchBar->show(); + mpDeleteBtn->show(); + mpCloseBtn->hide(); + mpRemoveFavoriteBtn->hide(); + mpNewFolderBtn->show(); + mpNewFolderBtn->setEnabled(true); + mpDeleteBtn->setEnabled(true); + break; + case IN_ROOT: + mpFavoriteBtn->show(); + mpSocialBtn->hide(); + mSearchBar->show(); + mpDeleteBtn->show(); + mpCloseBtn->hide(); + mpRemoveFavoriteBtn->hide(); + mpNewFolderBtn->show(); + mpNewFolderBtn->setEnabled(false); + mpDeleteBtn->setEnabled(false); + break; + case IN_PROPERTIES: + mpFavoriteBtn->show(); + mpSocialBtn->hide(); + mSearchBar->show(); + //mpSearchBtn->show(); + mpDeleteBtn->hide(); + mpCloseBtn->hide(); + mpRemoveFavoriteBtn->hide(); + mpNewFolderBtn->hide(); + break; + case IN_FAVORITE: + mpFavoriteBtn->hide(); + mpSocialBtn->hide(); + mSearchBar->show(); + //mpSearchBtn->show(); + mpDeleteBtn->hide(); + mpCloseBtn->hide(); + mpRemoveFavoriteBtn->show(); + mpNewFolderBtn->hide(); + break; + default: + break; + } +} + +void UBFeaturesActionBar::onSearchTextChanged(QString txt) +{ + Q_UNUSED(txt) + emit searchElement(mSearchBar->text()); +} + +void UBFeaturesActionBar::onActionNewFolder() +{ + emit newFolderToCreate(); +} + +/* +void UBFeaturesActionBar::dragMoveEvent(QDragMoveEvent *event) +{ + event->acceptProposedAction(); +} +*/ + +void UBFeaturesActionBar::dragEnterEvent( QDragEnterEvent *event ) +{ + if (event->mimeData()->hasFormat("text/uri-list")) + event->acceptProposedAction(); +} + +void UBFeaturesActionBar::dropEvent( QDropEvent *event ) +{ + QWidget *dest = childAt( event->pos() ); + if ( dest == mpDeleteBtn ) + { + event->setDropAction( Qt::MoveAction ); + event->accept(); + emit deleteElements( *event->mimeData() ); + } + else if ( dest == mpFavoriteBtn ) + { + event->setDropAction( Qt::CopyAction ); + event->accept(); + emit addToFavorite( *event->mimeData() ); + } + else if ( dest == mpRemoveFavoriteBtn ) + { + event->setDropAction( Qt::MoveAction ); + event->accept(); + emit removeFromFavorite( *event->mimeData() ); + } +} + +UBFeaturesActionBar::~UBFeaturesActionBar() +{ +} diff --git a/src/gui/UBFeaturesActionBar.h b/src/gui/UBFeaturesActionBar.h new file mode 100644 index 00000000..653fbbac --- /dev/null +++ b/src/gui/UBFeaturesActionBar.h @@ -0,0 +1,68 @@ +#ifndef UBFEATURESACTIONBAR_H +#define UBFEATURESACTIONBAR_H + +#include +#include +#include +#include "UBLibActionBar.h" +#include "board/UBFeaturesController.h" + +enum UBFeaturesActionBarState +{ + IN_ROOT, + IN_FOLDER, + IN_PROPERTIES, + IN_FAVORITE +}; + +class UBFeaturesActionBar : public QWidget +{ + Q_OBJECT +public: + UBFeaturesActionBar(UBFeaturesController *controller, QWidget* parent=0, const char* name="UBFeaturesActionBar"); + ~UBFeaturesActionBar(); + + void setCurrentState( UBFeaturesActionBarState state ); +signals: + void searchElement(const QString &text); + void newFolderToCreate(); + void deleteElements( const QMimeData &data ); + void addToFavorite( const QMimeData &data ); + void removeFromFavorite( const QMimeData &data ); +private slots: + void onSearchTextChanged(QString txt); + void onActionNewFolder(); +protected: + //void dragMoveEvent(QDragMoveEvent *event); + void dragEnterEvent( QDragEnterEvent *event ); + void dropEvent( QDropEvent *event ); +private: + void setButtons(); + UBFeaturesController *featuresController; + UBFeaturesActionBarState currentState; + + eButtonSet mCrntButtonSet; + eButtonSet mPreviousButtonSet; + + QButtonGroup* mButtonGroup; + QLineEdit* mSearchBar; + QHBoxLayout* mLayout; + QAction* mpFavoriteAction; + QAction* mpSocialAction; + QAction* mpDeleteAction; + QAction* mpSearchAction; + QAction* mpCloseAction; + QAction* mpRemoveFavorite; + QAction* mpNewFolderAction; + UBActionButton* mpFavoriteBtn; + UBActionButton* mpSocialBtn; + UBActionButton* mpDeleteBtn; + //UBActionButton* mpSearchBtn; + UBActionButton* mpCloseBtn; + UBActionButton* mpRemoveFavoriteBtn; + UBActionButton* mpNewFolderBtn; + +}; + + +#endif \ No newline at end of file diff --git a/src/gui/UBFeaturesWidget.cpp b/src/gui/UBFeaturesWidget.cpp new file mode 100644 index 00000000..e3affd5c --- /dev/null +++ b/src/gui/UBFeaturesWidget.cpp @@ -0,0 +1,737 @@ +#include "UBFeaturesWidget.h" +#include "domain/UBAbstractWidget.h" +#include "gui/UBThumbnailWidget.h" +#include "gui/UBLibraryWidget.h" +#include "frameworks/UBFileSystemUtils.h" +#include "core/UBApplication.h" +#include "core/UBDownloadManager.h" +#include "globals/UBGlobals.h" + +UBFeaturesWidget::UBFeaturesWidget(QWidget *parent, const char *name):UBDockPaletteWidget(parent) +{ + setObjectName(name); + mName = "FeaturesWidget"; + mVisibleState = true; + + SET_STYLE_SHEET(); + //setAttribute(Qt::WA_StyledBackground, true); + //setStyleSheet(UBApplication::globalStyleSheet()); + + mIconToLeft = QPixmap(":images/library_open.png"); + mIconToRight = QPixmap(":images/library_close.png"); + setAcceptDrops(true); + + stackedWidget = new QStackedWidget(this); + layout = new QVBoxLayout(this); + + controller = new UBFeaturesController(this); + + featuresModel = new UBFeaturesModel(this); + featuresModel->setFeaturesList( controller->getFeatures() ); + featuresModel->setSupportedDragActions( Qt::CopyAction | Qt::MoveAction ); + featuresListView = new UBFeaturesListView(this); + pathListView = new UBFeaturesListView(this); + + + featuresProxyModel = new UBFeaturesProxyModel(this); + featuresProxyModel->setFilterFixedString( controller->getRootPath() ); + featuresProxyModel->setSourceModel( featuresModel ); + featuresProxyModel->setFilterCaseSensitivity( Qt::CaseInsensitive ); + + featuresSearchModel = new UBFeaturesSearchProxyModel(this); + featuresSearchModel->setSourceModel( featuresModel ); + featuresSearchModel->setFilterCaseSensitivity( Qt::CaseInsensitive ); + + featuresPathModel = new UBFeaturesPathProxyModel(this); + featuresPathModel->setPath( controller->getRootPath() ); + featuresPathModel->setSourceModel( featuresModel ); + + + //featuresListView->setStyleSheet( QString("background: #EEEEEE;border-radius: 10px;border: 2px solid #999999;") ); + featuresListView->setDragDropMode( QAbstractItemView::DragDrop ); + featuresListView->setModel( featuresProxyModel ); + + featuresListView->setResizeMode( QListView::Adjust ); + featuresListView->setViewMode( QListView::IconMode ); + itemDelegate = new UBFeaturesItemDelegate( this, featuresListView ); + featuresListView->setItemDelegate( itemDelegate ); + + featuresListView->setIconSize( QSize(defaultThumbnailSize, defaultThumbnailSize) ); + featuresListView->setGridSize( QSize(defaultThumbnailSize * 1.75, defaultThumbnailSize * 1.75) ); + + //pathListView->setStyleSheet( QString("background: #EEEEEE; border-radius : 10px; border : 2px solid #999999;") ); + pathListView->setModel( featuresPathModel ); + pathListView->setViewMode( QListView::IconMode ); + pathListView->setIconSize( QSize(defaultThumbnailSize - 10, defaultThumbnailSize - 10) ); + pathListView->setGridSize( QSize(defaultThumbnailSize + 10, defaultThumbnailSize - 10) ); + pathListView->setFixedHeight( 60 ); + pathItemDelegate = new UBFeaturesPathItemDelegate( this ); + pathListView->setItemDelegate( pathItemDelegate ); + pathListView->setSelectionMode( QAbstractItemView::NoSelection ); + pathListView->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); + pathListView->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOn ); + //pathListView->setResizeMode( QListView::Adjust ); + //pathListView->setMovement( QListView::Static ); + pathListView->setDragDropMode( QAbstractItemView::DragDrop ); + + pathScene = new QGraphicsScene(this); + //pathViewer = new UBFeaturesPathViewer( QPixmap(":images/libpalette/home.png"), controller->getRootPath(), pathScene, this ); + featureProperties = new UBFeatureProperties(this); + + //layout->addWidget( pathViewer ); + //pathViewer->show(); + //layout->addWidget( featuresListView ); + layout->addWidget( pathListView ); + layout->addWidget( stackedWidget ); + + stackedWidget->addWidget( featuresListView ); + stackedWidget->addWidget( featureProperties ); + stackedWidget->setCurrentIndex(ID_LISTVIEW); + currentStackedWidget = ID_LISTVIEW; + + mActionBar = new UBFeaturesActionBar(controller, this); + thumbSlider = new QSlider( Qt::Horizontal, featuresListView ); + thumbSlider->setMinimum( minThumbnailSize ); + thumbSlider->setMaximum( maxThumbnailSize ); + thumbSlider->setValue( defaultThumbnailSize ); + //qDebug() << "init" << featuresListView->height(); + thumbSlider->move( 0, featuresListView->height() ); + thumbSlider->resize( thumbSlider->width(), thumbSlider->height() + 4 ); + thumbSlider->show(); + featuresListView->installEventFilter(this); + //layout->addWidget( thumbSlider ); + layout->addWidget( mActionBar ); + + /*connect(featuresListView->selectionModel(), SIGNAL(currentChanged ( const QModelIndex &, const QModelIndex & )), + this, SLOT(currentSelected(const QModelIndex &)));*/ + connect( featuresListView, SIGNAL(clicked ( const QModelIndex & ) ), + this, SLOT( currentSelected(const QModelIndex &) ) ); + connect( mActionBar, SIGNAL( searchElement(const QString &) ), this, SLOT( const searchStarted(QString &) ) ); + connect( mActionBar, SIGNAL( newFolderToCreate() ), this, SLOT( createNewFolder() ) ); + connect( mActionBar, SIGNAL( deleteElements(const QMimeData &) ), this, SLOT( deleteElements(const QMimeData &) ) ); + connect( mActionBar, SIGNAL( addToFavorite(const QMimeData &) ), this, SLOT( addToFavorite(const QMimeData &) ) ); + connect( mActionBar, SIGNAL( removeFromFavorite(const QMimeData &) ), this, SLOT( removeFromFavorite(const QMimeData &) ) ); + connect( pathListView, SIGNAL(clicked( const QModelIndex & ) ), + this, SLOT( currentPathChanged( const QModelIndex & ) ) ); + connect( thumbSlider, SIGNAL( sliderMoved(int) ), this, SLOT(thumbnailSizeChanged( int ) ) ); +} + +bool UBFeaturesWidget::eventFilter( QObject *target, QEvent *event ) +{ + if ( target == featuresListView && event->type() == QEvent::Resize ) + { + thumbSlider->move( 10, featuresListView->height() - thumbSlider->height() - 10 ); + thumbSlider->resize( featuresListView->width() - 20, thumbSlider->height() ); + //qDebug() << featuresListView->height(); + //return true; + } + return UBDockPaletteWidget::eventFilter(target, event); +} + +void UBFeaturesWidget::searchStarted( const QString &pattern ) +{ + if ( pattern.isEmpty() ) + { + featuresListView->setModel( featuresProxyModel ); + featuresProxyModel->invalidate(); + } + else if ( pattern.size() > 2 ) + { + featuresSearchModel->setFilterWildcard( "*" + pattern + "*" ); + featuresListView->setModel( featuresSearchModel ); + featuresSearchModel->invalidate(); + } +} + +void UBFeaturesWidget::currentSelected(const QModelIndex ¤t) +{ + if (current.isValid()) + { + QSortFilterProxyModel *model = dynamic_cast( featuresListView->model() ); + /*QString name = model->data(current).toString(); + QString path = model->data(current, Qt::UserRole).toString(); + eUBLibElementType type = (eUBLibElementType)model->data(current, Qt::UserRole + 1).toInt();*/ + UBFeature feature = model->data(current, Qt::UserRole + 1).value(); + + if ( feature.isFolder() ) + { + QString newPath = feature.getUrl() + "/" + feature.getName(); + //pathViewer->addPathElement( feature.getThumbnail(), newPath ); + controller->setCurrentElement( feature ); + + model->setFilterFixedString( newPath ); + model->invalidate(); + switchToListView(); + + featuresPathModel->setPath( newPath ); + featuresPathModel->invalidate(); + if ( feature.getType() == FEATURE_FAVORITE ) + { + mActionBar->setCurrentState( IN_FAVORITE ); + } + else + { + mActionBar->setCurrentState( IN_FOLDER ); + } + } + else + { + featureProperties->showElement( feature ); + switchToProperties(); + mActionBar->setCurrentState( IN_PROPERTIES ); + } + + } +} + +void UBFeaturesWidget::currentPathChanged(const QModelIndex &index) +{ + if ( index.isValid() ) + { + UBFeature feature = featuresPathModel->data(index, Qt::UserRole + 1).value(); + QString newPath = feature.getUrl() + "/" + feature.getName(); + + featuresPathModel->setPath( newPath ); + featuresPathModel->invalidate(); + + featuresListView->setModel( featuresProxyModel ); + featuresProxyModel->setFilterFixedString(newPath); + featuresProxyModel->invalidate(); + switchToListView(); + controller->setCurrentElement( feature ); + if ( feature.getType() == FEATURE_CATEGORY && feature.getName() == "root" ) + { + mActionBar->setCurrentState( IN_ROOT ); + } + else if (feature.getType() == FEATURE_FAVORITE) + { + mActionBar->setCurrentState( IN_FAVORITE ); + } + else + { + mActionBar->setCurrentState( IN_FOLDER ); + } + } +} + +void UBFeaturesWidget::createNewFolder() +{ + UBNewFolderDlg dlg; + if(QDialog::Accepted == dlg.exec()) + { + UBFeature newFolder = controller->newFolder( dlg.folderName() ); + featuresModel->addItem( newFolder ); + featuresProxyModel->invalidate(); + } + +} + +void UBFeaturesWidget::deleteElements( const QMimeData & mimeData ) +{ + if ( !mimeData.hasUrls() ) + return; + QList urls = mimeData.urls(); + + foreach ( QUrl url, urls ) + { + if ( controller->isTrash( url ) ) + { + controller->deleteItem( url ); + } + else + { + UBFeature elem = controller->moveItemToFolder( url, controller->getTrashElement() ); + controller->removeFromFavorite( url ); + featuresModel->addItem( elem ); + featuresModel->deleteFavoriteItem( UBFeaturesController::fileNameFromUrl( url ) ); + } + } + QSortFilterProxyModel *model = dynamic_cast( featuresListView->model() ); + model->invalidate(); +} + +void UBFeaturesWidget::addToFavorite( const QMimeData & mimeData ) +{ + if ( !mimeData.hasUrls() ) + return; + QList urls = mimeData.urls(); + + foreach ( QUrl url, urls ) + { + UBFeature elem = controller->addToFavorite( url ); + if ( !elem.getUrl().isEmpty() && !elem.getUrl().isNull() ) + featuresModel->addItem( elem ); + } + QSortFilterProxyModel *model = dynamic_cast( featuresListView->model() ); + model->invalidate(); +} + +void UBFeaturesWidget::removeFromFavorite( const QMimeData & mimeData ) +{ + if ( !mimeData.hasUrls() ) + return; + QList urls = mimeData.urls(); + foreach( QUrl url, urls ) + { + controller->removeFromFavorite( url ); + } +} + +void UBFeaturesWidget::thumbnailSizeChanged( int value ) +{ + featuresListView->setIconSize( QSize( value, value ) ); + featuresListView->setGridSize( QSize( value * 1.75, value * 1.75 ) ); +} + +void UBFeaturesWidget::switchToListView() +{ + stackedWidget->setCurrentIndex(ID_LISTVIEW); + currentStackedWidget = ID_LISTVIEW; +} + +void UBFeaturesWidget::switchToProperties() +{ + stackedWidget->setCurrentIndex(ID_PROPERTIES); + currentStackedWidget = ID_PROPERTIES; +} + + +/* + +void UBFeaturesWidget::currentPathChanged(const QString &path) +{ + int newDepth = path.count("/"); + pathViewer->truncatePath(newDepth); + featuresListView->setModel( featuresProxyModel ); + featuresProxyModel->setFilterFixedString(path); + featuresProxyModel->invalidate(); + switchToListView(); +} +*/ + + +UBFeaturesWidget::~UBFeaturesWidget() +{ +} + +UBFeaturesListView::UBFeaturesListView( QWidget* parent, const char* name ) : QListView(parent) +{ + setObjectName(name); +} + +void UBFeaturesListView::dragEnterEvent( QDragEnterEvent *event ) +{ + if ( event->mimeData()->hasUrls() ) + event->acceptProposedAction(); +} + +void UBFeaturesListView::dropEvent( QDropEvent *event ) +{ + if( event->source() || dynamic_cast( event->source() ) ) + { + event->setDropAction( Qt::MoveAction ); + } + QListView::dropEvent( event ); +} + + +UBFeatureProperties::UBFeatureProperties( QWidget *parent, const char *name ) : QWidget(parent) + , mpLayout(NULL) + , mpButtonLayout(NULL) + , mpAddPageButton(NULL) + , mpAddToLibButton(NULL) + , mpSetAsBackgroundButton(NULL) + , mpObjInfoLabel(NULL) + , mpThumbnail(NULL) + , mpOrigPixmap(NULL) + , mpElement(NULL) +{ + setObjectName(name); + + SET_STYLE_SHEET(); + //setStyleSheet(UBApplication::globalStyleSheet()); + + // Create the GUI + mpLayout = new QVBoxLayout(this); + setLayout(mpLayout); + + maxThumbHeight = height() / 4; + + mpThumbnail = new QLabel(); + QPixmap icon(":images/libpalette/notFound.png"); + icon.scaledToWidth(THUMBNAIL_WIDTH); + + mpThumbnail->setPixmap(icon); + mpThumbnail->setObjectName("DockPaletteWidgetBox"); + mpThumbnail->setStyleSheet("background:white;"); + mpThumbnail->setAlignment(Qt::AlignHCenter); + mpLayout->addWidget(mpThumbnail, 0); + + mpButtonLayout = new QHBoxLayout(); + mpLayout->addLayout(mpButtonLayout, 0); + + mpAddPageButton = new UBFeatureItemButton(); + mpAddPageButton->setText(tr("Add to page")); + mpButtonLayout->addWidget(mpAddPageButton); + + mpSetAsBackgroundButton = new UBFeatureItemButton(); + mpSetAsBackgroundButton->setText(tr("Set as background")); + mpButtonLayout->addWidget(mpSetAsBackgroundButton); + + mpAddToLibButton = new UBFeatureItemButton(); + mpAddToLibButton->setText(tr("Add to library")); + mpButtonLayout->addWidget(mpAddToLibButton); + + mpButtonLayout->addStretch(1); + + mpObjInfoLabel = new QLabel(tr("Object informations")); + mpObjInfoLabel->setStyleSheet(QString("color: #888888; font-size : 18px; font-weight:bold;")); + mpLayout->addWidget(mpObjInfoLabel, 0); + + connect(mpAddPageButton, SIGNAL(clicked()), this, SLOT(onAddToPage())); + +} + +void UBFeatureProperties::showElement( const UBFeature &elem ) +{ + if ( mpOrigPixmap ) + { + delete mpOrigPixmap; + mpOrigPixmap = NULL; + } + if ( mpElement ) + { + delete mpElement; + mpElement = NULL; + } + mpElement = new UBFeature( elem ); + mpOrigPixmap = new QPixmap( elem.getThumbnail() ); + mpThumbnail->setPixmap(elem.getThumbnail().scaledToWidth(THUMBNAIL_WIDTH)); + //populateMetadata(); + + if ( UBApplication::isFromWeb( elem.getUrl() ) ) + { + mpAddToLibButton->show(); + /*if(elem->metadatas()["Type"].toLower().contains("image")) + { + mpSetAsBackgroundButton->show(); + } + else + { + mpSetAsBackgroundButton->hide(); + }*/ + } + else + { + mpAddToLibButton->hide(); + if (UBFileSystemUtils::mimeTypeFromFileName( elem.getUrl() ).contains("image")) + { + mpSetAsBackgroundButton->show(); + } + else + { + mpSetAsBackgroundButton->hide(); + } + } +} + +void UBFeatureProperties::onAddToPage() +{ + QWidget *w = parentWidget()->parentWidget(); + UBFeaturesWidget* featuresWidget = dynamic_cast( w ); + featuresWidget->getFeaturesController()->addItemToPage( *mpElement ); + /*if ( UBApplication::isFromWeb( mpElement->getUrl() ) ) + { + sDownloadFileDesc desc; + desc.isBackground = false; + desc.modal = true; + desc.name = QFileInfo( mpElement->getName() ).fileName(); + desc.url = mpElement->getUrl(); + UBDownloadManager::downloadManager()->addFileToDownload(desc); + + } + else + { + QWidget *w = parentWidget()->parentWidget(); + UBFeaturesWidget* featuresWidget = dynamic_cast( w ); + featuresWidget->getFeaturesController()->addItemToPage( *mpElement ); + }*/ +} + +UBFeatureProperties::~UBFeatureProperties() +{ +} + +UBFeatureItemButton::UBFeatureItemButton(QWidget *parent, const char *name):QPushButton(parent) +{ + setObjectName(name); + setStyleSheet(QString("background-color : #DDDDDD; color : #555555; border-radius : 6px; padding : 5px; font-weight : bold; font-size : 12px;")); +} + +UBFeatureItemButton::~UBFeatureItemButton() +{ + +} + +QVariant UBFeaturesModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) + return QVariant(); + + if (role == Qt::DisplayRole) + return featuresList->at(index.row()).getName(); + else if (role == Qt::DecorationRole) + { + return QIcon( featuresList->at(index.row()).getThumbnail() ); + } + else if (role == Qt::UserRole) + { + return featuresList->at(index.row()).getUrl(); + } + else if (role == Qt::UserRole + 1) + { + //return featuresList->at(index.row()).getType(); + UBFeature f = featuresList->at(index.row()); + return QVariant::fromValue( f ); + } + + return QVariant(); +} + +QMimeData* UBFeaturesModel::mimeData(const QModelIndexList &indexes) const +{ + QMimeData *mimeData = new QMimeData(); + QList urlList; + + foreach (QModelIndex index, indexes) + { + if ( index.isValid() ) + { + UBFeature element = data( index, Qt::UserRole + 1 ).value(); + if ( element.getType() == FEATURE_INTERNAL ) + { + urlList.push_back( QUrl( element.getFullPath() ) ); + } + else if ( element.getType() == FEATURE_INTERACTIVE || element.getType() == FEATURE_ITEM ) + { + urlList.push_back( QUrl::fromLocalFile(element.getFullPath()) ); + } + } + } + mimeData->setUrls( urlList ); + + return mimeData; +} + +bool UBFeaturesModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent) +{ + Q_UNUSED(row) + + if ( !mimeData->hasUrls() ) + return false; + if ( action == Qt::IgnoreAction ) + return true; + if ( column > 0 ) + return false; + + int endRow = 0; + + if ( !parent.isValid() ) + { + return false; + /*if (row < 0) + endRow = featuresList->size(); + else + endRow = qMin( row, featuresList->size() );*/ + } + else + endRow = parent.row(); + Q_UNUSED(endRow) //why do we need this variable? + + UBFeature parentFeature = parent.data( Qt::UserRole + 1).value(); + + QList urls = mimeData->urls(); + + foreach ( QUrl url, urls ) + { + UBFeature element; + + if ( action == Qt::MoveAction ) + { + element = dynamic_cast(QObject::parent())->getFeaturesController()->moveItemToFolder( url, parentFeature ); + } + else + { + element = dynamic_cast(QObject::parent())->getFeaturesController()->copyItemToFolder( url, parentFeature ); + } + addItem( element ); + } + return true; +} + +void UBFeaturesModel::addItem( const UBFeature &item ) +{ + beginInsertRows( QModelIndex(), featuresList->size(), featuresList->size() ); + featuresList->push_back( item ); + endInsertRows(); +} + +void UBFeaturesModel::deleteFavoriteItem( const QString &path ) +{ + for ( int i = 0; i < featuresList->size(); ++i ) + { + if ( !QString::compare( featuresList->at(i).getFullPath(), path, Qt::CaseInsensitive ) && + !QString::compare( featuresList->at(i).getUrl(), "/root/favorites", Qt::CaseInsensitive ) ) + { + removeRow( i, QModelIndex() ); + return; + } + } +} + +bool UBFeaturesModel::removeRows( int row, int count, const QModelIndex & parent ) +{ + if ( row < 0 ) + return false; + if ( row + count > featuresList->size() ) + return false; + beginRemoveRows( parent, row, row + count - 1 ); + //featuresList->remove( row, count ); + featuresList->erase( featuresList->begin() + row, featuresList->begin() + row + count ); + endRemoveRows(); + return true; +} + +bool UBFeaturesModel::removeRow( int row, const QModelIndex & parent ) +{ + if ( row < 0 ) + return false; + if ( row >= featuresList->size() ) + return false; + beginRemoveRows( parent, row, row ); + //featuresList->remove( row ); + featuresList->erase( featuresList->begin() + row ); + endRemoveRows(); + return true; +} + +Qt::ItemFlags UBFeaturesModel::flags( const QModelIndex &index ) const +{ + Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index); + if ( index.isValid() ) + { + UBFeature item = index.data( Qt::UserRole + 1 ).value(); + if ( item.getType() == FEATURE_INTERACTIVE || + item.getType() == FEATURE_ITEM || + item.getType() == FEATURE_INTERNAL ) + return Qt::ItemIsDragEnabled | defaultFlags; + if ( item.isFolder() && !item.getFullPath().isNull() ) + return defaultFlags | Qt::ItemIsDropEnabled; + else return defaultFlags; + } + return defaultFlags | Qt::ItemIsDropEnabled; +} + + +QStringList UBFeaturesModel::mimeTypes() const +{ + QStringList types; + types << "text/uri-list"; + return types; +} + +int UBFeaturesModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + else + return featuresList->size(); +} + + +bool UBFeaturesProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex & sourceParent )const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + QString path = index.data( Qt::UserRole ).toString(); + + return filterRegExp().exactMatch(path); +} + +bool UBFeaturesSearchProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex & sourceParent )const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + /*QString name = sourceModel()->data(index, Qt::DisplayRole).toString(); + eUBLibElementType type = (eUBLibElementType)sourceModel()->data(index, Qt::UserRole + 1).toInt();*/ + + UBFeature feature = sourceModel()->data(index, Qt::UserRole + 1).value(); + bool isFile = feature.getType() == FEATURE_INTERACTIVE || + feature.getType() == FEATURE_INTERNAL || + feature.getType() == FEATURE_ITEM; + + return isFile && filterRegExp().exactMatch( feature.getName() ); +} + +bool UBFeaturesPathProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex & sourceParent )const +{ + QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); + /*QString name = sourceModel()->data(index, Qt::DisplayRole).toString(); + eUBLibElementType type = (eUBLibElementType)sourceModel()->data(index, Qt::UserRole + 1).toInt();*/ + + UBFeature feature = sourceModel()->data(index, Qt::UserRole + 1).value(); + QString virtualFullPath = feature.getUrl() + "/" + feature.getName(); + + return feature.isFolder() && path.startsWith( virtualFullPath ); +} + +QString UBFeaturesItemDelegate::displayText ( const QVariant & value, const QLocale & locale ) const +{ + Q_UNUSED(locale) + + QString text = value.toString(); + if (listView) + { + const QFontMetrics fm = listView->fontMetrics(); + const QSize iSize = listView->iconSize(); + + if ( iSize.width() > 0 && fm.width(text) > iSize.width() ) + { + while (fm.width(text) > iSize.width()) + text.resize(text.size()-1); + text += "..."; + } + } + return text; +} + +UBFeaturesPathItemDelegate::UBFeaturesPathItemDelegate(QWidget *parent) : QStyledItemDelegate(parent) +{ + arrowPixmap = new QPixmap(":images/navig_arrow.png"); +} + +QString UBFeaturesPathItemDelegate::displayText ( const QVariant & value, const QLocale & locale ) const +{ + Q_UNUSED(value) + Q_UNUSED(locale) + + return QString(); +} + +void UBFeaturesPathItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + UBFeature feature = index.data( Qt::UserRole + 1 ).value(); + QRect rect = option.rect; + if ( !feature.getFullPath().isEmpty() ) + { + painter->drawPixmap( rect.left() - 10, rect.center().y() - 5, *arrowPixmap ); + } + painter->drawPixmap( rect.left() + 5, rect.center().y() - 5, feature.getThumbnail().scaledToHeight( 30, Qt::SmoothTransformation ) ); +} + +UBFeaturesPathItemDelegate::~UBFeaturesPathItemDelegate() +{ + if ( arrowPixmap ) + { + delete arrowPixmap; + arrowPixmap = NULL; + } +} diff --git a/src/gui/UBFeaturesWidget.h b/src/gui/UBFeaturesWidget.h new file mode 100644 index 00000000..ea718f22 --- /dev/null +++ b/src/gui/UBFeaturesWidget.h @@ -0,0 +1,241 @@ +#ifndef UBFEATURESWIDGET_H +#define UBFEATURESWIDGET_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "UBDockPaletteWidget.h" +//#include "UBLibActionBar.h" +#include "board/UBFeaturesController.h" +#include "UBFeaturesActionBar.h" + + +#define THUMBNAIL_WIDTH 400 +#define ID_LISTVIEW 0 +#define ID_PROPERTIES 1 + +class UBListModel; + +class UBFeaturesModel; +class UBFeaturesItemDelegate; +class UBFeaturesPathItemDelegate; +class UBFeaturesProxyModel; +class UBFeaturesSearchProxyModel; +class UBFeaturesPathProxyModel; +class UBFeaturesPathViewer; +class UBFeatureProperties; +class UBFeatureItemButton; +class UBFeaturesListView; + +class UBFeaturesWidget : public UBDockPaletteWidget +{ + Q_OBJECT +public: + UBFeaturesWidget(QWidget* parent=0, const char* name="UBFeaturesWidget"); + virtual ~UBFeaturesWidget(); + + bool visibleInMode(eUBDockPaletteWidgetMode mode) + { + return mode == eUBDockPaletteWidget_BOARD + || mode == eUBDockPaletteWidget_DESKTOP; + } + UBFeaturesController * getFeaturesController()const { return controller; }; + + static const int minThumbnailSize = 20; + static const int maxThumbnailSize = 100; + static const int defaultThumbnailSize = 40; +private: + void switchToListView(); + void switchToProperties(); + + UBFeaturesController *controller; + + UBFeaturesItemDelegate *itemDelegate; + UBFeaturesPathItemDelegate *pathItemDelegate; + + UBFeaturesModel *featuresModel; + UBFeaturesProxyModel *featuresProxyModel; + UBFeaturesSearchProxyModel *featuresSearchModel; + UBFeaturesPathProxyModel *featuresPathModel; + + UBFeaturesListView *featuresListView; + UBFeaturesListView *pathListView; + + QSlider *thumbSlider; + QVBoxLayout *layout; + //UBFeaturesPathViewer *pathViewer; + QGraphicsScene *pathScene; + UBFeaturesActionBar *mActionBar; + UBFeatureProperties *featureProperties; + QStackedWidget *stackedWidget; + + int currentStackedWidget; + QModelIndex trashIndex; +private slots: + void currentSelected( const QModelIndex & ); + //void currentPathChanged(const QString &); + void currentPathChanged( const QModelIndex & ); + void searchStarted( const QString & ); + void createNewFolder(); + void deleteElements( const QMimeData & ); + void addToFavorite( const QMimeData & ); + void removeFromFavorite( const QMimeData & ); + void thumbnailSizeChanged( int ); +protected: + bool eventFilter(QObject *target, QEvent *event); +}; + +class UBFeaturesListView : public QListView +{ + Q_OBJECT +public: + UBFeaturesListView( QWidget* parent=0, const char* name="UBFeaturesListView" ); + virtual ~UBFeaturesListView() {;} +protected: + virtual void dragEnterEvent( QDragEnterEvent *event ); + virtual void dropEvent( QDropEvent *event ); +}; + + +class UBFeatureProperties : public QWidget +{ + Q_OBJECT +public: + UBFeatureProperties(QWidget* parent=0, const char* name="UBFeatureProperties"); + ~UBFeatureProperties(); + + void showElement(const UBFeature &elem); + + +protected: + //void resizeEvent(QResizeEvent *event); + //void showEvent(QShowEvent *event); + +private slots: + void onAddToPage(); + //void onAddToLib(); + //void onSetAsBackground(); + //void onBack(); + +private: + QVBoxLayout* mpLayout; + QHBoxLayout* mpButtonLayout; + UBFeatureItemButton* mpAddPageButton; + UBFeatureItemButton* mpAddToLibButton; + UBFeatureItemButton* mpSetAsBackgroundButton; + QLabel* mpObjInfoLabel; + //QTreeWidget* mpObjInfos; + QLabel* mpThumbnail; + QPixmap* mpOrigPixmap; + int maxThumbHeight; + UBFeature *mpElement; + //QTreeWidgetItem* mpItem; +}; + + + + +class UBFeatureItemButton : public QPushButton +{ +public: + UBFeatureItemButton(QWidget* parent=0, const char* name="UBFeatureItemButton"); + ~UBFeatureItemButton(); +}; + +class UBFeaturesModel : public QAbstractListModel +{ + Q_OBJECT +public: + UBFeaturesModel( QObject *parent = 0 ) : QAbstractListModel(parent) {;} + virtual ~UBFeaturesModel(){;} + + void addItem( const UBFeature &item ); + void deleteFavoriteItem( const QString &path ); + + QVariant data( const QModelIndex &index, int role = Qt::DisplayRole ) const; + QMimeData *mimeData( const QModelIndexList &indexes ) const; + QStringList mimeTypes() const; + int rowCount( const QModelIndex &parent ) const; + Qt::ItemFlags flags( const QModelIndex &index ) const; + bool dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent); + bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); + bool removeRow(int row, const QModelIndex &parent = QModelIndex()); + + Qt::DropActions supportedDropActions() const { return Qt::MoveAction | Qt::CopyAction; } + + void setFeaturesList( QList *flist ) { featuresList = flist; } +private: + QList *featuresList; +}; + +class UBFeaturesProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + UBFeaturesProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {;} + virtual ~UBFeaturesProxyModel() {} +protected: + virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex & sourceParent ) const; +}; + +class UBFeaturesSearchProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + UBFeaturesSearchProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {;} + virtual ~UBFeaturesSearchProxyModel() {} +protected: + virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex & sourceParent ) const; +}; + +class UBFeaturesPathProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + UBFeaturesPathProxyModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {;} + virtual ~UBFeaturesPathProxyModel() {} + void setPath( const QString &p ) { path = p; } +protected: + virtual bool filterAcceptsRow ( int sourceRow, const QModelIndex & sourceParent ) const; +private: + QString path; +}; + +class UBFeaturesItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + UBFeaturesItemDelegate(QWidget *parent = 0, const QListView *lw = 0) : QStyledItemDelegate(parent) { listView = lw; } + ~UBFeaturesItemDelegate() {} + //UBFeaturesItemDelegate(const QListView *lw = 0) { listView = lw; }; + //void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + //QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; + virtual QString displayText ( const QVariant & value, const QLocale & locale ) const; +private: + const QListView *listView; +}; + +class UBFeaturesPathItemDelegate : public QStyledItemDelegate +{ + Q_OBJECT +public: + UBFeaturesPathItemDelegate(QWidget *parent = 0); + ~UBFeaturesPathItemDelegate(); + virtual QString displayText ( const QVariant & value, const QLocale & locale ) const; + void paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; +private: + QPixmap *arrowPixmap; +}; + +#endif // UBFEATURESWIDGET_H diff --git a/src/gui/UBLibraryWidget.h b/src/gui/UBLibraryWidget.h index e4eb8d02..7f3bbeb4 100644 --- a/src/gui/UBLibraryWidget.h +++ b/src/gui/UBLibraryWidget.h @@ -29,6 +29,7 @@ #include #include "UBThumbnailWidget.h" +#include "board/UBLibraryController.h" class UBLibraryController; class UBChainedLibElement; diff --git a/src/gui/gui.pri b/src/gui/gui.pri index a901409f..a1dd1218 100644 --- a/src/gui/gui.pri +++ b/src/gui/gui.pri @@ -46,6 +46,8 @@ HEADERS += src/gui/UBThumbnailView.h \ src/gui/UBLibWebView.h \ src/gui/UBDownloadWidget.h \ src/gui/UBDockDownloadWidget.h \ + src/gui/UBFeaturesWidget.h \ + src/gui/UBFeaturesActionBar.h \ src/gui/UBDockTeacherGuideWidget.h \ src/gui/UBTeacherGuideWidget.h \ src/gui/UBTeacherGuideWidgetsTools.h \ @@ -99,6 +101,8 @@ SOURCES += src/gui/UBThumbnailView.cpp \ src/gui/UBLibWebView.cpp \ src/gui/UBDownloadWidget.cpp \ src/gui/UBDockDownloadWidget.cpp \ + src/gui/UBFeaturesWidget.cpp \ + src/gui/UBFeaturesActionBar.cpp \ src/gui/UBDockTeacherGuideWidget.cpp \ src/gui/UBTeacherGuideWidget.cpp \ src/gui/UBTeacherGuideWidgetsTools.cpp \