1 #include "LDHtmlInventory.h"
2 #include "LDPartsList.h"
3 #include "LDPartCount.h"
4 #include <LDLoader/LDLMainModel.h>
5 #include <TCFoundation/TCLocalStrings.h>
6 #include <TCFoundation/mystring.h>
7 #include "LDPreferences.h"
8 #include "LDrawModelViewer.h"
9 #include "LDViewPoint.h"
10 #include <string>
11
12 #ifdef WIN32
13 #if defined(_MSC_VER) && _MSC_VER >= 1400 && defined(_DEBUG)
14 #define new DEBUG_CLIENTBLOCK
15 #endif // _DEBUG
16 #endif // WIN32
17
18 const char *LDHtmlInventory::sm_style = "\
19 body\n\
20 {\n\
21 font-family: tahoma, sans-serif;\n\
22 }\n\
23 \n\
24 div\n\
25 {\n\
26 position: absolute;\n\
27 }\n\
28 \n\
29 table\n\
30 {\n\
31 border-collapse: collapse;\n\
32 border: 2px solid #000000;\n\
33 background-color: #FFFFDD;\n\
34 padding: 0px;\n\
35 }\n\
36 \n\
37 table.titleImage\n\
38 {\n\
39 width: 100%;\n\
40 border-bottom: 0px;\n\
41 }\n\
42 \n\
43 th.titleImage\n\
44 {\n\
45 background-color: #EEEEEE;\n\
46 color: #000000;\n\
47 font-size: 150%;\n\
48 border-bottom-style: none;\n\
49 padding-bottom: 0px;\n\
50 }\n\
51 \n\
52 tr\n\
53 {\n\
54 page-break-inside: avoid;\n\
55 }\n\
56 \n\
57 th\n\
58 {\n\
59 background-color: #0080D0;\n\
60 color: #FFFFFF;\n\
61 border-bottom: 1px solid #000000;\n\
62 border-right: 1px solid #00558A;\n\
63 padding: 4px 8px;\n\
64 }\n\
65 \n\
66 th.title\n\
67 {\n\
68 background-color: #EEEEEE;\n\
69 color: #000000;\n\
70 font-size: 150%;\n\
71 }\n\
72 \n\
73 td\n\
74 {\n\
75 vertical-align: top;\n\
76 background-color: #FFFFDD;\n\
77 border-bottom: 1px solid #BFBFA5;\n\
78 border-right: 1px solid #BFBFA5;\n\
79 padding: 2px 8px;\n\
80 }\n\
81 \n\
82 td.quantity\n\
83 {\n\
84 text-align: right;\n\
85 }\n\
86 \n\
87 td.colorNumber\n\
88 {\n\
89 text-align: right;\n\
90 border-right-style: none;\n\
91 }\n\
92 \n\
93 td.image\n\
94 {\n\
95 border-right-style: none;\n\
96 }\n\
97 \n\
98 table.color\n\
99 {\n\
100 border-style: none;\n\
101 width: 100%;\n\
102 }\n\
103 \n\
104 table.color td\n\
105 {\n\
106 border-style: none;\n\
107 padding: 0px 8px 0px 0px;\n\
108 width: 100%\n\
109 }\n\
110 \n\
111 table.color td.colorBox\n\
112 {\n\
113 padding: 1px 0px;\n\
114 width: auto\n\
115 }\n\
116 \n\
117 table.colorBox\n\
118 {\n\
119 border: 1px solid black;\n\
120 width: 2em;\n\
121 height: 1em;\n\
122 padding: 0px;\n\
123 }\n\
124 \n\
125 table.colorBox td\n\
126 {\n\
127 padding: 0px;\n\
128 }\n\
129 \n\
130 table.credits\n\
131 {\n\
132 border-collapse: collapse;\n\
133 border-style: none;\n\
134 background-color: transparent;\n\
135 margin: 0px;\n\
136 width: 100%;\n\
137 }\n\
138 \n\
139 td.credits\n\
140 {\n\
141 background-color: #EEEEEE;\n\
142 border-style: none;\n\
143 padding: 0px;\n\
144 }\n\
145 \n\
146 table.credits td\n\
147 {\n\
148 background-color: transparent;\n\
149 color: #808080;\n\
150 border-style: none;\n\
151 font-size: 65%;\n\
152 }\n\
153 \n\
154 a\n\
155 {\n\
156 text-decoration: none;\n\
157 border-style: none;\n\
158 }\n\
159 \n\
160 a:link\n\
161 {\n\
162 color: #000080;\n\
163 }\n\
164 \n\
165 a:visited\n\
166 {\n\
167 color: #0000FF;\n\
168 }\n\
169 \n\
170 a:hover\n\
171 {\n\
172 text-decoration: underline;\n\
173 color: #000080;\n\
174 }\n\
175 \n\
176 img\n\
177 {\n\
178 float: right;\n\
179 }\n\
180 \n\
181 th img\n\
182 {\n\
183 float: none;\n\
184 }\n\
185 \n\
186 a img\n\
187 {\n\
188 border-style: none;\n\
189 }\n\
190 \n\
191 :link:hover img\n\
192 {\n\
193 background-color: #D0E8FF;\n\
194 }\n\
195 \n\
196 :visited:hover img\n\
197 {\n\
198 background-color: #A0C0FF;\n\
199 }\n\
200 ";
201
202 const char *LDHtmlInventory::sm_cssHeader = "\
203 /* CSS Style Sheet auto-generated by LDView */\n\
204 \n\
205 ";
206
207 const char *LDHtmlInventory::sm_cssFilename = "LDViewPartsList.css";
208
LDHtmlInventory(void)209 LDHtmlInventory::LDHtmlInventory(void) :
210 m_prefs(new LDPreferences),
211 m_viewPoint(NULL)
212 {
213 int i;
214
215 m_prefs->loadInventorySettings();
216 m_showModel = m_prefs->getInvShowModel();
217 m_overwriteSnapshot = m_prefs->getInvOverwriteSnapshot();
218 m_externalCss = m_prefs->getInvExternalCss();
219 m_partImages = m_prefs->getInvPartImages();
220 m_showFile = m_prefs->getInvShowFile();
221 m_showTotal = m_prefs->getInvShowTotal();
222 m_lastSavePath = m_prefs->getInvLastSavePath();
223 const LongVector &columnOrder = m_prefs->getInvColumnOrder();
224 for (i = 0; i < (int)columnOrder.size(); i++)
225 {
226 m_columnOrder.push_back((LDPartListColumn)columnOrder[i]);
227 }
228 }
229
~LDHtmlInventory(void)230 LDHtmlInventory::~LDHtmlInventory(void)
231 {
232 }
233
dealloc(void)234 void LDHtmlInventory::dealloc(void)
235 {
236 m_prefs->release();
237 TCObject::dealloc();
238 }
239
populateColumnMap(void)240 void LDHtmlInventory::populateColumnMap(void)
241 {
242 int i;
243
244 m_columns = (int)m_columnOrder.size();
245 m_columnMap.clear();
246 for (i = 0; i < (int)m_columnOrder.size(); i++)
247 {
248 LDPartListColumn column = m_columnOrder[i];
249
250 m_columnMap[column] = true;
251 switch (column)
252 {
253 case LDPLCPart:
254 if (m_partImages)
255 {
256 m_columns++;
257 }
258 break;
259 case LDPLCColor:
260 m_columns++;
261 break;
262 default:
263 // Get rid of gcc warning
264 break;
265 }
266 }
267 }
268
generateHtml(const char * filename,LDPartsList * partsList,const char * modelName)269 bool LDHtmlInventory::generateHtml(
270 const char *filename,
271 LDPartsList *partsList,
272 const char *modelName)
273 {
274 FILE *file = ucfopen(filename, "w");
275 size_t nSlashSpot;
276
277 m_lastFilename = filename;
278 m_lastSavePath = filename;
279 populateColumnMap();
280 nSlashSpot = m_lastSavePath.find_last_of("/\\");
281 if (nSlashSpot < m_lastSavePath.size())
282 {
283 m_lastSavePath = m_lastSavePath.substr(0, nSlashSpot);
284 }
285 m_prefs->setInvLastSavePath(m_lastSavePath.c_str());
286 m_prefs->commitInventorySettings();
287 m_modelName = modelName;
288 nSlashSpot = m_modelName.find_last_of("/\\");
289 if (nSlashSpot < m_modelName.size())
290 {
291 m_modelName = m_modelName.substr(nSlashSpot + 1);
292 }
293 if (file)
294 {
295 const LDPartCountVector &partCounts = partsList->getPartCounts();
296 int i, j;
297
298 writeHeader(file);
299 writeTableHeader(file, partsList->getTotalParts());
300 for (i = 0; i < (int)partCounts.size(); i++)
301 {
302 const LDPartCount &partCount = partCounts[i];
303 const IntVector &colors = partCount.getColors();
304 LDLModel *model = const_cast<LDLModel *>(partCount.getModel());
305 LDLPalette *palette = model->getMainModel()->getPalette();
306 //int partTotal = partCount.getTotalCount();
307
308 for (j = 0; j < (int)colors.size(); j++)
309 {
310 int colorNumber = colors[j];
311 LDLColorInfo colorInfo = palette->getAnyColorInfo(colorNumber);
312
313 writePartRow(file, partCount, palette, colorInfo, colorNumber);
314 }
315 }
316 writeTableFooter(file);
317 writeFooter(file);
318 fclose(file);
319 return true;
320 }
321 else
322 {
323 return false;
324 }
325 }
326
safeOpenCssFile(const std::string & cssFilename,bool & match)327 FILE *LDHtmlInventory::safeOpenCssFile(const std::string &cssFilename,
328 bool &match)
329 {
330 FILE *cssFile = ucfopen(cssFilename.c_str(), "r");
331
332 match = false;
333 if (cssFile)
334 {
335 size_t headerSize = strlen(sm_cssHeader);
336 size_t contentSize = strlen(sm_style);
337
338 std::string fileHeader;
339 std::string fileContents;
340
341 fileHeader.resize(headerSize);
342 fileContents.resize(contentSize);
343 if (fread(&fileHeader[0], headerSize, 1, cssFile) == 1 &&
344 fread(&fileContents[0], contentSize, 1, cssFile) == 1 &&
345 fileHeader == sm_cssHeader &&
346 fileContents == sm_style)
347 {
348 TCByte test;
349
350 if (fread(&test, 1, 1, cssFile) == 0)
351 {
352 match = true;
353 }
354 }
355 fclose(cssFile);
356 return NULL;
357 }
358 return ucfopen(cssFilename.c_str(), "w");
359 }
360
writeExternalCss(void)361 bool LDHtmlInventory::writeExternalCss(void)
362 {
363 if (m_externalCss)
364 {
365 std::string cssFilename = m_lastSavePath + "/" + sm_cssFilename;
366 bool match;
367 FILE *cssFile = safeOpenCssFile(cssFilename, match);
368
369 if (cssFile)
370 {
371 fprintf(cssFile, "%s", sm_cssHeader);
372 fprintf(cssFile, "%s", sm_style);
373 fclose(cssFile);
374 }
375 if (cssFile || match)
376 {
377 return true;
378 }
379 }
380 return false;
381 }
382
writeHeader(FILE * file)383 void LDHtmlInventory::writeHeader(FILE *file)
384 {
385 //unsigned char utf8Signature[3] = { 0xEF, 0xBB, 0xBF };
386 //fwrite(utf8Signature, 3, 1, file);
387 fprintf(file, "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" "
388 "\"http://www.w3.org/TR/html4/strict.dtd\">\n");
389 fprintf(file, "<html>\n");
390 fprintf(file, "<head>\n");
391 fprintf(file, "<meta http-equiv=\"Content-Type\" "
392 "content=\"text/html; charset=UTF-8\">\n");
393 char title[1024];
394 sprintf(title, lsUtf8("PLTitle"), m_modelName.c_str());
395 fprintf(file, "<title>%s</title>\n", title);
396 if (writeExternalCss())
397 {
398 fprintf(file, "<link href=\"%s\" title=\"%s\" "
399 "rel=\"stylesheet\" type=\"text/css\">\n", sm_cssFilename,
400 lsUtf8("PLStyleSheetTitle"));
401 }
402 else
403 {
404 fprintf(file, "<style type=\"text/css\" title=\"%s\"><!--\n",
405 lsUtf8("PLStyleSheetTitle"));
406 fprintf(file, "%s", sm_style);
407 fprintf(file, "--></style>\n");
408 }
409 fprintf(file, "</head>\n");
410 fprintf(file, "<body>\n");
411 fprintf(file, "<div>\n");
412 }
413
writeFooter(FILE * file)414 void LDHtmlInventory::writeFooter(FILE *file)
415 {
416 fprintf(file, "</div>\n");
417 fprintf(file, "</body>\n");
418 fprintf(file, "</html>\n");
419 }
420
writePartHeaderCell(FILE * file)421 void LDHtmlInventory::writePartHeaderCell(FILE *file)
422 {
423 int colSpan = 2;
424
425 if (!m_partImages)
426 {
427 colSpan = 1;
428 }
429 writeHeaderCell(file, LDPLCPart, colSpan);
430 }
431
writeHeaderCell(FILE * file,LDPartListColumn column,int colSpan)432 void LDHtmlInventory::writeHeaderCell(
433 FILE *file,
434 LDPartListColumn column,
435 int colSpan)
436 {
437 std::string utf8ColumnName;
438 ucstringtoutf8(utf8ColumnName, getColumnNameUC(column));
439 if (colSpan == 1)
440 {
441 fprintf(file, " <th>%s</th>\n", utf8ColumnName.c_str());
442 }
443 else
444 {
445 fprintf(file, " <th colspan=\"%d\">%s</th>\n", colSpan,
446 utf8ColumnName.c_str());
447 }
448 }
449
writeHeaderCell(FILE * file,LDPartListColumn column)450 void LDHtmlInventory::writeHeaderCell(FILE *file, LDPartListColumn column)
451 {
452 switch (column)
453 {
454 case LDPLCPart:
455 writePartHeaderCell(file);
456 break;
457 case LDPLCDescription:
458 writeHeaderCell(file, LDPLCDescription, 1);
459 break;
460 case LDPLCColor:
461 writeHeaderCell(file, LDPLCColor, 2);
462 break;
463 case LDPLCQuantity:
464 writeHeaderCell(file, LDPLCQuantity, 1);
465 break;
466 }
467 }
468
writePartCell(FILE * file,const LDPartCount & partCount,LDLPalette * palette,const LDLColorInfo & colorInfo,int colorNumber)469 void LDHtmlInventory::writePartCell(
470 FILE *file,
471 const LDPartCount &partCount,
472 LDLPalette *palette,
473 const LDLColorInfo &colorInfo,
474 int colorNumber)
475 {
476 int peeronColorNumber = colorNumber;
477 std::string imgStyle;
478 std::string partName = partCount.getFilename();
479 size_t nDotSpot = partName.find('.');
480 int r, g, b, a;
481
482 palette->getRGBA(colorInfo, r, g, b, a);
483 if (nDotSpot < partName.size())
484 {
485 partName = partName.substr(0, nDotSpot);
486 }
487 if (peeronColorNumber >= 512)
488 {
489 char bgColor[10];
490
491 sprintf(bgColor, "%02X%02X%02X", r, g, b);
492 peeronColorNumber = 7;
493 imgStyle = (std::string)"style = \"padding: 4px; "
494 "background-color: #" + bgColor + "\" ";
495 }
496 if (m_partImages)
497 {
498 std::string className;
499 bool official = partCount.getModel()->isOfficial();
500
501 //if (official)
502 {
503 className = " class=\"image\"";
504 }
505 fprintf(file, " <td%s>"
506 "<a href=\"http://peeron.com/inv/parts/%s\">",
507 className.c_str(), partName.c_str());
508 if (official)
509 {
510 fprintf(file, "<img %salt=\"%s\" title=\"%s\" "
511 "src=\"http://media.peeron.com/ldraw/images/%d/100/%s.png\">",
512 imgStyle.c_str(), lsUtf8("PLViewOnPeeron"),
513 lsUtf8("PLViewOnPeeron"), peeronColorNumber, partName.c_str());
514 }
515 else
516 {
517 fprintf(file, "%s", lsUtf8("PLViewOnPeeron"));
518 }
519 fprintf(file, "</a></td>\n");
520 }
521 fprintf(file, " <td>%s</td>\n", partName.c_str());
522 }
523
writeDescriptionCell(FILE * file,const LDPartCount & partCount)524 void LDHtmlInventory::writeDescriptionCell(
525 FILE *file,
526 const LDPartCount &partCount)
527 {
528 if (m_columnMap[LDPLCDescription])
529 {
530 const char *description = partCount.getModel()->getDescription();
531 if (description)
532 {
533 fprintf(file, " <td>%s</td>\n", description);
534 }
535 else
536 {
537 fprintf(file, " <td><%s></td>\n",
538 lsUtf8("PLNoDescription"));
539 }
540 }
541 }
542
writeColorCell(FILE * file,LDLPalette * palette,const LDLColorInfo & colorInfo,int colorNumber)543 void LDHtmlInventory::writeColorCell(
544 FILE *file,
545 LDLPalette *palette,
546 const LDLColorInfo &colorInfo,
547 int colorNumber)
548 {
549 int r, g, b, a;
550
551 palette->getRGBA(colorInfo, r, g, b, a);
552 if (strlen(colorInfo.name))
553 {
554 fprintf(file, " <td class=\"colorNumber\">%d:</td>\n",
555 colorNumber);
556 }
557 else
558 {
559 if (colorNumber < 512)
560 {
561 fprintf(file, " <td class=\"colorNumber\">%d"
562 "</td>\n", colorNumber);
563 }
564 else
565 {
566 fprintf(file, " <td class=\"colorNumber\">#%X"
567 "</td>\n", colorNumber);
568 }
569 }
570 fprintf(file, " <td>\n");
571 fprintf(file, " <table class=\"color\">\n");
572 fprintf(file, " <tr>\n");
573 fprintf(file, " <td rowspan=\"2\">"
574 "%s<td>\n", colorInfo.name);
575 fprintf(file, " <td class=\"colorBox\"><table "
576 "class=\"colorBox\"><tr><td style=\"background-color: #%02X%02X%02X\">"
577 " </td></tr></table></td>\n", r, g, b);
578 fprintf(file, " </tr>\n");
579 fprintf(file, " </table>\n");
580 fprintf(file, " </td>\n");
581 }
582
writeQuantityCell(FILE * file,const LDPartCount & partCount,int colorNumber)583 void LDHtmlInventory::writeQuantityCell(
584 FILE *file,
585 const LDPartCount &partCount,
586 int colorNumber)
587 {
588 fprintf(file, " <td class=\"quantity\">%d</td>\n",
589 partCount.getColorCount(colorNumber));
590 }
591
writeCell(FILE * file,LDPartListColumn column,const LDPartCount & partCount,LDLPalette * palette,const LDLColorInfo & colorInfo,int colorNumber)592 void LDHtmlInventory::writeCell(
593 FILE *file, LDPartListColumn column,
594 const LDPartCount &partCount,
595 LDLPalette *palette,
596 const LDLColorInfo &colorInfo,
597 int colorNumber)
598 {
599 switch (column)
600 {
601 case LDPLCPart:
602 writePartCell(file, partCount, palette, colorInfo, colorNumber);
603 break;
604 case LDPLCDescription:
605 writeDescriptionCell(file, partCount);
606 break;
607 case LDPLCColor:
608 writeColorCell(file, palette, colorInfo, colorNumber);
609 break;
610 case LDPLCQuantity:
611 writeQuantityCell(file, partCount, colorNumber);
612 break;
613 }
614 }
615
getSnapshotPath(void) const616 const char *LDHtmlInventory::getSnapshotPath(void) const
617 {
618 m_snapshotPath = m_lastSavePath + "/" + getSnapshotFilename();
619 return m_snapshotPath.c_str();
620 }
621
getSnapshotFilename(void) const622 std::string LDHtmlInventory::getSnapshotFilename(void) const
623 {
624 size_t nSpot = m_lastFilename.find_last_of('.');
625 std::string filename;
626
627 if (nSpot < m_lastFilename.size())
628 {
629 filename = m_lastFilename.substr(0, nSpot);
630 }
631 else
632 {
633 filename = m_lastFilename;
634 }
635 filename += ".png";
636 nSpot = filename.find_last_of("/\\");
637 if (nSpot < filename.size())
638 {
639 filename = filename.substr(nSpot + 1);
640 }
641 return filename;
642 }
643
writeTableHeader(FILE * file,int totalParts)644 void LDHtmlInventory::writeTableHeader(FILE *file, int totalParts)
645 {
646 size_t i;
647
648 fprintf(file, "<table class=\"titleImage\">\n");
649 fprintf(file, " <tbody>\n");
650 if (m_showModel)
651 {
652 fprintf(file, " <tr>\n");
653 fprintf(file, " <th class=\"titleImage\" "
654 "colspan=\"%d\">\n", m_columns);
655 fprintf(file, " <img alt=\"<%s>\" "
656 "title=\"<%s>\" src=\"%s\">\n",
657 m_modelName.c_str(), m_modelName.c_str(),
658 getSnapshotFilename().c_str());
659 fprintf(file, " </th>\n");
660 fprintf(file, " </tr>\n");
661 }
662 fprintf(file, " <tr>\n");
663 fprintf(file, " <th class=\"title\" colspan=\"%d\">\n", m_columns);
664 char title[1024];
665 sprintf(title, lsUtf8("PLTitle"), m_modelName.c_str());
666 fprintf(file, " %s", title);
667 if (m_showTotal)
668 {
669 fprintf(file, lsUtf8("PLTotalParts"), totalParts);
670 }
671 fprintf(file, "\n");
672 fprintf(file, " </th>\n");
673 fprintf(file, " </tr>\n");
674 fprintf(file, " </tbody>\n");
675 fprintf(file, "</table>\n");
676 fprintf(file, "<table>\n");
677 fprintf(file, " <thead>\n");
678 fprintf(file, " <tr>\n");
679 for (i = 0; i < m_columnOrder.size(); i++)
680 {
681 writeHeaderCell(file, m_columnOrder[i]);
682 }
683 fprintf(file, " </tr>\n");
684 fprintf(file, " </thead>\n");
685 fprintf(file, " <tbody>\n");
686 }
687
writeTableFooter(FILE * file)688 void LDHtmlInventory::writeTableFooter(FILE *file)
689 {
690 const char *ldviewCreditAlign = "left";
691
692 //fprintf(file, " <tfoot>\n");
693 fprintf(file, " <tr>\n");
694 fprintf(file, " <td colspan=\"%d\" class=\"credits\">\n",
695 m_columns);
696 fprintf(file, " <table class=\"credits\">\n");
697 fprintf(file, " <tbody>\n");
698 fprintf(file, " <tr>\n");
699 if (!m_partImages)
700 {
701 ldviewCreditAlign = "center";
702 }
703 fprintf(file, " <td align=\"%s\">\n",
704 ldviewCreditAlign);
705 fprintf(file, " %s\n",
706 lsUtf8("PLGeneratedBy"));
707 fprintf(file, " </td>\n");
708 if (m_partImages)
709 {
710 fprintf(file, " <td align=\"right\">\n");
711 fprintf(file, " %s\n",
712 lsUtf8("PLProvidedBy"));
713 fprintf(file, " </td>\n");
714 }
715 fprintf(file, " </tr>\n");
716 fprintf(file, " </tbody>\n");
717 fprintf(file, " </table>\n");
718 fprintf(file, " </td>\n");
719 fprintf(file, " </tr>\n");
720 //fprintf(file, " </tfoot>\n");
721 fprintf(file, " </tbody>\n");
722 fprintf(file, "</table>\n");
723 }
724
writePartRow(FILE * file,const LDPartCount & partCount,LDLPalette * palette,const LDLColorInfo & colorInfo,int colorNumber)725 void LDHtmlInventory::writePartRow(
726 FILE *file,
727 const LDPartCount &partCount,
728 LDLPalette *palette,
729 const LDLColorInfo &colorInfo,
730 int colorNumber)
731 {
732 size_t i;
733
734 fprintf(file, " <tr>\n");
735 for (i = 0; i < m_columnOrder.size(); i++)
736 {
737 writeCell(file, m_columnOrder[i], partCount, palette, colorInfo,
738 colorNumber);
739 }
740 fprintf(file, " </tr>\n");
741 }
742
setShowModelFlag(bool value)743 void LDHtmlInventory::setShowModelFlag(bool value)
744 {
745 m_showModel = value;
746 m_prefs->setInvShowModel(value);
747 }
748
setOverwriteSnapshotFlag(bool value)749 void LDHtmlInventory::setOverwriteSnapshotFlag(bool value)
750 {
751 m_overwriteSnapshot = value;
752 m_prefs->setInvOverwriteSnapshot(value);
753 }
754
setExternalCssFlag(bool value)755 void LDHtmlInventory::setExternalCssFlag(bool value)
756 {
757 m_externalCss = value;
758 m_prefs->setInvExternalCss(value);
759 }
760
setPartImagesFlag(bool value)761 void LDHtmlInventory::setPartImagesFlag(bool value)
762 {
763 m_partImages = value;
764 m_prefs->setInvPartImages(value);
765 }
766
setShowFileFlag(bool value)767 void LDHtmlInventory::setShowFileFlag(bool value)
768 {
769 // Note: this class doesn't actually use the flag; it just keeps track of
770 // the value and makes sure it gets saved and restored in the user defaults.
771 m_showFile = value;
772 m_prefs->setInvShowFile(value);
773 }
774
setShowTotalFlag(bool value)775 void LDHtmlInventory::setShowTotalFlag(bool value)
776 {
777 m_showTotal = value;
778 m_prefs->setInvShowTotal(value);
779 }
780
setColumnOrder(const LDPartListColumnVector & value)781 void LDHtmlInventory::setColumnOrder(const LDPartListColumnVector &value)
782 {
783 LongVector columnOrder;
784 int i;
785
786 m_columnOrder = value;
787 for (i = 0; i < (int)value.size(); i++)
788 {
789 columnOrder.push_back(value[i]);
790 }
791 m_prefs->setInvColumnOrder(columnOrder);
792 }
793
isColumnEnabled(LDPartListColumn column)794 bool LDHtmlInventory::isColumnEnabled(LDPartListColumn column)
795 {
796 populateColumnMap();
797 return m_columnMap[column];
798 }
799
getColumnNameUC(LDPartListColumn column)800 CUCSTR LDHtmlInventory::getColumnNameUC(LDPartListColumn column)
801 {
802 switch (column)
803 {
804 case LDPLCPart:
805 return ls(_UC("PLPartColName"));
806 break;
807 case LDPLCDescription:
808 return ls(_UC("PLDescriptionColName"));
809 break;
810 case LDPLCColor:
811 return ls(_UC("PLColorColName"));
812 break;
813 case LDPLCQuantity:
814 return ls(_UC("PLQuantityColName"));
815 break;
816 }
817 return _UC("<Unknown Column Name>");
818 }
819
getColumnName(LDPartListColumn column)820 const char *LDHtmlInventory::getColumnName(LDPartListColumn column)
821 {
822 switch (column)
823 {
824 case LDPLCPart:
825 return ls("PLPartColName");
826 break;
827 case LDPLCDescription:
828 return ls("PLDescriptionColName");
829 break;
830 case LDPLCColor:
831 return ls("PLColorColName");
832 break;
833 case LDPLCQuantity:
834 return ls("PLQuantityColName");
835 break;
836 }
837 return "<Unknown Column Name>";
838 }
839
prepForSnapshot(LDrawModelViewer * modelViewer)840 void LDHtmlInventory::prepForSnapshot(LDrawModelViewer *modelViewer)
841 {
842 TCObject::release(m_viewPoint);
843 m_viewPoint = modelViewer->saveViewPoint();
844 modelViewer->resetView();
845 modelViewer->setRotationSpeed(0);
846 modelViewer->setXYPan(0, 0);
847 modelViewer->setBackgroundRGB(0xEE, 0xEE, 0xEE);
848 modelViewer->setStereoMode(LDVStereoNone);
849 }
850
restoreAfterSnapshot(LDrawModelViewer * modelViewer)851 void LDHtmlInventory::restoreAfterSnapshot(LDrawModelViewer *modelViewer)
852 {
853 if (m_viewPoint)
854 {
855 modelViewer->restoreViewPoint(m_viewPoint);
856 m_viewPoint->release();
857 }
858 }
859
isSnapshotNeeded(void) const860 bool LDHtmlInventory::isSnapshotNeeded(void) const
861 {
862 if (m_showModel)
863 {
864 if (m_overwriteSnapshot)
865 {
866 return true;
867 }
868 else
869 {
870 const char *snapshotPath = getSnapshotPath();
871 FILE *pFile = ucfopen(snapshotPath, "rb");
872
873 if (pFile)
874 {
875 fclose(pFile);
876 }
877 else
878 {
879 return true;
880 }
881 }
882 }
883 return false;
884 }
885
defaultFilename(const char * modelFilename)886 std::string LDHtmlInventory::defaultFilename(const char *modelFilename)
887 {
888 char *filePart = filenameFromPath(modelFilename);
889 char *dirPart = directoryFromPath(modelFilename);
890 std::string htmlFilename;
891
892 if (dirPart)
893 {
894 htmlFilename = dirPart;
895 delete[] dirPart;
896 htmlFilename += '/';
897 }
898 char *findSpot = strrchr(filePart, '.');
899 if (findSpot)
900 {
901 findSpot[0] = 0;
902 }
903 htmlFilename += filePart;
904 delete[] filePart;
905 htmlFilename += ".html";
906 filePart = cleanedUpPath(htmlFilename.c_str());
907 htmlFilename = filePart;
908 delete[] filePart;
909 return htmlFilename;
910 }
911