/***************************** LICENSE START ***********************************

 Copyright 2013 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include "MvQEditor.h"

#include <QAction>
#include <QActionGroup>
#include <QApplication>
#include <QCloseEvent>
#include <QDateTime>
#include <QDebug>
#include <QDialogButtonBox>
#include <QDrag>
#include <QHBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QPainter>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QSettings>
#include <QStyle>
#include <QStyleOption>
#include <QStackedLayout>
#include <QStackedWidget>
#include <QToolBar>
#include <QToolButton>
#include <QVBoxLayout>

#include "EditorDrawerFactory.h"
#include "Folder.h"
#include "IconClass.h"
#include "MvRequest.h"
#include "Path.h"
#include "Request.h"

#include "MvQEditorDrawerPanel.h"
#include "MvQFolderModel.h"
#include "MvQTemplateDrawer.h"
#include "MvQIconProvider.h"
#include "MvQTheme.h"
#include "MvQMethods.h"
#include "MvQIconMimeData.h"

//#define DEBUG_MV_MVQEDITOR__

//===========================
//
// MvQEditorDragLabel
//
//===========================

MvQEditorDragLabel::MvQEditorDragLabel(QPixmap pix, int maxHeight, QWidget* parent) :
    QLabel(parent),
    obj_(nullptr),
    canDrag_(false),
    oriPix_(pix)
{
    setPixmap(oriPix_);
    setFrameShape(QFrame::Box);
    setFrameShape(QFrame::StyledPanel);
    setObjectName(QString::fromUtf8("editorHeaderIcon"));
    setMaximumHeight(maxHeight);
    setMouseTracking(true);

    highlightPix_ = pix;
    QPainter painter(&highlightPix_);
    QPen pen(QColor(27,136,196));
    pen.setWidth(2);
    painter.setPen(pen);
    painter.drawRect(QRect(0,0,
                           highlightPix_.width(),highlightPix_.height()).
                           adjusted(1,1,-1,-1));
}

void MvQEditorDragLabel::setIconObject(IconObject *obj)
{
    obj_ = obj;
}

void MvQEditorDragLabel::enterEvent(QEvent* event)
{
    setPixmap(highlightPix_);
    QLabel::enterEvent(event);
}

void MvQEditorDragLabel::leaveEvent(QEvent* event)
{
    setPixmap(oriPix_);
    QLabel::leaveEvent(event);
}

void MvQEditorDragLabel::mousePressEvent(QMouseEvent* event)
{
    if (!obj_) {
        QLabel::mousePressEvent(event);
        return;
    }

    canDrag_ = false;
    if (event->button() == Qt::LeftButton) {
       startPos_ = event->pos();
       canDrag_  = true;
    }

    QLabel::mousePressEvent(event);
}

void MvQEditorDragLabel::mouseMoveEvent(QMouseEvent* event)
{
    if (obj_ && canDrag_ && event->buttons() & Qt::LeftButton) {
        int distance = (event->pos() - startPos_).manhattanLength();
        if (distance >= QApplication::startDragDistance()) {
            canDrag_ = false;
            performDrag(Qt::CopyAction, event->pos());
        }
        return;
    }

    QLabel::mouseMoveEvent(event);
}

void MvQEditorDragLabel::performDrag(Qt::DropAction dropAction, QPoint scenePos)
{
    if (obj_) {
        QDrag *drag = buildDrag(obj_, scenePos);
        if (drag) {
            emit dragStarted();
            //We always initiate a copy action
            drag->exec(Qt::CopyAction, dropAction);
        }
        else {
            qDebug() << "MvQEditorDragLabel::performDrag -> Could not build drag object!!!";
        }
    }

    canDrag_ = false;
}

QDrag* MvQEditorDragLabel::buildDrag(IconObject* dragObj, QPoint dragPos)
{
    if (dragObj) {
        QDrag* drag = new QDrag(this);

        //Hotspot is the bottom right corner of the dragged object's pixmap
        //we overwrite it if dragPos is null!! We use normalised coordinates
        QPointF hotSpotInPix(1, 1);

        //It has to have as many elements as there are in objLst
        QList<QPoint> pixDistanceLst;
        //QPointF hotSpotInPix=0.;

        drag->setPixmap(oriPix_);

        QList<IconObject*> objLst;
        objLst << dragObj;

        //Create and set drag mime data
        MvQIconMimeData* mimeData = new MvQIconMimeData(nullptr,
                                                        dragObj, hotSpotInPix,
                                                        objLst, pixDistanceLst);

        mimeData->setFromEditor(true);
        mimeData->setFromHelper(false);
        drag->setMimeData(mimeData);

        return drag;
    }

    return nullptr;
}

//================================================
//
// MvQEditorHeader
//
//================================================

MvQEditorHeader::MvQEditorHeader(MvQEditor* owner, QPixmap pix) :
    QWidget(owner),
    owner_(owner)
{
    QHBoxLayout* hb = new QHBoxLayout(this);
    hb->setSpacing(0);
    hb->setContentsMargins(0, 0, 0, 0);

    QFont font;
    font.setBold(true);
    QFontMetrics fm(font);
    int txth = 3 * fm.height() + 2 * fm.leading() + 8;
    txth     = (txth > 32) ? txth : 32;

    //Pixmap label - can be dragged into a plot window
    pixLabel_ = new MvQEditorDragLabel(pix, txth, this);
    hb->addWidget(pixLabel_);

    connect(pixLabel_, SIGNAL(dragStarted()),
            owner_,SLOT(save()));

    stackLayout_ = new QStackedLayout();
    hb->addLayout(stackLayout_);

    //Info panel
    QWidget* w           = new QWidget;
    QHBoxLayout* labelHb = new QHBoxLayout(w);
    labelHb->setSpacing(0);
    labelHb->setContentsMargins(2, 1, 2, 1);
    stackLayout_->addWidget(w);

    label_ = new QLabel("", this);
    label_->setObjectName(QString::fromUtf8("editorHeaderLabel"));
    label_->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    label_->setAutoFillBackground(true);
    label_->setTextInteractionFlags(Qt::LinksAccessibleByMouse | Qt::TextSelectableByKeyboard | Qt::TextSelectableByMouse);
    label_->setFrameShape(QFrame::Box);
    label_->setFrameShape(QFrame::StyledPanel);
    label_->setMargin(2);
    label_->setMaximumHeight(txth);
    labelHb->addWidget(label_);

    renameTb_ = new QToolButton(this);
    renameTb_->setAutoRaise(true);
    //renameTb_->setText(tr("Rename"));
    renameTb_->setToolTip(tr("Click to rename icon"));
    renameTb_->setIcon(QPixmap(QString::fromUtf8(":/desktop/edit.svg")));
    labelHb->addWidget(renameTb_);

    connect(renameTb_, SIGNAL(clicked(bool)),
            this, SLOT(slotStartEdit(bool)));

    //Editor
    w                   = new QWidget;
    QHBoxLayout* editHb = new QHBoxLayout(w);
    editHb->setSpacing(0);
    editHb->setContentsMargins(2, 1, 2, 1);
    stackLayout_->addWidget(w);

    edit_ = new QLineEdit(this);
    editHb->addWidget(edit_);

    //Rename buttonBox_

    QToolButton* acceptTb = new QToolButton(this);
    acceptTb->setAutoRaise(true);
    acceptTb->setIcon(QPixmap(QString::fromUtf8(":/desktop/accept.svg")));
    editHb->addWidget(acceptTb);

    QToolButton* cancelTb = new QToolButton(this);
    cancelTb->setAutoRaise(true);
    cancelTb->setIcon(QPixmap(QString::fromUtf8(":/desktop/cancel.svg")));
    editHb->addWidget(cancelTb);

    connect(acceptTb, SIGNAL(clicked(bool)),
            this, SLOT(slotAcceptEdit(bool)));

    connect(cancelTb, SIGNAL(clicked(bool)),
            this, SLOT(slotCancelEdit(bool)));

    setProperty("editor", "true");
}

void MvQEditorHeader::slotStartEdit(bool)
{
    if (stackLayout_->currentIndex() == 0) {
        stackLayout_->setCurrentIndex(1);
        if (owner_->current())
            edit_->setText(QString::fromStdString(owner_->current()->name()));
        else
            edit_->clear();
    }
}

void MvQEditorHeader::slotAcceptEdit(bool)
{
    if (stackLayout_->currentIndex() == 1) {
        owner_->rename(edit_->text());
        stackLayout_->setCurrentIndex(0);
    }
}

void MvQEditorHeader::slotCancelEdit(bool)
{
    if (stackLayout_->currentIndex() == 1) {
        stackLayout_->setCurrentIndex(0);
        edit_->clear();
    }
}

void MvQEditorHeader::updateLabel(IconObject* obj)
{
    if (!obj)
        return;

    QString str = "<b><font color=" + MvQTheme::colour("editor", "header_text").name() + tr("> Icon name: </font>");
    str += "<font color=" + MvQTheme::colour("editor", "header_icon_name").name() + ">" + QString::fromStdString(obj->name()) + "</font></b><br>";

    str += "<font color=" + MvQTheme::colour("editor", "header_text").name() + ">";

    str += tr("<b>Folder: </b>");
    str += QString::fromStdString(obj->parent()->fullName()) + "<br>";

    str += tr("<b>Type: </b> ");
    str += QString::fromStdString(obj->className());

    QDateTime dt = QDateTime::fromTime_t(obj->path().lastModified());
    str += tr(" <b>Modified: </b>");
    str += dt.toString("yyyy-MM-dd hh:mm");

    if (obj->locked())
        str += tr(" <b>Status: <font color=\'red\'>Read only</font></b>");

    str += "</font>";

    label_->setText(str);
    pixLabel_->setIconObject(obj);

    lock(obj->locked());
}

void MvQEditorHeader::lock(bool b)
{
    renameTb_->setEnabled(!b);
}

void MvQEditorHeader::paintEvent(QPaintEvent*)
{
    QStyleOption opt;
    opt.init(this);
    QPainter p(this);
    style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}

//================================================
//
// MvQEditorTextPanel
//
//================================================

MvQEditorTextPanel::MvQEditorTextPanel(const IconClass& c, Editor* owner, QWidget* parent) :
    QWidget(parent),
    class_(c),
    owner_(owner),
    current_(0),
    correct_(true),
    beingLoaded_(false)
{
    QVBoxLayout* vb = new QVBoxLayout;
    setLayout(vb);

    vb->setSpacing(0);
    vb->setContentsMargins(0, 0, 0, 0);

    //Warning label
    QHBoxLayout* warnLayout = new QHBoxLayout();
    vb->addLayout(warnLayout);

    warnLabel_ = new QLabel("This is the contents of the file storing your icon settings. Please only edit it at <b> your own <b>risk</b>!", this);
    warnLabel_->setWordWrap(true);
    warnLabel_->setObjectName("editorWarningLabel");
    warnLabel_->setAlignment(Qt::AlignCenter);
    warnLabel_->setAutoFillBackground(true);
    warnLayout->addWidget(warnLabel_, 1);

    //Message label
    QHBoxLayout* msgLayout = new QHBoxLayout();
    vb->addLayout(msgLayout);

    msgLabel_ = new QLabel("Hello", this);
    msgLabel_->setObjectName("editorMessageLabel");
    msgLabel_->setWordWrap(true);
    msgLayout->addWidget(msgLabel_, 1);
    msgLabel_->hide();

    //Text editor
    te_ = new QPlainTextEdit(this);
    te_->setProperty("mvStyle", "fileContents");
    vb->addWidget(te_, 1);

    connect(te_, SIGNAL(textChanged()),
            this, SLOT(slotTextChanged()));
}

void MvQEditorTextPanel::setObject(IconObject* obj)
{
    current_ = obj;

    QString str = tr("This is the contents of the file storing your icon settings.");

    if (obj->locked()) {
        te_->setReadOnly(true);
        te_->setProperty("mvStyle", "fileContentsReadOnly");
    }
    else {
        te_->setReadOnly(false);
        te_->setProperty("mvStyle", "fileContents");
        str += tr("Please only edit it at <b> your own <b>risk</b>!");
    }

    te_->update();
    warnLabel_->setText(str);
}


void MvQEditorTextPanel::loadRequestFile()
{
    beingLoaded_ = true;
    QFile f(QString::fromStdString(current_->path().str()));
    f.open(QFile::ReadOnly | QFile::Text);
    QTextStream rs(&f);
    te_->setPlainText(rs.readAll());
    f.close();
    beingLoaded_ = false;
}

/*bool MvQEditorTextPanel::checkVerb()
{
  	const char* v=current_->request().getVerb();
        const char* ic=current_->iconClass().name().c_str();
	
  	if(strcmp(v,ic) != 0)
	{
	  	QString s="<b><font color=\'red\'> Error: </b></font> Request type <b>" + QString(v) + "</b> in text does not match icon type <b>"  + QString(ic) + "</b>! ";
		s+="Please change request type to <b>" + QString(ic) + "</b> or revert the icon back to system default.";
		
		msgLabel_->setText(s);	
		
		return false;
	}
	
	return true;
}*/

bool MvQEditorTextPanel::check(bool fromSave)
{
    QString s = te_->toPlainText();
    Request r = Request::fromText(s.toStdString());
    QString verb;

#ifdef DEBUG_MV_MVQEDITOR__
    qDebug() << "TEXT --->";
    r.print();
    qDebug() << "<--- TEXT";
#endif

    if (r)
        verb = QString(r.getVerb());

    QString ic = QString::fromStdString(current_->editorClass().name());
    //QString ic=QString::fromStdString(current_->iconClass().name());

    QString msg;
    bool failed = false;
    if (verb.compare(ic, Qt::CaseInsensitive) != 0) {
        msg = "Request type <b>" + verb + "</b> in text does not match icon type <b>" + ic + "</b>! ";
        msg += "Please change the request type to <b>" + ic + "</b> or revert the icon back to system defaults.";
        failed = true;
    }

    if (failed) {
        QString s = "<table><tr><td><img src=\':/desktop/error.svg\' /></td><td width=\'4\'/><td><b>Error: </b>";
        if (fromSave)
            s += "<u>Cannot save file!</u>";
        else
            s += "<u>Broken request!</u>";

        s += "<br>" + msg + "</td></tr></table>";
        msgLabel_->show();
        msgLabel_->setText(s);
    }
    else
        msgLabel_->hide();

    correct_ = (!failed);

    return correct_;
}


void MvQEditorTextPanel::slotTextChanged()
{
    if (!beingLoaded_) {
        owner_->changed();
        msgLabel_->hide();
    }
}


void MvQEditorTextPanel::save()
{
    FILE* f = fopen(current_->path().str().c_str(), "w");
    if (f == NULL) {
        //marslog(LOG_EROR|LOG_PERR,"%s",tmp);
        return;
    }
#ifdef DEBUG_MV_MVQEDITOR__
    qDebug() << te_->toPlainText() << current_->path().str().c_str();
#endif
    fprintf(f, "%s\n", te_->toPlainText().toStdString().c_str());
    fclose(f);
}

void MvQEditorTextPanel::load()
{
    loadRequestFile();
    check(false);
}

//================================================
//
// MvQEditor
//
//================================================

MvQEditor::MvQEditor(const IconClass& name, const string& kind, QWidget* parent) :
    QDialog(parent),
    Editor(name, kind),
    showDisabledAc_(NULL),
    drawerFilled_(false),
    ignoreChange_(false)
{
    //Set Window icon
    setWindowIcon(MvQIconProvider::pixmap(name, 24));

    QVBoxLayout* vb = new QVBoxLayout;
    vb->setSpacing(0);
    vb->setContentsMargins(0, 0, 0, 0);
    setLayout(vb);

    //Header
    headerPanel_ = new MvQEditorHeader(this, MvQIconProvider::pixmap(name, 32));
    vb->addWidget(headerPanel_);


    //-------------------
    // Toolbar
    //-------------------

    toolBarLayout_ = new QHBoxLayout();
    toolBarLayout_->setSpacing(0);
    toolBarLayout_->setContentsMargins(0, 0, 0, 0);

    //vb->addLayout(toolBarLayout_);

    //Widget to provide bg for the toolbars
    QWidget* w = new QWidget(this);
    w->setProperty("editor", "true");
    w->setLayout(toolBarLayout_);
    vb->addWidget(w);

    toolbarLeft_ = new QToolBar(this);
    //toolbarLeft_->setIconSize(QSize(20,20));
    toolBarLayout_->addWidget(toolbarLeft_);

    toolbarRight_ = new QToolBar(w);
    //toolbarRight_->setIconSize(QSize(18,18));

    //toolBarLayout_->addWidget(toolbarLeft_,1);
    //toolBarLayout_->addStretch(1);
    toolBarLayout_->addWidget(toolbarRight_);

    QWidget* spacer = new QWidget(this);
    spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    sepAc_ = toolbarRight_->addWidget(spacer);

    toolBarLayout_->addWidget(toolbarRight_);
    toolBarLayout_->addWidget(toolbarRight_);

    //Gui edit
    guiAc_ = new QAction(this);
    guiAc_->setIcon(QPixmap(":/desktop/gui_edit.svg"));
    guiAc_->setCheckable(true);
    guiAc_->setToolTip(tr("<b>GUI</b> edit mode.<br> To switch between edit modes changes have to be <u>saved<u>!"));
    toolbarRight_->addAction(guiAc_);

    //Text edit
    textAc_ = new QAction(this);
    textAc_->setIcon(QPixmap(":/desktop/text_edit.svg"));
    textAc_->setCheckable(true);
    textAc_->setToolTip(tr("<b>Text</b> edit mode.<br> To switch between edit modes changes have to be <u>saved</u>!"));
    toolbarRight_->addAction(textAc_);

    viewAg_ = new QActionGroup(this);
    viewAg_->setExclusive(true);
    viewAg_->addAction(guiAc_);
    viewAg_->addAction(textAc_);

    guiAc_->setChecked(true);

    connect(viewAg_, SIGNAL(triggered(QAction*)),
            this, SLOT(slotChangeView(QAction*)));

    //Search
    //QSearchLine
    //QLabel
    //searchLine_=new QLineEdit(this);

    //toolBarLayout_->addStretch(1);

    //---------------------
    // Central part
    //---------------------

    viewSw_ = new QStackedWidget(this);
    vb->addWidget(viewSw_, 1);

    //Panel layout
    w              = new QWidget(this);
    centralLayout_ = new QVBoxLayout;
    centralLayout_->setSpacing(0);
    centralLayout_->setContentsMargins(1, 1, 1, 1);
    w->setLayout(centralLayout_);
    viewSw_->addWidget(w);

    //Text widget
    textPanel_ = new MvQEditorTextPanel(name, this, this);
    viewSw_->addWidget(textPanel_);
    viewSw_->addWidget(textPanel_);

    viewSw_->setCurrentIndex(0);

    //--------------------
    // Drawer
    //--------------------

    drawerPanel_ = new MvQEditorDrawerPanel(this);

    /*map<string, EditorDrawer*> drawers=EditorDrawerFactory::create(this);
	for(map<string, EditorDrawer*>::iterator j = drawers.begin();j != drawers.end(); ++j) 
	{
	  	drawerPanel_->addDrawer((*j).second->widget(),
						(*j).second->name());
	}*/

    vb->addWidget(drawerPanel_);

    drawerPanel_->shrink();

    //--------------------
    // Buttonbox
    //--------------------

    buttonBox_ = new QDialogButtonBox(this);

    savePb_   = buttonBox_->addButton(QDialogButtonBox::Save);
    okPb_     = buttonBox_->addButton(QDialogButtonBox::Ok);
    cancelPb_ = buttonBox_->addButton(QDialogButtonBox::Cancel);
    resetPb_  = buttonBox_->addButton(QDialogButtonBox::Reset);

    savePb_->setDefault(true);
    savePb_->setEnabled(false);
    resetPb_->setEnabled(false);

    /*QCheckBox* stayOpenCb= new QCheckBox(tr("Stay open"),this);
	stayOpenCb->setChecked(false);
	buttonBox_->addButton(stayOpenCb,QDialogButtonBox::YesRole);*/

    //buttonBox_->addButton(QDialogButtonBox::Close);

    connect(buttonBox_, SIGNAL(clicked(QAbstractButton*)),
            this, SLOT(slotButtonClicked(QAbstractButton*)));

    vb->addWidget(buttonBox_);
}


MvQEditor::~MvQEditor()
{
}

void MvQEditor::setupShowDisabledActions()
{
    showDisabledAc_ = new QAction(this);
    showDisabledAc_->setText(tr("Show disabled parameters"));
    showDisabledAc_->setCheckable(true);
    showDisabledAc_->setChecked(false);
    toolbarLeft_->addAction(showDisabledAc_);

    MvRequest r = MvApplication::getExpandedPreferences();
    if (const char* c = r("SHOW_DISABLED_PARAMETERS_IN_ICON_EDITORS")) {
        if (strcmp(c, "ON") == 0)
            showDisabledAc_->setChecked(true);
    }

    connect(showDisabledAc_, SIGNAL(triggered(bool)),
            this, SLOT(slotShowDisabled(bool)));
}


bool MvQEditor::showDisabled() const
{
    return (showDisabledAc_) ? showDisabledAc_->isChecked() : false;
}

void MvQEditor::showIt()
{
    show();

    //Mimimize the drawer
    drawerPanel_->shrink();
}

void MvQEditor::addToToolBar(QList<QAction*> lst)
{
    toolbarRight_->insertActions(sepAc_, lst);
}

//Iconobserver method
void MvQEditor::iconChanged(IconObject* obj)
{
    if (obj == current_) {
        headerPanel_->updateLabel(current_);
        updateWindowTitle();
    }
}


void MvQEditor::changed()
{
    if (!temporary_ && !ignoreChange_) {
        savePb_->setEnabled(true);
        resetPb_->setEnabled(true);
        viewAg_->setEnabled(false);
    }

    //resetPb_->setEnabled(true);
}

void MvQEditor::edit()
{
    if (!current_)
        return;

    //Set default button status
    savePb_->setEnabled(false);
    resetPb_->setEnabled(false);

    //Populate drawers if needed
    if (!drawerFilled_) {
        map<string, EditorDrawer*> drawers = EditorDrawerFactory::create(this);
        for (map<string, EditorDrawer*>::iterator j = drawers.begin(); j != drawers.end(); ++j) {
            drawerPanel_->addDrawer((*j).second->widget(),
                                    (*j).second->name());
        }
        drawerFilled_ = true;
    }

    //Read the previous size
    readSettings();

    //Header
    headerPanel_->updateLabel(current_);

    //Title
    updateWindowTitle();

    //Text
    textPanel_->setObject(current_);

    //If request is broken we switch to text mode
    if (!current_->checkRequest()) {
        textPanel_->load();
        viewAg_->setEnabled(false);
        textAc_->setChecked(true);
        slotChangeView(textAc_);
        //textAc_->toggled();
    }
    //otherwise we start with gui mode
    else {
        viewAg_->setEnabled(true);
        guiAc_->setChecked(true);
        slotChangeView(guiAc_);  // this will call reset
        viewAg_->setEnabled(true);
    }

    savePb_->setEnabled(false);
    resetPb_->setEnabled(false);

    okPb_->setEnabled(!current_->locked());
}

bool MvQEditor::isTextMode()
{
    return (viewSw_->currentIndex() == TextViewMode);
}

void MvQEditor::slotTextChanged()
{
    changed();
}

void MvQEditor::save()
{
    slotButtonClicked(savePb_);
}

void MvQEditor::raiseIt()
{
    if (isMinimized())
        showNormal();

    raise();
}

void MvQEditor::closeIt()
{
    close();
    reject();
}

void MvQEditor::rename(QString text)
{
    if (!current_)
        return;

    if (!text.isEmpty()) {
        string n = text.toStdString();
        if (n != current_->name()) {
            current_->editor(0);
            current_->rename(n);
            current_->editor(this);
        }
        headerPanel_->updateLabel(current_);
        updateWindowTitle();
    }
}

void MvQEditor::slotChangeView(QAction* ac)
{
    if (savePb_->isEnabled()) {
        viewAg_->setEnabled(false);
        return;
    }

    //From gui to text mode
    if (ac == textAc_) {
        viewSw_->setCurrentIndex(TextViewMode);
        ignoreChange_ = true;
        textPanel_->load();
        ignoreChange_ = false;
    }
    //From text to gui mode
    else {
        viewSw_->setCurrentIndex(LineViewMode);
        ignoreChange_ = true;
        reset();
        ignoreChange_ = false;
    }
}

void MvQEditor::slotButtonClicked(QAbstractButton* button)
{
    if (!button)
        return;

    if (buttonBox_->standardButton(button) == QDialogButtonBox::Cancel) {
        writeSettings();

        savePb_->setEnabled(false);
        resetPb_->setEnabled(false);

        close();
        reject();
    }
    else if (buttonBox_->standardButton(button) == QDialogButtonBox::Ok) {
        writeSettings();

        //Text mode
        if (isTextMode()) {
            if (textPanel_->check())
                textPanel_->save();
            else {
                viewAg_->setEnabled(false);
                return;
            }
        }
        //GUI mode
        else {
            ignoreChange_ = true;
            apply();
            ignoreChange_ = false;
        }

        current_->modified();
        notifyObserverApply();

        savePb_->setEnabled(false);
        resetPb_->setEnabled(false);

        close();
        accept();
    }
    else if (buttonBox_->standardButton(button) == QDialogButtonBox::Save) {
        ignoreChange_ = true;

        //Text mode
        if (isTextMode()) {
            if (textPanel_->check())
                textPanel_->save();
            else {
                viewAg_->setEnabled(false);
                return;
            }
        }
        //GUI mode
        else {
            ignoreChange_ = true;
            apply();
            ignoreChange_ = false;
        }

        current_->modified();
        notifyObserverApply();

        savePb_->setEnabled(false);
        resetPb_->setEnabled(false);
        viewAg_->setEnabled(true);
    }
    else if (buttonBox_->standardButton(button) == QDialogButtonBox::Reset) {
        //Text mode
        if (isTextMode())
            textPanel_->load();
        else {
            ignoreChange_ = true;
            reset();
            ignoreChange_ = false;
        }

        savePb_->setEnabled(false);
        resetPb_->setEnabled(false);
        viewAg_->setEnabled(true);
    }
}

void MvQEditor::accept()
{
    editDone();
    QDialog::accept();
}

void MvQEditor::reject()
{
    notifyObserverClose();
    editDone();
    QDialog::reject();
}

void MvQEditor::temporary()
{
    Editor::temporary();
    savePb_->setEnabled(false);
    viewAg_->setEnabled(false);
    headerPanel_->lock(true);
}

void MvQEditor::closeEvent(QCloseEvent* event)
{
    writeSettings();
    close();
    accept();
    event->accept();
}

void MvQEditor::updateWindowTitle()
{
    QString txt = QString::fromStdString(current_->name());
    if (current_->parent())
        txt += " - " + QString::fromStdString(current_->parent()->fullName());

    txt += " - Metview";
    setWindowTitle(txt);
}

void MvQEditor::writeSettings()
{
    QSettings settings(MVQ_QSETTINGS_DEFAULT_ARGS, "MV4-Desktop-Editor-" + QString::fromStdString(class_.name()));

    //We have to clear it so that should not remember all the previous values
    settings.clear();

    settings.beginGroup("main");
    settings.setValue("size", size());
    settings.endGroup();

    writeSettings(settings);
}

void MvQEditor::readSettings()
{
    QSettings settings(MVQ_QSETTINGS_DEFAULT_ARGS, "MV4-Desktop-Editor-" + QString::fromStdString(class_.name()));

    settings.beginGroup("main");
    if (settings.contains("size")) {
        resize(settings.value("size").toSize());
    }
    else {
        resize(QSize(520, 500));
    }

    settings.endGroup();

    readSettings(settings);
}
