From 882dd0c435eb9a43e01819660dc8f4b4aed98a90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luis=20=C3=81ngel=20San=20Mart=C3=ADn?= Date: Sat, 11 May 2013 23:27:31 +0200 Subject: [PATCH] a?adido nuevo widget para gestionar las importacione y actualizaciones En OSX se ha desactivado el uso de QGraphicsOpacityEffect debido a un bug en Qt --- YACReader/notifications_label_widget.cpp | 4 +- YACReaderLibrary/YACReaderLibrary.pro | 6 +- YACReaderLibrary/create_library_dialog.cpp | 1 + YACReaderLibrary/images.qrc | 6 +- YACReaderLibrary/import_widget.cpp | 338 +++++++++++++++++++++ YACReaderLibrary/import_widget.h | 38 +++ YACReaderLibrary/library_creator.cpp | 2 + YACReaderLibrary/library_creator.h | 1 + YACReaderLibrary/library_window.cpp | 32 +- YACReaderLibrary/library_window.h | 6 +- YACReaderLibrary/no_libraries_widget.cpp | 38 ++- images/glowLine.png | Bin 0 -> 460 bytes images/importBottomCoversDecoration.png | Bin 0 -> 138 bytes images/importTopCoversDecoration.png | Bin 0 -> 132 bytes images/importingIcon.png | Bin 0 -> 5746 bytes images/noLibrariesIcon.png | Bin 6143 -> 3923 bytes 16 files changed, 452 insertions(+), 20 deletions(-) create mode 100644 YACReaderLibrary/import_widget.cpp create mode 100644 YACReaderLibrary/import_widget.h create mode 100644 images/glowLine.png create mode 100644 images/importBottomCoversDecoration.png create mode 100644 images/importTopCoversDecoration.png create mode 100644 images/importingIcon.png diff --git a/YACReader/notifications_label_widget.cpp b/YACReader/notifications_label_widget.cpp index 5c8ada5b..ffd82c32 100644 --- a/YACReader/notifications_label_widget.cpp +++ b/YACReader/notifications_label_widget.cpp @@ -42,10 +42,10 @@ NotificationsLabelWidget::NotificationsLabelWidget(QWidget * parent) textLabel->setAttribute(Qt::WA_LayoutUsesWidgetRect,true); textLabel->setGeometry(imgLabel->geometry()); - +#ifndef Q_WS_MAC imgLabel->setGraphicsEffect(effect); textLabel->setGraphicsEffect(effect2); - +#endif resize(p.size()); updatePosition(); diff --git a/YACReaderLibrary/YACReaderLibrary.pro b/YACReaderLibrary/YACReaderLibrary.pro index d7d643e9..ad0040f5 100644 --- a/YACReaderLibrary/YACReaderLibrary.pro +++ b/YACReaderLibrary/YACReaderLibrary.pro @@ -73,7 +73,8 @@ HEADERS += comic_flow.h \ ../common/yacreader_flow_gl.h \ ../common/yacreader_global.h \ ../common/onstart_flow_selection_dialog.h \ - no_libraries_widget.h + no_libraries_widget.h \ + import_widget.h SOURCES += comic_flow.cpp \ create_library_dialog.cpp \ @@ -108,7 +109,8 @@ SOURCES += comic_flow.cpp \ ../common/qnaturalsorting.cpp \ ../common/yacreader_flow_gl.cpp \ ../common/onstart_flow_selection_dialog.cpp \ - no_libraries_widget.cpp + no_libraries_widget.cpp \ + import_widget.cpp include(./server/server.pri) diff --git a/YACReaderLibrary/create_library_dialog.cpp b/YACReaderLibrary/create_library_dialog.cpp index 596258b8..a2d1cfb4 100644 --- a/YACReaderLibrary/create_library_dialog.cpp +++ b/YACReaderLibrary/create_library_dialog.cpp @@ -105,6 +105,7 @@ void CreateLibraryDialog::create() this->adjustSize(); accept->setEnabled(false); emit(createLibrary(QDir::cleanPath(path->text()),QDir::cleanPath(path->text())+"/.yacreaderlibrary",nameEdit->text())); + close(); } else QMessageBox::critical(NULL,tr("Path not found"),tr("The selected path does not exist or is not a valid path. Be sure that you have write access to this folder")); diff --git a/YACReaderLibrary/images.qrc b/YACReaderLibrary/images.qrc index f01ea5aa..e032e785 100644 --- a/YACReaderLibrary/images.qrc +++ b/YACReaderLibrary/images.qrc @@ -57,8 +57,12 @@ ../images/comicRar.png ../images/comicTar.png ../images/comic7z.png - ../images/serverConfigBackground.png + ../images/serverConfigBackground.png ../images/noLibrariesIcon.png ../images/noLibrariesLine.png + ../images/importingIcon.png + ../images/importTopCoversDecoration.png + ../images/importBottomCoversDecoration.png + ../images/glowLine.png \ No newline at end of file diff --git a/YACReaderLibrary/import_widget.cpp b/YACReaderLibrary/import_widget.cpp new file mode 100644 index 00000000..b9f175bf --- /dev/null +++ b/YACReaderLibrary/import_widget.cpp @@ -0,0 +1,338 @@ +#include "import_widget.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +class YACReaderActivityIndicatorWidget : public QWidget +{ +public: + YACReaderActivityIndicatorWidget(QWidget * parent = 0); +public slots: + +private: + QLabel * normal; + QLabel * glow; +}; + +YACReaderActivityIndicatorWidget::YACReaderActivityIndicatorWidget(QWidget * parent) + :QWidget(parent) +{ + QPixmap line(":/images/noLibrariesLine.png"); + QPixmap glowLine(":/images/glowLine.png"); + normal = new QLabel(this); + glow = new QLabel(this); + + normal->setPixmap(line); + glow->setPixmap(glowLine); + + + + QHBoxLayout * layout = new QHBoxLayout(); + + layout->addWidget(normal,0,Qt::AlignVCenter); + + setLayout(layout); + + layout->setMargin(4); + layout->setSpacing(0); + + //setFixedHeight(3); + //resize(579,3); + glow->setGeometry(4,4,glowLine.width(),glowLine.height()); + //normal->setGeometry(0,1,579,1); + + QGraphicsOpacityEffect * effect = new QGraphicsOpacityEffect(); + //effect->setOpacity(1.0); + + + QPropertyAnimation * animation = new QPropertyAnimation(effect,"opacity"); + + animation->setDuration(1000); + animation->setStartValue(1); + animation->setEndValue(0); + //animation->setEasingCurve(QEasingCurve::InQuint); + + QPropertyAnimation * animation2 = new QPropertyAnimation(effect,"opacity"); + + animation2->setDuration(1000); + animation2->setStartValue(0); + animation2->setEndValue(1); + //animation2->setEasingCurve(QEasingCurve::InQuint); + +#ifndef Q_WS_MAC + glow->setGraphicsEffect(effect); +#endif + + connect(animation,SIGNAL(finished()),animation2,SLOT(start())); + connect(animation2,SIGNAL(finished()),animation,SLOT(start())); + + animation->start(); +} + + + + +ImportWidget::ImportWidget(QWidget *parent) : + QWidget(parent) +{ + setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + + QPalette p(palette()); + p.setColor(QPalette::Background, QColor(250,250,250)); + setAutoFillBackground(true); + setPalette(p); + + QPixmap icon(":/images/importingIcon.png"); + QLabel * iconLabel = new QLabel(); + iconLabel->setPixmap(icon); + + /*QPixmap line(":/images/noLibrariesLine.png"); + QLabel * lineLabel = new QLabel(); + lineLabel->setPixmap(line);*/ + + YACReaderActivityIndicatorWidget * activityIndicator = new YACReaderActivityIndicatorWidget(); + + QLabel * text = new QLabel(""+tr("Importing comics")+""); + text->setStyleSheet("QLabel {font-size:25px;font-weight:bold;}"); + QLabel * textDescription = new QLabel(""+tr("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")+""); + textDescription->setWordWrap(true); + textDescription->setMaximumWidth(330); + currentComicLabel = new QLabel("..."); + + QVBoxLayout * coversViewLayout = new QVBoxLayout; + coversView = new QGraphicsView(); + //coversView->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); + coversView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + coversView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + coversView->setMaximumHeight(300); + coversView->setStyleSheet("QGraphicsView {background-color: #E6E6E6;border:none;}"); + + coversScene = new QGraphicsScene(); + coversScene->setSceneRect(0,0,coversView->width(),coversView->height()); + coversView->setAlignment(Qt::AlignLeft); + coversView->setScene(coversScene); + + + QLabel * topDecorator = new QLabel(); + QLabel * bottomDecorator = new QLabel(); + QPixmap top(":/images/importTopCoversDecoration.png"); + QPixmap bottom(":/images/importBottomCoversDecoration.png"); + topDecorator->setPixmap(top); + bottomDecorator->setPixmap(bottom); + topDecorator->setScaledContents(true); + bottomDecorator->setScaledContents(true); + topDecorator->setFixedHeight(top.height()); + bottomDecorator->setFixedHeight(bottom.height()); + + coversViewLayout->addWidget(topDecorator,0); + coversViewLayout->addWidget(coversView,1); + coversViewLayout->addWidget(bottomDecorator,0); + coversViewLayout->setMargin(0); + coversViewLayout->setSpacing(0); + + QPushButton * stop = new QPushButton(tr("stop")); + stop->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred); + stop->setMaximumWidth(100); + + QVBoxLayout * layout = new QVBoxLayout(this); + QHBoxLayout * buttonLayout = new QHBoxLayout(); + QHBoxLayout * topLayout = new QHBoxLayout(); + QVBoxLayout * textLayout = new QVBoxLayout(); + + QWidget * topWidget = new QWidget(); + topWidget->setFixedSize(650,180); + textLayout->addSpacing(12); + textLayout->addWidget(text); + textLayout->addSpacing(12); + textLayout->addWidget(textDescription); + textLayout->addStretch(); + + topLayout->addStretch(); + topLayout->addWidget(iconLabel,0,Qt::AlignVCenter); + topLayout->addSpacing(30); + topLayout->addLayout(textLayout,1); + topLayout->addStretch(); + topLayout->setMargin(0); + + topWidget->setLayout(topLayout); + + layout->setAlignment(Qt::AlignHCenter); + + buttonLayout->addSpacing(250); + buttonLayout->addWidget(stop); + buttonLayout->addSpacing(250); + + layout->addSpacing(50); + layout->addWidget(topWidget,0,Qt::AlignHCenter); + layout->addSpacing(20); + layout->addWidget(activityIndicator,0,Qt::AlignHCenter); + layout->addSpacing(10); + layout->addLayout(buttonLayout,0); + layout->addSpacing(10); + layout->addStretch(); + portadasLabel = new QLabel(""+tr("Some of the comics being added...")+""); + layout->addWidget(portadasLabel,0,Qt::AlignHCenter); + layout->addLayout(coversViewLayout); + //layout->addStretch(); + layout->addWidget(currentComicLabel,0,Qt::AlignHCenter); + layout->setContentsMargins(0,layout->contentsMargins().top(),0,layout->contentsMargins().bottom()); + + connect(stop,SIGNAL(clicked()),this,SIGNAL(stop())); + //connect(stop,SIGNAL(clicked()),this,SLOT(addCoverTest())); + + previousWidth = 10; + updatingCovers = false; + elapsedTimer = new QElapsedTimer(); +} + +void ImportWidget::newComic(const QString & path, const QString & coverPath) +{ + currentComicLabel->setText(""+path+""); + + if(((elapsedTimer->elapsed()>=1000) || ((previousWidth < coversView->width()) && (elapsedTimer->elapsed()>=500))) && !updatingCovers)//todo elapsed time + { + + QPixmap p(coverPath); + p = p.scaledToHeight(300,Qt::SmoothTransformation); + QGraphicsPixmapItem * item = new QGraphicsPixmapItem(p); + item->setPos(previousWidth,0); + item->setZValue(i/10000.0); + previousWidth += 10 + p.width(); + coversScene->addItem(item); + + elapsedTimer->start(); + if(previousWidth >= coversView->width()+200 && !updatingCovers) + { + updatingCovers = true; + QGraphicsItem * last = coversScene->items().last(); + int width = p.width(); + if(previousWidth > 3000) + { + coversScene->removeItem(last); + delete last; + } + + foreach(QGraphicsItem * itemToMove, coversScene->items()) + { + QTimeLine *timer = new QTimeLine(400); + timer->setFrameRange(0, 24); + timer->setUpdateInterval(17); + + QGraphicsItemAnimation *animation = new QGraphicsItemAnimation; + animation->setItem(itemToMove); + animation->setTimeLine(timer); + + QPointF point = itemToMove->scenePos(); + float step = (width+10)/24.0; + for (int i = 0; i < 24; ++i) + animation->setPosAt(i / 24.0, QPointF(point.x()-((i+1)*step), point.y())); + + timer->start(); + connect(timer,SIGNAL(finished()),timer,SLOT(deleteLater())); + connect(timer,SIGNAL(finished()),animation,SLOT(deleteLater())); + } + + QTimer::singleShot(400,this,SLOT(finishedUpdatingCover())); + + previousWidth -= 10+width; + } + + } +} + +void ImportWidget::finishedUpdatingCover() +{ + updatingCovers = false; +} + +void ImportWidget::newCover(const QPixmap & image) +{ + +} +static int i = 1; +static int previousWidth = 10; +static int j = 0; +void ImportWidget::addCoverTest() +{ + QPixmap p(QString("c:/temp/%1.jpg").arg(i)); + p = p.scaledToHeight(300,Qt::SmoothTransformation); + QGraphicsPixmapItem * item = new QGraphicsPixmapItem(p); + item->setPos(previousWidth,0); + item->setZValue(i/10000.0); + previousWidth += 10 + p.width(); + coversScene->addItem(item); + if(previousWidth >= coversView->width()) + { + QGraphicsItem * last = coversScene->items().last(); + int width = p.width(); + if(j>=1) + { + coversScene->removeItem(last); + delete last; + } + else + j++; + + foreach(QGraphicsItem * itemToMove, coversScene->items()) + { + + QTimeLine *timer = new QTimeLine(/*350*/1000); + timer->setFrameRange(0, 60); + + QGraphicsItemAnimation *animation = new QGraphicsItemAnimation; + animation->setItem(itemToMove); + animation->setTimeLine(timer); + + QPointF point = itemToMove->scenePos(); + float step = (width+10)/60.0; + for (int i = 0; i < 60; ++i) + animation->setPosAt(i / 60.0, QPointF(point.x()-((i+1)*step), point.y())); + + timer->start(); + } + previousWidth -= 10+width; + } + + i++; +} + +void ImportWidget::clear() +{ + previousWidth = 10; + + //nos aseguramos de que las animaciones han finalizado antes de borrar + QList all = coversScene->items(); + for (int i = 0; i < all.size(); i++) + { + QGraphicsItem *gi = all[i]; + if(gi->parentItem()==NULL) + delete gi; + } + coversScene->clear(); + + updatingCovers = false; + + currentComicLabel->setText("..."); + + i = 0; +} + +void ImportWidget::clearScene() +{ + + +} \ No newline at end of file diff --git a/YACReaderLibrary/import_widget.h b/YACReaderLibrary/import_widget.h new file mode 100644 index 00000000..c8927fd0 --- /dev/null +++ b/YACReaderLibrary/import_widget.h @@ -0,0 +1,38 @@ +#ifndef IMPORT_WIDGET_H +#define IMPORT_WIDGET_H + +#include + +class QLabel; +class QGraphicsView; +class QGraphicsScene; +class QElapsedTimer; + +class ImportWidget : public QWidget +{ + Q_OBJECT +public: + explicit ImportWidget(QWidget *parent = 0); + +signals: + void stop(); +public slots: + void newComic(const QString & path, const QString & coverPath); + void newCover(const QPixmap & image); + void clear(); + void addCoverTest(); + void finishedUpdatingCover(); + void clearScene(); +private: + QLabel * currentComicLabel; + QLabel * portadasLabel; + QGraphicsView * coversView; + QGraphicsScene * coversScene; + int previousWidth; + bool updatingCovers; + QElapsedTimer * elapsedTimer; + quint64 i; + +}; + +#endif // IMPORT_WIDGET_H diff --git a/YACReaderLibrary/library_creator.cpp b/YACReaderLibrary/library_creator.cpp index 60817f31..57068bd8 100644 --- a/YACReaderLibrary/library_creator.cpp +++ b/YACReaderLibrary/library_creator.cpp @@ -233,6 +233,8 @@ void LibraryCreator::insertComic(const QString & relativePath,const QFileInfo & //ThumbnailCreator tc(QDir::cleanPath(fileInfo.absoluteFilePath()),_target+"/covers/"+fileInfo.fileName()+".jpg"); tc.create(); numPages = tc.getNumPages(); + + emit(comicAdded(relativePath,_target+"/covers/"+hash+".jpg")); } comic.info.setNumPages(numPages); comic.insert(_database); diff --git a/YACReaderLibrary/library_creator.h b/YACReaderLibrary/library_creator.h index c2518d27..925792a8 100644 --- a/YACReaderLibrary/library_creator.h +++ b/YACReaderLibrary/library_creator.h @@ -52,6 +52,7 @@ void finished(); void coverExtracted(QString); void folderUpdated(QString); + void comicAdded(QString,QString); void updated(); void created(); }; diff --git a/YACReaderLibrary/library_window.cpp b/YACReaderLibrary/library_window.cpp index 3e2fc5e7..08c7dc45 100644 --- a/YACReaderLibrary/library_window.cpp +++ b/YACReaderLibrary/library_window.cpp @@ -22,6 +22,7 @@ #include "yacreader_global.h" #include "onstart_flow_selection_dialog.h" #include "no_libraries_widget.h" +#include "import_widget.h" // @@ -37,7 +38,7 @@ LibraryWindow::LibraryWindow() } else { - hideNoLibrariesWidget(); + showRootWidget(); } } @@ -228,6 +229,9 @@ void LibraryWindow::doLayout() noLibrariesWidget = new NoLibrariesWidget(); mainWidget->addWidget(noLibrariesWidget); + importWidget = new ImportWidget(); + mainWidget->addWidget(importWidget); + connect(noLibrariesWidget,SIGNAL(createNewLibrary()),this,SLOT(createLibrary())); connect(noLibrariesWidget,SIGNAL(addExistingLibrary()),this,SLOT(showAddLibrary())); } @@ -595,12 +599,19 @@ void LibraryWindow::createConnections() //libraryCreator connections connect(createLibraryDialog,SIGNAL(createLibrary(QString,QString,QString)),this,SLOT(create(QString,QString,QString))); connect(importComicsInfoDialog,SIGNAL(finished(int)),this,SLOT(reloadCurrentLibrary())); + connect(libraryCreator,SIGNAL(coverExtracted(QString)),createLibraryDialog,SLOT(showCurrentFile(QString))); connect(libraryCreator,SIGNAL(finished()),createLibraryDialog,SLOT(close())); connect(libraryCreator,SIGNAL(coverExtracted(QString)),updateLibraryDialog,SLOT(showCurrentFile(QString))); connect(libraryCreator,SIGNAL(finished()),updateLibraryDialog,SLOT(close())); + connect(libraryCreator,SIGNAL(finished()),this,SLOT(showRootWidget())); connect(libraryCreator,SIGNAL(updated()),this,SLOT(reloadCurrentLibrary())); connect(libraryCreator,SIGNAL(created()),this,SLOT(openLastCreated())); + //new import widget + connect(libraryCreator,SIGNAL(comicAdded(QString,QString)),importWidget,SLOT(newComic(QString,QString))); + //connect(libraryCreator,SIGNAL(finished()),importWidget,SLOT(clear())); + //connect(importWidget,SIGNAL(stop()),this,SLOT(cancelCreating())); + connect(importWidget,SIGNAL(stop()),this,SLOT(stopLibraryCreator())); //packageManager connections connect(exportLibraryDialog,SIGNAL(exportPath(QString)),this,SLOT(exportLibrary(QString))); @@ -694,7 +705,7 @@ void LibraryWindow::loadLibrary(const QString & name) { if(libraries.size()>0) //si hay bibliotecas... { - hideNoLibrariesWidget(); + showRootWidget(); QString path=libraries.value(name)+"/.yacreaderlibrary"; QDir d; //TODO change this by static methods (utils class?? with delTree for example) QString dbVersion; @@ -1008,6 +1019,8 @@ void LibraryWindow::create(QString source, QString dest, QString name) _lastAdded = name; _sourceLastAdded = source; + showImportingWidget(); + } void LibraryWindow::reloadCurrentLibrary() @@ -1101,7 +1114,9 @@ void LibraryWindow::saveLibraries() void LibraryWindow::updateLibrary() { - updateLibraryDialog->show(); + //updateLibraryDialog->show(); + showImportingWidget(); + QString currentLibrary = selectedLibrary->currentText(); QString path = libraries.value(currentLibrary); _lastAdded = currentLibrary; @@ -1539,7 +1554,16 @@ void LibraryWindow::showNoLibrariesWidget() { mainWidget->setCurrentIndex(1); } -void LibraryWindow::hideNoLibrariesWidget() + +void LibraryWindow::showRootWidget() { + libraryToolBar->setDisabled(false); mainWidget->setCurrentIndex(0); +} + +void LibraryWindow::showImportingWidget() +{ + importWidget->clear(); + libraryToolBar->setDisabled(true); + mainWidget->setCurrentIndex(2); } \ No newline at end of file diff --git a/YACReaderLibrary/library_window.h b/YACReaderLibrary/library_window.h index 2d8005eb..513d8fb8 100644 --- a/YACReaderLibrary/library_window.h +++ b/YACReaderLibrary/library_window.h @@ -13,6 +13,7 @@ #include #include +//TODO cambiar por class XXXXX #include "create_library_dialog.h" #include "add_library_dialog.h" #include "library_creator.h" @@ -32,6 +33,7 @@ #include "treeitem.h" #include "server_config_dialog.h" #include "no_libraries_widget.h" +#include "import_widget.h" class LibraryWindow : public QMainWindow { @@ -83,6 +85,7 @@ private: QStackedWidget * mainWidget; NoLibrariesWidget * noLibrariesWidget; + ImportWidget * importWidget; bool fetching; @@ -217,7 +220,8 @@ public: void showImportComicsInfo(); void asignNumbers(); void showNoLibrariesWidget(); - void hideNoLibrariesWidget(); + void showRootWidget(); + void showImportingWidget(); //server interface QMap getLibraries(){return libraries;}; diff --git a/YACReaderLibrary/no_libraries_widget.cpp b/YACReaderLibrary/no_libraries_widget.cpp index f9c88451..093523af 100644 --- a/YACReaderLibrary/no_libraries_widget.cpp +++ b/YACReaderLibrary/no_libraries_widget.cpp @@ -1,6 +1,6 @@ #include "no_libraries_widget.h" -#include +#include #include #include #include @@ -23,8 +23,11 @@ NoLibrariesWidget::NoLibrariesWidget(QWidget *parent) : QLabel * lineLabel = new QLabel(); lineLabel->setPixmap(line); - QLabel * text = new QLabel(tr("You don't have any librarires yet")); + QLabel * text = new QLabel(""+tr("You don't have any librarires yet")+""); text->setStyleSheet("QLabel {font-size:25px;font-weight:bold;}"); + QLabel * textDescription = new QLabel(""+tr("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")+""); + textDescription->setWordWrap(true); + textDescription->setMaximumWidth(330); QPushButton * createButton = new QPushButton(tr("create your first library")); createButton->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred); @@ -33,22 +36,37 @@ NoLibrariesWidget::NoLibrariesWidget(QWidget *parent) : QVBoxLayout * layout = new QVBoxLayout(this); QHBoxLayout * buttonLayout = new QHBoxLayout(); - //QHBoxLayout * topLayout = new QHBoxLayout(); - //QVBoxLayout * textLayout = new QVBoxLayout(); + QHBoxLayout * topLayout = new QHBoxLayout(); + QVBoxLayout * textLayout = new QVBoxLayout(); + + QWidget * topWidget = new QWidget(); + topWidget->setFixedSize(650,160); + textLayout->addSpacing(12); + textLayout->addWidget(text); + textLayout->addSpacing(12); + textLayout->addWidget(textDescription); + textLayout->addStretch(); + + topLayout->addStretch(); + topLayout->addWidget(iconLabel,0,Qt::AlignVCenter); + topLayout->addSpacing(30); + topLayout->addLayout(textLayout,1); + topLayout->addStretch(); + topLayout->setMargin(0); + + topWidget->setLayout(topLayout); layout->setAlignment(Qt::AlignHCenter); - buttonLayout->addSpacing(100); + buttonLayout->addSpacing(125); buttonLayout->addWidget(createButton); layout->addSpacing(25); buttonLayout->addWidget(addButton); - buttonLayout->addSpacing(100); + buttonLayout->addSpacing(125); layout->addStretch(); - layout->addWidget(iconLabel,0,Qt::AlignHCenter); - layout->addSpacing(10); - layout->addWidget(text,0,Qt::AlignHCenter); - layout->addSpacing(10); + layout->addWidget(topWidget); + layout->addSpacing(20); layout->addWidget(lineLabel,0,Qt::AlignHCenter); layout->addSpacing(10); layout->addLayout(buttonLayout,0); diff --git a/images/glowLine.png b/images/glowLine.png new file mode 100644 index 0000000000000000000000000000000000000000..13ee7b3b8247d5a65504c02f8cd04a4607a23130 GIT binary patch literal 460 zcmV;-0W>0v!@e#&uBcplOCP)=tS)}XFeX^+xunc zn-``$&6SXptu2-+b%1ms{)S~rFA9?J7W)D1$ zV;}UR&)CAw#>;7md&3UeNN*?CUJKqPT-L6?Dmth}9BfoliF8opuj&k7aXpLlP~;*_ zgDSr z1<%~X^wgl##FWaylc_d9MLM1?jv*DdSPmL;F*tBAJKp&H-yihpgsmqS3j3^P69t literal 0 HcmV?d00001 diff --git a/images/importTopCoversDecoration.png b/images/importTopCoversDecoration.png new file mode 100644 index 0000000000000000000000000000000000000000..0343fdb42384e364eba064e4ab240d19c3340dd3 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^j6lr6!2~3?S1^eIDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MQWZdjv*Ddk|K5#C{Et7!{YGE%gZJ6?(I4G;l)Mew)FG! e4jMQ#Ffx2!A$VD|lKmV|2ZN`ppUXO@geCwmMk{9k literal 0 HcmV?d00001 diff --git a/images/importingIcon.png b/images/importingIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..bb4f6afbd16ee5fe23f275702fe3a7051a6356f5 GIT binary patch literal 5746 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 literal 6143 zcmbU_XFOYd+Yz)zsXbaMVw55S88#Jr#jHI_s&+)wE=pBZt)@j$qg3spYTjm*8eMi( z)rg`-?adqabN6}Q56|!U@Sa~z&N=^ct^YO8b=}7rYB4cfU;qFBOgh>a6Uw!Ka^}#T zq5ONzmAX+byhII4qN&dfVt^9?2T*hIxsC(rcsaS^OmI#vLB8*CiU0uh4L37OqNRbp zyt9uN#OV|U66l4eU;_Y(DuH+>XAc|^bRFmF=B)%?ZEOL9++38v*ANCU1H3x!rki#! z0cRR)XyzR3;VkC@R#65i2FgOKS<2mz6ia)!a-AS4n3mqj3va7mCf3@#0YQGQ4%xU4(^DKCuz{d0gR+z2i= zYiiFkP^G$0@V5+DQdA-F=}a&mH~G^C}aC=gP9LEc2CKq+rOp+6Kb zI6r5C8=mOq;|)5c=ycu3pQr?;NcyiWc;O8U{!Q51?;k}`R0a)n!b9N@7}U$_bYFi% z`w>lW|0~9Sg!VHF!sDPOI6ohMf-}V)H-!EmQ*`&=8Jz-Bq>(owxKWJabh z6Lm03V9Fbai<^tQnvA9_5`#n`<*p($q~UNm3=DT-W*{3l!#N?H?% zk(IlOM99M78q#u_(nt*iN?Hwpx(Y|3k$-S?y#0ty-p;r`eBCH~|G`E7S6q2@0?vu( zLooC4@%-Zf*qc5?AHSPEc#yg&5+rub&D+H%z)$?tJpbA)21jtag>%s)_;`W-)~~$V zf8ehHS67!s!K7s|SCOatz6yiMXsW}Jns784gI1FT|AXuD|IrzgA`JA@IsT8c{8^%S z;OXtZU7zys@8H3CQzC{y2@U2IAx;2*1FC~jGYkB>l*Nd(-3jVUB?~$RK|z;*1(mqo zg>I9Q(Uf2LyqBL^m-82<3wImPbUVVJyt6J}(Z1jMWcj-)O&M8UJs76ZVMpA5_e3#a zNVZ%`!L-x&!sYUB-2{&=?de=x&`nxNkiC+t-^nIJ)LUl(?rjB`$#0KqB)bo0GFJ~K z8&59YV3X2$`0$|)D=Vv9a&od9dM?kTqoc!=_}CMfVT$E4yJ~5f#>*L5mGi>E)!n@( zBr`LU_&f$n&CbqFjowa3OjKAKl|v%u-p=@;pJ~)QPE8Gf?wo`#PL^FubM*Hg8X37q zU8izCA;DgNle307(dX@&5Dk_Z&io@CFH0rQF0j!JCN5U)R~MK3r6buIs6o}UAk=Dx zfXU16uaJ9Fjb?V47o`R>a5x+!l0dF|h8rq2&%g?tjaKw-U2~3ro*~mFYW(JirHN1E zjF4#?II%iEjM~wi@EvgeVEd4Yr-t%`861SLN0?b%G&{~4N_obH?+mf`}i>Taz zB=v}mx1TVz&nXXJyAjF-4_P^V{fuMnSqMwtzHN2n02u38??)P9vK<= zIzE2DlUZ$=)5P|!jzl6A&(6+PwDFeV-?{N@=^?=B3o};-Z3#TVb00Pc_c`M^YHkEEE(EYYTb2>b%)09 zr*YA0xf?(0)t*Pt-?%rh&?j-_%04;n?w2XNCnz4@wH)itevjuUC7~OgY&gQl!vo9x z$hW$<__f;a=Z7!}2HlMQC(Jx2tmg6e_2=-pK9_q8qq0F#j znY{hy@$Qh-mn8(6cVraJnkS2>A2e-wd3ggk0K+0tsEWG^E9w(6)jk|N*UqHjd!qn; z+N96!dIMDLsa8pp+^qp_ zsn@=K?Ma&?75gh=KH+eR{B5(xU!PfpqO}*4O>+MH`LmYiO7m1giA9C|5kFuLPassK zuXHnt3Kw5H{@p>&W8{X!KT`_Xe$?67dE!PV#?Rc<1(|^c{Ao?o{rJ47 zk->W3`TgEo5kVWCuD5|-O)tq4Uy2C{J*QID^h?(|lm6)!+)XufH95sYQ&ZD(_oKp{ zFQ(GvGBPq=_-;F%8%>XDO66k8H;-^OHa1j5v79xp>M?1+?B~tR&9ZrcidYZhn>(qB zMhQHt)M>xAvh}i=bhFDkmL^+HUQjZagR85nkA{np(FidAEn3d;x^>ww$E&p?kFbYE zIi7BAV<{OK2Le`BR&qq`BRP-cSiV#nTj8huQf?OUzUNwNLB<<%!QQ(j z;E?{O2q>@{Z693%$!ED=PEO%T&(pRlP0r^)#T3M0O^=}93YJie?4<&*&O$}T`c^@97Os4|r<7us zviKJ2mxNT~o&XE1!9Y?rC5iAdu870kCZA+wh4Db#p2#4;4v|H6Ivgu&fe_EpS5sR- z3OHwH=PSY8*_LI)bW|p@dSdnN>MuUo%t?tg4}AIZY_347FZ^^J-af`)E&0SIBO{|C zgPRn)tYBhl8qkw3wVrB|BGDkCzq+w;hfP(vsGNrzq;VXP(yN~NcIwG^1^sEv-U8I8 zbM(@3fy3{6!rR-%F2h^i+H>|$Qb{4BLE1UZ!wls4%%?a6wbaTFOv;)n-;<=QOKqd8IP|zQ>#xCP%n_j{MT$Mx$mJEPgub%iS~;X z5h**6*OrpCCFgJ7$3(JanOqDU&Tz%-aQ{eg@|5os(NMdy9+Qq;Ny34QUx72f3ASG| zQXd-}B=z}&?|U1=?(x^*hGj`jCx{+N>I5;%wXz9UrLYUS=g)|LtiW?gndv1N@AM;M`2L8OJrIeUg_D`cp!Oqx9$=4MVx8e zIgUww#iJ~cp*X{v*Yk5{j_mBkXtk4#b1!B8iPVM@{bT?)IV8O%~kO@e+^4QuxGE zi5%!)b~thr#VG)+6GWZFEs!8?k{^d@iy;IC?wW5+(vf4UjFZJaeJ*1{6MM3M z7&&1Ykz9q|=g^{nJ%WZt=Wkik?gQmW6OPiNi+|;x z7F4UF$pj zw-a6Ua17!Y2V6+8J<~v3FliiLRz4OKQ(HO+O;HtRn2k_RrAg{<3|M`(%R=ILKRIR1 z+D2+Nnf3X6Sa*&lm5-Km;2Of5wa!0?qlhAw`u43?L*UwUTUAvRWA#-lb8|#Ys7mKM zQ?M-uU23$t;nvQMirmOX(=~d*Ne4j^Q7^eW8zP5BYo{LSxVbHy*mLTRE=Xj?>}s%0 zfy3*Cd870UH@CKwf@^+WDGcRAbVq7|ZD-G?3fmBM0AtoBChOl3xfqA{rbvsylIm@4_JD(?T+HyvIfuXm zOmC~uy1C~g5eSvwn~&R@n~I3+ij0`5hK67^N8~zf+R5}2utQxw*SILa>LJoMPz`Hx zbacc7sJ`~iWVUzejH>cAOUvEE(3WimF$oEYvrg6iec@L6+)}jK{&Q!-^2f;pbE(;1 zDx0h}s(ZqG8+;B}L!~&bi{rMBTs$dF;A$Iwphj3M{ovL3y}dhC7-8#kN%3AUr1;h? zZ{I#X&$WM{+FLW?Fr3Tr5t_9fGjL+?5>JEk<>GyktEPVLzA?5dPyu_k6ke8od$}z6IPLs{+JDN}0M^F`V zrTKAjNePs?Pw`N+>7Cfm3#3pB+X%C3CrR|L*34grRP0UHaJ%?3F)`hbU3;FMo*s~& zpC9WS151(>LAce{)+(&8uj_IhSU(`>7WDM!qHafo{I>DE%A_)#mP?;6?;O>AEEo9l zH+jdB)VWOgFyl(t8z?O;RY*xm(TBs~1oi_K>J&Ydn+vyTAMNX#n?H6Huc#L;G@CxJ z*0nT0ADFyta50sf_i0{`GYQ}2Fmp87%mE5pBuk#h3=21!&t3}r;T3)a+~wCTpnS`H%X<3M zy$e7x7@57=xQL)NoN0I-=dtXbeZ#CjROL4=Pz*5=ub%jxYJQ4hlli(jv`>XN{z7%Y zAW|AJ;8R>BR;iAllR`WKl45w%G*}6l=JGLd4Da*)i;Z;@QyYcH!4Jp@Wbu0BNT>n z0u(vt9TIY`77dP$(sk&Isa9BV2?(4N2BU|t!pw^*u4WlOJoJ=SbDASxDsz=)_p)FY z$&?~X{fQs{;Q-*uoSMwDEZJ~b=$Ru!{)6y=h4{rxM4`J^V)qW!jC1UgfNucF@i;Ul z%B1Mc8{|3ccLwxo`&v1r^|ArnOd}YPbFR#p2c5727fV_DzpNCLtyp!uJZ4fEKQER| z8_%w}TL70N$qWq+y3nSL1LiJcYo8;*)BQxlp{VuBxczj_xL3u27OVz5HEEa5#%obs zS2s5P?4fy(p2|e3-puulSVs=t7}R`wAUend7%T;ljfZS=7RMvV%w>!0TTzU91_Kdm zcHb4>FW(ZdoQH4%$>5<+pI8`SC_vxVg`8i;zbpYVPw`)Lwkj*aOF`z|CC@yFmYmV? zH_D-3SRYFO->CrJ2}P`li7ud?bU=sW?hqhDLqnC^{bxe!@t-C#C|;+ct*;;NBH=iQ!Y;>+4-9NH_mYF@!lrdF)gkrGXMtpM;?iiP*Xg`#jWWv9 z;$7=^wq@5Y99USGpC2`$c+sSU6FNh@{>9RXd5%DAJled3(W|kcA{#OgI8z-5V1?^KqKTsnu9@-ThK(FXG(2!;IB;D?2W(Z?ubywrRIQ4T zMs#oV79*q8nf+`s?HX@o(RJ>Kg3WUEb#(R=HXm`-WaUPJLwJ%6Ko0anJEFq5-&(>? z>FRD0bS7gR(OyV9&p zZZnvTfF(Sl!R*|EP}6!;+May2s2%S&y|;SH-+#i++IqiPhr=4XGSN744%AX{Yl$vK zuec;^(0+=NG&li!opEt-x7*+}xo=+|i3~n$vrNtO;+6qeePmiHDJkiq>12scIk?#_ z((+-Hd9xuu&SN{#c70)anI9NmKub$|kG72^hApbUkaav`a63AZsKq(bv{_nM_%i_C z-NIB;Eej+|0+Y;%I@>9cv0k)7sUffHp5g0ljU2m=x7E)p3H$OdV!tkLCjxpx_NHLr zJ1P58TY&|2Z;U?LL{#$Zmw_&0ucS&+ra!3a)J^Ur_X%UKqOR|(zG1AsM^c+f$a69? zcQRBL%~uja@`0A?ZEDb2CoM_l4G#$Jg)o`W9=NWd6?M}bx%l3++_ zlnaD~g}+skaG)cLV4{ZMfV+ZHYajy*nagZpVG&GoIg+3ZsqeU6iRm8^F_)BJ8M0TR zfRwrNwX^uqsIEXMZGHhr7z=rw-Iwjr`dK08Hlxzec_L+c(}(O^v@qu?}1|u2A0n5#@C!PPN`8_g+(CYvqpf zQZeqLKgIyqiX2=ucKw|>fbTR7JVa((=HW2 q&jw{U1H&!W