File: lc_bricklink.cpp

package info (click to toggle)
leocad 25.09-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 9,008 kB
  • sloc: cpp: 51,794; xml: 11,265; python: 81; sh: 52; makefile: 16
file content (128 lines) | stat: -rw-r--r-- 3,318 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "lc_global.h"
#include "lc_file.h"
#include "lc_library.h"
#include "lc_mainwindow.h"
#include "pieceinf.h"

static QJsonDocument lcLoadBrickLinkMapping()
{
	std::map<std::string, std::string> Remapping;

	QFile File(lcGetPiecesLibrary()->mLibraryDir.absoluteFilePath(QLatin1String("ldraw2bl.txt")));
	QByteArray Data;

	if (File.open(QIODevice::ReadOnly))
		Data = File.readAll();
	else
	{
		QFile DefaultFile(":/resources/ldraw2bl.txt");

		if (DefaultFile.open(QIODevice::ReadOnly))
			Data = DefaultFile.readAll();
	}

	return QJsonDocument::fromJson(Data);
}

static std::string lcGetBrickLinkPart(const QJsonObject& PartMapping, const QString& LDrawPart)
{
	QJsonObject::const_iterator PartIt = PartMapping.find(LDrawPart);

	return (PartIt != PartMapping.end()) ? PartIt.value().toString().toStdString() : LDrawPart.toStdString();
}

static int lcGetBrickLinkColor(const QJsonObject& ColorMapping, int ColorIndex)
{
	int ColorCode = gColorList[ColorIndex].Code;
	QJsonObject::const_iterator ColorIt = ColorMapping.find(QString::number(ColorCode));

	return (ColorIt != ColorMapping.end()) ? ColorIt.value().toString().toInt() : 0;
}

class lcBrickLinkItem
{
public:
	lcBrickLinkItem(const std::string& id, int color, int count)
		: mId(id), mColor(color), mCount(count)
	{
	}

	void AddToCount(int count)
	{
		mCount += count;
	}

	std::string mId;
	int mColor;
	int mCount;
};

void lcExportBrickLink(const QString& SaveFileName, const lcPartsList& PartsList)
{
	QJsonDocument Document = lcLoadBrickLinkMapping();
	QJsonObject Root = Document.object();
	QJsonObject PartMapping = Root["Parts"].toObject();
	QJsonObject ColorMapping = Root["Colors"].toObject();

	lcDiskFile BrickLinkFile(SaveFileName);
	char Line[1024];

	if (!BrickLinkFile.Open(QIODevice::WriteOnly))
	{
		QMessageBox::warning(gMainWindow, QObject::tr("LeoCAD"), QObject::tr("Could not open file '%1' for writing.").arg(SaveFileName));
		return;
	}

	std::map<std::string, lcBrickLinkItem> Inventory;

	BrickLinkFile.WriteLine("<INVENTORY>\n");

	for (const auto& PartIt : PartsList)
	{
		const PieceInfo* Info = PartIt.first;

		for (const auto& ColorIt : PartIt.second)
		{
			char FileName[LC_PIECE_NAME_LEN];
			strcpy(FileName, Info->mFileName);
			char* Ext = strchr(FileName, '.');
			if (Ext)
				*Ext = 0;

			std::string Remapped = lcGetBrickLinkPart(PartMapping, FileName);
			int Color = lcGetBrickLinkColor(ColorMapping, ColorIt.first);
			std::string key(Remapped);
			key += "-" + std::to_string(Color);
			auto iter = Inventory.find(key);
			if (iter == Inventory.end())
			{
				Inventory.emplace(std::make_pair(key, lcBrickLinkItem(Remapped, Color, ColorIt.second)));
			}
			else
			{
				iter->second.AddToCount(ColorIt.second);
			}
		}
	}

	for (const auto& Item : Inventory)
	{
		BrickLinkFile.WriteLine("  <ITEM>\n");
		BrickLinkFile.WriteLine("    <ITEMTYPE>P</ITEMTYPE>\n");
		sprintf(Line, "    <ITEMID>%s</ITEMID>\n", Item.second.mId.c_str());
		BrickLinkFile.WriteLine(Line);

		sprintf(Line, "    <MINQTY>%d</MINQTY>\n", Item.second.mCount);
		BrickLinkFile.WriteLine(Line);

		if (Item.second.mColor)
		{
			sprintf(Line, "    <COLOR>%d</COLOR>\n", Item.second.mColor);
			BrickLinkFile.WriteLine(Line);
		}

		BrickLinkFile.WriteLine("  </ITEM>\n");
	}

	BrickLinkFile.WriteLine("</INVENTORY>\n");
}