<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "stateseditorview.h"
#include "stateseditorwidget.h"
#include "stateseditormodel.h"
#include <customnotifications.h>
#include <rewritingexception.h>

#include <QPainter>
#include <QTimerEvent>
#include <QMessageBox>
#include <QDebug>
#include <math.h>

#include <nodemetainfo.h>

#include <variantproperty.h>
#include <nodelistproperty.h>

namespace QmlDesigner {

/**
  We always have 'one' current state, where we get updates from (see sceneChanged()). In case
  the current state is the base state, we render the base state + all other states.
  */
StatesEditorView::StatesEditorView(QObject *parent) :
        QmlModelView(parent),
        m_statesEditorModel(new StatesEditorModel(this)),
        m_lastIndex(-1)
{
    Q_ASSERT(m_statesEditorModel);
    // base state
}

StatesEditorWidget *StatesEditorView::widget()
{
    if (m_statesEditorWidget.isNull())
        m_statesEditorWidget = new StatesEditorWidget(this, m_statesEditorModel.data());

    return m_statesEditorWidget.data();
}

void StatesEditorView::removeState(int nodeId)
{
    try {
        if (nodeId > 0 && hasModelNodeForInternalId(nodeId)) {
            ModelNode stateNode(modelNodeForInternalId(nodeId));
            Q_ASSERT(stateNode.metaInfo().isSubclassOf("QtQuick/State", 4, 7));
            NodeListProperty parentProperty = stateNode.parentProperty().toNodeListProperty();

            if (parentProperty.count() <= 1) {
                setCurrentState(baseState());
            } else if (parentProperty.isValid()){
                int index = parentProperty.indexOf(stateNode);
                if (index == 0) {
                    setCurrentState(parentProperty.at(1));
                } else {
                    setCurrentState(parentProperty.at(index - 1));
                }
            }

            stateNode.destroy();
        }
    }  catch (RewritingException &e) {
        QMessageBox::warning(0, "Error", e.description());
    }
}

void StatesEditorView::synchonizeCurrentStateFromWidget()
{
    if (!model())
        return;
    int internalId = m_statesEditorWidget->currentStateInternalId();

    if (internalId > 0 && hasModelNodeForInternalId(internalId)) {
        ModelNode node = modelNodeForInternalId(internalId);
        QmlModelState modelState(node);
        if (modelState.isValid() && modelState != currentState())
            setCurrentState(modelState);
    } else {
        setCurrentState(baseState());
    }
}

void StatesEditorView::createNewState()
{
    if (currentState().isBaseState()) {
        addState();
    } else {
        duplicateCurrentState();
    }
}

void StatesEditorView::addState()
{
    // can happen when root node is e.g. a ListModel
    if (!rootQmlItemNode().isValid())
        return;

    QStringList modelStateNames = rootStateGroup().names();

    QString newStateName;
    int index = 1;
    while (true) {
        newStateName = tr("State%1", "Default name for newly created states").arg(index++);
        if (!modelStateNames.contains(newStateName))
            break;
    }

    try {
        if (rootStateGroup().allStates().count() < 1)
            model()->addImport(Import::createLibraryImport("QtQuick", "1.0"));
        ModelNode newState = rootStateGroup().addState(newStateName);
        setCurrentState(newState);
    }  catch (RewritingException &e) {
        QMessageBox::warning(0, "Error", e.description());
    }
}

void StatesEditorView::resetModel()
{
    if (m_statesEditorModel)
        m_statesEditorModel->reset();

    if (m_statesEditorWidget) {
        if (currentState().isBaseState()) {
            m_statesEditorWidget->setCurrentStateInternalId(currentState().modelNode().internalId());
        } else {
            m_statesEditorWidget->setCurrentStateInternalId(0);
        }
    }
}

void StatesEditorView::duplicateCurrentState()
{
    QmlModelState state = currentState();

    Q_ASSERT(!state.isBaseState());

    QString newName = state.name();

    // Strip out numbers at the end of the string
    QRegExp regEx(QString("[0-9]+$"));
    int numberIndex = newName.indexOf(regEx);
    if ((numberIndex != -1) && (numberIndex+regEx.matchedLength()==newName.length()))
        newName = newName.left(numberIndex);

    int i = 1;
    QStringList stateNames = rootStateGroup().names();
    while (stateNames.contains(newName + QString::number(i)))
        i++;

    QmlModelState newState = state.duplicate(newName + QString::number(i));
    setCurrentState(newState);
}

bool StatesEditorView::validStateName(const QString &name) const
{
    if (name == tr("base state"))
        return false;
    QList<QmlModelState> modelStates = rootStateGroup().allStates();
    foreach (const QmlModelState &state, modelStates) {
        if (state.name() == name)
            return false;
    }
    return true;
}

void StatesEditorView::renameState(int nodeId, const QString &newName)
{
    if (hasModelNodeForInternalId(nodeId)) {
        QmlModelState state(modelNodeForInternalId(nodeId));
        try {
            if (state.isValid() && state.name() != newName) {
                // Jump to base state for the change
                QmlModelState oldState = currentState();
                setCurrentState(baseState());
                state.setName(newName);
                setCurrentState(oldState);
            }
        }  catch (RewritingException &e) {
            QMessageBox::warning(0, "Error", e.description());
        }
    }
}

void StatesEditorView::modelAttached(Model *model)
{
    if (model == QmlModelView::model())
        return;

    Q_ASSERT(model);
    QmlModelView::modelAttached(model);

    if (m_statesEditorWidget)
        m_statesEditorWidget->setNodeInstanceView(nodeInstanceView());

    resetModel();
}

void StatesEditorView::modelAboutToBeDetached(Model *model)
{
    QmlModelView::modelAboutToBeDetached(model);
    resetModel();
}

void StatesEditorView::propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList)
{
    foreach (const AbstractProperty &property, propertyList) {
        if (property.name() == "states" && property.parentModelNode().isRootNode())
            m_statesEditorModel->reset();
    }
}

void StatesEditorView::variantPropertiesChanged(const QList<VariantProperty> &propertyList, PropertyChangeFlags /*propertyChange*/)
{
}

void StatesEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
{
    if (removedNode.hasParentProperty()) {
        const NodeAbstractProperty propertyParent = removedNode.parentProperty();
        if (propertyParent.parentModelNode().isRootNode() && propertyParent.name() == "states") {
            m_lastIndex = propertyParent.indexOf(removedNode);
        }
    }
}

void StatesEditorView::nodeRemoved(const ModelNode & /*removedNode*/, const NodeAbstractProperty &parentProperty, PropertyChangeFlags /*propertyChange*/)
{
    if (parentProperty.isValid() && parentProperty.parentModelNode().isRootNode() && parentProperty.name() == "states") {
        m_statesEditorModel->removeState(m_lastIndex);
        m_lastIndex = -1;
    }
}

void StatesEditorView::nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
{
    if (oldPropertyParent.isValid() && oldPropertyParent.parentModelNode().isRootNode() && oldPropertyParent.name() == "states")
        m_lastIndex = oldPropertyParent.indexOf(node);
}

void StatesEditorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
{
    if (oldPropertyParent.isValid() && oldPropertyParent.parentModelNode().isRootNode() && oldPropertyParent.name() == "states")
        m_statesEditorModel->removeState(m_lastIndex);

    m_lastIndex = -1;

    if (newPropertyParent.isValid() && newPropertyParent.parentModelNode().isRootNode() && newPropertyParent.name() == "states") {
        int index = newPropertyParent.indexOf(node);
        m_statesEditorModel->insertState(index);
    }
}

void StatesEditorView::nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode & /*movedNode*/, int /*oldIndex*/)
{
    if (listProperty.isValid() && listProperty.parentModelNode().isRootNode() && listProperty.name() == "states")
        resetModel();
}

void StatesEditorView::nodeInstancePropertyChanged(const ModelNode &node, const QString &propertyName)
{
    // sets currentState() used in sceneChanged
    QmlModelView::nodeInstancePropertyChanged(node, propertyName);
}

void StatesEditorView::stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState)
{
    if (newQmlModelState.isBaseState()) {
        m_statesEditorWidget->setCurrentStateInternalId(0);
    } else {
        m_statesEditorWidget->setCurrentStateInternalId(newQmlModelState.modelNode().internalId());
    }
    QmlModelView::stateChanged(newQmlModelState, oldQmlModelState);
}

void StatesEditorView::transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName)
{
    QmlModelView::transformChanged(qmlObjectNode, propertyName);
}

void StatesEditorView::parentChanged(const QmlObjectNode &qmlObjectNode)
{
    QmlModelView::parentChanged(qmlObjectNode);
}

void StatesEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName)
{
    QmlModelView::otherPropertyChanged(qmlObjectNode, propertyName);
}

void StatesEditorView::customNotification(const AbstractView * view, const QString & identifier, const QList<ModelNode> & nodeList, const QList<QVariant> &imageList)
{

    if (identifier == "__instance preview image changed__")   {
        int minimumIndex = 10000;
        int maximumIndex = -1;
        foreach(const ModelNode &node, nodeList) {
            if (node.isRootNode()) {
                minimumIndex = qMin(minimumIndex, 0);
                maximumIndex = qMax(maximumIndex, 0);
            } else {
                int index = rootStateGroup().allStates().indexOf(QmlModelState(node)) + 1;
                if (index > 0) {
                    minimumIndex = qMin(minimumIndex, index);
                    maximumIndex = qMax(maximumIndex, index);
                }
            }
        }

        if (maximumIndex >= 0)
            m_statesEditorModel->updateState(minimumIndex, maximumIndex);

    } else {
        QmlModelView::customNotification(view, identifier, nodeList, imageList);
    }
}

void StatesEditorView::scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList)
{

    QmlModelView::scriptFunctionsChanged(node, scriptFunctionList);
}

void StatesEditorView::nodeIdChanged(const ModelNode &/*node*/, const QString &/*newId*/, const QString &/*oldId*/)
{

}

void StatesEditorView::bindingPropertiesChanged(const QList<BindingProperty> &/*propertyList*/, PropertyChangeFlags /*propertyChange*/)
{

}

void StatesEditorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/, const QList<ModelNode> &/*lastSelectedNodeList*/)
{

}

} // namespace QmlDesigner
<commit_msg>QmlDesigner: Fix warning<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** No Commercial Usage
**
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
**
** Alternatively, 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.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**************************************************************************/

#include "stateseditorview.h"
#include "stateseditorwidget.h"
#include "stateseditormodel.h"
#include <customnotifications.h>
#include <rewritingexception.h>

#include <QPainter>
#include <QTimerEvent>
#include <QMessageBox>
#include <QDebug>
#include <math.h>

#include <nodemetainfo.h>

#include <variantproperty.h>
#include <nodelistproperty.h>

namespace QmlDesigner {

/**
  We always have 'one' current state, where we get updates from (see sceneChanged()). In case
  the current state is the base state, we render the base state + all other states.
  */
StatesEditorView::StatesEditorView(QObject *parent) :
        QmlModelView(parent),
        m_statesEditorModel(new StatesEditorModel(this)),
        m_lastIndex(-1)
{
    Q_ASSERT(m_statesEditorModel);
    // base state
}

StatesEditorWidget *StatesEditorView::widget()
{
    if (m_statesEditorWidget.isNull())
        m_statesEditorWidget = new StatesEditorWidget(this, m_statesEditorModel.data());

    return m_statesEditorWidget.data();
}

void StatesEditorView::removeState(int nodeId)
{
    try {
        if (nodeId > 0 && hasModelNodeForInternalId(nodeId)) {
            ModelNode stateNode(modelNodeForInternalId(nodeId));
            Q_ASSERT(stateNode.metaInfo().isSubclassOf("QtQuick/State", 4, 7));
            NodeListProperty parentProperty = stateNode.parentProperty().toNodeListProperty();

            if (parentProperty.count() <= 1) {
                setCurrentState(baseState());
            } else if (parentProperty.isValid()){
                int index = parentProperty.indexOf(stateNode);
                if (index == 0) {
                    setCurrentState(parentProperty.at(1));
                } else {
                    setCurrentState(parentProperty.at(index - 1));
                }
            }

            stateNode.destroy();
        }
    }  catch (RewritingException &e) {
        QMessageBox::warning(0, "Error", e.description());
    }
}

void StatesEditorView::synchonizeCurrentStateFromWidget()
{
    if (!model())
        return;
    int internalId = m_statesEditorWidget->currentStateInternalId();

    if (internalId > 0 && hasModelNodeForInternalId(internalId)) {
        ModelNode node = modelNodeForInternalId(internalId);
        QmlModelState modelState(node);
        if (modelState.isValid() && modelState != currentState())
            setCurrentState(modelState);
    } else {
        setCurrentState(baseState());
    }
}

void StatesEditorView::createNewState()
{
    if (currentState().isBaseState()) {
        addState();
    } else {
        duplicateCurrentState();
    }
}

void StatesEditorView::addState()
{
    // can happen when root node is e.g. a ListModel
    if (!rootQmlItemNode().isValid())
        return;

    QStringList modelStateNames = rootStateGroup().names();

    QString newStateName;
    int index = 1;
    while (true) {
        newStateName = tr("State%1", "Default name for newly created states").arg(index++);
        if (!modelStateNames.contains(newStateName))
            break;
    }

    try {
        if (rootStateGroup().allStates().count() < 1)
            model()->addImport(Import::createLibraryImport("QtQuick", "1.0"));
        ModelNode newState = rootStateGroup().addState(newStateName);
        setCurrentState(newState);
    }  catch (RewritingException &e) {
        QMessageBox::warning(0, "Error", e.description());
    }
}

void StatesEditorView::resetModel()
{
    if (m_statesEditorModel)
        m_statesEditorModel->reset();

    if (m_statesEditorWidget) {
        if (currentState().isBaseState()) {
            m_statesEditorWidget->setCurrentStateInternalId(currentState().modelNode().internalId());
        } else {
            m_statesEditorWidget->setCurrentStateInternalId(0);
        }
    }
}

void StatesEditorView::duplicateCurrentState()
{
    QmlModelState state = currentState();

    Q_ASSERT(!state.isBaseState());

    QString newName = state.name();

    // Strip out numbers at the end of the string
    QRegExp regEx(QString("[0-9]+$"));
    int numberIndex = newName.indexOf(regEx);
    if ((numberIndex != -1) && (numberIndex+regEx.matchedLength()==newName.length()))
        newName = newName.left(numberIndex);

    int i = 1;
    QStringList stateNames = rootStateGroup().names();
    while (stateNames.contains(newName + QString::number(i)))
        i++;

    QmlModelState newState = state.duplicate(newName + QString::number(i));
    setCurrentState(newState);
}

bool StatesEditorView::validStateName(const QString &name) const
{
    if (name == tr("base state"))
        return false;
    QList<QmlModelState> modelStates = rootStateGroup().allStates();
    foreach (const QmlModelState &state, modelStates) {
        if (state.name() == name)
            return false;
    }
    return true;
}

void StatesEditorView::renameState(int nodeId, const QString &newName)
{
    if (hasModelNodeForInternalId(nodeId)) {
        QmlModelState state(modelNodeForInternalId(nodeId));
        try {
            if (state.isValid() && state.name() != newName) {
                // Jump to base state for the change
                QmlModelState oldState = currentState();
                setCurrentState(baseState());
                state.setName(newName);
                setCurrentState(oldState);
            }
        }  catch (RewritingException &e) {
            QMessageBox::warning(0, "Error", e.description());
        }
    }
}

void StatesEditorView::modelAttached(Model *model)
{
    if (model == QmlModelView::model())
        return;

    Q_ASSERT(model);
    QmlModelView::modelAttached(model);

    if (m_statesEditorWidget)
        m_statesEditorWidget->setNodeInstanceView(nodeInstanceView());

    resetModel();
}

void StatesEditorView::modelAboutToBeDetached(Model *model)
{
    QmlModelView::modelAboutToBeDetached(model);
    resetModel();
}

void StatesEditorView::propertiesAboutToBeRemoved(const QList<AbstractProperty> &propertyList)
{
    foreach (const AbstractProperty &property, propertyList) {
        if (property.name() == "states" && property.parentModelNode().isRootNode())
            m_statesEditorModel->reset();
    }
}

void StatesEditorView::variantPropertiesChanged(const QList<VariantProperty> &/*propertyList*/, PropertyChangeFlags /*propertyChange*/)
{
}

void StatesEditorView::nodeAboutToBeRemoved(const ModelNode &removedNode)
{
    if (removedNode.hasParentProperty()) {
        const NodeAbstractProperty propertyParent = removedNode.parentProperty();
        if (propertyParent.parentModelNode().isRootNode() && propertyParent.name() == "states") {
            m_lastIndex = propertyParent.indexOf(removedNode);
        }
    }
}

void StatesEditorView::nodeRemoved(const ModelNode & /*removedNode*/, const NodeAbstractProperty &parentProperty, PropertyChangeFlags /*propertyChange*/)
{
    if (parentProperty.isValid() && parentProperty.parentModelNode().isRootNode() && parentProperty.name() == "states") {
        m_statesEditorModel->removeState(m_lastIndex);
        m_lastIndex = -1;
    }
}

void StatesEditorView::nodeAboutToBeReparented(const ModelNode &node, const NodeAbstractProperty &/*newPropertyParent*/, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
{
    if (oldPropertyParent.isValid() && oldPropertyParent.parentModelNode().isRootNode() && oldPropertyParent.name() == "states")
        m_lastIndex = oldPropertyParent.indexOf(node);
}

void StatesEditorView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags /*propertyChange*/)
{
    if (oldPropertyParent.isValid() && oldPropertyParent.parentModelNode().isRootNode() && oldPropertyParent.name() == "states")
        m_statesEditorModel->removeState(m_lastIndex);

    m_lastIndex = -1;

    if (newPropertyParent.isValid() && newPropertyParent.parentModelNode().isRootNode() && newPropertyParent.name() == "states") {
        int index = newPropertyParent.indexOf(node);
        m_statesEditorModel->insertState(index);
    }
}

void StatesEditorView::nodeOrderChanged(const NodeListProperty &listProperty, const ModelNode & /*movedNode*/, int /*oldIndex*/)
{
    if (listProperty.isValid() && listProperty.parentModelNode().isRootNode() && listProperty.name() == "states")
        resetModel();
}

void StatesEditorView::nodeInstancePropertyChanged(const ModelNode &node, const QString &propertyName)
{
    // sets currentState() used in sceneChanged
    QmlModelView::nodeInstancePropertyChanged(node, propertyName);
}

void StatesEditorView::stateChanged(const QmlModelState &newQmlModelState, const QmlModelState &oldQmlModelState)
{
    if (newQmlModelState.isBaseState()) {
        m_statesEditorWidget->setCurrentStateInternalId(0);
    } else {
        m_statesEditorWidget->setCurrentStateInternalId(newQmlModelState.modelNode().internalId());
    }
    QmlModelView::stateChanged(newQmlModelState, oldQmlModelState);
}

void StatesEditorView::transformChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName)
{
    QmlModelView::transformChanged(qmlObjectNode, propertyName);
}

void StatesEditorView::parentChanged(const QmlObjectNode &qmlObjectNode)
{
    QmlModelView::parentChanged(qmlObjectNode);
}

void StatesEditorView::otherPropertyChanged(const QmlObjectNode &qmlObjectNode, const QString &propertyName)
{
    QmlModelView::otherPropertyChanged(qmlObjectNode, propertyName);
}

void StatesEditorView::customNotification(const AbstractView * view, const QString & identifier, const QList<ModelNode> & nodeList, const QList<QVariant> &imageList)
{

    if (identifier == "__instance preview image changed__")   {
        int minimumIndex = 10000;
        int maximumIndex = -1;
        foreach(const ModelNode &node, nodeList) {
            if (node.isRootNode()) {
                minimumIndex = qMin(minimumIndex, 0);
                maximumIndex = qMax(maximumIndex, 0);
            } else {
                int index = rootStateGroup().allStates().indexOf(QmlModelState(node)) + 1;
                if (index > 0) {
                    minimumIndex = qMin(minimumIndex, index);
                    maximumIndex = qMax(maximumIndex, index);
                }
            }
        }

        if (maximumIndex >= 0)
            m_statesEditorModel->updateState(minimumIndex, maximumIndex);

    } else {
        QmlModelView::customNotification(view, identifier, nodeList, imageList);
    }
}

void StatesEditorView::scriptFunctionsChanged(const ModelNode &node, const QStringList &scriptFunctionList)
{

    QmlModelView::scriptFunctionsChanged(node, scriptFunctionList);
}

void StatesEditorView::nodeIdChanged(const ModelNode &/*node*/, const QString &/*newId*/, const QString &/*oldId*/)
{

}

void StatesEditorView::bindingPropertiesChanged(const QList<BindingProperty> &/*propertyList*/, PropertyChangeFlags /*propertyChange*/)
{

}

void StatesEditorView::selectedNodesChanged(const QList<ModelNode> &/*selectedNodeList*/, const QList<ModelNode> &/*lastSelectedNodeList*/)
{

}

} // namespace QmlDesigner
<|endoftext|>


<commit_before>/*
* Copyright 2013 Christian Loose <christian.loose@hamburg.de>
*
* 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 name of the author may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 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 AUTHOR 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.
*/
#include "discountmarkdownconverter.h"

extern "C" {
#ifdef Q_OS_WIN
#include <Windows.h>
#endif
#include <mkdio.h>
}

#include "markdowndocument.h"
#include "template/htmltemplate.h"

class DiscountMarkdownDocument : public MarkdownDocument
{
public:
	explicit DiscountMarkdownDocument(MMIOT *document_) : discountDocument(document_) {}
	~DiscountMarkdownDocument() { mkd_cleanup(discountDocument); }

	MMIOT *document() const { return discountDocument; }

private:
	MMIOT *discountDocument;
};

DiscountMarkdownConverter::DiscountMarkdownConverter()
{
}

MarkdownDocument *DiscountMarkdownConverter::createDocument(const QString &text, ConverterOptions options)
{
	MMIOT *doc = 0;

	if (text.length() > 0) {
		QString markdownText(text);

		// text has to always end with a line break,
		// otherwise characters are missing in HTML
		if (!markdownText.endsWith('\n')) {
			markdownText.append('\n');
		}

		unsigned long converterOptions = translateConverterOptions(options);

		QByteArray utf8Data = markdownText.toUtf8();
		doc = mkd_string(utf8Data, utf8Data.length(), converterOptions);

		mkd_compile(doc, converterOptions);
	}

	return new DiscountMarkdownDocument(doc);
}

QString DiscountMarkdownConverter::renderAsHtml(MarkdownDocument *document)
{
	QString html;

	if (document) {
		DiscountMarkdownDocument *doc = dynamic_cast<DiscountMarkdownDocument*>(document);

		if (doc && doc->document()) {
			char *out;
			mkd_document(doc->document(), &out);

			html = QString::fromUtf8(out);
		}
	}

	return html;
}

QString DiscountMarkdownConverter::renderAsTableOfContents(MarkdownDocument *document)
{
	QString toc;

	if (document) {
		DiscountMarkdownDocument *doc = dynamic_cast<DiscountMarkdownDocument*>(document);

		if (doc && doc->document()) {
			// generate table of contents
			char *out;
			mkd_toc(doc->document(), &out);

			toc = QString::fromUtf8(out);
		}
	}

	return toc;
}

Template *DiscountMarkdownConverter::templateRenderer() const
{
	static HtmlTemplate htmlTemplate;
	return &htmlTemplate;
}

MarkdownConverter::ConverterOptions DiscountMarkdownConverter::supportedOptions() const
{
	return MarkdownConverter::AutolinkOption |
		   MarkdownConverter::NoStrikethroughOption |
		   MarkdownConverter::NoAlphaListOption |
		   MarkdownConverter::NoDefinitionListOption |
		   MarkdownConverter::NoSmartypantsOption |
		   MarkdownConverter::ExtraFootnoteOption |
		   MarkdownConverter::NoSuperscriptOption;
}

unsigned long DiscountMarkdownConverter::translateConverterOptions(ConverterOptions options) const
{
	unsigned long converterOptions = MKD_TOC | MKD_NOSTYLE;

	// autolink
	if (options.testFlag(MarkdownConverter::AutolinkOption)) {
		converterOptions |= MKD_AUTOLINK;
	}

	// strikethrough
	if (options.testFlag(MarkdownConverter::NoStrikethroughOption)) {
		converterOptions |= MKD_NOSTRIKETHROUGH;
	}

	// alphabetic lists
	if (options.testFlag(MarkdownConverter::NoAlphaListOption)) {
		converterOptions |= MKD_NOALPHALIST;
	}

	// definition lists
	if (options.testFlag(MarkdownConverter::NoDefinitionListOption)) {
		converterOptions |= MKD_NODLIST;
	}

	// SmartyPants
	if (options.testFlag(MarkdownConverter::NoSmartypantsOption)) {
		converterOptions |= MKD_NOPANTS;
	}

	// Footnotes
	if (options.testFlag(MarkdownConverter::ExtraFootnoteOption)) {
		converterOptions |= MKD_EXTRA_FOOTNOTE;
	}

	// Superscript
	if (options.testFlag(MarkdownConverter::NoSuperscriptOption)) {
		converterOptions |= MKD_NOSUPERSCRIPT;
	}

	return converterOptions;
}

<commit_msg>allow compilation with old markdown<commit_after>/*
* Copyright 2013 Christian Loose <christian.loose@hamburg.de>
*
* 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 name of the author may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 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 AUTHOR 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.
*/
#include "discountmarkdownconverter.h"

extern "C" {
#ifdef Q_OS_WIN
#include <Windows.h>
#endif
#include <mkdio.h>
}

#include "markdowndocument.h"
#include "template/htmltemplate.h"

class DiscountMarkdownDocument : public MarkdownDocument
{
public:
	explicit DiscountMarkdownDocument(MMIOT *document_) : discountDocument(document_) {}
	~DiscountMarkdownDocument() { mkd_cleanup(discountDocument); }

	MMIOT *document() const { return discountDocument; }

private:
	MMIOT *discountDocument;
};

DiscountMarkdownConverter::DiscountMarkdownConverter()
{
}

MarkdownDocument *DiscountMarkdownConverter::createDocument(const QString &text, ConverterOptions options)
{
	MMIOT *doc = 0;

	if (text.length() > 0) {
		QString markdownText(text);

		// text has to always end with a line break,
		// otherwise characters are missing in HTML
		if (!markdownText.endsWith('\n')) {
			markdownText.append('\n');
		}

		unsigned long converterOptions = translateConverterOptions(options);

		QByteArray utf8Data = markdownText.toUtf8();
		doc = mkd_string(utf8Data, utf8Data.length(), converterOptions);

		mkd_compile(doc, converterOptions);
	}

	return new DiscountMarkdownDocument(doc);
}

QString DiscountMarkdownConverter::renderAsHtml(MarkdownDocument *document)
{
	QString html;

	if (document) {
		DiscountMarkdownDocument *doc = dynamic_cast<DiscountMarkdownDocument*>(document);

		if (doc && doc->document()) {
			char *out;
			mkd_document(doc->document(), &out);

			html = QString::fromUtf8(out);
		}
	}

	return html;
}

QString DiscountMarkdownConverter::renderAsTableOfContents(MarkdownDocument *document)
{
	QString toc;

	if (document) {
		DiscountMarkdownDocument *doc = dynamic_cast<DiscountMarkdownDocument*>(document);

		if (doc && doc->document()) {
			// generate table of contents
			char *out;
			mkd_toc(doc->document(), &out);

			toc = QString::fromUtf8(out);
		}
	}

	return toc;
}

Template *DiscountMarkdownConverter::templateRenderer() const
{
	static HtmlTemplate htmlTemplate;
	return &htmlTemplate;
}

MarkdownConverter::ConverterOptions DiscountMarkdownConverter::supportedOptions() const
{
	return MarkdownConverter::AutolinkOption |
		   MarkdownConverter::NoStrikethroughOption |
		   MarkdownConverter::NoAlphaListOption |
		   MarkdownConverter::NoDefinitionListOption |
		   MarkdownConverter::NoSmartypantsOption |
		   MarkdownConverter::ExtraFootnoteOption |
		   MarkdownConverter::NoSuperscriptOption;
}

unsigned long DiscountMarkdownConverter::translateConverterOptions(ConverterOptions options) const
{
	unsigned long converterOptions = MKD_TOC;

#ifdef MKD_NOSTYLE
	converterOptions |= MKD_NOSTYLE;
#endif

	// autolink
	if (options.testFlag(MarkdownConverter::AutolinkOption)) {
		converterOptions |= MKD_AUTOLINK;
	}

	// strikethrough
	if (options.testFlag(MarkdownConverter::NoStrikethroughOption)) {
		converterOptions |= MKD_NOSTRIKETHROUGH;
	}

	// alphabetic lists
	if (options.testFlag(MarkdownConverter::NoAlphaListOption)) {
		converterOptions |= MKD_NOALPHALIST;
	}

	// definition lists
	if (options.testFlag(MarkdownConverter::NoDefinitionListOption)) {
		converterOptions |= MKD_NODLIST;
	}

	// SmartyPants
	if (options.testFlag(MarkdownConverter::NoSmartypantsOption)) {
		converterOptions |= MKD_NOPANTS;
	}

	// Footnotes
	if (options.testFlag(MarkdownConverter::ExtraFootnoteOption)) {
		converterOptions |= MKD_EXTRA_FOOTNOTE;
	}

	// Superscript
	if (options.testFlag(MarkdownConverter::NoSuperscriptOption)) {
		converterOptions |= MKD_NOSUPERSCRIPT;
	}

	return converterOptions;
}

<|endoftext|>


<commit_before>#include <functional>

#include "extensions/quic_listeners/quiche/platform/flags_impl.h"

#include "test/test_common/logging.h"

#include "gtest/gtest.h"
#include "quiche/spdy/platform/api/spdy_arraysize.h"
#include "quiche/spdy/platform/api/spdy_bug_tracker.h"
#include "quiche/spdy/platform/api/spdy_containers.h"
#include "quiche/spdy/platform/api/spdy_endianness_util.h"
#include "quiche/spdy/platform/api/spdy_estimate_memory_usage.h"
#include "quiche/spdy/platform/api/spdy_flags.h"
#include "quiche/spdy/platform/api/spdy_logging.h"
#include "quiche/spdy/platform/api/spdy_ptr_util.h"
#include "quiche/spdy/platform/api/spdy_string.h"
#include "quiche/spdy/platform/api/spdy_string_piece.h"
#include "quiche/spdy/platform/api/spdy_test_helpers.h"

// Basic tests to validate functioning of the QUICHE spdy platform
// implementation. For platform APIs in which the implementation is a simple
// typedef/passthrough to a std:: or absl:: construct, the tests are kept
// minimal, and serve primarily to verify the APIs compile and link without
// issue.

namespace Envoy {
namespace Extensions {
namespace QuicListeners {
namespace Quiche {
namespace {

TEST(SpdyPlatformTest, SpdyArraysize) {
  int array[] = {0, 1, 2, 3, 4};
  EXPECT_EQ(5, SPDY_ARRAYSIZE(array));
}

TEST(SpdyPlatformTest, SpdyBugTracker) {
  EXPECT_DEBUG_DEATH(SPDY_BUG << "Here is a bug,", " bug");
  EXPECT_DEBUG_DEATH(SPDY_BUG_IF(true) << "There is a bug,", " bug");
  EXPECT_LOG_NOT_CONTAINS("error", "", SPDY_BUG_IF(false) << "A feature is not a bug.");

  EXPECT_EQ(true, FLAGS_spdy_always_log_bugs_for_tests);
}

TEST(SpdyPlatformTest, SpdyHashMap) {
  spdy::SpdyHashMap<spdy::SpdyString, int> hmap;
  hmap.insert({"foo", 2});
  EXPECT_EQ(2, hmap["foo"]);
}

TEST(SpdyPlatformTest, SpdyHashSet) {
  spdy::SpdyHashSet<spdy::SpdyString, spdy::SpdyHash<spdy::SpdyString>,
                    std::equal_to<spdy::SpdyString>>
      hset({"foo", "bar"});
  EXPECT_EQ(1, hset.count("bar"));
  EXPECT_EQ(0, hset.count("qux"));
}

TEST(SpdyPlatformTest, SpdyEndianness) {
  EXPECT_EQ(0x1234, spdy::SpdyNetToHost16(spdy::SpdyHostToNet16(0x1234)));
  EXPECT_EQ(0x12345678, spdy::SpdyNetToHost32(spdy::SpdyHostToNet32(0x12345678)));
}

TEST(SpdyPlatformTest, SpdyEstimateMemoryUsage) {
  spdy::SpdyString s = "foo";
  // Stubbed out to always return 0.
  EXPECT_EQ(0, spdy::SpdyEstimateMemoryUsage(s));
}

TEST(SpdyPlatformTest, SpdyLog) {
  // SPDY_LOG macros are defined to QUIC_LOG macros, which is tested in
  // QuicPlatformTest. Here we just make sure SPDY_LOG macros compile.
  SPDY_LOG(INFO) << "INFO log may not show up by default.";
  SPDY_LOG(ERROR) << "ERROR log should show up by default.";

  // VLOG is only emitted if INFO is enabled and verbosity level is high enough.
  SPDY_VLOG(1) << "VLOG(1)";

  SPDY_DLOG(INFO) << "DLOG(INFO)";
  SPDY_DLOG(ERROR) << "DLOG(ERROR)";

  SPDY_DLOG_IF(ERROR, true) << "DLOG_IF(ERROR, true)";
  SPDY_DLOG_IF(ERROR, false) << "DLOG_IF(ERROR, false)";

  SPDY_DVLOG(2) << "DVLOG(2)";

  SPDY_DVLOG_IF(3, true) << "DVLOG_IF(3, true)";
  SPDY_DVLOG_IF(4, false) << "DVLOG_IF(4, false)";
}

TEST(SpdyPlatformTest, SpdyMakeUnique) {
  auto p = spdy::SpdyMakeUnique<int>(4);
  EXPECT_EQ(4, *p);
}

TEST(SpdyPlatformTest, SpdyWrapUnique) {
  auto p = spdy::SpdyWrapUnique(new int(6));
  EXPECT_EQ(6, *p);
}

TEST(SpdyPlatformTest, SpdyString) {
  spdy::SpdyString s = "foo";
  EXPECT_EQ('o', s[1]);
}

TEST(SpdyPlatformTest, SpdyStringPiece) {
  spdy::SpdyString s = "bar";
  spdy::SpdyStringPiece sp(s);
  EXPECT_EQ('b', sp[0]);
}

TEST(SpdyPlatformTest, SpdyTestHelpers) {
  auto bug = [](const char* error_message) { SPDY_BUG << error_message; };

  EXPECT_SPDY_BUG(bug("bug one is expected"), "bug one");
  EXPECT_SPDY_BUG(bug("bug two is expected"), "bug two");
}

TEST(SpdyPlatformTest, SpdyFlags) {
  auto& flag_registry = quiche::FlagRegistry::GetInstance();
  flag_registry.ResetFlags();
  EXPECT_FALSE(GetSpdyReloadableFlag(spdy_testonly_default_false));
  EXPECT_FALSE(GetSpdyRestartFlag(spdy_testonly_default_false));

  flag_registry.FindFlag("spdy_reloadable_flag_spdy_testonly_default_false")
      ->SetValueFromString("true");
  EXPECT_TRUE(GetSpdyReloadableFlag(spdy_testonly_default_false));
  EXPECT_FALSE(GetSpdyRestartFlag(spdy_testonly_default_false));

  flag_registry.ResetFlags();
  flag_registry.FindFlag("spdy_restart_flag_spdy_testonly_default_false")
      ->SetValueFromString("yes");
  EXPECT_FALSE(GetSpdyReloadableFlag(spdy_testonly_default_false));
  EXPECT_TRUE(GetSpdyRestartFlag(spdy_testonly_default_false));
}

} // namespace
} // namespace Quiche
} // namespace QuicListeners
} // namespace Extensions
} // namespace Envoy
<commit_msg>Do not use SpdyString wrapper for std::string. (#7854)<commit_after>#include <functional>
#include <string>

#include "extensions/quic_listeners/quiche/platform/flags_impl.h"

#include "test/test_common/logging.h"

#include "gtest/gtest.h"
#include "quiche/spdy/platform/api/spdy_arraysize.h"
#include "quiche/spdy/platform/api/spdy_bug_tracker.h"
#include "quiche/spdy/platform/api/spdy_containers.h"
#include "quiche/spdy/platform/api/spdy_endianness_util.h"
#include "quiche/spdy/platform/api/spdy_estimate_memory_usage.h"
#include "quiche/spdy/platform/api/spdy_flags.h"
#include "quiche/spdy/platform/api/spdy_logging.h"
#include "quiche/spdy/platform/api/spdy_ptr_util.h"
#include "quiche/spdy/platform/api/spdy_string_piece.h"
#include "quiche/spdy/platform/api/spdy_test_helpers.h"

// Basic tests to validate functioning of the QUICHE spdy platform
// implementation. For platform APIs in which the implementation is a simple
// typedef/passthrough to a std:: or absl:: construct, the tests are kept
// minimal, and serve primarily to verify the APIs compile and link without
// issue.

namespace Envoy {
namespace Extensions {
namespace QuicListeners {
namespace Quiche {
namespace {

TEST(SpdyPlatformTest, SpdyArraysize) {
  int array[] = {0, 1, 2, 3, 4};
  EXPECT_EQ(5, SPDY_ARRAYSIZE(array));
}

TEST(SpdyPlatformTest, SpdyBugTracker) {
  EXPECT_DEBUG_DEATH(SPDY_BUG << "Here is a bug,", " bug");
  EXPECT_DEBUG_DEATH(SPDY_BUG_IF(true) << "There is a bug,", " bug");
  EXPECT_LOG_NOT_CONTAINS("error", "", SPDY_BUG_IF(false) << "A feature is not a bug.");

  EXPECT_EQ(true, FLAGS_spdy_always_log_bugs_for_tests);
}

TEST(SpdyPlatformTest, SpdyHashMap) {
  spdy::SpdyHashMap<std::string, int> hmap;
  hmap.insert({"foo", 2});
  EXPECT_EQ(2, hmap["foo"]);
}

TEST(SpdyPlatformTest, SpdyHashSet) {
  spdy::SpdyHashSet<std::string, spdy::SpdyHash<std::string>, std::equal_to<std::string>> hset(
      {"foo", "bar"});
  EXPECT_EQ(1, hset.count("bar"));
  EXPECT_EQ(0, hset.count("qux"));
}

TEST(SpdyPlatformTest, SpdyEndianness) {
  EXPECT_EQ(0x1234, spdy::SpdyNetToHost16(spdy::SpdyHostToNet16(0x1234)));
  EXPECT_EQ(0x12345678, spdy::SpdyNetToHost32(spdy::SpdyHostToNet32(0x12345678)));
}

TEST(SpdyPlatformTest, SpdyEstimateMemoryUsage) {
  std::string s = "foo";
  // Stubbed out to always return 0.
  EXPECT_EQ(0, spdy::SpdyEstimateMemoryUsage(s));
}

TEST(SpdyPlatformTest, SpdyLog) {
  // SPDY_LOG macros are defined to QUIC_LOG macros, which is tested in
  // QuicPlatformTest. Here we just make sure SPDY_LOG macros compile.
  SPDY_LOG(INFO) << "INFO log may not show up by default.";
  SPDY_LOG(ERROR) << "ERROR log should show up by default.";

  // VLOG is only emitted if INFO is enabled and verbosity level is high enough.
  SPDY_VLOG(1) << "VLOG(1)";

  SPDY_DLOG(INFO) << "DLOG(INFO)";
  SPDY_DLOG(ERROR) << "DLOG(ERROR)";

  SPDY_DLOG_IF(ERROR, true) << "DLOG_IF(ERROR, true)";
  SPDY_DLOG_IF(ERROR, false) << "DLOG_IF(ERROR, false)";

  SPDY_DVLOG(2) << "DVLOG(2)";

  SPDY_DVLOG_IF(3, true) << "DVLOG_IF(3, true)";
  SPDY_DVLOG_IF(4, false) << "DVLOG_IF(4, false)";
}

TEST(SpdyPlatformTest, SpdyMakeUnique) {
  auto p = spdy::SpdyMakeUnique<int>(4);
  EXPECT_EQ(4, *p);
}

TEST(SpdyPlatformTest, SpdyWrapUnique) {
  auto p = spdy::SpdyWrapUnique(new int(6));
  EXPECT_EQ(6, *p);
}

TEST(SpdyPlatformTest, SpdyString) {
  std::string s = "foo";
  EXPECT_EQ('o', s[1]);
}

TEST(SpdyPlatformTest, SpdyStringPiece) {
  std::string s = "bar";
  spdy::SpdyStringPiece sp(s);
  EXPECT_EQ('b', sp[0]);
}

TEST(SpdyPlatformTest, SpdyTestHelpers) {
  auto bug = [](const char* error_message) { SPDY_BUG << error_message; };

  EXPECT_SPDY_BUG(bug("bug one is expected"), "bug one");
  EXPECT_SPDY_BUG(bug("bug two is expected"), "bug two");
}

TEST(SpdyPlatformTest, SpdyFlags) {
  auto& flag_registry = quiche::FlagRegistry::GetInstance();
  flag_registry.ResetFlags();
  EXPECT_FALSE(GetSpdyReloadableFlag(spdy_testonly_default_false));
  EXPECT_FALSE(GetSpdyRestartFlag(spdy_testonly_default_false));

  flag_registry.FindFlag("spdy_reloadable_flag_spdy_testonly_default_false")
      ->SetValueFromString("true");
  EXPECT_TRUE(GetSpdyReloadableFlag(spdy_testonly_default_false));
  EXPECT_FALSE(GetSpdyRestartFlag(spdy_testonly_default_false));

  flag_registry.ResetFlags();
  flag_registry.FindFlag("spdy_restart_flag_spdy_testonly_default_false")
      ->SetValueFromString("yes");
  EXPECT_FALSE(GetSpdyReloadableFlag(spdy_testonly_default_false));
  EXPECT_TRUE(GetSpdyRestartFlag(spdy_testonly_default_false));
}

} // namespace
} // namespace Quiche
} // namespace QuicListeners
} // namespace Extensions
} // namespace Envoy
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QStandardPaths>
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickItem>
#include <QDir>
#include <QMenu>
#include <QAction>
#include <QDesktopServices>
#include <QCloseEvent>
#include <QSystemTrayIcon>
#include <QMessageBox>

#include <QtQml/qqml.h>
#include "wqmlfile.h"
#include "wqmlsystem.h"

mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::mainWindow){
    ui->setupUi(this);

    appConfig();
    addTrayIcon();
    addQmlApis();

    addTreeRightClickMenu();
    openWidgetsInFile();
}

mainWindow::~mainWindow()
{
    delete ui;
}

void mainWindow::addQmlApis(){
    qmlRegisterType<wqmlfile>("com.widgetci.file", 1, 0, "WFile");
    qmlRegisterType<wqmlsystem>("com.widgetci.system", 1, 0, "WSystem");
}

void mainWindow::openWidgetsInFile(){
    widgetsDataSettings = new QSettings(appDataDir + "/widgets.ini", QSettings::IniFormat);

    int count = 0;
    for(auto e : widgetsDataSettings->childGroups()){
        widgetsDataSettings->beginGroup(e);
        int wx = widgetsDataSettings->value("x", -1000).toInt();
        int wy = widgetsDataSettings->value("y", -1000).toInt();
        bool visible = widgetsDataSettings->value("visible", false).toBool();
        widgetsDataSettings->endGroup();

        if(visible){
            toggleWidget(e, wx, wy);
            count++;
        }
    }
    if(count == 0) this->show(); // if no widgets visible, show the form.
}

// Toggle widgets
void mainWindow::toggleWidget(QTreeWidgetItem *item, int wx = -1000, int wy = -1000){
    QString wid_filename = item->text(0);

    // If widget not exists. Create one.
    if(!map_widgetList.contains(wid_filename)){

        // Load configs about the widget
        QMap<QString, QVariant> widConf = getWidgetSettings(item->text(0));

        //Check if has spesific coordinates
        if(wx == -1000 || wy == -1000){
            wx = widConf["x"].toInt();
            wy = widConf["y"].toInt();
        }

        // Add the widget
        WWidget *wid = new WWidget(QUrl::fromLocalFile(widgetsDir + "/" + wid_filename + "/main.qml"), wid_filename, wx, wy);
        wid->toggleZPos(widConf["z-pos"].toInt());
        wid->widgetSettings = widgetsDataSettings;

        // Check for errors. (File not found etc...)
        if( wid->status() == QQuickView::Error ){

            QString errorString = "";
            for (int i = 0; i < wid->errors().length(); ++i) {
                errorString.append(wid->errors().at(i).toString());
            }
            errorString.append(tr("\n\nPlease try to fix the error and refresh the list"));

            item->setBackground(0, QBrush(QColor(160,0,0,255)));
            item->setTextColor(0, QColor(180, 180, 180, 255));
            item->setSelected(false);

            QMessageBox::warning(this, tr("An error occured"), errorString, QMessageBox::Ok);
            return;
        }else if(wid->status() == QQuickView::Ready){
            item->setBackground(0, QBrush(QColor(0,0,0,0)));
        }

        map_widgetList.insert(wid->filename, wid);

        item->setIcon(0, ico_toggleon);
        item->setTextColor(0, colorOn);

        // Delete the widget from list when destroyed
        disconnect(wid, &QQuickWindow::destroyed, 0, 0);
        connect(wid, &QQuickWindow::destroyed, [=]{
            if(map_widgetList.contains(wid->filename)){
                if(!CLOSING) saveWidgetSettings(wid->filename); // Save settings before closing the widgets.

                map_widgetList.remove(wid->filename);

                QList<QTreeWidgetItem *> item_lst = obj_widgetList->findItems(wid->filename, Qt::MatchExactly, 0);
                if(item_lst.length() > 0){
                    item_lst[0]->setTextColor(0, colorOff);
                    item_lst[0]->setIcon(0, ico_toggleoff);
                }
            }
        });

    }else if(map_widgetList.contains(wid_filename)){
        delete map_widgetList[wid_filename];
    }
}
void mainWindow::toggleWidget(QString widgetName, int wx = -1000, int wy = -1000){
    QList <QTreeWidgetItem *> items = obj_widgetList->findItems(widgetName, Qt::MatchExactly, 0);
    if(items.length() > 0){
        toggleWidget(items[0], wx, wy);
    }
}

QMap<QString, QVariant> mainWindow::getWidgetSettings(QString widgetname){
    QMap<QString, QVariant> mapTmp;

    widgetsDataSettings->beginGroup(widgetname);
    mapTmp["x"] = widgetsDataSettings->value("x", -1000);
    mapTmp["y"] = widgetsDataSettings->value("y", -1000);
    mapTmp["visible"] = widgetsDataSettings->value("visible", false);
    mapTmp["z-pos"] = widgetsDataSettings->value("z-pos", 0);
    mapTmp["lock"] = widgetsDataSettings->value("lock", false);
    widgetsDataSettings->endGroup();

    return mapTmp;
}

void mainWindow::saveWidgetSettings(QString widgetname){
    widgetsDataSettings->beginGroup(widgetname);
    widgetsDataSettings->setValue("x", map_widgetList[widgetname]->x());
    widgetsDataSettings->setValue("y", map_widgetList[widgetname]->y());
    widgetsDataSettings->setValue("visible", map_widgetList[widgetname]->isVisible());
    widgetsDataSettings->setValue("z-pos", map_widgetList[widgetname]->z_pos);
    widgetsDataSettings->endGroup();
    widgetsDataSettings->sync();
}

void mainWindow::updateWidgetList(QTreeWidget* widgetList_obj){
    QMap<QString, WWidget *> tmpWidgetsMap(map_widgetList);
    widgetList_obj->clear();

    QDir dir(widgetsDir);
    QStringList folderList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

    // Close all widgets (to open just available ones later)
    for(QString e : map_widgetList.keys()){
        delete map_widgetList.value(e);
    }

    // Add folders one by one
    for(int i=0; i<folderList.length(); i++){
        QString folder = folderList.at(i);

        QTreeWidgetItem* item = new QTreeWidgetItem(widgetList_obj);
        item->setText(0, folder);
        item->setIcon(0, ico_toggleoff);

        if(tmpWidgetsMap.contains(folder)){
            toggleWidget(folder);
            //item->setIcon(0, ico_toggleon);
        }
    }

    // Enable|Disable widgets by double clicking on themauto
    disconnect(widgetList_obj, &QTreeWidget::itemActivated, 0, 0); // prevent multiple connections & runs
    connect(widgetList_obj, &QTreeWidget::itemActivated, [=](QTreeWidgetItem* item) {
        toggleWidget(item);
    });
}

void mainWindow::addTreeRightClickMenu(){
    // Initialize the variables
    ico_toggleoff = QIcon(":/img/toggleoff.png");
    ico_toggleon = QIcon(":/img/toggleon.png");
    colorOn = QColor(0, 230, 0, 255);
    colorOff = QColor(255, 255, 255, 255);

    // QTreeWidget list object from ui:
    obj_widgetList = ui->obj_widgetList;

    // Update & Refresh the widgets
    updateWidgetList(obj_widgetList);

    // Right Click Menu
    obj_widgetList->setContextMenuPolicy(Qt::CustomContextMenu);
    menu_wlRightClick = new QMenu(this);

    // Right Click Menu Actions
    QAction* act_wlrc_ShowHide = new QAction(tr("Show"), this);
    connect(act_wlrc_ShowHide, &QAction::triggered, [=]{
        // Show/Hide Action
        toggleWidget(obj_widgetList->currentItem());
    });
    QAction* act_wlrc_Edit = new QAction(tr("Edit"), this);
    connect(act_wlrc_Edit, &QAction::triggered, [=]{
        // Edit the widget file with default editor
        QDesktopServices::openUrl(QUrl::fromLocalFile(widgetsDir + "/" + obj_widgetList->currentItem()->text(0) + "/main.qml"));
    });
    QAction* act_wlrc_Reload = new QAction(tr("Reload"), this);
    connect(act_wlrc_Reload, &QAction::triggered, [=]{
        // Reload the widget
        if(map_widgetList.contains(obj_widgetList->currentItem()->text(0)))
            map_widgetList.value(obj_widgetList->currentItem()->text(0))->reload();
    });
    QAction* act_wlrc_RefreshTheList = new QAction(tr("Refresh the list"), this);
    connect(act_wlrc_RefreshTheList, &QAction::triggered, [=]{
        // Refresh all the list.
        updateWidgetList(obj_widgetList);
    });
    QAction* act_wlrc_Delete = new QAction(tr("Remove"), this);
    connect(act_wlrc_Delete, &QAction::triggered, [=]{
        if(map_widgetList.contains(obj_widgetList->currentItem()->text(0)))
            toggleWidget(obj_widgetList->currentItem()->text(0));
        delete obj_widgetList->currentItem();
        obj_widgetList->clearSelection();
    });
    QAction* act_wlrc_DeleteDisk = new QAction(tr("Delete From Disk..."), this);
    connect(act_wlrc_DeleteDisk, &QAction::triggered, [=]{
        int answer = QMessageBox::warning(this, tr("Warning"), tr("The '%1' folder will be deleted from disk.\n\nAre you sure?").arg(obj_widgetList->currentItem()->text(0)), QMessageBox::Cancel | QMessageBox::Ok);
        if(answer == QMessageBox::Ok){
            QDir folder(widgetsDir + "/" + obj_widgetList->currentItem()->text(0));
            if(folder.removeRecursively()){
                QMessageBox::information(this, tr("Information"), tr("The folder has been deleted successfully."), QMessageBox::Ok);
                if(map_widgetList.contains(obj_widgetList->currentItem()->text(0))){
                    toggleWidget(obj_widgetList->currentItem()->text(0));
                    updateWidgetList(obj_widgetList);
                }

            }else{
                QMessageBox::critical(this, tr("Information"), tr("The folder couldn't be removed.\nCheck the folder and the files may be using by another program."), QMessageBox::Ok);
            }

        }
    });

    // Add Actions to the QTreeWidget's Right Click Menu
    menu_wlRightClick->addAction(act_wlrc_ShowHide);
    menu_wlRightClick->addSeparator();
    menu_wlRightClick->addAction(act_wlrc_Reload);
    menu_wlRightClick->addAction(act_wlrc_Edit);
    menu_wlRightClick->addAction(act_wlrc_RefreshTheList);
    menu_wlRightClick->addSeparator();
    menu_wlRightClick->addAction(act_wlrc_Delete);
    menu_wlRightClick->addAction(act_wlrc_DeleteDisk);
    connect(obj_widgetList, &QTreeWidget::customContextMenuRequested, [=](const QPoint & pos) {
        QPoint pt(pos);
        pt.setX(pt.x()+2);
        pt.setY(pt.y()+22);

        QTreeWidgetItem *item = obj_widgetList->currentItem();
        QString wid_filename = item->text(0);
        if(!map_widgetList.contains(wid_filename)){
            act_wlrc_ShowHide->setText(tr("Show"));
            act_wlrc_Reload->setEnabled(false);
        }else if(map_widgetList.contains(wid_filename)){
            act_wlrc_ShowHide->setText(tr("Hide"));
            act_wlrc_Reload->setEnabled(true);
        }

        menu_wlRightClick->exec( obj_widgetList->mapToGlobal(pt) );
    });
}

void mainWindow::addActionsToTray(){
    // Create Menu & Items
    trayMenu = new QMenu(this);
    QAction* openManager = new QAction(tr("Open Manager..."), this);
    QAction* reloadAll = new QAction(tr("Reload All"), this);
    QAction* quit = new QAction(tr("Quit"), this);

    trayMenu->addAction(openManager);
    trayMenu->addAction(reloadAll);
    trayMenu->addSeparator();
    trayMenu->addAction(quit);

    // Connect
    connect(openManager, &QAction::triggered, [=]{
        this->setVisible(true);
        this->raise();
        QApplication::setActiveWindow(this);
    });
    connect(reloadAll, &QAction::triggered, [=]{
        for(auto e : map_widgetList.keys()){
          map_widgetList.value(e)->reload();
        }
    });
    connect(quit, &QAction::triggered, [=]{
        onAppQuit();
    });
}

void mainWindow::addTrayIcon(){
    // Add actions
    addActionsToTray();

    // Set the app icon
    appIcon = new QIcon(":/img/icon.png");
    setWindowIcon(*appIcon);

    // Set the tray
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayMenu);
    trayIcon->setIcon(*appIcon);
    trayIcon->show();
    connect(trayIcon, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason){
        if(reason == QSystemTrayIcon::DoubleClick){
            this->setVisible(true);
            this->raise();
            QApplication::setActiveWindow(this);
        }
    });

}

void mainWindow::appConfig(){
    // Set directory variables.
    appDataDir = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0];
    widgetsDir = appDataDir + "/widgets";

    // Create the directory if not exists.
    QDir dir(widgetsDir);
    if(!dir.exists()){
        QDir localdir(":/widgets/defaultwidgets/");
        QStringList folderList = localdir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

        // Copy the local folders one by one
        QFile file;
        for(int i=0; i<folderList.length(); i++){
            QString folder = folderList.at(i);

            //qDebug() << localdir.path() + folder << widgetsDir + "/" + folder;
            dir.mkpath(widgetsDir + "/" + folder);

            // Copy the files inside folder
            QDir filedir(localdir.path() + "/" + folder);
            QStringList filelist = filedir.entryList(QDir::Files | QDir::NoDotAndDotDot);
            for (int a = 0; a < filelist.length(); ++a) {
                file.copy(localdir.path() + "/" + folder + "/" + filelist.at(a), widgetsDir + "/" + folder + "/" + filelist.at(a));
            }
        }
    }
}

void mainWindow::on_obj_showFolderBtn_clicked(){
    QDesktopServices::openUrl(widgetsDir);
}

void mainWindow::on_obj_refreshWidgetListBtn_clicked(){
    updateWidgetList(ui->obj_widgetList);
}

// Before the app quit
void mainWindow::onAppQuit(){
    CLOSING = true;

    // Close the widgets too.
    for(auto e : map_widgetList.keys()){
        // Save widget configs.
        saveWidgetSettings(e);

        // Destroy them.
        delete map_widgetList.value(e);
    }
    QApplication::quit();
}

// Window Close Event
void mainWindow::closeEvent(QCloseEvent *event){
    event->ignore();
    this->setVisible(false);
}
<commit_msg>[FIXED] ReadOnly copied widget files at first opening. Now they are writeable.<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QStandardPaths>
#include <QtQuick/QQuickView>
#include <QtQuick/QQuickItem>
#include <QDir>
#include <QMenu>
#include <QAction>
#include <QDesktopServices>
#include <QCloseEvent>
#include <QSystemTrayIcon>
#include <QMessageBox>

#include <QtQml/qqml.h>
#include "wqmlfile.h"
#include "wqmlsystem.h"

mainWindow::mainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::mainWindow){
    ui->setupUi(this);

    appConfig();
    addTrayIcon();
    addQmlApis();

    addTreeRightClickMenu();
    openWidgetsInFile();
}

mainWindow::~mainWindow()
{
    delete ui;
}

void mainWindow::addQmlApis(){
    qmlRegisterType<wqmlfile>("com.widgetci.file", 1, 0, "WFile");
    qmlRegisterType<wqmlsystem>("com.widgetci.system", 1, 0, "WSystem");
}

void mainWindow::openWidgetsInFile(){
    widgetsDataSettings = new QSettings(appDataDir + "/widgets.ini", QSettings::IniFormat);

    int count = 0;
    for(auto e : widgetsDataSettings->childGroups()){
        widgetsDataSettings->beginGroup(e);
        int wx = widgetsDataSettings->value("x", -1000).toInt();
        int wy = widgetsDataSettings->value("y", -1000).toInt();
        bool visible = widgetsDataSettings->value("visible", false).toBool();
        widgetsDataSettings->endGroup();

        if(visible){
            toggleWidget(e, wx, wy);
            count++;
        }
    }
    if(count == 0) this->show(); // if no widgets visible, show the form.
}

// Toggle widgets
void mainWindow::toggleWidget(QTreeWidgetItem *item, int wx = -1000, int wy = -1000){
    QString wid_filename = item->text(0);

    // If widget not exists. Create one.
    if(!map_widgetList.contains(wid_filename)){

        // Load configs about the widget
        QMap<QString, QVariant> widConf = getWidgetSettings(item->text(0));

        //Check if has spesific coordinates
        if(wx == -1000 || wy == -1000){
            wx = widConf["x"].toInt();
            wy = widConf["y"].toInt();
        }

        // Add the widget
        WWidget *wid = new WWidget(QUrl::fromLocalFile(widgetsDir + "/" + wid_filename + "/main.qml"), wid_filename, wx, wy);
        wid->toggleZPos(widConf["z-pos"].toInt());
        wid->widgetSettings = widgetsDataSettings;

        // Check for errors. (File not found etc...)
        if( wid->status() == QQuickView::Error ){

            QString errorString = "";
            for (int i = 0; i < wid->errors().length(); ++i) {
                errorString.append(wid->errors().at(i).toString());
            }
            errorString.append(tr("\n\nPlease try to fix the error and refresh the list"));

            item->setBackground(0, QBrush(QColor(160,0,0,255)));
            item->setTextColor(0, QColor(180, 180, 180, 255));
            item->setSelected(false);

            QMessageBox::warning(this, tr("An error occured"), errorString, QMessageBox::Ok);
            return;
        }else if(wid->status() == QQuickView::Ready){
            item->setBackground(0, QBrush(QColor(0,0,0,0)));
        }

        map_widgetList.insert(wid->filename, wid);

        item->setIcon(0, ico_toggleon);
        item->setTextColor(0, colorOn);

        // Delete the widget from list when destroyed
        disconnect(wid, &QQuickWindow::destroyed, 0, 0);
        connect(wid, &QQuickWindow::destroyed, [=]{
            if(map_widgetList.contains(wid->filename)){
                if(!CLOSING) saveWidgetSettings(wid->filename); // Save settings before closing the widgets.

                map_widgetList.remove(wid->filename);

                QList<QTreeWidgetItem *> item_lst = obj_widgetList->findItems(wid->filename, Qt::MatchExactly, 0);
                if(item_lst.length() > 0){
                    item_lst[0]->setTextColor(0, colorOff);
                    item_lst[0]->setIcon(0, ico_toggleoff);
                }
            }
        });

    }else if(map_widgetList.contains(wid_filename)){
        delete map_widgetList[wid_filename];
    }
}
void mainWindow::toggleWidget(QString widgetName, int wx = -1000, int wy = -1000){
    QList <QTreeWidgetItem *> items = obj_widgetList->findItems(widgetName, Qt::MatchExactly, 0);
    if(items.length() > 0){
        toggleWidget(items[0], wx, wy);
    }
}

QMap<QString, QVariant> mainWindow::getWidgetSettings(QString widgetname){
    QMap<QString, QVariant> mapTmp;

    widgetsDataSettings->beginGroup(widgetname);
    mapTmp["x"] = widgetsDataSettings->value("x", -1000);
    mapTmp["y"] = widgetsDataSettings->value("y", -1000);
    mapTmp["visible"] = widgetsDataSettings->value("visible", false);
    mapTmp["z-pos"] = widgetsDataSettings->value("z-pos", 0);
    mapTmp["lock"] = widgetsDataSettings->value("lock", false);
    widgetsDataSettings->endGroup();

    return mapTmp;
}

void mainWindow::saveWidgetSettings(QString widgetname){
    widgetsDataSettings->beginGroup(widgetname);
    widgetsDataSettings->setValue("x", map_widgetList[widgetname]->x());
    widgetsDataSettings->setValue("y", map_widgetList[widgetname]->y());
    widgetsDataSettings->setValue("visible", map_widgetList[widgetname]->isVisible());
    widgetsDataSettings->setValue("z-pos", map_widgetList[widgetname]->z_pos);
    widgetsDataSettings->endGroup();
    widgetsDataSettings->sync();
}

void mainWindow::updateWidgetList(QTreeWidget* widgetList_obj){
    QMap<QString, WWidget *> tmpWidgetsMap(map_widgetList);
    widgetList_obj->clear();

    QDir dir(widgetsDir);
    QStringList folderList = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

    // Close all widgets (to open just available ones later)
    for(QString e : map_widgetList.keys()){
        delete map_widgetList.value(e);
    }

    // Add folders one by one
    for(int i=0; i<folderList.length(); i++){
        QString folder = folderList.at(i);

        QTreeWidgetItem* item = new QTreeWidgetItem(widgetList_obj);
        item->setText(0, folder);
        item->setIcon(0, ico_toggleoff);

        if(tmpWidgetsMap.contains(folder)){
            toggleWidget(folder);
            //item->setIcon(0, ico_toggleon);
        }
    }

    // Enable|Disable widgets by double clicking on themauto
    disconnect(widgetList_obj, &QTreeWidget::itemActivated, 0, 0); // prevent multiple connections & runs
    connect(widgetList_obj, &QTreeWidget::itemActivated, [=](QTreeWidgetItem* item) {
        toggleWidget(item);
    });
}

void mainWindow::addTreeRightClickMenu(){
    // Initialize the variables
    ico_toggleoff = QIcon(":/img/toggleoff.png");
    ico_toggleon = QIcon(":/img/toggleon.png");
    colorOn = QColor(0, 230, 0, 255);
    colorOff = QColor(255, 255, 255, 255);

    // QTreeWidget list object from ui:
    obj_widgetList = ui->obj_widgetList;

    // Update & Refresh the widgets
    updateWidgetList(obj_widgetList);

    // Right Click Menu
    obj_widgetList->setContextMenuPolicy(Qt::CustomContextMenu);
    menu_wlRightClick = new QMenu(this);

    // Right Click Menu Actions
    QAction* act_wlrc_ShowHide = new QAction(tr("Show"), this);
    connect(act_wlrc_ShowHide, &QAction::triggered, [=]{
        // Show/Hide Action
        toggleWidget(obj_widgetList->currentItem());
    });
    QAction* act_wlrc_Edit = new QAction(tr("Edit"), this);
    connect(act_wlrc_Edit, &QAction::triggered, [=]{
        // Edit the widget file with default editor
        QDesktopServices::openUrl(QUrl::fromLocalFile(widgetsDir + "/" + obj_widgetList->currentItem()->text(0) + "/main.qml"));
    });
    QAction* act_wlrc_Reload = new QAction(tr("Reload"), this);
    connect(act_wlrc_Reload, &QAction::triggered, [=]{
        // Reload the widget
        if(map_widgetList.contains(obj_widgetList->currentItem()->text(0)))
            map_widgetList.value(obj_widgetList->currentItem()->text(0))->reload();
    });
    QAction* act_wlrc_RefreshTheList = new QAction(tr("Refresh the list"), this);
    connect(act_wlrc_RefreshTheList, &QAction::triggered, [=]{
        // Refresh all the list.
        updateWidgetList(obj_widgetList);
    });
    QAction* act_wlrc_Delete = new QAction(tr("Remove"), this);
    connect(act_wlrc_Delete, &QAction::triggered, [=]{
        if(map_widgetList.contains(obj_widgetList->currentItem()->text(0)))
            toggleWidget(obj_widgetList->currentItem()->text(0));
        delete obj_widgetList->currentItem();
        obj_widgetList->clearSelection();
    });
    QAction* act_wlrc_DeleteDisk = new QAction(tr("Delete From Disk..."), this);
    connect(act_wlrc_DeleteDisk, &QAction::triggered, [=]{
        int answer = QMessageBox::warning(this, tr("Warning"), tr("The '%1' folder will be deleted from disk.\n\nAre you sure?").arg(obj_widgetList->currentItem()->text(0)), QMessageBox::Cancel | QMessageBox::Ok);
        if(answer == QMessageBox::Ok){
            QDir folder(widgetsDir + "/" + obj_widgetList->currentItem()->text(0));
            if(folder.removeRecursively()){
                QMessageBox::information(this, tr("Information"), tr("The folder has been deleted successfully."), QMessageBox::Ok);
                if(map_widgetList.contains(obj_widgetList->currentItem()->text(0))){
                    toggleWidget(obj_widgetList->currentItem()->text(0));
                    updateWidgetList(obj_widgetList);
                }

            }else{
                QMessageBox::critical(this, tr("Information"), tr("The folder couldn't be removed.\nCheck the folder and the files may be using by another program."), QMessageBox::Ok);
            }

        }
    });

    // Add Actions to the QTreeWidget's Right Click Menu
    menu_wlRightClick->addAction(act_wlrc_ShowHide);
    menu_wlRightClick->addSeparator();
    menu_wlRightClick->addAction(act_wlrc_Reload);
    menu_wlRightClick->addAction(act_wlrc_Edit);
    menu_wlRightClick->addAction(act_wlrc_RefreshTheList);
    menu_wlRightClick->addSeparator();
    menu_wlRightClick->addAction(act_wlrc_Delete);
    menu_wlRightClick->addAction(act_wlrc_DeleteDisk);
    connect(obj_widgetList, &QTreeWidget::customContextMenuRequested, [=](const QPoint & pos) {
        QPoint pt(pos);
        pt.setX(pt.x()+2);
        pt.setY(pt.y()+22);

        QTreeWidgetItem *item = obj_widgetList->currentItem();
        QString wid_filename = item->text(0);
        if(!map_widgetList.contains(wid_filename)){
            act_wlrc_ShowHide->setText(tr("Show"));
            act_wlrc_Reload->setEnabled(false);
        }else if(map_widgetList.contains(wid_filename)){
            act_wlrc_ShowHide->setText(tr("Hide"));
            act_wlrc_Reload->setEnabled(true);
        }

        menu_wlRightClick->exec( obj_widgetList->mapToGlobal(pt) );
    });
}

void mainWindow::addActionsToTray(){
    // Create Menu & Items
    trayMenu = new QMenu(this);
    QAction* openManager = new QAction(tr("Open Manager..."), this);
    QAction* reloadAll = new QAction(tr("Reload All"), this);
    QAction* quit = new QAction(tr("Quit"), this);

    trayMenu->addAction(openManager);
    trayMenu->addAction(reloadAll);
    trayMenu->addSeparator();
    trayMenu->addAction(quit);

    // Connect
    connect(openManager, &QAction::triggered, [=]{
        this->setVisible(true);
        this->raise();
        QApplication::setActiveWindow(this);
    });
    connect(reloadAll, &QAction::triggered, [=]{
        for(auto e : map_widgetList.keys()){
          map_widgetList.value(e)->reload();
        }
    });
    connect(quit, &QAction::triggered, [=]{
        onAppQuit();
    });
}

void mainWindow::addTrayIcon(){
    // Add actions
    addActionsToTray();

    // Set the app icon
    appIcon = new QIcon(":/img/icon.png");
    setWindowIcon(*appIcon);

    // Set the tray
    trayIcon = new QSystemTrayIcon(this);
    trayIcon->setContextMenu(trayMenu);
    trayIcon->setIcon(*appIcon);
    trayIcon->show();
    connect(trayIcon, &QSystemTrayIcon::activated, [=](QSystemTrayIcon::ActivationReason reason){
        if(reason == QSystemTrayIcon::DoubleClick){
            this->setVisible(true);
            this->raise();
            QApplication::setActiveWindow(this);
        }
    });

}

void mainWindow::appConfig(){
    // Set directory variables.
    appDataDir = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation)[0];
    widgetsDir = appDataDir + "/widgets";

    // Create the directory if not exists.
    QDir dir(widgetsDir);
    if(!dir.exists()){
        QDir localdir(":/widgets/defaultwidgets/");
        QStringList folderList = localdir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);

        // Copy the local folders one by one
        QFile file;
        for(int i=0; i<folderList.length(); i++){
            QString folder = folderList.at(i);

            //qDebug() << localdir.path() + folder << widgetsDir + "/" + folder;
            dir.mkpath(widgetsDir + "/" + folder);

            // Copy the files inside folder
            QDir filedir(localdir.path() + "/" + folder);
            QStringList filelist = filedir.entryList(QDir::Files | QDir::NoDotAndDotDot);
            for (int a = 0; a < filelist.length(); ++a) {

                QString fileSrc = localdir.path() + "/" + folder + "/" + filelist.at(a);
                QString fileTarget = widgetsDir + "/" + folder + "/" + filelist.at(a);

                // Copy the file
                file.copy( fileSrc , fileTarget );
                // Set permissions Readable and Writeable.
                file.setPermissions(fileTarget, QFileDevice::ReadOther | QFileDevice::WriteOther | QFileDevice::ExeGroup);
            }
        }
    }
}

void mainWindow::on_obj_showFolderBtn_clicked(){
    QDesktopServices::openUrl(widgetsDir);
}

void mainWindow::on_obj_refreshWidgetListBtn_clicked(){
    updateWidgetList(ui->obj_widgetList);
}

// Before the app quit
void mainWindow::onAppQuit(){
    CLOSING = true;

    // Close the widgets too.
    for(auto e : map_widgetList.keys()){
        // Save widget configs.
        saveWidgetSettings(e);

        // Destroy them.
        delete map_widgetList.value(e);
    }
    QApplication::quit();
}

// Window Close Event
void mainWindow::closeEvent(QCloseEvent *event){
    event->ignore();
    this->setVisible(false);
}
<|endoftext|>


<commit_before>// wingtrack.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "FlyCapture2.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <opencv2/gpu/gpu.hpp>

using namespace FlyCapture2;
using namespace cv;
using namespace cv::gpu;

#define USEGPU 1

void PrintBuildInfo()
{
	FC2Version fc2Version;
	Utilities::GetLibraryVersion(&fc2Version);
	char version[128];
	sprintf_s(
		version,
		"FlyCapture2 library version: %d.%d.%d.%d\n",
		fc2Version.major, fc2Version.minor, fc2Version.type, fc2Version.build);

	printf("%s", version);

	char timeStamp[512];
	sprintf_s(timeStamp, "Application build date: %s %s\n\n", __DATE__, __TIME__);

	printf("%s", timeStamp);
}

void PrintCameraInfo(CameraInfo* pCamInfo)
{
	printf(
		"\n*** CAMERA INFORMATION ***\n"
		"Serial number - %u\n"
		"Camera model - %s\n"
		"Camera vendor - %s\n"
		"Sensor - %s\n"
		"Resolution - %s\n"
		"Firmware version - %s\n"
		"Firmware build time - %s\n\n",
		pCamInfo->serialNumber,
		pCamInfo->modelName,
		pCamInfo->vendorName,
		pCamInfo->sensorInfo,
		pCamInfo->sensorResolution,
		pCamInfo->firmwareVersion,
		pCamInfo->firmwareBuildTime);
}

void PrintFormat7Capabilities(Format7Info fmt7Info)
{
	printf(
		"Max image pixels: (%u, %u)\n"
		"Image Unit size: (%u, %u)\n"
		"Offset Unit size: (%u, %u)\n"
		"Pixel format bitfield: 0x%08x\n",
		fmt7Info.maxWidth,
		fmt7Info.maxHeight,
		fmt7Info.imageHStepSize,
		fmt7Info.imageVStepSize,
		fmt7Info.offsetHStepSize,
		fmt7Info.offsetVStepSize,
		fmt7Info.pixelFormatBitField);
}

void PrintError(Error error)
{
	error.PrintErrorTrace();
}

int _tmain(int argc, _TCHAR* argv[])
{

	const Mode k_fmt7Mode = MODE_0;
	const PixelFormat k_fmt7PixFmt = PIXEL_FORMAT_RAW8;

	Error error;

	BusManager busMgr;
	unsigned int numCameras;
	error = busMgr.GetNumOfCameras(&numCameras);
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	printf("Number of cameras detected: %u\n", numCameras);

	if (numCameras < 1)
	{
		printf("Insufficient number of cameras... exiting\n");
		return -1;
	}

	PGRGuid guid;
	error = busMgr.GetCameraFromIndex(0, &guid);
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	Camera cam;

	// Connect to a camera
	error = cam.Connect(&guid);
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	// Get the camera information
	CameraInfo camInfo;
	error = cam.GetCameraInfo(&camInfo);
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	PrintCameraInfo(&camInfo);

	// Query for available Format 7 modes
	Format7Info fmt7Info;
	bool supported;
	fmt7Info.mode = k_fmt7Mode;
	error = cam.GetFormat7Info(&fmt7Info, &supported);
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	PrintFormat7Capabilities(fmt7Info);

	if ((k_fmt7PixFmt & fmt7Info.pixelFormatBitField) == 0)
	{
		// Pixel format not supported!
		printf("Pixel format is not supported\n");
		return -1;
	}

	Format7ImageSettings fmt7ImageSettings;
	fmt7ImageSettings.mode = k_fmt7Mode;
	fmt7ImageSettings.offsetX = 0;
	fmt7ImageSettings.offsetY = 0;
	fmt7ImageSettings.width = fmt7Info.maxWidth;
	fmt7ImageSettings.height = fmt7Info.maxHeight;
	fmt7ImageSettings.pixelFormat = k_fmt7PixFmt;

	bool valid;
	Format7PacketInfo fmt7PacketInfo;

	// Validate the settings to make sure that they are valid
	error = cam.ValidateFormat7Settings(
		&fmt7ImageSettings,
		&valid,
		&fmt7PacketInfo);
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	if (!valid)
	{
		// Settings are not valid
		printf("Format7 settings are not valid\n");
		return -1;
	}

	// Set the settings to the camera
	error = cam.SetFormat7Configuration(
		&fmt7ImageSettings,
		fmt7PacketInfo.recommendedBytesPerPacket);
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	// Start capturing images
	error = cam.StartCapture();
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	// Retrieve frame rate property
	Property frmRate;
	frmRate.type = FRAME_RATE;
	error = cam.GetProperty(&frmRate);
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	printf("Frame rate is %3.2f fps\n", frmRate.absValue);

	Image rawImage;

	BackgroundSubtractorMOG mog_cpu;
	MOG_GPU mog_gpu;

	Mat fgmask; //fg mask generated by MOG method
	GpuMat d_frame, d_fgmask;

	for (int imageCount = 0; ; imageCount++)
	{
		// Retrieve an image
		error = cam.RetrieveBuffer(&rawImage);
		if (error != PGRERROR_OK)
		{
			PrintError(error);
			continue;
		}

		// Create a converted image
		Image convertedImage;

		// Convert the raw image
		error = rawImage.Convert(PIXEL_FORMAT_MONO8, &convertedImage);
		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		// convert to OpenCV Mat
		unsigned int rowBytes = (double)convertedImage.GetReceivedDataSize() / (double)convertedImage.GetRows();
		Mat frame = Mat(convertedImage.GetRows(), convertedImage.GetCols(), CV_8UC1, convertedImage.GetData(), rowBytes);

		if (USEGPU)
		{
			d_frame.upload(frame);
			mog_gpu(d_frame, d_fgmask, 0.01f);
			d_fgmask.download(fgmask);
		}
        else
            mog_cpu(frame, fgmask, 0.01);

		imshow("raw image", frame);
		imshow("FG mask", fgmask);

		char key = waitKey(1);

		if (key == 27)
			break;
	}

	// Stop capturing images
	error = cam.StopCapture();
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	// Disconnect the camera
	error = cam.Disconnect();
	if (error != PGRERROR_OK)
	{
		PrintError(error);
		return -1;
	}

	printf("Done! Press Enter to exit...\n");
	getchar();

	return 0;
}

<commit_msg>Added reading fmf files, debugging required<commit_after>// wingtrack.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "FlyCapture2.h"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/video/background_segm.hpp>
#include <opencv2/gpu/gpu.hpp>

using namespace FlyCapture2;
using namespace cv;
using namespace cv::gpu;

#define USEGPU 1

FILE *FMF_In;
unsigned __int32 fmfVersion, SizeY, SizeX, nframes;
unsigned __int64 bytesPerChunk;
long maxFramesInFile;
char *buf;

Camera cam;

BackgroundSubtractorMOG mog_cpu;
MOG_GPU mog_gpu;

Mat frame, fgmask;
GpuMat d_frame, d_fgmask;

Error error;

void PrintBuildInfo()
{
	FC2Version fc2Version;
	Utilities::GetLibraryVersion(&fc2Version);
	char version[128];
	sprintf_s(
		version,
		"FlyCapture2 library version: %d.%d.%d.%d\n",
		fc2Version.major, fc2Version.minor, fc2Version.type, fc2Version.build);

	printf("%s", version);

	char timeStamp[512];
	sprintf_s(timeStamp, "Application build date: %s %s\n\n", __DATE__, __TIME__);

	printf("%s", timeStamp);
}

void PrintCameraInfo(CameraInfo* pCamInfo)
{
	printf(
		"\n*** CAMERA INFORMATION ***\n"
		"Serial number - %u\n"
		"Camera model - %s\n"
		"Camera vendor - %s\n"
		"Sensor - %s\n"
		"Resolution - %s\n"
		"Firmware version - %s\n"
		"Firmware build time - %s\n\n",
		pCamInfo->serialNumber,
		pCamInfo->modelName,
		pCamInfo->vendorName,
		pCamInfo->sensorInfo,
		pCamInfo->sensorResolution,
		pCamInfo->firmwareVersion,
		pCamInfo->firmwareBuildTime);
}

void PrintFormat7Capabilities(Format7Info fmt7Info)
{
	printf(
		"Max image pixels: (%u, %u)\n"
		"Image Unit size: (%u, %u)\n"
		"Offset Unit size: (%u, %u)\n"
		"Pixel format bitfield: 0x%08x\n",
		fmt7Info.maxWidth,
		fmt7Info.maxHeight,
		fmt7Info.imageHStepSize,
		fmt7Info.imageVStepSize,
		fmt7Info.offsetHStepSize,
		fmt7Info.offsetVStepSize,
		fmt7Info.pixelFormatBitField);
}

void PrintError(Error error)
{
	error.PrintErrorTrace();
}

void ReadFMFHeader()
{
	fread(&fmfVersion, sizeof(unsigned __int32), 1, FMF_In);
	fread(&SizeY, sizeof(unsigned __int32), 1, FMF_In);
	fread(&SizeX, sizeof(unsigned __int32), 1, FMF_In);
	fread(&bytesPerChunk, sizeof(unsigned __int64), 1, FMF_In);
	fread(&nframes, sizeof(unsigned __int64), 1, FMF_In);

	buf = new char[bytesPerChunk];

	maxFramesInFile = (unsigned long int)nframes;
}

int ReadFMFFrame(unsigned long frameIndex)
{
	//IplImage *temp = cvCreateImage(cvSize(SizeX, SizeY), IPL_DEPTH_8U, 1);

	if((long)frameIndex>=0L && (long)frameIndex < maxFramesInFile)
		fseek (FMF_In, frameIndex*bytesPerChunk + 28 , SEEK_SET );
	else
		return -1; // Cannot grab .. illegal frame number

	fread(buf, sizeof(double), 1, FMF_In);
	fread(buf, bytesPerChunk-sizeof(double), 1, FMF_In);

	//memmove(temp->imageData, buf, bytesPerChunk);
	return 1;
}

void CloseFMF()
{
	fclose(FMF_In);
}

int _tmain(int argc, _TCHAR* argv[])
{
	bool isVideo = false;
	bool isCam = false;

	if (argc == 2)
	{
		FMF_In = fopen(argv[1], "rb");

		if(FMF_In == NULL) // Cannot open File
		{
			printf("Cannot open input video file\n");
			return -1;
		}

		ReadFMFHeader();
		isVideo = true;
	}
	else
	{
		const Mode k_fmt7Mode = MODE_0;
		const PixelFormat k_fmt7PixFmt = PIXEL_FORMAT_RAW8;

		BusManager busMgr;
		unsigned int numCameras;
		error = busMgr.GetNumOfCameras(&numCameras);

		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		printf("Number of cameras detected: %u\n", numCameras);

		if (numCameras < 1)
		{
			printf("Insufficient number of cameras... exiting\n");
			return -1;
		}

		PGRGuid guid;
		error = busMgr.GetCameraFromIndex(0, &guid);

		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		// Connect to a camera
		error = cam.Connect(&guid);

		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		// Get the camera information
		CameraInfo camInfo;
		error = cam.GetCameraInfo(&camInfo);

		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		PrintCameraInfo(&camInfo);

		// Query for available Format 7 modes
		Format7Info fmt7Info;
		bool supported;
		fmt7Info.mode = k_fmt7Mode;
		error = cam.GetFormat7Info(&fmt7Info, &supported);

		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		PrintFormat7Capabilities(fmt7Info);

		if ((k_fmt7PixFmt & fmt7Info.pixelFormatBitField) == 0)
		{
			// Pixel format not supported!
			printf("Pixel format is not supported\n");
			return -1;
		}

		Format7ImageSettings fmt7ImageSettings;
		fmt7ImageSettings.mode = k_fmt7Mode;
		fmt7ImageSettings.offsetX = 0;
		fmt7ImageSettings.offsetY = 0;
		fmt7ImageSettings.width = fmt7Info.maxWidth;
		fmt7ImageSettings.height = fmt7Info.maxHeight;
		fmt7ImageSettings.pixelFormat = k_fmt7PixFmt;

		bool valid;
		Format7PacketInfo fmt7PacketInfo;

		// Validate the settings to make sure that they are valid
		error = cam.ValidateFormat7Settings(
			&fmt7ImageSettings,
			&valid,
			&fmt7PacketInfo);

		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		if (!valid)
		{
			// Settings are not valid
			printf("Format7 settings are not valid\n");
			return -1;
		}

		// Set the settings to the camera
		error = cam.SetFormat7Configuration(
			&fmt7ImageSettings,
			fmt7PacketInfo.recommendedBytesPerPacket);

		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		// Start capturing images
		error = cam.StartCapture();
		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		// Retrieve frame rate property
		Property frmRate;
		frmRate.type = FRAME_RATE;
		error = cam.GetProperty(&frmRate);
		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		printf("Frame rate is %3.2f fps\n", frmRate.absValue);

		isCam = true;

	}

	for (int imageCount = 0; ; imageCount++)
	{
		if (isCam)
		{
			Image rawImage, convertedImage;

			// Retrieve an image
			error = cam.RetrieveBuffer(&rawImage);
			if (error != PGRERROR_OK)
			{
				PrintError(error);
				continue;
			}

			// Convert the raw image
			error = rawImage.Convert(PIXEL_FORMAT_MONO8, &convertedImage);

			if (error != PGRERROR_OK)
			{
				PrintError(error);
				return -1;
			}

			// convert to OpenCV Mat
			unsigned int rowBytes = (double)convertedImage.GetReceivedDataSize() / (double)convertedImage.GetRows();
			Mat tFrame = Mat(convertedImage.GetRows(), convertedImage.GetCols(), CV_8UC1, convertedImage.GetData(), rowBytes);
			frame = tFrame;

		}
		else if (isVideo)
		{
			int success = ReadFMFFrame(imageCount);
			if (success){
					Mat tFrame = Mat(SizeY, SizeX, CV_8UC1, buf, bytesPerChunk);
					frame = tFrame;
			}
			else
				break;
		}

		if (USEGPU)
		{
			d_frame.upload(frame);
			mog_gpu(d_frame, d_fgmask, 0.01f);
			d_fgmask.download(fgmask);
		}
        else
            mog_cpu(frame, fgmask, 0.01);

		imshow("raw image", frame);
		imshow("FG mask", fgmask);

		char key = waitKey(1);

		if (key == 27)
			break;
	}

	if (isCam)
	{
		// Stop capturing images
		error = cam.StopCapture();
		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}

		// Disconnect the camera
		error = cam.Disconnect();
		if (error != PGRERROR_OK)
		{
			PrintError(error);
			return -1;
		}
	}
	else
		CloseFMF();

	printf("Done! Press Enter to exit...\n");
	getchar();

	return 0;
}

<|endoftext|>


<commit_before>/*
    This file is part of kdepim.

    Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>

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

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "kolabwizard.h"
#include "kolabconfig.h"

#include <libkcal/resourcecalendar.h>
#include <kabc/resource.h>

#include "kresources/imap/kcal/resourceimap.h"
#include "kresources/imap/kabc/resourceimap.h"
#include "kresources/imap/knotes/resourceimap.h"

#include <klineedit.h>
#include <klocale.h>

#include <qlayout.h>
#include <qcheckbox.h>
#include <qlabel.h>

class CreateCalenderImapResource : public KConfigPropagator::Change
{
  public:
    CreateCalenderImapResource()
      : KConfigPropagator::Change( i18n("Create Calender IMAP Resource") )
    {
    }

    void apply()
    {
      kdDebug() << "Creating Calender IMAP Resource" << endl;

      KCal::CalendarResourceManager m( "calendar" );
      m.readConfig();
      QString server = KolabConfig::self()->server();
      KCal::ResourceIMAP *r = new KCal::ResourceIMAP( server );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }
};

class CreateContactImapResource : public KConfigPropagator::Change
{
  public:
    CreateContactImapResource()
      : KConfigPropagator::Change( i18n("Create Contact IMAP Resource") )
    {
    }

    void apply()
    {
      KRES::Manager<KABC::Resource> m( "contact" );
      m.readConfig();
      KABC::ResourceIMAP *r = new KABC::ResourceIMAP( 0 );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }

};

class CreateNotesImapResource : public KConfigPropagator::Change
{
  public:
    CreateNotesImapResource()
      : KConfigPropagator::Change( i18n("Create Notes IMAP Resource") )
    {
    }

    void apply()
    {
      KRES::Manager<ResourceNotes> m( "notes" );
      m.readConfig();
      KNotesIMAP::ResourceIMAP *r = new KNotesIMAP::ResourceIMAP( 0 );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }

};

class KolabPropagator : public KConfigPropagator
{
  public:
    KolabPropagator()
      : KConfigPropagator( KolabConfig::self(), "kolab.kcfg" )
    {
    }

  protected:
    void addCustomChanges( Change::List &changes )
    {
      QString freeBusyBaseUrl = "webdavs://" + KolabConfig::self()->server() +
                                "/freebusy/";

      ChangeConfig *c = new ChangeConfig;
      c->file = "korganizerrc";
      c->group = "FreeBusy";

      c->name = "FreeBusyPublishUrl";
      c->label = "";

      QString user = KolabConfig::self()->user();
      int pos = user.find( "@" );
      if ( pos > 0 ) user = user.left( pos );

      c->value = freeBusyBaseUrl + user + ".ifb";

      changes.append( c );

      c = new ChangeConfig;
      c->file = "korganizerrc";
      c->group = "FreeBusy";

      c->name = "FreeBusyRetrieveUrl";
      c->value = freeBusyBaseUrl;

      changes.append( c );

      KCal::CalendarResourceManager m( "calendar" );
      m.readConfig();
      KCal::CalendarResourceManager::Iterator it;
      for ( it = m.begin(); it != m.end(); ++it ) {
        if ( (*it)->type() == "imap" ) break;
      }
      if ( it == m.end() ) {
        changes.append( new CreateCalenderImapResource );
        changes.append( new CreateContactImapResource );
        changes.append( new CreateNotesImapResource );
      }
    }
};

KolabWizard::KolabWizard() : KConfigWizard( new KolabPropagator )
{
  QFrame *page = createWizardPage( i18n("Kolab Server") );

  QGridLayout *topLayout = new QGridLayout( page );
  topLayout->setSpacing( spacingHint() );

  QLabel *label = new QLabel( i18n("Server name:"), page );
  topLayout->addWidget( label, 0, 0 );
  mServerEdit = new KLineEdit( page );
  topLayout->addWidget( mServerEdit, 0, 1 );

  label = new QLabel( i18n("User name:"), page );
  topLayout->addWidget( label, 1, 0 );
  mUserEdit = new KLineEdit( page );
  topLayout->addWidget( mUserEdit, 1, 1 );

  label = new QLabel( i18n("Password:"), page );
  topLayout->addWidget( label, 2, 0 );
  mPasswordEdit = new KLineEdit( page );
  mPasswordEdit->setEchoMode( KLineEdit::Password );
  topLayout->addWidget( mPasswordEdit, 2, 1 );

  mSavePasswordCheck = new QCheckBox( i18n("Save password"), page );
  topLayout->addMultiCellWidget( mSavePasswordCheck, 3, 3, 0, 1 );

  topLayout->setRowStretch( 4, 1 );

  setupRulesPage();
  setupChangesPage();

  resize( 400, 300 );
}

KolabWizard::~KolabWizard()
{
}

void KolabWizard::usrReadConfig()
{
  mServerEdit->setText( KolabConfig::self()->server() );
  mUserEdit->setText( KolabConfig::self()->user() );
  mPasswordEdit->setText( KolabConfig::self()->password() );
  mSavePasswordCheck->setChecked( KolabConfig::self()->savePassword() );
}

void KolabWizard::usrWriteConfig()
{
  KolabConfig::self()->setServer( mServerEdit->text() );
  KolabConfig::self()->setUser( mUserEdit->text() );
  KolabConfig::self()->setPassword( mPasswordEdit->text() );
  KolabConfig::self()->setSavePassword( mSavePasswordCheck->isChecked() );
}
<commit_msg>- add new ldap entry - turn on groupware functionality in kmail<commit_after>/*
    This file is part of kdepim.

    Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org>
    Copyright (c) 2004 Daniel Molkentin <molkentin@kde.org>

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

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "kolabwizard.h"
#include "kolabconfig.h"

#include "kmailchanges.h"

#include <libkcal/resourcecalendar.h>
#include <kabc/resource.h>

#include "kresources/imap/kcal/resourceimap.h"
#include "kresources/imap/kabc/resourceimap.h"
#include "kresources/imap/knotes/resourceimap.h"

#include <klineedit.h>
#include <klocale.h>

#include <qlayout.h>
#include <qcheckbox.h>
#include <qlabel.h>

class SetupLDAPSearchAccount : public KConfigPropagator::Change
{
  public:
    SetupLDAPSearchAccount()
      : KConfigPropagator::Change( i18n("Setup LDAP Search Account") )
    {
    }

    void apply()
    {
      QString host = KolabConfig::self()->server();
      QString basedn = host;
      basedn.replace(".",",dc=");
      basedn.prepend("dc=");

      KConfig c( "kabldaprc" );
      c.setGroup( "LDAP" );
      uint selHosts = c.readNumEntry("NumSelectedHosts", 0);
      c.writeEntry( "NumSelectedHosts", selHosts + 1 );
      c.writeEntry( QString("SelectedHost%1").arg(selHosts), host);
      c.writeEntry( QString("SelectedBase%1").arg(selHosts), basedn);
      c.writeEntry( QString("SelectedPort%1").arg(selHosts), "389");
    }

};

class CreateCalenderImapResource : public KConfigPropagator::Change
{
  public:
    CreateCalenderImapResource()
      : KConfigPropagator::Change( i18n("Create Calender IMAP Resource") )
    {
    }

    void apply()
    {
      KCal::CalendarResourceManager m( "calendar" );
      m.readConfig();
      QString server = KolabConfig::self()->server();
      KCal::ResourceIMAP *r = new KCal::ResourceIMAP( server );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }
};

class CreateContactImapResource : public KConfigPropagator::Change
{
  public:
    CreateContactImapResource()
      : KConfigPropagator::Change( i18n("Create Contact IMAP Resource") )
    {
    }

    void apply()
    {
      KRES::Manager<KABC::Resource> m( "contact" );
      m.readConfig();
      KABC::ResourceIMAP *r = new KABC::ResourceIMAP( 0 );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }

};

class CreateNotesImapResource : public KConfigPropagator::Change
{
  public:
    CreateNotesImapResource()
      : KConfigPropagator::Change( i18n("Create Notes IMAP Resource") )
    {
    }

    void apply()
    {
      KRES::Manager<ResourceNotes> m( "notes" );
      m.readConfig();
      KNotesIMAP::ResourceIMAP *r = new KNotesIMAP::ResourceIMAP( 0 );
      r->setResourceName( i18n("Kolab Server") );
      m.add( r );
      m.writeConfig();
    }

};

class KolabPropagator : public KConfigPropagator
{
  public:
    KolabPropagator()
      : KConfigPropagator( KolabConfig::self(), "kolab.kcfg" )
    {
    }

  protected:
    void addCustomChanges( Change::List &changes )
    {
      QString freeBusyBaseUrl = "webdavs://" + KolabConfig::self()->server() +
                                "/freebusy/";

      ChangeConfig *c = new ChangeConfig;
      c->file = "korganizerrc";
      c->group = "FreeBusy";

      c->name = "FreeBusyPublishUrl";
      c->label = "";

      QString user = KolabConfig::self()->user();
      int pos = user.find( "@" );
      if ( pos > 0 ) user = user.left( pos );

      c->value = freeBusyBaseUrl + user + ".ifb";

      changes.append( c );

      c = new ChangeConfig;
      c->file = "korganizerrc";
      c->group = "FreeBusy";

      c->name = "FreeBusyRetrieveUrl";
      c->value = freeBusyBaseUrl;

      // KMail cruft has been outsourced
      createKMailChanges( changes );

      changes.append( c );
      changes.append( new SetupLDAPSearchAccount );

      KCal::CalendarResourceManager m( "calendar" );
      m.readConfig();
      KCal::CalendarResourceManager::Iterator it;
      for ( it = m.begin(); it != m.end(); ++it ) {
        if ( (*it)->type() == "imap" ) break;
      }
      if ( it == m.end() ) {
        changes.append( new CreateCalenderImapResource );
        changes.append( new CreateContactImapResource );
        changes.append( new CreateNotesImapResource );
      }
    }
};

KolabWizard::KolabWizard() : KConfigWizard( new KolabPropagator )
{
  QFrame *page = createWizardPage( i18n("Kolab Server") );

  QGridLayout *topLayout = new QGridLayout( page );
  topLayout->setSpacing( spacingHint() );

  QLabel *label = new QLabel( i18n("Server name:"), page );
  topLayout->addWidget( label, 0, 0 );
  mServerEdit = new KLineEdit( page );
  topLayout->addWidget( mServerEdit, 0, 1 );

  label = new QLabel( i18n("User name:"), page );
  topLayout->addWidget( label, 1, 0 );
  mUserEdit = new KLineEdit( page );
  topLayout->addWidget( mUserEdit, 1, 1 );

  label = new QLabel( i18n("Password:"), page );
  topLayout->addWidget( label, 2, 0 );
  mPasswordEdit = new KLineEdit( page );
  mPasswordEdit->setEchoMode( KLineEdit::Password );
  topLayout->addWidget( mPasswordEdit, 2, 1 );

  mSavePasswordCheck = new QCheckBox( i18n("Save password"), page );
  topLayout->addMultiCellWidget( mSavePasswordCheck, 3, 3, 0, 1 );

  topLayout->setRowStretch( 4, 1 );

  setupRulesPage();
  setupChangesPage();

  resize( 400, 300 );
}

KolabWizard::~KolabWizard()
{
}

void KolabWizard::usrReadConfig()
{
  mServerEdit->setText( KolabConfig::self()->server() );
  mUserEdit->setText( KolabConfig::self()->user() );
  mPasswordEdit->setText( KolabConfig::self()->password() );
  mSavePasswordCheck->setChecked( KolabConfig::self()->savePassword() );
}

void KolabWizard::usrWriteConfig()
{
  KolabConfig::self()->setServer( mServerEdit->text() );
  KolabConfig::self()->setUser( mUserEdit->text() );
  KolabConfig::self()->setPassword( mPasswordEdit->text() );
  KolabConfig::self()->setSavePassword( mSavePasswordCheck->isChecked() );
}
<|endoftext|>