diff --git a/Sankore_3.1.pro b/Sankore_3.1.pro
index 96c00aa1..6d4112ae 100644
--- a/Sankore_3.1.pro
+++ b/Sankore_3.1.pro
@@ -367,6 +367,7 @@ linux-g++-32 {
linux-g++-64 {
LIBS += -lcrypto
+ LIBS += -lX11
QMAKE_CFLAGS += -fopenmp
QMAKE_CXXFLAGS += -fopenmp
QMAKE_LFLAGS += -fopenmp
diff --git a/resources/forms/mainWindow.ui b/resources/forms/mainWindow.ui
index 7704a319..f8c9ba81 100644
--- a/resources/forms/mainWindow.ui
+++ b/resources/forms/mainWindow.ui
@@ -69,6 +69,7 @@
+
@@ -1633,6 +1634,21 @@
Import old Sankore or Uniboard documents
+
+
+ false
+
+
+
+ :/images/toolbar/library.png:/images/toolbar/library.png
+
+
+ Gtorup items
+
+
+ Erase Content
+
+
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/UBBoardController.cpp b/src/board/UBBoardController.cpp
index 612ee6b1..d3faba2b 100644
--- a/src/board/UBBoardController.cpp
+++ b/src/board/UBBoardController.cpp
@@ -1809,7 +1809,7 @@ UBGraphicsWidgetItem *UBBoardController::addW3cWidget(const QUrl &pUrl, const QP
newUrl = QUrl::fromLocalFile(UBPersistenceManager::persistenceManager()->addGraphicsWidgteToDocument(mActiveDocument, pUrl.toLocalFile(), uuid));
- w3cWidgetItem = mActiveScene->addW3CWidget(pUrl, pos);
+ w3cWidgetItem = mActiveScene->addW3CWidget(newUrl, pos);
if (w3cWidgetItem) {
w3cWidgetItem->setUuid(uuid);
diff --git a/src/board/UBBoardPaletteManager.cpp b/src/board/UBBoardPaletteManager.cpp
index f21c089b..51b8622e 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,8 +154,15 @@ void UBBoardPaletteManager::setupDockPaletteWidgets()
mRightPalette = new UBRightPalette(mContainer);
// RIGHT palette widgets
- mRightPalette->registerWidget(mpLibWidget);
- mRightPalette->addTab(mpLibWidget);
+
+ mRightPalette->registerWidget(mpFeaturesWidget);
+ mRightPalette->addTab(mpFeaturesWidget);
+
+ //Do not show deprecated lib widget to prevent collisions. Uncomment to return lib widget
+// mRightPalette->registerWidget(mpLibWidget);
+// mRightPalette->addTab(mpLibWidget);
+
+
// The cache widget will be visible only if a cache is put on the page
mRightPalette->registerWidget(mpCachePropWidget);
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 288eecd8..3dd30148 100644
--- a/src/board/UBBoardView.cpp
+++ b/src/board/UBBoardView.cpp
@@ -16,6 +16,7 @@
#include
#include
+#include
#include "UBDrawingController.h"
@@ -433,7 +434,9 @@ void UBBoardView::mousePressEvent (QMouseEvent *event)
|| movingItem->type() == UBGraphicsPolygonItem::Type
|| movingItem->type() == UBGraphicsCache::Type
|| movingItem->type() == UBGraphicsTriangle::Type
- || movingItem == this->scene()->backgroundObject())
+ || movingItem == this->scene()->backgroundObject()
+ || movingItem->group())
+
{
movingItem = NULL;
QGraphicsView::mousePressEvent (event);
@@ -841,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/document/UBDocumentProxy.cpp b/src/document/UBDocumentProxy.cpp
index 67f11b0f..c37f9b28 100644
--- a/src/document/UBDocumentProxy.cpp
+++ b/src/document/UBDocumentProxy.cpp
@@ -297,6 +297,8 @@ QString UBDocumentProxy::sessionAuthors()
QDateTime UBDocumentProxy::documentDate()
{
+ qDebug()<< UBSettings::documentDate;
+ qDebug()<pos() - mDragStartPosition).manhattanLength() < QApplication::startDragDistance()))
+ if(NULL != mMimeData)
{
QDrag* mDrag = new QDrag(event->widget());
mDrag->setMimeData(mMimeData);
@@ -227,7 +227,7 @@ bool UBGraphicsItemDelegate::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
return true;
}
else
- return true;
+ return false;
}
bool UBGraphicsItemDelegate::weelEvent(QGraphicsSceneWheelEvent *event)
diff --git a/src/domain/UBGraphicsItemDelegate.h b/src/domain/UBGraphicsItemDelegate.h
index 828f98d1..f560b546 100644
--- a/src/domain/UBGraphicsItemDelegate.h
+++ b/src/domain/UBGraphicsItemDelegate.h
@@ -184,15 +184,12 @@ class UBGraphicsItemDelegate : public QObject
QList mButtons;
protected slots:
-
virtual void gotoContentSource(bool checked);
private:
void updateFrame();
void updateButtons(bool showUpdated = false);
-
-
QPointF mOffset;
QTransform mPreviousTransform;
QPointF mPreviousPosition;
diff --git a/src/domain/UBGraphicsPolygonItem.cpp b/src/domain/UBGraphicsPolygonItem.cpp
index 9569dcd9..f05dd1e9 100644
--- a/src/domain/UBGraphicsPolygonItem.cpp
+++ b/src/domain/UBGraphicsPolygonItem.cpp
@@ -184,6 +184,19 @@ void UBGraphicsPolygonItem::paint ( QPainter * painter, const QStyleOptionGraphi
QGraphicsPolygonItem::paint(painter, option, widget);
}
+QPainterPath UBGraphicsPolygonItem::shape() const
+{
+
+ QPainterPath path;
+ path.addRect(boundingRect());
+
+ return path;
+
+// static QPainterPath shapePath = QGraphicsPolygonItem::shape();
+
+// return shapePath;
+}
+
UBGraphicsScene* UBGraphicsPolygonItem::scene()
{
diff --git a/src/domain/UBGraphicsPolygonItem.h b/src/domain/UBGraphicsPolygonItem.h
index 25895096..2934b66b 100644
--- a/src/domain/UBGraphicsPolygonItem.h
+++ b/src/domain/UBGraphicsPolygonItem.h
@@ -115,6 +115,8 @@ class UBGraphicsPolygonItem : public QGraphicsPolygonItem, public UBItem
protected:
void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget);
+ QPainterPath shape () const;
+
private:
diff --git a/src/domain/UBGraphicsScene.cpp b/src/domain/UBGraphicsScene.cpp
index 04edd9c0..1494ce85 100644
--- a/src/domain/UBGraphicsScene.cpp
+++ b/src/domain/UBGraphicsScene.cpp
@@ -30,6 +30,7 @@
#include "core/UBPersistenceManager.h"
#include "gui/UBMagnifer.h"
+#include "gui/UBMainWindow.h"
#include "tools/UBGraphicsRuler.h"
#include "tools/UBGraphicsProtractor.h"
@@ -56,6 +57,8 @@
#include "UBGraphicsTextItem.h"
#include "UBGraphicsStrokesGroup.h"
+#include "domain/ubgraphicsgroupcontaineritem.h"
+
#include "UBAppleWidget.h"
#include "UBW3CWidget.h"
#include "UBGraphicsStroke.h"
@@ -158,9 +161,6 @@ qreal UBZLayerController::changeZLevelTo(QGraphicsItem *item, moveDestination de
while (iCurElement.hasNext() && iCurElement.peekNext().value()->data(UBGraphicsItemData::ItemOwnZValue).toReal() == nextZ) {
UBGraphicsItem::assignZValue(iCurElement.next().value(), nextZ);
}
-
- item->scene()->clearSelection();
- item->setSelected(true);
}
}
@@ -256,6 +256,7 @@ UBGraphicsScene::UBGraphicsScene(UBDocumentProxy* parent)
, mDocument(parent)
, mDarkBackground(false)
, mCrossedBackground(false)
+ , mIsDesktopMode(false)
, mIsModified(true)
, mBackgroundObject(0)
, mPreviousWidth(0)
@@ -269,7 +270,6 @@ UBGraphicsScene::UBGraphicsScene(UBDocumentProxy* parent)
, magniferControlViewWidget(0)
, magniferDisplayViewWidget(0)
, mZLayerController(new UBZLayerController(this))
- , mIsDesktopMode(false)
, mpLastPolygon(NULL)
{
UBCoreGraphicsScene::setObjectName("BoardScene");
@@ -291,6 +291,9 @@ UBGraphicsScene::UBGraphicsScene(UBDocumentProxy* parent)
}
connect(this, SIGNAL(selectionChanged()), this, SLOT(selectionChangedProcessing()));
+ connect(this, SIGNAL(selectionChanged()), this, SLOT(enableGroupingButton()));
+
+ connect(UBApplication::mainWindow->actionGroupItems, SIGNAL(triggered()), this, SLOT(processGroupItems()));
}
UBGraphicsScene::~UBGraphicsScene()
@@ -309,6 +312,36 @@ void UBGraphicsScene::selectionChangedProcessing()
UBApplication::showMessage("ZValue is " + QString::number(selectedItems().first()->zValue(), 'f') + "own z value is "
+ QString::number(selectedItems().first()->data(UBGraphicsItemData::ItemOwnZValue).toReal(), 'f'));
}
+void UBGraphicsScene::enableGroupingButton()
+{
+ QAction *groupAction = UBApplication::mainWindow->actionGroupItems;
+
+ if (selectedItems().count() > 1) {
+ groupAction->setEnabled(true);
+ } else {
+ groupAction->setEnabled(false);
+ }
+}
+void UBGraphicsScene::processGroupItems()
+{
+ qDebug() << "processing grouping items";
+
+ UBGraphicsGroupContainerItem *groupItem = new UBGraphicsGroupContainerItem();
+
+ foreach (QGraphicsItem *item, selectedItems()) {
+ item->setSelected(false);
+ item->setFlag(QGraphicsItem::ItemIsSelectable, false);
+ item->setFlag( QGraphicsItem::ItemIsMovable, false);
+ item->setFlag(QGraphicsItem::ItemIsFocusable);
+ groupItem->addToGroup(item);
+ }
+
+ addItem(groupItem);
+// groupItem->setPos(50, 50);
+ groupItem->setVisible(true);
+ groupItem->setFocus();
+ qDebug() << groupItem->boundingRect();
+}
// MARK: -
// MARK: Mouse/Tablet events handling
@@ -1984,6 +2017,14 @@ void UBGraphicsScene::setOwnZlevel(QGraphicsItem *item)
{
item->setZValue(item->data(UBGraphicsItemData::ItemOwnZValue).toReal());
}
+void UBGraphicsScene::groupItems(QList &itemList)
+{
+ foreach (QGraphicsItem *item, itemList) {
+ qDebug() << "selected item found";
+ item->setSelected(false);
+ }
+}
+
qreal UBGraphicsScene::changeZLevelTo(QGraphicsItem *item, UBZLayerController::moveDestination dest)
{
diff --git a/src/domain/UBGraphicsScene.h b/src/domain/UBGraphicsScene.h
index fa094a3a..4b9d946f 100644
--- a/src/domain/UBGraphicsScene.h
+++ b/src/domain/UBGraphicsScene.h
@@ -287,6 +287,8 @@ class UBGraphicsScene: public UBCoreGraphicsScene, public UBItem
void setSelectedZLevel(QGraphicsItem *item);
void setOwnZlevel(QGraphicsItem *item);
+
+ void groupItems(QList &itemList);
public slots:
void hideEraser();
@@ -303,6 +305,8 @@ public slots:
void setToolCursor(int tool);
void selectionChangedProcessing();
+ void enableGroupingButton();
+ void processGroupItems();
void moveMagnifier(QPoint newPos);
void closeMagnifier();
diff --git a/src/domain/domain.pri b/src/domain/domain.pri
index c2d33f85..c7ed4466 100644
--- a/src/domain/domain.pri
+++ b/src/domain/domain.pri
@@ -24,6 +24,8 @@ HEADERS += src/domain/UBGraphicsScene.h \
src/domain/UBGraphicsAudioItemDelegate.h \
src/domain/UBAbstractUndoCommand.h\
src/domain/UBAngleWidget.h \
+ src/domain/ubgraphicsgroupcontaineritem.h \
+ src/domain/ubgraphicsgroupcontaineritemdelegate.h \
src/domain/UBGraphicsStrokesGroup.h
HEADERS += src/domain/UBGraphicsItemDelegate.h \
@@ -58,6 +60,8 @@ SOURCES += src/domain/UBGraphicsScene.cpp \
src/domain/UBGraphicsAudioItemDelegate.cpp \
src/domain/UBAbstractUndoCommand.cpp \
src/domain/UBAngleWidget.cpp \
+ src/domain/ubgraphicsgroupcontaineritem.cpp \
+ src/domain/ubgraphicsgroupcontaineritemdelegate.cpp \
src/domain/UBGraphicsStrokesGroup.cpp
SOURCES += src/domain/UBGraphicsItemDelegate.cpp \
diff --git a/src/domain/ubgraphicsgroupcontaineritem.cpp b/src/domain/ubgraphicsgroupcontaineritem.cpp
new file mode 100644
index 00000000..0a706099
--- /dev/null
+++ b/src/domain/ubgraphicsgroupcontaineritem.cpp
@@ -0,0 +1,86 @@
+#include "ubgraphicsgroupcontaineritem.h"
+
+#include
+
+#include "domain/UBGraphicsItemDelegate.h"
+#include "domain/ubgraphicsgroupcontaineritemdelegate.h"
+#include "domain/UBGraphicsScene.h"
+
+UBGraphicsGroupContainerItem::UBGraphicsGroupContainerItem(QGraphicsItem *parent)
+ : QGraphicsItemGroup(parent)
+{
+ setData(UBGraphicsItemData::ItemLayerType, UBItemLayerType::Object);
+
+ mDelegate = new UBGraphicsGroupContainerItemDelegate(this, 0);
+ mDelegate->init();
+
+ setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
+ setFlag(QGraphicsItem::ItemIsSelectable, true);
+ setFlag(QGraphicsItem::ItemIsMovable, true);
+
+ UBGraphicsGroupContainerItem::setAcceptHoverEvents(true);
+
+ setData(UBGraphicsItemData::itemLayerType, QVariant(itemLayerType::ObjectItem)); //Necessary to set if we want z value to be assigned correctly
+}
+
+
+UBGraphicsScene *UBGraphicsGroupContainerItem::scene()
+{
+ UBGraphicsScene *castScene = dynamic_cast(scene());
+
+ return castScene;
+}
+UBGraphicsGroupContainerItem *UBGraphicsGroupContainerItem::deepCopy() const
+{
+
+ UBGraphicsGroupContainerItem *copy = new UBGraphicsGroupContainerItem(parentItem());
+
+ copy->setPos(this->pos());
+ copy->setTransform(this->transform());
+ copy->setFlag(QGraphicsItem::ItemIsMovable, true);
+ copy->setFlag(QGraphicsItem::ItemIsSelectable, true);
+ copy->setData(UBGraphicsItemData::ItemLayerType, this->data(UBGraphicsItemData::ItemLayerType));
+ copy->setData(UBGraphicsItemData::ItemLocked, this->data(UBGraphicsItemData::ItemLocked));
+ copy->setUuid(this->uuid()); // this is OK for now as long as Widgets are imutable
+
+// copy->resize(this->size());
+
+ return copy;
+}
+void UBGraphicsGroupContainerItem::remove()
+{
+ if (mDelegate)
+ mDelegate->remove();
+}
+
+
+void UBGraphicsGroupContainerItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (mDelegate->mousePressEvent(event)) {
+ //NOOP
+ } else {
+ QGraphicsItemGroup::mousePressEvent(event);
+ setSelected(true);
+ }
+}
+
+void UBGraphicsGroupContainerItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
+{
+ if (mDelegate->mouseMoveEvent(event)) {
+ // NOOP;
+ } else {
+ QGraphicsItemGroup::mouseMoveEvent(event);
+ }
+}
+
+void UBGraphicsGroupContainerItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
+{
+ mDelegate->mouseReleaseEvent(event);
+ QGraphicsItemGroup::mouseReleaseEvent(event);
+}
+
+QVariant UBGraphicsGroupContainerItem::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+ QVariant newValue = mDelegate->itemChange(change, value);
+ return QGraphicsItemGroup::itemChange(change, newValue);
+}
diff --git a/src/domain/ubgraphicsgroupcontaineritem.h b/src/domain/ubgraphicsgroupcontaineritem.h
new file mode 100644
index 00000000..193a3ca7
--- /dev/null
+++ b/src/domain/ubgraphicsgroupcontaineritem.h
@@ -0,0 +1,32 @@
+#ifndef UBGRAPHICSGROUPCONTAINERITEM_H
+#define UBGRAPHICSGROUPCONTAINERITEM_H
+
+#include
+
+#include "domain/UBItem.h"
+
+class UBGraphicsGroupContainerItem : public QGraphicsItemGroup, public UBItem, public UBGraphicsItem
+{
+
+public:
+ UBGraphicsGroupContainerItem (QGraphicsItem *parent = 0);
+ virtual UBGraphicsItemDelegate* Delegate() const { return mDelegate;}
+
+ virtual UBGraphicsScene* scene();
+ virtual UBGraphicsGroupContainerItem *deepCopy() const;
+ virtual void remove();
+
+
+protected:
+
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
+ virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
+
+ virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value);
+
+private:
+
+};
+
+#endif // UBGRAPHICSGROUPCONTAINERITEM_H
diff --git a/src/domain/ubgraphicsgroupcontaineritemdelegate.cpp b/src/domain/ubgraphicsgroupcontaineritemdelegate.cpp
new file mode 100644
index 00000000..ff763520
--- /dev/null
+++ b/src/domain/ubgraphicsgroupcontaineritemdelegate.cpp
@@ -0,0 +1,64 @@
+#include "ubgraphicsgroupcontaineritemdelegate.h"
+
+#include
+
+#include "UBGraphicsScene.h"
+#include "gui/UBResources.h"
+
+#include "domain/UBGraphicsDelegateFrame.h"
+#include "domain/ubgraphicsgroupcontaineritem.h"
+
+#include "core/memcheck.h"
+#include "board/UBBoardController.h"
+
+UBGraphicsGroupContainerItemDelegate::UBGraphicsGroupContainerItemDelegate(QGraphicsItem *pDelegated, QObject *parent) :
+ UBGraphicsItemDelegate(pDelegated, parent), mDestroyGroupButton(0)
+
+{
+
+}
+
+UBGraphicsGroupContainerItem *UBGraphicsGroupContainerItemDelegate::delegated()
+{
+ return dynamic_cast(mDelegated);
+}
+
+void UBGraphicsGroupContainerItemDelegate::decorateMenu(QMenu *menu)
+{
+ mLockAction = menu->addAction(tr("Locked"), this, SLOT(lock(bool)));
+ QIcon lockIcon;
+ lockIcon.addPixmap(QPixmap(":/images/locked.svg"), QIcon::Normal, QIcon::On);
+ lockIcon.addPixmap(QPixmap(":/images/unlocked.svg"), QIcon::Normal, QIcon::Off);
+ mLockAction->setIcon(lockIcon);
+ mLockAction->setCheckable(true);
+
+ mShowOnDisplayAction = mMenu->addAction(tr("Visible on Extended Screen"), this, SLOT(showHide(bool)));
+ mShowOnDisplayAction->setCheckable(true);
+
+ QIcon showIcon;
+ showIcon.addPixmap(QPixmap(":/images/eyeOpened.svg"), QIcon::Normal, QIcon::On);
+ showIcon.addPixmap(QPixmap(":/images/eyeClosed.svg"), QIcon::Normal, QIcon::Off);
+ mShowOnDisplayAction->setIcon(showIcon);
+}
+
+void UBGraphicsGroupContainerItemDelegate::buildButtons()
+{
+ UBGraphicsItemDelegate::buildButtons();
+
+ mDestroyGroupButton = new DelegateButton(":/images/font.svg", mDelegated, mFrame, Qt::TopLeftSection);
+
+ mButtons << mDestroyGroupButton;
+
+ connect(mDestroyGroupButton, SIGNAL(clicked()), (UBGraphicsGroupContainerItemDelegate*)this, SLOT(destroyGroup()));
+}
+
+void UBGraphicsGroupContainerItemDelegate::destroyGroup()
+{
+ qDebug() << "got an event";
+ foreach (QGraphicsItem *item, delegated()->childItems()) {
+ delegated()->removeFromGroup(item);
+ item->setFlag(QGraphicsItem::ItemIsSelectable, true);
+ }
+
+ remove(true);
+}
diff --git a/src/domain/ubgraphicsgroupcontaineritemdelegate.h b/src/domain/ubgraphicsgroupcontaineritemdelegate.h
new file mode 100644
index 00000000..7160bb00
--- /dev/null
+++ b/src/domain/ubgraphicsgroupcontaineritemdelegate.h
@@ -0,0 +1,28 @@
+#ifndef UBGRAPHICSGROUPCONTAINERITEMDELEGATE_H
+#define UBGRAPHICSGROUPCONTAINERITEMDELEGATE_H
+
+#include "domain/UBGraphicsItemDelegate.h"
+
+class UBGraphicsGroupContainerItem;
+
+class UBGraphicsGroupContainerItemDelegate : public UBGraphicsItemDelegate
+{
+Q_OBJECT
+
+public:
+ UBGraphicsGroupContainerItemDelegate(QGraphicsItem* pDelegated, QObject * parent = 0);
+ UBGraphicsGroupContainerItem *delegated();
+
+protected:
+ virtual void decorateMenu(QMenu *menu);
+ virtual void buildButtons();
+
+
+private slots:
+ void destroyGroup();
+
+private:
+ DelegateButton *mDestroyGroupButton;
+};
+
+#endif // UBGRAPHICSGROUPCONTAINERITEMDELEGATE_H
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/UBMagnifer.cpp b/src/gui/UBMagnifer.cpp
index 93693797..e13ab4b3 100644
--- a/src/gui/UBMagnifer.cpp
+++ b/src/gui/UBMagnifer.cpp
@@ -314,9 +314,6 @@ void UBMagnifier::grabPoint()
QPointF pfScLtF(UBApplication::boardController->controlView()->mapToScene(QPoint(itemPos.x(), itemPos.y())));
-
- QRect magnifierRect = rect();
-
float x = pfScLtF.x() - zWidthHalf;
float y = pfScLtF.y() - zHeightHalf;
@@ -351,9 +348,6 @@ void UBMagnifier::grabPoint(const QPoint &pGrab)
QPointF pfScLtF(UBApplication::boardController->controlView()->mapToScene(QPoint(itemPos.x(), itemPos.y())));
-
- QRect magnifierRect = rect();
-
float x = pfScLtF.x() - zWidthHalf;
float y = pfScLtF.y() - zHeightHalf;
diff --git a/src/gui/UBTeacherGuideWidget.cpp b/src/gui/UBTeacherGuideWidget.cpp
index 54d9e847..9fc0fdcd 100644
--- a/src/gui/UBTeacherGuideWidget.cpp
+++ b/src/gui/UBTeacherGuideWidget.cpp
@@ -723,10 +723,10 @@ void UBTeacherGuidePageZeroEditionWidget::onActiveSceneChanged()
{
UBDocumentProxy* documentProxy = UBApplication::documentController ? UBApplication::documentController->getCurrentDocument() : 0;
if(UBApplication::documentController && UBApplication::boardController->activeSceneIndex() == 0){
- QDateTime creationDate = documentProxy->documentDate();
- mpCreationLabel->setText(tr("Created the:") + creationDate.toString(Qt::SystemLocaleShortDate));
- QDateTime updatedDate = documentProxy->lastUpdate();
- mpLastModifiedLabel->setText(tr("Updated the:") + updatedDate.toString(Qt::SystemLocaleShortDate));
+// QDateTime creationDate = documentProxy->documentDate();
+// mpCreationLabel->setText(tr("Created the:") + creationDate.toString(Qt::SystemLocaleShortDate));
+// QDateTime updatedDate = documentProxy->lastUpdate();
+// mpLastModifiedLabel->setText(tr("Updated the:") + updatedDate.toString(Qt::SystemLocaleShortDate));
}
}
diff --git a/src/gui/UBThumbnailWidget.cpp b/src/gui/UBThumbnailWidget.cpp
index 96f448d9..a3c631fb 100644
--- a/src/gui/UBThumbnailWidget.cpp
+++ b/src/gui/UBThumbnailWidget.cpp
@@ -32,8 +32,9 @@ UBThumbnailWidget::UBThumbnailWidget(QWidget* parent)
, mSpacing(UBSettings::thumbnailSpacing)
, mLastSelectedThumbnail(0)
, mSelectionSpan(0)
- , mLassoRectItem(0)
, mPrevLassoRect(QRect())
+ , mLassoRectItem(0)
+
{
// By default, the drag is possible
bCanDrag = true;
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 \