/*****************************************************************************/ /* PicFile.cpp - ascii file importer */ /* */ /* Copyright (C) 2011 Rallaz, rallazz@gmail.com */ /* Copyright (C) 2014 cgrzemba, cgrzemba@opencsw.org */ /* */ /* This library is free software, licensed under the terms of the GNU */ /* General Public License as published by the Free Software Foundation, */ /* either version 2 of the License, or (at your option) any later version. */ /* You should have received a copy of the GNU General Public License */ /* along with this program. If not, see . */ /*****************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "document_interface.h" #include "picfile.h" PluginCapabilities PicFile::getCapabilities() const { PluginCapabilities pluginCapabilities; pluginCapabilities.menuEntryPoints << PluginMenuLocation("plugins_menu", tr("Read PIC file")); return pluginCapabilities; } QString PicFile::name() const { return (tr("import PIC file")); } void PicFile::execComm(Document_Interface *doc, QWidget *parent, [[maybe_unused]] QString cmd) { picPunto pdt(parent); int result = pdt.exec(); if (result == QDialog::Accepted) pdt.processFile(doc); } /*****************************/ picPunto::picPunto(QWidget *parent) : QDialog(parent) { cnt = 0; QStringList txtformats; QGridLayout *mainLayout = new QGridLayout; //readSettings(); QPushButton *filebut = new QPushButton(tr("File...")); fileedit = new QLineEdit(); QDoubleValidator *val = new QDoubleValidator(0); val->setBottom ( 0.0 ); scaleedit = new QLineEdit(); scaleedit->setValidator(val); QFormLayout *flo = new QFormLayout; flo->addRow( filebut, fileedit); flo->addRow( tr("Scale:"), scaleedit); mainLayout->addLayout(flo, 0, 0); QHBoxLayout *loacceptcancel = new QHBoxLayout; QPushButton *acceptbut = new QPushButton(tr("Accept")); loacceptcancel->addStretch(); loacceptcancel->addWidget(acceptbut); QPushButton *cancelbut = new QPushButton(tr("Cancel")); loacceptcancel->addWidget(cancelbut); mainLayout->addLayout(loacceptcancel, 1, 0); setLayout(mainLayout); readSettings(); connect(cancelbut, SIGNAL(clicked()), this, SLOT(reject())); connect(acceptbut, SIGNAL(clicked()), this, SLOT(checkAccept())); connect(filebut, SIGNAL(clicked()), this, SLOT(dptFile())); } void picPunto::checkAccept() { errmsg.clear(); if (failGUI(&errmsg)) { QMessageBox::critical ( this, "Pic file read plugin", errmsg ); errmsg.clear(); return; } writeSettings(); accept(); } void picPunto::dptFile() { QString fileName = QFileDialog::getOpenFileName(this, tr("Select file")); fileedit->setText(fileName); } bool picPunto::failGUI(QString *msg) { double val = scaleedit->text().toDouble(); if ( val == 0 ) { msg->insert(0, tr("Scale Factor is empty or invalid")); return true; } return false; } void picPunto::processFile(Document_Interface *doc) { QString sep = " "; currDoc = doc; scale = (scaleedit->text()).toDouble(); if (!QFile::exists(fileedit->text()) ) { QMessageBox::critical ( this, "picPunto", QString(tr("The file %1 not exist")).arg(fileedit->text()) ); return; } QFile infile(fileedit->text()); if (!infile.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox::critical ( this, "picPunto", QString(tr("Can't open the file %1")).arg(fileedit->text()) ); return; } QString currlay = currDoc->getCurrentLayer(); processFilePic(&infile); infile.close (); QMessageBox::information(this, "Info", QString(tr("%1 objects imported")).arg(cnt) ); currDoc = NULL; } double picPunto::getPValue(QString p) { return (p.toDouble() * scale); } void picPunto::drawLine() { QPointF prevP, nextP; int i; for (i = 0; i < dataList.size(); ++i) { pointData *pd = dataList.at(i); if (!pd->x.isEmpty() && !pd->y.isEmpty()){ prevP.setX(getPValue(pd->x)); prevP.setY(getPValue(pd->y)); i++; break; } else { QMessageBox::information(this, "Info", QString(tr("picPunto drawLine: first point is empty %1")).arg(i)); } } for (; i < dataList.size(); ++i) { pointData *pd = dataList.at(i); if (!pd->x.isEmpty() && !pd->y.isEmpty()){ nextP.setX(getPValue(pd->x)); nextP.setY(getPValue(pd->y)); currDoc->addLine(&prevP, &nextP); // QMessageBox::information(this, "Info", QString(tr("picPunto drawLine: addLine %1 %2,%3 %4,%5")).arg(i).arg(prevP.x()).arg(prevP.y()).arg(nextP.x()).arg(nextP.y())); prevP = nextP; cnt++; } else { QMessageBox::information(this, "Info", QString(tr("picPunto drawLine: next point is empty %1")).arg(i)); } } while (!dataList.isEmpty()) delete dataList.takeFirst(); } void picPunto::drawCircle(QString x, QString y, QString radius) { QPointF center; qreal rad; center.setX(getPValue(x)); center.setY(getPValue(y)); rad = getPValue(radius); currDoc->addCircle(¢er, rad); cnt++; } void picPunto::drawText(QString x, QString y, QString txt, QString align) { DPI::VAlign va = DPI::VAlignBottom; DPI::HAlign ha; QString sty = "txt"; double height = 0.05 * scale; ha = (align == "ljust") ? DPI::HAlignLeft : (align == "rjust") ? DPI::HAlignRight : DPI::HAlignCenter; QPointF pt(getPValue(x), getPValue(y)); currDoc->addText(txt, sty, &pt, height, 0.0, ha, va); cnt++; } void picPunto::drawBox(QString posx, QString posy, QString width, QString height) { QPointF prevP, nextP; prevP.setX(getPValue(posx)); prevP.setY(getPValue(posy)); nextP.setX(getPValue(posx)+getPValue(width)); nextP.setY(prevP.y()); currDoc->addLine(&prevP, &nextP); prevP=nextP; nextP.setY(prevP.y()+getPValue(height)); currDoc->addLine(&prevP, &nextP); prevP=nextP; nextP.setX(getPValue(posx)); currDoc->addLine(&prevP, &nextP); prevP=nextP; nextP.setY(getPValue(posy)); currDoc->addLine(&prevP, &nextP); cnt++; } void picPunto::processFilePic(QFile* file) { // QString outname, sep; QString sep = " "; #if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) Qt::SplitBehaviorFlags skip = Qt::KeepEmptyParts; #else QString::SplitBehavior skip = QString::KeepEmptyParts; #endif QStringList data; QString cmd; pointData *pd; while (!file->atEnd()) { int i = 2; QString line = file->readLine(); line.remove ( line.size()-1, 1); // printf("process line: %s\n",line.toStdString().c_str() ); data = line.split(sep, skip); if (data.size() < 4 ) continue; cmd = data.at(0); if (cmd == "line" ) { if (data.at(2) == "from"){ i++; // dashed line } for (;i < data.size(); i += 2) { pd = new pointData; pd->x = data.at(i).split(',').at(0); pd->y = data.at(i).split(',').at(1); dataList.append(pd); if ( i < data.size()-1 && data.at(i+1) != "to") { QMessageBox::critical ( this, "picPunto", QString(tr("format error in %1")).arg(line) ); return; } } if (dataList.size() > 0 ) drawLine(); } else { if (cmd == "circle") { // circle at 7.935,3.643 rad 0.035 if ( data.size() != 5 ) { QMessageBox::critical ( this, "picPunto", QString(tr("format error in %1")).arg(line) ); return; } drawCircle(data.at(2).split(',').at(0), data.at(2).split(',').at(1), data.at(4)); } else { if (cmd == "box") { // box invis fill 0.000 with .sw at (7.480,6.917) width 0.079 height 0.157 if ( data.size() < 11 ) { // QMessageBox::critical ( this, "picPunto", QString(tr("format error in %1")).arg(line) ); continue; } QString posx = data.at(7).split(',').at(0); QString posy = data.at(7).split(',').at(1); drawBox(posx.remove(0,1), posy.remove(posy.size()-1,1), data.at(9), data.at(11)); } else { if ( cmd.startsWith("\"\\s") && data.size() > 3 ) { // "\s5\fRAbstell fl?che\fP" at 8.132,7.456 ljust QString txt = line.split("\"", skip).at(1); QStringList rline = line.split("\"", skip).at(2).split(" ",skip); txt.remove ( txt.size()-3, 3); txt.remove (QRegularExpression("^.*fR")); // printf("process line: %s: %s\n",rline.at(2).toStdString().c_str(),txt.toStdString().c_str() ); drawText(rline.at(2).split(',').at(0), rline.at(2).split(',').at(1), txt, rline.at(3)); } } } } } } picPunto::~picPunto() { while (!dataList.isEmpty()) delete dataList.takeFirst(); } void picPunto::readSettings() { QString str; QSettings settings(QSettings::IniFormat, QSettings::UserScope, "LibreCAD", "picfile"); QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); QSize size = settings.value("size", QSize(400,50)).toSize(); str = settings.value("lastfile").toString(); fileedit->setText(str); str = settings.value("lastscale","1.0").toString(); scaleedit->setText(str); resize(size); move(pos); } void picPunto::writeSettings() { QSettings settings(QSettings::IniFormat, QSettings::UserScope, "LibreCAD", "picfile"); settings.setValue("pos", pos()); settings.setValue("size", size()); settings.setValue("lastfile", fileedit->text()); settings.setValue("lastscale", scaleedit->text()); }