1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 /**************************************************************************
8 * Copyright (C) 2010 by Franz Schmid *
9 * franz.schmid@altmuehlnet.de *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
25 ***************************************************************************/
26
27 #include <QCheckBox>
28 #include <QCursor>
29 #include <QDir>
30 #include <QDomDocument>
31 #include <QEventLoop>
32 #include <QFileDialog>
33 #include <QImageReader>
34 #include <QMenu>
35 #include <QMessageBox>
36
37 #include "cmykfw.h"
38 #include "colorlistbox.h"
39 #include "colorsandfills.h"
40 #include "commonstrings.h"
41 #include "dcolor.h"
42 #include "fileloader.h"
43 #include "gradientaddedit.h"
44 #include "iconmanager.h"
45 #include "loadsaveplugin.h"
46 #include "plugins/formatidlist.h"
47 #include "prefsfile.h"
48 #include "prefsmanager.h"
49 #include "query.h"
50 #include "scclocale.h"
51 #include "sccolor.h"
52 #include "sccolorengine.h"
53 #include "scconfig.h"
54 #include "sclimits.h"
55 #include "sclistboxpixmap.h"
56 #include "scpainter.h"
57 #include "scpaths.h"
58 #include "scribus.h"
59 #include "scribusview.h"
60 #include "scribusXml.h"
61 #include "sctextstream.h"
62 #include "ui/customfdialog.h"
63 #include "undomanager.h"
64 #include "util.h"
65 #include "util_color.h"
66 #include "util_formats.h"
67
68
ColorsAndFillsDialog(QWidget * parent,QHash<QString,VGradient> * docGradients,const ColorList & doco,const QString & docColSet,QHash<QString,ScPattern> * docPatterns,ScribusDoc * doc,ScribusMainWindow * scMW)69 ColorsAndFillsDialog::ColorsAndFillsDialog(QWidget* parent, QHash<QString, VGradient> *docGradients, const ColorList& doco, const QString& docColSet, QHash<QString, ScPattern> *docPatterns, ScribusDoc *doc, ScribusMainWindow *scMW) : QDialog(parent)
70 {
71 setupUi(this);
72 setModal(true);
73 paletteLocked = false;
74 modified = false;
75 sortRule = 0;
76 m_doc = doc;
77 m_colorList = doco;
78 mainWin = scMW;
79 setWindowIcon(IconManager::instance().loadIcon("AppIcon.png"));
80 dataTree->setContextMenuPolicy(Qt::CustomContextMenu);
81 dataTree->setIconSize(QSize(60, 48));
82 colorItems = new QTreeWidgetItem(dataTree);
83 colorItems->setText(0, tr("Solid Colors"));
84 gradientItems = new QTreeWidgetItem(dataTree);
85 gradientItems->setText(0, tr("Gradients"));
86 for (QHash<QString, VGradient>::Iterator it = docGradients->begin(); it != docGradients->end(); ++it)
87 {
88 dialogGradients.insert(it.key(), it.value());
89 origNames.insert(it.key(), it.key());
90 }
91 origGradients = docGradients->keys();
92
93 patternItems = new QTreeWidgetItem(dataTree);
94 patternItems->setText(0, tr("Patterns"));
95 for (QHash<QString, ScPattern>::Iterator it = docPatterns->begin(); it != docPatterns->end(); ++it)
96 {
97 dialogPatterns.insert(it.key(), it.value());
98 origNamesPatterns.insert(it.key(), it.key());
99 }
100 origPatterns = docPatterns->keys();
101
102 csm.findPaletteLocations();
103 systemSwatches = LoadColSet->addTopLevelItem( tr("Scribus Swatches"));
104 csm.findPalettes(systemSwatches);
105 LoadColSet->addSubItem("Scribus Small", systemSwatches);
106 systemSwatches->setExpanded(true);
107 userSwatches = LoadColSet->addTopLevelItem( tr("User Swatches"));
108 csm.findUserPalettes(userSwatches);
109 customColSet = csm.userPaletteNames();
110 userSwatches->setExpanded(true);
111 // QFileInfo fi(docColSet);
112 LoadColSet->setCurrentComboItem(docColSet);
113 if (mainWin->HaveDoc)
114 {
115 label->setText( tr("Merge Color Set"));
116 m_doc->getUsedColors(inDocUsedColors);
117 paletteLocked = false;
118 }
119 else
120 {
121 if (docColSet != "Scribus Small")
122 {
123 QString pfad;
124 if (customColSet.contains(docColSet))
125 pfad = csm.userPaletteFileFromName(docColSet);
126 else
127 pfad = csm.paletteFileFromName(docColSet);
128 QFileInfo fi(pfad);
129 if (fi.absolutePath().contains(ScPaths::applicationDataDir()+"swatches/locked"))
130 paletteLocked = true;
131 else
132 paletteLocked = !fi.isWritable();
133 }
134 }
135 importButton->setEnabled(false);
136 newButton->setEnabled(false);
137 editButton->setEnabled(false);
138 duplicateButton->setEnabled(false);
139 deleteButton->setEnabled(false);
140 deleteUnusedButton->setEnabled(false);
141 updateColorList();
142 updateGradientList();
143 updatePatternList();
144 dataTree->expandItem(colorItems);
145 dataTree->expandItem(gradientItems);
146 dataTree->expandItem(patternItems);
147 dataTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
148 connect(dataTree, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(itemSelected(QTreeWidgetItem*)));
149 connect(dataTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(selEditColor(QTreeWidgetItem*)));
150 connect(dataTree, SIGNAL(itemSelectionChanged()), this, SLOT(itemSelectionChanged()));
151 connect(dataTree, SIGNAL(customContextMenuRequested (const QPoint &)), this, SLOT(slotRightClick(QPoint)));
152 connect(newButton, SIGNAL(clicked()), this, SLOT(createNew()));
153 connect(editButton, SIGNAL(clicked()), this, SLOT(editColorItem()));
154 connect(duplicateButton, SIGNAL(clicked()), this, SLOT(duplicateColorItem()));
155 connect(deleteButton, SIGNAL(clicked()), this, SLOT(removeColorItem()));
156 connect(deleteUnusedButton, SIGNAL(clicked()), this, SLOT(removeUnusedColorItem()));
157 connect(importButton, SIGNAL(clicked()), this, SLOT(importColorItems()));
158 connect(okButton, SIGNAL(clicked()), this, SLOT(leaveDialog()));
159 connect(cancelButton, SIGNAL(clicked()), this, SLOT(reject()));
160 connect(SaveColSet, SIGNAL(clicked()), this, SLOT(saveDefaults()));
161 connect(LoadColSet, SIGNAL(activated(QTreeWidgetItem*)), this, SLOT(loadDefaults(QTreeWidgetItem*)));
162 }
163
leaveDialog()164 void ColorsAndFillsDialog::leaveDialog()
165 {
166 /* if (!mainWin->HaveDoc)
167 {
168 if (modified)
169 {
170 if (paletteLocked)
171 saveDefaults();
172 else
173 doSaveDefaults(LoadColSet->text(), true);
174 }
175 } */
176 accept();
177 }
178
updatePatternList(const QString & addedName)179 QTreeWidgetItem* ColorsAndFillsDialog::updatePatternList(const QString& addedName)
180 {
181 QList<QTreeWidgetItem*> lg = patternItems->takeChildren();
182 for (int i = 0; i < lg.count(); i++)
183 {
184 delete lg[i];
185 }
186 QTreeWidgetItem* ret = nullptr;
187 QStringList patK = dialogPatterns.keys();
188 patK.sort();
189 for (int a = 0; a < patK.count(); a++)
190 {
191 ScPattern sp = dialogPatterns.value(patK[a]);
192 QPixmap pm;
193 if (sp.getPattern()->width() >= sp.getPattern()->height())
194 pm = QPixmap::fromImage(sp.getPattern()->scaledToWidth(48, Qt::SmoothTransformation));
195 else
196 pm = QPixmap::fromImage(sp.getPattern()->scaledToHeight(48, Qt::SmoothTransformation));
197 QPixmap pm2(48, 48);
198 pm2.fill(palette().color(QPalette::Base));
199 QPainter p;
200 p.begin(&pm2);
201 p.drawPixmap(24 - pm.width() / 2, 24 - pm.height() / 2, pm);
202 p.end();
203 QTreeWidgetItem *item = new QTreeWidgetItem(patternItems);
204 item->setText(0, patK[a]);
205 if (patK[a] == addedName)
206 ret = item;
207 item->setIcon(0, pm2);
208 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
209 }
210 return ret;
211 }
212
updateGradientList(const QString & addedName)213 QTreeWidgetItem* ColorsAndFillsDialog::updateGradientList(const QString& addedName)
214 {
215 QList<QTreeWidgetItem*> lg = gradientItems->takeChildren();
216 for (int i = 0; i < lg.count(); i++)
217 {
218 delete lg[i];
219 }
220 QTreeWidgetItem* ret = nullptr;
221 QStringList patK = dialogGradients.keys();
222 patK.sort();
223 for (int a = 0; a < patK.count(); a++)
224 {
225 VGradient gr = dialogGradients.value(patK[a]);
226 QImage pixm(48, 12, QImage::Format_ARGB32);
227 QPainter pb;
228 QBrush b(QColor(205,205,205), IconManager::instance().loadPixmap("testfill.png"));
229 pb.begin(&pixm);
230 pb.fillRect(0, 0, 48, 12, b);
231 pb.end();
232 ScPainter *p = new ScPainter(&pixm, 48, 12);
233 p->setPen(Qt::black, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
234 p->setFillMode(ScPainter::Gradient);
235 p->fill_gradient = gr;
236 p->setGradient(VGradient::linear, FPoint(0,6), FPoint(48, 6), FPoint(0, 0), 1.0, 0.0);
237 p->drawRect(0, 0, 48, 12);
238 p->end();
239 delete p;
240 QPixmap pm;
241 pm = QPixmap::fromImage(pixm);
242 QTreeWidgetItem *item = new QTreeWidgetItem(gradientItems);
243 item->setText(0, patK[a]);
244 if (patK[a] == addedName)
245 ret = item;
246 item->setIcon(0, pm);
247 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
248 }
249 return ret;
250 }
251
updateColorList(const QString & addedName)252 QTreeWidgetItem* ColorsAndFillsDialog::updateColorList(const QString& addedName)
253 {
254 QList<QTreeWidgetItem*> lg = colorItems->takeChildren();
255 for (int a = 0; a < lg.count(); a++)
256 {
257 delete lg[a];
258 }
259 QTreeWidgetItem* ret = nullptr;
260 if (sortRule > 0)
261 {
262 QMap<QString, QString> sortMap;
263 ColorList::Iterator it;
264 for (it = m_colorList.begin(); it != m_colorList.end(); ++it)
265 {
266 if (sortRule == 1)
267 {
268 QColor c = it.value().getRawRGBColor();
269 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());
270 sortMap.insert(sortString, it.key());
271 }
272 else if (sortRule == 2)
273 {
274 QString sortString = QString("%1-%2");
275 if (it.value().isRegistrationColor())
276 sortMap.insert(sortString.arg("A", it.key()), it.key());
277 else if (it.value().isSpotColor())
278 sortMap.insert(sortString.arg("B", it.key()), it.key());
279 else if (it.value().getColorModel() == colorModelCMYK)
280 sortMap.insert(sortString.arg("C", it.key()), it.key());
281 else
282 sortMap.insert(sortString.arg("D", it.key()), it.key());
283 }
284 }
285 QMap<QString, QString>::Iterator itc;
286 for (itc = sortMap.begin(); itc != sortMap.end(); ++itc)
287 {
288 const ScColor& color = m_colorList[itc.value()];
289 QTreeWidgetItem *item = new QTreeWidgetItem(colorItems);
290 item->setText(0, itc.value());
291 if (itc.value() == addedName)
292 ret = item;
293 QPixmap* pPixmap = getFancyPixmap(color, m_doc);
294 item->setIcon(0, *pPixmap);
295 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
296 item->setData(0, Qt::ToolTipRole, getColorTooltip(color));
297 }
298 }
299 else
300 {
301 ColorList::Iterator it;
302 for (it = m_colorList.begin(); it != m_colorList.end(); ++it)
303 {
304 const ScColor& color = it.value();
305 QTreeWidgetItem *item = new QTreeWidgetItem(colorItems);
306 item->setText(0, it.key());
307 if (it.key() == addedName)
308 ret = item;
309 QPixmap* pPixmap = getFancyPixmap(color, m_doc);
310 item->setIcon(0, *pPixmap);
311 item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
312 item->setData(0, Qt::ToolTipRole, getColorTooltip(color));
313 }
314 }
315 return ret;
316 }
317
slotRightClick(QPoint p)318 void ColorsAndFillsDialog::slotRightClick(QPoint p)
319 {
320 QTreeWidgetItem* it = dataTree->itemAt(p);
321 if (!it)
322 return;
323
324 if ((it->parent() == colorItems) || (it == colorItems))
325 {
326 QMenu *pmen = new QMenu();
327 // qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
328 pmen->addAction( tr("Sort by Name"));
329 pmen->addAction( tr("Sort by Color"));
330 pmen->addAction( tr("Sort by Type"));
331 sortRule = pmen->actions().indexOf(pmen->exec(QCursor::pos()));
332 delete pmen;
333 updateColorList();
334 }
335 }
336
selEditColor(QTreeWidgetItem * it)337 void ColorsAndFillsDialog::selEditColor(QTreeWidgetItem *it)
338 {
339 if ((it) && (!paletteLocked))
340 {
341 if ((it->parent() == colorItems) || (it->parent() == gradientItems))
342 {
343 QString curCol = it->text(0);
344 bool enableDel = (!isMandatoryColor(curCol)) && (m_colorList.count() > 1);
345 bool enableEdit = (!isMandatoryColor(curCol));
346 duplicateButton->setEnabled(curCol != "Registration");
347 deleteButton->setEnabled(enableDel);
348 editButton->setEnabled(enableEdit);
349 if (enableEdit)
350 editColorItem();
351 }
352 }
353 }
354
itemSelectionChanged()355 void ColorsAndFillsDialog::itemSelectionChanged()
356 {
357 QList<QTreeWidgetItem *> selItems = dataTree->selectedItems();
358 if (selItems.count() > 1)
359 deleteButton->setEnabled(true);
360 }
361
itemSelected(QTreeWidgetItem * it)362 void ColorsAndFillsDialog::itemSelected(QTreeWidgetItem* it)
363 {
364 QList<QTreeWidgetItem *> selItems = dataTree->selectedItems();
365 importButton->setText( tr("&Import"));
366 newButton->setText( tr("Add"));
367 editButton->setText( tr("&Edit"));
368 if ((it) && (!paletteLocked))
369 {
370 if ((it->parent() == colorItems) || (it->parent() == gradientItems))
371 {
372 importButton->setEnabled(false);
373 newButton->setEnabled(true);
374 deleteUnusedButton->setEnabled(it->parent() == colorItems);
375 if (it->parent() == colorItems)
376 {
377 QString curCol = it->text(0);
378 //ScColor tmpColor = m_colorList[curCol];
379 bool enableDel = (!isMandatoryColor(curCol)) && (m_colorList.count() > 1);
380 bool enableEdit = (!isMandatoryColor(curCol));
381 duplicateButton->setEnabled(curCol != "Registration");
382 deleteButton->setEnabled(enableDel);
383 editButton->setEnabled(enableEdit);
384 }
385 else
386 {
387 editButton->setEnabled(true);
388 duplicateButton->setEnabled(true);
389 deleteButton->setEnabled(true);
390 }
391 }
392 else if (it->parent() == patternItems)
393 {
394 importButton->setText( tr("Load File"));
395 newButton->setText( tr("Load Set"));
396 editButton->setText( tr("Rename"));
397 importButton->setEnabled(true);
398 newButton->setEnabled(true);
399 editButton->setEnabled(true);
400 duplicateButton->setEnabled(false);
401 deleteButton->setEnabled(true);
402 }
403 else if (it == patternItems)
404 {
405 importButton->setText( tr("Load File"));
406 newButton->setText( tr("Load Set"));
407 importButton->setEnabled(true);
408 newButton->setEnabled(true);
409 editButton->setEnabled(false);
410 duplicateButton->setEnabled(false);
411 if (selItems.count() < 2)
412 deleteButton->setEnabled(it->childCount() > 0);
413 else
414 deleteButton->setEnabled(true);
415 }
416 else
417 {
418 importButton->setEnabled(true);
419 newButton->setEnabled(true);
420 editButton->setEnabled(false);
421 duplicateButton->setEnabled(false);
422 if (selItems.count() < 2)
423 deleteButton->setEnabled(it->childCount() > 0);
424 else
425 deleteButton->setEnabled(true);
426 deleteUnusedButton->setEnabled((it == colorItems) && (it->childCount() > 0));
427 }
428 }
429 else
430 {
431 importButton->setEnabled(false);
432 newButton->setEnabled(false);
433 editButton->setEnabled(false);
434 duplicateButton->setEnabled(false);
435 deleteButton->setEnabled(false);
436 deleteUnusedButton->setEnabled(false);
437 dataTree->clearSelection();
438 }
439 }
440
createNew()441 void ColorsAndFillsDialog::createNew()
442 {
443 if (paletteLocked)
444 return;
445 QTreeWidgetItem* it = dataTree->currentItem();
446 if (!it)
447 return;
448
449 if ((it->parent() == gradientItems) || (it == gradientItems))
450 {
451 VGradient fill_gradient = VGradient(VGradient::linear);
452 fill_gradient.clearStops();
453 fill_gradient.addStop(QColor(Qt::black), 0.0, 0.5, 1.0, "Black", 100);
454 fill_gradient.addStop(QColor(Qt::white), 1.0, 0.5, 1.0, "White", 100);
455 gradientEditDialog *dia = new gradientEditDialog(this, tr("New Gradient"), fill_gradient, m_colorList, m_doc, &dialogGradients, true);
456 if (dia->exec())
457 {
458 dialogGradients.insert(dia->name(), dia->gradient());
459 QTreeWidgetItem *lg = updateGradientList(dia->name());
460 if (lg != nullptr)
461 {
462 dataTree->expandItem(lg->parent());
463 dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
464 }
465 itemSelected(dataTree->currentItem());
466 modified = true;
467 }
468 delete dia;
469 }
470 else if ((it->parent() == colorItems) || (it == colorItems))
471 {
472 ScColor tmpColor = ScColor(0, 0, 0, 0);
473 CMYKChoose* dia = new CMYKChoose(this, m_doc, tmpColor, tr("New Color"), &m_colorList, true);
474 if (dia->exec())
475 {
476 dia->Farbe.setSpotColor(dia->isSpotColor());
477 m_colorList.insert(dia->colorName(), dia->Farbe);
478 QTreeWidgetItem *lg = updateColorList(dia->colorName());
479 if (lg != nullptr)
480 {
481 dataTree->expandItem(lg->parent());
482 dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
483 }
484 itemSelected(dataTree->currentItem());
485 modified = true;
486 }
487 delete dia;
488 }
489 else if ((it->parent() == patternItems) || (it == patternItems))
490 {
491 loadPatternDir();
492 updateColorList();
493 updateGradientList();
494 updatePatternList();
495 itemSelected(nullptr);
496 }
497 }
498
editColorItem()499 void ColorsAndFillsDialog::editColorItem()
500 {
501 if (paletteLocked)
502 return;
503 QTreeWidgetItem* it = dataTree->currentItem();
504 if (!it)
505 return;
506
507 if (it->parent() == gradientItems)
508 {
509 QString gradN = it->text(0);
510 QString patternName = origNames[it->text(0)];
511 QString newName;
512 gradientEditDialog *dia = new gradientEditDialog(this, gradN, dialogGradients[gradN], m_colorList, m_doc, &dialogGradients, false);
513 if (dia->exec())
514 {
515 newName = dia->name();
516 if (newName != gradN)
517 {
518 origNames.remove(patternName);
519 origNames.insert(newName, patternName);
520 replaceMap.insert(patternName, newName);
521 dialogGradients.remove(gradN);
522 dialogGradients.insert(newName, dia->gradient());
523 }
524 else
525 dialogGradients[gradN] = dia->gradient();
526 QStringList patterns = dialogPatterns.keys();
527 for (int c = 0; c < dialogPatterns.count(); ++c)
528 {
529 ScPattern pa = dialogPatterns[patterns[c]];
530 for (int o = 0; o < pa.items.count(); o++)
531 {
532 PageItem *ite = pa.items.at(o);
533 if (ite->gradient() == gradN)
534 ite->setGradient(newName);
535 if (ite->strokeGradient() == gradN)
536 ite->setStrokeGradient(newName);
537 if (ite->gradientMask() == gradN)
538 ite->setGradientMask(newName);
539 }
540 PageItem *ite = pa.items.at(0);
541 dialogPatterns[patterns[c]].pattern = ite->DrawObj_toImage(pa.items, 1.0);
542 }
543 QTreeWidgetItem *lg = updateGradientList(dia->name());
544 if (lg != nullptr)
545 {
546 dataTree->expandItem(lg->parent());
547 dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
548 }
549 itemSelected(dataTree->currentItem());
550 modified = true;
551 }
552 delete dia;
553 }
554 else if (it->parent() == colorItems)
555 {
556 ScColor tmpColor = m_colorList[it->text(0)];
557 CMYKChoose* dia = new CMYKChoose(this, m_doc, tmpColor, it->text(0), &m_colorList, false);
558 if (dia->exec())
559 {
560 dia->Farbe.setSpotColor(dia->isSpotColor());
561 dia->Farbe.setRegistrationColor(tmpColor.isRegistrationColor());
562 m_colorList[dia->colorName()] = dia->Farbe;
563 if (it->text(0) != dia->colorName())
564 {
565 replaceColorMap.insert(it->text(0), dia->colorName());
566 m_colorList.remove(it->text(0));
567 }
568 updateGradientColors(dia->colorName(), it->text(0));
569 updateGradientList();
570 updatePatternList();
571 QTreeWidgetItem *lg = updateColorList(dia->colorName());
572 if (lg != nullptr)
573 {
574 dataTree->expandItem(lg->parent());
575 dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
576 }
577 itemSelected(dataTree->currentItem());
578 modified = true;
579 }
580 delete dia;
581 }
582 else if (it->parent() == patternItems)
583 {
584 QString patternName = origNames[it->text(0)];
585 QString newName = "";
586 Query dia(this, "tt", true, tr("&Name:"), tr("Rename Entry"));
587 dia.setEditText(it->text(0), true);
588 dia.setTestList(dialogPatterns.keys());
589 if (dia.exec())
590 {
591 newName = dia.getEditText();
592 ScPattern pat = dialogPatterns.take(it->text(0));
593 dialogPatterns.insert(newName, pat);
594 replaceMapPatterns.insert(patternName, newName);
595 origNamesPatterns.remove(it->text(0));
596 origNamesPatterns.insert(newName, patternName);
597 QStringList patterns = dialogPatterns.keys();
598 for (int c = 0; c < dialogPatterns.count(); ++c)
599 {
600 ScPattern pa = dialogPatterns[patterns[c]];
601 for (int o = 0; o < pa.items.count(); o++)
602 {
603 PageItem *ite = pa.items.at(o);
604 if ((ite->pattern() == patternName) && ((ite->GrType == 8) || (ite->itemType() == PageItem::Symbol)))
605 ite->setPattern(newName);
606 if (!ite->strokePattern().isEmpty())
607 {
608 if (ite->strokePattern() == patternName)
609 ite->setStrokePattern(newName);
610 }
611 if (!ite->patternMask().isEmpty())
612 {
613 if (ite->patternMask() == patternName)
614 ite->setPatternMask(newName);
615 }
616 }
617 }
618 QTreeWidgetItem *lg = updatePatternList(newName);
619 if (lg != nullptr)
620 {
621 dataTree->expandItem(lg->parent());
622 dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
623 }
624 itemSelected(dataTree->currentItem());
625 }
626 else
627 return;
628 }
629 }
630
duplicateColorItem()631 void ColorsAndFillsDialog::duplicateColorItem()
632 {
633 if (paletteLocked)
634 return;
635 QTreeWidgetItem* it = dataTree->currentItem();
636 if (!it)
637 return;
638
639 if (it->parent() == gradientItems)
640 {
641 QString gradN = tr("Copy of %1").arg(it->text(0));
642 dialogGradients.insert(gradN, dialogGradients[it->text(0)]);
643 origNames.insert(gradN, gradN);
644 QString patternName = origNames[gradN];
645 QString newName;
646 gradientEditDialog *dia = new gradientEditDialog(this, gradN, dialogGradients[gradN], m_colorList, m_doc, &dialogGradients, false);
647 if (dia->exec())
648 {
649 newName = dia->name();
650 if (newName != gradN)
651 {
652 origNames.remove(patternName);
653 origNames.insert(newName, patternName);
654 replaceMap.insert(patternName, newName);
655 dialogGradients.remove(gradN);
656 dialogGradients.insert(newName, dia->gradient());
657 }
658 else
659 dialogGradients[gradN] = dia->gradient();
660 updatePatternList();
661 QTreeWidgetItem *lg = updateGradientList(dia->name());
662 if (lg != nullptr)
663 {
664 dataTree->expandItem(lg->parent());
665 dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
666 }
667 itemSelected(dataTree->currentItem());
668 modified = true;
669 }
670 else
671 {
672 dialogGradients.remove(gradN);
673 origNames.remove(gradN);
674 }
675 delete dia;
676 }
677 else if (it->parent() == colorItems)
678 {
679 QString nam = tr("Copy of %1").arg(it->text(0));
680 m_colorList.insert(nam, m_colorList[it->text(0)]);
681 ScColor tmpColor = m_colorList[nam];
682 CMYKChoose* dia = new CMYKChoose(this, m_doc, tmpColor, nam, &m_colorList, false);
683 if (dia->exec())
684 {
685 dia->Farbe.setSpotColor(dia->isSpotColor());
686 dia->Farbe.setRegistrationColor(tmpColor.isRegistrationColor());
687 m_colorList[dia->colorName()] = dia->Farbe;
688 if (nam != dia->colorName())
689 {
690 replaceColorMap.insert(nam, dia->colorName());
691 m_colorList.remove(nam);
692 }
693 updateGradientColors(dia->colorName(), nam);
694 updateGradientList();
695 updatePatternList();
696 QTreeWidgetItem *lg = updateColorList(dia->colorName());
697 if (lg != nullptr)
698 {
699 dataTree->expandItem(lg->parent());
700 dataTree->setCurrentItem(lg, 0, QItemSelectionModel::ClearAndSelect);
701 }
702 itemSelected(dataTree->currentItem());
703 modified = true;
704 }
705 else
706 m_colorList.remove(nam);
707 delete dia;
708 }
709 }
710
removeColorItem()711 void ColorsAndFillsDialog::removeColorItem()
712 {
713 if (paletteLocked)
714 return;
715 QList<QTreeWidgetItem *> selItems = dataTree->selectedItems();
716 if (selItems.count() > 1)
717 {
718 QStringList usedColors;
719 QStringList colors;
720 QStringList gradients;
721 QStringList patterns;
722 for (int a = 0; a < selItems.count(); a++)
723 {
724 QTreeWidgetItem* it = selItems[a];
725 if (it == gradientItems)
726 continue;
727 if (it == colorItems)
728 continue;
729 if (it == patternItems)
730 continue;
731 if (isMandatoryColor(it->text(0)))
732 continue;
733 if (it->parent() == gradientItems)
734 gradients.append(it->text(0));
735 if (it->parent() == colorItems)
736 colors.append(it->text(0));
737 if (it->parent() == patternItems)
738 patterns.append(it->text(0));
739 }
740 for (int a = 0; a < gradients.count(); a++)
741 {
742 dialogGradients.remove(gradients[a]);
743 replaceMap.insert(gradients[a], "");
744 }
745 bool hasUsed = false;
746 ColorList UsedCG = getGradientColors();
747 for (int a = 0; a < colors.count(); a++)
748 {
749 if (UsedCG.contains(colors[a]) || inDocUsedColors.contains(colors[a]))
750 {
751 hasUsed = true;
752 usedColors.append(colors[a]);
753 }
754 }
755 if (hasUsed)
756 {
757 ColorList dCols = m_colorList;
758 QString dColor = tr("Selected Colors");
759 for (int i = 0; i < usedColors.count(); i++)
760 {
761 dCols.remove(usedColors[i]);
762 }
763 dCols.insert(dColor , ScColor());
764 DelColor *dia = new DelColor(this, dCols, dColor, true);
765 if (dia->exec())
766 {
767 QString replacementColor(dia->getReplacementColor());
768 for (int i = 0; i < colors.count(); i++)
769 {
770 dColor = colors[i];
771 if (replacementColor == CommonStrings::tr_NoneColor)
772 replacementColor = CommonStrings::None;
773 if (replaceColorMap.values().contains(dColor))
774 {
775 QMap<QString,QString>::Iterator itt;
776 for (itt = replaceColorMap.begin(); itt != replaceColorMap.end(); ++itt)
777 {
778 if (itt.value() == dColor)
779 itt.value() = replacementColor;
780 }
781 }
782 replaceColorMap.insert(dColor, replacementColor);
783 m_colorList.remove(dColor);
784 updateGradientColors(replacementColor, dColor);
785 }
786 modified = true;
787 }
788 delete dia;
789 }
790 else
791 {
792 for (int a = 0; a < colors.count(); a++)
793 {
794 replaceColorMap.insert(colors[a], "Black");
795 m_colorList.remove(colors[a]);
796 }
797 modified = true;
798 }
799 updatePatternList();
800 updateGradientList();
801 updateColorList();
802 itemSelected(nullptr);
803 }
804 else
805 {
806 QTreeWidgetItem* it = dataTree->currentItem();
807 if (!it)
808 return;
809 if ((it->parent() == gradientItems) || (it == gradientItems))
810 {
811 if (it == gradientItems)
812 {
813 int t = ScMessageBox::warning(this, CommonStrings::trWarning, tr("Do you really want to clear all your gradients?"),
814 QMessageBox::Yes | QMessageBox::No,
815 QMessageBox::No, // GUI default
816 QMessageBox::Yes); // batch default
817 if (t == QMessageBox::No)
818 return;
819 replaceMap.clear();
820 for (QHash<QString, VGradient>::Iterator it = dialogGradients.begin(); it != dialogGradients.end(); ++it)
821 {
822 replaceMap.insert(it.key(), "");
823 }
824 dialogGradients.clear();
825 }
826 else
827 {
828 dialogGradients.remove(it->text(0));
829 replaceMap.insert(it->text(0), "");
830 }
831 }
832 else if ((it->parent() == colorItems) || (it == colorItems))
833 {
834 if (it == colorItems)
835 {
836 int t = ScMessageBox::warning(this, CommonStrings::trWarning, tr("Do you really want to clear all your colors and gradients?"),
837 QMessageBox::Yes | QMessageBox::No,
838 QMessageBox::No, // GUI default
839 QMessageBox::Yes); // batch default
840 if (t == QMessageBox::No)
841 return;
842 replaceMap.clear();
843 for (QHash<QString, VGradient>::Iterator it = dialogGradients.begin(); it != dialogGradients.end(); ++it)
844 {
845 replaceMap.insert(it.key(), "");
846 }
847 replaceColorMap.clear();
848 for (ColorList::Iterator it = m_colorList.begin(); it != m_colorList.end(); ++it)
849 {
850 replaceColorMap.insert(it.key(), "Black");
851 }
852 dialogPatterns.clear();
853 dialogGradients.clear();
854 m_colorList.clear();
855 m_colorList.ensureDefaultColors();
856 }
857 else
858 {
859 QString dColor = it->text(0);
860 if (isMandatoryColor(dColor))
861 return;
862 ColorList UsedCG = getGradientColors();
863 if (inDocUsedColors.contains(dColor) || UsedCG.contains(dColor))
864 {
865 DelColor *dia = new DelColor(this, m_colorList, dColor, true);
866 if (dia->exec())
867 {
868 QString replacementColor(dia->getReplacementColor());
869 if (replacementColor == CommonStrings::tr_NoneColor)
870 replacementColor = CommonStrings::None;
871 if (replaceColorMap.values().contains(dColor))
872 {
873 QMap<QString,QString>::Iterator itt;
874 for (itt = replaceColorMap.begin(); itt != replaceColorMap.end(); ++itt)
875 {
876 if (itt.value() == dColor)
877 itt.value() = replacementColor;
878 }
879 }
880 replaceColorMap.insert(dColor, replacementColor);
881 m_colorList.remove(dColor);
882 updateGradientColors(replacementColor, dColor);
883 }
884 delete dia;
885 }
886 else
887 {
888 replaceColorMap.insert(dColor, "Black");
889 updateGradientColors("Black", dColor);
890 m_colorList.remove(dColor);
891 }
892 }
893 }
894 else if ((it->parent() == patternItems) || (it == patternItems))
895 {
896 if (it == patternItems)
897 {
898 int t = ScMessageBox::warning(this, CommonStrings::trWarning, tr("Do you really want to clear all your patterns?"),
899 QMessageBox::Yes | QMessageBox::No,
900 QMessageBox::No, // GUI default
901 QMessageBox::Yes); // batch default
902 if (t == QMessageBox::No)
903 return;
904 replaceMapPatterns.clear();
905 for (QHash<QString, ScPattern>::Iterator it = dialogPatterns.begin(); it != dialogPatterns.end(); ++it)
906 {
907 replaceMapPatterns.insert(it.key(), "");
908 }
909 dialogPatterns.clear();
910 }
911 else if (it->parent() == patternItems)
912 {
913 QStringList patterns2Del;
914 QStringList mainPatterns = dialogPatterns.keys();
915 for (int a = 0; a < mainPatterns.count(); a++)
916 {
917 if (mainPatterns[a] != it->text(0))
918 {
919 QStringList subPatterns;
920 subPatterns = getUsedPatternsHelper(mainPatterns[a], subPatterns);
921 if (subPatterns.contains(it->text(0)))
922 patterns2Del.append(mainPatterns[a]);
923 }
924 }
925 patterns2Del.append(it->text(0));
926 for (int a = 0; a < patterns2Del.count(); a++)
927 {
928 dialogPatterns.remove(patterns2Del[a]);
929 }
930 }
931 }
932 updatePatternList();
933 updateGradientList();
934 updateColorList();
935 itemSelected(nullptr);
936 modified = true;
937 }
938 }
939
getUsedPatternsHelper(const QString & pattern,QStringList & results)940 QStringList ColorsAndFillsDialog::getUsedPatternsHelper(const QString& pattern, QStringList &results)
941 {
942 ScPattern *pat = &dialogPatterns[pattern];
943 QStringList pats;
944 pats.clear();
945 for (int c = 0; c < pat->items.count(); ++c)
946 {
947 if ((pat->items.at(c)->GrType == Gradient_Pattern) || (pat->items.at(c)->itemType() == PageItem::Symbol))
948 {
949 const QString& patName = pat->items.at(c)->pattern();
950 if (!patName.isEmpty() && !results.contains(patName))
951 pats.append(patName);
952 }
953 const QString& pat2 = pat->items.at(c)->strokePattern();
954 if (!pat2.isEmpty() && !results.contains(pat2))
955 pats.append(pat->items.at(c)->strokePattern());
956 const QString& pat3 = pat->items.at(c)->patternMask();
957 if (!pat3.isEmpty() && !results.contains(pat3))
958 pats.append(pat->items.at(c)->patternMask());
959 }
960 if (!pats.isEmpty())
961 {
962 results = pats;
963 for (int c = 0; c < pats.count(); ++c)
964 {
965 getUsedPatternsHelper(pats[c], results);
966 }
967 }
968 /* QStringList pats;
969 pats.clear();
970 for (int c = 0; c < pat->items.count(); ++c)
971 {
972 if ((!results.contains(pat->items.at(c)->pattern())) && ((pat->items.at(c)->GrType == Gradient_Pattern) || (pat->items.at(c)->itemType() == PageItem::Symbol)))
973 pats.append(pat->items.at(c)->pattern());
974 }
975 if (!pats.isEmpty())
976 {
977 results = pats;
978 for (int c = 0; c < pats.count(); ++c)
979 {
980 getUsedPatternsHelper(pats[c], results);
981 }
982 } */
983 return results;
984 }
985
removeUnusedColorItem()986 void ColorsAndFillsDialog::removeUnusedColorItem()
987 {
988 if (paletteLocked)
989 return;
990 QTreeWidgetItem* it = dataTree->currentItem();
991 if (!it)
992 return;
993
994 if ((it->parent() == colorItems) || (it == colorItems))
995 {
996 ColorList UsedC;
997 ColorList::Iterator it;
998 ColorList UsedCG = getGradientColors();
999 if (mainWin->HaveDoc)
1000 {
1001 m_colorList = inDocUsedColors;
1002 for (it = UsedCG.begin(); it != UsedCG.end(); ++it)
1003 {
1004 if (!m_colorList.contains(it.key()))
1005 m_colorList.insert(it.key(), it.value());
1006 }
1007 }
1008 else
1009 m_colorList = UsedCG;
1010 m_colorList.ensureDefaultColors();
1011 updatePatternList();
1012 updateGradientList();
1013 updateColorList();
1014 itemSelected(nullptr);
1015 modified = true;
1016 }
1017 }
1018
importColorItems()1019 void ColorsAndFillsDialog::importColorItems()
1020 {
1021 QTreeWidgetItem* it = dataTree->currentItem();
1022 if (!it)
1023 return;
1024
1025 if ((it->parent() == gradientItems) || (it == gradientItems))
1026 {
1027 QString fileName;
1028 QString allFormats = tr("All Supported Formats")+" (";
1029 allFormats += "*.sgr *.SGR";
1030 allFormats += " *.ggr *.GGR";
1031 allFormats += ");;";
1032 QString formats = tr("Scribus Gradient Files \"*.sgr\" (*.sgr *.SGR);;");
1033 formats += tr("Gimp Gradient Files \"*.ggr\" (*.ggr *.GGR);;");
1034 formats += tr("All Files (*)");
1035 allFormats += formats;
1036 PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
1037 QString wdir = dirs->get("gradients", ".");
1038 CustomFDialog dia(this, wdir, tr("Open"), allFormats, fdHidePreviewCheckBox | fdExistingFiles | fdDisableOk);
1039 if (dia.exec() == QDialog::Accepted)
1040 fileName = dia.selectedFile();
1041 else
1042 return;
1043 if (!fileName.isEmpty())
1044 {
1045 PrefsManager::instance().prefsFile->getContext("dirs")->set("gradients", fileName.left(fileName.lastIndexOf("/")));
1046 QFileInfo fi(fileName);
1047 QString ext = fi.suffix().toLower();
1048 if (ext == "sgr")
1049 loadScribusFormat(fileName);
1050 else if (ext == "ggr")
1051 loadGimpFormat(fileName);
1052 updateGradientList();
1053 updateColorList();
1054 itemSelected(nullptr);
1055 modified = true;
1056 }
1057 }
1058 else if ((it->parent() == colorItems) || (it == colorItems))
1059 {
1060 QStringList allFormatsV = LoadSavePlugin::getExtensionsForColors();
1061 allFormatsV.removeAll("sla");
1062 allFormatsV.removeAll("scd");
1063 allFormatsV.removeAll("sla.gz");
1064 allFormatsV.removeAll("scd.gz");
1065 allFormatsV.removeAll("ai");
1066 QString extra = allFormatsV.join(" *.");
1067 extra.prepend(" *.");
1068 QString fileName;
1069 PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
1070 QString wdir = dirs->get("colors", ".");
1071 QString docexts("*.sla *.sla.gz *.scd *.scd.gz");
1072 QString aiepsext(FormatsManager::instance()->extensionListForFormat(FormatsManager::EPS|FormatsManager::PS|FormatsManager::AI, 0));
1073 QString ooexts(" *.acb *.aco *.ase *.cxf *.gpl *.sbz *.skp *.soc *.xml");
1074 ooexts += extra;
1075 QString filter = tr("All Supported Formats (%1);;Documents (%2);;Other Files (%3);;All Files (*)").arg(docexts+" "+aiepsext+ooexts, docexts, aiepsext+ooexts);
1076 CustomFDialog dia(this, wdir, tr("Import Colors"), filter, fdHidePreviewCheckBox | fdDisableOk);
1077 if (dia.exec() == QDialog::Accepted)
1078 fileName = dia.selectedFile();
1079 else
1080 return;
1081 if (!fileName.isEmpty())
1082 dirs->set("colors", fileName.left(fileName.lastIndexOf("/")));
1083 if (!importColorsFromFile(fileName, m_colorList))
1084 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 -> 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>");
1085 else
1086 {
1087 m_colorList.ensureDefaultColors();
1088 updateGradientList();
1089 updateColorList();
1090 modified = true;
1091 }
1092 itemSelected(nullptr);
1093 }
1094 else if ((it->parent() == patternItems) || (it == patternItems))
1095 {
1096 QString fileName;
1097 QStringList formats;
1098 QString allFormats = tr("All Supported Formats")+" (";
1099 int fmtCode = FORMATID_FIRSTUSER;
1100 const FileFormat *fmt = LoadSavePlugin::getFormatById(fmtCode);
1101 while (fmt != nullptr)
1102 {
1103 if (fmt->load)
1104 {
1105 formats.append(fmt->filter);
1106 int an = fmt->filter.indexOf("(");
1107 int en = fmt->filter.indexOf(")");
1108 while (an != -1)
1109 {
1110 allFormats += fmt->filter.mid(an+1, en-an-1)+" ";
1111 an = fmt->filter.indexOf("(", en);
1112 en = fmt->filter.indexOf(")", an);
1113 }
1114 }
1115 fmtCode++;
1116 fmt = LoadSavePlugin::getFormatById(fmtCode);
1117 }
1118 allFormats += "*.sce *.SCE ";
1119 formats.append("Scribus Objects (*.sce *.SCE)");
1120 QString form1 = "";
1121 QString form2 = "";
1122 QStringList imgFormats;
1123 bool jpgFound = false;
1124 bool tiffFound = false;
1125 for (int i = 0; i < QImageReader::supportedImageFormats().count(); ++i )
1126 {
1127 form1 = QString(QImageReader::supportedImageFormats().at(i)).toLower();
1128 form2 = QString(QImageReader::supportedImageFormats().at(i)).toUpper();
1129 if ((form1 == "png") || (form1 == "xpm") || (form1 == "gif"))
1130 {
1131 formats.append(form2 + " (*."+form1+" *."+form2+")");
1132 allFormats += "*."+form1+" *."+form2+" ";
1133 imgFormats.append(form1);
1134 }
1135 else if ((form1 == "jpg") || (form1 == "jpeg"))
1136 {
1137 // JPEG is a special case because both .jpg and .jpeg
1138 // are acceptable extensions.
1139 if (!jpgFound)
1140 {
1141 formats.append("JPEG (*.jpg *.jpeg *.JPG *.JPEG)");
1142 allFormats += "*.jpg *.jpeg *.JPG *.JPEG ";
1143 imgFormats.append("jpeg");
1144 imgFormats.append("jpg");
1145 jpgFound = true;
1146 }
1147 }
1148 else if ((form1 == "tif") || (form1 == "tiff"))
1149 {
1150 if (!tiffFound)
1151 {
1152 formats.append("TIFF (*.tif *.tiff *.TIF *.TIFF)");
1153 allFormats += "*.tif *.tiff *.TIF *.TIFF ";
1154 imgFormats.append("tif");
1155 imgFormats.append("tiff");
1156 tiffFound = true;
1157 }
1158 }
1159 else if (form1 != "svg")
1160 {
1161 imgFormats.append(form1);
1162 allFormats += "*."+form1+" *."+form2+" ";
1163 }
1164 }
1165 if (!tiffFound)
1166 {
1167 formats.append("TIFF (*.tif *.tiff *.TIF *.TIFF)");
1168 allFormats += "*.tif *.tiff *.TIF *.TIFF ";
1169 }
1170 if (!jpgFound)
1171 {
1172 formats.append("JPEG (*.jpg *.jpeg *.JPG *.JPEG)");
1173 allFormats += "*.jpg *.jpeg *.JPG *.JPEG ";
1174 }
1175 formats.append("PSD (*.psd *.PSD)");
1176 formats.append("Gimp Patterns (*.pat *.PAT)");
1177 allFormats += "*.psd *.PSD ";
1178 allFormats += "*.pat *.PAT);;";
1179 imgFormats.append("tif");
1180 imgFormats.append("tiff");
1181 imgFormats.append("pat");
1182 imgFormats.append("psd");
1183 // imgFormats.append("pdf");
1184 imgFormats.append("eps");
1185 imgFormats.append("epsi");
1186 imgFormats.append("ps");
1187 formats.sort();
1188 allFormats += formats.join(";;");
1189 PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
1190 QString wdir = dirs->get("patterns", ".");
1191 CustomFDialog dia(this, wdir, tr("Open"), allFormats, fdHidePreviewCheckBox | fdExistingFiles | fdDisableOk);
1192 if (dia.exec() != QDialog::Accepted)
1193 return;
1194 fileName = dia.selectedFile();
1195 if (fileName.isEmpty())
1196 return;
1197 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
1198 PrefsManager::instance().prefsFile->getContext("dirs")->set("patterns", fileName.left(fileName.lastIndexOf("/")));
1199 QFileInfo fi(fileName);
1200 if ((fi.suffix().toLower() == "sce") || (!imgFormats.contains(fi.suffix().toLower())))
1201 {
1202 loadVectors(fileName);
1203 }
1204 else
1205 {
1206 QString patNam = fi.baseName().trimmed().simplified().replace(" ", "_");
1207 ScPattern pat = ScPattern();
1208 pat.setDoc(m_doc);
1209 pat.setPattern(fileName);
1210 if (!dialogPatterns.contains(patNam))
1211 {
1212 dialogPatterns.insert(patNam, pat);
1213 origNamesPatterns.insert(patNam, patNam);
1214 }
1215 }
1216 updateColorList();
1217 updateGradientList();
1218 updatePatternList();
1219 itemSelected(nullptr);
1220 qApp->restoreOverrideCursor();
1221 }
1222 }
1223
loadPatternDir()1224 void ColorsAndFillsDialog::loadPatternDir()
1225 {
1226 PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
1227 QString wdir = dirs->get("patterndir", ".");
1228 QString fileName = QFileDialog::getExistingDirectory(this, tr("Choose a Directory"), wdir);
1229 if (fileName.isEmpty())
1230 return;
1231
1232 QStringList formats;
1233 formats += "eps";
1234 formats += "epsi";
1235 formats += "pdf";
1236 QString form1 = "";
1237 for (int i = 0; i < QImageReader::supportedImageFormats().count(); ++i)
1238 {
1239 form1 = QString(QImageReader::supportedImageFormats().at(i)).toLower();
1240 if (form1 == "jpeg")
1241 form1 = "jpg";
1242 if ((form1 == "png") || (form1 == "xpm") || (form1 == "gif"))
1243 formats += form1;
1244 else if (form1 == "jpg")
1245 {
1246 formats += "jpg";
1247 formats += "jpeg";
1248 }
1249 }
1250 formats += "tif";
1251 formats += "tiff";
1252 formats += "psd";
1253 formats += "pat";
1254 QDir d(fileName, "*", QDir::Name, QDir::Files | QDir::Readable | QDir::NoSymLinks);
1255 if ((!d.exists()) || (d.count() == 0))
1256 return;
1257
1258 mainWin->setStatusBarInfoText( tr("Loading Patterns"));
1259 mainWin->mainWindowProgressBar->reset();
1260 mainWin->mainWindowProgressBar->setMaximum(d.count() * 2);
1261 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
1262 qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
1263 for (uint dc = 0; dc < d.count(); ++dc)
1264 {
1265 mainWin->mainWindowProgressBar->setValue(dc);
1266 qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
1267 QFileInfo fi(QDir::cleanPath(QDir::toNativeSeparators(fileName + "/" + d[dc])));
1268 QString ext = fi.suffix().toLower();
1269 if ((ext == "sce") || (!formats.contains(ext)))
1270 loadVectors(QDir::cleanPath(QDir::toNativeSeparators(fileName + "/" + d[dc])));
1271 }
1272 for (uint dc = 0; dc < d.count(); ++dc)
1273 {
1274 mainWin->mainWindowProgressBar->setValue(d.count() + dc);
1275 qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
1276
1277 QFileInfo fi(QDir::cleanPath(QDir::toNativeSeparators(fileName + "/" + d[dc])));
1278 QString ext = fi.suffix().toLower();
1279 if ((ext == "sce") || (!formats.contains(ext)))
1280 continue;
1281 if (!formats.contains(ext))
1282 continue;
1283
1284 QString patNam = fi.baseName().trimmed().simplified().replace(" ", "_");
1285 if (!dialogPatterns.contains(patNam))
1286 {
1287 ScPattern pat = ScPattern();
1288 pat.setDoc(m_doc);
1289 pat.setPattern(QDir::cleanPath(QDir::toNativeSeparators(fileName + "/" + d[dc])));
1290 dialogPatterns.insert(patNam, pat);
1291 origNamesPatterns.insert(patNam, patNam);
1292 }
1293 }
1294 d.cdUp();
1295 dirs->set("patterndir", d.absolutePath());
1296 qApp->restoreOverrideCursor();
1297 mainWin->setStatusBarInfoText("");
1298 mainWin->mainWindowProgressBar->reset();
1299 }
1300
loadVectors(const QString & data)1301 void ColorsAndFillsDialog::loadVectors(const QString& data)
1302 {
1303 int storedPageNum = m_doc->currentPageNumber();
1304 int storedContentsX = m_doc->view()->contentsX();
1305 int storedContentsY = m_doc->view()->contentsY();
1306 double storedViewScale = m_doc->view()->scale();
1307 FPoint stored_minCanvasCoordinate = m_doc->minCanvasCoordinate;
1308 FPoint stored_maxCanvasCoordinate = m_doc->maxCanvasCoordinate;
1309
1310 m_doc->PageColors = m_colorList;
1311 m_doc->docGradients = dialogGradients;
1312 UndoManager::instance()->setUndoEnabled(false);
1313 m_doc->setLoading(true);
1314 QFileInfo fi(data);
1315 QString patNam = fi.baseName().trimmed().simplified().replace(" ", "_");
1316 uint ac = m_doc->Items->count();
1317 uint ap = m_doc->docPatterns.count();
1318 bool savedAlignGrid = m_doc->SnapGrid;
1319 bool savedAlignGuides = m_doc->SnapGuides;
1320 bool savedAlignElement = m_doc->SnapElement;
1321 m_doc->SnapGrid = false;
1322 m_doc->SnapGuides = false;
1323 m_doc->SnapElement = false;
1324 if (fi.suffix().toLower() == "sce")
1325 {
1326 ScriXmlDoc ss;
1327 ss.readElem(data, m_doc, m_doc->currentPage()->xOffset(), m_doc->currentPage()->yOffset(), true, true);
1328 }
1329 else
1330 {
1331 FileLoader *fileLoader = new FileLoader(data);
1332 int testResult = fileLoader->testFile();
1333 delete fileLoader;
1334 if ((testResult != -1) && (testResult >= FORMATID_FIRSTUSER))
1335 {
1336 const FileFormat * fmt = LoadSavePlugin::getFormatById(testResult);
1337 if (fmt)
1338 {
1339 fmt->setupTargets(m_doc, nullptr, mainWin, nullptr, &(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts));
1340 fmt->loadFile(data, LoadSavePlugin::lfUseCurrentPage|LoadSavePlugin::lfInteractive|LoadSavePlugin::lfScripted|LoadSavePlugin::lfKeepPatterns|LoadSavePlugin::lfLoadAsPattern);
1341 }
1342 }
1343 }
1344 m_doc->SnapGrid = savedAlignGrid;
1345 m_doc->SnapGuides = savedAlignGuides;
1346 m_doc->SnapElement = savedAlignElement;
1347 uint ae = m_doc->Items->count();
1348 if (ac != ae)
1349 {
1350 for (uint as = ac; as < ae; ++as)
1351 {
1352 PageItem* ite = m_doc->Items->at(ac);
1353 if (ite->itemType() == PageItem::PathText)
1354 ite->updatePolyClip();
1355 else
1356 ite->layout();
1357 }
1358 ScPattern pat = ScPattern();
1359 pat.setDoc(m_doc);
1360 PageItem* currItem = m_doc->Items->at(ac);
1361 double minx = std::numeric_limits<double>::max();
1362 double miny = std::numeric_limits<double>::max();
1363 double maxx = -std::numeric_limits<double>::max();
1364 double maxy = -std::numeric_limits<double>::max();
1365 double x1, x2, y1, y2;
1366 currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
1367 minx = qMin(minx, x1);
1368 miny = qMin(miny, y1);
1369 maxx = qMax(maxx, x2);
1370 maxy = qMax(maxy, y2);
1371 pat.pattern = currItem->DrawObj_toImage(qMin(qMax(maxx - minx, maxy - miny), 500.0));
1372 pat.width = maxx - minx;
1373 pat.height = maxy - miny;
1374 currItem->setXYPos(0, 0, true);
1375 currItem->setWidthHeight(maxx - minx, maxy - miny, true);
1376 currItem->groupWidth = maxx - minx;
1377 currItem->groupHeight = maxy - miny;
1378 currItem->gWidth = maxx - minx;
1379 currItem->gHeight = maxy - miny;
1380 for (uint as = ac; as < ae; ++as)
1381 {
1382 pat.items.append(m_doc->Items->takeAt(ac));
1383 }
1384 if (!dialogPatterns.contains(patNam))
1385 {
1386 dialogPatterns.insert(patNam, pat);
1387 origNamesPatterns.insert(patNam, patNam);
1388 }
1389 for (QHash<QString, ScPattern>::Iterator it = m_doc->docPatterns.begin(); it != m_doc->docPatterns.end(); ++it)
1390 {
1391 if (!origPatterns.contains(it.key()))
1392 {
1393 dialogPatterns.insert(it.key(), it.value());
1394 origNamesPatterns.insert(it.key(), it.key());
1395 }
1396 }
1397 }
1398 else
1399 {
1400 uint ape = m_doc->docPatterns.count();
1401 if (ap != ape)
1402 {
1403 for (QHash<QString, ScPattern>::Iterator it = m_doc->docPatterns.begin(); it != m_doc->docPatterns.end(); ++it)
1404 {
1405 if (!origPatterns.contains(it.key()))
1406 {
1407 dialogPatterns.insert(it.key(), it.value());
1408 origNamesPatterns.insert(it.key(), it.key());
1409 }
1410 }
1411 }
1412 }
1413 m_doc->setLoading(false);
1414 m_colorList = m_doc->PageColors;
1415 dialogGradients = m_doc->docGradients;
1416 UndoManager::instance()->setUndoEnabled(true);
1417
1418 m_doc->minCanvasCoordinate = stored_minCanvasCoordinate;
1419 m_doc->maxCanvasCoordinate = stored_maxCanvasCoordinate;
1420 m_doc->view()->setScale(storedViewScale);
1421 m_doc->setCurrentPage(m_doc->DocPages.at(storedPageNum));
1422 m_doc->view()->setContentsPos(static_cast<int>(storedContentsX * storedViewScale), static_cast<int>(storedContentsY * storedViewScale));
1423 }
1424
isMandatoryColor(const QString & colorName)1425 bool ColorsAndFillsDialog::isMandatoryColor(const QString& colorName)
1426 {
1427 if (colorName == "Black" || colorName == "White")
1428 return true;
1429 ScColor color = m_colorList.value(colorName, ScColor());
1430 return color.isRegistrationColor();
1431 }
1432
getColorTooltip(const ScColor & color)1433 QString ColorsAndFillsDialog::getColorTooltip(const ScColor& color)
1434 {
1435 QString tooltip;
1436 if (color.getColorModel() == colorModelRGB)
1437 {
1438 int r, g, b;
1439 color.getRawRGBColor(&r, &g, &b);
1440 tooltip = tr("R: %1 G: %2 B: %3").arg(r).arg(g).arg(b);
1441 }
1442 else if (color.getColorModel() == colorModelCMYK)
1443 {
1444 double c, m, y, k;
1445 color.getCMYK(&c, &m, &y, &k);
1446 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);
1447 }
1448 else if (color.getColorModel() == colorModelLab)
1449 {
1450 double L, a, b;
1451 color.getLab(&L, &a, &b);
1452 tooltip = tr("L: %1 a: %2 b: %3").arg(L, 0, 'f', 2).arg(a, 0, 'f', 2).arg(b, 0, 'f', 2);
1453 }
1454 return tooltip;
1455 }
1456
getGradientColors()1457 ColorList ColorsAndFillsDialog::getGradientColors()
1458 {
1459 ColorList colorList;
1460 QHash<QString,VGradient>::Iterator itg;
1461 for (itg = dialogGradients.begin(); itg != dialogGradients.end(); ++itg)
1462 {
1463 QList<VColorStop*> cstops = itg.value().colorStops();
1464 for (int cst = 0; cst < itg.value().stops(); ++cst)
1465 {
1466 if ((!colorList.contains(cstops.at(cst)->name)) && (cstops.at(cst)->name != CommonStrings::None))
1467 colorList.insert(cstops.at(cst)->name, m_colorList[cstops.at(cst)->name]);
1468 }
1469 }
1470 QStringList patterns = dialogPatterns.keys();
1471 for (int c = 0; c < dialogPatterns.count(); ++c)
1472 {
1473 ScPattern pa = dialogPatterns[patterns[c]];
1474 for (int o = 0; o < pa.items.count(); o++)
1475 {
1476 PageItem *ite = pa.items.at(o);
1477 if ((!colorList.contains(ite->lineColor())) && (ite->lineColor() != CommonStrings::None))
1478 colorList.insert(ite->lineColor(), m_colorList[ite->lineColor()]);
1479 if ((!colorList.contains(ite->fillColor())) && (ite->fillColor() != CommonStrings::None))
1480 colorList.insert(ite->fillColor(), m_colorList[ite->fillColor()]);
1481 QString gCol1, gCol2, gCol3, gCol4;
1482 ite->get4ColorColors(gCol1, gCol2, gCol3, gCol4);
1483 if ((!colorList.contains(gCol1)) && (gCol1 != CommonStrings::None))
1484 colorList.insert(gCol1, m_colorList[gCol1]);
1485 if ((!colorList.contains(gCol2)) && (gCol2 != CommonStrings::None))
1486 colorList.insert(gCol2, m_colorList[gCol2]);
1487 if ((!colorList.contains(gCol3)) && (gCol3 != CommonStrings::None))
1488 colorList.insert(gCol3, m_colorList[gCol3]);
1489 if ((!colorList.contains(gCol4)) && (gCol4 != CommonStrings::None))
1490 colorList.insert(gCol4, m_colorList[gCol4]);
1491 for (int grow = 0; grow < ite->meshGradientArray.count(); grow++)
1492 {
1493 for (int gcol = 0; gcol < ite->meshGradientArray[grow].count(); gcol++)
1494 {
1495 MeshPoint mp = ite->meshGradientArray[grow][gcol];
1496 if ((!colorList.contains(mp.colorName)) && (mp.colorName != CommonStrings::None))
1497 colorList.insert(mp.colorName, m_colorList[mp.colorName]);
1498 }
1499 }
1500 QList<VColorStop*> cstops = ite->fill_gradient.colorStops();
1501 for (int cst = 0; cst < ite->fill_gradient.stops(); ++cst)
1502 {
1503 if ((!colorList.contains(cstops.at(cst)->name)) && (cstops.at(cst)->name != CommonStrings::None))
1504 colorList.insert(cstops.at(cst)->name, m_colorList[cstops.at(cst)->name]);
1505 }
1506 cstops = ite->stroke_gradient.colorStops();
1507 for (int cst = 0; cst < ite->stroke_gradient.stops(); ++cst)
1508 {
1509 if ((!colorList.contains(cstops.at(cst)->name)) && (cstops.at(cst)->name != CommonStrings::None))
1510 colorList.insert(cstops.at(cst)->name, m_colorList[cstops.at(cst)->name]);
1511 }
1512 cstops = ite->mask_gradient.colorStops();
1513 for (int cst = 0; cst < ite->mask_gradient.stops(); ++cst)
1514 {
1515 if ((!colorList.contains(cstops.at(cst)->name)) && (cstops.at(cst)->name != CommonStrings::None))
1516 colorList.insert(cstops.at(cst)->name, m_colorList[cstops.at(cst)->name]);
1517 }
1518 }
1519 }
1520 colorList.remove(CommonStrings::None);
1521 return colorList;
1522 }
1523
updateGradientColors(const QString & newName,const QString & oldName)1524 void ColorsAndFillsDialog::updateGradientColors(const QString& newName, const QString& oldName)
1525 {
1526 QHash<QString,VGradient>::Iterator itg;
1527 for (itg = dialogGradients.begin(); itg != dialogGradients.end(); ++itg)
1528 {
1529 QList<VColorStop*> cstops = itg.value().colorStops();
1530 for (int cst = 0; cst < itg.value().stops(); ++cst)
1531 {
1532 if (oldName == cstops.at(cst)->name)
1533 {
1534 cstops.at(cst)->name = newName;
1535 const ScColor& col = m_colorList[cstops.at(cst)->name];
1536 cstops.at(cst)->color = ScColorEngine::getShadeColorProof(col, m_doc, cstops.at(cst)->shade);
1537 }
1538 }
1539 }
1540 ColorList colorListBack = m_doc->PageColors;
1541 m_doc->PageColors = m_colorList;
1542 QStringList patterns = dialogPatterns.keys();
1543 for (int c = 0; c < dialogPatterns.count(); ++c)
1544 {
1545 ScPattern pa = dialogPatterns[patterns[c]];
1546 for (int o = 0; o < pa.items.count(); o++)
1547 {
1548 PageItem *ite = pa.items.at(o);
1549 if (oldName == ite->lineColor())
1550 ite->setLineColor(newName);
1551 if (oldName == ite->fillColor())
1552 ite->setFillColor(newName);
1553 QString gCol1, gCol2, gCol3, gCol4;
1554 ite->get4ColorColors(gCol1, gCol2, gCol3, gCol4);
1555 if (oldName == gCol1)
1556 gCol1 = newName;
1557 if (oldName == gCol2)
1558 gCol2 = newName;
1559 if (oldName == gCol3)
1560 gCol3 = newName;
1561 if (oldName == gCol4)
1562 gCol4 = newName;
1563 ite->set4ColorColors(gCol1, gCol2, gCol3, gCol4);
1564 for (int grow = 0; grow < ite->meshGradientArray.count(); grow++)
1565 {
1566 for (int gcol = 0; gcol < ite->meshGradientArray[grow].count(); gcol++)
1567 {
1568 MeshPoint mp = ite->meshGradientArray[grow][gcol];
1569 if (mp.colorName == oldName)
1570 {
1571 mp.colorName = newName;
1572 ite->setMeshPointColor(grow, gcol, mp.colorName, mp.shade, mp.transparency);
1573 }
1574 }
1575 }
1576 QList<VColorStop*> cstops = ite->fill_gradient.colorStops();
1577 for (int cst = 0; cst < ite->fill_gradient.stops(); ++cst)
1578 {
1579 if (oldName == cstops.at(cst)->name)
1580 {
1581 cstops.at(cst)->name = newName;
1582 ite->SetQColor(&cstops.at(cst)->color, cstops.at(cst)->name, cstops.at(cst)->shade);
1583 }
1584 }
1585 cstops = ite->stroke_gradient.colorStops();
1586 for (int cst = 0; cst < ite->stroke_gradient.stops(); ++cst)
1587 {
1588 if (oldName == cstops.at(cst)->name)
1589 {
1590 cstops.at(cst)->name = newName;
1591 ite->SetQColor(&cstops.at(cst)->color, cstops.at(cst)->name, cstops.at(cst)->shade);
1592 }
1593 }
1594 cstops = ite->mask_gradient.colorStops();
1595 for (int cst = 0; cst < ite->mask_gradient.stops(); ++cst)
1596 {
1597 if (oldName == cstops.at(cst)->name)
1598 {
1599 cstops.at(cst)->name = newName;
1600 ite->SetQColor(&cstops.at(cst)->color, cstops.at(cst)->name, cstops.at(cst)->shade);
1601 }
1602 }
1603 }
1604 PageItem *ite = pa.items.at(0);
1605 dialogPatterns[patterns[c]].pattern = ite->DrawObj_toImage(pa.items, 1.0);
1606 }
1607 m_doc->PageColors = colorListBack;
1608 }
1609
loadGimpFormat(const QString & fileName)1610 void ColorsAndFillsDialog::loadGimpFormat(const QString& fileName)
1611 {
1612 QFile f(fileName);
1613 if (f.open(QIODevice::ReadOnly))
1614 {
1615 ScTextStream ts(&f);
1616 QString tmp, dummy;
1617 QString gradientName = "";
1618 int numEntrys = 0;
1619 int entryCount = 0;
1620 int stopCount = 0;
1621 double left, middle, right, r0, g0, b0, a0, r1, g1, b1, a1;
1622 double oldr1 = 0.0;
1623 double oldg1 = 0.0;
1624 double oldb1 = 0.0;
1625 double olda1 = 0.0;
1626 tmp = ts.readLine();
1627 if (tmp.startsWith("GIMP Gradient"))
1628 {
1629 tmp = ts.readLine();
1630 ScTextStream CoE(&tmp, QIODevice::ReadOnly);
1631 CoE >> dummy;
1632 gradientName = CoE.readAll().trimmed();
1633 }
1634 if (!gradientName.isEmpty())
1635 {
1636 QString stopName = gradientName+QString("_Stop%1");
1637 QString stopNameInUse;
1638 VGradient gra = VGradient(VGradient::linear);
1639 gra.clearStops();
1640 QColor color;
1641 tmp = ts.readLine();
1642 ScTextStream CoE(&tmp, QIODevice::ReadOnly);
1643 CoE >> numEntrys;
1644 while (!ts.atEnd())
1645 {
1646 entryCount++;
1647 tmp = ts.readLine();
1648 ScTextStream Cval(&tmp, QIODevice::ReadOnly);
1649 Cval >> left >> middle >> right >> r0 >> g0 >> b0 >> a0 >> r1 >> g1 >> b1 >> a1;
1650 if ((entryCount == 1) && (entryCount < numEntrys))
1651 {
1652 stopNameInUse = stopName.arg(stopCount);
1653 addGimpColor(stopNameInUse, r0, g0, b0);
1654 color = QColor(qRound(r0 * 255), qRound(g0 * 255), qRound(b0 * 255));
1655 gra.addStop(color, left, 0.5, a0, stopNameInUse, 100);
1656 stopCount++;
1657 }
1658 else if (entryCount == numEntrys)
1659 {
1660 if ((entryCount != 1) && ((r0 != oldr1) || (g0 != oldg1) || (b0 != oldb1) || (a0 != olda1)))
1661 {
1662 stopNameInUse = stopName.arg(stopCount);
1663 addGimpColor(stopNameInUse, oldr1, oldg1, oldb1);
1664 color = QColor(qRound(oldr1 * 255), qRound(oldg1 * 255), qRound(oldb1 * 255));
1665 gra.addStop(color, left, 0.5, olda1, stopNameInUse, 100);
1666 stopCount++;
1667 }
1668 stopNameInUse = stopName.arg(stopCount);
1669 addGimpColor(stopNameInUse, r0, g0, b0);
1670 color = QColor(qRound(r0 * 255), qRound(g0 * 255), qRound(b0 * 255));
1671 gra.addStop(color, left, 0.5, a0, stopNameInUse, 100);
1672 stopCount++;
1673 stopNameInUse = stopName.arg(stopCount);
1674 addGimpColor(stopNameInUse, r1, g1, b1);
1675 color = QColor(qRound(r1 * 255), qRound(g1 * 255), qRound(b1 * 255));
1676 gra.addStop(color, right, 0.5, a1, stopNameInUse, 100);
1677 stopCount++;
1678 }
1679 else
1680 {
1681 if ((r0 == oldr1) && (g0 == oldg1) && (b0 == oldb1) && (a0 == olda1))
1682 {
1683 stopNameInUse = stopName.arg(stopCount);
1684 addGimpColor(stopNameInUse, r0, g0, b0);
1685 color = QColor(qRound(r0 * 255), qRound(g0 * 255), qRound(b0 * 255));
1686 gra.addStop(color, left, 0.5, a0, stopNameInUse, 100);
1687 stopCount++;
1688 }
1689 else
1690 {
1691 stopNameInUse = stopName.arg(stopCount);
1692 addGimpColor(stopNameInUse, oldr1, oldg1, oldb1);
1693 color = QColor(qRound(oldr1 * 255), qRound(oldg1 * 255), qRound(oldb1 * 255));
1694 gra.addStop(color, left, 0.5, olda1, stopNameInUse, 100);
1695 stopCount++;
1696 stopNameInUse = stopName.arg(stopCount);
1697 addGimpColor(stopNameInUse, r0, g0, b0);
1698 color = QColor(qRound(r0 * 255), qRound(g0 * 255), qRound(b0 * 255));
1699 gra.addStop(color, left, 0.5, a0, stopNameInUse, 100);
1700 stopCount++;
1701 }
1702 }
1703 oldr1 = r1;
1704 oldg1 = g1;
1705 oldb1 = b1;
1706 olda1 = a1;
1707 }
1708 if (!dialogGradients.contains(gradientName))
1709 dialogGradients.insert(gradientName, gra);
1710 else
1711 {
1712 QString tmp;
1713 gradientName += "("+tmp.setNum(dialogGradients.count())+")";
1714 dialogGradients.insert(gradientName, gra);
1715 }
1716 }
1717 f.close();
1718 }
1719 /* File format is:
1720 *
1721 * GIMP Gradient
1722 * Name: name
1723 * number_of_segments
1724 * left middle right r0 g0 b0 a0 r1 g1 b1 a1 type coloring left_color_type
1725 * left middle right r0 g0 b0 a0 r1 g1 b1 a1 type coloring right_color_type
1726 * ...
1727 */
1728 }
1729
addGimpColor(QString & colorName,double r,double g,double b)1730 void ColorsAndFillsDialog::addGimpColor(QString &colorName, double r, double g, double b)
1731 {
1732 ScColor lf = ScColor();
1733 bool found = false;
1734 int Rc, Gc, Bc, hR, hG, hB;
1735 Rc = qRound(r * 255);
1736 Gc = qRound(g * 255);
1737 Bc = qRound(b * 255);
1738 lf.setRgbColor(Rc, Gc, Bc);
1739 for (ColorList::Iterator it = m_colorList.begin(); it != m_colorList.end(); ++it)
1740 {
1741 if (it.value().getColorModel() == colorModelRGB)
1742 {
1743 it.value().getRGB(&hR, &hG, &hB);
1744 if ((Rc == hR) && (Gc == hG) && (Bc == hB))
1745 {
1746 colorName = it.key();
1747 found = true;
1748 return;
1749 }
1750 }
1751 }
1752 if (!found)
1753 {
1754 m_colorList.insert(colorName, lf);
1755 hasImportedColors = true;
1756 }
1757 }
1758
loadScribusFormat(const QString & fileName)1759 void ColorsAndFillsDialog::loadScribusFormat(const QString& fileName)
1760 {
1761 QFile f(fileName);
1762 if (!f.open(QIODevice::ReadOnly))
1763 return;
1764 QDomDocument docu("scridoc");
1765 QTextStream ts(&f);
1766 ts.setCodec("UTF-8");
1767 QString errorMsg;
1768 int errorLine = 0, errorColumn = 0;
1769 if (!docu.setContent(ts.readAll(), &errorMsg, &errorLine, &errorColumn) )
1770 {
1771 f.close();
1772 return;
1773 }
1774 f.close();
1775 QDomElement elem = docu.documentElement();
1776 if (elem.tagName() != "SCRIBUSGRADIENT")
1777 return;
1778 QDomNode DOC = elem.firstChild();
1779 while (!DOC.isNull())
1780 {
1781 QDomElement dc = DOC.toElement();
1782 if (dc.tagName()=="COLOR")
1783 {
1784 ScColor lf = ScColor();
1785 if (dc.hasAttribute("SPACE"))
1786 {
1787 QString space = dc.attribute("SPACE");
1788 if (space == "CMYK")
1789 {
1790 double c = dc.attribute("C", "0").toDouble() / 100.0;
1791 double m = dc.attribute("M", "0").toDouble() / 100.0;
1792 double y = dc.attribute("Y", "0").toDouble() / 100.0;
1793 double k = dc.attribute("K", "0").toDouble() / 100.0;
1794 lf.setCmykColorF(c, m, y, k);
1795 }
1796 else if (space == "RGB")
1797 {
1798 double r = dc.attribute("R", "0").toDouble() / 255.0;
1799 double g = dc.attribute("G", "0").toDouble() / 255.0;
1800 double b = dc.attribute("B", "0").toDouble() / 255.0;
1801 lf.setRgbColorF(r, g, b);
1802 }
1803 else if (space == "Lab")
1804 {
1805 double L = dc.attribute("L", "0").toDouble();
1806 double a = dc.attribute("A", "0").toDouble();
1807 double b = dc.attribute("B", "0").toDouble();
1808 lf.setLabColor(L, a, b);
1809 }
1810 }
1811 else if (dc.hasAttribute("CMYK"))
1812 lf.setNamedColor(dc.attribute("CMYK"));
1813 else if (dc.hasAttribute("RGB"))
1814 lf.fromQColor(QColor(dc.attribute("RGB")));
1815 else
1816 {
1817 double L = dc.attribute("L", "0").toDouble();
1818 double a = dc.attribute("A", "0").toDouble();
1819 double b = dc.attribute("B", "0").toDouble();
1820 lf.setLabColor(L, a, b);
1821 }
1822 if (dc.hasAttribute("Spot"))
1823 lf.setSpotColor(static_cast<bool>(dc.attribute("Spot").toInt()));
1824 else
1825 lf.setSpotColor(false);
1826 if (dc.hasAttribute("Register"))
1827 lf.setRegistrationColor(static_cast<bool>(dc.attribute("Register").toInt()));
1828 else
1829 lf.setRegistrationColor(false);
1830 if (!m_colorList.contains(dc.attribute("NAME")))
1831 {
1832 m_colorList.insert(dc.attribute("NAME"), lf);
1833 hasImportedColors = true;
1834 }
1835 }
1836 if (dc.tagName() == "Gradient")
1837 {
1838 VGradient gra = VGradient(VGradient::linear);
1839 gra.clearStops();
1840 QDomNode grad = dc.firstChild();
1841 while (!grad.isNull())
1842 {
1843 QDomElement stop = grad.toElement();
1844 QString name = stop.attribute("NAME");
1845 double ramp = ScCLocale::toDoubleC(stop.attribute("RAMP"), 0.0);
1846 int shade = stop.attribute("SHADE", "100").toInt();
1847 double opa = ScCLocale::toDoubleC(stop.attribute("TRANS"), 1.0);
1848 QColor color;
1849 if (name == CommonStrings::None)
1850 color = QColor(255, 255, 255, 0);
1851 else
1852 {
1853 const ScColor& col = m_colorList[name];
1854 color = ScColorEngine::getShadeColorProof(col, nullptr, shade);
1855 }
1856 gra.addStop(color, ramp, 0.5, opa, name, shade);
1857 grad = grad.nextSibling();
1858 }
1859 if (!dialogGradients.contains(dc.attribute("Name")))
1860 dialogGradients.insert(dc.attribute("Name"), gra);
1861 else
1862 {
1863 QString tmp;
1864 QString name = dc.attribute("Name");
1865 name += "("+tmp.setNum(dialogGradients.count())+")";
1866 dialogGradients.insert(name, gra);
1867 }
1868 }
1869 DOC=DOC.nextSibling();
1870 }
1871 }
1872
loadDefaults(QTreeWidgetItem * item)1873 void ColorsAndFillsDialog::loadDefaults(QTreeWidgetItem* item)
1874 {
1875 QString txt = item->data(0, Qt::UserRole).toString() + "/" + item->text(0);
1876 if (!mainWin->HaveDoc)
1877 {
1878 m_colorList.clear();
1879 dialogGradients.clear();
1880 dialogPatterns.clear();
1881 }
1882 QString pfadC2 = "";
1883 if (item->text(0) == "Scribus Small")
1884 {
1885 m_colorList.insert("White", ScColor(0, 0, 0, 0));
1886 m_colorList.insert("Black", ScColor(0, 0, 0, 255));
1887 ScColor cc = ScColor(255, 255, 255, 255);
1888 cc.setRegistrationColor(true);
1889 m_colorList.insert("Registration", cc);
1890 m_colorList.insert("Blue", ScColor(255, 255, 0, 0));
1891 m_colorList.insert("Cyan", ScColor(255, 0, 0, 0));
1892 m_colorList.insert("Green", ScColor(255, 0, 255, 0));
1893 m_colorList.insert("Red", ScColor(0, 255, 255, 0));
1894 m_colorList.insert("Yellow", ScColor(0, 0, 255, 0));
1895 m_colorList.insert("Magenta", ScColor(0, 255, 0, 0));
1896 paletteLocked = false;
1897 }
1898 else
1899 {
1900 if (!customColSet.contains(txt))
1901 pfadC2 = csm.paletteFileFromName(txt);
1902 else
1903 pfadC2 = csm.userPaletteFileFromName(txt);
1904 if (!mainWin->HaveDoc)
1905 {
1906 QFileInfo fi(pfadC2);
1907 if (fi.absolutePath().contains(ScPaths::applicationDataDir()+"swatches/locked"))
1908 paletteLocked = true;
1909 else
1910 paletteLocked = !fi.isWritable();
1911 }
1912 else
1913 paletteLocked = false;
1914 if (!csm.loadPalette(pfadC2, m_doc, m_colorList, dialogGradients, dialogPatterns, mainWin->HaveDoc))
1915 {
1916 m_colorList.insert("White", ScColor(0, 0, 0, 0));
1917 m_colorList.insert("Black", ScColor(0, 0, 0, 255));
1918 ScColor cc = ScColor(255, 255, 255, 255);
1919 cc.setRegistrationColor(true);
1920 m_colorList.insert("Registration", cc);
1921 m_colorList.insert("Blue", ScColor(255, 255, 0, 0));
1922 m_colorList.insert("Cyan", ScColor(255, 0, 0, 0));
1923 m_colorList.insert("Green", ScColor(255, 0, 255, 0));
1924 m_colorList.insert("Red", ScColor(0, 255, 255, 0));
1925 m_colorList.insert("Yellow", ScColor(0, 0, 255, 0));
1926 m_colorList.insert("Magenta", ScColor(0, 255, 0, 0));
1927 }
1928 }
1929 updateColorList();
1930 updateGradientList();
1931 updatePatternList();
1932 itemSelected(nullptr);
1933 }
1934
saveDefaults()1935 void ColorsAndFillsDialog::saveDefaults()
1936 {
1937 QTreeWidgetItem* item = LoadColSet->currentItem();
1938 QString NameK = item->data(0, Qt::UserRole).toString() + "/" + item->text(0);
1939 QString Name = LoadColSet->text();
1940 Query* dia = new Query(this, "Name", 1, tr("&Name:"), tr("Choose a Name"));
1941 if ((customColSet.contains(NameK)) && (!paletteLocked))
1942 dia->setEditText(Name, false);
1943 else
1944 dia->setEditText("", false);
1945 if (dia->exec())
1946 doSaveDefaults(dia->getEditText(), (dia->getEditText() != Name));
1947 delete dia;
1948 }
1949
doSaveDefaults(const QString & name,bool changed)1950 void ColorsAndFillsDialog::doSaveDefaults(const QString& name, bool changed)
1951 {
1952 QString filename = name;
1953 filename.replace(" ", "_");
1954 filename = QDir::toNativeSeparators(ScPaths::userPaletteFilesDir(true)) + filename;
1955 filename += ".xml";
1956 const FileFormat *fmt = LoadSavePlugin::getFormatById(FORMATID_SLA150EXPORT);
1957 if (fmt)
1958 {
1959 ScribusDoc *s_doc = new ScribusDoc();
1960 s_doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
1961 s_doc->setPage(100, 100, 0, 0, 0, 0, 0, 0, false, false);
1962 s_doc->addPage(0);
1963 s_doc->setGUI(false, mainWin, nullptr);
1964 s_doc->PageColors = m_colorList;
1965 s_doc->setGradients(dialogGradients);
1966 s_doc->setPatterns(dialogPatterns);
1967 fmt->setupTargets(s_doc, nullptr, mainWin, nullptr, &(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts));
1968 fmt->savePalette(filename);
1969 delete s_doc;
1970 }
1971 if (changed)
1972 {
1973 QString nameC = name;
1974 nameC.replace(" ", "_");
1975 nameC += ".xml";
1976 QFileInfo fi(filename);
1977 customColSet.append(fi.absolutePath() + "/" + nameC);
1978 QTreeWidgetItem *item = LoadColSet->addSubItem(name, userSwatches);
1979 item->setData(0, Qt::UserRole, fi.absolutePath());
1980 disconnect(LoadColSet, SIGNAL(activated(QTreeWidgetItem*)), this, SLOT(loadDefaults(QTreeWidgetItem*)));
1981 LoadColSet->setCurrentComboItem(fi.absolutePath() + "/" + name);
1982 connect(LoadColSet, SIGNAL(activated(QTreeWidgetItem*)), this, SLOT(loadDefaults(QTreeWidgetItem*)));
1983 }
1984 }
1985
getColorSetName()1986 QString ColorsAndFillsDialog::getColorSetName()
1987 {
1988 QString NameK;
1989 QTreeWidgetItem* item = LoadColSet->currentItem();
1990 if (item->text(0) == "Scribus Small")
1991 NameK = "Scribus Small";
1992 else
1993 NameK = item->data(0, Qt::UserRole).toString() + "/" + item->text(0);
1994 return NameK;
1995 }
1996
selectedColor()1997 ScColor ColorsAndFillsDialog::selectedColor()
1998 {
1999 QTreeWidgetItem* it = dataTree->currentItem();
2000 if (it)
2001 {
2002 if (it->parent() == colorItems)
2003 return m_colorList[it->text(0)];
2004 }
2005 return ScColor();
2006 }
2007
selectedColorName()2008 QString ColorsAndFillsDialog::selectedColorName()
2009 {
2010 QTreeWidgetItem* it = dataTree->currentItem();
2011 if (it)
2012 {
2013 if (it->parent() == colorItems)
2014 return it->text(0);
2015 }
2016 return CommonStrings::None;
2017 }
2018
keyPressEvent(QKeyEvent * k)2019 void ColorsAndFillsDialog::keyPressEvent(QKeyEvent* k)
2020 {
2021 if (k->modifiers()!=Qt::NoModifier || (k->key()!=Qt::Key_Delete && k->key()!=Qt::Key_Backspace))
2022 return;
2023
2024 QString belowText;
2025 QList<QTreeWidgetItem *> selItems = dataTree->selectedItems();
2026 if (selItems.count() > 0)
2027 {
2028 QTreeWidgetItem* belowItem = dataTree->itemBelow(selItems.last());
2029 if (belowItem)
2030 belowText = belowItem->text(0);
2031 }
2032
2033 removeColorItem();
2034
2035 QList<QTreeWidgetItem *> belowItems = dataTree->findItems(belowText, Qt::MatchFixedString|Qt::MatchCaseSensitive|Qt::MatchRecursive);
2036 if (belowItems.count() > 0)
2037 {
2038 // In case non deletable colors have been selected, some items
2039 //may still be selected, so clear selection first
2040 dataTree->selectionModel()->clearSelection();
2041 dataTree->setCurrentItem(belowItems[0]);
2042 }
2043 }
2044