UBFeaturesWidget.cpp 47.9 KB
Newer Older
1
/*
2
 * Copyright (C) 2010-2013 Groupement d'Intérêt Public pour l'Education Numérique en Afrique (GIP ENA)
3 4 5
 *
 * This file is part of Open-Sankoré.
 *
Claudio Valerio's avatar
Claudio Valerio committed
6 7 8
 * Open-Sankoré is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, version 3 of the License,
9 10 11 12 13 14
 * with a specific linking exception for the OpenSSL project's
 * "OpenSSL" library (or with modified versions of it that use the
 * same license as the "OpenSSL" library).
 *
 * Open-Sankoré is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Claudio Valerio's avatar
Claudio Valerio committed
15 16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
17
 *
Claudio Valerio's avatar
Claudio Valerio committed
18 19
 * You should have received a copy of the GNU General Public License
 * along with Open-Sankoré.  If not, see <http://www.gnu.org/licenses/>.
20 21 22
 */


Claudio Valerio's avatar
Claudio Valerio committed
23

24
#include <QDomDocument>
25 26
#include <QWebView>

Anna Udovichenko's avatar
Anna Udovichenko committed
27 28 29 30 31
#include "UBFeaturesWidget.h"
#include "gui/UBThumbnailWidget.h"
#include "frameworks/UBFileSystemUtils.h"
#include "core/UBApplication.h"
#include "core/UBDownloadManager.h"
32
#include "globals/UBGlobals.h"
33
#include "board/UBBoardController.h"
34 35 36

const char *UBFeaturesWidget::objNamePathList = "PathList";
const char *UBFeaturesWidget::objNameFeatureList = "FeatureList";
Anna Udovichenko's avatar
Anna Udovichenko committed
37

38 39 40 41 42
const QMargins FeatureListMargins(0, 0, 0, 30);
const int FeatureListBorderOffset = 10;
const char featureTypeSplitter = ':';
static const QString mimeSankoreFeatureTypes = "Sankore/featureTypes";

Aleksei Kanash's avatar
Aleksei Kanash committed
43 44 45
UBFeaturesWidget::UBFeaturesWidget(QWidget *parent, const char *name)
    : UBDockPaletteWidget(parent)
    , imageGatherer(NULL)
Anna Udovichenko's avatar
Anna Udovichenko committed
46 47 48 49 50
{
    setObjectName(name);
    mName = "FeaturesWidget";
    mVisibleState = true;

51
    SET_STYLE_SHEET();
Anna Udovichenko's avatar
Anna Udovichenko committed
52 53 54 55 56

    mIconToLeft = QPixmap(":images/library_open.png");
    mIconToRight = QPixmap(":images/library_close.png");
    setAcceptDrops(true);

57 58 59 60 61 62 63 64 65 66
    //Main UBFeature functionality
    controller = new UBFeaturesController(this);

    //Main layout including all the widgets in palette
    layout = new QVBoxLayout(this);

    //Path icon view on the top of the palette
    pathListView = new UBFeaturesListView(this, objNamePathList);
    controller->assignPathListView(pathListView);

67
    centralWidget = new UBFeaturesCentralWidget(this);
Claudio Valerio's avatar
Claudio Valerio committed
68
    controller->assignFeaturesListView(centralWidget->listView());
69
    centralWidget->setSliderPosition(UBSettings::settings()->featureSliderPosition->get().toInt());
70 71 72

    //Bottom actionbar for DnD, quick search etc
    mActionBar = new UBFeaturesActionBar(controller, this);
73

74
    //Filling main layout
75
    layout->addWidget(pathListView);
76
    layout->addWidget(centralWidget);
77 78
    layout->addWidget(mActionBar);

79
    connect(centralWidget->listView(), SIGNAL(clicked(const QModelIndex &)), this, SLOT(currentSelected(const QModelIndex &)));
80
    connect(this, SIGNAL(sendFileNameList(QStringList)), centralWidget, SIGNAL(sendFileNameList(QStringList)));
81 82 83 84 85 86 87 88 89
    connect(mActionBar, SIGNAL(searchElement(const QString &)), this, SLOT( searchStarted(const QString &)));
    connect(mActionBar, SIGNAL(newFolderToCreate()), this, SLOT(createNewFolder()));
    connect(mActionBar, SIGNAL(deleteElements(const UBFeaturesMimeData *)), this, SLOT(deleteElements(const UBFeaturesMimeData *)));
    connect(mActionBar, SIGNAL(deleteSelectedElements()), this, SLOT(deleteSelectedElements()));
    connect(mActionBar, SIGNAL(addToFavorite(const UBFeaturesMimeData *)), this, SLOT(addToFavorite(const UBFeaturesMimeData *)));
    connect(mActionBar, SIGNAL(removeFromFavorite(const UBFeaturesMimeData *)), this, SLOT(removeFromFavorite(const UBFeaturesMimeData *)));
    connect(mActionBar, SIGNAL(addElementsToFavorite() ), this, SLOT ( addElementsToFavorite()) );
    connect(mActionBar, SIGNAL(removeElementsFromFavorite()), this, SLOT (removeElementsFromFavorite()));

90
    connect(mActionBar, SIGNAL(rescanModel()), this, SLOT(rescanModel()));
91
    connect(pathListView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(currentSelected(const QModelIndex &)));
92
    connect(UBApplication::boardController, SIGNAL(displayMetadata(QMap<QString,QString>)), this, SLOT(onDisplayMetadata( QMap<QString,QString>)));
93 94
    connect(UBDownloadManager::downloadManager(), SIGNAL( addDownloadedFileToLibrary( bool, QUrl, QString, QByteArray, QString))
             , this, SLOT(onAddDownloadedFileToLibrary(bool, QUrl, QString,QByteArray, QString)));
95 96 97 98
    connect(centralWidget, SIGNAL(lockMainWidget(bool)), this, SLOT(lockIt(bool)));
    connect(centralWidget, SIGNAL(createNewFolderSignal(QString)), controller, SLOT(addNewFolder(QString)));
    connect(controller, SIGNAL(scanStarted()), centralWidget, SLOT(scanStarted()));
    connect(controller, SIGNAL(scanFinished()), centralWidget, SLOT(scanFinished()));
99 100
    connect(controller, SIGNAL(scanStarted()), mActionBar, SLOT(lockIt()));
    connect(controller, SIGNAL(scanFinished()), mActionBar, SLOT(unlockIt()));
101
    connect(controller, SIGNAL(maxFilesCountEvaluated(int)), centralWidget, SIGNAL(maxFilesCountEvaluated(int)));
102 103 104
    connect(controller, SIGNAL(featureAddedFromThread()), centralWidget, SIGNAL(increaseStatusBarValue()));
    connect(controller, SIGNAL(scanCategory(QString)), centralWidget, SIGNAL(scanCategory(QString)));
    connect(controller, SIGNAL(scanPath(QString)), centralWidget, SIGNAL(scanPath(QString)));
Anna Udovichenko's avatar
Anna Udovichenko committed
105 106
}

107 108
UBFeaturesWidget::~UBFeaturesWidget()
{
109 110
    if (NULL != imageGatherer)
        delete imageGatherer;
111 112
}

113
void UBFeaturesWidget::searchStarted(const QString &pattern)
Anna Udovichenko's avatar
Anna Udovichenko committed
114
{
115
    controller->searchStarted(pattern, centralWidget->listView());
Anna Udovichenko's avatar
Anna Udovichenko committed
116 117 118 119
}

void UBFeaturesWidget::currentSelected(const QModelIndex &current)
{
120 121 122 123
    if (!current.isValid()) {
        qWarning() << "SLOT:currentSelected, invalid index catched";
        return;
    }
124

125
    QString objName = sender()->objectName();
Anna Udovichenko's avatar
Anna Udovichenko committed
126

127
    if (objName.isEmpty()) {
Claudio Valerio's avatar
Claudio Valerio committed
128
        qWarning() << "incorrect sender";
129 130 131
    } else if (objName == objNamePathList) {
        //Calling to reset the model for listView. Maybe separate function needed
        controller->searchStarted("", centralWidget->listView());
132
    }
Anna Udovichenko's avatar
Anna Udovichenko committed
133

134
    UBFeature feature = controller->getFeature(current, objName);
135 136 137 138 139 140 141

    if ( feature.isFolder() ) {
        QString newPath = feature.getFullVirtualPath();

        controller->setCurrentElement(feature);
        controller->siftElements(newPath);

142
        centralWidget->switchTo(UBFeaturesCentralWidget::MainList);
143 144 145 146

        if ( feature.getType() == FEATURE_FAVORITE ) {
            mActionBar->setCurrentState( IN_FAVORITE );

147
        }  else if ( feature.getType() == FEATURE_CATEGORY && feature.getName() == "root" ) {
148 149 150
            mActionBar->setCurrentState( IN_ROOT );

        } else if (feature.getType() == FEATURE_TRASH) {
151
            mActionBar->setCurrentState(IN_TRASH);
152

153 154 155 156 157 158 159 160 161 162
        } else if (feature.getType() == FEATURE_SEARCH) {
            //The search feature behavior is not standard. If features list clicked - show empty element
            //else show existing saved features search QWebView
            if (sender()->objectName() == objNameFeatureList) {
                centralWidget->showElement(feature, UBFeaturesCentralWidget::FeaturesWebView);
            } else if (sender()->objectName() == objNamePathList) {
                centralWidget->switchTo(UBFeaturesCentralWidget::FeaturesWebView);
            }

        } else  {
163
            mActionBar->setCurrentState(IN_FOLDER);
164 165
        }

166 167
//    } else if (feature.getType() == FEATURE_SEARCH) {
//        centralWidget->showElement(feature, UBFeaturesCentralWidget::FeaturesWebView);
168 169

    } else {
170
        centralWidget->showElement(feature, UBFeaturesCentralWidget::FeaturePropertiesList);
171 172
        mActionBar->setCurrentState( IN_PROPERTIES );
    }
173
    mActionBar->cleanText();
Anna Udovichenko's avatar
Anna Udovichenko committed
174 175
}

176 177
void UBFeaturesWidget::createNewFolder()
{
178
    centralWidget->showAdditionalData(UBFeaturesCentralWidget::NewFolderDialog, UBFeaturesCentralWidget::Modal);
179
    emit sendFileNameList(controller->getFileNamesInFolders());
Aleksei Kanash's avatar
Aleksei Kanash committed
180 181
}

182
void UBFeaturesWidget::deleteElements( const UBFeaturesMimeData * mimeData )
183
{
184 185 186 187
    if (!mimeData->features().count() )
        return;

    QList<UBFeature> featuresList = mimeData->features();
188

189 190 191 192 193 194 195 196 197 198
    foreach ( UBFeature curFeature, featuresList ) {
        if ( curFeature.inTrash()) {
            controller->deleteItem(curFeature.getFullPath());

        } else {
           controller->moveToTrash(curFeature);
        }
    }

    controller->refreshModels();
199 200
}

201 202
void UBFeaturesWidget::deleteSelectedElements()
{
203
    QModelIndexList selected = centralWidget->listView()->selectionModel()->selectedIndexes();
204 205 206 207 208 209

    QList<UBFeature> featureasToMove;
    for (int i = 0; i < selected.count(); i++)
    {
        featureasToMove.append(controller->getFeature(selected.at(i), objNameFeatureList));
    }
210

211
    foreach (UBFeature feature, featureasToMove)
212
    {
213 214 215 216 217 218 219
        if (feature.isDeletable()) {
            if (feature.inTrash()) {
                controller->deleteItem(feature);
            } else {
                controller->moveToTrash(feature, true);
            }
        }
220
    }
221 222

    controller->refreshModels();
223 224
}

225
void UBFeaturesWidget::rescanModel()
226
{
227
    controller->rescanModel();
228 229
}

230 231 232 233 234 235 236
void UBFeaturesWidget::lockIt(bool pLock)
{
    mActionBar->setEnabled(!pLock);
    pathListView->setEnabled(!pLock);
    centralWidget->setLockedExcludingAdditional(pLock);
}

237
void UBFeaturesWidget::addToFavorite( const UBFeaturesMimeData * mimeData )
238
{
239 240 241 242 243 244 245 246 247
    if ( !mimeData->hasUrls() )
        return;

    QList<QUrl> urls = mimeData->urls();
    foreach ( QUrl url, urls ) {
        controller->addToFavorite(url);
    }

    controller->refreshModels();
248 249
}

250
void UBFeaturesWidget::removeFromFavorite( const UBFeaturesMimeData * mimeData )
251
{
252 253 254 255 256 257 258 259
    if ( !mimeData->hasUrls() )
        return;

    QList<QUrl> urls = mimeData->urls();

    foreach( QUrl url, urls ) {
        controller->removeFromFavorite(url);
    }
260 261
}

262 263
void UBFeaturesWidget::onDisplayMetadata( QMap<QString,QString> metadata )
{
264
    QString previewImageUrl = ":images/libpalette/notFound.png";
265

266
    QString widgetsUrl = QUrl::fromEncoded(metadata["Url"].toAscii()).toString()/*metadata.value("Url", QString())*/;
267
    QString widgetsThumbsUrl = QUrl::fromEncoded(metadata["thumbnailUrl"].toAscii()).toString();
268

269 270
    QString strType = UBFileSystemUtils::mimeTypeFromFileName(widgetsUrl);
    UBMimeType::Enum thumbType = UBFileSystemUtils::mimeTypeFromString(strType);
271

272 273 274 275
    switch (static_cast<int>(thumbType)) {
    case UBMimeType::Audio:
        previewImageUrl = ":images/libpalette/soundIcon.svg";
        break;
276

277 278 279
    case UBMimeType::Video:
        previewImageUrl = ":images/libpalette/movieIcon.svg";
        break;
280

281 282 283
    case UBMimeType::Flash:
        previewImageUrl = ":images/libpalette/FlashIcon.svg";
        break;
284

285 286 287 288 289
    case UBMimeType::RasterImage:
    case UBMimeType::VectorImage:
        previewImageUrl = widgetsUrl;
        break;
    }
290

291
    if (!widgetsThumbsUrl.isNull()) {
292 293 294 295 296 297 298 299
        previewImageUrl = ":/images/libpalette/loading.png";
        if (!imageGatherer)
            imageGatherer = new UBDownloadHttpFile(0, this);

        connect(imageGatherer, SIGNAL(downloadFinished(int, bool, QUrl, QUrl, QString, QByteArray, QPointF, QSize, bool)), this, SLOT(onPreviewLoaded(int, bool, QUrl, QUrl, QString, QByteArray, QPointF, QSize, bool)));

        // We send here the request and store its reply in order to be able to cancel it if needed
        imageGatherer->get(QUrl(widgetsThumbsUrl), QPoint(0,0), QSize(), false);
300
    }
301

Claudio Valerio's avatar
Claudio Valerio committed
302
    UBFeature feature( "/root", QImage(previewImageUrl), QString(), widgetsUrl, FEATURE_ITEM );
303
    feature.setMetadata( metadata );
304

305
    centralWidget->showElement(feature, UBFeaturesCentralWidget::FeaturePropertiesList);
306
    mActionBar->setCurrentState( IN_PROPERTIES );
307 308
}

309

310
void UBFeaturesWidget::onPreviewLoaded(int id, bool pSuccess, QUrl sourceUrl, QUrl originalUrl, QString pContentTypeHeader, QByteArray pData, QPointF pPos, QSize pSize, bool isBackground)
311
{
312 313
    Q_UNUSED(id);
    Q_UNUSED(pSuccess);
314
    Q_UNUSED(originalUrl);
315 316 317
    Q_UNUSED(isBackground);
    Q_UNUSED(pSize);
    Q_UNUSED(pPos);
318 319
    Q_UNUSED(sourceUrl);
    Q_UNUSED(pContentTypeHeader)
320

321 322 323
    QImage img;
    img.loadFromData(pData);
    QPixmap pix = QPixmap::fromImage(img);
324 325
    centralWidget->setPropertiesPixmap(pix);
    centralWidget->setPropertiesThumbnail(pix);
326 327
}

328
void UBFeaturesWidget::onAddDownloadedFileToLibrary(bool pSuccess, QUrl sourceUrl, QString pContentHeader, QByteArray pData, QString pTitle)
329
{
330
    if (pSuccess) {
Claudio Valerio's avatar
Claudio Valerio committed
331
        qDebug() << pData.length();
332
        controller->addDownloadedFile(sourceUrl, pData, pContentHeader, pTitle);
333
        controller->refreshModels();
334 335 336
    }
}

337 338
void UBFeaturesWidget::addElementsToFavorite()
{
339 340
    if ( centralWidget->currentView() == UBFeaturesCentralWidget::FeaturePropertiesList ) {
        UBFeature feature = centralWidget->getCurElementFromProperties();
341 342
        if ( feature != UBFeature() && !UBApplication::isFromWeb(feature.getFullPath().toString())) {
            controller->addToFavorite( feature.getFullPath() );
343
        }
344

345 346
    } else if ( centralWidget->currentView() == UBFeaturesCentralWidget::MainList ) {
        QModelIndexList selected = centralWidget->listView()->selectionModel()->selectedIndexes();
347
        for ( int i = 0; i < selected.size(); ++i ) {
348
            UBFeature feature = selected.at(i).data( Qt::UserRole + 1 ).value<UBFeature>();
349 350
            controller->addToFavorite(feature.getFullPath());
       }
351
    }
352 353

    controller->refreshModels();
354 355
}

356 357
void UBFeaturesWidget::removeElementsFromFavorite()
{
358
    QModelIndexList selected = centralWidget->listView()->selectionModel()->selectedIndexes();
359
    QList <QUrl> items;
360
    for ( int i = 0; i < selected.size(); ++i )  {
361 362 363
        UBFeature feature = selected.at(i).data( Qt::UserRole + 1 ).value<UBFeature>();
        items.append( feature.getFullPath() );
    }
364 365 366

    foreach ( QUrl url, items )  {
        controller->removeFromFavorite(url, true);
367
    }
368 369

    controller->refreshModels();
370 371
}

Anna Udovichenko's avatar
Anna Udovichenko committed
372 373
void UBFeaturesWidget::switchToListView()
{
Claudio Valerio's avatar
Claudio Valerio committed
374 375
//    stackedWidget->setCurrentIndex(ID_LISTVIEW);
//    currentStackedWidget = ID_LISTVIEW;
Anna Udovichenko's avatar
Anna Udovichenko committed
376 377 378 379
}

void UBFeaturesWidget::switchToProperties()
{
Claudio Valerio's avatar
Claudio Valerio committed
380 381
//    stackedWidget->setCurrentIndex(ID_PROPERTIES);
//    currentStackedWidget = ID_PROPERTIES;
Anna Udovichenko's avatar
Anna Udovichenko committed
382 383
}

384 385
void UBFeaturesWidget::switchToWebView()
{
Claudio Valerio's avatar
Claudio Valerio committed
386 387
//    stackedWidget->setCurrentIndex(ID_WEBVIEW);
//    currentStackedWidget = ID_WEBVIEW;
388
}
Anna Udovichenko's avatar
Anna Udovichenko committed
389

390 391 392 393
QStringList UBFeaturesMimeData::formats() const
{
    return QMimeData::formats();
}
394

395 396 397 398
void UBFeaturesWidget::importImage(const QImage &image, const QString &fileName)
{
    controller->importImage(image, fileName);
}
Anna Udovichenko's avatar
Anna Udovichenko committed
399

400
UBFeaturesListView::UBFeaturesListView( QWidget* parent, const char* name )
401
    : QListView(parent)
402
{
403
    setObjectName(name);
404 405
}

406 407
void UBFeaturesListView::dragEnterEvent( QDragEnterEvent *event )
{
408
    if ( event->mimeData()->hasUrls() || event->mimeData()->hasImage() )
409
        event->acceptProposedAction();
410 411
}

412 413
void UBFeaturesListView::dragMoveEvent( QDragMoveEvent *event )
{
414 415 416 417 418 419 420 421
    const UBFeaturesMimeData *fMimeData = qobject_cast<const UBFeaturesMimeData*>(event->mimeData());
    QModelIndex index = indexAt(event->pos());
    UBFeature onFeature = model()->data(index, Qt::UserRole + 1).value<UBFeature>();
    if (fMimeData) {
        if (!index.isValid() || !onFeature.isFolder()) {
            event->ignore();
            return;
        }
422 423 424 425 426 427
        foreach (UBFeature curFeature, fMimeData->features()) {
            if (curFeature == onFeature) {
                event->ignore();
                return;
            }
        }
428 429 430
     }

    if ( event->mimeData()->hasUrls() || event->mimeData()->hasImage() ) {
431
        event->acceptProposedAction();
432 433 434
    } else {
        event->ignore();
    }
435 436
}

437 438
void UBFeaturesListView::dropEvent( QDropEvent *event )
{
439
    QWidget *eventSource = event->source();
440
    if (eventSource && eventSource->objectName() == UBFeaturesWidget::objNameFeatureList) {
441 442 443 444 445 446 447 448 449 450 451 452
        event->setDropAction( Qt::MoveAction );
    }

    QListView::dropEvent( event );
}

void UBFeaturesListView::thumbnailSizeChanged( int value )
{
    setIconSize(QSize(value, value));
    setGridSize(QSize(value + 20, value + 20 ));

    UBSettings::settings()->featureSliderPosition->set(value);
453 454
}

455
UBFeaturesNavigatorWidget::UBFeaturesNavigatorWidget(QWidget *parent, const char *name) :
Claudio Valerio's avatar
Claudio Valerio committed
456
    QWidget(parent), mListView(0), mListSlider(0)
457 458

{
459
    name = "UBFeaturesNavigatorWidget";
460 461

    setObjectName(name);
462
//    SET_STYLE_SHEET()
463

464
    mListView = new UBFeaturesListView(this, UBFeaturesWidget::objNameFeatureList);
465

Claudio Valerio's avatar
Claudio Valerio committed
466
    mListSlider = new QSlider(Qt::Horizontal, this);
467

Claudio Valerio's avatar
Claudio Valerio committed
468 469 470 471
    mListSlider->setMinimum(UBFeaturesWidget::minThumbnailSize);
    mListSlider->setMaximum(UBFeaturesWidget::maxThumbnailSize);
    mListSlider->setValue(UBFeaturesWidget::minThumbnailSize);
    mListSlider->setMinimumHeight(20);
472 473 474 475 476

    mListView->setParent(this);
    QVBoxLayout *mainLayer = new QVBoxLayout(this);

    mainLayer->addWidget(mListView, 1);
Claudio Valerio's avatar
Claudio Valerio committed
477
    mainLayer->addWidget(mListSlider, 0);
478
    mainLayer->setMargin(0);
479

Claudio Valerio's avatar
Claudio Valerio committed
480
    connect(mListSlider, SIGNAL(valueChanged(int)), mListView, SLOT(thumbnailSizeChanged(int)));
481 482 483 484
}

void UBFeaturesNavigatorWidget::setSliderPosition(int pValue)
{
Claudio Valerio's avatar
Claudio Valerio committed
485
    mListSlider->setValue(pValue);
486
}
487

488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510
UBFeaturesCentralWidget::UBFeaturesCentralWidget(QWidget *parent) : QWidget(parent)
{
    setObjectName("UBFeaturesCentralWidget");
    SET_STYLE_SHEET();

    QVBoxLayout *mLayout = new QVBoxLayout(this);
    setLayout(mLayout);

    //Maintains the view of the main part of the palette. Consists of
    //mNavigator
    //featureProperties
    //webVeiw
    mStackedWidget = new QStackedWidget(this);

    //Main features icon view with QSlider on the bottom
    mNavigator = new UBFeaturesNavigatorWidget(this);

    //Specifies the properties of a standalone element
    mFeatureProperties = new UBFeatureProperties(this);

    //Used to show search bar on the search widget
    webView = new UBFeaturesWebView(this);

Claudio Valerio's avatar
Claudio Valerio committed
511 512 513 514 515 516
    //filling stackwidget
    mStackedWidget->addWidget(mNavigator);
    mStackedWidget->addWidget(mFeatureProperties);
    mStackedWidget->addWidget(webView);
    mStackedWidget->setCurrentIndex(MainList);
    mStackedWidget->setContentsMargins(0, 0, 0, 0);
517 518 519 520 521 522 523 524 525 526 527 528


    mAdditionalDataContainer = new QStackedWidget(this);
    mAdditionalDataContainer->setObjectName("mAdditionalDataContainer");

    //New folder dialog
    UBFeaturesNewFolderDialog *dlg = new UBFeaturesNewFolderDialog(mAdditionalDataContainer);
    mAdditionalDataContainer->addWidget(dlg);
    mAdditionalDataContainer->setCurrentIndex(NewFolderDialog);

    connect(dlg, SIGNAL(createNewFolder(QString)), this, SLOT(createNewFolderSlot(QString)));
    connect(dlg, SIGNAL(closeDialog()), this, SLOT(hideAdditionalData()));
529
    connect(this, SIGNAL(sendFileNameList(QStringList)), dlg, SLOT(setFileNameList(QStringList)));
530 531

    //Progress bar to show scanning progress
532
    UBFeaturesProgressInfo *progressBar = new UBFeaturesProgressInfo();
533 534 535
    mAdditionalDataContainer->addWidget(progressBar);
    mAdditionalDataContainer->setCurrentIndex(ProgressBarWidget);

536 537 538 539
    connect(this, SIGNAL(maxFilesCountEvaluated(int)), progressBar, SLOT(setProgressMax(int)));
    connect(this, SIGNAL(increaseStatusBarValue()), progressBar, SLOT(increaseProgressValue()));
    connect(this, SIGNAL(scanCategory(QString)), progressBar, SLOT(setCommmonInfoText(QString)));
    connect(this, SIGNAL(scanPath(QString)), progressBar, SLOT(setDetailedInfoText(QString)));
540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574

    mLayout->addWidget(mStackedWidget, 1);
    mLayout->addWidget(mAdditionalDataContainer, 0);

    mAdditionalDataContainer->hide();
}

void UBFeaturesCentralWidget::showElement(const UBFeature &feature, StackElement pView)
{
    if (pView == FeaturesWebView) {
        webView->showElement(feature);
        mStackedWidget->setCurrentIndex(FeaturesWebView);
    } else if (pView == FeaturePropertiesList) {
        mFeatureProperties->showElement(feature);
        mStackedWidget->setCurrentIndex(FeaturePropertiesList);
    }
}

void UBFeaturesCentralWidget::switchTo(StackElement pView)
{
    mStackedWidget->setCurrentIndex(pView);
}

void UBFeaturesCentralWidget::setPropertiesPixmap(const QPixmap &pix)
{
    mFeatureProperties->setOrigPixmap(pix);
}

void UBFeaturesCentralWidget::setPropertiesThumbnail(const QPixmap &pix)
{
    mFeatureProperties->setThumbnail(pix);
}

UBFeature UBFeaturesCentralWidget::getCurElementFromProperties()
{
575
    return mFeatureProperties->getCurrentElement();
576 577 578 579
}

void UBFeaturesCentralWidget::showAdditionalData(AddWidget pWidgetType, AddWidgetState pState)
{
580 581 582 583 584
    if (!mAdditionalDataContainer->widget(pWidgetType)) {
        qDebug() << "can't find widget specified by UBFeaturesCentralWidget::showAdditionalData(AddWidget pWidgetType, AddWidgetState pState)";
        return;
    }

585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611
    mAdditionalDataContainer->setMaximumHeight(mAdditionalDataContainer->widget(pWidgetType)->sizeHint().height());

    mAdditionalDataContainer->setCurrentIndex(pWidgetType);
    mAdditionalDataContainer->show();
    emit lockMainWidget(pState == Modal ? true : false);
}

void UBFeaturesCentralWidget::setLockedExcludingAdditional(bool pLock)
{
//    Lock all the members excluding mAdditionalDataContainer
    mStackedWidget->setEnabled(!pLock);
}

void UBFeaturesCentralWidget::createNewFolderSlot(QString pStr)
{
    emit createNewFolderSignal(pStr);
    hideAdditionalData();
}

void UBFeaturesCentralWidget::hideAdditionalData()
{
    emit lockMainWidget(false);
    mAdditionalDataContainer->hide();
}

void UBFeaturesCentralWidget::scanStarted()
{
612
    showAdditionalData(ProgressBarWidget);
613 614 615 616
}

void UBFeaturesCentralWidget::scanFinished()
{
617
    hideAdditionalData();
618 619 620
}

UBFeaturesNewFolderDialog::UBFeaturesNewFolderDialog(QWidget *parent) : QWidget(parent)
621 622 623
  , acceptText(tr("Accept"))
  , cancelText(tr("Cancel"))
  , labelText(tr("Enter a new folder name"))
624 625 626
{
    this->setStyleSheet("background:white;");

627
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
628

629
    QVBoxLayout *labelLayout = new QVBoxLayout();
630 631 632 633

    QLabel *mLabel = new QLabel(labelText, this);
    mLineEdit = new QLineEdit(this);

Ilia Ryabokon's avatar
Ilia Ryabokon committed
634
    mValidator = new QRegExpValidator(QRegExp("[^\\/\\:\\?\\*\\|\\<\\>\\\"]{2,}"), this);
635 636 637 638
    mLineEdit->setValidator(mValidator);
    labelLayout->addWidget(mLabel);
    labelLayout->addWidget(mLineEdit);

639
    QHBoxLayout *buttonLayout = new QHBoxLayout();
640

641
    acceptButton = new QPushButton(acceptText, this);
642 643 644 645 646 647 648
    QPushButton *cancelButton = new QPushButton(cancelText, this);
    buttonLayout->addWidget(acceptButton);
    buttonLayout->addWidget(cancelButton);

    mainLayout->addLayout(labelLayout);
    mainLayout->addLayout(buttonLayout);

649 650
    acceptButton->setEnabled(false);

651 652
    connect(acceptButton, SIGNAL(clicked()), this, SLOT(accept()));
    connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
653 654 655
    connect(mLineEdit, SIGNAL(textEdited(QString)), this, SLOT(reactOnTextChanged(QString)));

    reactOnTextChanged(QString());
656 657 658 659 660 661
}

void UBFeaturesNewFolderDialog::setRegexp(const QRegExp pRegExp)
{
    mValidator->setRegExp(pRegExp);
}
662 663 664 665
bool UBFeaturesNewFolderDialog::validString(const QString &pStr)
{
    return mLineEdit->hasAcceptableInput() && !mFileNameList.contains(pStr, Qt::CaseSensitive);
}
666 667 668 669 670 671 672 673 674 675 676 677

void UBFeaturesNewFolderDialog::accept()
{
//     Setting all the constraints we need
    emit createNewFolder(mLineEdit->text());
    mLineEdit->clear();
}
void UBFeaturesNewFolderDialog::reject()
{
    mLineEdit->clear();
    emit closeDialog();
}
678 679 680 681 682 683 684 685 686 687 688 689 690 691
void UBFeaturesNewFolderDialog::setFileNameList(const QStringList &pLst)
{
    mFileNameList = pLst;
}
void UBFeaturesNewFolderDialog::reactOnTextChanged(const QString &pStr)
{
    if (validString(pStr)) {
        acceptButton->setEnabled(true);
        mLineEdit->setStyleSheet("background:white;");
    } else {
        acceptButton->setEnabled(false);
        mLineEdit->setStyleSheet("background:#FFB3C8;");
    }
}
692

693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721
UBFeaturesProgressInfo::UBFeaturesProgressInfo(QWidget *parent) :
    QWidget(parent),
    mProgressBar(0),
    mCommonInfoLabel(0),
    mDetailedInfoLabel(0)
{
    QVBoxLayout *mainLayer = new QVBoxLayout(this);

    mProgressBar = new QProgressBar(this);
//    setting defaults
    mProgressBar->setMinimum(0);
    mProgressBar->setMaximum(100000);
    mProgressBar->setValue(0);

    mProgressBar->setStyleSheet("background:white");

    mCommonInfoLabel = new QLabel(this);
    mDetailedInfoLabel = new QLabel(this);
    mDetailedInfoLabel->setAlignment(Qt::AlignRight);
    mCommonInfoLabel->hide();
    mDetailedInfoLabel->hide();

    mainLayer->addWidget(mCommonInfoLabel);
    mainLayer->addWidget(mDetailedInfoLabel);
    mainLayer->addWidget(mProgressBar);
}

void UBFeaturesProgressInfo::setCommmonInfoText(const QString &str)
{
722
    mProgressBar->setFormat(tr("Loading ") + str + " (%p%)");
723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750
}

void UBFeaturesProgressInfo::setDetailedInfoText(const QString &str)
{
    mDetailedInfoLabel->setText(str);
}

void UBFeaturesProgressInfo::setProgressMax(int pValue)
{
    mProgressBar->setMaximum(pValue);
}

void UBFeaturesProgressInfo::setProgressMin(int pValue)
{
    mProgressBar->setMinimum(pValue);
}

void UBFeaturesProgressInfo::increaseProgressValue()
{
    mProgressBar->setValue(mProgressBar->value() + 1);
}

void UBFeaturesProgressInfo::sendFeature(UBFeature pFeature)
{
    Q_UNUSED(pFeature);
}


751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
UBFeaturesWebView::UBFeaturesWebView(QWidget* parent, const char* name):QWidget(parent)
    , mpView(NULL)
    , mpWebSettings(NULL)
    , mpLayout(NULL)
    , mpSankoreAPI(NULL)
{
    setObjectName(name);

    SET_STYLE_SHEET();

    mpLayout = new QVBoxLayout();
    setLayout(mpLayout);

    mpView = new QWebView(this);
    mpView->setObjectName("SearchEngineView");
    mpSankoreAPI = new UBWidgetUniboardAPI(UBApplication::boardController->activeScene());
    mpView->page()->mainFrame()->addToJavaScriptWindowObject("sankore", mpSankoreAPI);
Claudio Valerio's avatar
Claudio Valerio committed
768
    connect(mpView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(javaScriptWindowObjectCleared()));
769 770 771 772 773 774 775 776 777 778
    mpWebSettings = QWebSettings::globalSettings();
    mpWebSettings->setAttribute(QWebSettings::JavaEnabled, true);
    mpWebSettings->setAttribute(QWebSettings::PluginsEnabled, true);
    mpWebSettings->setAttribute(QWebSettings::LocalStorageDatabaseEnabled, true);
    mpWebSettings->setAttribute(QWebSettings::OfflineWebApplicationCacheEnabled, true);
    mpWebSettings->setAttribute(QWebSettings::OfflineStorageDatabaseEnabled, true);
    mpWebSettings->setAttribute(QWebSettings::JavascriptCanAccessClipboard, true);
    mpWebSettings->setAttribute(QWebSettings::DnsPrefetchEnabled, true);

    mpLayout->addWidget(mpView);
779
    mpLayout->setMargin(0);
780 781 782 783 784 785

    connect(mpView, SIGNAL(loadFinished(bool)), this, SLOT(onLoadFinished(bool)));
}

UBFeaturesWebView::~UBFeaturesWebView()
{
786 787
    if( NULL != mpSankoreAPI )
    {
788 789 790
        delete mpSankoreAPI;
        mpSankoreAPI = NULL;
    }
791 792
    if( NULL != mpView )
    {
793 794 795
        delete mpView;
        mpView = NULL;
    }
796 797
    if( NULL != mpLayout )
    {
798 799 800 801 802
        delete mpLayout;
        mpLayout = NULL;
    }
}

Claudio Valerio's avatar
Claudio Valerio committed
803 804 805 806 807
void UBFeaturesWebView::javaScriptWindowObjectCleared()
{
    mpView->page()->mainFrame()->addToJavaScriptWindowObject("sankore", mpSankoreAPI);
}

808 809
void UBFeaturesWebView::showElement(const UBFeature &elem)
{
810
    QString qsWidgetName;
811
    QString path = elem.getFullPath().toLocalFile();
812

813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839
    QString qsConfigPath = QString("%0/config.xml").arg(path);

    if(QFile::exists(qsConfigPath))
    {
        QFile f(qsConfigPath);
        if(f.open(QIODevice::ReadOnly))
        {
            QDomDocument domDoc;
            domDoc.setContent(QString(f.readAll()));
            QDomElement root = domDoc.documentElement();

            QDomNode node = root.firstChild();
            while(!node.isNull())
            {
                if(node.toElement().tagName() == "content")
                {
                    QDomAttr srcAttr = node.toElement().attributeNode("src");
                    qsWidgetName = srcAttr.value();
                    break;
                }
                node = node.nextSibling();
            }
            f.close();
        }
    }

    mpView->load(QUrl::fromLocalFile(QString("%0/%1").arg(path).arg(qsWidgetName)));
840 841 842 843 844 845 846 847 848 849
}

void UBFeaturesWebView::onLoadFinished(bool ok)
{
    if(ok && NULL != mpSankoreAPI){
        mpView->page()->mainFrame()->addToJavaScriptWindowObject("sankore", mpSankoreAPI);
    }
}


Anna Udovichenko's avatar
Anna Udovichenko committed
850 851 852 853 854 855 856
UBFeatureProperties::UBFeatureProperties( QWidget *parent, const char *name ) : QWidget(parent)
    , mpLayout(NULL)
    , mpButtonLayout(NULL)
    , mpAddPageButton(NULL)
    , mpAddToLibButton(NULL)
    , mpSetAsBackgroundButton(NULL)
    , mpObjInfoLabel(NULL)
857
    , mpObjInfos(NULL)
Anna Udovichenko's avatar
Anna Udovichenko committed
858 859 860 861
    , mpThumbnail(NULL)
    , mpOrigPixmap(NULL)
    , mpElement(NULL)
{
862
    setObjectName(name);
Anna Udovichenko's avatar
Anna Udovichenko committed
863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896

    // 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);

897
    mpObjInfoLabel = new QLabel(tr("Object informations"));
Anna Udovichenko's avatar
Anna Udovichenko committed
898 899 900
    mpObjInfoLabel->setStyleSheet(QString("color: #888888; font-size : 18px; font-weight:bold;"));
    mpLayout->addWidget(mpObjInfoLabel, 0);

901 902 903 904 905 906 907 908
    mpObjInfos = new QTreeWidget(this);
    mpObjInfos->setColumnCount(2);
    mpObjInfos->header()->hide();
    mpObjInfos->setAlternatingRowColors(true);
    mpObjInfos->setRootIsDecorated(false);
    mpObjInfos->setObjectName("DockPaletteWidgetBox");
    mpObjInfos->setStyleSheet("background:white;");
    mpLayout->addWidget(mpObjInfos, 1);
909
    mpLayout->setMargin(0);
910

911
    connect( mpAddPageButton, SIGNAL(clicked()), this, SLOT(onAddToPage()) );
912
    connect( mpSetAsBackgroundButton, SIGNAL( clicked() ), this, SLOT( onSetAsBackground() ) );
913 914 915
    connect( mpAddToLibButton, SIGNAL( clicked() ), this, SLOT(onAddToLib() ) );
}

916 917
UBFeatureProperties::~UBFeatureProperties()
{
918
    if ( mpOrigPixmap )
919 920 921 922
    {
        delete mpOrigPixmap;
        mpOrigPixmap = NULL;
    }
923 924 925 926 927
    if ( mpElement )
    {
        delete mpElement;
        mpElement = NULL;
    }
928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964
    if ( mpThumbnail )
    {
        delete mpThumbnail;
        mpThumbnail = NULL;
    }
    if ( mpButtonLayout )
    {
        delete mpButtonLayout;
        mpButtonLayout = NULL;
    }
    if ( mpAddPageButton )
    {
        delete mpAddPageButton;
        mpAddPageButton = NULL;
    }
    if ( mpSetAsBackgroundButton )
    {
        delete mpSetAsBackgroundButton;
        mpSetAsBackgroundButton = NULL;
    }
    if ( mpAddToLibButton )
    {
        delete mpAddToLibButton;
        mpAddToLibButton = NULL;
    }
    if ( mpObjInfoLabel )
    {
        delete mpObjInfoLabel;
        mpObjInfoLabel = NULL;
    }
    if ( mpObjInfos )
    {
        delete mpObjInfos;
        mpObjInfos = NULL;
    }
}

965 966 967 968 969 970 971 972 973 974 975
void UBFeatureProperties::resizeEvent( QResizeEvent *event )
{
    Q_UNUSED(event);
    adaptSize();
}

void UBFeatureProperties::showEvent (QShowEvent *event )
{
    Q_UNUSED(event);
    adaptSize();
}
Anna Udovichenko's avatar
Anna Udovichenko committed
976

977 978 979 980
UBFeature UBFeatureProperties::getCurrentElement() const
{
    if ( mpElement )
        return *mpElement;
981

982 983 984
    return UBFeature();
}

985
void UBFeatureProperties::setOrigPixmap(const QPixmap &pix)
986
{
987

988 989 990 991 992 993
    if (mpOrigPixmap)
        delete mpOrigPixmap;

    mpOrigPixmap = new QPixmap(pix);
}

994
void UBFeatureProperties::setThumbnail(const QPixmap &pix)
995
{
996
    mpThumbnail->setPixmap(pix.scaledToWidth(THUMBNAIL_WIDTH));
997
    adaptSize();
998 999
}

1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
void UBFeatureProperties::adaptSize()
{
    if( NULL != mpOrigPixmap )
    {
        if( width() < THUMBNAIL_WIDTH + 40 )
        {
            mpThumbnail->setPixmap( mpOrigPixmap->scaledToWidth( width() - 40 ) );
        }
        else
        {
            mpThumbnail->setPixmap( mpOrigPixmap->scaledToWidth( THUMBNAIL_WIDTH ) );
        }
    }
Anna Udovichenko's avatar
Anna Udovichenko committed
1013 1014
}

1015
void UBFeatureProperties::showElement(const UBFeature &elem)
Anna Udovichenko's avatar
Anna Udovichenko committed
1016
{
1017
    if ( mpOrigPixmap )
Anna Udovichenko's avatar
Anna Udovichenko committed
1018 1019 1020 1021
    {
        delete mpOrigPixmap;
        mpOrigPixmap = NULL;
    }
1022 1023 1024 1025 1026
    if ( mpElement )
    {
        delete mpElement;
        mpElement = NULL;
    }
1027 1028 1029
    mpElement = new UBFeature(elem);
    mpOrigPixmap = new QPixmap(QPixmap::fromImage(elem.getThumbnail()));
    mpThumbnail->setPixmap(QPixmap::fromImage(elem.getThumbnail()).scaledToWidth(THUMBNAIL_WIDTH));
1030
    populateMetadata();
Anna Udovichenko's avatar
Anna Udovichenko committed
1031

1032
    if ( UBApplication::isFromWeb( elem.getFullPath().toString() ) )
1033
    {
Anna Udovichenko's avatar
Anna Udovichenko committed
1034
        mpAddToLibButton->show();
1035 1036
        if( elem.getMetadata()["Type"].toLower().contains("image") )
        {
Anna Udovichenko's avatar
Anna Udovichenko committed
1037 1038
            mpSetAsBackgroundButton->show();
        }
1039 1040
        else
        {
Anna Udovichenko's avatar
Anna Udovichenko committed
1041
            mpSetAsBackgroundButton->hide();
1042
        }
Anna Udovichenko's avatar
Anna Udovichenko committed
1043
    }
1044 1045
    else
    {
Anna Udovichenko's avatar
Anna Udovichenko committed
1046
        mpAddToLibButton->hide();
1047
        if (UBFileSystemUtils::mimeTypeFromFileName( elem.getFullPath().toLocalFile() ).contains("image"))
1048
        {
Anna Udovichenko's avatar
Anna Udovichenko committed
1049 1050
            mpSetAsBackgroundButton->show();
        }
1051 1052
        else
        {
Anna Udovichenko's avatar
Anna Udovichenko committed
1053 1054 1055 1056 1057
            mpSetAsBackgroundButton->hide();
        }
    }
}

1058 1059 1060 1061
void UBFeatureProperties::populateMetadata()
{
    if(NULL != mpObjInfos){
        mpObjInfos->clear();
1062
        QMap<QString, QString> metas = mpElement->getMetadata();
1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076
        QList<QString> lKeys = metas.keys();
        QList<QString> lValues = metas.values();

        for(int i=0; i< metas.size(); i++){
            QStringList values;
            values << lKeys.at(i);
            values << lValues.at(i);
            mpItem = new QTreeWidgetItem(values);
            mpObjInfos->addTopLevelItem(mpItem);
        }
        mpObjInfos->resizeColumnToContents(0);
    }
}

Anna Udovichenko's avatar
Anna Udovichenko committed
1077 1078
void UBFeatureProperties::onAddToPage()
{
1079 1080
    QWidget *w = parentWidget()->parentWidget()->parentWidget();
    UBFeaturesWidget* featuresWidget = qobject_cast<UBFeaturesWidget*>( w );
1081 1082
    if (featuresWidget)
        featuresWidget->getFeaturesController()->addItemToPage( *mpElement );
1083
}
Anna Udovichenko's avatar
Anna Udovichenko committed
1084

1085 1086 1087 1088 1089 1090 1091
void UBFeatureProperties::onAddToLib()
{
    if ( UBApplication::isFromWeb(  mpElement->getFullPath().toString() ) )
    {
        sDownloadFileDesc desc;
        desc.isBackground = false;
        desc.modal = false;
1092
        desc.dest = sDownloadFileDesc::library;
1093
        desc.name = mpElement->getMetadata().value("Title", QString());
1094
        qDebug() << desc.name;
1095
        desc.srcUrl = mpElement->getFullPath().toString();
1096 1097 1098 1099 1100 1101 1102 1103 1104
        QString str1 = mpElement->getFullPath().toString().normalized(QString::NormalizationForm_C);
        QString str2 = mpElement->getFullPath().toString().normalized(QString::NormalizationForm_D);
        QString str3 = mpElement->getFullPath().toString().normalized(QString::NormalizationForm_KC);
        QString str4 = mpElement->getFullPath().toString().normalized(QString::NormalizationForm_KD);
        qDebug() << desc.srcUrl << endl
                    << "str1" << str1 << endl
                    << "str2" << str2 << endl
                    << "str3" << str3 << endl
                    << "str4" << str4 << endl;
1105 1106 1107 1108 1109
        UBDownloadManager::downloadManager()->addFileToDownload(desc);
    }
}


1110 1111
void UBFeatureProperties::onSetAsBackground()
{
1112 1113
    QWidget *w = parentWidget()->parentWidget()->parentWidget();
    UBFeaturesWidget* featuresWidget = qobject_cast<UBFeaturesWidget*>( w );
1114
    featuresWidget->getFeaturesController()->addItemAsBackground( *mpElement );
Anna Udovichenko's avatar
Anna Udovichenko committed
1115 1116
}

1117

Anna Udovichenko's avatar
Anna Udovichenko committed
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130

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
{
1131
    if (!index.isValid())
Anna Udovichenko's avatar
Anna Udovichenko committed
1132 1133
        return QVariant();

1134
    if (role == Qt::DisplayRole) {
Ilia Ryabokon's avatar
Ilia Ryabokon committed
1135
        return featuresList->at(index.row()).getDisplayName();
1136 1137 1138
    }

    else if (role == Qt::DecorationRole) {
1139
        return QIcon( QPixmap::fromImage(featuresList->at(index.row()).getThumbnail()));
1140 1141

    } else if (role == Qt::UserRole) {
1142
        return featuresList->at(index.row()).getVirtualPath();
1143

Claudio Valerio's avatar
Claudio Valerio committed
1144
    }    else if (role == Qt::UserRole + 1) {
1145 1146 1147 1148
        //return featuresList->at(index.row()).getType();
        UBFeature f = featuresList->at(index.row());
        return QVariant::fromValue( f );
    }
Anna Udovichenko's avatar
Anna Udovichenko committed
1149

1150
    return QVariant();
Anna Udovichenko's avatar
Anna Udovichenko committed
1151 1152 1153 1154
}

QMimeData* UBFeaturesModel::mimeData(const QModelIndexList &indexes) const
{
1155
    UBFeaturesMimeData *mimeData = new UBFeaturesMimeData();
1156
    QList <QUrl> urlList;
1157 1158
    QList <UBFeature> featuresList;
    QByteArray typeData;
Anna Udovichenko's avatar
Anna Udovichenko committed
1159

1160 1161 1162 1163
    foreach (QModelIndex index, indexes) {

        if (index.isValid()) {
            UBFeature element = data(index, Qt::UserRole + 1).value<UBFeature>();
1164
            urlList.push_back( element.getFullPath() );
1165 1166 1167 1168 1169 1170 1171
            QString curPath = element.getFullPath().toLocalFile();
            featuresList.append(element);

            if (!typeData.isNull()) {
                typeData += UBFeaturesController::featureTypeSplitter();
            }
            typeData += QString::number(element.getType()).toAscii();
1172 1173
        }
    }
1174 1175 1176 1177

    mimeData->setUrls(urlList);
    mimeData->setFeatures(featuresList);
    mimeData->setData(mimeSankoreFeatureTypes, typeData);
Anna Udovichenko's avatar
Anna Udovichenko committed
1178 1179 1180 1181 1182 1183

    return mimeData;
}

bool UBFeaturesModel::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int column, const QModelIndex &parent)
{
Ivan Ilin's avatar
Ivan Ilin committed
1184 1185
    Q_UNUSED(row)

1186
    const UBFeaturesMimeData *fMimeData = qobject_cast<const UBFeaturesMimeData*>(mimeData);
1187 1188
    UBFeaturesController *curController = qobject_cast<UBFeaturesController *>(QObject::parent());

1189 1190 1191 1192 1193 1194
    bool dataFromSameModel = false;

    if (fMimeData)
        dataFromSameModel = true;

    if ((!mimeData->hasUrls() && !mimeData->hasImage()) )
1195 1196 1197 1198 1199
        return false;
    if ( action == Qt::IgnoreAction )
        return true;
    if ( column > 0 )
        return false;
Anna Udovichenko's avatar
Anna Udovichenko committed
1200

1201 1202
    UBFeature parentFeature;
    if (!parent.isValid()) {
1203
        parentFeature = curController->getCurrentElement();
1204 1205
    } else {
        parentFeature = parent.data( Qt::UserRole + 1).value<UBFeature>();
1206
    }
1207

1208
    if (dataFromSameModel) {
1209 1210 1211 1212 1213 1214 1215 1216
        QList<UBFeature> featList = fMimeData->features();
        for (int i = 0; i < featList.count(); i++) {
            UBFeature sourceElement;
            if (dataFromSameModel) {
                sourceElement = featList.at(i);
                moveData(sourceElement, parentFeature, Qt::MoveAction);
            }
        }
1217 1218 1219 1220 1221 1222 1223
    } else if (mimeData->hasUrls()) {
        QList<QUrl> urlList = mimeData->urls();
        foreach (QUrl curUrl, urlList) {
            qDebug() << "URl catched is " << curUrl.toLocalFile();
            curController->moveExternalData(curUrl, parentFeature);
        }
    } else if (mimeData->hasImage()) {
1224
        QImage image = qvariant_cast<QImage>( mimeData->imageData() );
1225 1226
        curController->importImage( image, parentFeature );

1227
    }
1228

1229
    return true;
Anna Udovichenko's avatar
Anna Udovichenko committed
1230 1231
}

1232 1233
void UBFeaturesModel::addItem( const UBFeature &item )
{
1234 1235 1236
    beginInsertRows( QModelIndex(), featuresList->size(), featuresList->size() );
    featuresList->append( item );
    endInsertRows();
1237 1238
}

1239 1240
void UBFeaturesModel::deleteFavoriteItem( const QString &path )
{
1241 1242
    for ( int i = 0; i < featuresList->size(); ++i )
    {
1243
        if ( !QString::compare( featuresList->at(i).getFullPath().toString(), path, Qt::CaseInsensitive ) &&
1244 1245 1246 1247 1248 1249
            !QString::compare( featuresList->at(i).getVirtualPath(), "/root/favorites", Qt::CaseInsensitive ) )
        {
            removeRow( i, QModelIndex() );
            return;
        }
    }
1250 1251
}

1252 1253 1254
void UBFeaturesModel::deleteItem( const QString &path )
{
    for ( int i = 0; i < featuresList->size(); ++i )
1255
    {
1256
        if ( !QString::compare( featuresList->at(i).getFullPath().toString(), path, Qt::CaseInsensitive ) )
1257 1258 1259 1260 1261
        {
            removeRow( i, QModelIndex() );
            return;
        }
    }
1262 1263
}

1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
void UBFeaturesModel::deleteItem(const UBFeature &feature)
{
    int i = featuresList->indexOf(feature);
    if (i == -1) {
        qDebug() << "no matches in deleting item from UBFEaturesModel";
        return;
    }
    removeRow(i, QModelIndex());
}

Anna Udovichenko's avatar
Anna Udovichenko committed
1274 1275
bool UBFeaturesModel::removeRows( int row, int count, const QModelIndex & parent )
{
1276 1277 1278 1279 1280 1281 1282 1283 1284
    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;
Anna Udovichenko's avatar
Anna Udovichenko committed
1285 1286 1287 1288
}

bool UBFeaturesModel::removeRow(  int row, const QModelIndex & parent )
{
1289 1290 1291 1292 1293 1294 1295 1296 1297
    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;
Anna Udovichenko's avatar
Anna Udovichenko committed
1298 1299
}

1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310
void UBFeaturesModel::moveData(const UBFeature &source, const UBFeature &destination
                               , Qt::DropAction action = Qt::CopyAction, bool deleteManualy)
{
    UBFeaturesController *curController = qobject_cast<UBFeaturesController *>(QObject::parent());
    if (!curController)
        return;

    QString sourcePath = source.getFullPath().toLocalFile();
    QString sourceVirtualPath = source.getVirtualPath();

    UBFeatureElementType sourceType = source.getType();
1311
    QImage sourceIcon = source.getThumbnail();
1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351

    Q_ASSERT( QFileInfo( sourcePath ).exists() );

    QString name = QFileInfo( sourcePath ).fileName();
    QString destPath = destination.getFullPath().toLocalFile();

    QString destVirtualPath = destination.getFullVirtualPath();
    QString destFullPath = destPath + "/" + name;

    if ( sourcePath.compare(destFullPath, Qt::CaseInsensitive ) || destination.getType() != FEATURE_TRASH)
    {
        UBFileSystemUtils::copy(sourcePath, destFullPath);
        if (action == Qt::MoveAction) {
            curController->deleteItem( source.getFullPath() );
        }
    }

    //Passing all the source container ubdating dependancy pathes
    if (sourceType == FEATURE_FOLDER) {
        for (int i = 0; i < featuresList->count(); i++) {

            UBFeature &curFeature = (*featuresList)[i];

            QString curFeatureFullPath = curFeature.getFullPath().toLocalFile();
            QString curFeatureVirtualPath = curFeature.getVirtualPath();

            if (curFeatureFullPath.contains(sourcePath) && curFeatureFullPath != sourcePath) {

                UBFeature copyFeature = curFeature;
                QUrl newPath = QUrl::fromLocalFile(curFeatureFullPath.replace(sourcePath, destFullPath));
                QString newVirtualPath = curFeatureVirtualPath.replace(sourceVirtualPath, destVirtualPath);
                //when copying to trash don't change the real path
                if (destination.getType() != FEATURE_TRASH) {
                    // processing copy or move action for real FS
                    if (action == Qt::CopyAction) {
                        copyFeature.setFullPath(newPath);
                    } else {
                        curFeature.setFullPath(newPath);
                    }
                }
1352
                // processing copy or move action for virtual FS
1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365
                if (action == Qt::CopyAction) {
                    copyFeature.setFullVirtualPath(newVirtualPath);
                } else {
                    curFeature.setFullVirtualPath(newVirtualPath);
                }

                if (action == Qt::CopyAction) {
                    addItem(copyFeature);
                }
            }
        }
    }

Ilia Ryabokon's avatar
Ilia Ryabokon committed
1366
    UBFeature newElement( destVirtualPath + "/" + name, sourceIcon, name, QUrl::fromLocalFile(destFullPath), sourceType );
1367 1368 1369 1370 1371 1372
    addItem(newElement);

    if (deleteManualy) {
        deleteItem(source);
    }

1373 1374 1375
// Commented because of crashes on mac. But works fine. It is not predictable behavior. 
// Please uncomment it if model will not refreshes
//   emit dataRestructured();. 
1376
}
1377

Anna Udovichenko's avatar
Anna Udovichenko committed
1378 1379
Qt::ItemFlags UBFeaturesModel::flags( const QModelIndex &index ) const
{
1380
    Qt::ItemFlags resultFlags = QAbstractItemModel::flags(index);
1381 1382 1383
    if ( index.isValid() )
    {
        UBFeature item = index.data( Qt::UserRole + 1 ).value<UBFeature>();
1384
        if ( item.getType() == FEATURE_INTERACTIVE
1385 1386 1387 1388
             || item.getType() == FEATURE_ITEM
             || item.getType() == FEATURE_AUDIO
             || item.getType() == FEATURE_VIDEO
             || item.getType() == FEATURE_IMAGE
1389
             || item.getType() == FEATURE_FLASH
1390 1391
             || item.getType() == FEATURE_INTERNAL
             || item.getType() == FEATURE_FOLDER)
1392 1393 1394 1395 1396 1397 1398 1399

            resultFlags |= Qt::ItemIsDragEnabled;

        if ( item.isFolder() && !item.getVirtualPath().isNull() )
            resultFlags |= Qt::ItemIsDropEnabled;
    }

    return resultFlags;
Anna Udovichenko's avatar
Anna Udovichenko committed
1400 1401 1402 1403 1404
}


QStringList UBFeaturesModel::mimeTypes() const
{
1405
    QStringList types;
1406
    types << "text/uri-list" << "image/png" << "image/tiff" << "image/gif" << "image/jpeg";
Anna Udovichenko's avatar
Anna Udovichenko committed
1407 1408 1409 1410 1411
    return types;
}

int UBFeaturesModel::rowCount(const QModelIndex &parent) const
{
1412
    if (parent.isValid() || !featuresList)
Anna Udovichenko's avatar
Anna Udovichenko committed
1413 1414 1415 1416 1417 1418 1419
        return 0;
    else
        return featuresList->size();
}

bool UBFeaturesProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex & sourceParent )const
{
1420 1421 1422 1423
    QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
    QString path = index.data( Qt::UserRole ).toString();

    return filterRegExp().exactMatch(path);
Anna Udovichenko's avatar
Anna Udovichenko committed
1424 1425 1426 1427
}

bool UBFeaturesSearchProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex & sourceParent )const
{
1428 1429 1430
    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();*/
Anna Udovichenko's avatar
Anna Udovichenko committed
1431

1432
    UBFeature feature = sourceModel()->data(index, Qt::UserRole + 1).value<UBFeature>();
1433
    bool isFile = feature.getType() == FEATURE_INTERACTIVE
1434 1435 1436 1437 1438
            || feature.getType() == FEATURE_INTERNAL
            || feature.getType() == FEATURE_ITEM
            || feature.getType() == FEATURE_AUDIO
            || feature.getType() == FEATURE_VIDEO
            || feature.getType() == FEATURE_IMAGE;
1439

1440 1441 1442
    return isFile
            && feature.getFullVirtualPath().contains(mFilterPrefix)
            && filterRegExp().exactMatch( feature.getName() );
Anna Udovichenko's avatar
Anna Udovichenko committed
1443 1444 1445 1446
}

bool UBFeaturesPathProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex & sourceParent )const
{
1447
    QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
1448
    UBFeature feature = sourceModel()->data(index, Qt::UserRole + 1).value<UBFeature>();
Claudio Valerio's avatar
Claudio Valerio committed
1449
    
1450
    return feature.isFolder() && path.startsWith( feature.getFullVirtualPath()) ;
1451

Anna Udovichenko's avatar
Anna Udovichenko committed
1452 1453
}

Claudio Valerio's avatar
Claudio Valerio committed
1454
QString    UBFeaturesItemDelegate::displayText ( const QVariant & value, const QLocale & locale ) const
Anna Udovichenko's avatar
Anna Udovichenko committed
1455
{
Ivan Ilin's avatar
Ivan Ilin committed
1456 1457 1458
    Q_UNUSED(locale)

    QString text = value.toString();
Ilia Ryabokon's avatar
Ilia Ryabokon committed
1459
    text = text.replace(".wgt", "");
1460 1461
    text = text.replace(".wgs", "");
    text = text.replace(".swf","");
1462 1463 1464
    if (listView)
    {
        const QFontMetrics fm = listView->fontMetrics();
1465
        const QSize iSize = listView->gridSize();
1466 1467 1468
        return elidedText( fm, iSize.width(), Qt::ElideRight, text );
    }
    return text;
Anna Udovichenko's avatar
Anna Udovichenko committed
1469 1470
}

1471
UBFeaturesPathItemDelegate::UBFeaturesPathItemDelegate(QObject *parent) : QStyledItemDelegate(parent)
Anna Udovichenko's avatar
Anna Udovichenko committed
1472
{
1473
    arrowPixmap = new QPixmap(":images/navig_arrow.png");
Anna Udovichenko's avatar
Anna Udovichenko committed
1474 1475
}

Claudio Valerio's avatar
Claudio Valerio committed
1476
QString    UBFeaturesPathItemDelegate::displayText ( const QVariant & value, const QLocale & locale ) const
Anna Udovichenko's avatar
Anna Udovichenko committed
1477
{
Ivan Ilin's avatar
Ivan Ilin committed
1478 1479 1480 1481
    Q_UNUSED(value)
    Q_UNUSED(locale)

    return QString();
Anna Udovichenko's avatar
Anna Udovichenko committed
1482 1483 1484 1485
}

void UBFeaturesPathItemDelegate::paint( QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
1486 1487 1488 1489
    UBFeature feature = index.data( Qt::UserRole + 1 ).value<UBFeature>();
    QRect rect = option.rect;
    if ( !feature.getFullPath().isEmpty() )
    {
Ilia Ryabokon's avatar
Ilia Ryabokon committed
1490
        painter->drawPixmap( rect.left() - 10, rect.center().y() - 5, *arrowPixmap );
1491
    }
1492
    painter->drawImage( rect.left() + 5, rect.center().y() - 5, feature.getThumbnail().scaledToHeight( 30, Qt::SmoothTransformation ) );
Anna Udovichenko's avatar
Anna Udovichenko committed
1493 1494 1495 1496
}

UBFeaturesPathItemDelegate::~UBFeaturesPathItemDelegate()
{
1497 1498 1499 1500 1501
    if ( arrowPixmap )
    {
        delete arrowPixmap;
        arrowPixmap = NULL;
    }
Ivan Ilin's avatar
Ivan Ilin committed
1502
}