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 #include "checkDocument.h"
8
9 #include <QComboBox>
10 #include <QEvent>
11 #include <QHBoxLayout>
12 #include <QHeaderView>
13 #include <QImage>
14 #include <QLabel>
15 #include <QPixmap>
16 #include <QPushButton>
17 #include <QSpacerItem>
18 #include <QToolTip>
19 #include <QTreeWidget>
20 #include <QTreeWidgetItem>
21 #include <QVBoxLayout>
22
23 #include "commonstrings.h"
24 #include "documentchecker.h"
25 #include "pdfoptions.h"
26 #include "prefsmanager.h"
27 #include "scpage.h"
28 #include "scribusapp.h"
29 #include "scribuscore.h"
30 #include "scribusdoc.h"
31 #include "iconmanager.h"
32 #include "util.h"
33
34 // readable constants for QTreeWidgetItem column ids
35 #define COLUMN_ITEM 0
36 #define COLUMN_PROBLEM 1
37 #define COLUMN_LAYER 2
38 // #define COLUMN_INFO 3
39
CheckDocument(QWidget * parent,bool modal)40 CheckDocument::CheckDocument( QWidget* parent, bool modal )
41 : ScrPaletteBase( parent, "checkDocument", modal )
42 {
43 showPagesWithoutErrors = PrefsManager::instance().appPrefs.verifierPrefs.showPagesWithoutErrors;
44 showNonPrintingLayerErrors = PrefsManager::instance().appPrefs.verifierPrefs.showNonPrintingLayerErrors;
45
46 iconSetChange();
47
48 checkDocumentLayout = new QVBoxLayout( this );
49 checkDocumentLayout->setContentsMargins(9, 9, 9, 9);
50 checkDocumentLayout->setSpacing(6);
51
52 layout1 = new QHBoxLayout;
53 layout1->setContentsMargins(0, 0, 0, 0);
54 layout1->setSpacing(6);
55 textLabel1 = new QLabel( this );
56 layout1->addWidget( textLabel1 );
57 curCheckProfile = new QComboBox( this );
58 layout1->addWidget( curCheckProfile );
59 checkDocumentLayout->addLayout( layout1 );
60
61 reportDisplay = new QTreeWidget( this );
62 reportDisplay->header()->setSectionsClickable(false );
63 reportDisplay->header()->setSectionsMovable( false );
64 reportDisplay->setSortingEnabled(false);
65 reportDisplay->setAlternatingRowColors(true);
66 checkDocumentLayout->addWidget( reportDisplay );
67
68 layout2 = new QHBoxLayout;
69 layout2->setContentsMargins(0, 0, 0, 0);
70 layout2->setSpacing(6);
71 reScan = new QPushButton(this );
72 layout2->addWidget( reScan );
73 QSpacerItem* spacer = new QSpacerItem( 2, 2, QSizePolicy::Expanding, QSizePolicy::Minimum );
74 layout2->addItem( spacer );
75 ignoreErrors = new QPushButton(this );
76 layout2->addWidget( ignoreErrors );
77 checkDocumentLayout->addLayout( layout2 );
78 setIgnoreEnabled(false);
79 checkMode = checkNULL;
80 languageChange();
81 itemMap.clear();
82 posMap.clear();
83 pageMap.clear();
84 masterPageMap.clear();
85 masterPageItemMap.clear();
86 resize( QSize(320, 260).expandedTo(minimumSizeHint()) );
87
88 connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
89
90 connect(ignoreErrors, SIGNAL(clicked()), this, SIGNAL(ignoreAllErrors()));
91 connect(curCheckProfile, SIGNAL(activated(const QString&)), this, SLOT(newScan(const QString&)));
92 connect(reScan, SIGNAL(clicked()), this, SLOT(doReScan()));
93 }
94
changeEvent(QEvent * e)95 void CheckDocument::changeEvent(QEvent *e)
96 {
97 if (e->type() == QEvent::LanguageChange)
98 {
99 languageChange();
100 }
101 else
102 QWidget::changeEvent(e);
103 }
104
iconSetChange()105 void CheckDocument::iconSetChange()
106 {
107 graveError = IconManager::instance().loadPixmap("22/dialog-error.png");
108 onlyWarning = IconManager::instance().loadPixmap("22/dialog-warning.png");
109 noErrors = IconManager::instance().loadPixmap("ok.png");
110 }
111
languageChange()112 void CheckDocument::languageChange()
113 {
114 setWindowTitle( tr( "Preflight Verifier" ) );
115 QStringList headerLabels;
116 headerLabels << tr("Items") << tr("Problems")
117 << tr("Layer");// << tr("Information");
118 reportDisplay->setHeaderLabels(headerLabels);
119 reportDisplay->setColumnCount(headerLabels.count());
120
121 textLabel1->setText( tr("Current Profile:"));
122 ignoreErrors->setText( tr("&Ignore Errors"));
123 reScan->setText( tr("Check again"));
124
125 textLabel1->setToolTip( "<qt>"+ tr( "Preflight profile to base the report generation on. Options can be set in Document Setup or Preferences.") + "</qt>");
126 ignoreErrors->setToolTip( "<qt>"+ tr( "Ignore found errors and continue to export or print. Be sure to understand the errors you are ignoring before continuing.") + "</qt>");
127 reScan->setToolTip( "<qt>"+ tr( "Rerun the document scan to check corrections you may have made" ) + "</qt>");
128
129 warnMap.clear();
130 warnMap.insert(PV_ANNOTATION, qMakePair(tr("Object is a PDF Annotation or Field"), tr("Indicates that editorial changes have been made to a PDF are still present or your PDF contains unprintable annotation items. They may cause issues in professional printing. Also helpful reminder if you are wanting to publish a final draft without editorial relics.")));
131 warnMap.insert(PV_APPLIED_MASTER_DIFF_SIDE, qMakePair(tr("Applied master page has different page destination (left, middle, right side)"),
132 tr("Have you applied the correct Master Page?")));
133 warnMap.insert(PV_EMPTY_IMAGE_FRAME, qMakePair(tr("Empty Image Frame"), tr("If you have created an image frame, there is the presumption that you planned to put an image in it")));
134 warnMap.insert(PV_EMPTY_TEXT_FRAME, qMakePair(tr("Empty Text Frame"), tr("If you have created a text frame, there is the presumption that you planned to put text in it")));
135 warnMap.insert(PV_FONT_NOT_EMBEDDED, qMakePair(tr("Imported document contains non-embedded fonts"), tr("When some imported document uses non-embedded fonts, then their rendering will be wrong, unless by chance you have them installed on their system, but that cannot be guaranteed in case you want to share the resulting document")));
136 warnMap.insert(PV_HIGH_DPI, qMakePair(tr("Image resolution above %1 DPI,\ncurrently %2 x %3 DPI"), tr("This is a user definable setting serving as a caution for high resolution images, which may lead to unnecessarily large files")));
137 warnMap.insert(PV_IMAGE_FRAME_PART_FILLED, qMakePair(tr("Image dimension is smaller than its frame"), tr("The image does not fit the whole space you reserved for it. Maybe this is intended, or maybe this is caused by bad inner placement or scale. The result will either be a cropped image or white space around the image.")));
138 warnMap.insert(PV_IS_GIF, qMakePair(tr("Image is GIF"), tr("This warning alerts you that you are using a bitmap based graphic format that is typically not used for high resolution images (.gif is one of those). This may result in poor viewing quality (for example: when commercially printed, viewed on a high-resolution screens, etc...). If your PDF will be printed commercially, there are some printing systems that will have difficulty printing these types of images.")));
139 warnMap.insert(PV_LOW_DPI, qMakePair(tr("Image resolution below %1 DPI,\ncurrently %2 x %3 DPI"), tr("This is a user definable setting serving as a caution for low resolution images, which may lead to poor quality output")));
140 warnMap.insert(PV_MISSING_GLYPH, qMakePair(tr("Glyphs missing"), tr("You have one or more characters which do not have a corresponding glyph in your chosen font")));
141 warnMap.insert(PV_MISSING_IMAGE, qMakePair(tr("Missing Image"), tr("The assigned image file cannot be found")));
142 warnMap.insert(PV_NON_ON_PAGE, qMakePair(tr("Object is not on a Page"), tr("An object is placed somewhere outside of the page borders, it will not be printed and might be missing somewhere")));
143 warnMap.insert(PV_NOT_CMYK_SPOT, qMakePair(tr("Object colorspace is not CMYK or spot"), tr("PDF supports many different ways to represent the color of any object including RGB, CMYK and Spot (aka Separation) colors. Some of the PDF standards, such as PDF/X-1a, require the only CMYK and Spot colors be used.")));
144 warnMap.insert(PV_RASTER_PDF, qMakePair(tr("Object is a placed PDF"), tr("The warning is verifying for you that there is a PDF loaded into an Image Frame, where it will be rasterized or converted to a bitmap. Its resolution may be less than ideal. See PDF Export to learn how to minimize this problem.")));
145 warnMap.insert(PV_TEXT_OVERFLOW, qMakePair(tr("Text overflow"), tr("There is more text than can show in the frame as sized. Nonvisible excess characters like spaces and carriage returns may trigger this if nothing appears to be missing.")));
146 warnMap.insert(PV_TRANSPARENCY, qMakePair(tr("Object has transparency"), tr("This warning indicates that your document contains images that have a transparent layer. This is really only an issue if using older printing profiles or PostScript. It is safe to ignore this when exporting to PDF version greater than 1.4.")));
147 warnMap.insert(PV_WRONG_FONT, qMakePair(tr("Annotation uses a non-TrueType font"), tr("Annotations support only a standard set of fonts. Choose another one.")));
148 warnMap.insert(PV_LAYER_TRANSPARENCY, qMakePair(tr("Transparency used"), tr("This layer uses transparency, only an issue if using older printing profiles. You may safely ignore this when using modern printing methods, or exporting to PDF version greater than 1.4.")));
149 warnMap.insert(PV_LAYER_BLENDMODE, qMakePair(tr("Blendmode used"), tr("This layer uses blendmodes which relies on transparency, only an issue if using older printing profiles. You may safely ignore this when using modern printing methods, or exporting to PDF version greater than 1.4.")));
150 warnMap.insert(PV_LAYER_PRINTVIS_MISMATCH, qMakePair(tr("Print/Visible mismatch"), tr("This layer uses transparency, only an issue if using older printing profiles. You may safely ignore this when using modern printing methods, or exporting to PDF version greater than 1.4.")));
151 }
152
bestCheckerProfileForCheckMode(const QString & defaultProfile)153 QString CheckDocument::bestCheckerProfileForCheckMode(const QString& defaultProfile)
154 {
155 QString bestProfile = bestCheckerProfileForCheckMode(this->checkMode, defaultProfile);
156 return bestProfile;
157 }
158
bestCheckerProfileForCheckMode(CheckMode mode,const QString & defaultProfile)159 QString CheckDocument::bestCheckerProfileForCheckMode(CheckMode mode, const QString& defaultProfile)
160 {
161 QString bestProfile = defaultProfile;
162
163 if (mode == CheckDocument::checkPDF || mode == CheckDocument::checkOutputPreviewPDF)
164 {
165 PDFVersion pdfVersion = m_Doc->pdfOptions().Version;
166 if (pdfVersion == PDFVersion::PDF_13)
167 bestProfile = CommonStrings::PDF_1_3;
168 else if (pdfVersion == PDFVersion::PDF_14)
169 bestProfile = CommonStrings::PDF_1_4;
170 else if (pdfVersion == PDFVersion::PDF_15)
171 bestProfile = CommonStrings::PDF_1_5;
172 else if (pdfVersion == PDFVersion::PDF_16)
173 bestProfile = CommonStrings::PDF_1_6;
174 else if (pdfVersion == PDFVersion::PDF_X1a)
175 bestProfile = CommonStrings::PDF_X1a;
176 else if (pdfVersion == PDFVersion::PDF_X3)
177 bestProfile = CommonStrings::PDF_X3;
178 else if (pdfVersion == PDFVersion::PDF_X4)
179 bestProfile = CommonStrings::PDF_X4;
180 }
181 else if (mode == CheckDocument::checkEPS || mode == CheckDocument::checkOutputPreviewPS)
182 bestProfile = CommonStrings::PostScript;
183
184 const auto& checkerProfiles = m_Doc->checkerProfiles();
185 if (checkerProfiles.contains(bestProfile))
186 return bestProfile;
187 return defaultProfile;
188 }
189
setDoc(ScribusDoc * doc)190 void CheckDocument::setDoc(ScribusDoc *doc)
191 {
192 m_Doc = doc;
193 clearErrorList();
194 CheckerPrefsList::Iterator it;
195 CheckerPrefsList::Iterator itend=doc->checkerProfiles().end();
196 for (it = doc->checkerProfiles().begin(); it != itend ; ++it)
197 curCheckProfile->addItem(it.key());
198 setCurrentComboItem(curCheckProfile, doc->curCheckProfile());
199 }
200
slotSelect(QTreeWidgetItem * ite)201 void CheckDocument::slotSelect(QTreeWidgetItem* ite)
202 {
203 if (itemMap.contains(ite))
204 {
205 // #10537 Check item has not been destroyed before requesting its selection
206 if (itemMap[ite].isNull())
207 return;
208 ScCore->primaryMainWindow()->closeActiveWindowMasterPageEditor();
209 m_Doc->setActiveLayer(itemMap[ite]->m_layerID);
210 ScCore->primaryMainWindow()->changeLayer(m_Doc->activeLayer());
211 if (itemMap[ite]->isTextFrame())
212 emit selectElement(itemMap[ite], true, posMap[ite]);
213 else
214 emit selectElementByItem(itemMap[ite], true);
215 return;
216 }
217 if (pageMap.contains(ite))
218 {
219 // #10537 Get page index from pointer in case user has deleted a page
220 // after preflight has been run
221 int pageIndex = m_Doc->DocPages.indexOf(pageMap[ite]);
222 if (pageIndex < 0)
223 return;
224 ScCore->primaryMainWindow()->closeActiveWindowMasterPageEditor();
225 emit selectPage(pageIndex);
226 return;
227 }
228 if (masterPageMap.contains(ite))
229 {
230 // #10537 Get page index from pointer in case user has deleted a page
231 // after preflight has been run
232 int pageIndex = m_Doc->MasterPages.indexOf(masterPageMap[ite]);
233 if (pageIndex < 0)
234 return;
235 emit selectMasterPage(masterPageMap[ite]->pageName());
236 return;
237 }
238 if (masterPageItemMap.contains(ite))
239 {
240 // #10537 Check item has not been destroyed before requesting its selection
241 if (masterPageItemMap[ite].isNull())
242 return;
243 if (!m_Doc->masterPageMode())
244 emit selectMasterPage(masterPageItemMap[ite]->OnMasterPage);
245 m_Doc->setActiveLayer(masterPageItemMap[ite]->m_layerID);
246 ScCore->primaryMainWindow()->changeLayer(m_Doc->activeLayer());
247 if (masterPageItemMap[ite]->isTextFrame())
248 emit selectElement(masterPageItemMap[ite], true, posMap[ite]);
249 else
250 emit selectElementByItem(masterPageItemMap[ite], true);
251 return;
252 }
253 }
254
doReScan()255 void CheckDocument::doReScan()
256 {
257 showPagesWithoutErrors=PrefsManager::instance().appPrefs.verifierPrefs.showPagesWithoutErrors;
258 showNonPrintingLayerErrors=PrefsManager::instance().appPrefs.verifierPrefs.showNonPrintingLayerErrors;
259 newScan(curCheckProfile->currentText());
260 }
261
newScan(const QString & name)262 void CheckDocument::newScan(const QString& name)
263 {
264 clearErrorList();
265 if (m_Doc==nullptr)
266 return;
267 m_Doc->setCurCheckProfile(name);
268 DocumentChecker::checkDocument(m_Doc);
269 buildErrorList(m_Doc);
270 }
271
clearErrorList()272 void CheckDocument::clearErrorList()
273 {
274 disconnect(reportDisplay, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(slotSelect(QTreeWidgetItem*)));
275 reportDisplay->clear();
276 reportDisplay->setSortingEnabled(false);
277 itemMap.clear();
278 posMap.clear();
279 pageMap.clear();
280 masterPageMap.clear();
281 masterPageItemMap.clear();
282 }
283
buildItem(QTreeWidgetItem * item,PreflightError errorType,PageItem * pageItem)284 void CheckDocument::buildItem(QTreeWidgetItem * item,
285 PreflightError errorType,
286 PageItem * pageItem)
287 {
288 Q_ASSERT_X(item != nullptr, "CheckDocument::buildItem",
289 "No reference to QTreeWidgetItem item");
290 Q_ASSERT_X(pageItem != nullptr, "CheckDocument::buildItem",
291 "No reference to PageItem pageItem");
292
293 switch (errorType)
294 {
295 case MissingGlyph:
296 item->setText(COLUMN_PROBLEM, warnMap[PV_MISSING_GLYPH].first);
297 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_MISSING_GLYPH].second);
298 item->setIcon(COLUMN_ITEM, graveError);
299 pageGraveError = true;
300 itemError = true;
301 break;
302 case TextOverflow:
303 item->setText(COLUMN_PROBLEM, warnMap[PV_TEXT_OVERFLOW].first);
304 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_TEXT_OVERFLOW].second);
305 item->setIcon(COLUMN_ITEM, onlyWarning);
306 break;
307 case ObjectNotOnPage:
308 item->setText(COLUMN_PROBLEM, warnMap[PV_NON_ON_PAGE].first);
309 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_NON_ON_PAGE].second);
310 item->setIcon(COLUMN_ITEM, onlyWarning);
311 break;
312 case MissingImage:
313 if (pageItem->externalFile().isEmpty())
314 {
315 item->setText(COLUMN_PROBLEM, warnMap[PV_EMPTY_IMAGE_FRAME].first);
316 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_EMPTY_IMAGE_FRAME].second);
317 item->setIcon(COLUMN_ITEM, onlyWarning );
318 }
319 else
320 {
321 item->setText(COLUMN_PROBLEM, warnMap[PV_MISSING_IMAGE].first);
322 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_MISSING_IMAGE].second);
323 item->setIcon(COLUMN_ITEM, graveError );
324 pageGraveError = true;
325 }
326 break;
327 case ImageDPITooLow:
328 {
329 int xres = qRound(72.0 / pageItem->imageXScale());
330 int yres = qRound(72.0 / pageItem->imageYScale());
331 item->setText(COLUMN_PROBLEM, warnMap[PV_LOW_DPI].first.arg(minResDPI).arg(xres).arg(yres));
332 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_LOW_DPI].second);
333 item->setIcon(COLUMN_ITEM, onlyWarning );
334 break;
335 }
336 case ImageDPITooHigh:
337 {
338 int xres = qRound(72.0 / pageItem->imageXScale());
339 int yres = qRound(72.0 / pageItem->imageYScale());
340 item->setText(COLUMN_PROBLEM, warnMap[PV_HIGH_DPI].first.arg(maxResDPI).arg(xres).arg(yres));
341 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_HIGH_DPI].second);
342 item->setIcon(COLUMN_ITEM, onlyWarning );
343 break;
344 }
345 case PartFilledImageFrame:
346 item->setText(COLUMN_PROBLEM, warnMap[PV_IMAGE_FRAME_PART_FILLED].first);
347 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_IMAGE_FRAME_PART_FILLED].second);
348 item->setIcon(COLUMN_ITEM, onlyWarning);
349 break;
350 case Transparency:
351 item->setText(COLUMN_PROBLEM, warnMap[PV_TRANSPARENCY].first);
352 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_TRANSPARENCY].second);
353 item->setIcon(COLUMN_ITEM, graveError );
354 pageGraveError = true;
355 itemError = true;
356 break;
357 case PDFAnnotField:
358 item->setText(COLUMN_PROBLEM, warnMap[PV_ANNOTATION].second);
359 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_ANNOTATION].second);
360 item->setIcon(COLUMN_ITEM, onlyWarning );
361 break;
362 case PlacedPDF:
363 item->setText(COLUMN_PROBLEM, warnMap[PV_RASTER_PDF].first);
364 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_RASTER_PDF].second);
365 item->setIcon(COLUMN_ITEM, onlyWarning );
366 break;
367 case ImageIsGIF:
368 item->setText(COLUMN_PROBLEM, warnMap[PV_IS_GIF].first);
369 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_IS_GIF].second);
370 item->setIcon(COLUMN_ITEM, onlyWarning);
371 break;
372 case WrongFontInAnnotation:
373 item->setText(COLUMN_PROBLEM, warnMap[PV_WRONG_FONT].first);
374 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_WRONG_FONT].second);
375 item->setIcon(COLUMN_ITEM, graveError );
376 pageGraveError = true;
377 itemError = true;
378 break;
379 case NotCMYKOrSpot:
380 item->setText(COLUMN_PROBLEM, warnMap[PV_NOT_CMYK_SPOT].first);
381 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_NOT_CMYK_SPOT].second);
382 item->setIcon(COLUMN_ITEM, onlyWarning);
383 itemError = true;
384 break;
385 case FontNotEmbedded:
386 item->setText(COLUMN_PROBLEM, warnMap[PV_FONT_NOT_EMBEDDED].first);
387 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_FONT_NOT_EMBEDDED].second);
388 item->setIcon(COLUMN_ITEM, graveError);
389 itemError = true;
390 break;
391 case EmptyTextFrame:
392 item->setText(COLUMN_PROBLEM, warnMap[PV_EMPTY_TEXT_FRAME].first);
393 item->setToolTip(COLUMN_PROBLEM, warnMap[PV_EMPTY_TEXT_FRAME].second);
394 item->setIcon(COLUMN_ITEM, onlyWarning);
395 itemError = true;
396 break;
397 default:
398 break;
399 };
400 // additional informations
401 const ScLayer* layer = m_Doc->Layers.layerByID(pageItem->m_layerID);
402 if (layer)
403 {
404 item->setText(COLUMN_LAYER, layer->Name);
405 item->setData(COLUMN_LAYER, Qt::DecorationRole, layer->markerColor);
406 }
407 }
408
buildErrorList(ScribusDoc * doc)409 void CheckDocument::buildErrorList(ScribusDoc *doc)
410 {
411 // bool resultError = false;
412 m_Doc = doc;
413 disconnect(curCheckProfile, SIGNAL(activated(const QString&)), this, SLOT(newScan(const QString&)));
414 curCheckProfile->clear();
415 clearErrorList();
416
417 if (m_Doc==nullptr)
418 return;
419
420 minResDPI = qRound(doc->checkerProfiles()[doc->curCheckProfile()].minResolution);
421 maxResDPI = qRound(doc->checkerProfiles()[doc->curCheckProfile()].maxResolution);
422
423 CheckerPrefsList::Iterator it;
424 CheckerPrefsList::Iterator itend=doc->checkerProfiles().end();
425 for (it = doc->checkerProfiles().begin(); it != itend ; ++it)
426 curCheckProfile->addItem(it.key());
427 setCurrentComboItem(curCheckProfile, doc->curCheckProfile());
428 if (!doc->hasPreflightErrors()
429 //this flag is used by documentchecker as indicator for marks change after updating
430 && !doc->notesChanged())
431 {
432 QTreeWidgetItem * documentItem = new QTreeWidgetItem( reportDisplay );
433 documentItem->setText(COLUMN_ITEM, tr( "Document" ) );
434 documentItem->setIcon(COLUMN_ITEM, noErrors );
435 documentItem->setText(COLUMN_PROBLEM, tr( "No Problems found" ) );
436 ignoreErrors->setText( tr("OK"));
437 }
438 else
439 {
440 bool hasError = false;
441 bool layoutGraveError = false;
442 itemError = false;
443
444
445 // MARKS ***********************************************
446 if (doc->notesChanged())
447 {
448 QTreeWidgetItem * marksItem = new QTreeWidgetItem(reportDisplay);
449 marksItem->setText(0, tr("After Marks update document was changed"));
450 marksItem->setIcon(COLUMN_ITEM, onlyWarning );
451 doc->setNotesChanged(false);
452 }
453
454 // LAYERS **********************************************8
455 QTreeWidgetItem * layerItem = new QTreeWidgetItem(reportDisplay);
456 layerItem->setText(COLUMN_ITEM, tr("Layers"));
457
458 if (doc->docLayerErrors.count() != 0)
459 {
460 QMap<int, errorCodes>::Iterator docLayerErrorsIt;
461 errorCodes::Iterator layerErrorsIt;
462
463 for (docLayerErrorsIt = doc->docLayerErrors.begin();
464 docLayerErrorsIt != doc->docLayerErrors.end();
465 ++docLayerErrorsIt)
466 {
467 QTreeWidgetItem * layer = new QTreeWidgetItem(layerItem);
468 for (layerErrorsIt = docLayerErrorsIt.value().begin();
469 layerErrorsIt != docLayerErrorsIt.value().end(); ++layerErrorsIt)
470 {
471 QTreeWidgetItem * errorText = new QTreeWidgetItem( layer, 0 );
472 switch (layerErrorsIt.key())
473 {
474 case Transparency:
475 errorText->setText(COLUMN_ITEM, warnMap[PV_LAYER_TRANSPARENCY].first);
476 errorText->setToolTip(COLUMN_ITEM, warnMap[PV_LAYER_TRANSPARENCY].second);
477 errorText->setIcon(COLUMN_ITEM, graveError );
478 layoutGraveError = true;
479 break;
480 case BlendMode:
481 errorText->setText(COLUMN_ITEM, warnMap[PV_LAYER_BLENDMODE].first);
482 errorText->setToolTip(COLUMN_ITEM, warnMap[PV_LAYER_BLENDMODE].second);
483 errorText->setIcon(COLUMN_ITEM, graveError );
484 layoutGraveError = true;
485 break;
486 case OffConflictLayers:
487 errorText->setText(COLUMN_ITEM, warnMap[PV_LAYER_PRINTVIS_MISMATCH].first);
488 errorText->setToolTip(COLUMN_ITEM, warnMap[PV_LAYER_PRINTVIS_MISMATCH].second);
489 errorText->setIcon(COLUMN_ITEM, onlyWarning );
490 break;
491 default:
492 break;
493 }
494 }
495 layer->setText(COLUMN_ITEM,tr("Layer \"%1\"").arg(doc->layerName(docLayerErrorsIt.key())));
496 if (layoutGraveError)
497 layer->setIcon(COLUMN_ITEM, graveError );
498 else
499 layer->setIcon(COLUMN_ITEM, onlyWarning );
500 layer->setText(COLUMN_PROBLEM, tr("Issues: %1").arg(doc->docLayerErrors[docLayerErrorsIt.key()].count()));
501 layer->setExpanded(true);
502 }
503 layerItem->setExpanded(true);
504 }
505 // END of LAYERS
506
507 // Master Pages *****************************************************
508 QTreeWidgetItem * masterPageRootItem = new QTreeWidgetItem(reportDisplay);
509 masterPageRootItem->setText(COLUMN_ITEM, tr("Master Pages"));
510 int mpErrorCount = 0;
511
512 for (int mPage = 0; mPage < doc->MasterPages.count(); ++mPage)
513 {
514 hasError = false;
515 pageGraveError = false;
516 QTreeWidgetItem * page=nullptr;
517 if (showPagesWithoutErrors)
518 {
519 page = new QTreeWidgetItem( masterPageRootItem);
520 masterPageMap.insert(page, doc->MasterPages.at(mPage));
521 }
522
523 QMap<PageItem*, errorCodes>::Iterator masterItemErrorsIt;
524 for (masterItemErrorsIt = doc->masterItemErrors.begin();
525 masterItemErrorsIt != doc->masterItemErrors.end();
526 ++masterItemErrorsIt)
527 {
528 if (((masterItemErrorsIt.key()->OwnPage == mPage)
529 || (masterItemErrorsIt.key()->OnMasterPage == doc->MasterPages.at(mPage)->pageName()))
530 &&
531 ((showNonPrintingLayerErrors) ||
532 (!showNonPrintingLayerErrors && doc->layerPrintable(masterItemErrorsIt.key()->m_layerID)))
533 )
534 {
535 if (!showPagesWithoutErrors && page==nullptr)
536 {
537 page = new QTreeWidgetItem( masterPageRootItem);
538 masterPageMap.insert(page, doc->MasterPages.at(mPage));
539 }
540 hasError = true;
541 QTreeWidgetItem * object = new QTreeWidgetItem( page);
542 masterPageItemMap.insert(object, masterItemErrorsIt.key());
543 object->setText(COLUMN_ITEM, masterItemErrorsIt.key()->itemName());
544 errorCodes::Iterator it3;
545 if (masterItemErrorsIt.value().count() == 1)
546 {
547 it3 = masterItemErrorsIt.value().begin();
548 buildItem(object, it3.key(), masterItemErrorsIt.key());
549 posMap.insert(object, it3.value());
550 }
551 else
552 {
553 for (it3 = masterItemErrorsIt.value().begin(); it3 != masterItemErrorsIt.value().end(); ++it3)
554 {
555 QTreeWidgetItem * errorText = new QTreeWidgetItem( object, 0 );
556 buildItem(errorText, it3.key(), masterItemErrorsIt.key());
557 masterPageItemMap.insert(errorText, masterItemErrorsIt.key());
558 posMap.insert(object, it3.value());
559 }
560 object->setExpanded( true );
561 }
562 if (itemError)
563 object->setIcon(COLUMN_ITEM, graveError );
564 else
565 object->setIcon(COLUMN_ITEM, onlyWarning );
566 }
567 }
568 if (hasError)
569 {
570 ++mpErrorCount;
571 if (pageGraveError)
572 page->setIcon(COLUMN_ITEM, graveError );
573 else
574 page->setIcon(COLUMN_ITEM, onlyWarning );
575 page->setExpanded( true );
576 }
577 else
578 {
579 if (showPagesWithoutErrors && page!=nullptr)
580 page->setIcon(COLUMN_ITEM, noErrors );
581 }
582 if (page!=nullptr)
583 page->setText(COLUMN_ITEM, doc->MasterPages.at(mPage)->pageName());
584 }
585 masterPageRootItem->setExpanded(true);
586 masterPageRootItem->setText(COLUMN_PROBLEM, tr("Issues: %1").arg(mpErrorCount));
587 // END of MASTER PAGES
588
589 // PAGES ********************************8
590 for (int aPage = 0; aPage < doc->DocPages.count(); ++aPage)
591 {
592 int pageErrorCount=0;
593 QString tmp;
594 hasError = false;
595 pageGraveError = false;
596 QTreeWidgetItem * page=nullptr;
597 if (showPagesWithoutErrors)
598 {
599 page = new QTreeWidgetItem( reportDisplay);
600 pageMap.insert(page, doc->DocPages.at(aPage));
601 }
602
603 QMap<int, errorCodes>::Iterator pageErrorsIt;
604 for (pageErrorsIt = doc->pageErrors.begin();
605 pageErrorsIt != doc->pageErrors.end();
606 ++pageErrorsIt)
607 {
608 if (pageErrorsIt.key() == aPage)
609 {
610 if (page==nullptr)
611 {
612 page = new QTreeWidgetItem( reportDisplay);
613 pageMap.insert(page, doc->DocPages.at(aPage));
614 }
615 QTreeWidgetItem * errorText = new QTreeWidgetItem(page);
616 errorText->setText(COLUMN_PROBLEM, warnMap[PV_APPLIED_MASTER_DIFF_SIDE].first);
617 errorText->setToolTip(COLUMN_PROBLEM, warnMap[PV_APPLIED_MASTER_DIFF_SIDE].second);
618 errorText->setIcon(COLUMN_ITEM, onlyWarning );
619 pageMap.insert(errorText, doc->DocPages.at(aPage));
620 hasError=true;
621 page->setExpanded( true );
622 ++pageErrorCount;
623 }
624 }
625
626 QMap<PageItem*, errorCodes>::Iterator docItemErrorsIt;
627 for (docItemErrorsIt = doc->docItemErrors.begin();
628 docItemErrorsIt != doc->docItemErrors.end();
629 ++docItemErrorsIt)
630 {
631 if (docItemErrorsIt.key()->OwnPage == aPage &&
632 ((showNonPrintingLayerErrors) ||
633 (!showNonPrintingLayerErrors && doc->layerPrintable(docItemErrorsIt.key()->m_layerID)))
634 )
635 {
636 if (!showPagesWithoutErrors && page==nullptr)
637 {
638 page = new QTreeWidgetItem( reportDisplay);
639 pageMap.insert(page, doc->DocPages.at(aPage));
640 }
641 hasError = true;
642 itemError = false;
643 QTreeWidgetItem * object = new QTreeWidgetItem(page);
644 object->setText(COLUMN_ITEM, docItemErrorsIt.key()->itemName());
645 itemMap.insert(object, docItemErrorsIt.key());
646 errorCodes::Iterator it3;
647 if (docItemErrorsIt.value().count() == 1)
648 {
649 it3 = docItemErrorsIt.value().begin();
650 buildItem(object, it3.key(), docItemErrorsIt.key());
651 posMap.insert(object, it3.value());
652 ++pageErrorCount;
653 }
654 else
655 {
656 for (it3 = docItemErrorsIt.value().begin(); it3 != docItemErrorsIt.value().end(); ++it3)
657 {
658 QTreeWidgetItem * errorText = new QTreeWidgetItem( object);
659 buildItem(errorText, it3.key(), docItemErrorsIt.key());
660 itemMap.insert(errorText, docItemErrorsIt.key());
661 posMap.insert(object, it3.value());
662 ++pageErrorCount;
663 }
664 object->setExpanded( true );
665 }
666 if (itemError)
667 object->setIcon(COLUMN_ITEM, graveError );
668 else
669 object->setIcon(COLUMN_ITEM, onlyWarning );
670 }
671 }
672 if (hasError)
673 {
674 if (pageGraveError)
675 page->setIcon(COLUMN_ITEM, graveError );
676 else
677 page->setIcon(COLUMN_ITEM, onlyWarning );
678 page->setExpanded( true );
679 page->setText(COLUMN_PROBLEM, tr( "Issues: %1" ).arg(pageErrorCount) );
680 }
681 else
682 {
683 if (showPagesWithoutErrors && page!=nullptr)
684 page->setIcon( 0, noErrors );
685 }
686 if (page!=nullptr)
687 page->setText(COLUMN_ITEM, tr("Page ")+tmp.setNum(aPage+1));
688 }
689 // END of PAGES
690
691 // FREE ITEMS **************************************************
692 QMap<PageItem*, errorCodes>::Iterator freeItemsErrorsIt;
693 bool hasfreeItems = false;
694 for (freeItemsErrorsIt = doc->docItemErrors.begin(); freeItemsErrorsIt != doc->docItemErrors.end(); ++freeItemsErrorsIt)
695 {
696 if (doc->OnPage(freeItemsErrorsIt.key()) == -1)
697 {
698 hasfreeItems = true;
699 break;
700 }
701 }
702 if (hasfreeItems)
703 {
704 bool hasError = false;
705 bool pageGraveError = false;
706 QTreeWidgetItem * freeItem = new QTreeWidgetItem( reportDisplay);
707 for (freeItemsErrorsIt = doc->docItemErrors.begin(); freeItemsErrorsIt != doc->docItemErrors.end(); ++freeItemsErrorsIt)
708 {
709 if (doc->OnPage(freeItemsErrorsIt.key()) == -1)
710 {
711 hasError = true;
712 QTreeWidgetItem * object = new QTreeWidgetItem(freeItem);
713 object->setText(0, freeItemsErrorsIt.key()->itemName());
714 itemMap.insert(object, freeItemsErrorsIt.key());
715 errorCodes::Iterator it3;
716 if (freeItemsErrorsIt.value().count() == 1)
717 {
718 it3 = freeItemsErrorsIt.value().begin();
719 buildItem(object, it3.key(), freeItemsErrorsIt.key());
720 posMap.insert(object, it3.value());
721 }
722 else
723 {
724 for (it3 = freeItemsErrorsIt.value().begin(); it3 != freeItemsErrorsIt.value().end(); ++it3)
725 {
726 QTreeWidgetItem * errorText = new QTreeWidgetItem( object);
727 buildItem(errorText, it3.key(), freeItemsErrorsIt.key());
728 itemMap.insert(errorText, freeItemsErrorsIt.key());
729 posMap.insert(object, it3.value());
730 }
731 object->setExpanded( true );
732 }
733 if (pageGraveError)
734 object->setIcon(COLUMN_ITEM, graveError );
735 else
736 object->setIcon(COLUMN_ITEM, onlyWarning );
737 }
738 }
739 if (hasError)
740 {
741 if (pageGraveError)
742 freeItem->setIcon(COLUMN_ITEM, graveError );
743 else
744 freeItem->setIcon(COLUMN_ITEM, onlyWarning );
745 freeItem->setExpanded( true );
746 }
747 else
748 freeItem->setIcon(COLUMN_ITEM, noErrors );
749 freeItem->setText(COLUMN_ITEM, tr("Free Objects"));
750 }
751 // END of FREE ITEMS
752
753 ignoreErrors->setText( tr("&Ignore Errors"));
754 }
755
756 reportDisplay->resizeColumnToContents(COLUMN_ITEM);
757 reportDisplay->resizeColumnToContents(COLUMN_PROBLEM);
758 reportDisplay->resizeColumnToContents(COLUMN_LAYER);
759 connect(curCheckProfile, SIGNAL(activated(const QString&)), this, SLOT(newScan(const QString&)));
760 connect(reportDisplay, SIGNAL(itemClicked(QTreeWidgetItem*, int)), this, SLOT(slotSelect(QTreeWidgetItem*)));
761 }
762
setIgnoreEnabled(bool state)763 void CheckDocument::setIgnoreEnabled(bool state)
764 {
765 noButton = !state;
766 ignoreErrors->setVisible(state);
767 }
768
isIgnoreEnabled()769 bool CheckDocument::isIgnoreEnabled()
770 {
771 return !noButton;
772 }
773