1 /*
2  * LibrePCB - Professional EDA for everyone!
3  * Copyright (C) 2013 LibrePCB Developers, see AUTHORS.md for contributors.
4  * https://librepcb.org/
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 /*******************************************************************************
21  *  Includes
22  ******************************************************************************/
23 #include "componentsymbolvarianteditdialog.h"
24 
25 #include "ui_componentsymbolvarianteditdialog.h"
26 
27 #include <librepcb/common/fileio/transactionalfilesystem.h>
28 #include <librepcb/common/graphics/defaultgraphicslayerprovider.h>
29 #include <librepcb/common/graphics/graphicsscene.h>
30 #include <librepcb/common/norms.h>
31 #include <librepcb/library/cmp/component.h>
32 #include <librepcb/library/cmp/componentsymbolvariant.h>
33 #include <librepcb/library/sym/symbol.h>
34 #include <librepcb/library/sym/symbolgraphicsitem.h>
35 #include <librepcb/libraryeditor/libraryelementcache.h>
36 #include <librepcb/workspace/library/workspacelibrarydb.h>
37 #include <librepcb/workspace/workspace.h>
38 
39 #include <QtCore>
40 #include <QtWidgets>
41 
42 /*******************************************************************************
43  *  Namespace
44  ******************************************************************************/
45 namespace librepcb {
46 namespace library {
47 namespace editor {
48 
49 /*******************************************************************************
50  *  Constructors / Destructor
51  ******************************************************************************/
52 
ComponentSymbolVariantEditDialog(const workspace::Workspace & ws,const Component & cmp,ComponentSymbolVariant & symbVar,QWidget * parent)53 ComponentSymbolVariantEditDialog::ComponentSymbolVariantEditDialog(
54     const workspace::Workspace& ws, const Component& cmp,
55     ComponentSymbolVariant& symbVar, QWidget* parent) noexcept
56   : QDialog(parent),
57     mWorkspace(ws),
58     mComponent(cmp),
59     mOriginalSymbVar(symbVar),
60     mSymbVar(symbVar),
61     mGraphicsScene(new GraphicsScene()),
62     mLibraryElementCache(new LibraryElementCache(ws.getLibraryDb())),
63     mUi(new Ui::ComponentSymbolVariantEditDialog) {
64   mUi->setupUi(this);
65   mUi->cbxNorm->addItems(getAvailableNorms());
66   mUi->graphicsView->setScene(mGraphicsScene.data());
67   mUi->graphicsView->setOriginCrossVisible(false);
68   mGraphicsLayerProvider.reset(new DefaultGraphicsLayerProvider());
69 
70   // load metadata
71   mUi->edtName->setText(*mSymbVar.getNames().getDefaultValue());
72   mUi->edtDescription->setText(mSymbVar.getDescriptions().getDefaultValue());
73   mUi->cbxNorm->setCurrentText(mSymbVar.getNorm());
74 
75   // load symbol items
76   mUi->symbolListWidget->setReferences(mWorkspace, *mGraphicsLayerProvider,
77                                        mSymbVar.getSymbolItems(),
78                                        mLibraryElementCache, nullptr);
79   connect(
80       mUi->symbolListWidget,
81       &ComponentSymbolVariantItemListEditorWidget::triggerGraphicsItemsUpdate,
82       this, &ComponentSymbolVariantEditDialog::updateGraphicsItems);
83   mUi->pinSignalMapEditorWidget->setReferences(
84       &mSymbVar, mLibraryElementCache, &mComponent.getSignals(), nullptr);
85 
86   updateGraphicsItems();
87 }
88 
~ComponentSymbolVariantEditDialog()89 ComponentSymbolVariantEditDialog::~ComponentSymbolVariantEditDialog() noexcept {
90 }
91 
92 /*******************************************************************************
93  *  Setters
94  ******************************************************************************/
95 
setReadOnly(bool readOnly)96 void ComponentSymbolVariantEditDialog::setReadOnly(bool readOnly) noexcept {
97   mUi->edtName->setReadOnly(readOnly);
98   mUi->edtDescription->setReadOnly(readOnly);
99   mUi->cbxNorm->setDisabled(readOnly);
100   mUi->symbolListWidget->setReadOnly(readOnly);
101   mUi->pinSignalMapEditorWidget->setReadOnly(readOnly);
102   if (readOnly) {
103     mUi->buttonBox->setStandardButtons(QDialogButtonBox::StandardButton::Close);
104   } else {
105     mUi->buttonBox->setStandardButtons(
106         QDialogButtonBox::StandardButton::Cancel |
107         QDialogButtonBox::StandardButton::Ok);
108   }
109 }
110 
111 /*******************************************************************************
112  *  Private Methods
113  ******************************************************************************/
114 
accept()115 void ComponentSymbolVariantEditDialog::accept() noexcept {
116   try {
117     ElementName name(mUi->edtName->text().trimmed());  // can throw
118     mSymbVar.setName("", name);
119     mSymbVar.setDescription("", mUi->edtDescription->text().trimmed());
120     mSymbVar.setNorm(mUi->cbxNorm->currentText().trimmed());
121     mOriginalSymbVar = mSymbVar;
122     QDialog::accept();
123   } catch (const Exception& e) {
124     QMessageBox::critical(this, tr("Error"), e.getMsg());
125     return;
126   }
127 }
128 
updateGraphicsItems()129 void ComponentSymbolVariantEditDialog::updateGraphicsItems() noexcept {
130   mGraphicsItems.clear();
131   mSymbols.clear();
132   for (const ComponentSymbolVariantItem& item : mSymbVar.getSymbolItems()) {
133     try {
134       FilePath fp = mWorkspace.getLibraryDb().getLatestSymbol(
135           item.getSymbolUuid());  // can throw
136       std::shared_ptr<Symbol> sym = std::make_shared<Symbol>(
137           std::unique_ptr<TransactionalDirectory>(new TransactionalDirectory(
138               TransactionalFileSystem::openRO(fp))));  // can throw
139       mSymbols.append(sym);
140       std::shared_ptr<SymbolGraphicsItem> graphicsItem =
141           std::make_shared<SymbolGraphicsItem>(*sym, *mGraphicsLayerProvider);
142       graphicsItem->setPosition(item.getSymbolPosition());
143       graphicsItem->setRotation(item.getSymbolRotation());
144       mGraphicsScene->addItem(*graphicsItem);
145       mGraphicsItems.append(graphicsItem);
146     } catch (const Exception& e) {
147       // what could we do here? ;)
148     }
149   }
150   mUi->graphicsView->zoomAll();
151 }
152 
153 /*******************************************************************************
154  *  End of File
155  ******************************************************************************/
156 
157 }  // namespace editor
158 }  // namespace library
159 }  // namespace librepcb
160