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 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
10 // JLH = James L. Hammons <jlhamm@acm.org>
13 // --- ---------- -----------------------------------------------------------
14 // JLH 05/10/2010 Created this file. :-)
15 // JLH 08/28/2010 Restored functionality to library browser
18 #include "librarywidget.h"
20 #include "actionhandler.h"
21 #include "actionlibraryinsert.h"
23 #include "rs_staticgraphicview.h"
24 #include "rs_system.h"
25 #include "paintinterface.h"
27 LibraryWidget::LibraryWidget(QWidget * parent/*= 0*/, Qt::WindowFlags flags/*= 0*/):
28 QWidget(parent, flags), actionHandler(NULL)
31 std::cout << "LibraryWidget::LibraryWidget()" << std::endl;
34 ui.lvDirectory->setColumnCount(1);
36 QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
38 std::cout << "directorySize = " << directoryList.size() << std::endl;
40 for(int i=0; i<directoryList.size(); i++)
41 std::cout << directoryList.at(i).toLocal8Bit().constData() << std::endl;
46 for(QStringList::Iterator it=directoryList.begin(); it!=directoryList.end(); it++)
47 appendTree(NULL, (*it));
50 LibraryWidget::~LibraryWidget()
54 void LibraryWidget::setActionHandler(ActionHandler * ah)
60 * Escape releases focus.
62 void LibraryWidget::keyPressEvent(QKeyEvent * e)
71 QWidget::keyPressEvent(e);
79 void LibraryWidget::insert()
81 QListWidgetItem * item = ui.ivPreview->currentItem();
82 QString dxfPath = getItemPath(item);
84 if (QFileInfo(dxfPath).isReadable())
88 ActionInterface * a = actionHandler->setCurrentAction(RS2::ActionLibraryInsert);
92 ActionLibraryInsert * action = (ActionLibraryInsert *)a;
93 action->setFile(dxfPath);
97 RS_DEBUG->print(RS_Debug::D_ERROR, "LibraryWidget::insert:"
98 "Cannot create action ActionLibraryInsert");
104 RS_DEBUG->print(RS_Debug::D_ERROR,
105 "LibraryWidget::insert: Can't read file: '%s'", dxfPath.toLatin1().data());
110 * Appends the given directory to the given list view item. Called recursively until all
111 * library directories are appended.
113 void LibraryWidget::appendTree(QTreeWidgetItem * item, QString directory)
120 // read subdirectories of this directory:
121 QStringList lDirectoryList = dir.entryList(QDir::Dirs, QDir::Name);
123 for(QStringList::Iterator it=lDirectoryList.begin(); it!=lDirectoryList.end(); it++)
125 if ((*it) != "." && (*it) != "..")
127 // Look for an item already existing and take this instead of
129 QTreeWidgetItem * newItem = NULL;
130 QTreeWidgetItem * searchItem =
131 (item ? item->child(0) : ui.lvDirectory->topLevelItem(0));
135 for(int i=0; i<searchItem->childCount(); i++)
137 if (searchItem->child(i)->text(0) == (*it))
139 newItem = searchItem->child(i);
145 // Create new item if no existing was found:
150 newItem = (item ? new QTreeWidgetItem(item, list) : new QTreeWidgetItem(ui.lvDirectory, list));
153 appendTree(newItem, directory + "/" + (*it));
159 * Updates the icon preview.
161 void LibraryWidget::updatePreview(QTreeWidgetItem * item, int /*column*/)
166 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
168 // dir from the point of view of the library browser (e.g. /mechanical/screws)
169 QString directory = getItemDir(item);
170 ui.ivPreview->clear();
172 // List of all directories that contain part libraries:
173 QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
174 QStringList::Iterator it;
176 QStringList itemPathList;
180 // Look in all possible system directories for DXF files in the current library path:
181 for(it=directoryList.begin(); it!=directoryList.end(); ++it)
183 itemDir.setPath((*it) + directory);
185 if (itemDir.exists())
187 QStringList itemNameList = itemDir.entryList(filter, QDir::Files, QDir::Name);
188 QStringList::Iterator it2;
190 for(it2=itemNameList.begin(); it2!=itemNameList.end(); ++it2)
191 itemPathList += itemDir.path() + "/" + (*it2);
198 // Fill items into icon view:
199 QListWidgetItem * newItem;
201 for(it=itemPathList.begin(); it!=itemPathList.end(); ++it)
203 // QString label = QFileInfo(*it).baseName(true);
204 QString label = QFileInfo(*it).completeBaseName();
205 QPixmap pixmap = getPixmap(directory, QFileInfo(*it).fileName(), (*it));
206 // newItem = new QListWidgetItem(ui.ivPreview, label, pixmap);
207 newItem = new QListWidgetItem(QIcon(pixmap), label, ui.ivPreview);
208 //Doesn't do what we want...
209 // newItem->setSizeHint(QSize(64, 64));
212 QApplication::restoreOverrideCursor();
216 * @return Directory (in terms of the List view) to the given item (e.g. /mechanical/screws)
217 * (called recursively)
219 QString LibraryWidget::getItemDir(QTreeWidgetItem * item)
224 QTreeWidgetItem * parent = item->parent();
226 return getItemDir(parent) + QString("/%1").arg(item->text(0));
230 * @return Path of the DXF file that is represented by the given item.
232 QString LibraryWidget::getItemPath(QListWidgetItem * item)
234 QString dir = getItemDir(ui.lvDirectory->currentItem());
238 // List of all directories that contain part libraries:
239 QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
240 QStringList::Iterator it;
243 // Look in all possible system directories for DXF files in the current library path:
244 for(it=directoryList.begin(); it!=directoryList.end(); ++it)
246 itemDir.setPath((*it) + dir);
248 if (itemDir.exists())
250 QString f = (*it) + dir + "/" + item->text() + ".dxf";
252 if (QFileInfo(f).isReadable())
262 * @return Pixmap that serves as icon for the given DXF File.
263 * The existing PNG file is returned or created and returned..
265 * @param dir Library directory (e.g. "/mechanical/screws")
266 * @param dxfFile File name (e.g. "screw1.dxf")
267 * @param dxfPath Full path to the existing DXF file on disk
268 * (e.g. /home/tux/.qcad/library/mechanical/screws/screw1.dxf)
270 QPixmap LibraryWidget::getPixmap(const QString & dir, const QString & dxfFile,
271 const QString & dxfPath)
273 QString pngFile = getPathToPixmap(dir, dxfFile, dxfPath);
274 QFileInfo fiPng(pngFile);
276 // Found existing thumbnail:
278 return QPixmap(pngFile);
279 // Default thumbnail:
281 return QPixmap(64, 64);
285 * @return Path to the thumbnail of the given DXF file. If no thumbnail exists, one is
286 * created in the user's home. If no thumbnail can be created, an empty string is returned.
288 QString LibraryWidget::getPathToPixmap(const QString & dir, const QString & dxfFile,
289 const QString & dxfPath)
291 RS_DEBUG->print("LibraryWidget::getPathToPixmap: dir: '%s' dxfFile: '%s' dxfPath: '%s'",
292 dir.toLatin1().data(), dxfFile.toLatin1().data(), dxfPath.toLatin1().data());
294 // List of all directories that contain part libraries:
295 QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
296 directoryList.prepend(RS_SYSTEM->getHomeDir() + "/.qcad/library");
297 QStringList::Iterator it;
299 QFileInfo fiDxf(dxfPath);
303 // look in all possible system directories for PNG files
304 // in the current library path:
305 for(it=directoryList.begin(); it!=directoryList.end(); ++it)
307 itemDir = (*it) + dir;
308 // pngPath = itemDir + "/" + fiDxf.baseName(true) + ".png";
309 pngPath = itemDir + "/" + fiDxf.completeBaseName() + ".png";
310 RS_DEBUG->print("LibraryWidget::getPathToPixmap: checking: '%s'",
311 pngPath.toLatin1().data());
312 QFileInfo fiPng(pngPath);
314 // the thumbnail exists:
317 RS_DEBUG->print("LibraryWidget::getPathToPixmap: dxf date: %s, png date: %s",
318 fiDxf.lastModified().toString().toLatin1().data(), fiPng.lastModified().toString().toLatin1().data());
320 if (fiPng.lastModified() > fiDxf.lastModified())
322 RS_DEBUG->print("LibraryWidget::getPathToPixmap: thumbnail found: '%s'",
323 pngPath.toLatin1().data());
328 RS_DEBUG->print("LibraryWidget::getPathToPixmap: thumbnail needs to be updated: '%s'",
329 pngPath.toLatin1().data());
334 // the thumbnail must be created in the user's home.
336 // create all directories needed:
337 RS_SYSTEM->createHomePath("/.qcad/library" + dir);
338 /*QString d = "/.qcad/library" + dir;
341 QStringList dirs = QStringList::split('/', d, false);
342 QString created = RS_SYSTEM->getHomeDir();
343 for (it=dirs.begin(); it!=dirs.end(); ++it) {
344 created += QString("/%1").arg(*it);
346 if (created.isEmpty() || QFileInfo(created).isDir() || dr.mkdir(created, true)) {
347 RS_DEBUG->print("LibraryWidget: Created directory '%s'",
348 created.toLatin1().data());
351 RS_DEBUG->print(RS_Debug::D_ERROR,
352 "LibraryWidget: Cannot create directory '%s'",
353 created.toLatin1().data());
359 QString d = RS_SYSTEM->getHomeDir() + "/.qcad/library" + dir;
361 // pngPath = d + "/" + fiDxf.baseName(true) + ".png";
362 pngPath = d + "/" + fiDxf.completeBaseName() + ".png";
364 QPixmap * buffer = new QPixmap(128, 128);
365 // RS_PainterQt * painter = new RS_PainterQt(buffer);
366 QPainter qpntr(buffer);
367 PaintInterface * painter = new PaintInterface(&qpntr);
368 // painter->setBackgroundColor(RS_Color(255, 255, 255));
369 // painter->eraseRect(0, 0, 128, 128);
370 // qpntr.setBackgroundColor(RS_Color(255, 255, 255));
371 qpntr.setBackground(Qt::white);
372 qpntr.eraseRect(0, 0, 128, 128);
374 RS_StaticGraphicView gv(128, 128, painter);
377 if (graphic.open(dxfPath, RS2::FormatUnknown))
379 RS_Color black(0, 0, 0);
381 for(RS_Entity * e=graphic.firstEntity(RS2::ResolveAll); e!=NULL; e=graphic.nextEntity(RS2::ResolveAll))
383 RS_Pen pen = e->getPen();
388 gv.setContainer(&graphic);
390 gv.drawEntity(&graphic, true);
396 img = img.smoothScale(64, 64);
398 iio.setFileName(pngPath);
399 iio.setFormat("PNG");
404 RS_DEBUG->print(RS_Debug::D_ERROR,
405 "LibraryWidget::getPathToPixmap: Cannot write thumbnail: '%s'",
406 pngPath.toLatin1().data());
409 #warning "LibraryWidget::getPathToPixmap(): Needs porting to Qt4... !!! FIX !!!"
414 RS_DEBUG->print(RS_Debug::D_ERROR, "LibraryWidget::getPathToPixmap: Cannot open file: '%s'", dxfPath.toLatin1().data());