<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "stackhandler.h"

#include "debuggeractions.h"
#include "debuggercore.h"
#include "debuggerengine.h"

#include <utils/qtcassert.h>
#include <utils/savedaction.h>

#include <QDebug>
#include <QFileInfo>

namespace Debugger {
namespace Internal {

////////////////////////////////////////////////////////////////////////
//
// StackHandler
//
////////////////////////////////////////////////////////////////////////

/*!
    \class Debugger::Internal::StackHandler
    \brief A model to represent the stack in a QTreeView.
 */

StackHandler::StackHandler()
  : m_positionIcon(QIcon(QLatin1String(":/debugger/images/location_16.png"))),
    m_emptyIcon(QIcon(QLatin1String(":/debugger/images/debugger_empty_14.png")))
{
    m_resetLocationScheduled = false;
    m_contentsValid = false;
    m_currentIndex = -1;
    m_canExpand = false;
    connect(debuggerCore()->action(OperateByInstruction), SIGNAL(triggered()),
        this, SLOT(resetModel()));
}

StackHandler::~StackHandler()
{
}

int StackHandler::rowCount(const QModelIndex &parent) const
{
    // Since the stack is not a tree, row count is 0 for any valid parent
    return parent.isValid() ? 0 : (m_stackFrames.size() + m_canExpand);
}

int StackHandler::columnCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : 5;
}

QVariant StackHandler::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= m_stackFrames.size() + m_canExpand)
        return QVariant();

    if (index.row() == m_stackFrames.size()) {
        if (role == Qt::DisplayRole && index.column() == 0)
            return tr("...");
        if (role == Qt::DisplayRole && index.column() == 1)
            return tr("<More>");
        if (role == Qt::DecorationRole && index.column() == 0)
            return m_emptyIcon;
        return QVariant();
    }

    const StackFrame &frame = m_stackFrames.at(index.row());

    if (role == Qt::DisplayRole) {
        switch (index.column()) {
        case 0: // Stack frame level
            return QString::number(frame.level);
        case 1: // Function name
            return frame.function;
        case 2: // File name
            return frame.file.isEmpty() ? frame.from : QFileInfo(frame.file).fileName();
        case 3: // Line number
            return frame.line >= 0 ? QVariant(frame.line) : QVariant();
        case 4: // Address
            if (frame.address)
                return QString::fromLatin1("0x%1").arg(frame.address, 0, 16);
            return QString();
        }
        return QVariant();
    }

    if (role == Qt::DecorationRole && index.column() == 0) {
        // Return icon that indicates whether this is the active stack frame
        return (m_contentsValid && index.row() == m_currentIndex)
            ? m_positionIcon : m_emptyIcon;
    }

    if (role == Qt::ToolTipRole)
        return frame.toToolTip();

    return QVariant();
}

QVariant StackHandler::headerData(int section, Qt::Orientation orient, int role) const
{
    if (orient == Qt::Horizontal && role == Qt::DisplayRole) {
        switch (section) {
            case 0: return tr("Level");
            case 1: return tr("Function");
            case 2: return tr("File");
            case 3: return tr("Line");
            case 4: return tr("Address");
        };
    }
    return QVariant();
}

Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const
{
    if (index.row() >= m_stackFrames.size() + m_canExpand)
        return 0;
    if (index.row() == m_stackFrames.size())
        return QAbstractTableModel::flags(index);
    const StackFrame &frame = m_stackFrames.at(index.row());
    const bool isValid = frame.isUsable()
        || debuggerCore()->boolSetting(OperateByInstruction);
    return isValid && m_contentsValid
        ? QAbstractTableModel::flags(index) : Qt::ItemFlags();
}

StackFrame StackHandler::currentFrame() const
{
    if (m_currentIndex == -1)
        return StackFrame();
    QTC_ASSERT(m_currentIndex >= 0, return StackFrame());
    QTC_ASSERT(m_currentIndex < m_stackFrames.size(), return StackFrame());
    return m_stackFrames.at(m_currentIndex);
}

void StackHandler::setCurrentIndex(int level)
{
    if (level == -1 || level == m_currentIndex)
        return;

    // Emit changed for previous frame
    QModelIndex i = index(m_currentIndex, 0);
    emit dataChanged(i, i);

    m_currentIndex = level;
    emit currentIndexChanged();

    // Emit changed for new frame
    i = index(m_currentIndex, 0);
    emit dataChanged(i, i);
}

void StackHandler::removeAll()
{
    m_stackFrames.clear();
    setCurrentIndex(-1);
    reset();
}

void StackHandler::setFrames(const StackFrames &frames, bool canExpand)
{
    m_resetLocationScheduled = false;
    m_contentsValid = true;
    m_canExpand = canExpand;
    m_stackFrames = frames;
    if (m_currentIndex >= m_stackFrames.size())
        setCurrentIndex(m_stackFrames.size() - 1);
    reset();
    emit stackChanged();
}

const StackFrames &StackHandler::frames() const
{
    return m_stackFrames;
}

void StackHandler::scheduleResetLocation()
{
    m_resetLocationScheduled = true;
    m_contentsValid = false;
}

void StackHandler::resetLocation()
{
    if (m_resetLocationScheduled) {
        m_resetLocationScheduled = false;
        reset();
    }
}

} // namespace Internal
} // namespace Debugger
<commit_msg>StackHandler: Set Current Index<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "stackhandler.h"

#include "debuggeractions.h"
#include "debuggercore.h"
#include "debuggerengine.h"

#include <utils/qtcassert.h>
#include <utils/savedaction.h>

#include <QDebug>
#include <QFileInfo>

namespace Debugger {
namespace Internal {

////////////////////////////////////////////////////////////////////////
//
// StackHandler
//
////////////////////////////////////////////////////////////////////////

/*!
    \class Debugger::Internal::StackHandler
    \brief A model to represent the stack in a QTreeView.
 */

StackHandler::StackHandler()
  : m_positionIcon(QIcon(QLatin1String(":/debugger/images/location_16.png"))),
    m_emptyIcon(QIcon(QLatin1String(":/debugger/images/debugger_empty_14.png")))
{
    m_resetLocationScheduled = false;
    m_contentsValid = false;
    m_currentIndex = -1;
    m_canExpand = false;
    connect(debuggerCore()->action(OperateByInstruction), SIGNAL(triggered()),
        this, SLOT(resetModel()));
}

StackHandler::~StackHandler()
{
}

int StackHandler::rowCount(const QModelIndex &parent) const
{
    // Since the stack is not a tree, row count is 0 for any valid parent
    return parent.isValid() ? 0 : (m_stackFrames.size() + m_canExpand);
}

int StackHandler::columnCount(const QModelIndex &parent) const
{
    return parent.isValid() ? 0 : 5;
}

QVariant StackHandler::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || index.row() >= m_stackFrames.size() + m_canExpand)
        return QVariant();

    if (index.row() == m_stackFrames.size()) {
        if (role == Qt::DisplayRole && index.column() == 0)
            return tr("...");
        if (role == Qt::DisplayRole && index.column() == 1)
            return tr("<More>");
        if (role == Qt::DecorationRole && index.column() == 0)
            return m_emptyIcon;
        return QVariant();
    }

    const StackFrame &frame = m_stackFrames.at(index.row());

    if (role == Qt::DisplayRole) {
        switch (index.column()) {
        case 0: // Stack frame level
            return QString::number(frame.level);
        case 1: // Function name
            return frame.function;
        case 2: // File name
            return frame.file.isEmpty() ? frame.from : QFileInfo(frame.file).fileName();
        case 3: // Line number
            return frame.line >= 0 ? QVariant(frame.line) : QVariant();
        case 4: // Address
            if (frame.address)
                return QString::fromLatin1("0x%1").arg(frame.address, 0, 16);
            return QString();
        }
        return QVariant();
    }

    if (role == Qt::DecorationRole && index.column() == 0) {
        // Return icon that indicates whether this is the active stack frame
        return (m_contentsValid && index.row() == m_currentIndex)
            ? m_positionIcon : m_emptyIcon;
    }

    if (role == Qt::ToolTipRole)
        return frame.toToolTip();

    return QVariant();
}

QVariant StackHandler::headerData(int section, Qt::Orientation orient, int role) const
{
    if (orient == Qt::Horizontal && role == Qt::DisplayRole) {
        switch (section) {
            case 0: return tr("Level");
            case 1: return tr("Function");
            case 2: return tr("File");
            case 3: return tr("Line");
            case 4: return tr("Address");
        };
    }
    return QVariant();
}

Qt::ItemFlags StackHandler::flags(const QModelIndex &index) const
{
    if (index.row() >= m_stackFrames.size() + m_canExpand)
        return 0;
    if (index.row() == m_stackFrames.size())
        return QAbstractTableModel::flags(index);
    const StackFrame &frame = m_stackFrames.at(index.row());
    const bool isValid = frame.isUsable()
        || debuggerCore()->boolSetting(OperateByInstruction);
    return isValid && m_contentsValid
        ? QAbstractTableModel::flags(index) : Qt::ItemFlags();
}

StackFrame StackHandler::currentFrame() const
{
    if (m_currentIndex == -1)
        return StackFrame();
    QTC_ASSERT(m_currentIndex >= 0, return StackFrame());
    QTC_ASSERT(m_currentIndex < m_stackFrames.size(), return StackFrame());
    return m_stackFrames.at(m_currentIndex);
}

void StackHandler::setCurrentIndex(int level)
{
    if (level == -1 || level == m_currentIndex)
        return;

    // Emit changed for previous frame
    QModelIndex i = index(m_currentIndex, 0);
    emit dataChanged(i, i);

    m_currentIndex = level;
    emit currentIndexChanged();

    // Emit changed for new frame
    i = index(m_currentIndex, 0);
    emit dataChanged(i, i);
}

void StackHandler::removeAll()
{
    m_stackFrames.clear();
    setCurrentIndex(-1);
    reset();
}

void StackHandler::setFrames(const StackFrames &frames, bool canExpand)
{
    m_resetLocationScheduled = false;
    m_contentsValid = true;
    m_canExpand = canExpand;
    m_stackFrames = frames;
    if (m_stackFrames.size() >= 0)
        setCurrentIndex(0);
    else
        m_currentIndex = -1;
    reset();
    emit stackChanged();
}

const StackFrames &StackHandler::frames() const
{
    return m_stackFrames;
}

void StackHandler::scheduleResetLocation()
{
    m_resetLocationScheduled = true;
    m_contentsValid = false;
}

void StackHandler::resetLocation()
{
    if (m_resetLocationScheduled) {
        m_resetLocationScheduled = false;
        reset();
    }
}

} // namespace Internal
} // namespace Debugger
<|endoftext|>


<commit_before>/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/

#include "fakevimplugin.h"

#include "fakevimconstants.h"
#include "fakevimhandler.h"

#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/filemanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/ifile.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>

#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/session.h>

#include <texteditor/basetexteditor.h>
#include <texteditor/basetextmark.h>
#include <texteditor/itexteditor.h>
#include <texteditor/texteditorconstants.h>
#include <texteditor/interactionsettings.h>
#include <texteditor/tabsettings.h>
#include <texteditor/texteditorsettings.h>

#include <utils/qtcassert.h>

#include <QtCore/QDebug>
#include <QtCore/QtPlugin>
#include <QtCore/QObject>
#include <QtCore/QPoint>
#include <QtCore/QSettings>

#include <QtGui/QMessageBox>
#include <QtGui/QPlainTextEdit>
#include <QtGui/QTextBlock>
#include <QtGui/QTextCursor>
#include <QtGui/QTextEdit>

using namespace FakeVim::Internal;
using namespace TextEditor;
using namespace Core;
using namespace ProjectExplorer;

namespace FakeVim {
namespace Constants {

const char * const INSTALL_HANDLER        = "FakeVim.InstallHandler";
const char * const MINI_BUFFER            = "FakeVim.MiniBuffer";
const char * const INSTALL_KEY            = "Alt+V,Alt+V";

} // namespace Constants
} // namespace FakeVim

///////////////////////////////////////////////////////////////////////
//
// FakeVimPluginPrivate
//
///////////////////////////////////////////////////////////////////////

namespace FakeVim {
namespace Internal {

class FakeVimPluginPrivate : public QObject
{
    Q_OBJECT

public:
    FakeVimPluginPrivate(FakeVimPlugin *);
    ~FakeVimPluginPrivate();
    friend class FakeVimPlugin;

    bool initialize();
    void shutdown();

private slots:
    void editorOpened(Core::IEditor *);
    void editorAboutToClose(Core::IEditor *);

    void installHandlerOnCurrentEditor();
    void installHandler(Core::IEditor *editor);
    void removeHandler();

    void showCommandBuffer(const QString &contents);
    void showExtraInformation(const QString &msg);
    void changeSelection(const QList<QTextEdit::ExtraSelection> &selections);
    void writeFile(bool *handled, const QString &fileName, const QString &contents);

private:
    FakeVimPlugin *q;
    QAction *m_installHandlerAction;
};

} // namespace Internal
} // namespace FakeVim

FakeVimPluginPrivate::FakeVimPluginPrivate(FakeVimPlugin *plugin)
{
    q = plugin;
    m_installHandlerAction = 0;
}

FakeVimPluginPrivate::~FakeVimPluginPrivate()
{
}

void FakeVimPluginPrivate::shutdown()
{
}

bool FakeVimPluginPrivate::initialize()
{
    Core::ActionManager *actionManager = Core::ICore::instance()->actionManager();
    QTC_ASSERT(actionManager, return false);

    QList<int> globalcontext;
    globalcontext << Core::Constants::C_GLOBAL_ID;

    m_installHandlerAction = new QAction(this);
    m_installHandlerAction->setText(tr("Set vi-Style Keyboard Action Handler"));

    Core::Command *cmd = 0;
    cmd = actionManager->registerAction(m_installHandlerAction,
        Constants::INSTALL_HANDLER, globalcontext);
    cmd->setDefaultKeySequence(QKeySequence(Constants::INSTALL_KEY));

    ActionContainer *advancedMenu =
        actionManager->actionContainer(Core::Constants::M_EDIT_ADVANCED);
    advancedMenu->addAction(cmd, Core::Constants::G_EDIT_EDITOR);

    connect(m_installHandlerAction, SIGNAL(triggered()),
        this, SLOT(installHandlerOnCurrentEditor()));

    // EditorManager
    QObject *editorManager = Core::ICore::instance()->editorManager();
    connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
        this, SLOT(editorAboutToClose(Core::IEditor*)));
    connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
        this, SLOT(editorOpened(Core::IEditor*)));

    return true;
}

void FakeVimPluginPrivate::installHandler(Core::IEditor *editor)
{
    if (!editor)
        return;

    QWidget *widget = editor->widget();
    if (!widget)
        return;

    // we can only handle QTextEdit and QPlainTextEdit
    if (!qobject_cast<QTextEdit *>(widget) && !qobject_cast<QPlainTextEdit *>(widget))
        return;

    FakeVimHandler *handler = new FakeVimHandler(widget, widget);

    connect(handler, SIGNAL(extraInformationChanged(QString)),
        this, SLOT(showExtraInformation(QString)));
    connect(handler, SIGNAL(commandBufferChanged(QString)),
        this, SLOT(showCommandBuffer(QString)));
    connect(handler, SIGNAL(quitRequested()),
        this, SLOT(removeHandler()), Qt::QueuedConnection);
    connect(handler, SIGNAL(writeFileRequested(bool*,QString,QString)),
        this, SLOT(writeFile(bool*,QString,QString)));
    connect(handler, SIGNAL(selectionChanged(QList<QTextEdit::ExtraSelection>)),
        this, SLOT(changeSelection(QList<QTextEdit::ExtraSelection>)));

    handler->setupWidget();
    handler->setExtraData(editor);

    if (BaseTextEditor *bt = qobject_cast<BaseTextEditor *>(widget)) {
        using namespace TextEditor;
        using namespace FakeVim::Constants;
        handler->setCurrentFileName(editor->file()->fileName());
        TabSettings settings = bt->tabSettings();
        handler->setConfigValue(ConfigTabStop,
            QString::number(settings.m_tabSize));
        handler->setConfigValue(ConfigShiftWidth,
            QString::number(settings.m_indentSize));
        handler->setConfigValue(ConfigExpandTab,
            settings.m_spacesForTabs ? ConfigOn : ConfigOff);
        handler->setConfigValue(ConfigSmartTab,
            settings.m_smartBackspace ? ConfigOn : ConfigOff);
        handler->setConfigValue(ConfigAutoIndent,
            settings.m_autoIndent ? ConfigOn : ConfigOff);
    }
}

void FakeVimPluginPrivate::installHandlerOnCurrentEditor()
{
    installHandler(EditorManager::instance()->currentEditor());
}

void FakeVimPluginPrivate::writeFile(bool *handled,
    const QString &fileName, const QString &contents)
{
    Q_UNUSED(contents);

    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (!handler)
        return;

    Core::IEditor *editor = qobject_cast<Core::IEditor *>(handler->extraData());
    if (editor && editor->file()->fileName() == fileName) {
        // Handle that as a special case for nicer interaction with core
        Core::IFile *file = editor->file();
        Core::ICore::instance()->fileManager()->blockFileChange(file);
        file->save(fileName);
        Core::ICore::instance()->fileManager()->unblockFileChange(file);
        *handled = true;
    }
}

void FakeVimPluginPrivate::removeHandler()
{
    if (FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender())) {
        handler->restoreWidget();
        handler->deleteLater();
    }
    Core::EditorManager::instance()->hideEditorInfoBar(
        QLatin1String(Constants::MINI_BUFFER));
}

void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor)
{
    //qDebug() << "OPENING: " << editor << editor->widget();
    QSettings *s = ICore::instance()->settings();
    bool automatic = s->value("textInteractionSettings/UseVim").toBool();
    if (automatic)
       installHandler(editor);
}

void FakeVimPluginPrivate::editorAboutToClose(Core::IEditor *editor)
{
    //qDebug() << "CLOSING: " << editor << editor->widget();
    Q_UNUSED(editor);
}

void FakeVimPluginPrivate::showCommandBuffer(const QString &contents)
{
    //qDebug() << "SHOW COMMAND BUFFER" << contents;
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (handler) {
        Core::EditorManager::instance()->showEditorInfoBar(
            QLatin1String(Constants::MINI_BUFFER), contents,
            tr("Quit FakeVim"), handler, SLOT(quit()));
    }
}

void FakeVimPluginPrivate::showExtraInformation(const QString &text)
{
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (handler)
        QMessageBox::information(handler->widget(), tr("FakeVim Information"), text);
}

void FakeVimPluginPrivate::changeSelection
    (const QList<QTextEdit::ExtraSelection> &selection)
{
    if (FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender()))
        if (BaseTextEditor *bt = qobject_cast<BaseTextEditor *>(handler->widget()))
            bt->setExtraSelections(BaseTextEditor::FakeVimSelection, selection);
}

///////////////////////////////////////////////////////////////////////
//
// FakeVimPlugin
//
///////////////////////////////////////////////////////////////////////

FakeVimPlugin::FakeVimPlugin()
    : d(new FakeVimPluginPrivate(this))
{}

FakeVimPlugin::~FakeVimPlugin()
{
    delete d;
}

bool FakeVimPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
    Q_UNUSED(arguments);
    Q_UNUSED(errorMessage);
    return d->initialize();
}

void FakeVimPlugin::shutdown()
{
    d->shutdown();
}

void FakeVimPlugin::extensionsInitialized()
{
}

#include "fakevimplugin.moc"

Q_EXPORT_PLUGIN(FakeVimPlugin)
<commit_msg>Fixes:    commands: rename FakeVim.InstallHandler -> TextEditor.FakeVimHandler<commit_after>/***************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact:  Qt Software Information (qt-info@nokia.com)
**
**
** Non-Open Source Usage
**
** Licensees may use this file in accordance with the Qt Beta Version
** License Agreement, Agreement version 2.2 provided with the Software or,
** alternatively, in accordance with the terms contained in a written
** agreement between you and Nokia.
**
** GNU General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 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 GNU
** General Public Licensing requirements will be met:
**
** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
** http://www.gnu.org/copyleft/gpl.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt GPL Exception
** version 1.3, included in the file GPL_EXCEPTION.txt in this package.
**
***************************************************************************/

#include "fakevimplugin.h"

#include "fakevimconstants.h"
#include "fakevimhandler.h"

#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/filemanager.h>
#include <coreplugin/icore.h>
#include <coreplugin/ifile.h>
#include <coreplugin/messagemanager.h>
#include <coreplugin/modemanager.h>
#include <coreplugin/uniqueidmanager.h>

#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/session.h>

#include <texteditor/basetexteditor.h>
#include <texteditor/basetextmark.h>
#include <texteditor/itexteditor.h>
#include <texteditor/texteditorconstants.h>
#include <texteditor/interactionsettings.h>
#include <texteditor/tabsettings.h>
#include <texteditor/texteditorsettings.h>

#include <utils/qtcassert.h>

#include <QtCore/QDebug>
#include <QtCore/QtPlugin>
#include <QtCore/QObject>
#include <QtCore/QPoint>
#include <QtCore/QSettings>

#include <QtGui/QMessageBox>
#include <QtGui/QPlainTextEdit>
#include <QtGui/QTextBlock>
#include <QtGui/QTextCursor>
#include <QtGui/QTextEdit>

using namespace FakeVim::Internal;
using namespace TextEditor;
using namespace Core;
using namespace ProjectExplorer;

namespace FakeVim {
namespace Constants {

const char * const INSTALL_HANDLER        = "TextEditor.FakeVimHandler";
const char * const MINI_BUFFER            = "TextEditor.FakeVimMiniBuffer";
const char * const INSTALL_KEY            = "Alt+V,Alt+V";

} // namespace Constants
} // namespace FakeVim

///////////////////////////////////////////////////////////////////////
//
// FakeVimPluginPrivate
//
///////////////////////////////////////////////////////////////////////

namespace FakeVim {
namespace Internal {

class FakeVimPluginPrivate : public QObject
{
    Q_OBJECT

public:
    FakeVimPluginPrivate(FakeVimPlugin *);
    ~FakeVimPluginPrivate();
    friend class FakeVimPlugin;

    bool initialize();
    void shutdown();

private slots:
    void editorOpened(Core::IEditor *);
    void editorAboutToClose(Core::IEditor *);

    void installHandlerOnCurrentEditor();
    void installHandler(Core::IEditor *editor);
    void removeHandler();

    void showCommandBuffer(const QString &contents);
    void showExtraInformation(const QString &msg);
    void changeSelection(const QList<QTextEdit::ExtraSelection> &selections);
    void writeFile(bool *handled, const QString &fileName, const QString &contents);

private:
    FakeVimPlugin *q;
    QAction *m_installHandlerAction;
};

} // namespace Internal
} // namespace FakeVim

FakeVimPluginPrivate::FakeVimPluginPrivate(FakeVimPlugin *plugin)
{
    q = plugin;
    m_installHandlerAction = 0;
}

FakeVimPluginPrivate::~FakeVimPluginPrivate()
{
}

void FakeVimPluginPrivate::shutdown()
{
}

bool FakeVimPluginPrivate::initialize()
{
    Core::ActionManager *actionManager = Core::ICore::instance()->actionManager();
    QTC_ASSERT(actionManager, return false);

    QList<int> globalcontext;
    globalcontext << Core::Constants::C_GLOBAL_ID;

    m_installHandlerAction = new QAction(this);
    m_installHandlerAction->setText(tr("Set vi-Style Keyboard Action Handler"));

    Core::Command *cmd = 0;
    cmd = actionManager->registerAction(m_installHandlerAction,
        Constants::INSTALL_HANDLER, globalcontext);
    cmd->setDefaultKeySequence(QKeySequence(Constants::INSTALL_KEY));

    ActionContainer *advancedMenu =
        actionManager->actionContainer(Core::Constants::M_EDIT_ADVANCED);
    advancedMenu->addAction(cmd, Core::Constants::G_EDIT_EDITOR);

    connect(m_installHandlerAction, SIGNAL(triggered()),
        this, SLOT(installHandlerOnCurrentEditor()));

    // EditorManager
    QObject *editorManager = Core::ICore::instance()->editorManager();
    connect(editorManager, SIGNAL(editorAboutToClose(Core::IEditor*)),
        this, SLOT(editorAboutToClose(Core::IEditor*)));
    connect(editorManager, SIGNAL(editorOpened(Core::IEditor*)),
        this, SLOT(editorOpened(Core::IEditor*)));

    return true;
}

void FakeVimPluginPrivate::installHandler(Core::IEditor *editor)
{
    if (!editor)
        return;

    QWidget *widget = editor->widget();
    if (!widget)
        return;

    // we can only handle QTextEdit and QPlainTextEdit
    if (!qobject_cast<QTextEdit *>(widget) && !qobject_cast<QPlainTextEdit *>(widget))
        return;

    FakeVimHandler *handler = new FakeVimHandler(widget, widget);

    connect(handler, SIGNAL(extraInformationChanged(QString)),
        this, SLOT(showExtraInformation(QString)));
    connect(handler, SIGNAL(commandBufferChanged(QString)),
        this, SLOT(showCommandBuffer(QString)));
    connect(handler, SIGNAL(quitRequested()),
        this, SLOT(removeHandler()), Qt::QueuedConnection);
    connect(handler, SIGNAL(writeFileRequested(bool*,QString,QString)),
        this, SLOT(writeFile(bool*,QString,QString)));
    connect(handler, SIGNAL(selectionChanged(QList<QTextEdit::ExtraSelection>)),
        this, SLOT(changeSelection(QList<QTextEdit::ExtraSelection>)));

    handler->setupWidget();
    handler->setExtraData(editor);

    if (BaseTextEditor *bt = qobject_cast<BaseTextEditor *>(widget)) {
        using namespace TextEditor;
        using namespace FakeVim::Constants;
        handler->setCurrentFileName(editor->file()->fileName());
        TabSettings settings = bt->tabSettings();
        handler->setConfigValue(ConfigTabStop,
            QString::number(settings.m_tabSize));
        handler->setConfigValue(ConfigShiftWidth,
            QString::number(settings.m_indentSize));
        handler->setConfigValue(ConfigExpandTab,
            settings.m_spacesForTabs ? ConfigOn : ConfigOff);
        handler->setConfigValue(ConfigSmartTab,
            settings.m_smartBackspace ? ConfigOn : ConfigOff);
        handler->setConfigValue(ConfigAutoIndent,
            settings.m_autoIndent ? ConfigOn : ConfigOff);
    }
}

void FakeVimPluginPrivate::installHandlerOnCurrentEditor()
{
    installHandler(EditorManager::instance()->currentEditor());
}

void FakeVimPluginPrivate::writeFile(bool *handled,
    const QString &fileName, const QString &contents)
{
    Q_UNUSED(contents);

    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (!handler)
        return;

    Core::IEditor *editor = qobject_cast<Core::IEditor *>(handler->extraData());
    if (editor && editor->file()->fileName() == fileName) {
        // Handle that as a special case for nicer interaction with core
        Core::IFile *file = editor->file();
        Core::ICore::instance()->fileManager()->blockFileChange(file);
        file->save(fileName);
        Core::ICore::instance()->fileManager()->unblockFileChange(file);
        *handled = true;
    }
}

void FakeVimPluginPrivate::removeHandler()
{
    if (FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender())) {
        handler->restoreWidget();
        handler->deleteLater();
    }
    Core::EditorManager::instance()->hideEditorInfoBar(
        QLatin1String(Constants::MINI_BUFFER));
}

void FakeVimPluginPrivate::editorOpened(Core::IEditor *editor)
{
    //qDebug() << "OPENING: " << editor << editor->widget();
    QSettings *s = ICore::instance()->settings();
    bool automatic = s->value("textInteractionSettings/UseVim").toBool();
    if (automatic)
       installHandler(editor);
}

void FakeVimPluginPrivate::editorAboutToClose(Core::IEditor *editor)
{
    //qDebug() << "CLOSING: " << editor << editor->widget();
    Q_UNUSED(editor);
}

void FakeVimPluginPrivate::showCommandBuffer(const QString &contents)
{
    //qDebug() << "SHOW COMMAND BUFFER" << contents;
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (handler) {
        Core::EditorManager::instance()->showEditorInfoBar(
            QLatin1String(Constants::MINI_BUFFER), contents,
            tr("Quit FakeVim"), handler, SLOT(quit()));
    }
}

void FakeVimPluginPrivate::showExtraInformation(const QString &text)
{
    FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender());
    if (handler)
        QMessageBox::information(handler->widget(), tr("FakeVim Information"), text);
}

void FakeVimPluginPrivate::changeSelection
    (const QList<QTextEdit::ExtraSelection> &selection)
{
    if (FakeVimHandler *handler = qobject_cast<FakeVimHandler *>(sender()))
        if (BaseTextEditor *bt = qobject_cast<BaseTextEditor *>(handler->widget()))
            bt->setExtraSelections(BaseTextEditor::FakeVimSelection, selection);
}

///////////////////////////////////////////////////////////////////////
//
// FakeVimPlugin
//
///////////////////////////////////////////////////////////////////////

FakeVimPlugin::FakeVimPlugin()
    : d(new FakeVimPluginPrivate(this))
{}

FakeVimPlugin::~FakeVimPlugin()
{
    delete d;
}

bool FakeVimPlugin::initialize(const QStringList &arguments, QString *errorMessage)
{
    Q_UNUSED(arguments);
    Q_UNUSED(errorMessage);
    return d->initialize();
}

void FakeVimPlugin::shutdown()
{
    d->shutdown();
}

void FakeVimPlugin::extensionsInitialized()
{
}

#include "fakevimplugin.moc"

Q_EXPORT_PLUGIN(FakeVimPlugin)
<|endoftext|>


<commit_before>/*  This file is part of the Vc library.

    Copyright (C) 2009 Matthias Kretz <kretz@kde.org>

    Vc is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Vc 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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/Vc>
#include "benchmark.h"
#include "random.h"
#include <limits>

using namespace Vc;

enum {
    MemorySize = 1024 * 1024 * 64 // 64 MiB
};

void *blackHolePtr = 0;

template<typename V>
static void doBlah()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;
    typedef typename V::Mask M;

    const T two = 2;
    const T divider = std::numeric_limits<T>::max() / 1500;
    const T bound = 1000;

    enum {
        ArraySize = MemorySize / sizeof(V)
    };
    union {
        V *v;
        T *t;
    } mem = { new V[ArraySize] };
    for (int i = 0; i < ArraySize; ++i) {
        mem.v[i] = PseudoRandom<V>::next();
    }
    V t = mem.v[0];
    mem.v[0].makeZero();
    for (int i = 1; i < ArraySize; ++i) {
        t = (t * mem.v[i] + t) / divider;
        t(t >= bound || t < 0) = two;
        mem.v[i] = t;
        t(t == 0) += V(One);
    }
    M mask;
    T data[1000];
    for (I i(Vc::Zero); !(mask = i < 1000).isEmpty(); i += I::Size) {
        I i2 = static_cast<I>(V(mem.t, i, mask));
        V v(data, i2, mask, Vc::Zero);
        v = v * two + t;
        v.scatter(data, i2, mask);
    }
    asm volatile(""::"r"(&data[0]));
    blackHolePtr = mem.v;
}

template<typename V>
static double opsFactor()
{
    enum {
        ArraySize = MemorySize / sizeof(V)
    };
    return V::Size * (ArraySize * (5 + 10) + (1000 + V::Size - 1) / V::Size * 5);
}

int bmain()
{
    Benchmark timer("DhryRock", opsFactor<int_v>() + opsFactor<uint_v>() + opsFactor<short_v>() + opsFactor<ushort_v>(), "Op");
    while (timer.wantsMoreDataPoints()) {
        timer.Start();
        doBlah<int_v>();
        delete[] (int_v *)blackHolePtr;
        doBlah<uint_v>();
        delete[] (uint_v *)blackHolePtr;
        doBlah<short_v>();
        delete[] (short_v *)blackHolePtr;
        doBlah<ushort_v>();
        delete[] (ushort_v *)blackHolePtr;
        timer.Stop();
    }
    timer.Print();
    return 0;
}
<commit_msg>use static_cast instead of C-cast<commit_after>/*  This file is part of the Vc library.

    Copyright (C) 2009 Matthias Kretz <kretz@kde.org>

    Vc is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as
    published by the Free Software Foundation, either version 3 of
    the License, or (at your option) any later version.

    Vc 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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Vc.  If not, see <http://www.gnu.org/licenses/>.

*/

#include <Vc/Vc>
#include "benchmark.h"
#include "random.h"
#include <limits>

using namespace Vc;

enum {
    MemorySize = 1024 * 1024 * 64 // 64 MiB
};

void *blackHolePtr = 0;

template<typename V>
static void doBlah()
{
    typedef typename V::EntryType T;
    typedef typename V::IndexType I;
    typedef typename V::Mask M;

    const T two = 2;
    const T divider = std::numeric_limits<T>::max() / 1500;
    const T bound = 1000;

    enum {
        ArraySize = MemorySize / sizeof(V)
    };
    union {
        V *v;
        T *t;
    } mem = { new V[ArraySize] };
    for (int i = 0; i < ArraySize; ++i) {
        mem.v[i] = PseudoRandom<V>::next();
    }
    V t = mem.v[0];
    mem.v[0].makeZero();
    for (int i = 1; i < ArraySize; ++i) {
        t = (t * mem.v[i] + t) / divider;
        t(t >= bound || t < 0) = two;
        mem.v[i] = t;
        t(t == 0) += V(One);
    }
    M mask;
    T data[1000];
    for (I i(Vc::Zero); !(mask = i < 1000).isEmpty(); i += I::Size) {
        I i2 = static_cast<I>(V(mem.t, i, mask));
        V v(data, i2, mask, Vc::Zero);
        v = v * two + t;
        v.scatter(data, i2, mask);
    }
    asm volatile(""::"r"(&data[0]));
    blackHolePtr = mem.v;
}

template<typename V>
static double opsFactor()
{
    enum {
        ArraySize = MemorySize / sizeof(V)
    };
    return V::Size * (ArraySize * (5 + 10) + (1000 + V::Size - 1) / V::Size * 5);
}

int bmain()
{
    Benchmark timer("DhryRock", opsFactor<int_v>() + opsFactor<uint_v>() + opsFactor<short_v>() + opsFactor<ushort_v>(), "Op");
    while (timer.wantsMoreDataPoints()) {
        timer.Start();
        doBlah<int_v>();
        delete[] static_cast<int_v *>(blackHolePtr);
        doBlah<uint_v>();
        delete[] static_cast<uint_v *>(blackHolePtr);
        doBlah<short_v>();
        delete[] static_cast<short_v *>(blackHolePtr);
        doBlah<ushort_v>();
        delete[] static_cast<ushort_v *>(blackHolePtr);
        timer.Stop();
    }
    timer.Print();
    return 0;
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.1  2002/02/01 22:21:50  peiyongz
 * Initial revision
 *
 * Revision 1.3  2000/02/06 07:47:46  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.2  2000/01/15 01:26:16  rahulj
 * Added support for HTTP to the parser using libWWW 5.2.8.
 * Renamed URL.[ch]pp to XMLURL.[ch]pp and like wise for the class name.
 * Only tested under NT 4.0 SP 5.
 * Removed URL.hpp from files where it was not used.
 *
 * Revision 1.1  2000/01/12 00:13:26  roddey
 * These were moved from internal/ to framework/, which was something that should have
 * happened long ago. They are really framework type of classes.
 *
 * Revision 1.1.1.1  1999/11/09 01:08:18  twl
 * Initial checkin
 *
 * Revision 1.3  1999/11/08 20:44:44  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/BinFileInputStream.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLURL.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/framework/URLInputSource.hpp>

// ---------------------------------------------------------------------------
//  URLInputSource: Constructors and Destructor
// ---------------------------------------------------------------------------
URLInputSource::URLInputSource(const XMLURL& urlId) :

    fURL(urlId)
{
    setSystemId(fURL.getURLText());
}

URLInputSource::URLInputSource( const   XMLCh* const    baseId
                                , const XMLCh* const    systemId) :
    fURL(baseId, systemId)
{
    // Create a URL that will build up the full URL and store as the system id
    setSystemId(fURL.getURLText());
}

URLInputSource::URLInputSource( const   XMLCh* const    baseId
                                , const XMLCh* const    systemId
                                , const XMLCh* const    publicId) :
    InputSource(0, publicId)
    , fURL(systemId, publicId)
{
    setSystemId(fURL.getURLText());
}

URLInputSource::URLInputSource( const   XMLCh* const    baseId
                                , const char* const     systemId) :
    fURL(baseId, systemId)
{
    setSystemId(fURL.getURLText());
}

URLInputSource::URLInputSource( const   XMLCh* const   baseId
                                , const char* const    systemId
                                , const char* const    publicId) :
    InputSource(0, publicId)
    , fURL(baseId, systemId)
{
    setSystemId(fURL.getURLText());
}

URLInputSource::~URLInputSource()
{
}

// ---------------------------------------------------------------------------
//  URLInputSource: Implementation of the input source interface
// ---------------------------------------------------------------------------
BinInputStream* URLInputSource::makeStream() const
{
    // Ask the URL to create us an appropriate input stream
    return fURL.makeNewStream();
}
<commit_msg>fairly serious error in the two XMLCh* constructor, the fURL member was being improperly initialized with the (systemID,publicID) instead of (baseId,systemId)<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 * $Log$
 * Revision 1.2  2002/04/25 00:12:34  jasons
 * fairly serious error in the two XMLCh* constructor, the fURL member
 * was being improperly initialized with the (systemID,publicID) instead
 * of (baseId,systemId)
 *
 * Revision 1.1.1.1  2002/02/01 22:21:50  peiyongz
 * sane_include
 *
 * Revision 1.3  2000/02/06 07:47:46  rahulj
 * Year 2K copyright swat.
 *
 * Revision 1.2  2000/01/15 01:26:16  rahulj
 * Added support for HTTP to the parser using libWWW 5.2.8.
 * Renamed URL.[ch]pp to XMLURL.[ch]pp and like wise for the class name.
 * Only tested under NT 4.0 SP 5.
 * Removed URL.hpp from files where it was not used.
 *
 * Revision 1.1  2000/01/12 00:13:26  roddey
 * These were moved from internal/ to framework/, which was something that should have
 * happened long ago. They are really framework type of classes.
 *
 * Revision 1.1.1.1  1999/11/09 01:08:18  twl
 * Initial checkin
 *
 * Revision 1.3  1999/11/08 20:44:44  rahul
 * Swat for adding in Product name and CVS comment log variable.
 *
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/BinFileInputStream.hpp>
#include <xercesc/util/Janitor.hpp>
#include <xercesc/util/XMLURL.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/framework/URLInputSource.hpp>

// ---------------------------------------------------------------------------
//  URLInputSource: Constructors and Destructor
// ---------------------------------------------------------------------------
URLInputSource::URLInputSource(const XMLURL& urlId) :

    fURL(urlId)
{
    setSystemId(fURL.getURLText());
}

URLInputSource::URLInputSource( const   XMLCh* const    baseId
                                , const XMLCh* const    systemId) :
    fURL(baseId, systemId)
{
    // Create a URL that will build up the full URL and store as the system id
    setSystemId(fURL.getURLText());
}

URLInputSource::URLInputSource( const   XMLCh* const    baseId
                                , const XMLCh* const    systemId
                                , const XMLCh* const    publicId) :
    InputSource(0, publicId)
    , fURL(baseId, systemId)
{
    setSystemId(fURL.getURLText());
}

URLInputSource::URLInputSource( const   XMLCh* const    baseId
                                , const char* const     systemId) :
    fURL(baseId, systemId)
{
    setSystemId(fURL.getURLText());
}

URLInputSource::URLInputSource( const   XMLCh* const   baseId
                                , const char* const    systemId
                                , const char* const    publicId) :
    InputSource(0, publicId)
    , fURL(baseId, systemId)
{
    setSystemId(fURL.getURLText());
}

URLInputSource::~URLInputSource()
{
}

// ---------------------------------------------------------------------------
//  URLInputSource: Implementation of the input source interface
// ---------------------------------------------------------------------------
BinInputStream* URLInputSource::makeStream() const
{
    // Ask the URL to create us an appropriate input stream
    return fURL.makeNewStream();
}
<|endoftext|>


<commit_before>#include "customuploader.hpp"

#include <QApplication>
#include <QBuffer>
#include <QClipboard>
#include <QDebug>
#include <QFile>
#include <QJsonDocument>
#include <QNetworkReply>
#include <io/ioutils.hpp>
#include <notifications.hpp>

using std::runtime_error;

void error(QString absFilePath, QString err) {
    throw runtime_error((QString("Invalid file: ").append(absFilePath) + ": " + err).toStdString());
}

CustomUploader::CustomUploader(QString absFilePath) {
    types.insert("PNG", "image/png"); // This is a list of supported formats, too
    types.insert("GIF", "image/gif");
    types.insert("JPG", "image/jpeg");
    types.insert("JPEG", "image/jpeg");
    types.insert("WEBM", "video/webm");
    types.insert("MP4", "video/mp4");
    // Let's go
    QFile file(absFilePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) error(absFilePath, file.errorString());
    QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
    if (!doc.isObject()) {
        error(absFilePath, "Root not an object");
    }
    QJsonObject obj = doc.object();
    if (!obj["name"].isString())
        error(absFilePath, "name is not a string");
    else
        uName = obj["name"].toString();
    if (!obj.contains("desc")) {
        if (!obj["desc"].isString())
            /*t*/ error(absFilePath, "desc not a string");
        else
            desc = obj["desc"].toString();
    } else
        desc = absFilePath;
    QJsonValue m = obj["method"];
    if (!m.isUndefined() && !m.isNull()) {
        if (!m.isString()) error(absFilePath, "method not a string");
        QString toCheck = m.toString().toLower();
        if (toCheck == "post")
            method = HttpMethod::POST;
        else
            error(absFilePath, "method invalid");
    }
    QJsonValue url = obj["target"];
    if (!url.isString()) {
        error(absFilePath, "target missing");
    }
    QUrl target(url.toString());
    if (!target.isValid()) error(absFilePath, "target not URL");
    this->target = target;
    QJsonValue formatValue = obj["format"];
    if (!formatValue.isUndefined() && !formatValue.isNull()) {
        if (formatValue.isString()) {
            QString formatString = formatValue.toString().toLower();
            if (formatString == "x-www-form-urlencoded")
                format = RequestFormat::X_WWW_FORM_URLENCODED;
            else if (formatString == "json")
                format = RequestFormat::JSON;
            else if (formatString == "plain")
                format = RequestFormat::PLAIN;
            else
                error(absFilePath, "format invalid");
        }
    } else
        error(absFilePath, "format provided but not string");
    QJsonValue imageValue = obj["imageformat"];
    if (!imageValue.isString()) {
        error(absFilePath, "imageformat not string");
    }
    QString imageFormat = imageValue.toString();
    if (imageFormat == "base64" || QRegExp("base64\\([^+]+\\+[^+]+)").exactMatch(imageFormat)
        || QRegExp("[^+]+\\+[^+]+").exactMatch(imageFormat)) {
        this->iFormat = imageFormat;
    } else
        error(absFilePath, "imageformat invalid");
    QJsonValue bodyValue = obj["body"];
    if (format != RequestFormat::PLAIN) {
        if (bodyValue.isUndefined()) error(absFilePath, "body not set");
        if (bodyValue.isObject())
            body = bodyValue;
        else
            error(absFilePath, "body not object");
    } else {
        if (bodyValue.isString()) {
            body = bodyValue;
        } else
            error(absFilePath, "body not string (reason: format: PLAIN)");
    }
    QJsonValue headerVal = obj["headers"];
    if (!(headerVal.isUndefined() || headerVal.isNull())) {
        if (!headerVal.isObject()) error(absFilePath, "headers must be object");
        headers = headerVal.toObject();
    } else
        headers = QJsonObject();
    QJsonValue returnPsVal = obj["return"];
    if (returnPsVal.isString()) {
        returnPathspec = returnPsVal.toString();
    } else
        error(absFilePath, "return invalid");
}

QString CustomUploader::name() {
    return uName;
}

QString CustomUploader::description() {
    return desc;
}

QString getCType(RequestFormat format, QString plainType) {
    switch (format) {
    case RequestFormat::X_WWW_FORM_URLENCODED:
        return "application/x-www-form-urlencoded";
    case RequestFormat::JSON:
        return "application/json";
    case RequestFormat::PLAIN:
        return plainType;
    }
    return plainType;
}

QList<QPair<QString, QString>> getHeaders(QJsonObject h, QString imageFormat, QMap<QString, QString> types, RequestFormat format) {
    QList<QPair<QString, QString>> headers;
    for (QString s : h.keys()) {
        if (s.toLower() == "content-type") continue;
        QJsonValue v = h[s];
        if (!v.isString())
            headers << QPair<QString, QString>(s, QJsonDocument::fromVariant(v.toVariant()).toJson());
        else
            headers << QPair<QString, QString>(s, v.toString());
    }
    headers << QPair<QString, QString>("Content-Type", getCType(format, types.value(imageFormat)));
    return headers;
}

QByteArray imageBytes(QPixmap *pixmap, QString format) {
    QByteArray returnVal;
    QBuffer buff(&returnVal);
    buff.open(QIODevice::WriteOnly);
    pixmap->save(&buff, format.toUpper().toLocal8Bit().constData());
    return returnVal;
}

QString CustomUploader::getFormatString(bool animated) {
    if (iFormat == "base64")
        return animated ? "GIF" : "PNG";
    else if (QRegExp("[^+]+\\+[^+]+").exactMatch(iFormat))
        return iFormat.split('+')[(int)animated];
    else if (QRegExp("base64\\([^+]+\\+[^+]+)").exactMatch(iFormat))
        return iFormat.mid(7, iFormat.length() - 8).split('+')[(int)animated];
    return "";
}

QJsonObject recurseAndReplace(QJsonObject &body, QByteArray &data, QString contentType) {
    QJsonObject o;
    for (QString s : body.keys()) {
        QJsonValue v = body[s];
        if (v.isObject()) {
            QJsonObject vo = v.toObject();
            o.insert(s, recurseAndReplace(vo, data, contentType));
        } else if (v.isString()) {
            QString str = v.toString();
            if (str.startsWith("/") && str.endsWith("/")) {
                o.insert(s, str.replace("%image", data).replace("%contenttype", contentType));
            }
        }
    }
    return o;
}

QString parsePathspec(QJsonDocument &response, QString &pathspec) {
    if (!pathspec.startsWith(".")) {
        // Does not point to anything
        return "";
    } else {
        if (!response.isObject()) return "";
        QStringList fields = pathspec.right(pathspec.length() - 1).split('.', QString::SkipEmptyParts);
        QJsonObject o = response.object();
        if (pathspec == ".") {
            return QString::fromUtf8(response.toJson());
        }
        QJsonValue val = o[fields.at(0)];
        if (val.isUndefined() || val.isNull())
            return "";
        else if (val.isString())
            return val.toString();
        else if (!val.isObject())
            return QString::fromUtf8(QJsonDocument::fromVariant(val.toVariant()).toJson());
        for (int i = 1; i < fields.size(); i++) {
            if (val.isUndefined() || val.isNull())
                return "";
            else if (val.isString())
                return val.toString();
            else if (!val.isObject())
                return QString::fromUtf8(QJsonDocument::fromVariant(val.toVariant()).toJson());
            else
                val = val.toObject()[fields.at(i)];
        }
        if (val.isUndefined() || val.isNull())
            return "";
        else if (val.isString())
            return val.toString();
        else if (!val.isObject())
            return QString::fromUtf8(QJsonDocument::fromVariant(val.toVariant()).toJson());
    }
    return "";
}

void parseResult(QJsonDocument result, QString returnPathspec, QString name) {
    if (result.isObject()) {
        qDebug() << result.object()[".url"];
        QString url = parsePathspec(result, returnPathspec);
        if (!url.isEmpty()) {
            QApplication::clipboard()->setText(url);
            notifications::notify("KShare Custom Uploader " + name, "Copied upload link to clipboard!");
        } else
            notifications::notify("KShare Custom Uploader " + name, "Upload done, but result empty!");
    } else
        notifications::notify("KShare Custom Uploader " + name, "Upload done, but result is not JSON Object!");
}

void CustomUploader::doUpload(QPixmap *pixmap) {
    auto h = getHeaders(headers, getFormatString(false), types, this->format);
    QString format = getFormatString(false); // Soon:tm:
    QByteArray data;
    QByteArray imgData = imageBytes(pixmap, format);
    if (iFormat == "base64" || QRegExp("base64\\([^+]\\+[^+]\\)").exactMatch(iFormat)) imgData = imgData.toBase64();
    switch (this->format) {
    case RequestFormat::PLAIN: {
        data = imgData;
    } break;
    case RequestFormat::JSON: {
        if (body.isString()) {
            QStringList split = body.toString().replace("%contenttype", types.value(format)).split("%imagedata");
            for (int i = 0; i < split.size(); i++) {
                data.append(split[i]);
                if (i < split.size() - 1) data.append(imgData);
            }
        } else {
            QJsonObject vo = body.toObject();
            data = QJsonDocument::fromVariant(recurseAndReplace(vo, imgData, types.value(format)).toVariantMap()).toJson();
        }
    } break;
    case RequestFormat::X_WWW_FORM_URLENCODED: {
        QJsonObject body = this->body.toObject();
        for (QString key : body.keys()) {
            QJsonValue val = body[key];
            if (val.isString()) {
                QString str = val.toString();
                QByteArray strB;
                if (str.startsWith("/") && str.endsWith("/")) {
                    str = str.mid(1, str.length() - 2);
                    QStringList split = str.replace("%contenttype", types.value(format)).split("%imagedata");
                    for (int i = 0; i < split.size(); i++) {
                        strB.append(split[i]);
                        if (i < split.size() - 1) strB.append(imgData);
                    }
                }
                data.append(QUrl::toPercentEncoding(key)).append('=').append(strB);
            } else {
                if (!data.isEmpty()) data.append('&');
                data.append(QUrl::toPercentEncoding(key))
                .append('=')
                .append(QUrl::toPercentEncoding(QJsonDocument::fromVariant(body[key].toVariant()).toJson()));
            }
        }
    } break;
    }
    switch (method) {
    case HttpMethod::POST:
        if (returnPathspec == "|") {
            ioutils::postData(target, h, data, [&](QByteArray result, QNetworkReply *) {
                QApplication::clipboard()->setText(QString::fromUtf8(result));
                notifications::notify("KShare Custom Uploader " + name(), "Copied upload result to clipboard!");
            });
        } else {
            ioutils::postJson(target, h, data, [&](QJsonDocument result, QByteArray, QNetworkReply *) {
                parseResult(result, returnPathspec, name());
            });
        }
        break;
    }
}
<commit_msg>Copy request to clipboard upon failure<commit_after>#include "customuploader.hpp"

#include <QApplication>
#include <QBuffer>
#include <QClipboard>
#include <QDebug>
#include <QFile>
#include <QJsonDocument>
#include <QNetworkReply>
#include <io/ioutils.hpp>
#include <notifications.hpp>

using std::runtime_error;

void error(QString absFilePath, QString err) {
    throw runtime_error((QString("Invalid file: ").append(absFilePath) + ": " + err).toStdString());
}

CustomUploader::CustomUploader(QString absFilePath) {
    types.insert("PNG", "image/png"); // This is a list of supported formats, too
    types.insert("GIF", "image/gif");
    types.insert("JPG", "image/jpeg");
    types.insert("JPEG", "image/jpeg");
    types.insert("WEBM", "video/webm");
    types.insert("MP4", "video/mp4");
    // Let's go
    QFile file(absFilePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) error(absFilePath, file.errorString());
    QJsonDocument doc = QJsonDocument::fromJson(file.readAll());
    if (!doc.isObject()) {
        error(absFilePath, "Root not an object");
    }
    QJsonObject obj = doc.object();
    if (!obj["name"].isString())
        error(absFilePath, "name is not a string");
    else
        uName = obj["name"].toString();
    if (!obj.contains("desc")) {
        if (!obj["desc"].isString())
            /*t*/ error(absFilePath, "desc not a string");
        else
            desc = obj["desc"].toString();
    } else
        desc = absFilePath;
    QJsonValue m = obj["method"];
    if (!m.isUndefined() && !m.isNull()) {
        if (!m.isString()) error(absFilePath, "method not a string");
        QString toCheck = m.toString().toLower();
        if (toCheck == "post")
            method = HttpMethod::POST;
        else
            error(absFilePath, "method invalid");
    }
    QJsonValue url = obj["target"];
    if (!url.isString()) {
        error(absFilePath, "target missing");
    }
    QUrl target(url.toString());
    if (!target.isValid()) error(absFilePath, "target not URL");
    this->target = target;
    QJsonValue formatValue = obj["format"];
    if (!formatValue.isUndefined() && !formatValue.isNull()) {
        if (formatValue.isString()) {
            QString formatString = formatValue.toString().toLower();
            if (formatString == "x-www-form-urlencoded")
                format = RequestFormat::X_WWW_FORM_URLENCODED;
            else if (formatString == "json")
                format = RequestFormat::JSON;
            else if (formatString == "plain")
                format = RequestFormat::PLAIN;
            else
                error(absFilePath, "format invalid");
        }
    } else
        error(absFilePath, "format provided but not string");
    QJsonValue imageValue = obj["imageformat"];
    if (!imageValue.isString()) {
        error(absFilePath, "imageformat not string");
    }
    QString imageFormat = imageValue.toString();
    if (imageFormat == "base64" || QRegExp("base64\\([^+]+\\+[^+]+)").exactMatch(imageFormat)
        || QRegExp("[^+]+\\+[^+]+").exactMatch(imageFormat)) {
        this->iFormat = imageFormat;
    } else
        error(absFilePath, "imageformat invalid");
    QJsonValue bodyValue = obj["body"];
    if (format != RequestFormat::PLAIN) {
        if (bodyValue.isUndefined()) error(absFilePath, "body not set");
        if (bodyValue.isObject())
            body = bodyValue;
        else
            error(absFilePath, "body not object");
    } else {
        if (bodyValue.isString()) {
            body = bodyValue;
        } else
            error(absFilePath, "body not string (reason: format: PLAIN)");
    }
    QJsonValue headerVal = obj["headers"];
    if (!(headerVal.isUndefined() || headerVal.isNull())) {
        if (!headerVal.isObject()) error(absFilePath, "headers must be object");
        headers = headerVal.toObject();
    } else
        headers = QJsonObject();
    QJsonValue returnPsVal = obj["return"];
    if (returnPsVal.isString()) {
        returnPathspec = returnPsVal.toString();
    } else
        error(absFilePath, "return invalid");
}

QString CustomUploader::name() {
    return uName;
}

QString CustomUploader::description() {
    return desc;
}

QString getCType(RequestFormat format, QString plainType) {
    switch (format) {
    case RequestFormat::X_WWW_FORM_URLENCODED:
        return "application/x-www-form-urlencoded";
    case RequestFormat::JSON:
        return "application/json";
    case RequestFormat::PLAIN:
        return plainType;
    }
    return plainType;
}

QList<QPair<QString, QString>> getHeaders(QJsonObject h, QString imageFormat, QMap<QString, QString> types, RequestFormat format) {
    QList<QPair<QString, QString>> headers;
    for (QString s : h.keys()) {
        if (s.toLower() == "content-type") continue;
        QJsonValue v = h[s];
        if (!v.isString())
            headers << QPair<QString, QString>(s, QJsonDocument::fromVariant(v.toVariant()).toJson());
        else
            headers << QPair<QString, QString>(s, v.toString());
    }
    headers << QPair<QString, QString>("Content-Type", getCType(format, types.value(imageFormat)));
    return headers;
}

QByteArray imageBytes(QPixmap *pixmap, QString format) {
    QByteArray returnVal;
    QBuffer buff(&returnVal);
    buff.open(QIODevice::WriteOnly);
    pixmap->save(&buff, format.toUpper().toLocal8Bit().constData());
    return returnVal;
}

QString CustomUploader::getFormatString(bool animated) {
    if (iFormat == "base64")
        return animated ? "GIF" : "PNG";
    else if (QRegExp("[^+]+\\+[^+]+").exactMatch(iFormat))
        return iFormat.split('+')[(int)animated];
    else if (QRegExp("base64\\([^+]+\\+[^+]+)").exactMatch(iFormat))
        return iFormat.mid(7, iFormat.length() - 8).split('+')[(int)animated];
    return "";
}

QJsonObject recurseAndReplace(QJsonObject &body, QByteArray &data, QString contentType) {
    QJsonObject o;
    for (QString s : body.keys()) {
        QJsonValue v = body[s];
        if (v.isObject()) {
            QJsonObject vo = v.toObject();
            o.insert(s, recurseAndReplace(vo, data, contentType));
        } else if (v.isString()) {
            QString str = v.toString();
            if (str.startsWith("/") && str.endsWith("/")) {
                o.insert(s, str.replace("%image", data).replace("%contenttype", contentType));
            }
        }
    }
    return o;
}

QString parsePathspec(QJsonDocument &response, QString &pathspec) {
    if (!pathspec.startsWith(".")) {
        // Does not point to anything
        return "";
    } else {
        if (!response.isObject()) return "";
        QStringList fields = pathspec.right(pathspec.length() - 1).split('.', QString::SkipEmptyParts);
        QJsonObject o = response.object();
        if (pathspec == ".") {
            return QString::fromUtf8(response.toJson());
        }
        QJsonValue val = o[fields.at(0)];
        if (val.isUndefined() || val.isNull())
            return "";
        else if (val.isString())
            return val.toString();
        else if (!val.isObject())
            return QString::fromUtf8(QJsonDocument::fromVariant(val.toVariant()).toJson());
        for (int i = 1; i < fields.size(); i++) {
            if (val.isUndefined() || val.isNull())
                return "";
            else if (val.isString())
                return val.toString();
            else if (!val.isObject())
                return QString::fromUtf8(QJsonDocument::fromVariant(val.toVariant()).toJson());
            else
                val = val.toObject()[fields.at(i)];
        }
        if (val.isUndefined() || val.isNull())
            return "";
        else if (val.isString())
            return val.toString();
        else if (!val.isObject())
            return QString::fromUtf8(QJsonDocument::fromVariant(val.toVariant()).toJson());
    }
    return "";
}

void parseResult(QJsonDocument result, QByteArray data, QString returnPathspec, QString name) {
    if (result.isObject()) {
        qDebug() << result.object()[".url"];
        QString url = parsePathspec(result, returnPathspec);
        if (!url.isEmpty()) {
            QApplication::clipboard()->setText(url);
            notifications::notify("KShare Custom Uploader " + name, "Copied upload link to clipboard!");
        } else
            notifications::notify("KShare Custom Uploader " + name, "Upload done, but result empty!");
    } else {
        notifications::notify("KShare Custom Uploader " + name,
                              "Upload done, but result is not JSON Object! Result in clipboard.");
        QApplication::clipboard()->setText(data);
    }
}

void CustomUploader::doUpload(QPixmap *pixmap) {
    auto h = getHeaders(headers, getFormatString(false), types, this->format);
    QString format = getFormatString(false); // Soon:tm:
    QByteArray data;
    QByteArray imgData = imageBytes(pixmap, format);
    if (iFormat == "base64" || QRegExp("base64\\([^+]\\+[^+]\\)").exactMatch(iFormat)) imgData = imgData.toBase64();
    switch (this->format) {
    case RequestFormat::PLAIN: {
        data = imgData;
    } break;
    case RequestFormat::JSON: {
        if (body.isString()) {
            QStringList split = body.toString().replace("%contenttype", types.value(format)).split("%imagedata");
            for (int i = 0; i < split.size(); i++) {
                data.append(split[i]);
                if (i < split.size() - 1) data.append(imgData);
            }
        } else {
            QJsonObject vo = body.toObject();
            data = QJsonDocument::fromVariant(recurseAndReplace(vo, imgData, types.value(format)).toVariantMap()).toJson();
        }
    } break;
    case RequestFormat::X_WWW_FORM_URLENCODED: {
        QJsonObject body = this->body.toObject();
        for (QString key : body.keys()) {
            QJsonValue val = body[key];
            if (val.isString()) {
                QString str = val.toString();
                QByteArray strB;
                if (str.startsWith("/") && str.endsWith("/")) {
                    str = str.mid(1, str.length() - 2);
                    QStringList split = str.replace("%contenttype", types.value(format)).split("%imagedata");
                    for (int i = 0; i < split.size(); i++) {
                        strB.append(split[i]);
                        if (i < split.size() - 1) strB.append(imgData);
                    }
                }
                data.append(QUrl::toPercentEncoding(key)).append('=').append(strB);
            } else {
                if (!data.isEmpty()) data.append('&');
                data.append(QUrl::toPercentEncoding(key))
                .append('=')
                .append(QUrl::toPercentEncoding(QJsonDocument::fromVariant(body[key].toVariant()).toJson()));
            }
        }
    } break;
    }
    switch (method) {
    case HttpMethod::POST:
        if (returnPathspec == "|") {
            ioutils::postData(target, h, data, [&](QByteArray result, QNetworkReply *) {
                QApplication::clipboard()->setText(QString::fromUtf8(result));
                notifications::notify("KShare Custom Uploader " + name(), "Copied upload result to clipboard!");
            });
        } else {
            ioutils::postJson(target, h, data, [&](QJsonDocument result, QByteArray data, QNetworkReply *) {
                parseResult(result, data, returnPathspec, name());
            });
        }
        break;
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2017 Anyar, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "Damper.h"
#include "Spring.h"

#include <iostream>

using namespace asc;

// The goal is to be able to implement radix sorting

struct Seq
{
   size_t N{};
   size_t id{};

   void init()
   {
      if (!initialized)
      {
         for (auto& f : run_after)
            f();
      }
      initialized = true;
   }

   void increment()
   {
      ++N;
      for (auto& f : run_after)
         f();
   }

   void before(Seq& s)
   {
      run_after.emplace_back([&] { s.increment(); });
   }

   void after(Seq& s)
   {
      s.run_before.emplace_back([&] { increment(); });
   }

private:
   bool initialized{};
   std::vector<std::function<void()>> run_before, run_after;
};

int main()
{
   asc::state_t x;
   x.reserve(100);

   std::vector<Seq> seq;
   seq.emplace_back();
   seq.emplace_back();
   seq.emplace_back();
   seq.emplace_back();

   const size_t n = seq.size();
   for (size_t i = 0; i < n; ++i)
   {
      seq[i].id = i;
   }

   seq[2].before(seq[1]);
   //seq[0].after(seq[1]);

   for (auto& s : seq)
      s.init();

   std::sort(seq.begin(), seq.end(), [](auto& lhs, auto& rhs) { return lhs.N < rhs.N; });

   for (size_t i = 0; i < n; ++i)
      std::cout << seq[i].id << '\n';

   return 0;
}<commit_msg>Reverted modular-spring-damper/Main.cpp as unintentionally committed sequence testing code<commit_after>// Copyright (c) 2016-2017 Anyar, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "Damper.h"
#include "Spring.h"

using namespace asc;

int main()
{
   state_t x;
   x.reserve(100); // We reserve more space than necessary, but Ascent will only allocate what is needed
   double t = 0.0;
   double dt = 0.01;
   double t_end = 1.5;

   Body b0(x);
   Body b1(x);
   b1.m = 1.0;
   b1.s = 1.0;
   b1.v = 40.0;

   Spring spring(b0, b1);
   spring.k = 2000.0;

   Damper damper(b0, b1);
   damper.c = 5.0;

   RK4 integrator;
   Recorder recorder;

   auto system = [&](const asc::state_t& x, asc::state_t& D, const double t)
   {
      // We must run the spring and damper before the body in order to accumulate forces
      spring(x, D, t);
      damper(x, D, t);
      b1(x, D, t);
   };

   while (t < t_end)
   {
      recorder({ t, b1.s });
      integrator(system, x, t, dt);
   }

   recorder.csv("spring-damper", { "t", "b1 position" });

   return 0;
}<|endoftext|>


<commit_before>// Copyright 2016 Chris Drake
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <boost/optional.hpp>
#include <cryptominisat4/cryptominisat.h>

#include "boolexpr/boolexpr.h"
#include "argset.h"

using namespace boolexpr;

Array::Array()
    : items {}
{}

Array::Array(vector<bx_t> const & items)
    : items {items}
{}

Array::Array(vector<bx_t> const && items)
    : items {items}
{}

Array::Array(std::initializer_list<bx_t> const items)
    : items {items}
{}

Array *
boolexpr::operator~(Array const & self)
{
    size_t n = self.items.size();
    vector<bx_t> items(n);

    for (size_t i = 0; i < n; ++i) {
        items[i] = ~self.items[i];
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator|(Array const & lhs, Array const & rhs)
{
    vector<bx_t> items;

    auto lhs_it = lhs.items.begin();
    auto rhs_it = rhs.items.begin();

    while (lhs_it != lhs.items.end() && rhs_it != rhs.items.end()) {
        items.push_back(*lhs_it++ | *rhs_it++);
    }

    while (lhs_it != lhs.items.end()) {
        items.push_back(*lhs_it++);
    }

    while (rhs_it != rhs.items.end()) {
        items.push_back(*rhs_it++);
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator&(Array const & lhs, Array const & rhs)
{
    vector<bx_t> items;

    auto lhs_it = lhs.items.begin();
    auto rhs_it = rhs.items.begin();

    while (lhs_it != lhs.items.end() && rhs_it != rhs.items.end()) {
        items.push_back(*lhs_it++ & *rhs_it++);
    }

    while (lhs_it != lhs.items.end()) {
        items.push_back(*lhs_it++);
    }

    while (rhs_it != rhs.items.end()) {
        items.push_back(*rhs_it++);
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator^(Array const & lhs, Array const & rhs)
{
    vector<bx_t> items;

    auto lhs_it = lhs.items.begin();
    auto rhs_it = rhs.items.begin();

    while (lhs_it != lhs.items.end() && rhs_it != rhs.items.end()) {
        items.push_back(*lhs_it++ ^ *rhs_it++);
    }

    while (lhs_it != lhs.items.end()) {
        items.push_back(*lhs_it++);
    }

    while (rhs_it != rhs.items.end()) {
        items.push_back(*rhs_it++);
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator+(Array const & lhs, Array const & rhs)
{
    vector<bx_t> items(lhs.items.size() + rhs.items.size());

    size_t cnt = 0;

    for (size_t i = 0; i < lhs.items.size(); ++i) {
        items[cnt++] = lhs.items[i];
    }

    for (size_t i = 0; i < rhs.items.size(); ++i) {
        items[cnt++] = rhs.items[i];
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator*(Array const & lhs, size_t num)
{
    vector<bx_t> items(num * lhs.items.size());

    size_t cnt = 0;

    for (size_t i = 0; i < num; ++i) {
        for (size_t j = 0; j < lhs.items.size(); ++j) {
            items[cnt++] = lhs.items[j];
        }
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator*(size_t num, Array const & rhs)
{
    vector<bx_t> items(num * rhs.items.size());

    size_t cnt = 0;

    for (size_t i = 0; i < num; ++i) {
        for (size_t j = 0; j < rhs.items.size(); ++j) {
            items[cnt++] = rhs.items[j];
        }
    }

    return new Array(std::move(items));
}

bx_t const &
Array::operator[](size_t index) const
{
    return this->items[index];
}

bx_t &
Array::operator[](size_t index)
{
    return this->items[index];
}

size_t
Array::size() const
{
    return this->items.size();
}

vector<bx_t>::const_iterator
Array::begin() const
{
    return this->items.begin();
}

vector<bx_t>::const_iterator
Array::end() const
{
    return this->items.end();
}

Array *
Array::compose(var2bx_t const & var2bx) const
{
    size_t n = this->items.size();
    vector<bx_t> items(n);

    for (size_t i = 0; i < n; ++i) {
        items[i] = this->items[i]->compose(var2bx);
    }

    return new Array(std::move(items));
}

Array *
Array::restrict_(point_t const & point) const
{
    size_t n = this->items.size();
    vector<bx_t> items(n);

    for (size_t i = 0; i < n; ++i) {
        items[i] = this->items[i]->restrict_(point);
    }

    return new Array(std::move(items));
}

bool
Array::equiv(Array const & other) const
{

    if (this->items.size() != other.items.size()) {
        return false;
    }

    for (size_t i = 0; i < this->items.size(); ++i) {
        if (!this->items[i]->equiv(other.items[i])) {
            return false;
        }
    }

    return true;
}

Array *
Array::zext(size_t num) const
{
    vector<bx_t> items(this->items.size() + num);

    size_t cnt = 0;
    for (size_t i = 0; i < this->items.size(); ++i) {
        items[cnt++] = this->items[i];
    }

    for (size_t i = 0; i < num; ++i) {
        items[cnt++] = zero();
    }

    return new Array(std::move(items));
}

Array *
Array::sext(size_t num) const
{
    vector<bx_t> items(this->items.size() + num);

    size_t cnt = 0;
    for (size_t i = 0; i < this->items.size(); ++i) {
        items[cnt++] = this->items[i];
    }

    auto sign = this->items[this->items.size()-1];
    for (size_t i = 0; i < num; ++i) {
        items[cnt++] = sign;
    }

    return new Array(std::move(items));
}

bx_t
Array::or_reduce() const
{
    return or_(items);
}

bx_t
Array::and_reduce() const
{
    return and_(items);
}

bx_t
Array::xor_reduce() const
{
    return xor_(items);
}

std::pair<Array *, Array *>
Array::lsh(Array const & a) const
{
    auto m = this->items.size();
    auto n = a.items.size();

    assert(m >= n);

    vector<bx_t> left(m);
    vector<bx_t> right(n);

    for (size_t i = 0; i < n; ++i) {
        left[i] = a.items[i];
    }

    for (size_t i = n; i < m; ++i) {
        left[i] = this->items[i-n];
    }

    for (size_t i = 0; i < n; ++i) {
        right[i] = this->items[i+m-n];
    }

    return std::make_pair(new Array(std::move(left)),
                          new Array(std::move(right)));
}

std::pair<Array *, Array *>
Array::rsh(Array const & a) const
{
    auto m = this->items.size();
    auto n = a.items.size();

    assert(m >= n);

    vector<bx_t> left(n);
    vector<bx_t> right(m);

    for (size_t i = 0; i < n; ++i) {
        left[i] = this->items[i];
    }

    for (size_t i = 0; i < (m-n); ++i) {
        right[i] = this->items[i+n];
    }

    for (size_t i = (m-n); i < m; ++i) {
        right[i] = a.items[i-m+n];
    }

    return std::make_pair(new Array(std::move(left)),
                          new Array(std::move(right)));
}

std::pair<Array *, Array *>
Array::arsh(size_t n) const
{
    auto m = this->items.size();

    assert(m >= n);

    vector<bx_t> left(n);
    vector<bx_t> right(m);

    for (size_t i = 0; i < n; ++i) {
        left[i] = this->items[i];
    }

    for (size_t i = 0; i < (m-n); ++i) {
        right[i] = this->items[i+n];
    }

    for (size_t i = (m-n); i < m; ++i) {
        right[i] = this->items[m-1];
    }

    return std::make_pair(new Array(std::move(left)),
                          new Array(std::move(right)));
}
<commit_msg>Get rid of unnecessary header<commit_after>// Copyright 2016 Chris Drake
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <memory>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include <boost/optional.hpp>
#include <cryptominisat4/cryptominisat.h>

#include "boolexpr/boolexpr.h"

using namespace boolexpr;

Array::Array()
    : items {}
{}

Array::Array(vector<bx_t> const & items)
    : items {items}
{}

Array::Array(vector<bx_t> const && items)
    : items {items}
{}

Array::Array(std::initializer_list<bx_t> const items)
    : items {items}
{}

Array *
boolexpr::operator~(Array const & self)
{
    size_t n = self.items.size();
    vector<bx_t> items(n);

    for (size_t i = 0; i < n; ++i) {
        items[i] = ~self.items[i];
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator|(Array const & lhs, Array const & rhs)
{
    vector<bx_t> items;

    auto lhs_it = lhs.items.begin();
    auto rhs_it = rhs.items.begin();

    while (lhs_it != lhs.items.end() && rhs_it != rhs.items.end()) {
        items.push_back(*lhs_it++ | *rhs_it++);
    }

    while (lhs_it != lhs.items.end()) {
        items.push_back(*lhs_it++);
    }

    while (rhs_it != rhs.items.end()) {
        items.push_back(*rhs_it++);
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator&(Array const & lhs, Array const & rhs)
{
    vector<bx_t> items;

    auto lhs_it = lhs.items.begin();
    auto rhs_it = rhs.items.begin();

    while (lhs_it != lhs.items.end() && rhs_it != rhs.items.end()) {
        items.push_back(*lhs_it++ & *rhs_it++);
    }

    while (lhs_it != lhs.items.end()) {
        items.push_back(*lhs_it++);
    }

    while (rhs_it != rhs.items.end()) {
        items.push_back(*rhs_it++);
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator^(Array const & lhs, Array const & rhs)
{
    vector<bx_t> items;

    auto lhs_it = lhs.items.begin();
    auto rhs_it = rhs.items.begin();

    while (lhs_it != lhs.items.end() && rhs_it != rhs.items.end()) {
        items.push_back(*lhs_it++ ^ *rhs_it++);
    }

    while (lhs_it != lhs.items.end()) {
        items.push_back(*lhs_it++);
    }

    while (rhs_it != rhs.items.end()) {
        items.push_back(*rhs_it++);
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator+(Array const & lhs, Array const & rhs)
{
    vector<bx_t> items(lhs.items.size() + rhs.items.size());

    size_t cnt = 0;

    for (size_t i = 0; i < lhs.items.size(); ++i) {
        items[cnt++] = lhs.items[i];
    }

    for (size_t i = 0; i < rhs.items.size(); ++i) {
        items[cnt++] = rhs.items[i];
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator*(Array const & lhs, size_t num)
{
    vector<bx_t> items(num * lhs.items.size());

    size_t cnt = 0;

    for (size_t i = 0; i < num; ++i) {
        for (size_t j = 0; j < lhs.items.size(); ++j) {
            items[cnt++] = lhs.items[j];
        }
    }

    return new Array(std::move(items));
}

Array *
boolexpr::operator*(size_t num, Array const & rhs)
{
    vector<bx_t> items(num * rhs.items.size());

    size_t cnt = 0;

    for (size_t i = 0; i < num; ++i) {
        for (size_t j = 0; j < rhs.items.size(); ++j) {
            items[cnt++] = rhs.items[j];
        }
    }

    return new Array(std::move(items));
}

bx_t const &
Array::operator[](size_t index) const
{
    return this->items[index];
}

bx_t &
Array::operator[](size_t index)
{
    return this->items[index];
}

size_t
Array::size() const
{
    return this->items.size();
}

vector<bx_t>::const_iterator
Array::begin() const
{
    return this->items.begin();
}

vector<bx_t>::const_iterator
Array::end() const
{
    return this->items.end();
}

Array *
Array::compose(var2bx_t const & var2bx) const
{
    size_t n = this->items.size();
    vector<bx_t> items(n);

    for (size_t i = 0; i < n; ++i) {
        items[i] = this->items[i]->compose(var2bx);
    }

    return new Array(std::move(items));
}

Array *
Array::restrict_(point_t const & point) const
{
    size_t n = this->items.size();
    vector<bx_t> items(n);

    for (size_t i = 0; i < n; ++i) {
        items[i] = this->items[i]->restrict_(point);
    }

    return new Array(std::move(items));
}

bool
Array::equiv(Array const & other) const
{

    if (this->items.size() != other.items.size()) {
        return false;
    }

    for (size_t i = 0; i < this->items.size(); ++i) {
        if (!this->items[i]->equiv(other.items[i])) {
            return false;
        }
    }

    return true;
}

Array *
Array::zext(size_t num) const
{
    vector<bx_t> items(this->items.size() + num);

    size_t cnt = 0;
    for (size_t i = 0; i < this->items.size(); ++i) {
        items[cnt++] = this->items[i];
    }

    for (size_t i = 0; i < num; ++i) {
        items[cnt++] = zero();
    }

    return new Array(std::move(items));
}

Array *
Array::sext(size_t num) const
{
    vector<bx_t> items(this->items.size() + num);

    size_t cnt = 0;
    for (size_t i = 0; i < this->items.size(); ++i) {
        items[cnt++] = this->items[i];
    }

    auto sign = this->items[this->items.size()-1];
    for (size_t i = 0; i < num; ++i) {
        items[cnt++] = sign;
    }

    return new Array(std::move(items));
}

bx_t
Array::or_reduce() const
{
    return or_(items);
}

bx_t
Array::and_reduce() const
{
    return and_(items);
}

bx_t
Array::xor_reduce() const
{
    return xor_(items);
}

std::pair<Array *, Array *>
Array::lsh(Array const & a) const
{
    auto m = this->items.size();
    auto n = a.items.size();

    assert(m >= n);

    vector<bx_t> left(m);
    vector<bx_t> right(n);

    for (size_t i = 0; i < n; ++i) {
        left[i] = a.items[i];
    }

    for (size_t i = n; i < m; ++i) {
        left[i] = this->items[i-n];
    }

    for (size_t i = 0; i < n; ++i) {
        right[i] = this->items[i+m-n];
    }

    return std::make_pair(new Array(std::move(left)),
                          new Array(std::move(right)));
}

std::pair<Array *, Array *>
Array::rsh(Array const & a) const
{
    auto m = this->items.size();
    auto n = a.items.size();

    assert(m >= n);

    vector<bx_t> left(n);
    vector<bx_t> right(m);

    for (size_t i = 0; i < n; ++i) {
        left[i] = this->items[i];
    }

    for (size_t i = 0; i < (m-n); ++i) {
        right[i] = this->items[i+n];
    }

    for (size_t i = (m-n); i < m; ++i) {
        right[i] = a.items[i-m+n];
    }

    return std::make_pair(new Array(std::move(left)),
                          new Array(std::move(right)));
}

std::pair<Array *, Array *>
Array::arsh(size_t n) const
{
    auto m = this->items.size();

    assert(m >= n);

    vector<bx_t> left(n);
    vector<bx_t> right(m);

    for (size_t i = 0; i < n; ++i) {
        left[i] = this->items[i];
    }

    for (size_t i = 0; i < (m-n); ++i) {
        right[i] = this->items[i+n];
    }

    for (size_t i = (m-n); i < m; ++i) {
        right[i] = this->items[m-1];
    }

    return std::make_pair(new Array(std::move(left)),
                          new Array(std::move(right)));
}
<|endoftext|>