// Event filter, needed for FocusEvent detection, etc.
// avoids overwriting of classes
bool MainWindow::eventFilter(QObject* object, QEvent* event)
{
    if (event->type() == QEvent::FocusOut && object == ui_->textContent) {
        // So inform Presenter about changed content
        if (ui_->textContent->document()->isModified()) {
            NoteDto note = getSelectedNote();
            note.setContent(ui_->textContent->toPlainText().toStdString());

            presenter_.contentEditingFinished(note);

            ui_->textContent->document()->setModified(false);
        }
    } else if (event->type() == QEvent::KeyPress) {
        QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
        //qDebug("Key pressed: %d", keyEvent->key());
        if (object == ui_->listResult && keyEvent->key() == Qt::Key_Delete) {
            // Delete selected Note
            NoteDto note = getSelectedNote();
            presenter_.deleteNote(note);
        }
        if (object == ui_->lineSearch && keyEvent->key() == Qt::Key_Down) {
            qDebug() << "Go down in results";
            selectNextNote(true);
        }
        if (object == ui_->lineSearch && keyEvent->key() == Qt::Key_Up) {
            qDebug() << "Go up in results";
            selectNextNote(false);
        }
        if (object == ui_->lineSearch && keyEvent->key() == Qt::Key_Escape) {
            qDebug() << "Reset search to empty";
            setSearchFilter("");
        }
        if ((object == ui_->lineSearch || object == ui_->listResult)
            && (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter)) {
            qDebug() << "Enter note";
            focusNoteText();
        }
        if (keyEvent->key() == Qt::Key_N && keyEvent->modifiers() == Qt::ControlModifier) {
            // TODO: Handle case where user is creating many empty new notes (should be avoided)
            qDebug() << "Hotkey: New note";
            presenter_.newNoteClicked();
        }
    }
    // Standard event processing
    return QObject::eventFilter(object, event);
}
ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
    QFrame(parent),
    m_iconProvider(m_resIconSize),
    m_itemIconSize(24, 24),
    m_resIconSize(24, 24),
    m_itemsView(new QDeclarativeView(this)),
    m_resourcesView(new Internal::ItemLibraryTreeView(this)),
    m_filterFlag(QtBasic)
{
    setWindowTitle(tr("Library", "Title of library view"));

    /* create Items view and its model */
    m_itemsView->setAttribute(Qt::WA_OpaquePaintEvent);
    m_itemsView->setAttribute(Qt::WA_NoSystemBackground);
    m_itemsView->setAcceptDrops(false);
    m_itemsView->setFocusPolicy(Qt::ClickFocus);
    m_itemsView->setResizeMode(QDeclarativeView::SizeRootObjectToView);
    m_itemLibraryModel = new Internal::ItemLibraryModel(QDeclarativeEnginePrivate::getScriptEngine(m_itemsView->engine()), this);
    m_itemLibraryModel->setItemIconSize(m_itemIconSize);

    QDeclarativeContext *rootContext = m_itemsView->rootContext();
    rootContext->setContextProperty(QLatin1String("itemLibraryModel"), m_itemLibraryModel.data());
    rootContext->setContextProperty(QLatin1String("itemLibraryIconWidth"), m_itemIconSize.width());
    rootContext->setContextProperty(QLatin1String("itemLibraryIconHeight"), m_itemIconSize.height());

    QColor highlightColor = palette().highlight().color();
    if (0.5*highlightColor.saturationF()+0.75-highlightColor.valueF() < 0)
        highlightColor.setHsvF(highlightColor.hsvHueF(),0.1 + highlightColor.saturationF()*2.0, highlightColor.valueF());
    m_itemsView->rootContext()->setContextProperty(QLatin1String("highlightColor"), highlightColor);

    // loading the qml has to come after all needed context properties are set
    m_itemsView->setSource(QUrl("qrc:/ItemLibrary/qml/ItemsView.qml"));

    QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(m_itemsView->rootObject());
    connect(rootItem, SIGNAL(itemSelected(int)), this, SLOT(showItemInfo(int)));
    connect(rootItem, SIGNAL(itemDragged(int)), this, SLOT(startDragAndDrop(int)));
    connect(this, SIGNAL(scrollItemsView(QVariant)), rootItem, SLOT(scrollView(QVariant)));
    connect(this, SIGNAL(resetItemsView()), rootItem, SLOT(resetView()));

    /* create Resources view and its model */
    m_resourcesFileSystemModel = new QFileSystemModel(this);
    m_resourcesFileSystemModel->setIconProvider(&m_iconProvider);
    m_resourcesView->setModel(m_resourcesFileSystemModel.data());
    m_resourcesView->setIconSize(m_resIconSize);

    /* create image provider for loading item icons */
    m_itemsView->engine()->addImageProvider(QLatin1String("qmldesigner_itemlibrary"), new Internal::ItemLibraryImageProvider);

    /* other widgets */
    QTabBar *tabBar = new QTabBar(this);
    tabBar->addTab(tr("Items", "Title of library items view"));
    tabBar->addTab(tr("Resources", "Title of library resources view"));
    tabBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    m_lineEdit = new Utils::FilterLineEdit(this);
    m_lineEdit->setObjectName(QLatin1String("itemLibrarySearchInput"));
    m_lineEdit->setPlaceholderText(tr("<Filter>", "Library search input hint text"));
    m_lineEdit->setDragEnabled(false);
    m_lineEdit->setMinimumWidth(75);
    m_lineEdit->setTextMargins(0, 0, 20, 0);
    QWidget *lineEditFrame = new QWidget(this);
    lineEditFrame->setObjectName(QLatin1String("itemLibrarySearchInputFrame"));
    QGridLayout *lineEditLayout = new QGridLayout(lineEditFrame);
    lineEditLayout->setMargin(2);
    lineEditLayout->setSpacing(0);
    lineEditLayout->addItem(new QSpacerItem(5, 3, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, 0, 1, 3);
    lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 0);
    lineEditLayout->addWidget(m_lineEdit.data(), 1, 1, 1, 1);
    lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 2);
    connect(m_lineEdit.data(), SIGNAL(filterChanged(QString)), this, SLOT(setSearchFilter(QString)));

    m_stackedWidget = new QStackedWidget(this);
    m_stackedWidget->addWidget(m_itemsView.data());
    m_stackedWidget->addWidget(m_resourcesView.data());
    connect(tabBar, SIGNAL(currentChanged(int)),
            m_stackedWidget.data(), SLOT(setCurrentIndex(int)));
    connect(tabBar, SIGNAL(currentChanged(int)),
            this, SLOT(updateSearch()));

    QWidget *spacer = new QWidget(this);
    spacer->setObjectName(QLatin1String("itemLibrarySearchInputSpacer"));
    spacer->setFixedHeight(4);

    QGridLayout *layout = new QGridLayout(this);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    layout->addWidget(tabBar, 0, 0, 1, 1);
    layout->addWidget(spacer, 1, 0);
    layout->addWidget(lineEditFrame, 2, 0, 1, 1);
    layout->addWidget(m_stackedWidget.data(), 3, 0, 1, 1);

    setResourcePath(QDir::currentPath());
    setSearchFilter(QString());

    /* style sheets */
    setStyleSheet(QLatin1String(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css")));
    m_resourcesView->setStyleSheet(
            QLatin1String(Utils::FileReader::fetchQrc(":/qmldesigner/scrollbar.css")));
}
ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
    QFrame(parent),
    m_itemIconSize(24, 24),
    m_resIconSize(24, 24),
    m_iconProvider(m_resIconSize),
    m_itemsView(new QQuickView()),
    m_resourcesView(new ItemLibraryTreeView(this)),
    m_filterFlag(QtBasic)
{
    ItemLibraryModel::registerQmlTypes();

    setWindowTitle(tr("Library", "Title of library view"));

    /* create Items view and its model */
    m_itemsView->setResizeMode(QQuickView::SizeRootObjectToView);
    m_itemLibraryModel = new ItemLibraryModel(this);

    QQmlContext *rootContext = m_itemsView->rootContext();
    rootContext->setContextProperty(QStringLiteral("itemLibraryModel"), m_itemLibraryModel.data());
    rootContext->setContextProperty(QStringLiteral("itemLibraryIconWidth"), m_itemIconSize.width());
    rootContext->setContextProperty(QStringLiteral("itemLibraryIconHeight"), m_itemIconSize.height());
    rootContext->setContextProperty(QStringLiteral("rootView"), this);

    m_itemsView->rootContext()->setContextProperty(QStringLiteral("highlightColor"), Utils::StyleHelper::notTooBrightHighlightColor());

    /* create Resources view and its model */
    m_resourcesFileSystemModel = new QFileSystemModel(this);
    m_resourcesFileSystemModel->setIconProvider(&m_iconProvider);
    m_resourcesView->setModel(m_resourcesFileSystemModel.data());
    m_resourcesView->setIconSize(m_resIconSize);

    /* create image provider for loading item icons */
    m_itemsView->engine()->addImageProvider(QStringLiteral("qmldesigner_itemlibrary"), new Internal::ItemLibraryImageProvider);

    /* other widgets */
    QTabBar *tabBar = new QTabBar(this);
    tabBar->addTab(tr("QML Types", "Title of library QML types view"));
    tabBar->addTab(tr("Resources", "Title of library resources view"));
    tabBar->addTab(tr("Imports", "Title of library imports view"));
    tabBar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(setCurrentIndexOfStackedWidget(int)));
    connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(updateSearch()));

    m_filterLineEdit = new Utils::FancyLineEdit(this);
    m_filterLineEdit->setObjectName(QStringLiteral("itemLibrarySearchInput"));
    m_filterLineEdit->setPlaceholderText(tr("<Filter>", "Library search input hint text"));
    m_filterLineEdit->setDragEnabled(false);
    m_filterLineEdit->setMinimumWidth(75);
    m_filterLineEdit->setTextMargins(0, 0, 20, 0);
    m_filterLineEdit->setFiltering(true);
    QWidget *lineEditFrame = new QWidget(this);
    lineEditFrame->setObjectName(QStringLiteral("itemLibrarySearchInputFrame"));
    QGridLayout *lineEditLayout = new QGridLayout(lineEditFrame);
    lineEditLayout->setMargin(2);
    lineEditLayout->setSpacing(0);
    lineEditLayout->addItem(new QSpacerItem(5, 3, QSizePolicy::Fixed, QSizePolicy::Fixed), 0, 0, 1, 3);
    lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 0);
    lineEditLayout->addWidget(m_filterLineEdit.data(), 1, 1, 1, 1);
    lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 2);
    connect(m_filterLineEdit.data(), SIGNAL(filterChanged(QString)), this, SLOT(setSearchFilter(QString)));

    QWidget *container = createWindowContainer(m_itemsView.data());
    m_stackedWidget = new QStackedWidget(this);
    m_stackedWidget->addWidget(container);
    m_stackedWidget->addWidget(m_resourcesView.data());

    QWidget *spacer = new QWidget(this);
    spacer->setObjectName(QStringLiteral("itemLibrarySearchInputSpacer"));
    spacer->setFixedHeight(4);

    QGridLayout *layout = new QGridLayout(this);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->setSpacing(0);
    layout->addWidget(tabBar, 0, 0, 1, 1);
    layout->addWidget(spacer, 1, 0);
    layout->addWidget(lineEditFrame, 2, 0, 1, 1);
    layout->addWidget(m_stackedWidget.data(), 3, 0, 1, 1);

    setResourcePath(QDir::currentPath());
    setSearchFilter(QString());

    /* style sheets */
    setStyleSheet(QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/stylesheet.css")));
    m_resourcesView->setStyleSheet(QString::fromUtf8(Utils::FileReader::fetchQrc(":/qmldesigner/scrollbar.css")));

    m_qmlSourceUpdateShortcut = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_F5), this);
    connect(m_qmlSourceUpdateShortcut, SIGNAL(activated()), this, SLOT(reloadQmlSource()));

    // init the first load of the QML UI elements
    reloadQmlSource();
}