Subversion Repositories Scribus

Rev

Rev 25114 | 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.
*/

/***************************************************************************
                          symbolpalette.cpp  -  description
                             -------------------
    begin                : Sat May 8 2010
    copyright            : (C) 2010 by Franz Schmid
    email                : 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.                                   *
 *                                                                         *
 ***************************************************************************/

#include "symbolpalette.h"
#include <QPainter>
#include <QByteArray>
#include <QDrag>
#include <QMimeData>
#include "scpattern.h"
#include "scribusdoc.h"
#include "scribus.h"

SymbolView::SymbolView(QWidget* parent) : QListWidget(parent)
{
        setDragEnabled(true);
        setViewMode(QListView::IconMode);
        setFlow(QListView::LeftToRight);
        setSortingEnabled(true);
        setWrapping(true);
        setAcceptDrops(true);
        setDropIndicatorShown(true);
        setDragDropMode(QAbstractItemView::DragDrop);
        setResizeMode(QListView::Adjust);
        setSelectionMode(QAbstractItemView::SingleSelection);
        setContextMenuPolicy(Qt::CustomContextMenu);
        m_delegate = new ScListWidgetDelegate(this, this);
        setItemDelegate(m_delegate);
        setIconSize(QSize(48, 48));
        connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(handleContextMenu(QPoint)));
}

void SymbolView::handleContextMenu(QPoint p)
{
        QListWidgetItem *item = itemAt(p);
        if (item)
                return;

        QMenu *pmenu = new QMenu();
        QAction* viewAct;
        viewAct = pmenu->addAction( tr("Display Icons only"));
        viewAct->setCheckable(true);
        viewAct->setChecked(m_delegate->iconOnly());
        connect(viewAct, SIGNAL(triggered()), this, SLOT(changeDisplay()));
        pmenu->exec(QCursor::pos());
        pmenu->deleteLater();
}

void SymbolView::changeDisplay()
{
        reset();
        m_delegate->setIconOnly(!m_delegate->iconOnly());
        repaint();
}

void SymbolView::dragEnterEvent(QDragEnterEvent *e)
{
        if (e->source() == this)
                e->ignore();
        else
                e->acceptProposedAction();
}

void SymbolView::dragMoveEvent(QDragMoveEvent *e)
{
        if (e->source() == this)
                e->ignore();
        else
                e->acceptProposedAction();
}

void SymbolView::dropEvent(QDropEvent *e)
{
        if (e->mimeData()->hasText())
        {
                e->acceptProposedAction();
                if (e->source() == this)
                        return;
                QString text = e->mimeData()->text();
                if ((text.startsWith("<SCRIBUSELEM")) || (text.startsWith("SCRIBUSELEMUTF8")))
                        emit objectDropped();
        }
        else
                e->ignore();
}


bool SymbolView::viewportEvent(QEvent *event)
{
        if (event != nullptr)
        {
                if (event->type() == QEvent::ToolTip)
                {
                        QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
                        QListWidgetItem* it = itemAt(helpEvent->pos());
                        if (it != nullptr)
                        {
                                event->accept();
                                QString tipText = it->text();
                                QToolTip::showText(helpEvent->globalPos(), tipText, this);
                                return true;
                        }
                }
                else if (event->type() == QEvent::MouseButtonPress)
                {
                        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
                        if (mouseEvent->button() == Qt::RightButton)
                                return true;
                }
                else if (event->type() == QEvent::MouseButtonRelease)
                {
                        QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
                        if (mouseEvent->button() == Qt::RightButton)
                        {
                                emit customContextMenuRequested(mouseEvent->pos());
                                return true;
                        }
                }
        }
        return QListWidget::viewportEvent(event);
}

 void SymbolView::startDrag(Qt::DropActions supportedActions)
 {
        QMimeData *mimeData = new QMimeData;
        QByteArray data = currentItem()->text().toLocal8Bit();
        mimeData->setData("text/symbol", data);
        QDrag *drag = new QDrag(this);
        drag->setMimeData(mimeData);
        drag->setPixmap(currentItem()->icon().pixmap(48, 48));
        drag->exec(Qt::CopyAction);
        clearSelection();
}

SymbolPalette::SymbolPalette( QWidget* parent) : ScDockPalette(parent, "Symb", Qt::WindowFlags())
{
        setContentsMargins(3, 3, 3, 3);
        setMinimumSize( QSize( 220, 240 ) );
        setObjectName(QString::fromLocal8Bit("Symb"));
        setSizePolicy( QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
        SymbolViewWidget = new SymbolView(this);
        SymbolViewWidget->clear();
        setWidget( SymbolViewWidget );

        unsetDoc();
        m_scMW  = nullptr;
        editItemNames.clear();
        languageChange();
        m_item = nullptr;
        connect(SymbolViewWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(handleDoubleClick(QListWidgetItem*)));
        connect(SymbolViewWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(handleContextMenu(QPoint)));
        connect(SymbolViewWidget, SIGNAL(objectDropped()), this, SIGNAL(objectDropped()));
}

void SymbolPalette::handleContextMenu(QPoint p)
{
        if (!m_doc)
                return;

        QListWidgetItem *item = SymbolViewWidget->itemAt(p);
        if (!item)
                return;
        m_item = item;

        QMenu *pmenu = new QMenu();
        QAction* editAct = pmenu->addAction( tr("Edit Item"));
        editAct->setEnabled(item->flags() & Qt::ItemIsEnabled);
        connect(editAct, SIGNAL(triggered()), this, SLOT(handleEditItem()));

        QAction* delAct = pmenu->addAction( tr("Remove Item"));
        delAct->setEnabled(item->flags() & Qt::ItemIsEnabled);
        connect(delAct, SIGNAL(triggered()), this, SLOT(handleDeleteItem()));

        pmenu->exec(QCursor::pos());
        pmenu->deleteLater();
}

void SymbolPalette::handleDoubleClick(QListWidgetItem *item)
{
        if (item)
                emit startEdit(item->text());
}

void SymbolPalette::handleEditItem()
{
        if (m_item != nullptr)
        {
                emit startEdit(m_item->text());
                m_item = nullptr;
        }
}

void SymbolPalette::handleDeleteItem()
{
        if (m_item == nullptr)
                return;

        if (m_doc->docPatterns.contains(m_item->text()))
        {
                m_doc->removePattern(m_item->text());
                updateSymbolList();
                m_doc->regionsChanged()->update(QRect());
        }
        m_item = nullptr;
}

void SymbolPalette::editingStart(QStringList names)
{
        editItemNames = names;
        for (int a = 0; a < editItemNames.count(); a++)
        {
                QList<QListWidgetItem*> items = SymbolViewWidget->findItems(names[a], Qt::MatchExactly);
                if (items.count() > 0)
                        items[0]->setFlags(Qt::NoItemFlags);
        }
}

void SymbolPalette::editingFinished()
{
        editItemNames.clear();
        updateSymbolList();
}

void SymbolPalette::setMainWindow(ScribusMainWindow *mw)
{
        m_scMW = mw;
        if (m_scMW == nullptr)
        {
                SymbolViewWidget->clear();
                disconnect(m_scMW, SIGNAL(UpdateRequest(int)), this, SLOT(handleUpdateRequest(int)));
                return;
        }
        connect(m_scMW, SIGNAL(UpdateRequest(int)), this, SLOT(handleUpdateRequest(int)), Qt::UniqueConnection);
}

void SymbolPalette::setDoc(ScribusDoc *newDoc)
{
        if (m_scMW == nullptr)
                m_doc = nullptr;
        else
                m_doc = newDoc;
        if (m_doc == nullptr)
        {
                SymbolViewWidget->clear();
                setEnabled(true);
        }
        else
        {
                setEnabled(!m_doc->drawAsPreview);
                updateSymbolList();
        }
}

void SymbolPalette::unsetDoc()
{
        m_doc = nullptr;
        SymbolViewWidget->clear();
        setEnabled(true);
}

void SymbolPalette::handleUpdateRequest(int updateFlags)
{
        if (updateFlags & reqSymbolsUpdate)
                updateSymbolList();
}

void SymbolPalette::updateSymbolList()
{
        SymbolViewWidget->clear();
        SymbolViewWidget->setWordWrap(true);
        if (!m_doc)
                return;

        QStringList patK = m_doc->docPatterns.keys();
        patK.sort();
        for (int i = 0; i < patK.count(); ++i)
        {
                const QString& patternName = patK.at(i);
                ScPattern sp = m_doc->docPatterns.value(patternName);
                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();
                QListWidgetItem *item = new QListWidgetItem(pm2, patternName, SymbolViewWidget);
                if (editItemNames.contains(patternName))
                        item->setFlags(Qt::NoItemFlags);
                else
                        item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
        }
}

void SymbolPalette::changeEvent(QEvent *e)
{
        if (e->type() == QEvent::LanguageChange)
        {
                languageChange();
        }
        else
                ScDockPalette::changeEvent(e);
}

void SymbolPalette::languageChange()
{
        setWindowTitle( tr( "Symbols" ) );
}

void SymbolPalette::keyPressEvent(QKeyEvent* e)
{
        if (!m_doc)
                return;
        switch (e->key())
        {
                case Qt::Key_Backspace:
                case Qt::Key_Delete:
                        {
                                QListWidgetItem* it = SymbolViewWidget->currentItem();
                                if (it != nullptr)
                                {
                                        if (m_doc->docPatterns.contains(it->text()))
                                        {
                                                m_doc->removePattern(it->text());
                                                updateSymbolList();
                                                m_doc->regionsChanged()->update(QRect());
                                                e->accept();
                                        }
                                }
                        }
                        break;
                default:
                        break;
        }
}