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


Claudio Valerio's avatar
Claudio Valerio committed
26

Claudio Valerio's avatar
Claudio Valerio committed
27

28
#include <QDomDocument>
29
#include <QWebView>
30 31
#include <QWebFrame>
#include <QWidget>
32

Anna Udovichenko's avatar
Anna Udovichenko committed
33 34 35 36 37
#include "UBFeaturesWidget.h"
#include "gui/UBThumbnailWidget.h"
#include "frameworks/UBFileSystemUtils.h"
#include "core/UBApplication.h"
#include "core/UBDownloadManager.h"
38
#include "globals/UBGlobals.h"
39
#include "board/UBBoardController.h"
40 41 42

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

44 45 46 47 48
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
49 50 51
UBFeaturesWidget::UBFeaturesWidget(QWidget *parent, const char *name)
    : UBDockPaletteWidget(parent)
    , imageGatherer(NULL)
Anna Udovichenko's avatar
Anna Udovichenko committed
52 53 54 55 56
{
    setObjectName(name);
    mName = "FeaturesWidget";
    mVisibleState = true;

57
    SET_STYLE_SHEET();
Anna Udovichenko's avatar
Anna Udovichenko committed
58 59 60 61 62

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

63 64 65 66 67 68 69 70 71 72
    //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);

73
    centralWidget = new UBFeaturesCentralWidget(this);
Claudio Valerio's avatar
Claudio Valerio committed
74
    controller->assignFeaturesListView(centralWidget->listView());
75
    centralWidget->setSliderPosition(UBSettings::settings()->featureSliderPosition->get().toInt());
76 77 78

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

80
    //Filling main layout
81
    layout->addWidget(pathListView);
82
    layout->addWidget(centralWidget);
83 84
    layout->addWidget(mActionBar);

85
    connect(centralWidget->listView(), SIGNAL(clicked(const QModelIndex &)), this, SLOT(currentSelected(const QModelIndex &)));
86
    connect(this, SIGNAL(sendFileNameList(QStringList)), centralWidget, SIGNAL(sendFileNameList(QStringList)));
87 88 89 90 91 92 93 94 95
    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()));

96
    connect(mActionBar, SIGNAL(rescanModel()), this, SLOT(rescanModel()));
97
    connect(pathListView, SIGNAL(clicked(const QModelIndex &)), this, SLOT(currentSelected(const QModelIndex &)));
98
    connect(UBApplication::boardController, SIGNAL(displayMetadata(QMap<QString,QString>)), this, SLOT(onDisplayMetadata( QMap<QString,QString>)));
99 100
    connect(UBDownloadManager::downloadManager(), SIGNAL( addDownloadedFileToLibrary( bool, QUrl, QString, QByteArray, QString))
             , this, SLOT(onAddDownloadedFileToLibrary(bool, QUrl, QString,QByteArray, QString)));
101 102 103 104
    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()));
105 106
    connect(controller, SIGNAL(scanStarted()), mActionBar, SLOT(lockIt()));
    connect(controller, SIGNAL(scanFinished()), mActionBar, SLOT(unlockIt()));
107
    connect(controller, SIGNAL(maxFilesCountEvaluated(int)), centralWidget, SIGNAL(maxFilesCountEvaluated(int)));
108 109 110
    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
111 112
}

113 114
UBFeaturesWidget::~UBFeaturesWidget()
{
115 116
    if (NULL != imageGatherer)
        delete imageGatherer;
117 118
}

119
void UBFeaturesWidget::searchStarted(const QString &pattern)
Anna Udovichenko's avatar
Anna Udovichenko committed
120
{
121
    controller->searchStarted(pattern, centralWidget->listView());
Anna Udovichenko's avatar
Anna Udovichenko committed
122 123 124 125
}

void UBFeaturesWidget::currentSelected(const QModelIndex &current)
{
126 127 128 129
    if (!current.isValid()) {
        qWarning() << "SLOT:currentSelected, invalid index catched";
        return;
    }
130

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

133
    if (objName.isEmpty()) {
Claudio Valerio's avatar
Claudio Valerio committed
134
        qWarning() << "incorrect sender";
135 136 137
    } else if (objName == objNamePathList) {
        //Calling to reset the model for listView. Maybe separate function needed
        controller->searchStarted("", centralWidget->listView());
138
    }
Anna Udovichenko's avatar
Anna Udovichenko committed
139

140
    UBFeature feature = controller->getFeature(current, objName);
141 142 143 144 145 146 147

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

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

148
        centralWidget->switchTo(UBFeaturesCentralWidget::MainList);
149 150 151 152

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

153
        }  else if ( feature.getType() == FEATURE_CATEGORY && feature.getName() == "root" ) {
154 155 156
            mActionBar->setCurrentState( IN_ROOT );

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

159 160 161 162 163 164 165 166 167 168
        } 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  {
169
            mActionBar->setCurrentState(IN_FOLDER);
170 171
        }

172 173
//    } else if (feature.getType() == FEATURE_SEARCH) {
//        centralWidget->showElement(feature, UBFeaturesCentralWidget::FeaturesWebView);
174 175

    } else {
176
        centralWidget->showElement(feature, UBFeaturesCentralWidget::FeaturePropertiesList);
177 178
        mActionBar->setCurrentState( IN_PROPERTIES );
    }
179
    mActionBar->cleanText();
Anna Udovichenko's avatar
Anna Udovichenko committed
180 181
}

182 183
void UBFeaturesWidget::createNewFolder()
{
184
    centralWidget->showAdditionalData(UBFeaturesCentralWidget::NewFolderDialog, UBFeaturesCentralWidget::Modal);
185
    emit sendFileNameList(controller->getFileNamesInFolders());
Aleksei Kanash's avatar
Aleksei Kanash committed
186 187
}

188
void UBFeaturesWidget::deleteElements( const UBFeaturesMimeData * mimeData )
189
{
190 191 192 193
    if (!mimeData->features().count() )
        return;

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

195 196 197 198 199 200 201 202 203 204
    foreach ( UBFeature curFeature, featuresList ) {
        if ( curFeature.inTrash()) {
            controller->deleteItem(curFeature.getFullPath());

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

    controller->refreshModels();
205 206
}

207 208
void UBFeaturesWidget::deleteSelectedElements()
{
209
    QModelIndexList selected = centralWidget->listView()->selectionModel()->selectedIndexes();
210 211 212 213 214 215

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

217
    foreach (UBFeature feature, featureasToMove)
218
    {
219 220 221 222 223 224 225
        if (feature.isDeletable()) {
            if (feature.inTrash()) {
                controller->deleteItem(feature);
            } else {
                controller->moveToTrash(feature, true);
            }
        }
226
    }
227 228

    controller->refreshModels();
229 230
}

231
void UBFeaturesWidget::rescanModel()
232
{
233
    controller->rescanModel();
234 235
}

236 237 238 239 240 241 242
void UBFeaturesWidget::lockIt(bool pLock)
{
    mActionBar->setEnabled(!pLock);
    pathListView->setEnabled(!pLock);
    centralWidget->setLockedExcludingAdditional(pLock);
}

243
void UBFeaturesWidget::addToFavorite( const UBFeaturesMimeData * mimeData )
244
{
245 246 247 248 249 250 251 252 253
    if ( !mimeData->hasUrls() )
        return;

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

    controller->refreshModels();
254 255
}

256
void UBFeaturesWidget::removeFromFavorite( const UBFeaturesMimeData * mimeData )
257
{
258 259 260 261 262 263 264 265
    if ( !mimeData->hasUrls() )
        return;

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

    foreach( QUrl url, urls ) {
        controller->removeFromFavorite(url);
    }
266 267
}

268 269
void UBFeaturesWidget::onDisplayMetadata( QMap<QString,QString> metadata )
{
270
    QString previewImageUrl = ":images/libpalette/notFound.png";
271

272 273
    QString widgetsUrl = QUrl::fromEncoded(metadata["Url"].toLatin1()).toString()/*metadata.value("Url", QString())*/;
    QString widgetsThumbsUrl = QUrl::fromEncoded(metadata["thumbnailUrl"].toLatin1()).toString();
274

275 276
    QString strType = UBFileSystemUtils::mimeTypeFromFileName(widgetsUrl);
    UBMimeType::Enum thumbType = UBFileSystemUtils::mimeTypeFromString(strType);
277

278 279 280 281
    switch (static_cast<int>(thumbType)) {
    case UBMimeType::Audio:
        previewImageUrl = ":images/libpalette/soundIcon.svg";
        break;
282

283 284 285
    case UBMimeType::Video:
        previewImageUrl = ":images/libpalette/movieIcon.svg";
        break;
286

287 288 289
    case UBMimeType::Flash:
        previewImageUrl = ":images/libpalette/FlashIcon.svg";
        break;
290

291 292 293 294 295
    case UBMimeType::RasterImage:
    case UBMimeType::VectorImage:
        previewImageUrl = widgetsUrl;
        break;
    }
296

297
    if (!widgetsThumbsUrl.isNull()) {
298 299 300 301 302 303 304 305
        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);
306
    }
307

Claudio Valerio's avatar
Claudio Valerio committed
308
    UBFeature feature( "/root", QImage(previewImageUrl), QString(), widgetsUrl, FEATURE_ITEM );
309
    feature.setMetadata( metadata );
310

311
    centralWidget->showElement(feature, UBFeaturesCentralWidget::FeaturePropertiesList);
312
    mActionBar->setCurrentState( IN_PROPERTIES );
313 314
}

315

316
void UBFeaturesWidget::onPreviewLoaded(int id, bool pSuccess, QUrl sourceUrl, QUrl originalUrl, QString pContentTypeHeader, QByteArray pData, QPointF pPos, QSize pSize, bool isBackground)
317
{
318 319
    Q_UNUSED(id);
    Q_UNUSED(pSuccess);
320
    Q_UNUSED(originalUrl);
321 322 323
    Q_UNUSED(isBackground);
    Q_UNUSED(pSize);
    Q_UNUSED(pPos);
324 325
    Q_UNUSED(sourceUrl);
    Q_UNUSED(pContentTypeHeader)
326

327 328 329
    QImage img;
    img.loadFromData(pData);
    QPixmap pix = QPixmap::fromImage(img);
330 331
    centralWidget->setPropertiesPixmap(pix);
    centralWidget->setPropertiesThumbnail(pix);
332 333
}

334
void UBFeaturesWidget::onAddDownloadedFileToLibrary(bool pSuccess, QUrl sourceUrl, QString pContentHeader, QByteArray pData, QString pTitle)
335
{
336
    if (pSuccess) {
Claudio Valerio's avatar
Claudio Valerio committed
337
        qDebug() << pData.length();
338
        controller->addDownloadedFile(sourceUrl, pData, pContentHeader, pTitle);
339
        controller->refreshModels();
340 341 342
    }
}

343 344
void UBFeaturesWidget::addElementsToFavorite()
{
345 346
    if ( centralWidget->currentView() == UBFeaturesCentralWidget::FeaturePropertiesList ) {
        UBFeature feature = centralWidget->getCurElementFromProperties();
347 348
        if ( feature != UBFeature() && !UBApplication::isFromWeb(feature.getFullPath().toString())) {
            controller->addToFavorite( feature.getFullPath() );
349
        }
350

351 352
    } else if ( centralWidget->currentView() == UBFeaturesCentralWidget::MainList ) {
        QModelIndexList selected = centralWidget->listView()->selectionModel()->selectedIndexes();
353
        for ( int i = 0; i < selected.size(); ++i ) {
354
            UBFeature feature = selected.at(i).data( Qt::UserRole + 1 ).value<UBFeature>();
355 356
            controller->addToFavorite(feature.getFullPath());
       }
357
    }
358 359

    controller->refreshModels();
360 361
}

362 363
void UBFeaturesWidget::removeElementsFromFavorite()
{
364
    QModelIndexList selected = centralWidget->listView()->selectionModel()->selectedIndexes();
365
    QList <QUrl> items;
366
    for ( int i = 0; i < selected.size(); ++i )  {
367 368 369
        UBFeature feature = selected.at(i).data( Qt::UserRole + 1 ).value<UBFeature>();
        items.append( feature.getFullPath() );
    }
370 371 372

    foreach ( QUrl url, items )  {
        controller->removeFromFavorite(url, true);
373
    }
374 375

    controller->refreshModels();
376 377
}

Anna Udovichenko's avatar
Anna Udovichenko committed
378 379
void UBFeaturesWidget::switchToListView()
{
Claudio Valerio's avatar
Claudio Valerio committed
380 381
//    stackedWidget->setCurrentIndex(ID_LISTVIEW);
//    currentStackedWidget = ID_LISTVIEW;
Anna Udovichenko's avatar
Anna Udovichenko committed
382 383 384 385
}

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

390 391
void UBFeaturesWidget::switchToWebView()
{
Claudio Valerio's avatar
Claudio Valerio committed
392 393
//    stackedWidget->setCurrentIndex(ID_WEBVIEW);
//    currentStackedWidget = ID_WEBVIEW;
394
}
Anna Udovichenko's avatar
Anna Udovichenko committed
395

396 397 398 399
QStringList UBFeaturesMimeData::formats() const
{
    return QMimeData::formats();
}
400

401 402 403 404
void UBFeaturesWidget::importImage(const QImage &image, const QString &fileName)
{
    controller->importImage(image, fileName);
}
Anna Udovichenko's avatar
Anna Udovichenko committed
405

406
UBFeaturesListView::UBFeaturesListView( QWidget* parent, const char* name )
407
    : QListView(parent)
408
{
409
    setObjectName(name);
410 411
}

412 413
void UBFeaturesListView::dragEnterEvent( QDragEnterEvent *event )
{
414
    if ( event->mimeData()->hasUrls() || event->mimeData()->hasImage() )
415
        event->acceptProposedAction();
416 417
}

418 419
void UBFeaturesListView::dragMoveEvent( QDragMoveEvent *event )
{
420 421 422 423 424 425 426 427
    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;
        }
428 429 430 431 432 433
        foreach (UBFeature curFeature, fMimeData->features()) {
            if (curFeature == onFeature) {
                event->ignore();
                return;
            }
        }
434 435 436
     }

    if ( event->mimeData()->hasUrls() || event->mimeData()->hasImage() ) {
437
        event->acceptProposedAction();
438 439 440
    } else {
        event->ignore();
    }
441 442
}

443 444
void UBFeaturesListView::dropEvent( QDropEvent *event )
{
445
    QObject *eventSource = event->source();
446
    if (eventSource && eventSource->objectName() == UBFeaturesWidget::objNameFeatureList) {
447 448 449 450 451 452 453 454 455 456 457 458
        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);
459 460
}

461
UBFeaturesNavigatorWidget::UBFeaturesNavigatorWidget(QWidget *parent, const char *name) :
Claudio Valerio's avatar
Claudio Valerio committed
462
    QWidget(parent), mListView(0), mListSlider(0)
463 464

{
465
    name = "UBFeaturesNavigatorWidget";
466 467

    setObjectName(name);
468
//    SET_STYLE_SHEET()
469

470
    mListView = new UBFeaturesListView(this, UBFeaturesWidget::objNameFeatureList);
471

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

Claudio Valerio's avatar
Claudio Valerio committed
474 475 476 477
    mListSlider->setMinimum(UBFeaturesWidget::minThumbnailSize);
    mListSlider->setMaximum(UBFeaturesWidget::maxThumbnailSize);
    mListSlider->setValue(UBFeaturesWidget::minThumbnailSize);
    mListSlider->setMinimumHeight(20);
478 479 480 481 482

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

    mainLayer->addWidget(mListView, 1);
Claudio Valerio's avatar
Claudio Valerio committed
483
    mainLayer->addWidget(mListSlider, 0);
484
    mainLayer->setMargin(0);
485

Claudio Valerio's avatar
Claudio Valerio committed
486
    connect(mListSlider, SIGNAL(valueChanged(int)), mListView, SLOT(thumbnailSizeChanged(int)));
487 488 489 490
}

void UBFeaturesNavigatorWidget::setSliderPosition(int pValue)
{
Claudio Valerio's avatar
Claudio Valerio committed
491
    mListSlider->setValue(pValue);
492
}
493

494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516
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
517 518 519 520 521 522
    //filling stackwidget
    mStackedWidget->addWidget(mNavigator);
    mStackedWidget->addWidget(mFeatureProperties);
    mStackedWidget->addWidget(webView);
    mStackedWidget->setCurrentIndex(MainList);
    mStackedWidget->setContentsMargins(0, 0, 0, 0);
523 524 525 526 527 528 529 530 531 532 533 534


    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()));
535
    connect(this, SIGNAL(sendFileNameList(QStringList)), dlg, SLOT(setFileNameList(QStringList)));
536 537

    //Progress bar to show scanning progress
538
    UBFeaturesProgressInfo *progressBar = new UBFeaturesProgressInfo();
539 540 541
    mAdditionalDataContainer->addWidget(progressBar);
    mAdditionalDataContainer->setCurrentIndex(ProgressBarWidget);

542 543 544 545
    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)));
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 575 576 577 578 579 580

    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()
{
581
    return mFeatureProperties->getCurrentElement();
582 583 584 585
}

void UBFeaturesCentralWidget::showAdditionalData(AddWidget pWidgetType, AddWidgetState pState)
{
586 587 588 589 590
    if (!mAdditionalDataContainer->widget(pWidgetType)) {
        qDebug() << "can't find widget specified by UBFeaturesCentralWidget::showAdditionalData(AddWidget pWidgetType, AddWidgetState pState)";
        return;
    }

591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617
    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()
{
618
    showAdditionalData(ProgressBarWidget);
619 620 621 622
}

void UBFeaturesCentralWidget::scanFinished()
{
623
    hideAdditionalData();
624 625 626
}

UBFeaturesNewFolderDialog::UBFeaturesNewFolderDialog(QWidget *parent) : QWidget(parent)
627 628 629
  , acceptText(tr("Accept"))
  , cancelText(tr("Cancel"))
  , labelText(tr("Enter a new folder name"))
630 631 632
{
    this->setStyleSheet("background:white;");

633
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
634

635
    QVBoxLayout *labelLayout = new QVBoxLayout();
636 637 638 639

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

Ilia Ryabokon's avatar
Ilia Ryabokon committed
640
    mValidator = new QRegExpValidator(QRegExp("[^\\/\\:\\?\\*\\|\\<\\>\\\"]{2,}"), this);
641 642 643 644
    mLineEdit->setValidator(mValidator);
    labelLayout->addWidget(mLabel);
    labelLayout->addWidget(mLineEdit);

645
    QHBoxLayout *buttonLayout = new QHBoxLayout();
646

647
    acceptButton = new QPushButton(acceptText, this);
648 649 650 651 652 653 654
    QPushButton *cancelButton = new QPushButton(cancelText, this);
    buttonLayout->addWidget(acceptButton);
    buttonLayout->addWidget(cancelButton);

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

655 656
    acceptButton->setEnabled(false);

657 658
    connect(acceptButton, SIGNAL(clicked()), this, SLOT(accept()));
    connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
659 660 661
    connect(mLineEdit, SIGNAL(textEdited(QString)), this, SLOT(reactOnTextChanged(QString)));

    reactOnTextChanged(QString());
662 663 664 665 666 667
}

void UBFeaturesNewFolderDialog::setRegexp(const QRegExp pRegExp)
{
    mValidator->setRegExp(pRegExp);
}
668 669 670 671
bool UBFeaturesNewFolderDialog::validString(const QString &pStr)
{
    return mLineEdit->hasAcceptableInput() && !mFileNameList.contains(pStr, Qt::CaseSensitive);
}
672 673 674 675 676 677 678 679 680 681 682 683

void UBFeaturesNewFolderDialog::accept()
{
//     Setting all the constraints we need
    emit createNewFolder(mLineEdit->text());
    mLineEdit->clear();
}
void UBFeaturesNewFolderDialog::reject()
{
    mLineEdit->clear();
    emit closeDialog();
}
684 685 686 687 688 689 690 691 692 693 694 695 696 697
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;");
    }
}
698

699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727
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)
{
728
    mProgressBar->setFormat(tr("Loading ") + str + " (%p%)");
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
}

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


757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773
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
774
    connect(mpView->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(javaScriptWindowObjectCleared()));
775 776 777 778 779 780 781 782
    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);
783
    mpWebSettings->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, true);
784 785

    mpLayout->addWidget(mpView);
786
    mpLayout->setMargin(0);
787 788 789 790 791 792

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

UBFeaturesWebView::~UBFeaturesWebView()
{
793 794
    if( NULL != mpSankoreAPI )
    {
795 796 797
        delete mpSankoreAPI;
        mpSankoreAPI = NULL;
    }
798 799
    if( NULL != mpView )
    {
800 801 802
        delete mpView;
        mpView = NULL;
    }
803 804
    if( NULL != mpLayout )
    {
805 806 807 808 809
        delete mpLayout;
        mpLayout = NULL;
    }
}

Claudio Valerio's avatar
Claudio Valerio committed
810 811 812 813 814
void UBFeaturesWebView::javaScriptWindowObjectCleared()
{
    mpView->page()->mainFrame()->addToJavaScriptWindowObject("sankore", mpSankoreAPI);
}

815 816
void UBFeaturesWebView::showElement(const UBFeature &elem)
{
817
    QString qsWidgetName;
818
    QString path = elem.getFullPath().toLocalFile();
819

820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846
    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)));
847 848 849 850 851 852 853 854 855 856
}

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


Anna Udovichenko's avatar
Anna Udovichenko committed
857 858 859 860 861 862 863
UBFeatureProperties::UBFeatureProperties( QWidget *parent, const char *name ) : QWidget(parent)
    , mpLayout(NULL)
    , mpButtonLayout(NULL)
    , mpAddPageButton(NULL)
    , mpAddToLibButton(NULL)
    , mpSetAsBackgroundButton(NULL)
    , mpObjInfoLabel(NULL)
864
    , mpObjInfos(NULL)
Anna Udovichenko's avatar
Anna Udovichenko committed
865 866 867 868
    , mpThumbnail(NULL)
    , mpOrigPixmap(NULL)
    , mpElement(NULL)
{
869
    setObjectName(name);
Anna Udovichenko's avatar
Anna Udovichenko committed
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 897 898 899 900 901 902 903

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

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

908 909 910 911 912 913 914 915
    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);
916
    mpLayout->setMargin(0);
917

918
    connect( mpAddPageButton, SIGNAL(clicked()), this, SLOT(onAddToPage()) );
919
    connect( mpSetAsBackgroundButton, SIGNAL( clicked() ), this, SLOT( onSetAsBackground() ) );
920 921 922
    connect( mpAddToLibButton, SIGNAL( clicked() ), this, SLOT(onAddToLib() ) );
}

923 924
UBFeatureProperties::~UBFeatureProperties()
{
925
    if ( mpOrigPixmap )
926 927 928 929
    {
        delete mpOrigPixmap;
        mpOrigPixmap = NULL;
    }
930 931 932 933 934
    if ( mpElement )
    {
        delete mpElement;
        mpElement = NULL;
    }
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 965 966 967 968 969 970 971
    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;
    }
}

972 973 974 975 976 977 978 979 980 981 982
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
983

984 985 986 987
UBFeature UBFeatureProperties::getCurrentElement() const
{
    if ( mpElement )
        return *mpElement;
988

989 990 991
    return UBFeature();
}

992
void UBFeatureProperties::setOrigPixmap(const QPixmap &pix)
993
{
994

995 996 997 998 999 1000
    if (mpOrigPixmap)
        delete mpOrigPixmap;

    mpOrigPixmap = new QPixmap(pix);
}

1001
void UBFeatureProperties::setThumbnail(const QPixmap &pix)
1002
{
1003
    mpThumbnail->setPixmap(pix.scaledToWidth(THUMBNAIL_WIDTH));
1004
    adaptSize();
1005 1006
}

1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019
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
1020 1021
}

1022
void UBFeatureProperties::showElement(const UBFeature &elem)
Anna Udovichenko's avatar
Anna Udovichenko committed
1023
{
1024
    if ( mpOrigPixmap )
Anna Udovichenko's avatar
Anna Udovichenko committed
1025 1026 1027 1028
    {
        delete mpOrigPixmap;
        mpOrigPixmap = NULL;
    }
1029 1030 1031 1032 1033
    if ( mpElement )
    {
        delete mpElement;
        mpElement = NULL;
    }
1034 1035 1036
    mpElement = new UBFeature(elem);
    mpOrigPixmap = new QPixmap(QPixmap::fromImage(elem.getThumbnail()));
    mpThumbnail->setPixmap(QPixmap::fromImage(elem.getThumbnail()).scaledToWidth(THUMBNAIL_WIDTH));
1037
    populateMetadata();
Anna Udovichenko's avatar
Anna Udovichenko committed
1038

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

1065 1066 1067 1068
void UBFeatureProperties::populateMetadata()
{
    if(NULL != mpObjInfos){
        mpObjInfos->clear();
1069
        QMap<QString, QString> metas = mpElement->getMetadata();
1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083
        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
1084 1085
void UBFeatureProperties::onAddToPage()
{
1086 1087
    QWidget *w = parentWidget()->parentWidget()->parentWidget();
    UBFeaturesWidget* featuresWidget = qobject_cast<UBFeaturesWidget*>( w );
1088 1089
    if (featuresWidget)
        featuresWidget->getFeaturesController()->addItemToPage( *mpElement );
1090
}
Anna Udovichenko's avatar
Anna Udovichenko committed
1091

1092 1093 1094 1095 1096 1097 1098
void UBFeatureProperties::onAddToLib()
{
    if ( UBApplication::isFromWeb(  mpElement->getFullPath().toString() ) )
    {
        sDownloadFileDesc desc;
        desc.isBackground = false;
        desc.modal = false;
1099
        desc.dest = sDownloadFileDesc::library;
1100
        desc.name = mpElement->getMetadata().value("Title", QString());
1101
        qDebug() << desc.name;
1102
        desc.srcUrl = mpElement->getFullPath().toString();
1103 1104 1105 1106 1107 1108 1109 1110 1111
        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;
1112 1113 1114 1115 1116
        UBDownloadManager::downloadManager()->addFileToDownload(desc);
    }
}


1117 1118
void UBFeatureProperties::onSetAsBackground()
{
1119 1120
    QWidget *w = parentWidget()->parentWidget()->parentWidget();
    UBFeaturesWidget* featuresWidget = qobject_cast<UBFeaturesWidget*>( w );
1121
    featuresWidget->getFeaturesController()->addItemAsBackground( *mpElement );
Anna Udovichenko's avatar
Anna Udovichenko committed
1122 1123
}

1124

Anna Udovichenko's avatar
Anna Udovichenko committed
1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137

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

1141
    if (role == Qt::DisplayRole) {
Ilia Ryabokon's avatar
Ilia Ryabokon committed
1142
        return featuresList->at(index.row()).getDisplayName();
1143 1144 1145
    }

    else if (role == Qt::DecorationRole) {
1146
        return QIcon( QPixmap::fromImage(featuresList->at(index.row()).getThumbnail()));
1147 1148

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

Claudio Valerio's avatar
Claudio Valerio committed
1151
    }    else if (role == Qt::UserRole + 1) {
1152 1153 1154 1155
        //return featuresList->at(index.row()).getType();
        UBFeature f = featuresList->at(index.row());
        return QVariant::fromValue( f );
    }
Anna Udovichenko's avatar
Anna Udovichenko committed
1156

1157
    return QVariant();
Anna Udovichenko's avatar
Anna Udovichenko committed
1158 1159 1160 1161
}

QMimeData* UBFeaturesModel::mimeData(const QModelIndexList &indexes) const
{
1162
    UBFeaturesMimeData *mimeData = new UBFeaturesMimeData();
1163
    QList <QUrl> urlList;
1164 1165
    QList <UBFeature> featuresList;
    QByteArray typeData;
Anna Udovichenko's avatar
Anna Udovichenko committed
1166

1167 1168 1169 1170
    foreach (QModelIndex index, indexes) {

        if (index.isValid()) {
            UBFeature element = data(index, Qt::UserRole + 1).value<UBFeature>();
1171
            urlList.push_back( element.getFullPath() );
1172 1173 1174 1175 1176 1177
            QString curPath = element.getFullPath().toLocalFile();
            featuresList.append(element);

            if (!typeData.isNull()) {
                typeData += UBFeaturesController::featureTypeSplitter();
            }
1178
            typeData += QString::number(element.getType()).toLatin1();
1179 1180
        }
    }
1181 1182 1183 1184

    mimeData->setUrls(urlList);
    mimeData->setFeatures(featuresList);
    mimeData->setData(mimeSankoreFeatureTypes, typeData);
Anna Udovichenko's avatar
Anna Udovichenko committed
1185 1186 1187 1188 1189 1190

    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
1191 1192
    Q_UNUSED(row)

1193
    const UBFeaturesMimeData *fMimeData = qobject_cast<const UBFeaturesMimeData*>(mimeData);
1194 1195
    UBFeaturesController *curController = qobject_cast<UBFeaturesController *>(QObject::parent());

1196 1197 1198 1199 1200 1201
    bool dataFromSameModel = false;

    if (fMimeData)
        dataFromSameModel = true;

    if ((!mimeData->hasUrls() && !mimeData->hasImage()) )
1202 1203 1204 1205 1206
        return false;
    if ( action == Qt::IgnoreAction )
        return true;
    if ( column > 0 )
        return false;
Anna Udovichenko's avatar
Anna Udovichenko committed
1207

1208 1209
    UBFeature parentFeature;
    if (!parent.isValid()) {
1210
        parentFeature = curController->getCurrentElement();
1211 1212
    } else {
        parentFeature = parent.data( Qt::UserRole + 1).value<UBFeature>();
1213
    }
1214

1215
    if (dataFromSameModel) {
1216 1217 1218 1219 1220 1221 1222 1223
        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);
            }
        }
1224 1225 1226 1227 1228 1229 1230
    } 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()) {
1231
        QImage image = qvariant_cast<QImage>( mimeData->imageData() );
1232 1233
        curController->importImage( image, parentFeature );

1234
    }
1235

1236
    return true;
Anna Udovichenko's avatar
Anna Udovichenko committed
1237 1238
}

1239 1240
void UBFeaturesModel::addItem( const UBFeature &item )
{
1241 1242 1243
    beginInsertRows( QModelIndex(), featuresList->size(), featuresList->size() );
    featuresList->append( item );
    endInsertRows();
1244 1245
}

1246 1247
void UBFeaturesModel::deleteFavoriteItem( const QString &path )
{
1248 1249
    for ( int i = 0; i < featuresList->size(); ++i )
    {
1250
        if ( !QString::compare( featuresList->at(i).getFullPath().toString(), path, Qt::CaseInsensitive ) &&
1251 1252 1253 1254 1255 1256
            !QString::compare( featuresList->at(i).getVirtualPath(), "/root/favorites", Qt::CaseInsensitive ) )
        {
            removeRow( i, QModelIndex() );
            return;
        }
    }
1257 1258
}

1259 1260 1261
void UBFeaturesModel::deleteItem( const QString &path )
{
    for ( int i = 0; i < featuresList->size(); ++i )
1262
    {
1263
        if ( !QString::compare( featuresList->at(i).getFullPath().toString(), path, Qt::CaseInsensitive ) )
1264 1265 1266 1267 1268
        {
            removeRow( i, QModelIndex() );
            return;
        }
    }
1269 1270
}

1271 1272 1273 1274 1275 1276 1277 1278 1279 1280
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
1281 1282
bool UBFeaturesModel::removeRows( int row, int count, const QModelIndex & parent )
{
1283 1284 1285 1286 1287 1288 1289 1290 1291
    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
1292 1293 1294 1295
}

bool UBFeaturesModel::removeRow(  int row, const QModelIndex & parent )
{
1296 1297 1298 1299 1300 1301 1302 1303 1304
    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
1305 1306
}

1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317
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();
1318
    QImage sourceIcon = source.getThumbnail();
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 1352 1353 1354 1355 1356 1357 1358

    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);
                    }
                }
1359
                // processing copy or move action for virtual FS
1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372
                if (action == Qt::CopyAction) {
                    copyFeature.setFullVirtualPath(newVirtualPath);
                } else {
                    curFeature.setFullVirtualPath(newVirtualPath);
                }

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

Ilia Ryabokon's avatar
Ilia Ryabokon committed
1373
    UBFeature newElement( destVirtualPath + "/" + name, sourceIcon, name, QUrl::fromLocalFile(destFullPath), sourceType );
1374 1375 1376 1377 1378 1379
    addItem(newElement);

    if (deleteManualy) {
        deleteItem(source);
    }

1380 1381 1382
// Commented because of crashes on mac. But works fine. It is not predictable behavior. 
// Please uncomment it if model will not refreshes
//   emit dataRestructured();. 
1383
}
1384

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

            resultFlags |= Qt::ItemIsDragEnabled;

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

    return resultFlags;
Anna Udovichenko's avatar
Anna Udovichenko committed
1407 1408 1409 1410 1411
}


QStringList UBFeaturesModel::mimeTypes() const
{
1412
    QStringList types;
1413
    types << "text/uri-list" << "image/png" << "image/tiff" << "image/gif" << "image/jpeg";
Anna Udovichenko's avatar
Anna Udovichenko committed
1414 1415 1416 1417 1418
    return types;
}

int UBFeaturesModel::rowCount(const QModelIndex &parent) const
{
1419
    if (parent.isValid() || !featuresList)
Anna Udovichenko's avatar
Anna Udovichenko committed
1420 1421 1422 1423 1424 1425 1426
        return 0;
    else
        return featuresList->size();
}

bool UBFeaturesProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex & sourceParent )const
{
1427 1428 1429 1430
    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
1431 1432 1433 1434
}

bool UBFeaturesSearchProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex & sourceParent )const
{
1435 1436 1437
    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
1438

1439
    UBFeature feature = sourceModel()->data(index, Qt::UserRole + 1).value<UBFeature>();
1440
    bool isFile = feature.getType() == FEATURE_INTERACTIVE
1441 1442 1443 1444 1445
            || feature.getType() == FEATURE_INTERNAL
            || feature.getType() == FEATURE_ITEM
            || feature.getType() == FEATURE_AUDIO
            || feature.getType() == FEATURE_VIDEO
            || feature.getType() == FEATURE_IMAGE;
1446

1447 1448 1449
    return isFile
            && feature.getFullVirtualPath().contains(mFilterPrefix)
            && filterRegExp().exactMatch( feature.getName() );
Anna Udovichenko's avatar
Anna Udovichenko committed
1450 1451 1452 1453
}

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

Anna Udovichenko's avatar
Anna Udovichenko committed
1459 1460
}

Claudio Valerio's avatar
Claudio Valerio committed
1461
QString    UBFeaturesItemDelegate::displayText ( const QVariant & value, const QLocale & locale ) const
Anna Udovichenko's avatar
Anna Udovichenko committed
1462
{
Ivan Ilin's avatar
Ivan Ilin committed
1463 1464 1465
    Q_UNUSED(locale)

    QString text = value.toString();
Ilia Ryabokon's avatar
Ilia Ryabokon committed
1466
    text = text.replace(".wgt", "");
1467 1468
    text = text.replace(".wgs", "");
    text = text.replace(".swf","");
1469 1470 1471
    if (listView)
    {
        const QFontMetrics fm = listView->fontMetrics();
1472
        const QSize iSize = listView->gridSize();
1473 1474 1475
        return elidedText( fm, iSize.width(), Qt::ElideRight, text );
    }
    return text;
Anna Udovichenko's avatar
Anna Udovichenko committed
1476 1477
}

1478
UBFeaturesPathItemDelegate::UBFeaturesPathItemDelegate(QObject *parent) : QStyledItemDelegate(parent)
Anna Udovichenko's avatar
Anna Udovichenko committed
1479
{
1480
    arrowPixmap = new QPixmap(":images/navig_arrow.png");
Anna Udovichenko's avatar
Anna Udovichenko committed
1481 1482
}

Claudio Valerio's avatar
Claudio Valerio committed
1483
QString    UBFeaturesPathItemDelegate::displayText ( const QVariant & value, const QLocale & locale ) const
Anna Udovichenko's avatar
Anna Udovichenko committed
1484
{
Ivan Ilin's avatar
Ivan Ilin committed
1485 1486 1487 1488
    Q_UNUSED(value)
    Q_UNUSED(locale)

    return QString();
Anna Udovichenko's avatar
Anna Udovichenko committed
1489 1490 1491 1492
}

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

UBFeaturesPathItemDelegate::~UBFeaturesPathItemDelegate()
{
1504 1505 1506 1507 1508
    if ( arrowPixmap )
    {
        delete arrowPixmap;
        arrowPixmap = NULL;
    }
Ivan Ilin's avatar
Ivan Ilin committed
1509
}