Subversion Repositories Scribus

Rev

Rev 24527 | Rev 24738 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
For general Scribus (>=1.3.2) copyright and licensing information please refer
to the COPYING file provided with the program. Following this notice may exist
a copyright and/or license notice that predates the release of Scribus 1.3.2
for which a new license (GPL+exception) is in place.
*/

/**************************************************************************
*   Copyright (C) 2010 by Franz Schmid                                    *
*   franz.schmid@altmuehlnet.de                                           *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU General Public License     *
*   along with this program; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
***************************************************************************/


#include <memory>

#include <QCheckBox>
#include <QCursor>
#include <QDir>
#include <QDomDocument>
#include <QEventLoop>
#include <QFileDialog>
#include <QImageReader>
#include <QMenu>
#include <QMessageBox>
#include <QScopedPointer>

#include "cmykfw.h"
#include "colorlistbox.h"
#include "colorsandfills.h"
#include "commonstrings.h"
#include "dcolor.h"
#include "fileloader.h"
#include "gradientaddedit.h"
#include "iconmanager.h"
#include "loadsaveplugin.h"
#include "plugins/formatidlist.h"
#include "prefsfile.h"
#include "prefsmanager.h"
#include "query.h"
#include "scclocale.h"
#include "sccolor.h"
#include "sccolorengine.h"
#include "scconfig.h"
#include "sclimits.h"
#include "sclistboxpixmap.h"
#include "scpainter.h"
#include "scpaths.h"
#include "scribus.h"
#include "scribusview.h"
#include "scribusXml.h"
#include "sctextstream.h"
#include "ui/customfdialog.h"
#include "undomanager.h"
#include "util.h"
#include "util_color.h"
#include "util_formats.h"

ColorsAndFillsDialog::ColorsAndFillsDialog(QWidget* parent, QHash<QString, VGradient> *docGradients, const ColorList& doco, const QString& docColSet, QHash<QString, ScPattern> *docPatterns, ScribusDoc *doc, ScribusMainWindow *scMW)
                        : QDialog(parent),
                          m_doc(doc),
                          mainWin(scMW)
{
        setupUi(this);
        setModal(true);

        m_colorList = doco;

        setWindowIcon(IconManager::instance().loadIcon("AppIcon.png"));
        dataTree->setContextMenuPolicy(Qt::CustomContextMenu);
        dataTree->setIconSize(QSize(60, 48));
        colorItems = new QTreeWidgetItem(dataTree);
        colorItems->setText(0, tr("Solid Colors"));
        gradientItems = new QTreeWidgetItem(dataTree);
        gradientItems->setText(0, tr("Gradients"));
        for (QHash<QString, VGradient>::Iterator it = docGradients->begin(); it != docGradients->end(); ++it)
        {
                dialogGradients.insert(it.key(), it.value());
                origNames.insert(it.key(), it.key());
        }
        origGradients = docGradients->keys();

        patternItems = new QTreeWidgetItem(dataTree);
        patternItems->setText(0, tr("Patterns"));
        for (QHash<QString, ScPattern>::Iterator it = docPatterns->begin(); it != docPatterns->end(); ++it)
        {
                dialogPatterns.insert(it.key(), it.value());
                origNamesPatterns.insert(it.key(), it.key());
        }
        origPatterns = docPatterns->keys();

        csm.findPaletteLocations();
        systemSwatches = LoadColSet->addTopLevelItem( tr("Scribus Swatches"));
        csm.findPalettes(systemSwatches);
        LoadColSet->addSubItem("Scribus Small", systemSwatches);
        systemSwatches->setExpanded(true);
        userSwatches = LoadColSet->addTopLevelItem( tr("User Swatches"));
        csm.findUserPalettes(userSwatches);
        customColSet = csm.userPaletteNames();
        userSwatches->setExpanded(true);
//      QFileInfo fi(docColSet);
        LoadColSet->setCurrentComboItem(docColSet);
        if (mainWin->HaveDoc)
        {
                label->setText( tr("Merge Color Set"));
                m_doc->getUsedColors(inDocUsedColors);
                paletteLocked = false;
        }
        else
        {
                if (docColSet != "Scribus Small")
                {
                        QString pfad;
                        if (customColSet.contains(docColSet))
                                pfad = csm.userPaletteFileFromName(docColSet);
                        else
                                pfad = csm.paletteFileFromName(docColSet);
                        QFileInfo fi(pfad);
                        if (fi.absolutePath().contains(ScPaths::applicationDataDir()+"swatches/locked"))
                                paletteLocked = true;
                        else
                                paletteLocked = !fi.isWritable();
                }
        }
        importButton->setEnabled(false);
        newButton->setEnabled(false);
        editButton->setEnabled(false);
        duplicateButton->setEnabled(false);
        deleteButton->setEnabled(false);
        deleteUnusedButton->setEnabled(false);
        updateColorList();
        updateGradientList();
        updatePatternList();
        dataTree->expandItem(colorItems);
        dataTree->expandItem(gradientItems);
        dataTree->expandItem(patternItems);
        dataTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
        connect(dataTree, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(itemSelected(QTreeWidgetItem*)));
        connect(dataTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(selEditColor(QTreeWidgetItem*)));
        connect(dataTree, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
        connect(dataTree, SIGNAL(customContextMenuRequested (const QPoint &)), this, SLOT(slotRightClick(QPoint)));
        connect(newButton, SIGNAL(clicked()), this, SLOT(createNew()));
        connect(editButton, SIGNAL(clicked()), this, SLOT(editColorItem()));
        connect(duplicateButton, SIGNAL(clicked()), this, SLOT(duplicateColorItem()));
        connect(deleteButton, SIGNAL(clicked()), this, SLOT(removeColorItem()));
        connect(deleteUnusedButton, SIGNAL(clicked()), this, SLOT(removeUnusedColorItem()));
        connect(importButton, SIGNAL(clicked()), this, SLOT(importColorItems()));
        connect(okButton, SIGNAL(clicked()), this, SLOT(leaveDialog()));
        connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
        connect(SaveColSet, SIGNAL(clicked()), this, SLOT(saveDefaults()));
        connect(LoadColSet, SIGNAL(activated(QTreeWidgetItem*)), this, SLOT(loadDefaults(QTreeWidgetItem*)));
}

void ColorsAndFillsDialog::leaveDialog()
{
/*      if (!mainWin->HaveDoc)
        {
                if (modified)
                {
                        if (paletteLocked)
                                saveDefaults();
                        else
                                doSaveDefaults(LoadColSet->text(), true);
                }
        } */

        accept();
}

QTreeWidgetItem* ColorsAndFillsDialog::updatePatternList(const QString& addedName)
{
        QList<QTreeWidgetItem*> lg = patternItems->takeChildren();
        for (int i = 0; i < lg.count(); i++)
        {
                delete lg[i];
        }
        QTreeWidgetItem* ret = nullptr;
        QStringList patK = dialogPatterns.keys();
        patK.sort();
        for (int a = 0; a < patK.count(); a++)
        {
                ScPattern sp = dialogPatterns.value(patK[a]);
                QPixmap pm;
                if (sp.getPattern()->width() >= sp.getPattern()->height())
                        pm = QPixmap::fromImage(sp.getPattern()->scaledToWidth(48, Qt::SmoothTransformation));
                else
                        pm = QPixmap::fromImage(sp.getPattern()->scaledToHeight(48, Qt::SmoothTransformation));
                QPixmap pm2(48, 48);
                pm2.fill(palette().color(QPalette::Base));
                QPainter p;
                p.begin(&pm2);
                p.drawPixmap(24 - pm.width() / 2, 24 - pm.height() / 2, pm);
                p.end();
                QTreeWidgetItem *item = new QTreeWidgetItem(patternItems);
                item->setText(0, patK[a]);
                if (patK[a] == addedName)
                        ret = item;
                item->setIcon(0, pm2);
                item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
        }
        return ret;
}

QTreeWidgetItem* ColorsAndFillsDialog::updateGradientList(const QString& addedName)
{
        QList<QTreeWidgetItem*> lg = gradientItems->takeChildren();
        for (int i = 0; i < lg.count(); i++)
        {
                delete lg[i];
        }
        QTreeWidgetItem* ret = nullptr;
        QStringList patK = dialogGradients.keys();
        patK.sort();
        for (int a = 0; a < patK.count(); a++)
        {
                VGradient gr = dialogGradients.value(patK[a]);
                QImage pixm(48, 12, QImage::Format_ARGB32);
                QPainter pb;
                QBrush b(QColor(205,205,205), IconManager::instance().loadPixmap("testfill.png"));
                pb.begin(&pixm);
                pb.fillRect(0, 0, 48, 12, b);
                pb.end();

                ScPainter *p = new ScPainter(&pixm, 48, 12);
                p->setPen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
                p->setFillMode(ScPainter::Gradient);
                p->fill_gradient = gr;
                p->setGradient(VGradient::linear, FPoint(0,6), FPoint(48, 6), FPoint(0, 0), 1.0, 0.0);
                p->drawRect(0, 0, 48, 12);
                p->end();
                delete p;

                QPixmap pm = QPixmap::fromImage(pixm);
                QTreeWidgetItem *item = new QTreeWidgetItem(gradientItems);
                item->setText(0, patK[a]);
                if (patK[a] == addedName)
                        ret = item;
                item->setIcon(0, pm);
                item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
        }
        return ret;
}

QTreeWidgetItem* ColorsAndFillsDialog::updateColorList(const QString& addedName)
{
        QList<QTreeWidgetItem*> lg = colorItems->takeChildren();
        for (int i = 0; i < lg.count(); i++)
                delete lg[i];

        QTreeWidgetItem* ret = nullptr;
        if (sortRule > 0)
        {
                QMap<QString, QString> sortMap;
                ColorList::Iterator it;
                for (it = m_colorList.begin(); it != m_colorList.end(); ++it)
                {
                        if (sortRule == 1)
                        {
                                QColor c = it.value().getRawRGBColor();
                                QString sortString = QString("%1-%2-%3-%4").arg(c.hue(), 3, 10, QChar('0')).arg(c.saturation(), 3, 10, QChar('0')).arg(c.value(), 3, 10, QChar('0')).arg(it.key());
                                sortMap.insert(sortString, it.key());
                        }
                        else if (sortRule == 2)
                        {
                                QString sortString = QString("%1-%2");
                                if (it.value().isRegistrationColor())
                                        sortMap.insert(sortString.arg("A", it.key()), it.key());
                                else if (it.value().isSpotColor())
                                        sortMap.insert(sortString.arg("B", it.key()), it.key());
                                else if (it.value().getColorModel() == colorModelCMYK)
                                        sortMap.insert(sortString.arg("C", it.key()), it.key());
                                else
                                        sortMap.insert(sortString.arg("D", it.key()), it.key());
                        }
                }
                QMap<QString, QString>::Iterator itc;
                for (itc = sortMap.begin(); itc != sortMap.end(); ++itc)
                {
                        const ScColor& color = m_colorList[itc.value()];
                        QTreeWidgetItem *item = new QTreeWidgetItem(colorItems);
                        item->setText(0, itc.value());
                        if (itc.value() == addedName)
                                ret = item;
                        QPixmap* pPixmap = getFancyPixmap(color, m_doc);
                        item->setIcon(0, *pPixmap);
                        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
                        item->setData(0, Qt::ToolTipRole, getColorTooltip(color));
                }
        }
        else
        {
                ColorList::Iterator it;
                for (it = m_colorList.begin(); it != m_colorList.end(); ++it)
                {
                        const ScColor& color = it.value();
                        QTreeWidgetItem *item = new QTreeWidgetItem(colorItems);
                        item->setText(0, it.key());
                        if (it.key() == addedName)
                                ret = item;
                        QPixmap* pPixmap = getFancyPixmap(color, m_doc);
                        item->setIcon(0, *pPixmap);
                        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
                        item->setData(0, Qt::ToolTipRole, getColorTooltip(color));
                }
        }
        return ret;
}

void ColorsAndFillsDialog::slotRightClick(QPoint p)
{
        QTreeWidgetItem* it = dataTree->itemAt(p);
        if (!it)
                return;

        if ((it->parent() == colorItems) || (it == colorItems))
        {
                QMenu *pmen = new QMenu();
//                      qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
                pmen->addAction( tr("Sort by Name"));
                pmen->addAction( tr("Sort by Color"));
                pmen->addAction( tr("Sort by Type"));
                sortRule = pmen->actions().indexOf(pmen->exec(QCursor::pos()));
                pmen->deleteLater();
                updateColorList();
        }
}

void ColorsAndFillsDialog::selEditColor(QTreeWidgetItem *it)
{
        if (!it || paletteLocked)
                return;

        if ((it->parent() == colorItems) || (it->parent() == gradientItems))
        {
                QString curCol = it->text(0);
                bool enableDel  = (!isMandatoryColor(curCol)) && (m_colorList.count() > 1);
                bool enableEdit = (!isMandatoryColor(curCol));
                duplicateButton->setEnabled(curCol != "Registration");
                deleteButton->setEnabled(enableDel);
                editButton->setEnabled(enableEdit);
                if (enableEdit)
                        editColorItem();
        }
}

void ColorsAndFillsDialog::itemSelectionChanged()
{
        QList<QTreeWidgetItem *> selItems = dataTree->selectedItems();
        if (selItems.count() > 1)
                deleteButton->setEnabled(true);
}

void ColorsAndFillsDialog::itemSelected(QTreeWidgetItem* it)
{
        QList<QTreeWidgetItem *> selItems = dataTree->selectedItems();
        importButton->setText( tr("&Import"));
        newButton->setText( tr("Add"));
        editButton->setText( tr("&Edit"));
        if (it && !paletteLocked)
        {
                if ((it->parent() == colorItems) || (it->parent() == gradientItems))
                {
                        importButton->setEnabled(false);
                        newButton->setEnabled(true);
                        deleteUnusedButton->setEnabled(it->parent() == colorItems);
                        if (it->parent() == colorItems)
                        {
                                QString curCol = it->text(0);
                                //ScColor tmpColor = m_colorList[curCol];
                                bool enableDel  = (!isMandatoryColor(curCol)) && (m_colorList.count() > 1);
                                bool enableEdit = (!isMandatoryColor(curCol));
                                duplicateButton->setEnabled(curCol != "Registration");
                                deleteButton->setEnabled(enableDel);
                                editButton->setEnabled(enableEdit);
                        }
                        else
                        {
                                editButton->setEnabled(true);
                                duplicateButton->setEnabled(true);
                                deleteButton->setEnabled(true);
                        }
                }
                else if (it->parent() == patternItems)
                {
                        importButton->setText( tr("Load File"));
                        newButton->setText( tr("Load Set"));
                        editButton->setText( tr("Rename"));
                        importButton->setEnabled(true);
                        newButton->setEnabled(true);
                        editButton->setEnabled(true);
                        duplicateButton->setEnabled(false);
                        deleteButton->setEnabled(true);
                }
                else if (it == patternItems)
                {
                        importButton->setText( tr("Load File"));
                        newButton->setText( tr("Load Set"));
                        importButton->setEnabled(true);
                        newButton->setEnabled(true);
                        editButton->setEnabled(false);
                        duplicateButton->setEnabled(false);
                        if (selItems.count() < 2)
                                deleteButton->setEnabled(it->childCount() > 0);
                        else
                                deleteButton->setEnabled(true);
                }
                else
                {
                        importButton->setEnabled(true);
                        newButton->setEnabled(true);
                        editButton->setEnabled(false);
                        duplicateButton->setEnabled(false);
                        if (selItems.count() < 2)
                                deleteButton->setEnabled(it->childCount() > 0);
                        else
                                deleteButton->setEnabled(true);
                        deleteUnusedButton->setEnabled((it == colorItems) && (it->childCount() > 0));
                }
        }
        else
        {
                importButton->setEnabled(false);
                newButton->setEnabled(false);
                editButton->setEnabled(false);
                duplicateButton->setEnabled(false);
                deleteButton->setEnabled(false);
                deleteUnusedButton->setEnabled(false);
                dataTree->clearSelection();
        }
}

void ColorsAndFillsDialog::createNew()
{
        if (paletteLocked)
                return;
        QTreeWidgetItem* it = dataTree->currentItem();
        if (!it)
                return;

        if ((it->parent() == gradientItems) || (it == gradientItems))
        {
                VGradient fill_gradient(VGradient::linear);
                fill_gradient.clearStops();
                fill_gradient.addStop(QColor(Qt::black), 0.0, 0.5, 1.0, "Black", 100);
                fill_gradient.addStop(QColor(Qt::white), 1.0, 0.5, 1.0, "White", 100);
                QScopedPointer<gradientEditDialog> dia(new gradientEditDialog(this, tr("New Gradient"), fill_gradient, m_colorList, m_doc, &dialogGradients, true));
                if (!dia->exec())
                        return;

                dialogGradients.insert(dia->name(), dia->gradient());
                QTreeWidgetItem *lg = updateGradientList(dia->name());
                if (lg != nullptr)
                {
                        dataTree->expandItem(lg->parent());
                        dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
                }
                itemSelected(dataTree->currentItem());
                modified = true;
        }
        else if ((it->parent() == colorItems) || (it == colorItems))
        {
                ScColor tmpColor(0, 0, 0, 0);
                QScopedPointer<CMYKChoose> dia(new CMYKChoose(this, m_doc, tmpColor, tr("New Color"), &m_colorList, true));
                if (!dia->exec())
                        return;

                dia->Farbe.setSpotColor(dia->isSpotColor());
                m_colorList.insert(dia->colorName(), dia->Farbe);
                QTreeWidgetItem *lg = updateColorList(dia->colorName());
                if (lg != nullptr)
                {
                        dataTree->expandItem(lg->parent());
                        dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
                }
                itemSelected(dataTree->currentItem());
                modified = true;
        }
        else if ((it->parent() == patternItems) || (it == patternItems))
        {
                loadPatternDir();
                updateColorList();
                updateGradientList();
                updatePatternList();
                itemSelected(nullptr);
        }
}

void ColorsAndFillsDialog::editColorItem()
{
        if (paletteLocked)
                return;
        const QTreeWidgetItem* it = dataTree->currentItem();
        if (!it)
                return;

        if (it->parent() == gradientItems)
        {
                QString gradN = it->text(0);
                QString patternName = origNames[it->text(0)];
                QScopedPointer<gradientEditDialog> dia(new gradientEditDialog(this, gradN, dialogGradients[gradN], m_colorList, m_doc, &dialogGradients, false));
                if (!dia->exec())
                        return;

                QString newName = dia->name();
                if (newName != gradN)
                {
                        origNames.remove(patternName);
                        origNames.insert(newName, patternName);
                        replaceMap.insert(patternName, newName);
                        dialogGradients.remove(gradN);
                        dialogGradients.insert(newName, dia->gradient());
                }
                else
                        dialogGradients[gradN] = dia->gradient();
                QStringList patterns = dialogPatterns.keys();
                for (int c = 0; c < dialogPatterns.count(); ++c)
                {
                        ScPattern pa = dialogPatterns[patterns[c]];
                        for (int o = 0; o < pa.items.count(); o++)
                        {
                                PageItem *ite = pa.items.at(o);
                                if (ite->gradient() == gradN)
                                        ite->setGradient(newName);
                                if (ite->strokeGradient() == gradN)
                                        ite->setStrokeGradient(newName);
                                if (ite->gradientMask() == gradN)
                                        ite->setGradientMask(newName);
                        }
                        PageItem *ite = pa.items.at(0);
                        dialogPatterns[patterns[c]].pattern = ite->DrawObj_toImage(pa.items, 1.0);
                }
                QTreeWidgetItem *lg = updateGradientList(dia->name());
                if (lg != nullptr)
                {
                        dataTree->expandItem(lg->parent());
                        dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
                }
                itemSelected(dataTree->currentItem());
                modified = true;
        }
        else if (it->parent() == colorItems)
        {
                ScColor tmpColor = m_colorList[it->text(0)];
                QScopedPointer<CMYKChoose> dia(new CMYKChoose(this, m_doc, tmpColor, it->text(0), &m_colorList, false));
                if (!dia->exec())
                        return;

                dia->Farbe.setSpotColor(dia->isSpotColor());
                dia->Farbe.setRegistrationColor(tmpColor.isRegistrationColor());
                m_colorList[dia->colorName()] = dia->Farbe;
                if (it->text(0) != dia->colorName())
                {
                        replaceColorMap.insert(it->text(0), dia->colorName());
                        m_colorList.remove(it->text(0));
                }
                updateGradientColors(dia->colorName(), it->text(0));
                updateGradientList();
                updatePatternList();
                QTreeWidgetItem *lg = updateColorList(dia->colorName());
                if (lg != nullptr)
                {
                        dataTree->expandItem(lg->parent());
                        dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
                }
                itemSelected(dataTree->currentItem());
                modified = true;
        }
        else if (it->parent() == patternItems)
        {
                QString patternName = origNames[it->text(0)];
                QString newName = "";
                Query dia(this, "tt", true, tr("&Name:"), tr("Rename Entry"));
                dia.setEditText(it->text(0), true);
                dia.setTestList(dialogPatterns.keys());
                if (!dia.exec())
                        return;

                newName = dia.getEditText();
                ScPattern pat = dialogPatterns.take(it->text(0));
                dialogPatterns.insert(newName, pat);
                replaceMapPatterns.insert(patternName, newName);
                origNamesPatterns.remove(it->text(0));
                origNamesPatterns.insert(newName, patternName);
                QStringList patterns = dialogPatterns.keys();
                for (int c = 0; c < dialogPatterns.count(); ++c)
                {
                        ScPattern pa = dialogPatterns[patterns[c]];
                        for (int o = 0; o < pa.items.count(); o++)
                        {
                                PageItem *ite = pa.items.at(o);
                                if ((ite->pattern() == patternName) && ((ite->GrType == 8) || (ite->itemType() == PageItem::Symbol)))
                                        ite->setPattern(newName);
                                if (!ite->strokePattern().isEmpty())
                                {
                                        if (ite->strokePattern() == patternName)
                                                ite->setStrokePattern(newName);
                                }
                                if (!ite->patternMask().isEmpty())
                                {
                                        if (ite->patternMask() == patternName)
                                                ite->setPatternMask(newName);
                                }
                        }
                }
                QTreeWidgetItem *lg = updatePatternList(newName);
                if (lg != nullptr)
                {
                        dataTree->expandItem(lg->parent());
                        dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
                }
                itemSelected(dataTree->currentItem());
        }
}

void ColorsAndFillsDialog::duplicateColorItem()
{
        if (paletteLocked)
                return;
        const QTreeWidgetItem* it = dataTree->currentItem();
        if (!it)
                return;

        if (it->parent() == gradientItems)
        {
                QString gradN = tr("Copy of %1").arg(it->text(0));
                dialogGradients.insert(gradN, dialogGradients[it->text(0)]);
                origNames.insert(gradN, gradN);
                QString patternName = origNames[gradN];
                QScopedPointer<gradientEditDialog> dia(new gradientEditDialog(this, gradN, dialogGradients[gradN], m_colorList, m_doc, &dialogGradients, false));
                if (!dia->exec())
                {
                        dialogGradients.remove(gradN);
                        origNames.remove(gradN);
                        return;
                }

                QString newName = dia->name();
                if (newName != gradN)
                {
                        origNames.remove(patternName);
                        origNames.insert(newName, patternName);
                        replaceMap.insert(patternName, newName);
                        dialogGradients.remove(gradN);
                        dialogGradients.insert(newName, dia->gradient());
                }
                else
                        dialogGradients[gradN] = dia->gradient();
                updatePatternList();
                QTreeWidgetItem *lg = updateGradientList(dia->name());
                if (lg != nullptr)
                {
                        dataTree->expandItem(lg->parent());
                        dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
                }
                itemSelected(dataTree->currentItem());
                modified = true;
        }
        else if (it->parent() == colorItems)
        {
                QString nam = tr("Copy of %1").arg(it->text(0));
                m_colorList.insert(nam, m_colorList[it->text(0)]);
                ScColor tmpColor = m_colorList[nam];

                QScopedPointer<CMYKChoose> dia(new CMYKChoose(this, m_doc, tmpColor, nam, &m_colorList, false));
                if (!dia->exec())
                {
                        m_colorList.remove(nam);
                        return;
                }

                dia->Farbe.setSpotColor(dia->isSpotColor());
                dia->Farbe.setRegistrationColor(tmpColor.isRegistrationColor());
                m_colorList[dia->colorName()] = dia->Farbe;
                if (nam != dia->colorName())
                {
                        replaceColorMap.insert(nam, dia->colorName());
                        m_colorList.remove(nam);
                }
                updateGradientColors(dia->colorName(), nam);
                updateGradientList();
                updatePatternList();
                QTreeWidgetItem *lg = updateColorList(dia->colorName());
                if (lg != nullptr)
                {
                        dataTree->expandItem(lg->parent());
                        dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
                }
                itemSelected(dataTree->currentItem());
                modified = true;
        }
}

void ColorsAndFillsDialog::removeColorItem()
{
        if (paletteLocked)
                return;
        QList<QTreeWidgetItem *> selItems = dataTree->selectedItems();
        if (selItems.count() > 1)
        {
                QStringList usedColors;
                QStringList colors;
                QStringList gradients;
                QStringList patterns;
                for (int a = 0; a < selItems.count(); a++)
                {
                        QTreeWidgetItem* it = selItems[a];
                        if (it == gradientItems)
                                continue;
                        if (it == colorItems)
                                continue;
                        if (it == patternItems)
                                continue;
                        if (isMandatoryColor(it->text(0)))
                                continue;
                        if (it->parent() == gradientItems)
                                gradients.append(it->text(0));
                        if (it->parent() == colorItems)
                                colors.append(it->text(0));
                        if (it->parent() == patternItems)
                                patterns.append(it->text(0));
                }
                for (int a = 0; a < gradients.count(); a++)
                {
                        dialogGradients.remove(gradients[a]);
                        replaceMap.insert(gradients[a], "");
                }
                bool hasUsed = false;
                ColorList UsedCG = getGradientColors();
                for (int a = 0; a < colors.count(); a++)
                {
                        if (UsedCG.contains(colors[a]) || inDocUsedColors.contains(colors[a]))
                        {
                                hasUsed = true;
                                usedColors.append(colors[a]);
                        }
                }
                if (hasUsed)
                {
                        ColorList dCols = m_colorList;
                        QString dColor = tr("Selected Colors");
                        for (int i = 0; i < usedColors.count(); i++)
                        {
                                dCols.remove(usedColors[i]);
                        }
                        dCols.insert(dColor , ScColor());
                        DelColor *dia = new DelColor(this, dCols, dColor, true);
                        if (dia->exec())
                        {
                                QString replacementColor(dia->getReplacementColor());
                                for (int i = 0; i < colors.count(); i++)
                                {
                                        dColor = colors[i];
                                        if (replacementColor == CommonStrings::tr_NoneColor)
                                                replacementColor = CommonStrings::None;
                                        if (replaceColorMap.values().contains(dColor))
                                        {
                                                QMap<QString,QString>::Iterator itt;
                                                for (itt = replaceColorMap.begin(); itt != replaceColorMap.end(); ++itt)
                                                {
                                                        if (itt.value() == dColor)
                                                                itt.value() = replacementColor;
                                                }
                                        }
                                        replaceColorMap.insert(dColor, replacementColor);
                                        m_colorList.remove(dColor);
                                        updateGradientColors(replacementColor, dColor);
                                }
                                modified = true;
                        }
                        delete dia;
                }
                else
                {
                        for (int a = 0; a < colors.count(); a++)
                        {
                                replaceColorMap.insert(colors[a], "Black");
                                m_colorList.remove(colors[a]);
                        }
                        modified = true;
                }
                updatePatternList();
                updateGradientList();
                updateColorList();
                itemSelected(nullptr);
        }
        else
        {
                QTreeWidgetItem* it = dataTree->currentItem();
                if (!it)
                        return;
                if ((it->parent() == gradientItems) || (it == gradientItems))
                {
                        if (it == gradientItems)
                        {
                                int t = ScMessageBox::warning(this, CommonStrings::trWarning, tr("Do you really want to clear all your gradients?"),
                                                QMessageBox::Yes | QMessageBox::No,
                                                QMessageBox::No,        // GUI default
                                                QMessageBox::Yes);      // batch default
                                if (t == QMessageBox::No)
                                        return;
                                replaceMap.clear();
                                for (QHash<QString, VGradient>::Iterator it = dialogGradients.begin(); it != dialogGradients.end(); ++it)
                                {
                                        replaceMap.insert(it.key(), "");
                                }
                                dialogGradients.clear();
                        }
                        else
                        {
                                dialogGradients.remove(it->text(0));
                                replaceMap.insert(it->text(0), "");
                        }
                }
                else if ((it->parent() == colorItems) || (it == colorItems))
                {
                        if (it == colorItems)
                        {
                                int t = ScMessageBox::warning(this, CommonStrings::trWarning, tr("Do you really want to clear all your colors and gradients?"),
                                                QMessageBox::Yes | QMessageBox::No,
                                                QMessageBox::No,        // GUI default
                                                QMessageBox::Yes);      // batch default
                                if (t == QMessageBox::No)
                                        return;
                                replaceMap.clear();
                                for (QHash<QString, VGradient>::Iterator it = dialogGradients.begin(); it != dialogGradients.end(); ++it)
                                {
                                        replaceMap.insert(it.key(), "");
                                }
                                replaceColorMap.clear();
                                for (ColorList::Iterator it = m_colorList.begin(); it != m_colorList.end(); ++it)
                                {
                                        replaceColorMap.insert(it.key(), "Black");
                                }
                                dialogPatterns.clear();
                                dialogGradients.clear();
                                m_colorList.clear();
                                m_colorList.ensureDefaultColors();
                        }
                        else
                        {
                                QString dColor = it->text(0);
                                if (isMandatoryColor(dColor))
                                        return;
                                ColorList UsedCG = getGradientColors();
                                if (inDocUsedColors.contains(dColor) || UsedCG.contains(dColor))
                                {
                                        QScopedPointer<DelColor> dia(new DelColor(this, m_colorList, dColor, true));
                                        if (dia->exec())
                                        {
                                                QString replacementColor(dia->getReplacementColor());
                                                if (replacementColor == CommonStrings::tr_NoneColor)
                                                        replacementColor = CommonStrings::None;
                                                if (replaceColorMap.values().contains(dColor))
                                                {
                                                        QMap<QString,QString>::Iterator itt;
                                                        for (itt = replaceColorMap.begin(); itt != replaceColorMap.end(); ++itt)
                                                        {
                                                                if (itt.value() == dColor)
                                                                        itt.value() = replacementColor;
                                                        }
                                                }
                                                replaceColorMap.insert(dColor, replacementColor);
                                                m_colorList.remove(dColor);
                                                updateGradientColors(replacementColor, dColor);
                                        }
                                }
                                else
                                {
                                        replaceColorMap.insert(dColor, "Black");
                                        updateGradientColors("Black", dColor);
                                        m_colorList.remove(dColor);
                                }
                        }
                }
                else if ((it->parent() == patternItems) || (it == patternItems))
                {
                        if (it == patternItems)
                        {
                                int t = ScMessageBox::warning(this, CommonStrings::trWarning, tr("Do you really want to clear all your patterns?"),
                                                        QMessageBox::Yes | QMessageBox::No,
                                                        QMessageBox::No,        // GUI default
                                                        QMessageBox::Yes);      // batch default
                                if (t == QMessageBox::No)
                                        return;
                                replaceMapPatterns.clear();
                                for (QHash<QString, ScPattern>::Iterator it = dialogPatterns.begin(); it != dialogPatterns.end(); ++it)
                                {
                                        replaceMapPatterns.insert(it.key(), "");
                                }
                                dialogPatterns.clear();
                        }
                        else if (it->parent() == patternItems)
                        {
                                QStringList patterns2Del;
                                QStringList mainPatterns = dialogPatterns.keys();
                                for (int a = 0; a < mainPatterns.count(); a++)
                                {
                                        if (mainPatterns[a] != it->text(0))
                                        {
                                                QStringList subPatterns;
                                                subPatterns = getUsedPatternsHelper(mainPatterns[a], subPatterns);
                                                if (subPatterns.contains(it->text(0)))
                                                        patterns2Del.append(mainPatterns[a]);
                                        }
                                }
                                patterns2Del.append(it->text(0));
                                for (int a = 0; a < patterns2Del.count(); a++)
                                {
                                        dialogPatterns.remove(patterns2Del[a]);
                                }
                        }
                }
                updatePatternList();
                updateGradientList();
                updateColorList();
                itemSelected(nullptr);
                modified = true;
        }
}

QStringList ColorsAndFillsDialog::getUsedPatternsHelper(const QString& pattern, QStringList &results) const
{
        const ScPattern *pat = &dialogPatterns[pattern];
        QStringList pats;

        for (int c = 0; c < pat->items.count(); ++c)
        {
                if ((pat->items.at(c)->GrType == Gradient_Pattern) || (pat->items.at(c)->itemType() == PageItem::Symbol))
                {
                        const QString& patName = pat->items.at(c)->pattern();
                        if (!patName.isEmpty() && !results.contains(patName))
                                pats.append(patName);
                }
                const QString& pat2 = pat->items.at(c)->strokePattern();
                if (!pat2.isEmpty() && !results.contains(pat2))
                        pats.append(pat->items.at(c)->strokePattern());
                const QString& pat3 = pat->items.at(c)->patternMask();
                if (!pat3.isEmpty() && !results.contains(pat3))
                        pats.append(pat->items.at(c)->patternMask());
        }
        if (!pats.isEmpty())
        {
                results = pats;
                for (int c = 0; c < pats.count(); ++c)
                {
                        getUsedPatternsHelper(pats[c], results);
                }
        }
/*      QStringList pats;
        pats.clear();
        for (int c = 0; c < pat->items.count(); ++c)
        {
                if ((!results.contains(pat->items.at(c)->pattern())) && ((pat->items.at(c)->GrType == Gradient_Pattern) || (pat->items.at(c)->itemType() == PageItem::Symbol)))
                        pats.append(pat->items.at(c)->pattern());
        }
        if (!pats.isEmpty())
        {
                results = pats;
                for (int c = 0; c < pats.count(); ++c)
                {
                        getUsedPatternsHelper(pats[c], results);
                }
        } */

        return results;
}

void ColorsAndFillsDialog::removeUnusedColorItem()
{
        if (paletteLocked)
                return;
        QTreeWidgetItem* it = dataTree->currentItem();
        if (!it)
                return;

        if ((it->parent() == colorItems) || (it == colorItems))
        {
                ColorList UsedC;
                ColorList::Iterator it;
                ColorList UsedCG = getGradientColors();
                if (mainWin->HaveDoc)
                {
                        m_colorList = inDocUsedColors;
                        for (it = UsedCG.begin(); it != UsedCG.end(); ++it)
                        {
                                if (!m_colorList.contains(it.key()))
                                        m_colorList.insert(it.key(), it.value());
                        }
                }
                else
                        m_colorList = UsedCG;
                m_colorList.ensureDefaultColors();
                updatePatternList();
                updateGradientList();
                updateColorList();
                itemSelected(nullptr);
                modified = true;
        }
}

void ColorsAndFillsDialog::importColorItems()
{
        const QTreeWidgetItem* it = dataTree->currentItem();
        if (!it)
                return;

        if ((it->parent() == gradientItems) || (it == gradientItems))
        {
                QString allFormats = tr("All Supported Formats")+" (";
                allFormats += "*.sgr *.SGR";
                allFormats += " *.ggr *.GGR";
                allFormats += ");;";
                QString formats = tr("Scribus Gradient Files \"*.sgr\" (*.sgr *.SGR);;");
                formats += tr("Gimp Gradient Files \"*.ggr\" (*.ggr *.GGR);;");
                formats += tr("All Files (*)");
                allFormats += formats;

                PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
                QString wdir = dirs->get("gradients", ".");

                CustomFDialog dia(this, wdir, tr("Open"), allFormats, fdHidePreviewCheckBox | fdExistingFiles | fdDisableOk);
                if (dia.exec() != QDialog::Accepted)
                        return;
               
                QString fileName = dia.selectedFile();
                if (!fileName.isEmpty())
                {
                        PrefsManager::instance().prefsFile->getContext("dirs")->set("gradients", fileName.left(fileName.lastIndexOf("/")));
                        QFileInfo fi(fileName);
                        QString ext = fi.suffix().toLower();
                        if (ext == "sgr")
                                loadScribusFormat(fileName);
                        else if (ext == "ggr")
                                loadGimpFormat(fileName);
                        updateGradientList();
                        updateColorList();
                        itemSelected(nullptr);
                        modified = true;
                }
        }
        else if ((it->parent() == colorItems) || (it == colorItems))
        {
                QStringList allFormatsV = LoadSavePlugin::getExtensionsForColors();
                allFormatsV.removeAll("sla");
                allFormatsV.removeAll("scd");
                allFormatsV.removeAll("sla.gz");
                allFormatsV.removeAll("scd.gz");
                allFormatsV.removeAll("ai");
                QString extra = allFormatsV.join(" *.");
                extra.prepend(" *.");

                PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
                QString wdir = dirs->get("colors", ".");
                QString docexts("*.sla *.sla.gz *.scd *.scd.gz");
                QString aiepsext(FormatsManager::instance()->extensionListForFormat(FormatsManager::EPS|FormatsManager::PS|FormatsManager::AI, 0));
                QString ooexts(" *.acb *.aco *.ase *.cxf *.gpl *.sbz *.skp *.soc *.xml");
                ooexts += extra;
                QString filter = tr("All Supported Formats (%1);;Documents (%2);;Other Files (%3);;All Files (*)").arg(docexts+" "+aiepsext+ooexts, docexts, aiepsext+ooexts);
               
                CustomFDialog dia(this, wdir, tr("Import Colors"), filter, fdHidePreviewCheckBox | fdDisableOk);
                if (dia.exec() != QDialog::Accepted)
                        return;

                QString fileName = dia.selectedFile();
                if (!fileName.isEmpty())
                        dirs->set("colors", fileName.left(fileName.lastIndexOf("/")));
                if (!importColorsFromFile(fileName, m_colorList))
                        ScMessageBox::information(this, tr("Information"), "<qt>" + tr("The file %1 does not contain colors which can be imported.\nIf the file was a PostScript-based, try to import it with File -&gt; Import. \nNot all files have DSC conformant comments where the color descriptions are located.\n This prevents importing colors from some files.\nSee the Edit Colors section of the documentation for more details.").arg(fileName) + "</qt>");
                else
                {
                        m_colorList.ensureDefaultColors();
                        updateGradientList();
                        updateColorList();
                        modified = true;
                }
                itemSelected(nullptr);
        }
        else if ((it->parent() == patternItems) || (it == patternItems))
        {
                QString fileName;
                QStringList formats;
                QString allFormats = tr("All Supported Formats")+" (";
                int fmtCode = FORMATID_FIRSTUSER;
                const FileFormat *fmt = LoadSavePlugin::getFormatById(fmtCode);
                while (fmt != nullptr)
                {
                        if (fmt->load)
                        {
                                formats.append(fmt->filter);
                                int an = fmt->filter.indexOf("(");
                                int en = fmt->filter.indexOf(")");
                                while (an != -1)
                                {
                                        allFormats += fmt->filter.mid(an+1, en-an-1)+" ";
                                        an = fmt->filter.indexOf("(", en);
                                        en = fmt->filter.indexOf(")", an);
                                }
                        }
                        fmtCode++;
                        fmt = LoadSavePlugin::getFormatById(fmtCode);
                }
                allFormats += "*.sce *.SCE ";
                formats.append("Scribus Objects (*.sce *.SCE)");
                QString form1 = "";
                QString form2 = "";
                QStringList imgFormats;
                bool jpgFound = false;
                bool tiffFound = false;
                for (int i = 0; i < QImageReader::supportedImageFormats().count(); ++i )
                {
                        form1 = QString(QImageReader::supportedImageFormats().at(i)).toLower();
                        form2 = QString(QImageReader::supportedImageFormats().at(i)).toUpper();
                        if ((form1 == "png") || (form1 == "xpm") || (form1 == "gif"))
                        {
                                formats.append(form2 + " (*."+form1+" *."+form2+")");
                                allFormats += "*."+form1+" *."+form2+" ";
                                imgFormats.append(form1);
                        }
                        else if ((form1 == "jpg") || (form1 == "jpeg"))
                        {
                                // JPEG is a special case because both .jpg and .jpeg
                                // are acceptable extensions.
                                if (!jpgFound)
                                {
                                        formats.append("JPEG (*.jpg *.jpeg *.JPG *.JPEG)");
                                        allFormats += "*.jpg *.jpeg *.JPG *.JPEG ";
                                        imgFormats.append("jpeg");
                                        imgFormats.append("jpg");
                                        jpgFound = true;
                                }
                        }
                        else if ((form1 == "tif") || (form1 == "tiff"))
                        {
                                if (!tiffFound)
                                {
                                        formats.append("TIFF (*.tif *.tiff *.TIF *.TIFF)");
                                        allFormats += "*.tif *.tiff *.TIF *.TIFF ";
                                        imgFormats.append("tif");
                                        imgFormats.append("tiff");
                                        tiffFound = true;
                                }
                        }
                        else if (form1 != "svg")
                        {
                                imgFormats.append(form1);
                                allFormats += "*."+form1+" *."+form2+" ";
                        }
                }
                if (!tiffFound)
                {
                        formats.append("TIFF (*.tif *.tiff *.TIF *.TIFF)");
                        allFormats += "*.tif *.tiff *.TIF *.TIFF ";
                }
                if (!jpgFound)
                {
                        formats.append("JPEG (*.jpg *.jpeg *.JPG *.JPEG)");
                        allFormats += "*.jpg *.jpeg *.JPG *.JPEG ";
                }
                formats.append("PSD (*.psd *.PSD)");
                formats.append("Gimp Patterns (*.pat *.PAT)");
                allFormats += "*.psd *.PSD ";
                allFormats += "*.pat *.PAT);;";
                imgFormats.append("tif");
                imgFormats.append("tiff");
                imgFormats.append("pat");
                imgFormats.append("psd");
        //      imgFormats.append("pdf");
                imgFormats.append("eps");
                imgFormats.append("epsi");
                imgFormats.append("ps");
                formats.sort();
                allFormats += formats.join(";;");

                PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
                QString wdir = dirs->get("patterns", ".");
                CustomFDialog dia(this, wdir, tr("Open"), allFormats, fdHidePreviewCheckBox | fdExistingFiles | fdDisableOk);
                if (dia.exec() != QDialog::Accepted)
                        return;

                fileName = dia.selectedFile();
                if (fileName.isEmpty())
                        return;

                QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
                PrefsManager::instance().prefsFile->getContext("dirs")->set("patterns", fileName.left(fileName.lastIndexOf("/")));
                QFileInfo fi(fileName);
                if ((fi.suffix().toLower() == "sce") || (!imgFormats.contains(fi.suffix().toLower())))
                {
                        loadVectors(fileName);
                }
                else
                {
                        QString patNam = fi.baseName().trimmed().simplified().replace(" ", "_");
                        ScPattern pat;
                        pat.setDoc(m_doc);
                        pat.setPattern(fileName);
                        if (!dialogPatterns.contains(patNam))
                        {
                                dialogPatterns.insert(patNam, pat);
                                origNamesPatterns.insert(patNam, patNam);
                        }
                }
                updateColorList();
                updateGradientList();
                updatePatternList();
                itemSelected(nullptr);
                QGuiApplication::restoreOverrideCursor();
        }
}

void ColorsAndFillsDialog::loadPatternDir()
{
        PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
        QString wdir = dirs->get("patterndir", ".");
        QString fileName = QFileDialog::getExistingDirectory(this, tr("Choose a Directory"), wdir);
        if (fileName.isEmpty())
                return;

        QStringList formats;
        formats += "eps";
        formats += "epsi";
        formats += "pdf";
        QString form1 = "";
        for (int i = 0; i < QImageReader::supportedImageFormats().count(); ++i)
        {
                form1 = QString(QImageReader::supportedImageFormats().at(i)).toLower();
                if (form1 == "jpeg")
                        form1 = "jpg";
                if ((form1 == "png") || (form1 == "xpm") || (form1 == "gif"))
                formats += form1;
                else if (form1 == "jpg")
                {
                        formats += "jpg";
                        formats += "jpeg";
                }
        }
        formats += "tif";
        formats += "tiff";
        formats += "psd";
        formats += "pat";
        QDir d(fileName, "*", QDir::Name, QDir::Files | QDir::Readable | QDir::NoSymLinks);
        if ((!d.exists()) || (d.count() == 0))
                return;

        mainWin->setStatusBarInfoText( tr("Loading Patterns"));
        mainWin->mainWindowProgressBar->reset();
        mainWin->mainWindowProgressBar->setMaximum(d.count() * 2);

        QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
        QGuiApplication::processEvents(QEventLoop::ExcludeUserInputEvents);

        for (uint dc = 0; dc < d.count(); ++dc)
        {
                mainWin->mainWindowProgressBar->setValue(dc);
                QGuiApplication::processEvents(QEventLoop::ExcludeUserInputEvents);

                QFileInfo fi(QDir::cleanPath(QDir::toNativeSeparators(fileName + "/" + d[dc])));
                QString ext = fi.suffix().toLower();
                if ((ext == "sce") || (!formats.contains(ext)))
                        loadVectors(QDir::cleanPath(QDir::toNativeSeparators(fileName + "/" + d[dc])));
        }
        for (uint dc = 0; dc < d.count(); ++dc)
        {
                mainWin->mainWindowProgressBar->setValue(d.count() + dc);
                QGuiApplication::processEvents(QEventLoop::ExcludeUserInputEvents);

                QFileInfo fi(QDir::cleanPath(QDir::toNativeSeparators(fileName + "/" + d[dc])));
                QString ext = fi.suffix().toLower();
                if ((ext == "sce") || (!formats.contains(ext)))
                        continue;
                if (!formats.contains(ext))
                        continue;

                QString patNam = fi.baseName().trimmed().simplified().replace(" ", "_");
                if (!dialogPatterns.contains(patNam))
                {
                        ScPattern pat;
                        pat.setDoc(m_doc);
                        pat.setPattern(QDir::cleanPath(QDir::toNativeSeparators(fileName + "/" + d[dc])));
                        dialogPatterns.insert(patNam, pat);
                        origNamesPatterns.insert(patNam, patNam);
                }
        }
        d.cdUp();
        dirs->set("patterndir", d.absolutePath());

        QGuiApplication::restoreOverrideCursor();

        mainWin->setStatusBarInfoText("");
        mainWin->mainWindowProgressBar->reset();
}

void ColorsAndFillsDialog::loadVectors(const QString& data)
{
        int storedPageNum = m_doc->currentPageNumber();
        int storedContentsX = m_doc->view()->contentsX();
        int storedContentsY = m_doc->view()->contentsY();
        double storedViewScale = m_doc->view()->scale();
        FPoint stored_minCanvasCoordinate = m_doc->minCanvasCoordinate;
        FPoint stored_maxCanvasCoordinate = m_doc->maxCanvasCoordinate;

        m_doc->PageColors = m_colorList;
        m_doc->docGradients = dialogGradients;
        UndoManager::instance()->setUndoEnabled(false);
        m_doc->setLoading(true);
        QFileInfo fi(data);
        QString patNam = fi.baseName().trimmed().simplified().replace(" ", "_");
        uint ac = m_doc->Items->count();
        uint ap = m_doc->docPatterns.count();
        bool savedAlignGrid = m_doc->SnapGrid;
        bool savedAlignGuides = m_doc->SnapGuides;
        bool savedAlignElement = m_doc->SnapElement;
        m_doc->SnapGrid = false;
        m_doc->SnapGuides = false;
        m_doc->SnapElement = false;
        if (fi.suffix().toLower() == "sce")
        {
                ScriXmlDoc ss;
                ss.readElem(data, m_doc, m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset(), true, true);
        }
        else
        {
                FileLoader *fileLoader = new FileLoader(data);
                int testResult = fileLoader->testFile();
                delete fileLoader;
                if ((testResult != -1) && (testResult >= FORMATID_FIRSTUSER))
                {
                        const FileFormat * fmt = LoadSavePlugin::getFormatById(testResult);
                        if (fmt)
                        {
                                fmt->setupTargets(m_doc, nullptr, mainWin, nullptr, &(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts));
                                fmt->loadFile(data, LoadSavePlugin::lfUseCurrentPage|LoadSavePlugin::lfInteractive|LoadSavePlugin::lfScripted|LoadSavePlugin::lfKeepPatterns|LoadSavePlugin::lfLoadAsPattern);
                        }
                }
        }
        m_doc->SnapGrid = savedAlignGrid;
        m_doc->SnapGuides = savedAlignGuides;
        m_doc->SnapElement = savedAlignElement;
        uint ae = m_doc->Items->count();
        if (ac != ae)
        {
                for (uint as = ac; as < ae; ++as)
                {
                        PageItem* ite = m_doc->Items->at(ac);
                        if (ite->itemType() == PageItem::PathText)
                                ite->updatePolyClip();
                        else
                                ite->layout();
                }
                ScPattern pat;
                pat.setDoc(m_doc);
                PageItem* currItem = m_doc->Items->at(ac);
                double minx =  std::numeric_limits<double>::max();
                double miny =  std::numeric_limits<double>::max();
                double maxx = -std::numeric_limits<double>::max();
                double maxy = -std::numeric_limits<double>::max();
                double x1, x2, y1, y2;
                currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
                minx = qMin(minx, x1);
                miny = qMin(miny, y1);
                maxx = qMax(maxx, x2);
                maxy = qMax(maxy, y2);
                pat.pattern = currItem->DrawObj_toImage(qMin(qMax(maxx - minx, maxy - miny), 500.0));
                pat.width = maxx - minx;
                pat.height = maxy - miny;
                currItem->setXYPos(0, 0, true);
                currItem->setWidthHeight(maxx - minx, maxy - miny, true);
                currItem->groupWidth = maxx - minx;
                currItem->groupHeight = maxy - miny;
                currItem->gWidth = maxx - minx;
                currItem->gHeight = maxy - miny;
                for (uint as = ac; as < ae; ++as)
                {
                        pat.items.append(m_doc->Items->takeAt(ac));
                }
                if (!dialogPatterns.contains(patNam))
                {
                        dialogPatterns.insert(patNam, pat);
                        origNamesPatterns.insert(patNam, patNam);
                }
                for (QHash<QString, ScPattern>::Iterator it = m_doc->docPatterns.begin(); it != m_doc->docPatterns.end(); ++it)
                {
                        if (!origPatterns.contains(it.key()))
                        {
                                dialogPatterns.insert(it.key(), it.value());
                                origNamesPatterns.insert(it.key(), it.key());
                        }
                }
        }
        else
        {
                uint ape = m_doc->docPatterns.count();
                if (ap != ape)
                {
                        for (QHash<QString, ScPattern>::Iterator it = m_doc->docPatterns.begin(); it != m_doc->docPatterns.end(); ++it)
                        {
                                if (!origPatterns.contains(it.key()))
                                {
                                        dialogPatterns.insert(it.key(), it.value());
                                        origNamesPatterns.insert(it.key(), it.key());
                                }
                        }
                }
        }
        m_doc->setLoading(false);
        m_colorList = m_doc->PageColors;
        dialogGradients = m_doc->docGradients;
        UndoManager::instance()->setUndoEnabled(true);

        m_doc->minCanvasCoordinate = stored_minCanvasCoordinate;
        m_doc->maxCanvasCoordinate = stored_maxCanvasCoordinate;
        m_doc->view()->setScale(storedViewScale);
        m_doc->setCurrentPage(m_doc->DocPages.at(storedPageNum));
        m_doc->view()->setContentsPos(static_cast<int>(storedContentsX * storedViewScale), static_cast<int>(storedContentsY * storedViewScale));
}

bool ColorsAndFillsDialog::isMandatoryColor(const QString& colorName) const
{
        if (colorName == "Black" || colorName == "White")
                return true;
        ScColor color = m_colorList.value(colorName, ScColor());
        return color.isRegistrationColor();
}

QString ColorsAndFillsDialog::getColorTooltip(const ScColor& color) const
{
        QString tooltip;
        if (color.getColorModel() == colorModelRGB)
        {
                int r, g, b;
                color.getRawRGBColor(&r, &g, &b);
                tooltip = tr("R: %1 G: %2 B: %3").arg(r).arg(g).arg(b);
        }
        else if (color.getColorModel() == colorModelCMYK)
        {
                double c, m, y, k;
                color.getCMYK(&c, &m, &y, &k);
                return tr("C: %1% M: %2% Y: %3% K: %4%").arg(c * 100, 0, 'f', 2).arg(m * 100, 0, 'f', 2).arg(y * 100, 0, 'f', 2).arg(k * 100, 0, 'f', 2);
        }
        else if (color.getColorModel() == colorModelLab)
        {
                double L, a, b;
                color.getLab(&L, &a, &b);
                tooltip = tr("L: %1 a: %2 b: %3").arg(L, 0, 'f', 2).arg(a, 0, 'f', 2).arg(b, 0, 'f', 2);
        }
        return tooltip;
}

ColorList ColorsAndFillsDialog::getGradientColors() const
{
        ColorList colorList;
        for (auto itg = dialogGradients.begin(); itg != dialogGradients.end(); ++itg)
        {
                QList<VColorStop*> cstops = itg.value().colorStops();
                for (int cst = 0; cst < itg.value().stops(); ++cst)
                {
                        if ((!colorList.contains(cstops.at(cst)->name)) && (cstops.at(cst)->name != CommonStrings::None))
                                colorList.insert(cstops.at(cst)->name, m_colorList[cstops.at(cst)->name]);
                }
        }
        QStringList patterns = dialogPatterns.keys();
        for (int c = 0; c < dialogPatterns.count(); ++c)
        {
                ScPattern pa = dialogPatterns[patterns[c]];
                for (int o = 0; o < pa.items.count(); o++)
                {
                        PageItem *ite = pa.items.at(o);
                        if ((!colorList.contains(ite->lineColor())) && (ite->lineColor() != CommonStrings::None))
                                colorList.insert(ite->lineColor(), m_colorList[ite->lineColor()]);
                        if ((!colorList.contains(ite->fillColor())) && (ite->fillColor() != CommonStrings::None))
                                colorList.insert(ite->fillColor(), m_colorList[ite->fillColor()]);
                        QString gCol1, gCol2, gCol3, gCol4;
                        ite->get4ColorColors(gCol1, gCol2, gCol3, gCol4);
                        if ((!colorList.contains(gCol1)) && (gCol1 != CommonStrings::None))
                                colorList.insert(gCol1, m_colorList[gCol1]);
                        if ((!colorList.contains(gCol2)) && (gCol2 != CommonStrings::None))
                                colorList.insert(gCol2, m_colorList[gCol2]);
                        if ((!colorList.contains(gCol3)) && (gCol3 != CommonStrings::None))
                                colorList.insert(gCol3, m_colorList[gCol3]);
                        if ((!colorList.contains(gCol4)) && (gCol4 != CommonStrings::None))
                                colorList.insert(gCol4, m_colorList[gCol4]);
                        for (int grow = 0; grow < ite->meshGradientArray.count(); grow++)
                        {
                                for (int gcol = 0; gcol < ite->meshGradientArray[grow].count(); gcol++)
                                {
                                        MeshPoint mp = ite->meshGradientArray[grow][gcol];
                                        if ((!colorList.contains(mp.colorName)) && (mp.colorName != CommonStrings::None))
                                                colorList.insert(mp.colorName, m_colorList[mp.colorName]);
                                }
                        }
                        QList<VColorStop*> cstops = ite->fill_gradient.colorStops();
                        for (int cst = 0; cst < ite->fill_gradient.stops(); ++cst)
                        {
                                if ((!colorList.contains(cstops.at(cst)->name)) && (cstops.at(cst)->name != CommonStrings::None))
                                        colorList.insert(cstops.at(cst)->name, m_colorList[cstops.at(cst)->name]);
                        }
                        cstops = ite->stroke_gradient.colorStops();
                        for (int cst = 0; cst < ite->stroke_gradient.stops(); ++cst)
                        {
                                if ((!colorList.contains(cstops.at(cst)->name)) && (cstops.at(cst)->name != CommonStrings::None))
                                        colorList.insert(cstops.at(cst)->name, m_colorList[cstops.at(cst)->name]);
                        }
                        cstops = ite->mask_gradient.colorStops();
                        for (int cst = 0; cst < ite->mask_gradient.stops(); ++cst)
                        {
                                if ((!colorList.contains(cstops.at(cst)->name)) && (cstops.at(cst)->name != CommonStrings::None))
                                        colorList.insert(cstops.at(cst)->name, m_colorList[cstops.at(cst)->name]);
                        }
                }
        }
        colorList.remove(CommonStrings::None);
        return colorList;
}

void ColorsAndFillsDialog::updateGradientColors(const QString& newName, const QString& oldName)
{
        QHash<QString,VGradient>::Iterator itg;
        for (itg = dialogGradients.begin(); itg != dialogGradients.end(); ++itg)
        {
                QList<VColorStop*> cstops = itg.value().colorStops();
                for (int cst = 0; cst < itg.value().stops(); ++cst)
                {
                        if (oldName == cstops.at(cst)->name)
                        {
                                cstops.at(cst)->name = newName;
                                const ScColor& col = m_colorList[cstops.at(cst)->name];
                                cstops.at(cst)->color = ScColorEngine::getShadeColorProof(col, m_doc, cstops.at(cst)->shade);
                        }
                }
        }
        ColorList colorListBack = m_doc->PageColors;
        m_doc->PageColors = m_colorList;
        QStringList patterns = dialogPatterns.keys();
        for (int c = 0; c < dialogPatterns.count(); ++c)
        {
                ScPattern pa = dialogPatterns[patterns[c]];
                for (int o = 0; o < pa.items.count(); o++)
                {
                        PageItem *ite = pa.items.at(o);
                        if (oldName == ite->lineColor())
                                ite->setLineColor(newName);
                        if (oldName == ite->fillColor())
                                ite->setFillColor(newName);
                        QString gCol1, gCol2, gCol3, gCol4;
                        ite->get4ColorColors(gCol1, gCol2, gCol3, gCol4);
                        if (oldName == gCol1)
                                gCol1 = newName;
                        if (oldName == gCol2)
                                gCol2 = newName;
                        if (oldName == gCol3)
                                gCol3 = newName;
                        if (oldName == gCol4)
                                gCol4 = newName;
                        ite->set4ColorColors(gCol1, gCol2, gCol3, gCol4);
                        for (int grow = 0; grow < ite->meshGradientArray.count(); grow++)
                        {
                                for (int gcol = 0; gcol < ite->meshGradientArray[grow].count(); gcol++)
                                {
                                        MeshPoint mp = ite->meshGradientArray[grow][gcol];
                                        if (mp.colorName == oldName)
                                        {
                                                mp.colorName = newName;
                                                ite->setMeshPointColor(grow, gcol, mp.colorName, mp.shade, mp.transparency);
                                        }
                                }
                        }
                        QList<VColorStop*> cstops = ite->fill_gradient.colorStops();
                        for (int cst = 0; cst < ite->fill_gradient.stops(); ++cst)
                        {
                                if (oldName == cstops.at(cst)->name)
                                {
                                        cstops.at(cst)->name = newName;
                                        ite->SetQColor(&cstops.at(cst)->color, cstops.at(cst)->name, cstops.at(cst)->shade);
                                }
                        }
                        cstops = ite->stroke_gradient.colorStops();
                        for (int cst = 0; cst < ite->stroke_gradient.stops(); ++cst)
                        {
                                if (oldName == cstops.at(cst)->name)
                                {
                                        cstops.at(cst)->name = newName;
                                        ite->SetQColor(&cstops.at(cst)->color, cstops.at(cst)->name, cstops.at(cst)->shade);
                                }
                        }
                        cstops = ite->mask_gradient.colorStops();
                        for (int cst = 0; cst < ite->mask_gradient.stops(); ++cst)
                        {
                                if (oldName == cstops.at(cst)->name)
                                {
                                        cstops.at(cst)->name = newName;
                                        ite->SetQColor(&cstops.at(cst)->color, cstops.at(cst)->name, cstops.at(cst)->shade);
                                }
                        }
                }
                PageItem *ite = pa.items.at(0);
                dialogPatterns[patterns[c]].pattern = ite->DrawObj_toImage(pa.items, 1.0);
        }
        m_doc->PageColors = colorListBack;
}

void ColorsAndFillsDialog::loadGimpFormat(const QString& fileName)
{
        QFile f(fileName);
        if (f.open(QIODevice::ReadOnly))
        {
                ScTextStream ts(&f);
                QString tmp, dummy;
                QString gradientName = "";
                int numEntrys = 0;
                int entryCount = 0;
                int stopCount = 0;
                double left, middle, right, r0, g0, b0, a0, r1, g1, b1, a1;
                double oldr1 = 0.0;
                double oldg1 = 0.0;
                double oldb1 = 0.0;
                double olda1 = 0.0;
                tmp = ts.readLine();
                if (tmp.startsWith("GIMP Gradient"))
                {
                        tmp = ts.readLine();
                        ScTextStream CoE(&tmp, QIODevice::ReadOnly);
                        CoE >> dummy;
                        gradientName = CoE.readAll().trimmed();
                }
                if (!gradientName.isEmpty())
                {
                        QString stopName = gradientName+QString("_Stop%1");
                        QString stopNameInUse;
                        VGradient gra(VGradient::linear);
                        gra.clearStops();
                        QColor color;
                        tmp = ts.readLine();
                        ScTextStream CoE(&tmp, QIODevice::ReadOnly);
                        CoE >> numEntrys;
                        while (!ts.atEnd())
                        {
                                entryCount++;
                                tmp = ts.readLine();
                                ScTextStream Cval(&tmp, QIODevice::ReadOnly);
                                Cval >> left >> middle >> right >> r0 >> g0 >> b0 >> a0 >> r1 >> g1 >> b1 >> a1;
                                if ((entryCount == 1) && (entryCount < numEntrys))
                                {
                                        stopNameInUse = stopName.arg(stopCount);
                                        addGimpColor(stopNameInUse, r0, g0, b0);
                                        color = QColor(qRound(r0 * 255), qRound(g0 * 255), qRound(b0 * 255));
                                        gra.addStop(color, left, 0.5, a0, stopNameInUse, 100);
                                        stopCount++;
                                }
                                else if (entryCount == numEntrys)
                                {
                                        if ((entryCount != 1) && ((r0 != oldr1) || (g0 != oldg1) || (b0 != oldb1) || (a0 != olda1)))
                                        {
                                                stopNameInUse = stopName.arg(stopCount);
                                                addGimpColor(stopNameInUse, oldr1, oldg1, oldb1);
                                                color = QColor(qRound(oldr1 * 255), qRound(oldg1 * 255), qRound(oldb1 * 255));
                                                gra.addStop(color, left, 0.5, olda1, stopNameInUse, 100);
                                                stopCount++;
                                        }
                                        stopNameInUse = stopName.arg(stopCount);
                                        addGimpColor(stopNameInUse, r0, g0, b0);
                                        color = QColor(qRound(r0 * 255), qRound(g0 * 255), qRound(b0 * 255));
                                        gra.addStop(color, left, 0.5, a0, stopNameInUse, 100);
                                        stopCount++;
                                        stopNameInUse = stopName.arg(stopCount);
                                        addGimpColor(stopNameInUse, r1, g1, b1);
                                        color = QColor(qRound(r1 * 255), qRound(g1 * 255), qRound(b1 * 255));
                                        gra.addStop(color, right, 0.5, a1, stopNameInUse, 100);
                                        stopCount++;
                                }
                                else
                                {
                                        if ((r0 == oldr1) && (g0 == oldg1) && (b0 == oldb1) && (a0 == olda1))
                                        {
                                                stopNameInUse = stopName.arg(stopCount);
                                                addGimpColor(stopNameInUse, r0, g0, b0);
                                                color = QColor(qRound(r0 * 255), qRound(g0 * 255), qRound(b0 * 255));
                                                gra.addStop(color, left, 0.5, a0, stopNameInUse, 100);
                                                stopCount++;
                                        }
                                        else
                                        {
                                                stopNameInUse = stopName.arg(stopCount);
                                                addGimpColor(stopNameInUse, oldr1, oldg1, oldb1);
                                                color = QColor(qRound(oldr1 * 255), qRound(oldg1 * 255), qRound(oldb1 * 255));
                                                gra.addStop(color, left, 0.5, olda1, stopNameInUse, 100);
                                                stopCount++;
                                                stopNameInUse = stopName.arg(stopCount);
                                                addGimpColor(stopNameInUse, r0, g0, b0);
                                                color = QColor(qRound(r0 * 255), qRound(g0 * 255), qRound(b0 * 255));
                                                gra.addStop(color, left, 0.5, a0, stopNameInUse, 100);
                                                stopCount++;
                                        }
                                }
                                oldr1 = r1;
                                oldg1 = g1;
                                oldb1 = b1;
                                olda1 = a1;
                        }
                        if (!dialogGradients.contains(gradientName))
                                dialogGradients.insert(gradientName, gra);
                        else
                        {
                                QString tmp;
                                gradientName += "("+tmp.setNum(dialogGradients.count())+")";
                                dialogGradients.insert(gradientName, gra);
                        }
                }
                f.close();
        }
        /* File format is:
   *
   *   GIMP Gradient
   *   Name: name
   *   number_of_segments
   *   left middle right r0 g0 b0 a0 r1 g1 b1 a1 type coloring left_color_type
   *   left middle right r0 g0 b0 a0 r1 g1 b1 a1 type coloring right_color_type
   *   ...
   */

}

void ColorsAndFillsDialog::addGimpColor(QString &colorName, double r, double g, double b)
{
        ScColor lf;
        bool found = false;
        int hR, hG, hB;
        int Rc = qRound(r * 255);
        int Gc = qRound(g * 255);
        int Bc = qRound(b * 255);
        lf.setRgbColor(Rc, Gc, Bc);
        for (ColorList::Iterator it = m_colorList.begin(); it != m_colorList.end(); ++it)
        {
                if (it.value().getColorModel() == colorModelRGB)
                {
                        it.value().getRGB(&hR, &hG, &hB);
                        if ((Rc == hR) && (Gc == hG) && (Bc == hB))
                        {
                                colorName = it.key();
                                found = true;
                                return;
                        }
                }
        }
        if (!found)
        {
                m_colorList.insert(colorName, lf);
                hasImportedColors = true;
        }
}

void ColorsAndFillsDialog::loadScribusFormat(const QString& fileName)
{
        QFile f(fileName);
        if (!f.open(QIODevice::ReadOnly))
                return;
        QDomDocument docu("scridoc");
        QTextStream ts(&f);
        ts.setCodec("UTF-8");
        QString errorMsg;
        int errorLine = 0, errorColumn = 0;
        if (!docu.setContent(ts.readAll(), &errorMsg, &errorLine, &errorColumn) )
        {
                f.close();
                return;
        }
        f.close();
        QDomElement elem = docu.documentElement();
        if (elem.tagName() != "SCRIBUSGRADIENT")
                return;
        QDomNode DOC = elem.firstChild();
        while (!DOC.isNull())
        {
                QDomElement dc = DOC.toElement();
                if (dc.tagName()=="COLOR")
                {
                        ScColor lf;
                        if (dc.hasAttribute("SPACE"))
                        {
                                QString space = dc.attribute("SPACE");
                                if (space == "CMYK")
                                {
                                        double c = dc.attribute("C", "0").toDouble() / 100.0;
                                        double m = dc.attribute("M", "0").toDouble() / 100.0;
                                        double y = dc.attribute("Y", "0").toDouble() / 100.0;
                                        double k = dc.attribute("K", "0").toDouble() / 100.0;
                                        lf.setCmykColorF(c, m, y, k);
                                }
                                else if (space == "RGB")
                                {
                                        double r = dc.attribute("R", "0").toDouble() / 255.0;
                                        double g = dc.attribute("G", "0").toDouble() / 255.0;
                                        double b = dc.attribute("B", "0").toDouble() / 255.0;
                                        lf.setRgbColorF(r, g, b);
                                }
                                else if (space == "Lab")
                                {
                                        double L = dc.attribute("L", "0").toDouble();
                                        double a = dc.attribute("A", "0").toDouble();
                                        double b = dc.attribute("B", "0").toDouble();
                                        lf.setLabColor(L, a, b);
                                }
                        }
                        else if (dc.hasAttribute("CMYK"))
                                lf.setNamedColor(dc.attribute("CMYK"));
                        else if (dc.hasAttribute("RGB"))
                                lf.fromQColor(QColor(dc.attribute("RGB")));
                        else
                        {
                                double L = dc.attribute("L", "0").toDouble();
                                double a = dc.attribute("A", "0").toDouble();
                                double b = dc.attribute("B", "0").toDouble();
                                lf.setLabColor(L, a, b);
                        }
                        if (dc.hasAttribute("Spot"))
                                lf.setSpotColor(static_cast<bool>(dc.attribute("Spot").toInt()));
                        else
                                lf.setSpotColor(false);
                        if (dc.hasAttribute("Register"))
                                lf.setRegistrationColor(static_cast<bool>(dc.attribute("Register").toInt()));
                        else
                                lf.setRegistrationColor(false);
                        if (!m_colorList.contains(dc.attribute("NAME")))
                        {
                                m_colorList.insert(dc.attribute("NAME"), lf);
                                hasImportedColors = true;
                        }
                }
                if (dc.tagName() == "Gradient")
                {
                        VGradient gra(VGradient::linear);
                        gra.clearStops();
                        QDomNode grad = dc.firstChild();
                        while (!grad.isNull())
                        {
                                QDomElement stop = grad.toElement();
                                QString name = stop.attribute("NAME");
                                double ramp  = ScCLocale::toDoubleC(stop.attribute("RAMP"), 0.0);
                                int shade    = stop.attribute("SHADE", "100").toInt();
                                double opa   = ScCLocale::toDoubleC(stop.attribute("TRANS"), 1.0);
                                QColor color;
                                if (name == CommonStrings::None)
                                        color = QColor(255, 255, 255, 0);
                                else
                                {
                                        const ScColor& col = m_colorList[name];
                                        color = ScColorEngine::getShadeColorProof(col, nullptr, shade);
                                }
                                gra.addStop(color, ramp, 0.5, opa, name, shade);
                                grad = grad.nextSibling();
                        }
                        if (!dialogGradients.contains(dc.attribute("Name")))
                                dialogGradients.insert(dc.attribute("Name"), gra);
                        else
                        {
                                QString tmp;
                                QString name = dc.attribute("Name");
                                name += "("+tmp.setNum(dialogGradients.count())+")";
                                dialogGradients.insert(name, gra);
                        }
                }
                DOC=DOC.nextSibling();
        }
}

void ColorsAndFillsDialog::loadDefaults(QTreeWidgetItem* item)
{
        QString txt = item->data(0, Qt::UserRole).toString() + "/" + item->text(0);
        if (!mainWin->HaveDoc)
        {
                m_colorList.clear();
                dialogGradients.clear();
                dialogPatterns.clear();
        }
        QString pfadC2 = "";
        if (item->text(0) == "Scribus Small")
        {
                m_colorList.insert("White", ScColor(0, 0, 0, 0));
                m_colorList.insert("Black", ScColor(0, 0, 0, 255));
                ScColor cc(255, 255, 255, 255);
                cc.setRegistrationColor(true);
                m_colorList.insert("Registration", cc);
                m_colorList.insert("Blue", ScColor(255, 255, 0, 0));
                m_colorList.insert("Cyan", ScColor(255, 0, 0, 0));
                m_colorList.insert("Green", ScColor(255, 0, 255, 0));
                m_colorList.insert("Red", ScColor(0, 255, 255, 0));
                m_colorList.insert("Yellow", ScColor(0, 0, 255, 0));
                m_colorList.insert("Magenta", ScColor(0, 255, 0, 0));
                paletteLocked = false;
        }
        else
        {
                if (!customColSet.contains(txt))
                        pfadC2 = csm.paletteFileFromName(txt);
                else
                        pfadC2 = csm.userPaletteFileFromName(txt);
                if (!mainWin->HaveDoc)
                {
                        QFileInfo fi(pfadC2);
                        if (fi.absolutePath().contains(ScPaths::applicationDataDir()+"swatches/locked"))
                                paletteLocked = true;
                        else
                                paletteLocked = !fi.isWritable();
                }
                else
                        paletteLocked = false;
                if (!csm.loadPalette(pfadC2, m_doc, m_colorList, dialogGradients, dialogPatterns, mainWin->HaveDoc))
                {
                        m_colorList.insert("White", ScColor(0, 0, 0, 0));
                        m_colorList.insert("Black", ScColor(0, 0, 0, 255));
                        ScColor cc(255, 255, 255, 255);
                        cc.setRegistrationColor(true);
                        m_colorList.insert("Registration", cc);
                        m_colorList.insert("Blue", ScColor(255, 255, 0, 0));
                        m_colorList.insert("Cyan", ScColor(255, 0, 0, 0));
                        m_colorList.insert("Green", ScColor(255, 0, 255, 0));
                        m_colorList.insert("Red", ScColor(0, 255, 255, 0));
                        m_colorList.insert("Yellow", ScColor(0, 0, 255, 0));
                        m_colorList.insert("Magenta", ScColor(0, 255, 0, 0));
                }
        }
        updateColorList();
        updateGradientList();
        updatePatternList();
        itemSelected(nullptr);
}

void ColorsAndFillsDialog::saveDefaults()
{
        const QTreeWidgetItem* item = LoadColSet->currentItem();
        QString NameK = item->data(0, Qt::UserRole).toString() + "/" + item->text(0);
        QString Name = LoadColSet->text();

        Query* dia = new Query(this, "Name", 1, tr("&Name:"), tr("Choose a Name"));
        if ((customColSet.contains(NameK)) && (!paletteLocked))
                dia->setEditText(Name, false);
        else
                dia->setEditText("", false);
        if (dia->exec())
                doSaveDefaults(dia->getEditText(), (dia->getEditText() != Name));
        dia->deleteLater();
}

void ColorsAndFillsDialog::doSaveDefaults(const QString& name, bool changed)
{
        QString filename = name;
        filename.replace(" ", "_");
        filename  = QDir::toNativeSeparators(ScPaths::userPaletteFilesDir(true)) + filename;
        filename += ".xml";
        const FileFormat *fmt = LoadSavePlugin::getFormatById(FORMATID_SLA150EXPORT);
        if (fmt)
        {
                std::unique_ptr<ScribusDoc> s_doc(new ScribusDoc());
                s_doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
                s_doc->setPage(100, 100, 0, 0, 0, 0, 0, 0, false, false);
                s_doc->addPage(0);
                s_doc->setGUI(false, mainWin, nullptr);
                s_doc->PageColors = m_colorList;
                s_doc->setGradients(dialogGradients);
                s_doc->setPatterns(dialogPatterns);
                fmt->setupTargets(s_doc.get(), nullptr, mainWin, nullptr, &(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts));
                fmt->savePalette(filename);
        }
        if (changed)
        {
                QString nameC = name;
                nameC.replace(" ", "_");
                nameC += ".xml";
                QFileInfo fi(filename);
                customColSet.append(fi.absolutePath() + "/" + nameC);
                QTreeWidgetItem *item = LoadColSet->addSubItem(name, userSwatches);
                item->setData(0, Qt::UserRole, fi.absolutePath());
                disconnect(LoadColSet, SIGNAL(activated(QTreeWidgetItem*)), this, SLOT(loadDefaults(QTreeWidgetItem*)));
                LoadColSet->setCurrentComboItem(fi.absolutePath() + "/" + name);
                connect(LoadColSet, SIGNAL(activated(QTreeWidgetItem*)), this, SLOT(loadDefaults(QTreeWidgetItem*)));
        }
}

QString ColorsAndFillsDialog::getColorSetName()
{
        QString NameK;
        const QTreeWidgetItem* item = LoadColSet->currentItem();
        if (item->text(0) == "Scribus Small")
                NameK = "Scribus Small";
        else
                NameK = item->data(0, Qt::UserRole).toString() + "/" + item->text(0);
        return NameK;
}

ScColor ColorsAndFillsDialog::selectedColor() const
{
        const QTreeWidgetItem* it = dataTree->currentItem();
        if (it && (it->parent() == colorItems))
                return m_colorList[it->text(0)];
        return ScColor();
}

QString ColorsAndFillsDialog::selectedColorName() const
{
        const QTreeWidgetItem* it = dataTree->currentItem();
        if (it && (it->parent() == colorItems))
                return it->text(0);
        return CommonStrings::None;
}

void ColorsAndFillsDialog::keyPressEvent(QKeyEvent* k)
{
        if (k->modifiers()!=Qt::NoModifier || (k->key()!=Qt::Key_Delete && k->key()!=Qt::Key_Backspace))
                return;

        QString belowText;
        QList<QTreeWidgetItem *> selItems = dataTree->selectedItems();
        if (selItems.count() > 0)
        {
                const QTreeWidgetItem* belowItem = dataTree->itemBelow(selItems.last());
                if (belowItem)
                        belowText = belowItem->text(0);
        }

        removeColorItem();

        QList<QTreeWidgetItem *> belowItems = dataTree->findItems(belowText, Qt::MatchFixedString|Qt::MatchCaseSensitive|Qt::MatchRecursive);
        if (belowItems.count() > 0)
        {
                // In case non deletable colors have been selected, some items
                //may still be selected, so clear selection first
                dataTree->selectionModel()->clearSelection();
                dataTree->setCurrentItem(belowItems[0]);
        }
}