/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Labs Platform module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquickplatformmenuitem_p.h"
#include "qquickplatformmenu_p.h"
#include "qquickplatformmenuitemgroup_p.h"
#include "qquickplatformiconloader_p.h"

#include <QtGui/qicon.h>
#include <QtGui/qkeysequence.h>
#include <QtGui/qpa/qplatformtheme.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtQuickTemplates2/private/qquickshortcutcontext_p_p.h>

#include "widgets/qwidgetplatform_p.h"

QT_BEGIN_NAMESPACE

/*!
    \qmltype MenuItem
    \inherits QtObject
//!     \instantiates QQuickPlatformMenuItem
    \inqmlmodule Qt.labs.platform
    \since 5.8
    \brief A native menu item.

    The MenuItem type provides a QML API for native platform menu items.

    \image qtlabsplatform-menu.png

    A menu item consists of an \l {iconSource}{icon}, \l text, and \l shortcut.

    \code
    Menu {
        id: zoomMenu

        MenuItem {
            text: qsTr("Zoom In")
            shortcut: StandardKey.ZoomIn
            onTriggered: zoomIn()
        }

        MenuItem {
            text: qsTr("Zoom Out")
            shortcut: StandardKey.ZoomOut
            onTriggered: zoomOut()
        }
    }
    \endcode

    \labs

    \sa Menu, MenuItemGroup
*/

/*!
    \qmlsignal Qt.labs.platform::MenuItem::triggered()

    This signal is emitted when the menu item is triggered by the user.
*/

/*!
    \qmlsignal Qt.labs.platform::MenuItem::hovered()

    This signal is emitted when the menu item is hovered by the user.
*/

QQuickPlatformMenuItem::QQuickPlatformMenuItem(QObject *parent)
    : QObject(parent),
      m_complete(false),
      m_enabled(true),
      m_visible(true),
      m_separator(false),
      m_checkable(false),
      m_checked(false),
      m_role(QPlatformMenuItem::TextHeuristicRole),
      m_menu(nullptr),
      m_subMenu(nullptr),
      m_group(nullptr),
      m_iconLoader(nullptr),
      m_handle(nullptr)
{
}

QQuickPlatformMenuItem::~QQuickPlatformMenuItem()
{
    if (m_menu)
        m_menu->removeItem(this);
    if (m_group)
        m_group->removeItem(this);
#if QT_CONFIG(shortcut)
    if (m_shortcutId != -1) {
        QKeySequence sequence;
        if (m_shortcut.type() == QVariant::Int)
            sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
        else
            sequence = QKeySequence::fromString(m_shortcut.toString());
        QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_shortcutId, this, sequence);
    }
#endif
    delete m_iconLoader;
    m_iconLoader = nullptr;
    delete m_handle;
    m_handle = nullptr;
}

QPlatformMenuItem *QQuickPlatformMenuItem::handle() const
{
    return m_handle;
}

QPlatformMenuItem *QQuickPlatformMenuItem::create()
{
    if (!m_handle && m_menu && m_menu->handle()) {
        m_handle = m_menu->handle()->createMenuItem();

        // TODO: implement QCocoaMenu::createMenuItem()
        if (!m_handle)
            m_handle = QGuiApplicationPrivate::platformTheme()->createPlatformMenuItem();

        if (!m_handle)
            m_handle = QWidgetPlatform::createMenuItem();

        if (m_handle) {
            connect(m_handle, &QPlatformMenuItem::activated, this, &QQuickPlatformMenuItem::activate);
            connect(m_handle, &QPlatformMenuItem::hovered, this, &QQuickPlatformMenuItem::hovered);
        }
    }
    return m_handle;
}

void QQuickPlatformMenuItem::sync()
{
    if (!m_complete || !create())
        return;

    m_handle->setEnabled(isEnabled());
    m_handle->setVisible(isVisible());
    m_handle->setIsSeparator(m_separator);
    m_handle->setCheckable(m_checkable);
    m_handle->setChecked(m_checked);
    m_handle->setRole(m_role);
    m_handle->setText(m_text);
    m_handle->setFont(m_font);
    m_handle->setHasExclusiveGroup(m_group && m_group->isExclusive());
    if (m_subMenu) {
        // Sync first as dynamically created menus may need to get the
        // handle recreated
        m_subMenu->sync();
        if (m_subMenu->handle())
            m_handle->setMenu(m_subMenu->handle());
    }

#if QT_CONFIG(shortcut)
    QKeySequence sequence;
    if (m_shortcut.type() == QVariant::Int)
        sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
    else
        sequence = QKeySequence::fromString(m_shortcut.toString());
    m_handle->setShortcut(sequence.toString());
#endif

    if (m_menu && m_menu->handle())
        m_menu->handle()->syncMenuItem(m_handle);
}

/*!
    \readonly
    \qmlproperty Menu Qt.labs.platform::MenuItem::menu

    This property holds the menu that the item belongs to, or \c null if the
    item is not in a menu.
*/
QQuickPlatformMenu *QQuickPlatformMenuItem::menu() const
{
    return m_menu;
}

void QQuickPlatformMenuItem::setMenu(QQuickPlatformMenu *menu)
{
    if (m_menu == menu)
        return;

    m_menu = menu;
    emit menuChanged();
}

/*!
    \readonly
    \qmlproperty Menu Qt.labs.platform::MenuItem::subMenu

    This property holds the sub-menu that the item contains, or \c null if
    the item is not a sub-menu item.
*/
QQuickPlatformMenu *QQuickPlatformMenuItem::subMenu() const
{
    return m_subMenu;
}

void QQuickPlatformMenuItem::setSubMenu(QQuickPlatformMenu *menu)
{
    if (m_subMenu == menu)
        return;

    m_subMenu = menu;
    sync();
    emit subMenuChanged();
}

/*!
    \qmlproperty MenuItemGroup Qt.labs.platform::MenuItem::group

    This property holds the group that the item belongs to, or \c null if the
    item is not in a group.
*/
QQuickPlatformMenuItemGroup *QQuickPlatformMenuItem::group() const
{
    return m_group;
}

void QQuickPlatformMenuItem::setGroup(QQuickPlatformMenuItemGroup *group)
{
    if (m_group == group)
        return;

    bool wasEnabled = isEnabled();
    bool wasVisible = isVisible();

    if (group)
        group->addItem(this);

    m_group = group;
    sync();
    emit groupChanged();

    if (isEnabled() != wasEnabled)
        emit enabledChanged();
    if (isVisible() != wasVisible)
        emit visibleChanged();
}

/*!
    \qmlproperty bool Qt.labs.platform::MenuItem::enabled

    This property holds whether the item is enabled. The default value is \c true.

    Disabled items cannot be triggered by the user. They do not disappear from menus,
    but they are displayed in a way which indicates that they are unavailable. For
    example, they might be displayed using only shades of gray.

    When an item is disabled, it is not possible to trigger it through its \l shortcut.
*/
bool QQuickPlatformMenuItem::isEnabled() const
{
    return m_enabled && (!m_group || m_group->isEnabled());
}

void QQuickPlatformMenuItem::setEnabled(bool enabled)
{
    if (m_enabled == enabled)
        return;

    bool wasEnabled = isEnabled();
    m_enabled = enabled;
    sync();
    if (isEnabled() != wasEnabled)
        emit enabledChanged();
}

/*!
    \qmlproperty bool Qt.labs.platform::MenuItem::visible

    This property holds whether the item is visible. The default value is \c true.
*/
bool QQuickPlatformMenuItem::isVisible() const
{
    return m_visible && (!m_group || m_group->isVisible());
}

void QQuickPlatformMenuItem::setVisible(bool visible)
{
    if (m_visible == visible)
        return;

    bool wasVisible = isVisible();
    m_visible = visible;
    sync();
    if (isVisible() != wasVisible)
        emit visibleChanged();
}

/*!
    \qmlproperty bool Qt.labs.platform::MenuItem::separator

    This property holds whether the item is a separator line. The default value
    is \c false.

    \sa MenuSeparator
*/
bool QQuickPlatformMenuItem::isSeparator() const
{
    return m_separator;
}

void QQuickPlatformMenuItem::setSeparator(bool separator)
{
    if (m_separator == separator)
        return;

    m_separator = separator;
    sync();
    emit separatorChanged();
}

/*!
    \qmlproperty bool Qt.labs.platform::MenuItem::checkable

    This property holds whether the item is checkable.

    A checkable menu item has an on/off state. For example, in a word processor,
    a "Bold" menu item may be either on or off. A menu item that is not checkable
    is a command item that is simply executed, e.g. file save.

    The default value is \c false.

    \sa checked, MenuItemGroup
*/
bool QQuickPlatformMenuItem::isCheckable() const
{
    return m_checkable;
}

void QQuickPlatformMenuItem::setCheckable(bool checkable)
{
    if (m_checkable == checkable)
        return;

    m_checkable = checkable;
    sync();
    emit checkableChanged();
}

/*!
    \qmlproperty bool Qt.labs.platform::MenuItem::checked

    This property holds whether the item is checked (on) or unchecked (off).
    The default value is \c false.

    \sa checkable, MenuItemGroup
*/
bool QQuickPlatformMenuItem::isChecked() const
{
    return m_checked;
}

void QQuickPlatformMenuItem::setChecked(bool checked)
{
    if (m_checked == checked)
        return;

    if (checked && !m_checkable)
        setCheckable(true);

    m_checked = checked;
    sync();
    emit checkedChanged();
}

/*!
    \qmlproperty enumeration Qt.labs.platform::MenuItem::role

    This property holds the role of the item. The role determines whether
    the item should be placed into the application menu on macOS.

    Available values:
    \value MenuItem.NoRole The item should not be put into the application menu
    \value MenuItem.TextHeuristicRole The item should be put in the application menu based on the action's text (default)
    \value MenuItem.ApplicationSpecificRole The item should be put in the application menu with an application-specific role
    \value MenuItem.AboutQtRole The item handles the "About Qt" menu item.
    \value MenuItem.AboutRole The item should be placed where the "About" menu item is in the application menu. The text of
           the menu item will be set to "About <application name>". The application name is fetched from the
           \c{Info.plist} file in the application's bundle (See \l{Qt for macOS - Deployment}).
    \value MenuItem.PreferencesRole The item should be placed where the "Preferences..." menu item is in the application menu.
    \value MenuItem.QuitRole The item should be placed where the Quit menu item is in the application menu.

    Specifying the role only has effect on items that are in the immediate
    menus of a menubar, not in the submenus of those menus. For example, if
    you have a "File" menu in your menubar and the "File" menu has a submenu,
    specifying a role for the items in that submenu has no effect. They will
    never be moved to the application menu.
*/
QPlatformMenuItem::MenuRole QQuickPlatformMenuItem::role() const
{
    return m_role;
}

void QQuickPlatformMenuItem::setRole(QPlatformMenuItem::MenuRole role)
{
    if (m_role == role)
        return;

    m_role = role;
    sync();
    emit roleChanged();
}

/*!
    \qmlproperty string Qt.labs.platform::MenuItem::text

    This property holds the menu item's text.
*/
QString QQuickPlatformMenuItem::text() const
{
    return m_text;
}

void QQuickPlatformMenuItem::setText(const QString &text)
{
    if (m_text == text)
        return;

    m_text = text;
    sync();
    emit textChanged();
}

/*!
    \qmlproperty url Qt.labs.platform::MenuItem::iconSource
    \deprecated Use icon.source instead
*/
QUrl QQuickPlatformMenuItem::iconSource() const
{
    return icon().source();
}

void QQuickPlatformMenuItem::setIconSource(const QUrl& source)
{
    QQuickPlatformIcon newIcon = icon();
    if (source == newIcon.source())
        return;

    newIcon.setSource(source);
    iconLoader()->setIcon(newIcon);
    emit iconSourceChanged();
}

/*!
    \qmlproperty string Qt.labs.platform::MenuItem::iconName
    \deprecated Use icon.name instead
*/
QString QQuickPlatformMenuItem::iconName() const
{
    return icon().name();
}

void QQuickPlatformMenuItem::setIconName(const QString& name)
{
    QQuickPlatformIcon newIcon = icon();
    if (name == newIcon.name())
        return;

    newIcon.setName(name);
    iconLoader()->setIcon(newIcon);
    emit iconNameChanged();
}

/*!
    \qmlproperty keysequence Qt.labs.platform::MenuItem::shortcut

    This property holds the menu item's shortcut.

    The shortcut key sequence can be set to one of the
    \l{QKeySequence::StandardKey}{standard keyboard shortcuts}, or it can be
    specified by a string containing a sequence of up to four key presses
    that are needed to \l{triggered}{trigger} the shortcut.

    The default value is an empty key sequence.

    \code
    MenuItem {
        shortcut: "Ctrl+E,Ctrl+W"
        onTriggered: edit.wrapMode = TextEdit.Wrap
    }
    \endcode
*/
QVariant QQuickPlatformMenuItem::shortcut() const
{
    return m_shortcut;
}

bool QQuickPlatformMenuItem::event(QEvent *e)
{
#if QT_CONFIG(shortcut)
    if (e->type() == QEvent::Shortcut) {
        QShortcutEvent *se = static_cast<QShortcutEvent *>(e);
        if (se->shortcutId() == m_shortcutId) {
            activate();
            return true;
        }
    }
#endif
    return QObject::event(e);
}

void QQuickPlatformMenuItem::setShortcut(const QVariant& shortcut)
{
    if (m_shortcut == shortcut)
        return;

#if QT_CONFIG(shortcut)
    if (m_shortcutId != -1) {
        QKeySequence sequence;
        if (m_shortcut.type() == QVariant::Int)
            sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
        else
            sequence = QKeySequence::fromString(m_shortcut.toString());
        QGuiApplicationPrivate::instance()->shortcutMap.removeShortcut(m_shortcutId, this, sequence);
    }
#endif
    m_shortcut = shortcut;
    sync();
#if QT_CONFIG(shortcut)
    QKeySequence sequence;
    if (m_shortcut.type() == QVariant::Int)
        sequence = QKeySequence(static_cast<QKeySequence::StandardKey>(m_shortcut.toInt()));
    else
        sequence = QKeySequence::fromString(m_shortcut.toString());
    m_shortcutId = QGuiApplicationPrivate::instance()->shortcutMap.addShortcut(this, sequence,
        Qt::WindowShortcut, QQuickShortcutContext::matcher);
#endif
    emit shortcutChanged();
}

/*!
    \qmlproperty font Qt.labs.platform::MenuItem::font

    This property holds the menu item's font.

    \sa text
*/
QFont QQuickPlatformMenuItem::font() const
{
    return m_font;
}

void QQuickPlatformMenuItem::setFont(const QFont& font)
{
    if (m_font == font)
        return;

    m_font = font;
    sync();
    emit fontChanged();
}

/*!
    \since Qt.labs.platform 1.1 (Qt 5.12)
    \qmlpropertygroup Qt.labs.platform::MenuItem::icon
    \qmlproperty url Qt.labs.platform::MenuItem::icon.source
    \qmlproperty string Qt.labs.platform::MenuItem::icon.name
    \qmlproperty bool Qt.labs.platform::MenuItem::icon.mask

    This property holds the menu item's icon.

    \code
    MenuItem {
        icon.mask: true
        icon.name: "edit-undo"
        icon.source: "qrc:/images/undo.png"
    }
    \endcode

    \sa QIcon::fromTheme()
*/
QQuickPlatformIcon QQuickPlatformMenuItem::icon() const
{
    if (!m_iconLoader)
        return QQuickPlatformIcon();

    return m_iconLoader->icon();
}

void QQuickPlatformMenuItem::setIcon(const QQuickPlatformIcon &icon)
{
    if (iconLoader()->icon() == icon)
        return;

    iconLoader()->setIcon(icon);
    emit iconChanged();
}

/*!
    \qmlmethod void Qt.labs.platform::MenuItem::toggle()

    Toggles the \l checked state to its opposite state.
*/
void QQuickPlatformMenuItem::toggle()
{
    if (m_checkable)
        setChecked(!m_checked);
}

void QQuickPlatformMenuItem::classBegin()
{
}

void QQuickPlatformMenuItem::componentComplete()
{
    if (m_handle && m_iconLoader)
        m_iconLoader->setEnabled(true);
    m_complete = true;
    sync();
}

QQuickPlatformIconLoader *QQuickPlatformMenuItem::iconLoader() const
{
    if (!m_iconLoader) {
        QQuickPlatformMenuItem *that = const_cast<QQuickPlatformMenuItem *>(this);
        static int slot = staticMetaObject.indexOfSlot("updateIcon()");
        m_iconLoader = new QQuickPlatformIconLoader(slot, that);
        m_iconLoader->setEnabled(m_complete);
    }
    return m_iconLoader;
}

void QQuickPlatformMenuItem::activate()
{
    toggle();
    emit triggered();
}

void QQuickPlatformMenuItem::updateIcon()
{
    if (!m_handle || !m_iconLoader)
        return;

    m_handle->setIcon(m_iconLoader->toQIcon());
    sync();
}

QT_END_NAMESPACE
