Rev 25137 |
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.
*/
#include <QSignalBlocker>
#include "propertywidget_pareffect.h"
#include "appmodehelper.h"
#include "appmodes.h"
#include "iconmanager.h"
#include "localemgr.h"
#include "pageitem.h"
#include "pageitem_table.h"
#include "scribus.h"
#include "scribusapp.h"
#include "scribusdoc.h"
#include "selection.h"
#include "util.h"
PropertyWidget_ParEffect::PropertyWidget_ParEffect(QWidget *parent) : QFrame(parent)
{
setupUi(this);
layout()->setAlignment(Qt::AlignTop);
languageChange();
dropCapLines->setValue(2);
if (m_doc)
peCharStyleCombo->updateStyleList();
fillBulletStrEditCombo();
enableParEffect(false);
bulletCharTableButton->setIcon(IconManager::instance().loadIcon("22/insert-table.png"));
numStart->setMinimum(1);
numStart->setMaximum(9999);
numLevelSpin->setMinimum(1);
numLevelSpin->setMaximum(3);
dropCapLines->setMinimum(2);
dropCapLines->setMaximum(99);
connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
}
void PropertyWidget_ParEffect::setMainWindow(ScribusMainWindow* mw)
{
m_ScMW = mw;
connect(m_ScMW->appModeHelper, SIGNAL(AppModeChanged(int,int)), this, SLOT(handleAppModeChanged(int,int)));
connect(m_ScMW, SIGNAL(UpdateRequest(int)), this , SLOT(handleUpdateRequest(int)));
}
void PropertyWidget_ParEffect::setDoc(ScribusDoc *doc)
{
if(doc == (ScribusDoc*) m_doc)
return;
if (m_doc)
{
disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
disconnect(m_doc , SIGNAL(docChanged()) , this, SLOT(handleSelectionChanged()));
}
m_doc = doc;
peCharStyleCombo->setDoc(doc);
if (m_doc.isNull())
{
disconnectSignals();
return;
}
m_unitRatio = m_doc->unitRatio();
m_unitIndex = m_doc->unitIndex();
fillNumerationsCombo();
connect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
connect(m_doc , SIGNAL(docChanged()) , this, SLOT(handleSelectionChanged()));
// Handle properties update when switching document
handleSelectionChanged();
}
void PropertyWidget_ParEffect::setCurrentItem(PageItem *item)
{
if (item && m_doc.isNull())
setDoc(item->doc());
m_item = item;
disconnectSignals();
if (!m_item) return;
if (m_item->isTextFrame() || m_item->isPathText() || m_item->isTable())
{
configureWidgets();
ParagraphStyle parStyle = m_item->itemText.defaultStyle();
if (m_doc->appMode == modeEdit || m_doc->appMode == modeEditTable)
m_item->currentTextProps(parStyle);
updateStyle(parStyle);
connectSignals();
}
}
void PropertyWidget_ParEffect::iconSetChange()
{
IconManager& iconManager = IconManager::instance();
bulletCharTableButton->setIcon(iconManager.loadIcon("22/insert-table.png"));
}
void PropertyWidget_ParEffect::unitChange()
{
if (!m_doc)
return;
m_unitRatio = m_doc->unitRatio();
m_unitIndex = m_doc->unitIndex();
bool sigBlocked = peOffset->blockSignals(true);
peOffset->setNewUnit( m_unitIndex );
peOffset->blockSignals(sigBlocked);
}
void PropertyWidget_ParEffect::localeChange()
{
const QLocale& l(LocaleManager::instance().userPreferredLocale());
peOffset->setLocale(l);
}
void PropertyWidget_ParEffect::fillNumerationsCombo()
{
QStringList numNames;
if (m_doc)
{
const auto numerationKeys = m_doc->numerations.keys();
for (const QString& numName : numerationKeys)
{
if (numName.isEmpty())
continue;
numNames.append(numName);
}
numNames.sort();
}
numNames.prepend("<local block>");
numComboBox->clear();
numComboBox->insertItems(0, numNames);
}
void PropertyWidget_ParEffect::updateCharStyles()
{
peCharStyleCombo->updateStyleList();
}
void PropertyWidget_ParEffect::showCharStyle(const QString& name)
{
bool blocked = peCharStyleCombo->blockSignals(true);
peCharStyleCombo->setStyle(name);
peCharStyleCombo->blockSignals(blocked);
}
void PropertyWidget_ParEffect::enableDropCap(bool enable)
{
// dropCapRadio_->setChecked(enable);
dropCapLines->setEnabled(enable);
if (enable)
{
dropCapsGroup->show();
enableBullet(false);
enableNum(false);
}
else
dropCapsGroup->hide();
}
void PropertyWidget_ParEffect::enableBullet(bool enable)
{
bulletStrEdit->setVisible(enable);
bulletCharTableButton->setVisible(enable);
bullGroup->setVisible(enable);
if (enable)
{
enableDropCap(false);
enableNum(false);
}
}
void PropertyWidget_ParEffect::enableNum(bool enable)
{
numComboBox->setVisible(enable);
numLevelSpin->setVisible(enable);
numStart->setVisible(enable);
numPrefix->setVisible(enable);
numSuffix->setVisible(enable);
numFormatCombo->setVisible(enable);
numGroup->setVisible(enable);
if (enable)
{
enableBullet(false);
enableDropCap(false);
}
}
void PropertyWidget_ParEffect::enableParEffect(bool enable)
{
peOffset->setVisible(enable);
peCharStyleCombo->setVisible(enable);
peIndent->setVisible(enable);
peGroup->setVisible(enable);
if (!enable)
{
enableBullet(false);
enableDropCap(false);
enableNum(false);
peCombo->setCurrentIndex(0);
}
}
void PropertyWidget_ParEffect::fillBulletStrEditCombo()
{
bulletStrEdit->clear();
bulletStrEdit->addItem(QChar(0x2022));
bulletStrEdit->addItem("*");
bulletStrEdit->addItem(QChar(0x2013));
bulletStrEdit->setMinimumWidth(50);
if (bulletStrEdit->currentText().isEmpty())
bulletStrEdit->setEditText(QChar(0x2022));
}
void PropertyWidget_ParEffect::fillPECombo()
{
QSignalBlocker sb(peCombo);
int currIndex = peCombo->currentIndex();
peCombo->clear();
peCombo->addItem(tr("No Paragraph Effects"));
peCombo->addItem(tr("Drop Caps"));
peCombo->addItem(tr("Bulleted List"));
peCombo->addItem(tr("Numbered List"));
peCombo->setCurrentIndex(currIndex);
}
void PropertyWidget_ParEffect::updateStyle(const ParagraphStyle& newPStyle)
{
int oldPeComboIndex = peCombo->currentIndex();
if (peCombo->currentIndex() && !newPStyle.hasBullet() && !newPStyle.hasDropCap() && !newPStyle.hasNum())
{
enableParEffect(false);
return;
}
QSignalBlocker blocker1(peCombo);
QSignalBlocker blocker2(dropCapLines);
QSignalBlocker blocker3(bulletStrEdit);
QSignalBlocker blocker4(numComboBox);
QSignalBlocker blocker5(numLevelSpin);
QSignalBlocker blocker6(numFormatCombo);
QSignalBlocker blocker7(numPrefix);
QSignalBlocker blocker8(numSuffix);
QSignalBlocker blocker9(numStart);
QSignalBlocker blockerA(peOffset);
QSignalBlocker blockerB(peIndent);
QSignalBlocker blockerC(peCharStyleCombo);
bool enablePE = true;
if (newPStyle.hasDropCap())
{
peCombo->setCurrentIndex(1);
enableDropCap(true);
}
else if (newPStyle.hasBullet())
{
peCombo->setCurrentIndex(2);
enableBullet(true);
}
else if (newPStyle.hasNum())
{
peCombo->setCurrentIndex(3);
enableNum(true);
}
else
enablePE = false;
QString numName = numComboBox->currentText();
dropCapLines->setValue(newPStyle.dropCapLines());
bulletStrEdit->setEditText(newPStyle.bulletStr());
numName = newPStyle.numName();
if (numName.isEmpty())
numName = "<local block>";
numComboBox->setCurrentIndex(numComboBox->findText(numName));
NumStruct * numS = m_doc->numerations.value(numName);
if (numS)
numLevelSpin->setMaximum(numS->m_counters.count() + 1);
else
numLevelSpin->setMaximum(3);
numLevelSpin->setValue(newPStyle.numLevel() + 1);
numPrefix->setText(newPStyle.numPrefix());
numSuffix->setText(newPStyle.numSuffix());
numStart->setValue(newPStyle.numStart());
numFormatCombo->setCurrentFormat((NumFormat) newPStyle.numFormat());
peOffset->setValue(newPStyle.parEffectOffset() * m_unitRatio);
peIndent->setChecked(newPStyle.parEffectIndent());
showCharStyle(newPStyle.peCharStyleName());
enableParEffect(enablePE);
if (oldPeComboIndex != peCombo->currentIndex())
emit needsRelayout();
}
void PropertyWidget_ParEffect::connectSignals()
{
connect(peCombo, SIGNAL(activated(int)), this, SLOT(handleParEffectUse()), Qt::UniqueConnection);
connect(dropCapLines, SIGNAL(valueChanged(int)), this, SLOT(handleDropCapLines(int)), Qt::UniqueConnection);
connect(bulletStrEdit, SIGNAL(editTextChanged(QString)), this, SLOT(handleBulletStr(QString)), Qt::UniqueConnection);
connect(numComboBox, SIGNAL(textActivated(QString)), this, SLOT(handleNumName(QString)), Qt::UniqueConnection);
connect(numLevelSpin, SIGNAL(valueChanged(int)), this, SLOT(handleNumLevel(int)), Qt::UniqueConnection);
connect(numFormatCombo, SIGNAL(activated(int)), this, SLOT(handleNumFormat(int)), Qt::UniqueConnection);
connect(numPrefix, SIGNAL(textChanged(QString)), this, SLOT(handleNumPrefix(QString)), Qt::UniqueConnection);
connect(numSuffix, SIGNAL(textChanged(QString)), this, SLOT(handleNumSuffix(QString)), Qt::UniqueConnection);
connect(numStart, SIGNAL(valueChanged(int)), this, SLOT(handleNumStart(int)), Qt::UniqueConnection);
connect(peOffset, SIGNAL(valueChanged(double)), this, SLOT(handlePEOffset(double)), Qt::UniqueConnection);
connect(peIndent, SIGNAL(toggled(bool)), this, SLOT(handlePEIndent(bool)), Qt::UniqueConnection);
connect(peCharStyleCombo, SIGNAL(newStyle(QString)), this, SLOT(handlePECharStyle(QString)), Qt::UniqueConnection);
}
void PropertyWidget_ParEffect::disconnectSignals()
{
disconnect(peCombo, SIGNAL(activated(int)), this, SLOT(handleParEffectUse()));
disconnect(dropCapLines, SIGNAL(valueChanged(int)), this, SLOT(handleDropCapLines(int)));
disconnect(bulletStrEdit, SIGNAL(editTextChanged(QString)), this, SLOT(handleBulletStr(QString)));
disconnect(numComboBox, SIGNAL(textActivated(QString)), this, SLOT(handleNumName(QString)));
disconnect(numLevelSpin, SIGNAL(valueChanged(int)), this, SLOT(handleNumLevel(int)));
disconnect(numFormatCombo, SIGNAL(activated(int)), this, SLOT(handleNumFormat(int)));
disconnect(numPrefix, SIGNAL(textChanged(QString)), this, SLOT(handleNumPrefix(QString)));
disconnect(numSuffix, SIGNAL(textChanged(QString)), this, SLOT(handleNumSuffix(QString)));
disconnect(numStart, SIGNAL(valueChanged(int)), this, SLOT(handleNumStart(int)));
disconnect(peOffset, SIGNAL(valueChanged(double)), this, SLOT(handlePEOffset(double)));
disconnect(peIndent, SIGNAL(toggled(bool)), this, SLOT(handlePEIndent(bool)));
disconnect(peCharStyleCombo, SIGNAL(newStyle(QString)), this, SLOT(handlePECharStyle(QString)));
}
void PropertyWidget_ParEffect::configureWidgets()
{
bool enabled = false;
if (m_item && m_doc)
{
PageItem_TextFrame *textItem = m_item->asTextFrame();
if (m_doc->appMode == modeEditTable)
textItem = m_item->asTable()->activeCell().textFrame();
if (textItem || m_item->isPathText())
enabled = true;
}
setEnabled(enabled);
}
void PropertyWidget_ParEffect::handleAppModeChanged(int oldMode, int mode)
{
if (oldMode == modeEditTable || mode == modeEditTable)
{
setCurrentItem(m_item);
}
}
void PropertyWidget_ParEffect::handleSelectionChanged()
{
if (!m_doc || !m_ScMW || m_ScMW->scriptIsRunning())
return;
PageItem* currItem = currentItemFromSelection();
setCurrentItem(currItem);
updateGeometry();
}
void PropertyWidget_ParEffect::handleUpdateRequest(int updateFlags)
{
if (updateFlags & reqCharStylesUpdate)
updateCharStyles();
if (updateFlags & reqStyleComboDocUpdate)
setDoc(m_doc ? m_doc : nullptr);
if (updateFlags & reqNumUpdate)
fillNumerationsCombo();
}
void PropertyWidget_ParEffect::handleParEffectUse()
{
if (!m_doc || !m_item)
return;
ParagraphStyle newStyle;
enableParEffect(peCombo->currentIndex() != 0);
if (peCombo->currentIndex() == 1)
{
enableDropCap(true);
newStyle.setDropCapLines(dropCapLines->value());
newStyle.setHasDropCap(true);
newStyle.setHasBullet(false);
newStyle.setHasNum(false);
}
else if (peCombo->currentIndex() == 2)
{
enableBullet(true);
newStyle.setHasBullet(true);
QString bStr = bulletStrEdit->currentText();
if (bStr.isEmpty())
bStr = QChar(0x2022);
newStyle.setBulletStr(bStr);
newStyle.setHasNum(false);
newStyle.setHasDropCap(false);
}
else if (peCombo->currentIndex() == 3)
{
enableNum(true);
newStyle.setHasDropCap(false);
newStyle.setHasBullet(false);
newStyle.setHasNum(true);
newStyle.setNumName(numComboBox->currentText());
newStyle.setNumFormat(numFormatCombo->currentFormat());
newStyle.setNumLevel(numLevelSpin->value() - 1);
newStyle.setNumStart(numStart->value());
newStyle.setNumPrefix(numPrefix->text());
newStyle.setNumSuffix(numSuffix->text());
if (newStyle.numName() == "<local block>")
{
newStyle.setNumOther(true);
newStyle.setNumHigher(true);
}
}
else
{
newStyle.setHasDropCap(false);
newStyle.setHasBullet(false);
newStyle.setHasNum(false);
}
newStyle.setParEffectOffset(peOffset->value() / m_unitRatio);
newStyle.setParEffectIndent(peIndent->isChecked());
handleChanges(m_item, newStyle);
emit needsRelayout();
}
void PropertyWidget_ParEffect::handleBulletStr(QString bulStr)
{
if (!m_doc || !m_item)
return;
ParagraphStyle newStyle;
if (bulStr.isEmpty())
bulStr = QChar(0x2022);
newStyle.setBulletStr(bulStr);
handleChanges(m_item, newStyle);
}
void PropertyWidget_ParEffect::handleDropCapLines(int dcLines)
{
if (!m_doc || !m_item)
return;
ParagraphStyle newStyle;
newStyle.setDropCapLines(dcLines);
handleChanges(m_item, newStyle);
}
void PropertyWidget_ParEffect::handleNumName(const QString& numName)
{
if (!m_doc || !m_item)
return;
disconnectSignals();
ParagraphStyle newStyle;
if (numName == "<local block>")
{
newStyle.setNumOther(true);
newStyle.setNumHigher(true);
newStyle.setNumRestart(NSRstory);
}
else
{
NumStruct * numS = m_doc->numerations.value(numName);
Q_ASSERT(numS);
int level = qMin(numLevelSpin->value(), numS->m_counters.count()) - 1;
numLevelSpin->setValue(level + 1);
newStyle.setNumLevel(level);
Numeration num = numS->m_nums[level];
numFormatCombo->setCurrentFormat(num.numFormat);
numStart->setValue(num.start);
numPrefix->setText(num.prefix);
numSuffix->setText(num.suffix);
}
newStyle.setNumPrefix(numPrefix->text());
newStyle.setNumSuffix(numSuffix->text());
newStyle.setNumName(numName);
newStyle.setNumFormat(numFormatCombo->currentFormat());
handleChanges(m_item, newStyle);
connectSignals();
}
void PropertyWidget_ParEffect::handleNumFormat(int /*style*/)
{
if (!m_doc || !m_item)
return;
NumFormat format = numFormatCombo->currentFormat();
ParagraphStyle newStyle;
newStyle.setNumFormat(format);
handleChanges(m_item, newStyle);
}
void PropertyWidget_ParEffect::handleNumLevel(int level)
{
if (!m_doc || !m_item)
return;
if ((numComboBox->currentText() != "<local block>") && level == numLevelSpin->maximum())
{
NumStruct * numS = m_doc->numerations.value(numComboBox->currentText());
Q_ASSERT(numS);
while (level > numS->m_counters.count())
{
numS->m_counters.append(0);
Numeration num;
num.numFormat = numFormatCombo->currentFormat();
num.prefix = numPrefix->text();
num.suffix = numSuffix->text();
num.start = numStart->value();
numS->m_nums.append(num);
}
}
ParagraphStyle newStyle;
newStyle.setNumLevel(level -1);
handleChanges(m_item, newStyle);
}
void PropertyWidget_ParEffect::handleNumPrefix(const QString& prefix)
{
if (!m_doc || !m_item)
return;
ParagraphStyle newStyle;
newStyle.setNumPrefix(prefix);
handleChanges(m_item, newStyle);
}
void PropertyWidget_ParEffect::handleNumSuffix(const QString& suffix)
{
if (!m_doc || !m_item)
return;
ParagraphStyle newStyle;
newStyle.setNumSuffix(suffix);
handleChanges(m_item, newStyle);
}
void PropertyWidget_ParEffect::handleNumStart(int start)
{
if (!m_doc || !m_item)
return;
ParagraphStyle newStyle;
newStyle.setNumStart(start);
handleChanges(m_item, newStyle);
}
void PropertyWidget_ParEffect::handlePEOffset(double offset)
{
if (!m_doc || !m_item)
return;
ParagraphStyle newStyle;
newStyle.setParEffectOffset(offset / m_unitRatio);
handleChanges(m_item, newStyle);
}
void PropertyWidget_ParEffect::handlePEIndent(bool indent)
{
if (!m_doc || !m_item)
return;
ParagraphStyle newStyle;
newStyle.setParEffectIndent(indent);
handleChanges(m_item, newStyle);
}
void PropertyWidget_ParEffect::handlePECharStyle(const QString& name)
{
if (!m_doc || !m_item)
return;
ParagraphStyle newStyle;
newStyle.setPeCharStyleName(name);
handleChanges(m_item, newStyle);
}
void PropertyWidget_ParEffect::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange)
{
languageChange();
return;
}
QWidget::changeEvent(e);
}
void PropertyWidget_ParEffect::handleChanges(PageItem *item, ParagraphStyle &newStyle)
{
if (m_doc->appMode == modeEditTable)
item = item->asTable()->activeCell().textFrame();
if (item != nullptr)
{
disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
disconnect(m_doc , SIGNAL(docChanged()) , this, SLOT(handleSelectionChanged()));
Selection tempSelection(this, false);
tempSelection.addItem(item, true);
m_doc->itemSelection_ApplyParagraphStyle(newStyle, &tempSelection);
m_doc->updateNumbers();
connect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(handleSelectionChanged()));
connect(m_doc , SIGNAL(docChanged()) , this, SLOT(handleSelectionChanged()));
}
}
void PropertyWidget_ParEffect::languageChange()
{
fillPECombo();
retranslateUi(this);
}
void PropertyWidget_ParEffect::openEnhanced()
{
if (m_enhanced)
return;
QApplication::changeOverrideCursor(QCursor(Qt::WaitCursor));
m_enhanced = new CharSelectEnhanced(this);
m_enhanced->setModal(true);
connect(m_enhanced, SIGNAL(insertSpecialChars(const QVector<uint>&)), this, SLOT(insertSpecialChars(const QVector<uint>&)));
connect(m_enhanced, SIGNAL(paletteShown(bool)), bulletCharTableButton, SLOT(setChecked(bool)));
m_enhanced->setDoc(m_doc);
m_enhanced->setEnabled(true);
setCurrentComboItem(m_enhanced->fontSelector, m_item->currentStyle().charStyle().font().scName());
m_enhanced->newFont(m_enhanced->fontSelector->currentIndex());
m_enhanced->show();
QApplication::changeOverrideCursor(Qt::ArrowCursor);
}
void PropertyWidget_ParEffect::closeEnhanced(bool show)
{
if (!m_enhanced || show)
return;
disconnect(m_enhanced, SIGNAL(insertSpecialChars(const QVector<uint> &)), this, SLOT(insertSpecialChars(const QVector<uint> &)));
disconnect(m_enhanced, SIGNAL(paletteShown(bool)), bulletCharTableButton, SLOT(setChecked(bool)));
m_enhanced->close();
m_enhanced->deleteLater();
m_enhanced = nullptr;
}
void PropertyWidget_ParEffect::on_bulletCharTableButton_toggled(bool checked)
{
if (m_enhanced && !checked)
closeEnhanced();
else if (!m_enhanced && checked)
openEnhanced();
}
void PropertyWidget_ParEffect::insertSpecialChars(const QVector<uint> &charCodes)
{
QString chars = QString::fromUcs4(charCodes.data(), charCodes.length());
bulletStrEdit->lineEdit()->setText(chars);
}