Warning, file /sdk/ktechlab/src/flowcodedocument.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /***************************************************************************
0002  *   Copyright (C) 2003-2005 by David Saxton                               *
0003  *   david@bluehaze.org                                                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  ***************************************************************************/
0010 
0011 #include "flowcodedocument.h"
0012 #include "canvasmanipulator.h"
0013 #include "documentiface.h"
0014 #include "drawpart.h"
0015 #include "flowcode.h"
0016 #include "flowcodeview.h"
0017 #include "flowpart.h"
0018 #include "itemdocumentdata.h"
0019 #include "ktechlab.h"
0020 #include "languagemanager.h"
0021 #include "microinfo.h"
0022 #include "microlibrary.h"
0023 #include "outputmethoddlg.h"
0024 #include "picitem.h"
0025 #include "programmerdlg.h"
0026 #include "textdocument.h"
0027 
0028 #include <KLocalizedString>
0029 
0030 #include <ktechlab_debug.h>
0031 
0032 FlowCodeDocument::FlowCodeDocument(const QString &caption)
0033     : FlowICNDocument(caption)
0034 {
0035     m_pDocumentIface = new FlowCodeDocumentIface(this);
0036     m_type = Document::dt_flowcode;
0037     m_microInfo = nullptr;
0038     m_microSettings = nullptr;
0039     m_picItem = nullptr;
0040     m_pLastTextOutputTarget = nullptr;
0041 
0042     m_cmManager->addManipulatorInfo(CMSelect::manipulatorInfo());
0043     m_cmManager->addManipulatorInfo(CMDraw::manipulatorInfo());
0044     m_cmManager->addManipulatorInfo(CMRightClick::manipulatorInfo());
0045     m_cmManager->addManipulatorInfo(CMRepeatedItemAdd::manipulatorInfo());
0046     m_cmManager->addManipulatorInfo(CMItemResize::manipulatorInfo());
0047     m_cmManager->addManipulatorInfo(CMItemDrag::manipulatorInfo());
0048 
0049     m_fileExtensionInfo = QString("*.flowcode|FlowCode (*.flowcode)\n*|%1").arg(i18n("All Files"));
0050     m_fileExtensionValue = QString(".flowcode");
0051     requestStateSave();
0052 }
0053 
0054 FlowCodeDocument::~FlowCodeDocument()
0055 {
0056     m_bDeleted = true;
0057     if (m_picItem)
0058         m_picItem->removeItem();
0059 
0060     delete m_microSettings;
0061     delete m_pDocumentIface;
0062 }
0063 
0064 View *FlowCodeDocument::createView(ViewContainer *viewContainer, uint viewAreaId)
0065 {
0066     View *view = new FlowCodeView(this, viewContainer, viewAreaId);
0067     handleNewView(view);
0068     return view;
0069 }
0070 
0071 void FlowCodeDocument::setPicType(const QString &id)
0072 {
0073     if (m_microSettings && m_microSettings->microInfo() && m_microSettings->microInfo()->id() == id)
0074         return;
0075 
0076     MicroInfo *microInfo = MicroLibrary::self()->microInfoWithID(id);
0077 
0078     if (!microInfo) {
0079         qCWarning(KTL_LOG) << "FlowCodeDocument::setPicType: Could not set the pic type to PIC \"" << id << "\"";
0080         return;
0081     }
0082 
0083     m_microInfo = microInfo;
0084 
0085     if (m_microSettings) {
0086         // TODO write the pic settings to somewhere temporary and then restore them
0087         delete m_microSettings;
0088     }
0089 
0090     m_microSettings = new MicroSettings(m_microInfo);
0091     connect(m_microSettings, &MicroSettings::pinMappingsChanged, this, &FlowCodeDocument::pinMappingsChangedFlowCode);
0092     // TODO restore pic settings from temporary location if appropriate
0093 
0094     delete m_picItem;
0095     m_picItem = new PicItem(this, true, "picItem", m_microSettings);
0096     m_picItem->show();
0097 
0098     emit picTypeChanged();
0099 }
0100 
0101 bool FlowCodeDocument::isValidItem(const QString &itemId)
0102 {
0103     return itemId.startsWith("flow/") || itemId.startsWith("dp/");
0104 }
0105 
0106 bool FlowCodeDocument::isValidItem(Item *item)
0107 {
0108     if (!dynamic_cast<FlowPart *>(item) && !dynamic_cast<DrawPart *>(item))
0109         return false;
0110 
0111     if (!item->id().startsWith("START") && !item->id().startsWith("PPEND"))
0112         return true;
0113 
0114     const ItemMap::iterator ciEnd = m_itemList.end();
0115 
0116     if (item->id().startsWith("START")) {
0117         int count = 0;
0118 
0119         for (ItemMap::iterator it = m_itemList.begin(); it != ciEnd; ++it) {
0120             if ((*it)->id().startsWith("START"))
0121                 count++;
0122         }
0123         if (count > 1)
0124             return false;
0125     } else if (item->id().startsWith("PPEND")) {
0126         int count = 0;
0127         for (ItemMap::iterator it = m_itemList.begin(); it != ciEnd; ++it) {
0128             if ((*it)->id().startsWith("PPEND"))
0129                 count++;
0130         }
0131 
0132         if (count > 1)
0133             return false;
0134     }
0135 
0136     return true;
0137 }
0138 
0139 void FlowCodeDocument::setLastTextOutputTarget(TextDocument *target)
0140 {
0141     m_pLastTextOutputTarget = target;
0142 }
0143 
0144 void FlowCodeDocument::slotConvertTo(QAction *action)
0145 {
0146     int target = action->data().toInt();
0147     switch ((ConvertToTarget)target) {
0148     case FlowCodeDocument::MicrobeOutput:
0149         convertToMicrobe();
0150         break;
0151 
0152     case FlowCodeDocument::AssemblyOutput:
0153         convertToAssembly();
0154         break;
0155 
0156     case FlowCodeDocument::HexOutput:
0157         convertToHex();
0158         break;
0159 
0160     case FlowCodeDocument::PICOutput:
0161         convertToPIC();
0162         break;
0163     }
0164 }
0165 
0166 void FlowCodeDocument::convertToMicrobe()
0167 {
0168     OutputMethodDlg *dlg = new OutputMethodDlg(i18n("Microbe Code Output"), url(), false, activeView());
0169     dlg->setOutputExtension(".microbe");
0170     dlg->setFilter(QString("*.microbe|Microbe (*.microbe)\n*|%1").arg(i18n("All Files")));
0171 
0172     const int accepted = dlg->exec();
0173     if (accepted != QDialog::Accepted) {
0174         delete dlg;
0175         return;
0176     }
0177 
0178     ProcessOptions o(dlg->info());
0179     o.setTextOutputTarget(m_pLastTextOutputTarget, this, SLOT(setLastTextOutputTarget(TextDocument *)));
0180     o.p_flowCodeDocument = this;
0181     o.setProcessPath(ProcessOptions::ProcessPath::FlowCode_Microbe);
0182     LanguageManager::self()->compile(o);
0183 
0184     delete dlg;
0185 }
0186 
0187 void FlowCodeDocument::convertToAssembly()
0188 {
0189     OutputMethodDlg *dlg = new OutputMethodDlg(i18n("Assembly Code Output"), url(), false, activeView());
0190     dlg->setOutputExtension(".asm");
0191     dlg->setFilter(QString("*.asm *.src *.inc|%1 (*.asm, *.src, *.inc)\n*|%2").arg(i18n("Assembly Code")).arg(i18n("All Files")));
0192 
0193     const int accepted = dlg->exec();
0194     if (accepted != QDialog::Accepted) {
0195         delete dlg;
0196         return;
0197     }
0198 
0199     ProcessOptions o(dlg->info());
0200     o.setTextOutputTarget(m_pLastTextOutputTarget, this, SLOT(setLastTextOutputTarget(TextDocument *)));
0201     o.p_flowCodeDocument = this;
0202     o.setProcessPath(ProcessOptions::ProcessPath::FlowCode_AssemblyAbsolute);
0203     LanguageManager::self()->compile(o);
0204 
0205     delete dlg;
0206 }
0207 
0208 void FlowCodeDocument::convertToHex()
0209 {
0210     OutputMethodDlg *dlg = new OutputMethodDlg(i18n("Hex Code Output"), url(), false, KTechlab::self());
0211     dlg->setOutputExtension(".hex");
0212     dlg->setFilter(QString("*.hex|Hex (*.hex)\n*|%1").arg(i18n("All Files")));
0213 
0214     const int accepted = dlg->exec();
0215     if (accepted != QDialog::Accepted) {
0216         delete dlg;
0217         return;
0218     }
0219 
0220     ProcessOptions o(dlg->info());
0221     o.setTextOutputTarget(m_pLastTextOutputTarget, this, SLOT(setLastTextOutputTarget(TextDocument *)));
0222     o.p_flowCodeDocument = this;
0223     o.setProcessPath(ProcessOptions::ProcessPath::FlowCode_Program);
0224     LanguageManager::self()->compile(o);
0225 
0226     delete dlg;
0227 }
0228 
0229 void FlowCodeDocument::convertToPIC()
0230 {
0231     ProgrammerDlg *dlg = new ProgrammerDlg(microSettings()->microInfo()->id(), (QWidget *)KTechlab::self());
0232     dlg->setObjectName("Programmer Dlg");
0233 
0234     const int accepted = dlg->exec();
0235     if (accepted != QDialog::Accepted) {
0236         dlg->deleteLater();
0237         return;
0238     }
0239 
0240     ProcessOptions o;
0241     dlg->initOptions(&o);
0242     o.p_flowCodeDocument = this;
0243     o.setProcessPath(ProcessOptions::ProcessPath::FlowCode_PIC);
0244     LanguageManager::self()->compile(o);
0245 
0246     dlg->deleteLater();
0247 }
0248 
0249 void FlowCodeDocument::varNameChanged(const QString &newValue, const QString &oldValue)
0250 {
0251     if (m_bDeleted)
0252         return;
0253 
0254     // Decrease the old variable count
0255     // If none are left after, remove it from microsettings
0256     StringIntMap::iterator it = m_varNames.find(oldValue);
0257     if (it != m_varNames.end()) {
0258         --(it.value());
0259         if (it.value() <= 0) {
0260             VariableInfo *info = microSettings()->variableInfo(it.key());
0261             if (info && !info->permanent)
0262                 microSettings()->deleteVariable(oldValue);
0263             m_varNames.erase(it);
0264         }
0265     }
0266 
0267     // Add the new variable to a count, tell microsettings about it if it is new
0268     if (!newValue.isEmpty()) {
0269         it = m_varNames.find(newValue);
0270         if (it != m_varNames.end()) {
0271             ++it.value();
0272         } else {
0273             m_varNames[newValue] = 1;
0274             microSettings()->setVariable(newValue, QVariant(), false);
0275         }
0276     }
0277 
0278     // Tell all FlowParts to update their variable lists
0279     const ItemMap::iterator end = m_itemList.end();
0280     for (ItemMap::iterator it = m_itemList.begin(); it != end; ++it) {
0281         if (FlowPart *flowPart = dynamic_cast<FlowPart *>(*it))
0282             flowPart->updateVarNames();
0283     }
0284 }