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
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/10/2010 Created this file. :-)
15 #include "librarywidget.h"
18 #include "rs_staticgraphicview.h"
19 #include "rs_system.h"
20 #include "paintinterface.h"
22 LibraryWidget::LibraryWidget(QWidget * parent/*= 0*/, Qt::WindowFlags flags/*= 0*/):
23 QWidget(parent, flags), actionHandler(NULL)
27 QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
29 for(QStringList::Iterator it = directoryList.begin(); it!=directoryList.end(); ++it)
30 appendTree(NULL, (*it));
33 LibraryWidget::~LibraryWidget()
37 void LibraryWidget::setActionHandler(QG_ActionHandler * ah)
43 * Escape releases focus.
45 void LibraryWidget::keyPressEvent(QKeyEvent * e)
54 QWidget::keyPressEvent(e);
62 void LibraryWidget::insert()
65 // Q3IconViewItem * item = ivPreview->currentItem();
66 QListWidgetItem * item = ivPreview->currentItem();
67 QString dxfPath = getItemPath(item);
69 if (QFileInfo(dxfPath).isReadable())
71 if (actionHandler != NULL)
73 ActionInterface * a = actionHandler->setCurrentAction(RS2::ActionLibraryInsert);
77 ActionLibraryInsert * action = (ActionLibraryInsert *)a;
78 action->setFile(dxfPath);
82 RS_DEBUG->print(RS_Debug::D_ERROR, "LibraryWidget::insert:"
83 "Cannot create action ActionLibraryInsert");
89 RS_DEBUG->print(RS_Debug::D_ERROR,
90 "LibraryWidget::insert: Can't read file: '%s'", dxfPath.toLatin1().data());
93 #warning "!!! Need to port to Qt4 !!!"
98 * Appends the given directory to the given list view item. Called recursively until all
99 * library directories are appended.
101 void LibraryWidget::appendTree(QG_ListViewItem * item, QString directory)
104 QStringList::Iterator it;
107 // read subdirectories of this directory:
110 QStringList lDirectoryList = dir.entryList(QDir::Dirs, QDir::Name);
112 QG_ListViewItem* newItem;
113 QG_ListViewItem* searchItem;
115 for(it=lDirectoryList.begin(); it!=lDirectoryList.end(); ++it)
117 if ((*it) != "." && (*it) != "..")
121 // Look for an item already existing and take this
122 // instead of making a new one:
124 searchItem = (QG_ListViewItem *)item->firstChild();
126 searchItem = (QG_ListViewItem *)lvDirectory->firstChild();
128 while (searchItem != NULL)
130 if (searchItem->text(0) == (*it))
136 searchItem = (QG_ListViewItem *)searchItem->nextSibling();
139 // Create new item if no existing was found:
143 newItem = new QG_ListViewItem(item, (*it));
145 newItem = new QG_ListViewItem(lvDirectory, (*it));
148 appendTree(newItem, directory + "/" + (*it));
153 #warning "!!! Need to port to Qt4 !!!"
158 * Updates the icon preview.
160 //void LibraryWidget::updatePreview(Q3ListViewItem * item)
161 void LibraryWidget::updatePreview(QListWidgetItem * item)
167 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
169 // dir from the point of view of the library browser (e.g. /mechanical/screws)
170 QString directory = getItemDir(item);
173 // List of all directories that contain part libraries:
174 QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
175 QStringList::Iterator it;
177 QStringList itemPathList;
179 // look in all possible system directories for DXF files in the current library path:
180 for(it=directoryList.begin(); it!=directoryList.end(); ++it)
182 itemDir.setPath((*it) + directory);
184 if (itemDir.exists())
186 QStringList itemNameList = itemDir.entryList("*.dxf", QDir::Files, QDir::Name);
187 QStringList::Iterator it2;
189 for(it2=itemNameList.begin(); it2!=itemNameList.end(); ++it2)
190 itemPathList += itemDir.path() + "/" + (*it2);
197 // Fill items into icon view:
198 Q3IconViewItem * newItem;
199 for(it=itemPathList.begin(); it!=itemPathList.end(); ++it)
201 QString label = QFileInfo(*it).baseName(true);
202 QPixmap pixmap = getPixmap(directory, QFileInfo(*it).fileName(), (*it));
203 newItem = new Q3IconViewItem(ivPreview, label, pixmap);
206 QApplication::restoreOverrideCursor();
208 #warning "!!! Need to port to Qt4 !!!"
213 * @return Directory (in terms of the List view) to the given item (e.g. /mechanical/screws)
215 //QString LibraryWidget::getItemDir(Q3ListViewItem * item)
216 QString LibraryWidget::getItemDir(QListWidgetItem * item)
224 Q3ListViewItem* parent = item->parent();
225 return getItemDir(parent) + QString("/%1").arg(item->text(0));
227 #warning "!!! Need to port to Qt4 !!!"
233 * @return Path of the DXF file that is represented by the given item.
235 //QString LibraryWidget::getItemPath(Q3IconViewItem * item)
236 QString LibraryWidget::getItemPath(QListWidgetItem * item)
239 QString dir = getItemDir(lvDirectory->currentItem());
243 // List of all directories that contain part libraries:
244 QStringList directoryList = RS_SYSTEM->getDirectoryList("library");
245 QStringList::Iterator it;
248 // look in all possible system directories for DXF files in the current library path:
249 for(it=directoryList.begin(); it!=directoryList.end(); ++it)
251 itemDir.setPath((*it)+dir);
253 if (itemDir.exists())
255 QString f = (*it) + dir + "/" + item->text() + ".dxf";
257 if (QFileInfo(f).isReadable())
269 #warning "!!! Need to port to Qt4 !!!"
275 * @return Pixmap that serves as icon for the given DXF File.
276 * The existing PNG file is returned or created and returned..
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)
283 QPixmap LibraryWidget::getPixmap(const QString & dir, const QString & dxfFile,
284 const QString & dxfPath)
286 QString pngFile = getPathToPixmap(dir, dxfFile, dxfPath);
287 QFileInfo fiPng(pngFile);
289 // found existing thumbnail:
291 return QPixmap(pngFile);
292 // default thumbnail:
294 return QPixmap(64, 64);
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.
301 QString LibraryWidget::getPathToPixmap(const QString & dir, const QString & dxfFile,
302 const QString & dxfPath)
304 RS_DEBUG->print("LibraryWidget::getPathToPixmap: dir: '%s' dxfFile: '%s' dxfPath: '%s'",
305 dir.toLatin1().data(), dxfFile.toLatin1().data(), dxfPath.toLatin1().data());
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;
312 QFileInfo fiDxf(dxfPath);
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)
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);
327 // the thumbnail exists:
330 RS_DEBUG->print("LibraryWidget::getPathToPixmap: dxf date: %s, png date: %s",
331 fiDxf.lastModified().toString().toLatin1().data(), fiPng.lastModified().toString().toLatin1().data());
333 if (fiPng.lastModified() > fiDxf.lastModified())
335 RS_DEBUG->print("LibraryWidget::getPathToPixmap: thumbnail found: '%s'",
336 pngPath.toLatin1().data());
341 RS_DEBUG->print("LibraryWidget::getPathToPixmap: thumbnail needs to be updated: '%s'",
342 pngPath.toLatin1().data());
347 // the thumbnail must be created in the user's home.
349 // create all directories needed:
350 RS_SYSTEM->createHomePath("/.qcad/library" + dir);
351 /*QString d = "/.qcad/library" + dir;
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);
359 if (created.isEmpty() || QFileInfo(created).isDir() || dr.mkdir(created, true)) {
360 RS_DEBUG->print("LibraryWidget: Created directory '%s'",
361 created.toLatin1().data());
364 RS_DEBUG->print(RS_Debug::D_ERROR,
365 "LibraryWidget: Cannot create directory '%s'",
366 created.toLatin1().data());
372 QString d = RS_SYSTEM->getHomeDir() + "/.qcad/library" + dir;
374 // pngPath = d + "/" + fiDxf.baseName(true) + ".png";
375 pngPath = d + "/" + fiDxf.completeBaseName() + ".png";
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);
387 RS_StaticGraphicView gv(128, 128, painter);
390 if (graphic.open(dxfPath, RS2::FormatUnknown))
392 RS_Color black(0, 0, 0);
394 for(RS_Entity * e=graphic.firstEntity(RS2::ResolveAll); e!=NULL; e=graphic.nextEntity(RS2::ResolveAll))
396 RS_Pen pen = e->getPen();
401 gv.setContainer(&graphic);
403 gv.drawEntity(&graphic, true);
405 #warning "Needs porting to Qt4... !!! FIX !!!"
410 img = img.smoothScale(64, 64);
412 iio.setFileName(pngPath);
413 iio.setFormat("PNG");
418 RS_DEBUG->print(RS_Debug::D_ERROR,
419 "LibraryWidget::getPathToPixmap: Cannot write thumbnail: '%s'",
420 pngPath.toLatin1().data());
426 RS_DEBUG->print(RS_Debug::D_ERROR, "LibraryWidget::getPathToPixmap: Cannot open file: '%s'",
427 dxfPath.toLatin1().data());
430 // GraphicView deletes painter