/*

Base class for various kdm greeter dialogs

Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org>
Copyright (C) 2000-2004 Oswald Buddenhagen <ossi@kde.org>


This program 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; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

*/

#include "kgdialog.h"
#include "kgverify.h"
#include "kconsole.h"
#include "kdmshutdown.h"
#include "kdm_greet.h"
#include "utils.h"

//#include <klocale.h>

#include <QAction>
#include <QMenu>
#include <QApplication> //alex
#include <QFile> //alex
#include <QProcess> //alex

KGDialog::KGDialog(bool themed) : inherited(nullptr, !themed)
{
    needSep=false;
#ifdef HAVE_VTS
    dpyMenu=nullptr;
#endif
    switchCode=0;

#ifdef WITH_KDM_XCONSOLE
    consoleView = _showLog ? new KConsole(this) : 0;
#endif

    optMenu = nullptr;
    verify = nullptr;
}

void
#ifdef XDMCP
KGDialog::completeMenu(int _switchIf, int _switchCode, const QString &_switchMsg, int _switchAccel)
#else
KGDialog::completeMenu()
#endif
{
#ifdef HAVE_VTS
    if (_isLocal) {
        dpyMenu = new QMenu(this);
        inserten(tr("Sw&itch User"), Qt::ALT + Qt::Key_I, dpyMenu);
/*alex: with this action - crash when move mouse on tty submenu, can be reproduced by my test
        QAction *action = new QAction(this);
        action->setMenu(dpyMenu);
        action->setShortcut(Qt::ALT + Qt::CTRL + Qt::Key_Insert);
        connect(action, SIGNAL(triggered(bool)),
                SLOT(slotActivateMenu(bool)));
        addAction(action);
*/
        connect(dpyMenu, SIGNAL(triggered(QAction*)),
                SLOT(slotDisplaySelected(QAction*)));
        connect(dpyMenu, SIGNAL(aboutToShow()),
                SLOT(slotPopulateDisplays()));
	needSep=true; //alex
    }
#endif

    if (_allowClose || _isReserve)
        inserten(_isReserve ? tr("Abort S&ession") :
                 _isLocal ? tr("R&estart X Server") :
                            tr("Clos&e Connection"),
                 Qt::ALT + Qt::Key_E, SLOT(slotExit()));
    //alex
    if ( //(*_preloader && QString::fromLocal8Bit(_preloader).contains("fly-vkbd")) &&
	 QFile("/usr/bin/fly-vkbd").exists())
    {
      inserten(tr("&Virtual keyboard"),  Qt::ALT + Qt::Key_K, SLOT(slotVkbd()));
      needSep=true; //alex
    }


#ifdef XDMCP
    if (_isLocal && _loginMode != _switchIf) {
        switchCode = _switchCode;
        if (_switchMsg!=QString::null) /* alex: don't insert disabled item */
        inserten(_switchMsg, _switchAccel, SLOT(slotSwitch()));
    }
#endif

    if (_hasConsole)
        inserten(tr("Co&nsole Login"), Qt::ALT + Qt::Key_N, SLOT(slotConsole()));

    if (_allowShutdown != SHUT_NONE) {
        inserten(tr("&Shutdown..."),  Qt::ALT + Qt::Key_S, SLOT(slotShutdown()));
        inserten(Qt::ALT + Qt::CTRL + Qt::Key_Delete, SLOT(slotShutdown()));
        inserten(Qt::SHIFT + Qt::ALT + Qt::CTRL + Qt::Key_PageUp, SLOT(slotShutdown()), SHUT_REBOOT);
        inserten(Qt::SHIFT + Qt::ALT + Qt::CTRL + Qt::Key_PageDown, SLOT(slotShutdown()), SHUT_HALT);
    }
}

void
KGDialog::ensureMenu()
{
    if (!optMenu) {
        optMenu = new QMenu(this);
        connect(optMenu, SIGNAL(triggered(QAction*)), SLOT(slotActivateMenu(QAction*)));
        needSep = false;
    } else if (needSep) {
        optMenu->addSeparator();
        needSep = false;
    }
}

void
KGDialog::inserten(const QKeySequence &shortcut, const char *member, int data)
{
    QAction *action = new QAction(this);
    action->setShortcut(shortcut);
    if (data != -1)
        action->setData(data);
    connect(action, SIGNAL(triggered()), member);
    addAction(action);
}

void
KGDialog::inserten(const QString &txt, const QKeySequence &shortcut, const char *member)
{
    ensureMenu();
    optMenu->addAction(txt, this, member, shortcut);
}

void
KGDialog::inserten(const QString &txt, const QKeySequence &shortcut, QMenu *cmnu)
{
    ensureMenu();
    QAction *action = optMenu->addMenu(cmnu);
    action->setShortcut(shortcut);
    action->setText(txt);
}

void
KGDialog::slotActivateMenu(QAction *action)
{
    QMenu *cmnu = action->menu();
    if (cmnu) {
        QSize sh(cmnu->sizeHint() / 2);
        cmnu->exec(geometry().center() - QPoint(sh.width(), sh.height()));
    }
}

void
KGDialog::slotActivateMenu(bool)
{
    slotActivateMenu(static_cast<QAction *>(sender()));
}

void
KGDialog::slotExit()
{
    if (verify)
        verify->abort();
    //::exit(_isReserve ? EX_RESERVE : EX_RESERVER_DPY);
    //alex: try so
    done(_isReserve ? EX_RESERVE : EX_RESERVER_DPY);
}

void
KGDialog::slotSwitch()
{
#ifdef XDMCP
    done(switchCode);
#endif
}

void
KGDialog::slotConsole()
{
    QList<DpySpec> sess;
#ifdef HAVE_VTS
    sess = fetchSessions(0);
#endif
    if (verify)
        verify->suspend();
    int ret = KDMConfShutdown(-1, sess, SHUT_CONSOLE, QString()).exec();
    if (verify)
        verify->resume();
    if (!ret)
        return;
    if (verify)
        verify->abort();
    gSet(1);
    gSendInt(G_Console);
    gSet(0);
}

void
KGDialog::slotShutdown()
{
    if (verify)
        verify->suspend();
    QAction *action = (QAction *)sender();
    if (action->data().isNull()) {
        if (_scheduledSd == SHUT_ALWAYS)
            KDMShutdown::scheduleShutdown(this);
        else
            KDMSlimShutdown(this).exec(); //alex: qt 5.1 dialog positioning bug: if remove 'this' - OK, hopefuly will be fixed in 5.2
    } else
        KDMSlimShutdown::externShutdown(action->data().toInt(), QString(), -1, false);
    if (verify)
        verify->resume();
}

void
KGDialog::slotDisplaySelected(QAction *action)
{
#ifdef HAVE_VTS
    gSet(1);
    gSendInt(G_Activate);
    gSendInt(action->data().toInt());
    gSet(0);
#else
    (void)action;
#endif
}

void
KGDialog::slotPopulateDisplays()
{
#ifdef HAVE_VTS
    dpyMenu->clear();
    QList<DpySpec> sessions = fetchSessions(lstPassive | lstTTY);
    QString user, loc;
    foreach (const DpySpec &sess, sessions) {
        decodeSession(sess, user, loc);
        QAction *action = dpyMenu->addAction(
            /*i18nc( "session (location)",*/tr( "%1 (%2)" ).arg(user).arg(loc));
        action->setData(sess.vt ? sess.vt : -1);
        action->setCheckable(true);
        if (!sess.vt)
            action->setEnabled(false);
        if (sess.flags & isSelf)
            action->setChecked(true);
    }
#endif
}

//#include "kgdialog.moc"
