| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #include <QApplication> |
| | #include <QDir> |
| | #include <QFileInfo> |
| | #include <QImageWriter> |
| | #include <QKeyEvent> |
| | #include <QListView> |
| | #include <QPushButton> |
| | #include <QStandardItemModel> |
| | #include <QStandardPaths> |
| | #include <QToolButton> |
| | #include <QTreeView> |
| | #include <QVBoxLayout> |
| | #include <QAbstractItemView> |
| |
|
| | #include "qg_librarywidget.h" |
| | #include "lc_containertraverser.h" |
| | #include "lc_documentsstorage.h" |
| | #include "lc_graphicviewport.h" |
| | #include "lc_printviewportrenderer.h" |
| | #include "qg_actionhandler.h" |
| | #include "rs_actioninterface.h" |
| | #include "rs_actionlibraryinsert.h" |
| | #include "rs_debug.h" |
| | #include "rs_graphic.h" |
| | #include "rs_painter.h" |
| | #include "rs_settings.h" |
| | #include "rs_system.h" |
| |
|
| | namespace { |
| | |
| | void writePng(const QString& pngPath, QPixmap pixmap) |
| | { |
| | QImageWriter iio; |
| | QImage img = pixmap.toImage(); |
| | img = img.scaled(64,64, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); |
| | |
| | iio.setFileName(pngPath); |
| | iio.setFormat("PNG"); |
| | if (!iio.write(img)) { |
| | RS_DEBUG->print(RS_Debug::D_ERROR, |
| | "QG_LibraryWidget::getPathToPixmap: Cannot write thumbnail: '%s'", |
| | pngPath.toLatin1().data()); |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | QG_LibraryWidget::QG_LibraryWidget(QG_ActionHandler *action_handler, QWidget* parent, const char* name, Qt::WindowFlags fl) |
| | : LC_GraphicViewAwareWidget(parent, name, fl), actionHandler{action_handler}{ |
| | auto vboxLayout = new QVBoxLayout(this); |
| | vboxLayout->setSpacing(2); |
| | vboxLayout->setContentsMargins(2, 2, 2, 2); |
| | dirView = new QTreeView(this); |
| | dirView->setRootIsDecorated(true); |
| | dirView->setEditTriggers(QAbstractItemView::NoEditTriggers); |
| | vboxLayout->addWidget(dirView); |
| | ivPreview = new QListView(this); |
| | ivPreview->setViewMode(QListView::IconMode); |
| | vboxLayout->addWidget(ivPreview); |
| | bInsert = new QPushButton(tr("Insert"), this); |
| | vboxLayout->addWidget(bInsert); |
| |
|
| | QHBoxLayout *refreshButtonsLayout = new QHBoxLayout(); |
| | bRefresh = new QPushButton(tr("Refresh"), this); |
| | refreshButtonsLayout->addWidget(bRefresh); |
| | bRebuild = new QPushButton(tr("Rebuild"), this); |
| | refreshButtonsLayout->addWidget(bRebuild); |
| | vboxLayout->addLayout(refreshButtonsLayout); |
| |
|
| | buildTree(); |
| |
|
| | connect(dirView, &QTreeView::expanded, this, &QG_LibraryWidget::expandView); |
| | connect(dirView, &QTreeView::collapsed, this, &QG_LibraryWidget::collapseView); |
| | connect(dirView, &QTreeView::clicked, this, &QG_LibraryWidget::updatePreview); |
| | connect(bInsert, &QPushButton::clicked, this, &QG_LibraryWidget::insert); |
| | connect(bRefresh, &QPushButton::clicked, this, &QG_LibraryWidget::refresh); |
| | connect(bRebuild, &QPushButton::clicked, this, &QG_LibraryWidget::buildTree); |
| |
|
| | updateWidgetSettings(); |
| | } |
| |
|
| | QG_LibraryWidget::~QG_LibraryWidget() = default; |
| |
|
| | void QG_LibraryWidget::setGraphicView([[maybe_unused]]RS_GraphicView* gview) { |
| | |
| | } |
| |
|
| | void QG_LibraryWidget::setActionHandler(QG_ActionHandler* ah) { |
| | actionHandler = ah; |
| | } |
| |
|
| | |
| | |
| | |
| | void QG_LibraryWidget::keyPressEvent(QKeyEvent* e) { |
| | switch (e->key()) { |
| | case Qt::Key_Escape: |
| | emit escape(); |
| | break; |
| | default: |
| | QWidget::keyPressEvent(e); |
| | break; |
| | } |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | void QG_LibraryWidget::insert() { |
| | QItemSelectionModel* selIconView = ivPreview->selectionModel(); |
| | QModelIndex idx = selIconView->currentIndex(); |
| | QStandardItem * item = iconModel->itemFromIndex ( idx ); |
| | if (item == nullptr) { |
| | return; |
| | } |
| |
|
| | QString dxfPath = getItemPath(item); |
| |
|
| | if (QFileInfo(dxfPath).isReadable()) { |
| | if (actionHandler) { |
| | std::shared_ptr<RS_ActionInterface> a = |
| | actionHandler->setCurrentAction(RS2::ActionLibraryInsert); |
| | if (a) { |
| | auto* action = static_cast<RS_ActionLibraryInsert*>(a.get()); |
| | action->setFile(std::move(dxfPath)); |
| | } else { |
| | RS_DEBUG->print(RS_Debug::D_ERROR, |
| | "QG_LibraryWidget::insert:" |
| | "Cannot create action RS_ActionLibraryInsert"); |
| | } |
| | } |
| | } else { |
| | RS_DEBUG->print(RS_Debug::D_ERROR, |
| | "QG_LibraryWidget::insert: Can't read file: '%s'", dxfPath.toLatin1().data()); |
| | } |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | void QG_LibraryWidget::refresh() { |
| | scanTree(); |
| | updatePreview(dirView->selectionModel()->currentIndex()); |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | void QG_LibraryWidget::scanTree() { |
| | QStringList directoryList = RS_SYSTEM->getDirectoryList("library"); |
| | foreach(auto& directory, directoryList) { |
| | appendTree(nullptr, directory); |
| | } |
| |
|
| | QString customPath= LC_GET_ONE_STR("Paths", "Library", ""); |
| |
|
| | if(customPath.size()>0){ |
| | |
| | appendTree(nullptr,customPath); |
| | } |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | void QG_LibraryWidget::buildTree() { |
| | dirModel = std::make_unique<QStandardItemModel>(); |
| | iconModel = std::make_unique<QStandardItemModel>(); |
| | scanTree(); |
| | dirView->setModel(dirModel.get()); |
| | ivPreview->setModel(iconModel.get()); |
| | dirModel->setHorizontalHeaderLabels ( QStringList(tr("Directories"))); |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | void QG_LibraryWidget::appendTree(QStandardItem* item, QString directory) { |
| | |
| | QDir dir(directory); |
| |
|
| | if (!dir.exists()) { |
| | return; |
| | } |
| |
|
| | |
| | QStringList lDirectoryList = dir.entryList(QDir::Dirs|QDir::NoDotAndDotDot, QDir::Name); |
| |
|
| | if (!item) item = dirModel->invisibleRootItem(); |
| |
|
| | foreach (const auto& lDirectory, lDirectoryList) { |
| | QStandardItem* newItem=nullptr; |
| |
|
| | |
| | |
| | for (int j = 0; j < item->rowCount(); ++j) { |
| | QStandardItem* const searchItem = item->child (j); |
| | if (searchItem->text() == lDirectory) { |
| | newItem=searchItem; |
| | break; |
| | } |
| | } |
| |
|
| | |
| | if (!newItem) { |
| | newItem = new QStandardItem(QIcon(":/icons/folderclosed.lci"), lDirectory); |
| | item->setChild(item->rowCount(), newItem); |
| | } |
| | appendTree(newItem, directory+QDir::separator()+lDirectory); |
| | } |
| | item->sortChildren ( 0, Qt::AscendingOrder ); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | void QG_LibraryWidget::expandView( QModelIndex idx ){ |
| | QStandardItem * item = dirModel->itemFromIndex ( idx ); |
| | if (item != nullptr) { |
| | item->setIcon(QIcon(":/icons/fileopen.lci")); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | void QG_LibraryWidget::collapseView( QModelIndex idx ){ |
| | QStandardItem * item = dirModel->itemFromIndex ( idx ); |
| | if (item != nullptr) { |
| | item->setIcon(QIcon(":/icons/folderclosed.lci")); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | void QG_LibraryWidget::updatePreview(QModelIndex idx) { |
| | QStandardItem * item = dirModel->itemFromIndex ( idx ); |
| | if (item == nullptr) { |
| | return; |
| | } |
| |
|
| | QApplication::setOverrideCursor( QCursor(Qt::WaitCursor) ); |
| |
|
| | |
| | QString directory = getItemDir(item); |
| | iconModel->clear(); |
| |
|
| | |
| | QStringList directoryList = RS_SYSTEM->getDirectoryList("library"); |
| | QDir itemDir; |
| | QStringList itemPathList; |
| |
|
| | |
| | for (int i = 0; i < directoryList.size(); ++i) { |
| | itemDir.setPath(directoryList.at(i)+directory); |
| |
|
| | if (itemDir.exists()) { |
| | QStringList itemNameList = |
| | itemDir.entryList(QStringList("*.dxf"), QDir::Files, QDir::Name); |
| | for (int j = 0; j < itemNameList.size(); ++j) { |
| | itemPathList += itemDir.path()+QDir::separator()+itemNameList.at(j); |
| | } |
| | } |
| | } |
| |
|
| | |
| | itemPathList.sort(); |
| |
|
| | |
| | for (int i = 0; i < itemPathList.size(); ++i) { |
| | QString label = QFileInfo(itemPathList.at(i)).completeBaseName(); |
| | QIcon icon = getIcon(directory, QFileInfo(itemPathList.at(i)).fileName(), itemPathList.at(i)); |
| | auto newItem = new QStandardItem(icon, label); |
| | iconModel->setItem(i, newItem); |
| | } |
| | QApplication::restoreOverrideCursor(); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | QString QG_LibraryWidget::getItemDir(QStandardItem* item) { |
| | if (item == nullptr) |
| | return {}; |
| |
|
| | QStandardItem* parent = item->parent(); |
| | return getItemDir(parent) + QDir::separator() + QString("%1").arg(item->text()); |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | QString QG_LibraryWidget::getItemPath(QStandardItem* item) { |
| | if (item == nullptr) |
| | return {}; |
| | QItemSelectionModel* selDirView = dirView->selectionModel(); |
| | QModelIndex idx = selDirView->currentIndex(); |
| | QStandardItem * dirItem = dirModel->itemFromIndex ( idx ); |
| | QString dir = getItemDir(dirItem); |
| |
|
| | |
| | QStringList directoryList = RS_SYSTEM->getDirectoryList("library"); |
| |
|
| | |
| | for (auto it=directoryList.begin(); it!=directoryList.end(); ++it) { |
| | QDir itemDir((*it)+dir); |
| | if (itemDir.exists()) { |
| | QString dxfFile = (*it) + dir + QDir::separator() + item->text() + ".dxf"; |
| | if (QFileInfo(dxfFile).isReadable()) { |
| | return dxfFile; |
| | } |
| | } |
| | } |
| |
|
| | return {}; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | QIcon QG_LibraryWidget::getIcon(const QString& dir, const QString& dxfFile, |
| | const QString& dxfPath) { |
| | QString pngFile = getPathToPixmap(dir, dxfFile, dxfPath); |
| | QFileInfo fiPng(pngFile); |
| |
|
| | |
| | if (fiPng.isFile()) { |
| | return QIcon(pngFile); |
| | } |
| | |
| | else { |
| | return QIcon(QPixmap(64,64)); |
| | } |
| | } |
| |
|
| | |
| |
|
| | |
| | |
| | |
| | |
| | QString QG_LibraryWidget::getPathToPixmap(const QString& dir, |
| | const QString& dxfFile, |
| | const QString& dxfPath) { |
| |
|
| | |
| | QString iconCacheLocation=QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QDir::separator() + "iconCache" + QDir::separator(); |
| |
|
| | RS_DEBUG->print("QG_LibraryWidget::getPathToPixmap: " |
| | "dir: '%s' dxfFile: '%s' dxfPath: '%s'", |
| | dir.toLatin1().data(), dxfFile.toLatin1().data(), dxfPath.toLatin1().data()); |
| |
|
| | |
| | QStringList directoryList = RS_SYSTEM->getDirectoryList("library"); |
| | directoryList.prepend(iconCacheLocation); |
| |
|
| | QFileInfo fiDxf(dxfPath); |
| |
|
| | |
| | |
| | foreach (QString path, directoryList) { |
| | QString itemDir = path + dir; |
| | QString pngPath = itemDir + QDir::separator() + fiDxf.baseName() + ".png"; |
| | RS_DEBUG->print("QG_LibraryWidget::getPathToPixmap: checking: '%s'", |
| | pngPath.toLatin1().data()); |
| | QFileInfo fiPng(pngPath); |
| |
|
| | |
| | if (fiPng.isFile()) { |
| | RS_DEBUG->print("QG_LibraryWidget::getPathToPixmap: dxf date: %s, png date: %s", |
| | fiDxf.lastModified().toString().toLatin1().data(), fiPng.lastModified().toString().toLatin1().data()); |
| | if (fiPng.lastModified() > fiDxf.lastModified()) { |
| | RS_DEBUG->print("QG_LibraryWidget::getPathToPixmap: thumbnail found: '%s'", |
| | pngPath.toLatin1().data()); |
| | return pngPath; |
| | } else { |
| | RS_DEBUG->print("QG_LibraryWidget::getPathToPixmap: thumbnail needs to be updated: '%s'", |
| | pngPath.toLatin1().data()); |
| | } |
| | } |
| | } |
| |
|
| | |
| | RS_SYSTEM->createPaths(iconCacheLocation + dir); |
| |
|
| | QString pngPath = iconCacheLocation + dir + QDir::separator() + fiDxf.baseName() + ".png"; |
| |
|
| | QPixmap buffer(128,128); |
| | RS_Painter painter(&buffer); |
| | painter.setBackground(RS_Color(255,255,255)); |
| | painter.eraseRect(0,0, 128,128); |
| |
|
| | LC_GraphicViewport viewport; |
| | viewport.setSize(128,128); |
| |
|
| | RS_Graphic graphic; |
| |
|
| | LC_DocumentsStorage storage; |
| |
|
| | if (!storage.loadDocument(&graphic, dxfPath, RS2::FormatUnknown)) { |
| | RS_DEBUG->print(RS_Debug::D_ERROR, |
| | "QG_LibraryWidget::getPathToPixmap: Cannot open file: '%s'", |
| | dxfPath.toLatin1().data()); |
| | return {}; |
| | } |
| |
|
| | viewport.setContainer(&graphic); |
| | viewport.initAfterDocumentOpen(); |
| | viewport.zoomAuto(false); |
| |
|
| | LC_PrintViewportRenderer renderer(&viewport, &painter); |
| | renderer.loadSettings(); |
| | renderer.setupPainter(&painter); |
| |
|
| | for(RS_Entity* e: lc::LC_ContainerTraverser{graphic, RS2::ResolveAll}.entities()) { |
| | if (e != nullptr && e->rtti() != RS2::EntityHatch) { |
| | RS_Pen pen = e->getPen(); |
| | pen.setColor(Qt::black); |
| | e->setPen(pen); |
| | renderer.justDrawEntity(&painter, e); |
| | } |
| | } |
| |
|
| | |
| | painter.end(); |
| |
|
| | |
| | writePng(pngPath, std::move(buffer)); |
| | LC_LOG << "Writing to " << pngPath << " OK"; |
| | return pngPath; |
| | } |
| |
|
| | void QG_LibraryWidget::updateWidgetSettings(){ |
| | LC_GROUP("Widgets"); { |
| | bool flatIcons = LC_GET_BOOL("DockWidgetsFlatIcons", true); |
| | int iconSize = LC_GET_INT("DockWidgetsIconSize", 16); |
| |
|
| | QSize size(iconSize, iconSize); |
| |
|
| | QList<QToolButton *> widgets = this->findChildren<QToolButton *>(); |
| | foreach(QToolButton *w, widgets) { |
| | w->setAutoRaise(flatIcons); |
| | w->setIconSize(size); |
| | } |
| | } |
| | LC_GROUP_END(); |
| | } |
| |
|