]> Shamusworld >> Repos - architektonas/blob - src/forms/librarywidget.cpp
193914e9941e8158fddbdb5cd6a6925814817e5d
[architektonas] / src / forms / librarywidget.cpp
1 // librarywidget.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
7 //
8 // JLH = James L. Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
11 // ---  ----------  -----------------------------------------------------------
12 // JLH  05/10/2010  Created this file. :-)
13 //
14
15 #include "librarywidget.h"
16
17 #include "rs_graphic.h"
18 #include "rs_staticgraphicview.h"
19 #include "rs_system.h"
20 #include "paintintf.h"
21
22 LibraryWidget::LibraryWidget(QWidget * parent/*= 0*/, Qt::WindowFlags flags/*= 0*/):
23         QWidget(parent, flags), actionHandler(NULL)
24 {
25         ui.setupUi(this);
26
27         QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
28
29         for(QStringList::Iterator it = directoryList.begin(); it!=directoryList.end(); ++it)
30                 appendTree(NULL, (*it));
31 }
32
33 LibraryWidget::~LibraryWidget()
34 {
35 }
36
37 void LibraryWidget::setActionHandler(QG_ActionHandler * ah)
38 {
39         actionHandler = ah;
40 }
41
42 /**
43  * Escape releases focus.
44  */
45 void LibraryWidget::keyPressEvent(QKeyEvent * e)
46 {
47         switch (e->key())
48         {
49         case Qt::Key_Escape:
50                 emit escape();
51                 break;
52
53         default:
54                 QWidget::keyPressEvent(e);
55                 break;
56         }
57 }
58
59 /**
60 * Insert.
61 */
62 void LibraryWidget::insert()
63 {
64 #if 0
65 //      Q3IconViewItem * item = ivPreview->currentItem();
66         QListWidgetItem * item = ivPreview->currentItem();
67         QString dxfPath = getItemPath(item);
68
69         if (QFileInfo(dxfPath).isReadable())
70         {
71                 if (actionHandler != NULL)
72                 {
73                         RS_ActionInterface * a = actionHandler->setCurrentAction(RS2::ActionLibraryInsert);
74
75                         if (a != NULL)
76                         {
77                                 RS_ActionLibraryInsert * action = (RS_ActionLibraryInsert *)a;
78                                 action->setFile(dxfPath);
79                         }
80                         else
81                         {
82                                 RS_DEBUG->print(RS_Debug::D_ERROR, "LibraryWidget::insert:"
83                                         "Cannot create action RS_ActionLibraryInsert");
84                         }
85                 }
86         }
87         else
88         {
89                 RS_DEBUG->print(RS_Debug::D_ERROR,
90                         "LibraryWidget::insert: Can't read file: '%s'", dxfPath.toLatin1().data());
91         }
92 #else
93 #warning "!!! Need to port to Qt4 !!!"
94 #endif
95 }
96
97 /**
98 * Appends the given directory to the given list view item. Called recursively until all
99 * library directories are appended.
100 */
101 void LibraryWidget::appendTree(QG_ListViewItem * item, QString directory)
102 {
103 #if 0
104         QStringList::Iterator it;
105         QDir dir(directory);
106
107         // read subdirectories of this directory:
108         if (dir.exists())
109         {
110                 QStringList lDirectoryList = dir.entryList(QDir::Dirs, QDir::Name);
111
112                 QG_ListViewItem* newItem;
113                 QG_ListViewItem* searchItem;
114
115                 for(it=lDirectoryList.begin(); it!=lDirectoryList.end(); ++it)
116                 {
117                         if ((*it) != "." && (*it) != "..")
118                         {
119                                 newItem = NULL;
120
121                                 // Look for an item already existing and take this
122                                 //   instead of making a new one:
123                                 if (item != NULL)
124                                         searchItem = (QG_ListViewItem *)item->firstChild();
125                                 else
126                                         searchItem = (QG_ListViewItem *)lvDirectory->firstChild();
127
128                                 while (searchItem != NULL)
129                                 {
130                                         if (searchItem->text(0) == (*it))
131                                         {
132                                                 newItem=searchItem;
133                                                 break;
134                                         }
135
136                                         searchItem = (QG_ListViewItem *)searchItem->nextSibling();
137                                 }
138
139                                 // Create new item if no existing was found:
140                                 if (newItem == NULL)
141                                 {
142                                         if (item)
143                                                 newItem = new QG_ListViewItem(item, (*it));
144                                         else
145                                                 newItem = new QG_ListViewItem(lvDirectory, (*it));
146                                 }
147
148                                 appendTree(newItem, directory + "/" + (*it));
149                         }
150                 }
151         }
152 #else
153 #warning "!!! Need to port to Qt4 !!!"
154 #endif
155 }
156
157 /**
158 * Updates the icon preview.
159 */
160 //void LibraryWidget::updatePreview(Q3ListViewItem * item)
161 void LibraryWidget::updatePreview(QListWidgetItem * item)
162 {
163 #if 0
164         if (item == NULL)
165                 return;
166
167         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
168
169         // dir from the point of view of the library browser (e.g. /mechanical/screws)
170         QString directory = getItemDir(item);
171         ivPreview->clear();
172
173         // List of all directories that contain part libraries:
174         QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
175         QStringList::Iterator it;
176         QDir itemDir;
177         QStringList itemPathList;
178
179         // look in all possible system directories for DXF files in the current library path:
180         for(it=directoryList.begin(); it!=directoryList.end(); ++it)
181         {
182                 itemDir.setPath((*it) + directory);
183
184                 if (itemDir.exists())
185                 {
186                         QStringList itemNameList = itemDir.entryList("*.dxf", QDir::Files, QDir::Name);
187                         QStringList::Iterator it2;
188
189                         for(it2=itemNameList.begin(); it2!=itemNameList.end(); ++it2)
190                                 itemPathList += itemDir.path() + "/" + (*it2);
191                 }
192         }
193
194         // Sort entries:
195         itemPathList.sort();
196
197         // Fill items into icon view:
198         Q3IconViewItem * newItem;
199         for(it=itemPathList.begin(); it!=itemPathList.end(); ++it)
200         {
201                 QString label = QFileInfo(*it).baseName(true);
202                 QPixmap pixmap = getPixmap(directory, QFileInfo(*it).fileName(), (*it));
203                 newItem = new Q3IconViewItem(ivPreview, label, pixmap);
204         }
205
206         QApplication::restoreOverrideCursor();
207 #else
208 #warning "!!! Need to port to Qt4 !!!"
209 #endif
210 }
211
212 /**
213 * @return Directory (in terms of the List view) to the given item (e.g. /mechanical/screws)
214 */
215 //QString LibraryWidget::getItemDir(Q3ListViewItem * item)
216 QString LibraryWidget::getItemDir(QListWidgetItem * item)
217 {
218 #if 0
219         QString ret = "";
220
221         if (item == NULL)
222                 return ret;
223
224         Q3ListViewItem* parent = item->parent();
225         return getItemDir(parent) + QString("/%1").arg(item->text(0));
226 #else
227 #warning "!!! Need to port to Qt4 !!!"
228         return "";
229 #endif
230 }
231
232 /**
233 * @return Path of the DXF file that is represented by the given item.
234 */
235 //QString LibraryWidget::getItemPath(Q3IconViewItem * item)
236 QString LibraryWidget::getItemPath(QListWidgetItem * item)
237 {
238 #if 0
239         QString dir = getItemDir(lvDirectory->currentItem());
240
241         if (item != NULL)
242         {
243                 // List of all directories that contain part libraries:
244                 QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
245                 QStringList::Iterator it;
246                 QDir itemDir;
247
248                 // look in all possible system directories for DXF files in the current library path:
249                 for(it=directoryList.begin(); it!=directoryList.end(); ++it)
250                 {
251                         itemDir.setPath((*it)+dir);
252
253                         if (itemDir.exists())
254                         {
255                                 QString f = (*it) + dir + "/" + item->text() + ".dxf";
256
257                                 if (QFileInfo(f).isReadable())
258                                         return f;
259                         }
260                 }
261
262                 return "";
263         }
264         else
265         {
266                 return "";
267         }
268 #else
269 #warning "!!! Need to port to Qt4 !!!"
270         return "";
271 #endif
272 }
273
274 /**
275 * @return Pixmap that serves as icon for the given DXF File.
276 * The existing PNG file is returned or created and returned..
277 *
278 * @param dir Library directory (e.g. "/mechanical/screws")
279 * @param dxfFile File name (e.g. "screw1.dxf")
280 * @param dxfPath Full path to the existing DXF file on disk
281 *                          (e.g. /home/tux/.qcad/library/mechanical/screws/screw1.dxf)
282 */
283 QPixmap LibraryWidget::getPixmap(const QString & dir, const QString & dxfFile,
284         const QString & dxfPath)
285 {
286         QString pngFile = getPathToPixmap(dir, dxfFile, dxfPath);
287         QFileInfo fiPng(pngFile);
288
289         // found existing thumbnail:
290         if (fiPng.isFile())
291                 return QPixmap(pngFile);
292         // default thumbnail:
293         else
294                 return QPixmap(64, 64);
295 }
296
297 /**
298 * @return Path to the thumbnail of the given DXF file. If no thumbnail exists, one is
299 * created in the user's home. If no thumbnail can be created, an empty string is returned.
300 */
301 QString LibraryWidget::getPathToPixmap(const QString & dir, const QString & dxfFile,
302         const QString & dxfPath)
303 {
304         RS_DEBUG->print("LibraryWidget::getPathToPixmap: dir: '%s' dxfFile: '%s' dxfPath: '%s'",
305                 dir.toLatin1().data(), dxfFile.toLatin1().data(), dxfPath.toLatin1().data());
306
307         // List of all directories that contain part libraries:
308         QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
309         directoryList.prepend(RS_SYSTEM->getHomeDir() + "/.qcad/library");
310         QStringList::Iterator it;
311
312         QFileInfo fiDxf(dxfPath);
313         QString itemDir;
314         QString pngPath;
315
316         // look in all possible system directories for PNG files
317         //  in the current library path:
318         for(it=directoryList.begin(); it!=directoryList.end(); ++it)
319         {
320                 itemDir = (*it) + dir;
321 //              pngPath = itemDir + "/" + fiDxf.baseName(true) + ".png";
322                 pngPath = itemDir + "/" + fiDxf.completeBaseName() + ".png";
323                 RS_DEBUG->print("LibraryWidget::getPathToPixmap: checking: '%s'",
324                         pngPath.toLatin1().data());
325                 QFileInfo fiPng(pngPath);
326
327                 // the thumbnail exists:
328                 if (fiPng.isFile())
329                 {
330                         RS_DEBUG->print("LibraryWidget::getPathToPixmap: dxf date: %s, png date: %s",
331                                 fiDxf.lastModified().toString().toLatin1().data(), fiPng.lastModified().toString().toLatin1().data());
332
333                         if (fiPng.lastModified() > fiDxf.lastModified())
334                         {
335                                 RS_DEBUG->print("LibraryWidget::getPathToPixmap: thumbnail found: '%s'",
336                                         pngPath.toLatin1().data());
337                                 return pngPath;
338                         }
339                         else
340                         {
341                                 RS_DEBUG->print("LibraryWidget::getPathToPixmap: thumbnail needs to be updated: '%s'",
342                                         pngPath.toLatin1().data());
343                         }
344                 }
345         }
346
347         // the thumbnail must be created in the user's home.
348
349         // create all directories needed:
350         RS_SYSTEM->createHomePath("/.qcad/library" + dir);
351         /*QString d = "/.qcad/library" + dir;
352         QDir dr;
353
354         QStringList dirs = QStringList::split('/', d, false);
355         QString created = RS_SYSTEM->getHomeDir();
356         for (it=dirs.begin(); it!=dirs.end(); ++it) {
357                 created += QString("/%1").arg(*it);
358
359                 if (created.isEmpty() || QFileInfo(created).isDir() || dr.mkdir(created, true)) {
360         RS_DEBUG->print("LibraryWidget: Created directory '%s'",
361         created.toLatin1().data());
362                 }
363                 else {
364         RS_DEBUG->print(RS_Debug::D_ERROR,
365         "LibraryWidget: Cannot create directory '%s'",
366         created.toLatin1().data());
367                         return "";
368                 }
369 }
370         */
371
372         QString d = RS_SYSTEM->getHomeDir() + "/.qcad/library" + dir;
373
374 //      pngPath = d + "/" + fiDxf.baseName(true) + ".png";
375         pngPath = d + "/" + fiDxf.completeBaseName() + ".png";
376
377         QPixmap * buffer = new QPixmap(128, 128);
378 //      RS_PainterQt * painter = new RS_PainterQt(buffer);
379         QPainter qpntr(buffer);
380         PaintInterface * painter = new PaintInterface(&qpntr);
381 //      painter->setBackgroundColor(RS_Color(255, 255, 255));
382 //      painter->eraseRect(0, 0, 128, 128);
383 //      qpntr.setBackgroundColor(RS_Color(255, 255, 255));
384         qpntr.setBackground(Qt::white);
385         qpntr.eraseRect(0, 0, 128, 128);
386
387         RS_StaticGraphicView gv(128, 128, painter);
388         RS_Graphic graphic;
389
390         if (graphic.open(dxfPath, RS2::FormatUnknown))
391         {
392                 RS_Color black(0, 0, 0);
393
394                 for(RS_Entity * e=graphic.firstEntity(RS2::ResolveAll); e!=NULL; e=graphic.nextEntity(RS2::ResolveAll))
395                 {
396                         RS_Pen pen = e->getPen();
397                         pen.setColor(black);
398                         e->setPen(pen);
399                 }
400
401                 gv.setContainer(&graphic);
402                 gv.zoomAuto(false);
403                 gv.drawEntity(&graphic, true);
404
405 #warning "Needs porting to Qt4... !!! FIX !!!"
406 #if 0
407                 QImageIO iio;
408                 QImage img;
409                 img = *buffer;
410                 img = img.smoothScale(64, 64);
411                 iio.setImage(img);
412                 iio.setFileName(pngPath);
413                 iio.setFormat("PNG");
414
415                 if (!iio.write())
416                 {
417                         pngPath = "";
418                         RS_DEBUG->print(RS_Debug::D_ERROR,
419                                 "LibraryWidget::getPathToPixmap: Cannot write thumbnail: '%s'",
420                                 pngPath.toLatin1().data());
421                 }
422 #endif
423         }
424         else
425         {
426                 RS_DEBUG->print(RS_Debug::D_ERROR, "LibraryWidget::getPathToPixmap: Cannot open file: '%s'",
427                         dxfPath.toLatin1().data());
428         }
429
430         // GraphicView deletes painter
431 //      painter->end();
432         // No, it doesn't
433         delete painter;
434         delete buffer;
435
436         return pngPath;
437 }