Thu, 03 Oct 2013 20:56:20 +0300
last code reformatting i swear
--- a/src/addObjectDialog.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/addObjectDialog.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -37,371 +37,377 @@ // ============================================================================= // ----------------------------------------------------------------------------- -class SubfileListItem : public QTreeWidgetItem { - PROPERTY (Primitive*, primInfo, setPrimInfo) - -public: - SubfileListItem (QTreeWidgetItem* parent, Primitive* info) : - QTreeWidgetItem (parent), m_primInfo (info) {} - SubfileListItem (QTreeWidget* parent, Primitive* info) : - QTreeWidgetItem (parent), m_primInfo (info) {} +class SubfileListItem : public QTreeWidgetItem +{ PROPERTY (Primitive*, primInfo, setPrimInfo) + + public: + SubfileListItem (QTreeWidgetItem* parent, Primitive* info) : + QTreeWidgetItem (parent), m_primInfo (info) {} + SubfileListItem (QTreeWidget* parent, Primitive* info) : + QTreeWidgetItem (parent), m_primInfo (info) {} }; // ============================================================================= // ----------------------------------------------------------------------------- -AddObjectDialog::AddObjectDialog (const LDObject::Type type, LDObject* obj, QWidget* parent) : QDialog (parent) { - setlocale (LC_ALL, "C"); - +AddObjectDialog::AddObjectDialog (const LDObject::Type type, LDObject* obj, QWidget* parent) : QDialog (parent) +{ setlocale (LC_ALL, "C"); + short coordCount = 0; str typeName = LDObject::typeName (type); - - switch (type) { - case LDObject::Comment: - le_comment = new QLineEdit; - if (obj) - le_comment->setText (static_cast<LDComment*> (obj)->text); - - le_comment->setMinimumWidth (384); - break; - - case LDObject::Line: - coordCount = 6; - break; - - case LDObject::Triangle: - coordCount = 9; - break; - - case LDObject::Quad: - case LDObject::CndLine: - coordCount = 12; - break; - - case LDObject::Vertex: - coordCount = 3; - break; - - case LDObject::BFC: - rb_bfcType = new RadioGroup ("Statement", {}, 0, Qt::Vertical); - - for (int i = 0; i < LDBFC::NumStatements; ++i) { - // Separate these in two columns - if (i == LDBFC::NumStatements / 2) - rb_bfcType->rowBreak(); - - rb_bfcType->addButton (LDBFC::statements[i]); - } - - if (obj) - rb_bfcType->setValue ((int) static_cast<LDBFC*> (obj)->type); - break; - - case LDObject::Subfile: - coordCount = 3; - - // If the primitive lister is busy writing data, we have to wait - // for that to happen first. This should be quite considerably rare. - while (primitiveLoaderBusy()) - ; - - tw_subfileList = new QTreeWidget(); - tw_subfileList->setHeaderLabel (tr ("Primitives")); - - for (PrimitiveCategory& cat : g_PrimitiveCategories) { - SubfileListItem* parentItem = new SubfileListItem (tw_subfileList, null); - parentItem->setText (0, cat.name()); - QList<QTreeWidgetItem*> subfileItems; - - for (Primitive& prim : cat.prims) { - SubfileListItem* item = new SubfileListItem (parentItem, &prim); - item->setText (0, fmt ("%1 - %2", prim.name, prim.title)); - subfileItems << item; - - // If this primitive is the one the current object points to, - // select it by default - if (obj && static_cast<LDSubfile*> (obj)->fileInfo()->name() == prim.name) - tw_subfileList->setCurrentItem (item); + + switch (type) + { case LDObject::Comment: + le_comment = new QLineEdit; + + if (obj) + le_comment->setText (static_cast<LDComment*> (obj)->text); + + le_comment->setMinimumWidth (384); + break; + + case LDObject::Line: + coordCount = 6; + break; + + case LDObject::Triangle: + coordCount = 9; + break; + + case LDObject::Quad: + case LDObject::CndLine: + coordCount = 12; + break; + + case LDObject::Vertex: + coordCount = 3; + break; + + case LDObject::BFC: + rb_bfcType = new RadioGroup ("Statement", {}, 0, Qt::Vertical); + + for (int i = 0; i < LDBFC::NumStatements; ++i) + { // Separate these in two columns + if (i == LDBFC::NumStatements / 2) + rb_bfcType->rowBreak(); + + rb_bfcType->addButton (LDBFC::statements[i]); } - - tw_subfileList->addTopLevelItem (parentItem); - } - - connect (tw_subfileList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_subfileTypeChanged())); - lb_subfileName = new QLabel ("File:"); - le_subfileName = new QLineEdit; - le_subfileName->setFocus(); - - if (obj) { - LDSubfile* ref = static_cast<LDSubfile*> (obj); - le_subfileName->setText (ref->fileInfo()->name()); - } - break; - - default: - critical (fmt ("Unhandled LDObject type %1 (%2) in AddObjectDialog", (int) type, typeName)); - return; + + if (obj) + rb_bfcType->setValue ( (int) static_cast<LDBFC*> (obj)->type); + + break; + + case LDObject::Subfile: + coordCount = 3; + + // If the primitive lister is busy writing data, we have to wait + // for that to happen first. This should be quite considerably rare. + while (primitiveLoaderBusy()) + ; + + tw_subfileList = new QTreeWidget(); + tw_subfileList->setHeaderLabel (tr ("Primitives")); + + for (PrimitiveCategory & cat : g_PrimitiveCategories) + { SubfileListItem* parentItem = new SubfileListItem (tw_subfileList, null); + parentItem->setText (0, cat.name()); + QList<QTreeWidgetItem*> subfileItems; + + for (Primitive & prim : cat.prims) + { SubfileListItem* item = new SubfileListItem (parentItem, &prim); + item->setText (0, fmt ("%1 - %2", prim.name, prim.title)); + subfileItems << item; + + // If this primitive is the one the current object points to, + // select it by default + if (obj && static_cast<LDSubfile*> (obj)->fileInfo()->name() == prim.name) + tw_subfileList->setCurrentItem (item); + } + + tw_subfileList->addTopLevelItem (parentItem); + } + + connect (tw_subfileList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_subfileTypeChanged())); + lb_subfileName = new QLabel ("File:"); + le_subfileName = new QLineEdit; + le_subfileName->setFocus(); + + if (obj) + { LDSubfile* ref = static_cast<LDSubfile*> (obj); + le_subfileName->setText (ref->fileInfo()->name()); + } + + break; + + default: + critical (fmt ("Unhandled LDObject type %1 (%2) in AddObjectDialog", (int) type, typeName)); + return; } - + QPixmap icon = getIcon (fmt ("add-%1", typeName)); LDObject* defaults = LDObject::getDefault (type); - + lb_typeIcon = new QLabel; lb_typeIcon->setPixmap (icon); - + // Show a color edit dialog for the types that actually use the color - if (defaults->isColored()) { - if (obj != null) + if (defaults->isColored()) + { if (obj != null) colnum = obj->color(); else colnum = (type == LDObject::CndLine || type == LDObject::Line) ? edgecolor : maincolor; - + pb_color = new QPushButton; setButtonBackground (pb_color, colnum); connect (pb_color, SIGNAL (clicked()), this, SLOT (slot_colorButtonClicked())); } - - for (short i = 0; i < coordCount; ++i) { - dsb_coords[i] = new QDoubleSpinBox; + + for (short i = 0; i < coordCount; ++i) + { dsb_coords[i] = new QDoubleSpinBox; dsb_coords[i]->setDecimals (5); dsb_coords[i]->setMinimum (-10000.0); dsb_coords[i]->setMaximum (10000.0); } - + QGridLayout* const layout = new QGridLayout; layout->addWidget (lb_typeIcon, 0, 0); - - switch (type) { - case LDObject::Line: - case LDObject::CndLine: - case LDObject::Triangle: - case LDObject::Quad: - // Apply coordinates - if (obj) { - for (short i = 0; i < coordCount / 3; ++i) - for (short j = 0; j < 3; ++j) - dsb_coords[(i * 3) + j]->setValue (obj->getVertex (i).coord (j)); - } - break; - - case LDObject::Comment: - layout->addWidget (le_comment, 0, 1); - break; - - case LDObject::BFC: - layout->addWidget (rb_bfcType, 0, 1); - break; - - case LDObject::Subfile: - layout->addWidget (tw_subfileList, 1, 1, 1, 2); - layout->addWidget (lb_subfileName, 2, 1); - layout->addWidget (le_subfileName, 2, 2); - break; - - default: - break; + + switch (type) + { case LDObject::Line: + case LDObject::CndLine: + case LDObject::Triangle: + case LDObject::Quad: + + // Apply coordinates + if (obj) + { for (short i = 0; i < coordCount / 3; ++i) + for (short j = 0; j < 3; ++j) + dsb_coords[ (i * 3) + j]->setValue (obj->getVertex (i).coord (j)); + } + + break; + + case LDObject::Comment: + layout->addWidget (le_comment, 0, 1); + break; + + case LDObject::BFC: + layout->addWidget (rb_bfcType, 0, 1); + break; + + case LDObject::Subfile: + layout->addWidget (tw_subfileList, 1, 1, 1, 2); + layout->addWidget (lb_subfileName, 2, 1); + layout->addWidget (le_subfileName, 2, 2); + break; + + default: + break; } - - if (defaults->hasMatrix()) { - LDMatrixObject* mo = obj ? dynamic_cast<LDMatrixObject*> (obj) : null; - + + if (defaults->hasMatrix()) + { LDMatrixObject* mo = obj ? dynamic_cast<LDMatrixObject*> (obj) : null; + QLabel* lb_matrix = new QLabel ("Matrix:"); le_matrix = new QLineEdit; // le_matrix->setValidator (new QDoubleValidator); matrix defaultMatrix = g_identity; - - if (mo) { - for (const Axis ax : g_Axes) - dsb_coords[ax]->setValue (mo->position()[ax]); - + + if (mo) + { for (const Axis ax : g_Axes) + dsb_coords[ax]->setValue (mo->position() [ax]); + defaultMatrix = mo->transform(); } - + le_matrix->setText (defaultMatrix.stringRep()); layout->addWidget (lb_matrix, 4, 1); layout->addWidget (le_matrix, 4, 2, 1, 3); } - + if (defaults->isColored()) layout->addWidget (pb_color, 1, 0); - - if (coordCount > 0) { - QGridLayout* const qCoordLayout = new QGridLayout; - + + if (coordCount > 0) + { QGridLayout* const qCoordLayout = new QGridLayout; + for (short i = 0; i < coordCount; ++i) qCoordLayout->addWidget (dsb_coords[i], (i / 3), (i % 3)); - + layout->addLayout (qCoordLayout, 0, 1, (coordCount / 3), 3); } - + QDialogButtonBox* bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); QWidget::connect (bbx_buttons, SIGNAL (accepted()), this, SLOT (accept())); QWidget::connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject())); layout->addWidget (bbx_buttons, 5, 0, 1, 4); setLayout (layout); setWindowTitle (fmt (tr ("Edit %1"), typeName)); - + setWindowIcon (icon); delete defaults; } // ============================================================================= // ----------------------------------------------------------------------------- -void AddObjectDialog::setButtonBackground (QPushButton* button, short colnum) { - LDColor* col = getColor (colnum); - +void AddObjectDialog::setButtonBackground (QPushButton* button, short colnum) +{ LDColor* col = getColor (colnum); + button->setIcon (getIcon ("palette")); button->setAutoFillBackground (true); - + if (col) button->setStyleSheet (fmt ("background-color: %1", col->hexcode)); } // ============================================================================= // ----------------------------------------------------------------------------- -str AddObjectDialog::currentSubfileName() { - SubfileListItem* item = static_cast<SubfileListItem*> (tw_subfileList->currentItem()); - +str AddObjectDialog::currentSubfileName() +{ SubfileListItem* item = static_cast<SubfileListItem*> (tw_subfileList->currentItem()); + if (item->primInfo() == null) return ""; // selected a heading - + return item->primInfo()->name; } // ============================================================================= // ----------------------------------------------------------------------------- -void AddObjectDialog::slot_colorButtonClicked() { - ColorSelector::getColor (colnum, colnum, this); +void AddObjectDialog::slot_colorButtonClicked() +{ ColorSelector::getColor (colnum, colnum, this); setButtonBackground (pb_color, colnum); } // ============================================================================= // ----------------------------------------------------------------------------- -void AddObjectDialog::slot_subfileTypeChanged() { - str name = currentSubfileName(); - +void AddObjectDialog::slot_subfileTypeChanged() +{ str name = currentSubfileName(); + if (name.length() > 0) le_subfileName->setText (name); } // ============================================================================= // ----------------------------------------------------------------------------- -template<class T> static T* initObj (LDObject*& obj) { - if (obj == null) +template<class T> static T* initObj (LDObject*& obj) +{ if (obj == null) obj = new T; - + return static_cast<T*> (obj); } // ============================================================================= // ----------------------------------------------------------------------------- -void AddObjectDialog::staticDialog (const LDObject::Type type, LDObject* obj) { - setlocale (LC_ALL, "C"); - +void AddObjectDialog::staticDialog (const LDObject::Type type, LDObject* obj) +{ setlocale (LC_ALL, "C"); + // FIXME: Redirect to Edit Raw if (obj && obj->getType() == LDObject::Error) return; - + if (type == LDObject::Empty) return; // Nothing to edit with empties - + const bool newObject = (obj == null); matrix transform = g_identity; AddObjectDialog dlg (type, obj); - + if (obj) assert (obj->getType() == type); - + if (dlg.exec() == false) return; - - if (type == LDObject::Subfile) { - QStringList matrixstrvals = dlg.le_matrix->text().split (" "); - - if (matrixstrvals.size() == 9) { - double matrixvals[9]; + + if (type == LDObject::Subfile) + { QStringList matrixstrvals = dlg.le_matrix->text().split (" "); + + if (matrixstrvals.size() == 9) + { double matrixvals[9]; int i = 0; - - for (str val : matrixstrvals) + + for (str val : matrixstrvals) matrixvals[i++] = val.toFloat(); - + transform = matrix (matrixvals); } } - - switch (type) { - case LDObject::Comment: - { - LDComment* comm = initObj<LDComment> (obj); + + switch (type) + { case LDObject::Comment: + { LDComment* comm = initObj<LDComment> (obj); comm->text = dlg.le_comment->text(); } break; - - case LDObject::Line: - case LDObject::Triangle: - case LDObject::Quad: - case LDObject::CndLine: - if (!obj) - obj = LDObject::getDefault (type); - - for (short i = 0; i < obj->vertices(); ++i) { - vertex v; + + case LDObject::Line: + case LDObject::Triangle: + case LDObject::Quad: + case LDObject::CndLine: + + if (!obj) + obj = LDObject::getDefault (type); + + for (short i = 0; i < obj->vertices(); ++i) + { vertex v; + for (const Axis ax : g_Axes) - v[ax] = dlg.dsb_coords[(i * 3) + ax]->value(); - - obj->setVertex (i, v); - } - break; - - case LDObject::BFC: - { - LDBFC* bfc = initObj<LDBFC> (obj); + v[ax] = dlg.dsb_coords[ (i * 3) + ax]->value(); + + obj->setVertex (i, v); + } + + break; + + case LDObject::BFC: + { LDBFC* bfc = initObj<LDBFC> (obj); bfc->type = (LDBFC::Type) dlg.rb_bfcType->value(); } break; - - case LDObject::Vertex: - { - LDVertex* vert = initObj<LDVertex> (obj); - - for (const Axis ax : g_Axes) + + case LDObject::Vertex: + { LDVertex* vert = initObj<LDVertex> (obj); + + for (const Axis ax : g_Axes) vert->pos[ax] = dlg.dsb_coords[ax]->value(); } break; - - case LDObject::Subfile: - { - str name = dlg.le_subfileName->text(); + + case LDObject::Subfile: + { str name = dlg.le_subfileName->text(); + if (name.length() == 0) return; // no subfile filename - + LDFile* file = getFile (name); - if (!file) { - critical (fmt ("Couldn't open `%1': %2", name, strerror (errno))); + + if (!file) + { critical (fmt ("Couldn't open `%1': %2", name, strerror (errno))); return; } - + LDSubfile* ref = initObj<LDSubfile> (obj); - - for (const Axis ax : g_Axes) + + for (const Axis ax : g_Axes) ref->setCoordinate (ax, dlg.dsb_coords[ax]->value()); - + ref->setTransform (transform); ref->setFileInfo (file); } break; - - default: - break; + + default: + break; } - + if (obj->isColored()) obj->setColor (dlg.colnum); - - if (newObject) { - ulong idx = g_win->getInsertionPoint(); + + if (newObject) + { ulong idx = g_win->getInsertionPoint(); LDFile::current()->insertObj (idx, obj); } - + g_win->fullRefresh(); } #include "moc_addObjectDialog.cpp"
--- a/src/addObjectDialog.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/addObjectDialog.h Thu Oct 03 20:56:20 2013 +0300 @@ -16,8 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef ZZ_ADDOBJECTDIALOG_H -#define ZZ_ADDOBJECTDIALOG_H +#ifndef LDFORGE_ADDOBJECTDIALOG_H +#define LDFORGE_ADDOBJECTDIALOG_H #include <QDialog> #include "ldtypes.h" @@ -31,42 +31,42 @@ class QTreeWidget; class QDoubleSpinBox; -class AddObjectDialog : public QDialog { - Q_OBJECT - -public: - AddObjectDialog (const LDObject::Type type, LDObject* obj, QWidget* parent = null); - static void staticDialog (const LDObject::Type type, LDObject* obj); - - QLabel* lb_typeIcon; - - // Comment line edit - QLineEdit* le_comment; - - // Coordinate edits for.. anything with coordinates, really. - QDoubleSpinBox* dsb_coords[12]; - - // Color selection dialog button - QPushButton* pb_color; - - // BFC-related widgets - RadioGroup* rb_bfcType; - - // Subfile stuff - QTreeWidget* tw_subfileList; - QLineEdit* le_subfileName; - QLabel* lb_subfileName; - QLineEdit* le_matrix; - -private: - void setButtonBackground (QPushButton* button, short color); - str currentSubfileName(); - - short colnum; - -private slots: - void slot_colorButtonClicked(); - void slot_subfileTypeChanged(); +class AddObjectDialog : public QDialog +{ Q_OBJECT + + public: + AddObjectDialog (const LDObject::Type type, LDObject* obj, QWidget* parent = null); + static void staticDialog (const LDObject::Type type, LDObject* obj); + + QLabel* lb_typeIcon; + + // Comment line edit + QLineEdit* le_comment; + + // Coordinate edits for.. anything with coordinates, really. + QDoubleSpinBox* dsb_coords[12]; + + // Color selection dialog button + QPushButton* pb_color; + + // BFC-related widgets + RadioGroup* rb_bfcType; + + // Subfile stuff + QTreeWidget* tw_subfileList; + QLineEdit* le_subfileName; + QLabel* lb_subfileName; + QLineEdit* le_matrix; + + private: + void setButtonBackground (QPushButton* button, short color); + str currentSubfileName(); + + short colnum; + + private slots: + void slot_colorButtonClicked(); + void slot_subfileTypeChanged(); }; -#endif // ZZ_ADDOBJECTDIALOG_H \ No newline at end of file +#endif // ZZ_ADDOBJECTDIALOG_H
--- a/src/colorSelectDialog.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/colorSelectDialog.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -31,6 +31,7 @@ #include "config.h" #include "misc.h" #include "ui_colorsel.h" +#include "moc_colorSelectDialog.cpp" static const int g_numColumns = 16; static const short g_squareSize = 32; @@ -40,78 +41,78 @@ // ============================================================================= // ----------------------------------------------------------------------------- -ColorSelector::ColorSelector (short defval, QWidget* parent) : QDialog (parent) { - // Remove the default color if it's invalid +ColorSelector::ColorSelector (short defval, QWidget* parent) : QDialog (parent) +{ // Remove the default color if it's invalid if (!::getColor (defval)) defval = -1; - + m_firstResize = true; ui = new Ui_ColorSelUI; ui->setupUi (this); - + m_scene = new QGraphicsScene; ui->viewport->setScene (m_scene); setSelection (::getColor (defval)); - + // not really an icon but eh m_scene->setBackgroundBrush (getIcon ("checkerboard")); drawScene(); - + int width = viewportWidth(); ui->viewport->setMinimumWidth (width); ui->viewport->setMaximumWidth (width); - + drawColorInfo(); } // ============================================================================= // ----------------------------------------------------------------------------- -ColorSelector::~ColorSelector() { - delete ui; +ColorSelector::~ColorSelector() +{ delete ui; } // ============================================================================= // ----------------------------------------------------------------------------- -void ColorSelector::drawScene() { - const int numCols = g_numColumns; +void ColorSelector::drawScene() +{ const int numCols = g_numColumns; const int square = g_squareSize; const int g_maxHeight = (numRows() * square); QRect sceneRect (0, 0, viewportWidth(), g_maxHeight); - + m_scene->setSceneRect (sceneRect); ui->viewport->setSceneRect (sceneRect); - + const double penWidth = 1.0f; - + // Draw the color rectangles. m_scene->clear(); - - for (short i = 0; i < MAX_COLORS; ++i) { - LDColor* info = ::getColor (i); - + + for (short i = 0; i < MAX_COLORS; ++i) + { LDColor* info = ::getColor (i); + if (!info) continue; - + const double x = (i % numCols) * square; const double y = (i / numCols) * square; const double w = square - (penWidth / 2); - + QColor col = info->faceColor; - - if (i == maincolor) { - // Use the user preferences for main color here + + if (i == maincolor) + { // Use the user preferences for main color here col = QColor (gl_maincolor); col.setAlpha (gl_maincolor_alpha * 255.0f); } - + QPen pen (info->edgeColor, penWidth, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin); m_scene->addRect (x, y, w, w, pen, col); QGraphicsTextItem* numtext = m_scene->addText (fmt ("%1", i)); - numtext->setDefaultTextColor ((luma (col) < 80) ? Qt::white : Qt::black); + numtext->setDefaultTextColor ( (luma (col) < 80) ? Qt::white : Qt::black); numtext->setPos (x, y); - - if (sel() && i == sel()->index) { - auto curspic = m_scene->addPixmap (getIcon ("colorcursor")); + + if (sel() && i == sel()->index) + { auto curspic = m_scene->addPixmap (getIcon ("colorcursor")); curspic->setPos (x, y); } } @@ -119,62 +120,62 @@ // ============================================================================= // ----------------------------------------------------------------------------- -int ColorSelector::numRows() const { - return (MAX_COLORS / g_numColumns); +int ColorSelector::numRows() const +{ return (MAX_COLORS / g_numColumns); } // ============================================================================= // ----------------------------------------------------------------------------- -int ColorSelector::viewportWidth() const { - return g_numColumns * g_squareSize + 21; +int ColorSelector::viewportWidth() const +{ return g_numColumns * g_squareSize + 21; } // ============================================================================= // ----------------------------------------------------------------------------- -void ColorSelector::drawColorInfo() { - if (!sel()) { - ui->colorLabel->setText ("---"); +void ColorSelector::drawColorInfo() +{ if (!sel()) + { ui->colorLabel->setText ("---"); return; } - + ui->colorLabel->setText (fmt ("%1 - %2", sel()->index, sel()->name)); } // ============================================================================= // ----------------------------------------------------------------------------- -void ColorSelector::resizeEvent (QResizeEvent* ev) { - // If this is the first resize, check if we need to scroll down to see the +void ColorSelector::resizeEvent (QResizeEvent* ev) +{ // If this is the first resize, check if we need to scroll down to see the // currently selected color. We cannot do this in the constructor because the // height is not set properly there. - if (m_firstResize) { - int visibleColors = (ui->viewport->height() / g_squareSize) * g_numColumns; - - if (sel() && sel()->index >= visibleColors) { - int y = (sel()->index / g_numColumns) * g_squareSize; + if (m_firstResize) + { int visibleColors = (ui->viewport->height() / g_squareSize) * g_numColumns; + + if (sel() && sel()->index >= visibleColors) + { int y = (sel()->index / g_numColumns) * g_squareSize; ui->viewport->verticalScrollBar()->setValue (y); } - + m_firstResize = false; } - + (void) ev; drawScene(); } // ============================================================================= // ----------------------------------------------------------------------------- -void ColorSelector::mousePressEvent (QMouseEvent* event) { - QPointF scenepos = ui->viewport->mapToScene (event->pos()); - - ulong x = ((ulong) scenepos.x() - (g_squareSize / 2)) / g_squareSize; - ulong y = ((ulong) scenepos.y() - (g_squareSize / 2)) / g_squareSize; +void ColorSelector::mousePressEvent (QMouseEvent* event) +{ QPointF scenepos = ui->viewport->mapToScene (event->pos()); + + ulong x = ( (ulong) scenepos.x() - (g_squareSize / 2)) / g_squareSize; + ulong y = ( (ulong) scenepos.y() - (g_squareSize / 2)) / g_squareSize; ulong idx = (y * g_numColumns) + x; - + LDColor* col = ::getColor (idx); - + if (!col) return; - + setSelection (col); drawScene(); drawColorInfo(); @@ -182,14 +183,13 @@ // ============================================================================= // ----------------------------------------------------------------------------- -bool ColorSelector::getColor (short& val, short int defval, QWidget* parent) { - ColorSelector dlg (defval, parent); - - if (dlg.exec() && dlg.sel() != null) { - val = dlg.sel()->index; +bool ColorSelector::getColor (short& val, short int defval, QWidget* parent) +{ ColorSelector dlg (defval, parent); + + if (dlg.exec() && dlg.sel() != null) + { val = dlg.sel()->index; return true; } - + return false; -} -#include "moc_colorSelectDialog.cpp" +} \ No newline at end of file
--- a/src/colorSelectDialog.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/colorSelectDialog.h Thu Oct 03 20:56:20 2013 +0300 @@ -16,8 +16,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef COLORSELECTOR_H -#define COLORSELECTOR_H +#ifndef LDFORGE_COLORSELECTOR_H +#define LDFORGE_COLORSELECTOR_H #include <QDialog> #include "common.h" @@ -26,28 +26,28 @@ class Ui_ColorSelUI; class QGraphicsScene; -class ColorSelector : public QDialog { - Q_OBJECT +class ColorSelector : public QDialog +{ Q_OBJECT READ_PROPERTY (LDColor*, sel, setSelection) - -public: - explicit ColorSelector (short defval = -1, QWidget* parent = null); - virtual ~ColorSelector(); - static bool getColor (short& val, short defval = -1, QWidget* parent = null); - -protected: - void mousePressEvent (QMouseEvent* event); - void resizeEvent (QResizeEvent* ev); - -private: - Ui_ColorSelUI* ui; - QGraphicsScene* m_scene; - bool m_firstResize; - - int numRows() const; - int viewportWidth() const; - void drawScene(); - void drawColorInfo(); + + public: + explicit ColorSelector (short defval = -1, QWidget* parent = null); + virtual ~ColorSelector(); + static bool getColor (short& val, short defval = -1, QWidget* parent = null); + + protected: + void mousePressEvent (QMouseEvent* event); + void resizeEvent (QResizeEvent* ev); + + private: + Ui_ColorSelUI* ui; + QGraphicsScene* m_scene; + bool m_firstResize; + + int numRows() const; + int viewportWidth() const; + void drawScene(); + void drawColorInfo(); }; -#endif // COLORSELECTOR_H \ No newline at end of file +#endif // COLORSELECTOR_H
--- a/src/colors.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/colors.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -33,49 +33,49 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void initColors() { - LDColor* col; +void initColors() +{ LDColor* col; print ("%1: initializing color information.\n", __func__); - + // Always make sure there's 16 and 24 available. They're special like that. col = new LDColor; col->faceColor = - col->hexcode = "#AAAAAA"; + col->hexcode = "#AAAAAA"; col->edgeColor = Qt::black; g_LDColors[maincolor] = col; - + col = new LDColor; col->faceColor = - col->edgeColor = - col->hexcode = "#000000"; + col->edgeColor = + col->hexcode = "#000000"; g_LDColors[edgecolor] = col; - + parseLDConfig(); } // ============================================================================= // ----------------------------------------------------------------------------- -LDColor* getColor (short colnum) { - // Check bounds +LDColor* getColor (short colnum) +{ // Check bounds if (colnum < 0 || colnum >= MAX_COLORS) return null; - + return g_LDColors[colnum]; } // ============================================================================= // ----------------------------------------------------------------------------- -void setColor (short colnum, LDColor* col) { - if (colnum < 0 || colnum >= MAX_COLORS) +void setColor (short colnum, LDColor* col) +{ if (colnum < 0 || colnum >= MAX_COLORS) return; - + g_LDColors[colnum] = col; } // ============================================================================= // ----------------------------------------------------------------------------- -int luma (QColor& col) { - return (0.2126f * col.red()) + - (0.7152f * col.green()) + - (0.0722f * col.blue()); -} \ No newline at end of file +int luma (QColor& col) +{ return (0.2126f * col.red()) + + (0.7152f * col.green()) + + (0.0722f * col.blue()); +}
--- a/src/colors.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/colors.h Thu Oct 03 20:56:20 2013 +0300 @@ -16,19 +16,19 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef COLORS_H -#define COLORS_H +#ifndef LDFORGE_COLORS_H +#define LDFORGE_COLORS_H #include <QColor> #include "common.h" #define MAX_COLORS 512 -class LDColor { -public: - str name, hexcode; - QColor faceColor, edgeColor; - short index; +class LDColor +{ public: + str name, hexcode; + QColor faceColor, edgeColor; + short index; }; void initColors(); @@ -42,4 +42,4 @@ static const short maincolor = 16; static const short edgecolor = 24; -#endif // COLORS_H \ No newline at end of file +#endif // LDFORGE_COLORS_H
--- a/src/common.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/common.h Thu Oct 03 20:56:20 2013 +0300 @@ -48,9 +48,6 @@ // RC Number for BUILD_RC #define RC_NUMBER 0 -// Uncomment for portable build... maybe it's time to move to cmake? -// #define PORTABLE - // ============================================= #if (BUILD_ID != BUILD_INTERNAL) #define RELEASE @@ -183,4 +180,4 @@ typedef void FILE; // :| #endif // IN_IDE_PARSER -#endif // COMMON_H \ No newline at end of file +#endif // COMMON_H
--- a/src/config.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/config.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -33,13 +33,14 @@ #include "file.h" Config* g_configPointers[MAX_CONFIG]; -static ushort g_cfgPointerCursor = 0; +static int g_cfgPointerCursor = 0; // ============================================================================= // Get the QSettings object. A portable build refers to a file in the current // directory, a non-portable build to ~/.config/LDForge or to registry. // ----------------------------------------------------------------------------- -static QSettings* getSettingsObject() { +static QSettings* getSettingsObject() +{ #ifdef PORTABLE # ifdef _WIN32 # define EXTENSION ".ini" @@ -58,18 +59,18 @@ // ============================================================================= // Load the configuration from file // ----------------------------------------------------------------------------- -bool Config::load() { - QSettings* settings = getSettingsObject(); +bool Config::load() +{ QSettings* settings = getSettingsObject(); print ("config::load: Loading configuration file from %1\n", settings->fileName()); - - for (Config* cfg : g_configPointers) { - if (!cfg) + + for (Config* cfg : g_configPointers) + { if (!cfg) break; - + QVariant val = settings->value (cfg->name, cfg->defaultVariant()); cfg->loadFromVariant (val); } - + settings->deleteLater(); return true; } @@ -77,20 +78,20 @@ // ============================================================================= // Save the configuration to disk // ----------------------------------------------------------------------------- -bool Config::save() { - QSettings* settings = getSettingsObject(); +bool Config::save() +{ QSettings* settings = getSettingsObject(); print ("Saving configuration to %1...\n", settings->fileName()); - - for (Config* cfg : g_configPointers) { - if (!cfg) + + for (Config* cfg : g_configPointers) + { if (!cfg) break; - + if (cfg->isDefault()) continue; - + settings->setValue (cfg->name, cfg->toVariant()); } - + settings->sync(); settings->deleteLater(); return true; @@ -99,11 +100,11 @@ // ============================================================================= // Reset configuration defaults. // ----------------------------------------------------------------------------- -void Config::reset() { - for (Config* cfg : g_configPointers) { - if (!cfg) +void Config::reset() +{ for (Config * cfg : g_configPointers) + { if (!cfg) break; - + cfg->resetValue(); } } @@ -112,15 +113,15 @@ // Where is the configuration file located at? Note that the Windows build uses // the registry so only use this with PORTABLE code. // ----------------------------------------------------------------------------- -str Config::filepath (str file) { - return Config::dirpath() + DIRSLASH + file; +str Config::filepath (str file) +{ return Config::dirpath() + DIRSLASH + file; } // ============================================================================= // Directory of the configuration file. PORTABLE code here as well. // ----------------------------------------------------------------------------- -str Config::dirpath() { - QSettings* cfg = getSettingsObject(); +str Config::dirpath() +{ QSettings* cfg = getSettingsObject(); return dirname (cfg->fileName()); } @@ -129,10 +130,10 @@ // on the vector's c-tor being called before the configs' c-tors. With global // variables we cannot assume that!! Therefore we need to use a C-style array here. // ----------------------------------------------------------------------------- -void Config::addToArray (Config* ptr) { - if (g_cfgPointerCursor == 0) +void Config::addToArray (Config* ptr) +{ if (g_cfgPointerCursor == 0) memset (g_configPointers, 0, sizeof g_configPointers); - + assert (g_cfgPointerCursor < MAX_CONFIG); g_configPointers[g_cfgPointerCursor++] = ptr; -} \ No newline at end of file +}
--- a/src/config.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/config.h Thu Oct 03 20:56:20 2013 +0300 @@ -37,42 +37,53 @@ #define extern_cfg(T, NAME) extern T##Config NAME // ========================================================= -class Config { -public: - enum Type { - Int, - String, - Float, - Bool, - KeySequence, - List, - }; +class Config +{ public: + enum Type + { Int, + String, + Float, + Bool, + KeySequence, + List, + }; - Config (const char* name, const char* defstring); - const char* name; + Config (const char* name, const char* defstring); + const char* name; + + virtual Type getType() const + { return (Type) 0; + } + + virtual void resetValue() {} + virtual void loadFromVariant (const QVariant& val) + { (void) val; + } - virtual Type getType() const { - return (Type) 0; - } - - virtual void resetValue() {} - virtual void loadFromVariant (const QVariant& val) { (void) val; } - virtual bool isDefault() const { return false; } - virtual QVariant toVariant() const { return QVariant(); } - virtual QVariant defaultVariant() const { return QVariant(); } - - // ------------------------------------------ - static bool load(); - static bool save(); - static void reset(); - static str dirpath(); - static str filepath (str file); - -protected: - static void addToArray (Config* ptr); - -private: - const char* m_defstring; + virtual bool isDefault() const + { return false; + } + + virtual QVariant toVariant() const + { return QVariant(); + } + + virtual QVariant defaultVariant() const + { return QVariant(); + } + + // ------------------------------------------ + static bool load(); + static bool save(); + static void reset(); + static str dirpath(); + static str filepath (str file); + + protected: + static void addToArray (Config* ptr); + + private: + const char* m_defstring; }; // ============================================================================= @@ -130,106 +141,106 @@ T operator--(int) { return value--; } // ============================================================================= -class IntConfig : public Config { -public: - IMPLEMENT_CONFIG (Int, int) - DEFINE_ALL_COMPARE_OPERATORS (int) - DEFINE_INCREMENT_OPERATORS (int) - DEFINE_BINARY_OPERATOR (int, +) - DEFINE_BINARY_OPERATOR (int, -) - DEFINE_BINARY_OPERATOR (int, *) - DEFINE_BINARY_OPERATOR (int, /) - DEFINE_BINARY_OPERATOR (int, %) - DEFINE_BINARY_OPERATOR (int, ^) - DEFINE_BINARY_OPERATOR (int, |) - DEFINE_BINARY_OPERATOR (int, &) - DEFINE_BINARY_OPERATOR (int, >>) - DEFINE_BINARY_OPERATOR (int, <<) - DEFINE_UNARY_OPERATOR (int, !) - DEFINE_UNARY_OPERATOR (int, ~) - DEFINE_UNARY_OPERATOR (int, -) - DEFINE_UNARY_OPERATOR (int, +) - DEFINE_ASSIGN_OPERATOR (int, =) - DEFINE_ASSIGN_OPERATOR (int, +=) - DEFINE_ASSIGN_OPERATOR (int, -=) - DEFINE_ASSIGN_OPERATOR (int, *=) - DEFINE_ASSIGN_OPERATOR (int, /=) - DEFINE_ASSIGN_OPERATOR (int, %=) - DEFINE_ASSIGN_OPERATOR (int, >>=) - DEFINE_ASSIGN_OPERATOR (int, <<=) +class IntConfig : public Config +{ public: + IMPLEMENT_CONFIG (Int, int) + DEFINE_ALL_COMPARE_OPERATORS (int) + DEFINE_INCREMENT_OPERATORS (int) + DEFINE_BINARY_OPERATOR (int, +) + DEFINE_BINARY_OPERATOR (int, -) + DEFINE_BINARY_OPERATOR (int, *) + DEFINE_BINARY_OPERATOR (int, /) + DEFINE_BINARY_OPERATOR (int, %) + DEFINE_BINARY_OPERATOR (int, ^) + DEFINE_BINARY_OPERATOR (int, |) + DEFINE_BINARY_OPERATOR (int, &) + DEFINE_BINARY_OPERATOR (int, >>) + DEFINE_BINARY_OPERATOR (int, <<) + DEFINE_UNARY_OPERATOR (int, !) + DEFINE_UNARY_OPERATOR (int, ~) + DEFINE_UNARY_OPERATOR (int, -) + DEFINE_UNARY_OPERATOR (int, +) + DEFINE_ASSIGN_OPERATOR (int, =) + DEFINE_ASSIGN_OPERATOR (int, +=) + DEFINE_ASSIGN_OPERATOR (int, -=) + DEFINE_ASSIGN_OPERATOR (int, *=) + DEFINE_ASSIGN_OPERATOR (int, /=) + DEFINE_ASSIGN_OPERATOR (int, %=) + DEFINE_ASSIGN_OPERATOR (int, >>=) + DEFINE_ASSIGN_OPERATOR (int, <<=) }; // ============================================================================= -class StringConfig : public Config { -public: - IMPLEMENT_CONFIG (String, str) - - DEFINE_COMPARE_OPERATOR (str, ==) - DEFINE_COMPARE_OPERATOR (str, !=) - DEFINE_ASSIGN_OPERATOR (str, =) - DEFINE_ASSIGN_OPERATOR (str, +=) - - QChar operator[] (int n) { - return value[n]; - } +class StringConfig : public Config +{ public: + IMPLEMENT_CONFIG (String, str) + + DEFINE_COMPARE_OPERATOR (str, ==) + DEFINE_COMPARE_OPERATOR (str, !=) + DEFINE_ASSIGN_OPERATOR (str, =) + DEFINE_ASSIGN_OPERATOR (str, +=) + + QChar operator[] (int n) + { return value[n]; + } }; // ============================================================================= -class FloatConfig : public Config { -public: - IMPLEMENT_CONFIG (Float, float) - DEFINE_ALL_COMPARE_OPERATORS (float) - DEFINE_INCREMENT_OPERATORS (float) - DEFINE_BINARY_OPERATOR (float, +) - DEFINE_BINARY_OPERATOR (float, -) - DEFINE_BINARY_OPERATOR (float, *) - DEFINE_UNARY_OPERATOR (float, !) - DEFINE_ASSIGN_OPERATOR (float, =) - DEFINE_ASSIGN_OPERATOR (float, +=) - DEFINE_ASSIGN_OPERATOR (float, -=) - DEFINE_ASSIGN_OPERATOR (float, *=) +class FloatConfig : public Config +{ public: + IMPLEMENT_CONFIG (Float, float) + DEFINE_ALL_COMPARE_OPERATORS (float) + DEFINE_INCREMENT_OPERATORS (float) + DEFINE_BINARY_OPERATOR (float, +) + DEFINE_BINARY_OPERATOR (float, -) + DEFINE_BINARY_OPERATOR (float, *) + DEFINE_UNARY_OPERATOR (float, !) + DEFINE_ASSIGN_OPERATOR (float, =) + DEFINE_ASSIGN_OPERATOR (float, +=) + DEFINE_ASSIGN_OPERATOR (float, -=) + DEFINE_ASSIGN_OPERATOR (float, *=) }; // ============================================================================= -class BoolConfig : public Config { -public: - IMPLEMENT_CONFIG (Bool, bool) - DEFINE_ALL_COMPARE_OPERATORS (bool) - DEFINE_ASSIGN_OPERATOR (bool, =) +class BoolConfig : public Config +{ public: + IMPLEMENT_CONFIG (Bool, bool) + DEFINE_ALL_COMPARE_OPERATORS (bool) + DEFINE_ASSIGN_OPERATOR (bool, =) }; // ============================================================================= -class KeySequenceConfig : public Config { -public: - IMPLEMENT_CONFIG (KeySequence, QKeySequence) - DEFINE_ALL_COMPARE_OPERATORS (QKeySequence) - DEFINE_ASSIGN_OPERATOR (QKeySequence, =) +class KeySequenceConfig : public Config +{ public: + IMPLEMENT_CONFIG (KeySequence, QKeySequence) + DEFINE_ALL_COMPARE_OPERATORS (QKeySequence) + DEFINE_ASSIGN_OPERATOR (QKeySequence, =) }; // ============================================================================= -class ListConfig : public Config { -public: - IMPLEMENT_CONFIG (List, QList<QVariant>) - DEFINE_ASSIGN_OPERATOR (QList<QVariant>, =) - - typedef QList<QVariant>::iterator it; - typedef QList<QVariant>::const_iterator c_it; - - it begin() { - return value.begin(); - } - - c_it begin() const { - return value.constBegin(); - } - - it end() { - return value.end(); - } - - c_it end() const { - return value.constEnd(); - } +class ListConfig : public Config +{ public: + IMPLEMENT_CONFIG (List, QList<QVariant>) + DEFINE_ASSIGN_OPERATOR (QList<QVariant>, =) + + typedef QList<QVariant>::iterator it; + typedef QList<QVariant>::const_iterator c_it; + + it begin() + { return value.begin(); + } + + c_it begin() const + { return value.constBegin(); + } + + it end() + { return value.end(); + } + + c_it end() const + { return value.constEnd(); + } }; -#endif // CONFIG_H \ No newline at end of file +#endif // CONFIG_H
--- a/src/configDialog.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/configDialog.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -84,19 +84,19 @@ ConfigDialog::ConfigDialog (ConfigDialog::Tab deftab, QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) { - assert (g_win); + assert (g_win != null); ui = new Ui_ConfigUI; ui->setupUi (this); - + // Interface tab setButtonBackground (ui->backgroundColorButton, gl_bgcolor); connect (ui->backgroundColorButton, SIGNAL (clicked()), - this, SLOT (slot_setGLBackground())); - + this, SLOT (slot_setGLBackground())); + setButtonBackground (ui->mainColorButton, gl_maincolor); connect (ui->mainColorButton, SIGNAL (clicked()), - this, SLOT (slot_setGLForeground())); - + this, SLOT (slot_setGLForeground())); + ui->mainColorAlpha->setValue (gl_maincolor_alpha * 10.0f); ui->lineThickness->setValue (gl_linethickness); ui->colorizeObjects->setChecked (lv_colorize); @@ -104,21 +104,21 @@ ui->blackEdges->setChecked (gl_blackedges); ui->implicitFiles->setChecked (gui_implicitfiles); ui->m_logostuds->setChecked (gl_logostuds); - + ulong i = 0; #define act(N) addShortcut (key_##N, ACTION(N), i); #include "actions.h" - + ui->shortcutsList->setSortingEnabled (true); ui->shortcutsList->sortItems(); - + connect (ui->shortcut_set, SIGNAL (clicked()), this, SLOT (slot_setShortcut())); connect (ui->shortcut_reset, SIGNAL (clicked()), this, SLOT (slot_resetShortcut())); connect (ui->shortcut_clear, SIGNAL (clicked()), this, SLOT (slot_clearShortcut())); - + quickColors = quickColorsFromConfig(); updateQuickColorList(); - + connect (ui->quickColor_add, SIGNAL (clicked()), this, SLOT (slot_setColor())); connect (ui->quickColor_remove, SIGNAL (clicked()), this, SLOT (slot_delColor())); connect (ui->quickColor_edit, SIGNAL (clicked()), this, SLOT (slot_setColor())); @@ -126,92 +126,92 @@ connect (ui->quickColor_moveUp, SIGNAL (clicked()), this, SLOT (slot_moveColor())); connect (ui->quickColor_moveDown, SIGNAL (clicked()), this, SLOT (slot_moveColor())); connect (ui->quickColor_clear, SIGNAL (clicked()), this, SLOT (slot_clearColors())); - + ui->downloadPath->setText (net_downloadpath); ui->guessNetPaths->setChecked (net_guesspaths); ui->autoCloseNetPrompt->setChecked (net_autoclose); - connect (ui->findDownloadPath, SIGNAL (clicked(bool)), this, SLOT (slot_findDownloadFolder())); - + connect (ui->findDownloadPath, SIGNAL (clicked (bool)), this, SLOT (slot_findDownloadFolder())); + ui->m_profileName->setText (ld_defaultname); ui->m_profileUsername->setText (ld_defaultuser); ui->m_profileLicense->setCurrentIndex (ld_defaultlicense); ui->tabs->setCurrentIndex (deftab); - + initGrids(); initExtProgs(); - + connect (ui->buttonBox, SIGNAL (clicked (QAbstractButton*)), - this, SLOT (buttonClicked(QAbstractButton*))); + this, SLOT (buttonClicked (QAbstractButton*))); } // ============================================================================= // ----------------------------------------------------------------------------- -ConfigDialog::~ConfigDialog() { - delete ui; +ConfigDialog::~ConfigDialog() +{ delete ui; } // ============================================================================= // Adds a shortcut entry to the list of shortcuts. // ----------------------------------------------------------------------------- -void ConfigDialog::addShortcut (KeySequenceConfig& cfg, QAction* act, ulong& i) { - ShortcutListItem* item = new ShortcutListItem; +void ConfigDialog::addShortcut (KeySequenceConfig& cfg, QAction* act, ulong& i) +{ ShortcutListItem* item = new ShortcutListItem; item->setIcon (act->icon()); item->setKeyConfig (&cfg); item->setAction (act); setShortcutText (item); - + // If the action doesn't have a valid icon, use an empty one // so that the list is kept aligned. if (act->icon().isNull()) item->setIcon (getIcon ("empty")); - + ui->shortcutsList->insertItem (i++, item); } // ============================================================================= // Initializes the table of grid stuff // ----------------------------------------------------------------------------- -void ConfigDialog::initGrids() { - QGridLayout* gridlayout = new QGridLayout; +void ConfigDialog::initGrids() +{ QGridLayout* gridlayout = new QGridLayout; QLabel* xlabel = new QLabel ("X"), - *ylabel = new QLabel ("Y"), - *zlabel = new QLabel ("Z"), - *anglabel = new QLabel ("Angle"); + *ylabel = new QLabel ("Y"), + *zlabel = new QLabel ("Z"), + *anglabel = new QLabel ("Angle"); short i = 1; - - for (QLabel* label : initlist<QLabel*> ({ xlabel, ylabel, zlabel, anglabel })) { - label->setAlignment (Qt::AlignCenter); + +for (QLabel * label : initlist<QLabel*> ( { xlabel, ylabel, zlabel, anglabel })) + { label->setAlignment (Qt::AlignCenter); gridlayout->addWidget (label, 0, i++); } - - for (int i = 0; i < g_NumGrids; ++i) { - // Icon + + for (int i = 0; i < g_NumGrids; ++i) + { // Icon lb_gridIcons[i] = new QLabel; lb_gridIcons[i]->setPixmap (getIcon (fmt ("grid-%1", str (g_GridInfo[i].name).toLower()))); - + // Text label lb_gridLabels[i] = new QLabel (fmt ("%1:", g_GridInfo[i].name)); - + QHBoxLayout* labellayout = new QHBoxLayout; labellayout->addWidget (lb_gridIcons[i]); labellayout->addWidget (lb_gridLabels[i]); gridlayout->addLayout (labellayout, i + 1, 0); - + // Add the widgets - for (int j = 0; j < 4; ++j) { - dsb_gridData[i][j] = new QDoubleSpinBox; + for (int j = 0; j < 4; ++j) + { dsb_gridData[i][j] = new QDoubleSpinBox; dsb_gridData[i][j]->setValue (g_GridInfo[i].confs[j]->value); gridlayout->addWidget (dsb_gridData[i][j], i + 1, j + 1); } } - + ui->grids->setLayout (gridlayout); } // ============================================================================= // ----------------------------------------------------------------------------- -static const struct extProgInfo { - const str name, iconname; +static const struct extProgInfo +{ const str name, iconname; StringConfig* const path; mutable QLineEdit* input; mutable QPushButton* setPathButton; @@ -219,7 +219,8 @@ BoolConfig* const wine; mutable QCheckBox* wineBox; #endif // _WIN32 -} g_extProgInfo[] = { +} g_extProgInfo[] = +{ #ifndef _WIN32 # define EXTPROG(NAME, LOWNAME) { #NAME, #LOWNAME, &prog_##LOWNAME, null, null, &prog_##LOWNAME##_wine, null }, #else @@ -237,51 +238,51 @@ // ============================================================================= // Initializes the stuff in the ext programs tab // ----------------------------------------------------------------------------- -void ConfigDialog::initExtProgs() { - QGridLayout* pathsLayout = new QGridLayout; +void ConfigDialog::initExtProgs() +{ QGridLayout* pathsLayout = new QGridLayout; ulong row = 0; - - for (const extProgInfo & info : g_extProgInfo) { - QLabel* icon = new QLabel, + +for (const extProgInfo & info : g_extProgInfo) + { QLabel* icon = new QLabel, *progLabel = new QLabel (info.name); QLineEdit* input = new QLineEdit; QPushButton* setPathButton = new QPushButton; - + icon->setPixmap (getIcon (info.iconname)); input->setText (info.path->value); setPathButton->setIcon (getIcon ("folder")); info.input = input; info.setPathButton = setPathButton; - + connect (setPathButton, SIGNAL (clicked()), this, SLOT (slot_setExtProgPath())); - + pathsLayout->addWidget (icon, row, 0); pathsLayout->addWidget (progLabel, row, 1); pathsLayout->addWidget (input, row, 2); pathsLayout->addWidget (setPathButton, row, 3); - + #ifndef _WIN32 QCheckBox* wineBox = new QCheckBox ("Wine"); wineBox->setChecked (*info.wine); info.wineBox = wineBox; pathsLayout->addWidget (wineBox, row, 4); #endif - + ++row; } - + ui->extProgs->setLayout (pathsLayout); } // ============================================================================= // Set the settings based on widget data. // ----------------------------------------------------------------------------- -void ConfigDialog::applySettings() { - // Apply configuration +void ConfigDialog::applySettings() +{ // Apply configuration lv_colorize = ui->colorizeObjects->isChecked(); gl_colorbfc = ui->colorBFC->isChecked(); gl_blackedges = ui->blackEdges->isChecked(); - gl_maincolor_alpha = ((double) ui->mainColorAlpha->value()) / 10.0f; + gl_maincolor_alpha = ( (double) ui->mainColorAlpha->value()) / 10.0f; gl_linethickness = ui->lineThickness->value(); gui_implicitfiles = ui->implicitFiles->isChecked(); net_downloadpath = ui->downloadPath->text(); @@ -291,29 +292,29 @@ ld_defaultuser = ui->m_profileUsername->text(); ld_defaultname = ui->m_profileName->text(); ld_defaultlicense = ui->m_profileLicense->currentIndex(); - + // Rebuild the quick color toolbar g_win->setQuickColors (quickColors); gui_colortoolbar = quickColorString(); - + // Set the grid settings for (int i = 0; i < g_NumGrids; ++i) for (int j = 0; j < 4; ++j) g_GridInfo[i].confs[j]->value = dsb_gridData[i][j]->value(); - + // Apply key shortcuts #define act(N) ACTION(N)->setShortcut (key_##N); #include "actions.h" - + // Ext program settings - for (const extProgInfo & info : g_extProgInfo) { - *info.path = info.input->text(); - +for (const extProgInfo & info : g_extProgInfo) + { *info.path = info.input->text(); + #ifndef _WIN32 *info.wine = info.wineBox->isChecked(); #endif // _WIN32 } - + Config::save(); reloadAllSubfiles(); loadLogoedStuds(); @@ -326,53 +327,56 @@ // ============================================================================= // A dialog button was clicked // ----------------------------------------------------------------------------- -void ConfigDialog::buttonClicked (QAbstractButton* button) { - typedef QDialogButtonBox QDDB; +void ConfigDialog::buttonClicked (QAbstractButton* button) +{ typedef QDialogButtonBox QDDB; QDialogButtonBox* dbb = ui->buttonBox; - - if (button == dbb->button (QDDB::Ok)) { - applySettings(); + + if (button == dbb->button (QDDB::Ok)) + { applySettings(); accept(); - } elif (button == dbb->button (QDDB::Apply)) { - applySettings(); - } elif (button == dbb->button (QDDB::Cancel)) { - reject(); + } elif (button == dbb->button (QDDB::Apply)) + + { applySettings(); + } elif (button == dbb->button (QDDB::Cancel)) + { reject(); } } // ============================================================================= // Update the list of color toolbar items in the quick color tab. // ----------------------------------------------------------------------------- -void ConfigDialog::updateQuickColorList (LDQuickColor* sel) { - for (QListWidgetItem* item : quickColorItems) +void ConfigDialog::updateQuickColorList (LDQuickColor* sel) +{ for (QListWidgetItem * item : quickColorItems) delete item; - + quickColorItems.clear(); - + // Init table items - for (LDQuickColor& entry : quickColors) { - QListWidgetItem* item = new QListWidgetItem; - - if (entry.isSeparator()) { - item->setText ("--------"); +for (LDQuickColor & entry : quickColors) + { QListWidgetItem* item = new QListWidgetItem; + + if (entry.isSeparator()) + { item->setText ("--------"); item->setIcon (getIcon ("empty")); - } else { - LDColor* col = entry.color(); - - if (col == null) { - item->setText ("[[unknown color]]"); + } + else + { LDColor* col = entry.color(); + + if (col == null) + { item->setText ("[[unknown color]]"); item->setIcon (getIcon ("error")); - } else { - item->setText (col->name); + } + else + { item->setText (col->name); item->setIcon (makeColorIcon (col, 16)); } } - + ui->quickColorList->addItem (item); quickColorItems << item; - - if (sel && &entry == sel) { - ui->quickColorList->setCurrentItem (item); + + if (sel && &entry == sel) + { ui->quickColorList->setCurrentItem (item); ui->quickColorList->scrollToItem (item); } } @@ -381,43 +385,43 @@ // ============================================================================= // Quick colors: add or edit button was clicked. // ----------------------------------------------------------------------------- -void ConfigDialog::slot_setColor() { - LDQuickColor* entry = null; +void ConfigDialog::slot_setColor() +{ LDQuickColor* entry = null; QListWidgetItem* item = null; const bool isNew = static_cast<QPushButton*> (sender()) == ui->quickColor_add; - - if (isNew == false) { - item = getSelectedQuickColor(); - + + if (isNew == false) + { item = getSelectedQuickColor(); + if (!item) return; - + ulong i = getItemRow (item, quickColorItems); entry = &quickColors[i]; - + if (entry->isSeparator() == true) return; // don't color separators } - + short defval = entry ? entry->color()->index : -1; short val; - + if (ColorSelector::getColor (val, defval, this) == false) return; - + if (entry) entry->setColor (getColor (val)); - else { - LDQuickColor entry (getColor (val), null); - + else + { LDQuickColor entry (getColor (val), null); + item = getSelectedQuickColor(); ulong idx; - + if (item) idx = getItemRow (item, quickColorItems) + 1; else idx = quickColorItems.size(); - + quickColors.insert (idx, entry); entry = quickColors[idx]; } @@ -428,10 +432,10 @@ // ============================================================================= // Remove a quick color // ----------------------------------------------------------------------------- -void ConfigDialog::slot_delColor() { - if (ui->quickColorList->selectedItems().size() == 0) +void ConfigDialog::slot_delColor() +{ if (ui->quickColorList->selectedItems().size() == 0) return; - + QListWidgetItem* item = ui->quickColorList->selectedItems() [0]; quickColors.erase (getItemRow (item, quickColorItems)); updateQuickColorList(); @@ -440,52 +444,52 @@ // ============================================================================= // Move a quick color up/down // ----------------------------------------------------------------------------- -void ConfigDialog::slot_moveColor() { - const bool up = (static_cast<QPushButton*> (sender()) == ui->quickColor_moveUp); - +void ConfigDialog::slot_moveColor() +{ const bool up = (static_cast<QPushButton*> (sender()) == ui->quickColor_moveUp); + if (ui->quickColorList->selectedItems().size() == 0) return; - + QListWidgetItem* item = ui->quickColorList->selectedItems() [0]; int idx = getItemRow (item, quickColorItems); int dest = up ? (idx - 1) : (idx + 1); - + if (dest < 0 || (ulong) dest >= quickColorItems.size()) return; // destination out of bounds - + LDQuickColor tmp = quickColors[dest]; quickColors[dest] = quickColors[idx]; quickColors[idx] = tmp; - + updateQuickColorList (&quickColors[dest]); } // ============================================================================= // Add a separator to quick colors // ----------------------------------------------------------------------------- -void ConfigDialog::slot_addColorSeparator() { - quickColors << LDQuickColor::getSeparator(); +void ConfigDialog::slot_addColorSeparator() +{ quickColors << LDQuickColor::getSeparator(); updateQuickColorList (&quickColors[quickColors.size() - 1]); } // ============================================================================= // Clear all quick colors // ----------------------------------------------------------------------------- -void ConfigDialog::slot_clearColors() { - quickColors.clear(); +void ConfigDialog::slot_clearColors() +{ quickColors.clear(); updateQuickColorList(); } // ============================================================================= // Pick a color and set the appropriate configuration option. // ----------------------------------------------------------------------------- -void ConfigDialog::pickColor (StringConfig& conf, QPushButton* button) { - QColor col = QColorDialog::getColor (QColor (conf)); - - if (col.isValid()) { - uchar r = col.red(), - g = col.green(), - b = col.blue(); +void ConfigDialog::pickColor (StringConfig& conf, QPushButton* button) +{ QColor col = QColorDialog::getColor (QColor (conf)); + + if (col.isValid()) + { uchar r = col.red(), + g = col.green(), + b = col.blue(); conf.value.sprintf ("#%.2X%.2X%.2X", r, g, b); setButtonBackground (button, conf.value); } @@ -493,21 +497,21 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void ConfigDialog::slot_setGLBackground() { - pickColor (gl_bgcolor, ui->backgroundColorButton); +void ConfigDialog::slot_setGLBackground() +{ pickColor (gl_bgcolor, ui->backgroundColorButton); } // ============================================================================= // ----------------------------------------------------------------------------- -void ConfigDialog::slot_setGLForeground() { - pickColor (gl_maincolor, ui->mainColorButton); +void ConfigDialog::slot_setGLForeground() +{ pickColor (gl_maincolor, ui->mainColorButton); } // ============================================================================= // Sets background color of a given button. // ----------------------------------------------------------------------------- -void ConfigDialog::setButtonBackground (QPushButton* button, str value) { - button->setIcon (getIcon ("colorselect")); +void ConfigDialog::setButtonBackground (QPushButton* button, str value) +{ button->setIcon (getIcon ("colorselect")); button->setAutoFillBackground (true); button->setStyleSheet (fmt ("background-color: %1", value)); } @@ -515,51 +519,52 @@ // ============================================================================= // Finds the given list widget item in the list of widget items given. // ----------------------------------------------------------------------------- -int ConfigDialog::getItemRow (QListWidgetItem* item, List<QListWidgetItem*>& haystack) { - int i = 0; - - for (QListWidgetItem* it : haystack) { - if (it == item) +int ConfigDialog::getItemRow (QListWidgetItem* item, List<QListWidgetItem*>& haystack) +{ int i = 0; + +for (QListWidgetItem * it : haystack) + { if (it == item) return i; - + ++i; } + return -1; } // ============================================================================= // Which quick color is currently selected? // ----------------------------------------------------------------------------- -QListWidgetItem* ConfigDialog::getSelectedQuickColor() { - if (ui->quickColorList->selectedItems().size() == 0) +QListWidgetItem* ConfigDialog::getSelectedQuickColor() +{ if (ui->quickColorList->selectedItems().size() == 0) return null; - - return ui->quickColorList->selectedItems()[0]; + + return ui->quickColorList->selectedItems() [0]; } // ============================================================================= // Get the list of shortcuts selected // ----------------------------------------------------------------------------- -QList<ShortcutListItem*> ConfigDialog::getShortcutSelection() { - QList<ShortcutListItem*> out; - - for (QListWidgetItem* entry : ui->shortcutsList->selectedItems()) +QList<ShortcutListItem*> ConfigDialog::getShortcutSelection() +{ QList<ShortcutListItem*> out; + +for (QListWidgetItem * entry : ui->shortcutsList->selectedItems()) out << static_cast<ShortcutListItem*> (entry); - + return out; } // ============================================================================= // Edit the shortcut of a given action. // ----------------------------------------------------------------------------- -void ConfigDialog::slot_setShortcut() { - QList<ShortcutListItem*> sel = getShortcutSelection(); - +void ConfigDialog::slot_setShortcut() +{ QList<ShortcutListItem*> sel = getShortcutSelection(); + if (sel.size() < 1) return; - + ShortcutListItem* item = sel[0]; - + if (KeySequenceDialog::staticDialog (item->keyConfig(), this)) setShortcutText (item); } @@ -567,11 +572,11 @@ // ============================================================================= // Reset a shortcut to defaults // ----------------------------------------------------------------------------- -void ConfigDialog::slot_resetShortcut() { - QList<ShortcutListItem*> sel = getShortcutSelection(); - - for (ShortcutListItem* item : sel) { - item->keyConfig()->reset(); +void ConfigDialog::slot_resetShortcut() +{ QList<ShortcutListItem*> sel = getShortcutSelection(); + +for (ShortcutListItem * item : sel) + { item->keyConfig()->reset(); setShortcutText (item); } } @@ -579,11 +584,11 @@ // ============================================================================= // Remove the shortcut of an action. // ----------------------------------------------------------------------------- -void ConfigDialog::slot_clearShortcut() { - QList<ShortcutListItem*> sel = getShortcutSelection(); - - for (ShortcutListItem* item : sel) { - item->keyConfig()->value = QKeySequence(); +void ConfigDialog::slot_clearShortcut() +{ QList<ShortcutListItem*> sel = getShortcutSelection(); + +for (ShortcutListItem * item : sel) + { item->keyConfig()->value = QKeySequence(); setShortcutText (item); } } @@ -591,38 +596,38 @@ // ============================================================================= // Set the path of an external program // ----------------------------------------------------------------------------- -void ConfigDialog::slot_setExtProgPath() { - const extProgInfo* info = null; - - for (const extProgInfo& it : g_extProgInfo) { - if (it.setPathButton == sender()) { - info = ⁢ +void ConfigDialog::slot_setExtProgPath() +{ const extProgInfo* info = null; + +for (const extProgInfo & it : g_extProgInfo) + { if (it.setPathButton == sender()) + { info = ⁢ break; } } - + assert (info != null); str fpath = QFileDialog::getOpenFileName (this, fmt ("Path to %1", info->name), *info->path, g_extProgPathFilter); - + if (fpath.isEmpty()) return; - + info->input->setText (fpath); } // ============================================================================= // '...' button pressed for the download path // ----------------------------------------------------------------------------- -void ConfigDialog::slot_findDownloadFolder() { - str dpath = QFileDialog::getExistingDirectory(); +void ConfigDialog::slot_findDownloadFolder() +{ str dpath = QFileDialog::getExistingDirectory(); ui->downloadPath->setText (dpath); } // ============================================================================= // Updates the text string for a given shortcut list item // ----------------------------------------------------------------------------- -void ConfigDialog::setShortcutText (ShortcutListItem* item) { - QAction* act = item->action(); +void ConfigDialog::setShortcutText (ShortcutListItem* item) +{ QAction* act = item->action(); str label = act->iconText(); str keybind = item->keyConfig()->value.toString(); item->setText (fmt ("%1 (%2)", label, keybind)); @@ -631,19 +636,19 @@ // ============================================================================= // Gets the configuration string of the quick color toolbar // ----------------------------------------------------------------------------- -str ConfigDialog::quickColorString() { - str val; - - for (const LDQuickColor& entry : quickColors) { - if (val.length() > 0) +str ConfigDialog::quickColorString() +{ str val; + +for (const LDQuickColor & entry : quickColors) + { if (val.length() > 0) val += ':'; - + if (entry.isSeparator()) val += '|'; else val += fmt ("%1", entry.color()->index); } - + return val; } @@ -655,14 +660,14 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ========================================================================================================================= KeySequenceDialog::KeySequenceDialog (QKeySequence seq, QWidget* parent, Qt::WindowFlags f) : - QDialog (parent, f), seq (seq) { - lb_output = new QLabel; + QDialog (parent, f), seq (seq) +{ lb_output = new QLabel; IMPLEMENT_DIALOG_BUTTONS - + setWhatsThis ("Into this dialog you can input a key sequence for use as a " - "shortcut in LDForge. Use OK to confirm the new shortcut and Cancel to " - "dismiss."); - + "shortcut in LDForge. Use OK to confirm the new shortcut and Cancel to " + "dismiss."); + QVBoxLayout* layout = new QVBoxLayout; layout->addWidget (lb_output); layout->addWidget (bbx_buttons); @@ -673,32 +678,32 @@ // ============================================================================= // ----------------------------------------------------------------------------- -bool KeySequenceDialog::staticDialog (KeySequenceConfig* cfg, QWidget* parent) { - KeySequenceDialog dlg (cfg->value, parent); - +bool KeySequenceDialog::staticDialog (KeySequenceConfig* cfg, QWidget* parent) +{ KeySequenceDialog dlg (cfg->value, parent); + if (dlg.exec() == false) return false; - + cfg->value = dlg.seq; return true; } // ============================================================================= // ----------------------------------------------------------------------------- -void KeySequenceDialog::updateOutput() { - str shortcut = seq.toString(); - +void KeySequenceDialog::updateOutput() +{ str shortcut = seq.toString(); + if (seq == QKeySequence()) shortcut = "<empty>"; - + str text = fmt ("<center><b>%1</b></center>", shortcut); lb_output->setText (text); } // ============================================================================= // ----------------------------------------------------------------------------- -void KeySequenceDialog::keyPressEvent (QKeyEvent* ev) { - seq = ev->key() + ev->modifiers(); +void KeySequenceDialog::keyPressEvent (QKeyEvent* ev) +{ seq = ev->key() + ev->modifiers(); updateOutput(); } #include "moc_configDialog.cpp"
--- a/src/configDialog.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/configDialog.h Thu Oct 03 20:56:20 2013 +0300 @@ -27,91 +27,91 @@ class QDoubleSpinBox; // ============================================================================= -class ShortcutListItem : public QListWidgetItem { - PROPERTY (KeySequenceConfig*, keyConfig, setKeyConfig) +class ShortcutListItem : public QListWidgetItem +{ PROPERTY (KeySequenceConfig*, keyConfig, setKeyConfig) PROPERTY (QAction*, action, setAction) - -public: - explicit ShortcutListItem (QListWidget* view = null, int type = Type) : - QListWidgetItem (view, type) {} + + public: + explicit ShortcutListItem (QListWidget* view = null, int type = Type) : + QListWidgetItem (view, type) {} }; // ============================================================================= -class ConfigDialog : public QDialog { - Q_OBJECT - -public: - enum Tab { - InterfaceTab, - ProfileTab, - ShortcutsTab, - QuickColorsTab, - GridsTab, - ExtProgsTab, - DownloadTab - }; - - explicit ConfigDialog (Tab deftab = InterfaceTab, QWidget* parent = null, Qt::WindowFlags f = 0); - virtual ~ConfigDialog(); - float getGridValue (int i, int j) const; - - List<LDQuickColor> quickColors; - QDoubleSpinBox* dsb_gridData[3][4]; - -private: - Ui_ConfigUI* ui; - QLabel* lb_gridLabels[3]; - QLabel* lb_gridIcons[3]; - List<QListWidgetItem*> quickColorItems; - - void applySettings(); - void addShortcut (KeySequenceConfig& cfg, QAction* act, ulong& i); - void setButtonBackground (QPushButton* button, str value); - void pickColor (StringConfig& cfg, QPushButton* button); - void updateQuickColorList (LDQuickColor* sel = null); - void setShortcutText (ShortcutListItem* item); - int getItemRow (QListWidgetItem* item, List<QListWidgetItem*>& haystack); - str quickColorString(); - QListWidgetItem* getSelectedQuickColor(); - QList<ShortcutListItem*> getShortcutSelection(); - void initGrids(); - void initExtProgs(); - -private slots: - void slot_setGLBackground(); - void slot_setGLForeground(); - void slot_setShortcut(); - void slot_resetShortcut(); - void slot_clearShortcut(); - void slot_setColor(); - void slot_delColor(); - void slot_addColorSeparator(); - void slot_moveColor(); - void slot_clearColors(); - void slot_setExtProgPath(); - void slot_findDownloadFolder(); - void buttonClicked (QAbstractButton* button); +class ConfigDialog : public QDialog +{ Q_OBJECT + + public: + enum Tab + { InterfaceTab, + ProfileTab, + ShortcutsTab, + QuickColorsTab, + GridsTab, + ExtProgsTab, + DownloadTab + }; + + explicit ConfigDialog (Tab deftab = InterfaceTab, QWidget* parent = null, Qt::WindowFlags f = 0); + virtual ~ConfigDialog(); + float getGridValue (int i, int j) const; + + List<LDQuickColor> quickColors; + QDoubleSpinBox* dsb_gridData[3][4]; + + private: + Ui_ConfigUI* ui; + QLabel* lb_gridLabels[3]; + QLabel* lb_gridIcons[3]; + List<QListWidgetItem*> quickColorItems; + + void applySettings(); + void addShortcut (KeySequenceConfig& cfg, QAction* act, ulong& i); + void setButtonBackground (QPushButton* button, str value); + void pickColor (StringConfig& cfg, QPushButton* button); + void updateQuickColorList (LDQuickColor* sel = null); + void setShortcutText (ShortcutListItem* item); + int getItemRow (QListWidgetItem* item, List<QListWidgetItem*>& haystack); + str quickColorString(); + QListWidgetItem* getSelectedQuickColor(); + QList<ShortcutListItem*> getShortcutSelection(); + void initGrids(); + void initExtProgs(); + + private slots: + void slot_setGLBackground(); + void slot_setGLForeground(); + void slot_setShortcut(); + void slot_resetShortcut(); + void slot_clearShortcut(); + void slot_setColor(); + void slot_delColor(); + void slot_addColorSeparator(); + void slot_moveColor(); + void slot_clearColors(); + void slot_setExtProgPath(); + void slot_findDownloadFolder(); + void buttonClicked (QAbstractButton* button); }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -class KeySequenceDialog : public QDialog { - Q_OBJECT +class KeySequenceDialog : public QDialog +{ Q_OBJECT + + public: + explicit KeySequenceDialog (QKeySequence seq, QWidget* parent = null, Qt::WindowFlags f = 0); + static bool staticDialog (KeySequenceConfig* cfg, QWidget* parent = null); -public: - explicit KeySequenceDialog (QKeySequence seq, QWidget* parent = null, Qt::WindowFlags f = 0); - static bool staticDialog (KeySequenceConfig* cfg, QWidget* parent = null); - - QLabel* lb_output; - QDialogButtonBox* bbx_buttons; - QKeySequence seq; - -private: - void updateOutput(); - -private slots: - virtual void keyPressEvent (QKeyEvent* ev) override; + QLabel* lb_output; + QDialogButtonBox* bbx_buttons; + QKeySequence seq; + + private: + void updateOutput(); + + private slots: + virtual void keyPressEvent (QKeyEvent* ev) override; }; -#endif // CONFIGDIALOG_H \ No newline at end of file +#endif // CONFIGDIALOG_H
--- a/src/dialogs.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/dialogs.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -48,53 +48,54 @@ // ============================================================================= // ----------------------------------------------------------------------------- -OverlayDialog::OverlayDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) { - ui = new Ui_OverlayUI; +OverlayDialog::OverlayDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) +{ ui = new Ui_OverlayUI; ui->setupUi (this); - - m_cameraArgs = { - { ui->top, GL::Top }, + + m_cameraArgs = + { { ui->top, GL::Top }, { ui->bottom, GL::Bottom }, { ui->front, GL::Front }, { ui->back, GL::Back }, { ui->left, GL::Left }, { ui->right, GL::Right } }; - + GL::Camera cam = g_win->R()->camera(); - + if (cam == GL::Free) cam = GL::Top; - + connect (ui->width, SIGNAL (valueChanged (double)), this, SLOT (slot_dimensionsChanged())); connect (ui->height, SIGNAL (valueChanged (double)), this, SLOT (slot_dimensionsChanged())); connect (ui->buttonBox, SIGNAL (helpRequested()), this, SLOT (slot_help())); connect (ui->fileSearchButton, SIGNAL (clicked (bool)), this, SLOT (slot_fpath())); - + slot_dimensionsChanged(); fillDefaults (cam); } // ============================================================================= // ----------------------------------------------------------------------------- -OverlayDialog::~OverlayDialog() { - delete ui; +OverlayDialog::~OverlayDialog() +{ delete ui; } // ============================================================================= // ----------------------------------------------------------------------------- -void OverlayDialog::fillDefaults (int newcam) { - overlayMeta& info = g_win->R()->getOverlay (newcam); +void OverlayDialog::fillDefaults (int newcam) +{ overlayMeta& info = g_win->R()->getOverlay (newcam); radioDefault<int> (newcam, m_cameraArgs); - - if (info.img != null) { - ui->filename->setText (info.fname); + + if (info.img != null) + { ui->filename->setText (info.fname); ui->originX->setValue (info.ox); ui->originY->setValue (info.oy); ui->width->setValue (info.lw); ui->height->setValue (info.lh); - } else { - ui->filename->setText (""); + } + else + { ui->filename->setText (""); ui->originX->setValue (0); ui->originY->setValue (0); ui->width->setValue (0.0f); @@ -104,40 +105,40 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str OverlayDialog::fpath() const { - return ui->filename->text(); +str OverlayDialog::fpath() const +{ return ui->filename->text(); } -ushort OverlayDialog::ofsx() const { - return ui->originX->value(); +ushort OverlayDialog::ofsx() const +{ return ui->originX->value(); } -ushort OverlayDialog::ofsy() const { - return ui->originY->value(); +ushort OverlayDialog::ofsy() const +{ return ui->originY->value(); } -double OverlayDialog::lwidth() const { - return ui->width->value(); +double OverlayDialog::lwidth() const +{ return ui->width->value(); } -double OverlayDialog::lheight() const { - return ui->height->value(); +double OverlayDialog::lheight() const +{ return ui->height->value(); } -int OverlayDialog::camera() const { - return radioSwitch<int> (GL::Top, m_cameraArgs); +int OverlayDialog::camera() const +{ return radioSwitch<int> (GL::Top, m_cameraArgs); } -void OverlayDialog::slot_fpath() { - ui->filename->setText (QFileDialog::getOpenFileName (null, "Overlay image")); +void OverlayDialog::slot_fpath() +{ ui->filename->setText (QFileDialog::getOpenFileName (null, "Overlay image")); } -void OverlayDialog::slot_help() { - showDocumentation (g_docs_overlays); +void OverlayDialog::slot_help() +{ showDocumentation (g_docs_overlays); } -void OverlayDialog::slot_dimensionsChanged() { - bool enable = (ui->width->value() != 0) || (ui->height->value() != 0); +void OverlayDialog::slot_dimensionsChanged() +{ bool enable = (ui->width->value() != 0) || (ui->height->value() != 0); ui->buttonBox->button (QDialogButtonBox::Ok)->setEnabled (enable); } @@ -146,94 +147,93 @@ LDrawPathDialog::LDrawPathDialog (const bool validDefault, QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f), m_validDefault (validDefault) -{ - ui = new Ui_LDPathUI; +{ ui = new Ui_LDPathUI; ui->setupUi (this); ui->status->setText ("---"); - + if (validDefault) ui->heading->hide(); - else { - cancelButton()->setText ("Exit"); + else + { cancelButton()->setText ("Exit"); cancelButton()->setIcon (getIcon ("exit")); } - + okButton()->setEnabled (false); - + connect (ui->path, SIGNAL (textEdited (QString)), this, SLOT (slot_tryConfigure())); connect (ui->searchButton, SIGNAL (clicked()), this, SLOT (slot_findPath())); connect (ui->buttonBox, SIGNAL (rejected()), this, validDefault ? SLOT (reject()) : SLOT (slot_exit())); connect (ui->buttonBox, SIGNAL (accepted()), this, SLOT (slot_accept())); - + setPath (io_ldpath); - + if (validDefault) slot_tryConfigure(); } // ============================================================================= // ----------------------------------------------------------------------------- -LDrawPathDialog::~LDrawPathDialog() { - delete ui; +LDrawPathDialog::~LDrawPathDialog() +{ delete ui; } -QPushButton* LDrawPathDialog::okButton() { - return ui->buttonBox->button (QDialogButtonBox::Ok); +QPushButton* LDrawPathDialog::okButton() +{ return ui->buttonBox->button (QDialogButtonBox::Ok); } -QPushButton* LDrawPathDialog::cancelButton() { - return ui->buttonBox->button (QDialogButtonBox::Cancel); +QPushButton* LDrawPathDialog::cancelButton() +{ return ui->buttonBox->button (QDialogButtonBox::Cancel); } -void LDrawPathDialog::setPath (str path) { - ui->path->setText (path); +void LDrawPathDialog::setPath (str path) +{ ui->path->setText (path); } -str LDrawPathDialog::filename() const { - return ui->path->text(); +str LDrawPathDialog::filename() const +{ return ui->path->text(); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDrawPathDialog::slot_findPath() { - str newpath = QFileDialog::getExistingDirectory (this, "Find LDraw Path"); - - if (newpath.length() > 0 && newpath != filename()) { - setPath (newpath); +void LDrawPathDialog::slot_findPath() +{ str newpath = QFileDialog::getExistingDirectory (this, "Find LDraw Path"); + + if (newpath.length() > 0 && newpath != filename()) + { setPath (newpath); slot_tryConfigure(); } } // ============================================================================= // ----------------------------------------------------------------------------- -void LDrawPathDialog::slot_exit() { - exit (1); +void LDrawPathDialog::slot_exit() +{ exit (1); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDrawPathDialog::slot_tryConfigure() { - if (LDPaths::tryConfigure (filename()) == false) { - ui->status->setText (fmt ("<span style=\"color:#700; \">%1</span>", LDPaths::getError())); +void LDrawPathDialog::slot_tryConfigure() +{ if (LDPaths::tryConfigure (filename()) == false) + { ui->status->setText (fmt ("<span style=\"color:#700; \">%1</span>", LDPaths::getError())); okButton()->setEnabled (false); return; } - + ui->status->setText ("<span style=\"color: #270; \">OK!</span>"); okButton()->setEnabled (true); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDrawPathDialog::slot_accept() { - Config::save(); +void LDrawPathDialog::slot_accept() +{ Config::save(); accept(); } // ============================================================================= // ----------------------------------------------------------------------------- -OpenProgressDialog::OpenProgressDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) { - ui = new Ui_OpenProgressUI; +OpenProgressDialog::OpenProgressDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) +{ ui = new Ui_OpenProgressUI; ui->setupUi (this); ui->progressText->setText ("Parsing..."); @@ -243,35 +243,35 @@ // ============================================================================= // ----------------------------------------------------------------------------- -OpenProgressDialog::~OpenProgressDialog() { - delete ui; +OpenProgressDialog::~OpenProgressDialog() +{ delete ui; } // ============================================================================= // ----------------------------------------------------------------------------- -READ_ACCESSOR (ulong, OpenProgressDialog::numLines) { - return m_numLines; +READ_ACCESSOR (ulong, OpenProgressDialog::numLines) +{ return m_numLines; } // ============================================================================= // ----------------------------------------------------------------------------- -SET_ACCESSOR (ulong, OpenProgressDialog::setNumLines) { - m_numLines = val; +SET_ACCESSOR (ulong, OpenProgressDialog::setNumLines) +{ m_numLines = val; ui->progressBar->setRange (0, numLines()); updateValues(); } // ============================================================================= // ----------------------------------------------------------------------------- -void OpenProgressDialog::updateValues() { - ui->progressText->setText (fmt ("Parsing... %1 / %2", progress(), numLines())); +void OpenProgressDialog::updateValues() +{ ui->progressText->setText (fmt ("Parsing... %1 / %2", progress(), numLines())); ui->progressBar->setValue (progress()); } // ============================================================================= // ----------------------------------------------------------------------------- -void OpenProgressDialog::updateProgress (int progress) { - m_progress = progress; +void OpenProgressDialog::updateProgress (int progress) +{ m_progress = progress; updateValues(); } @@ -280,58 +280,56 @@ ExtProgPathPrompt::ExtProgPathPrompt (str progName, QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f), ui (new Ui_ExtProgPath) -{ - ui->setupUi (this); - +{ ui->setupUi (this); + str labelText = ui->m_label->text(); labelText.replace ("<PROGRAM>", progName); ui->m_label->setText (labelText); - + connect (ui->m_findPath, SIGNAL (clicked (bool)), this, SLOT (findPath())); } // ============================================================================= // ----------------------------------------------------------------------------- -ExtProgPathPrompt::~ExtProgPathPrompt() { - delete ui; +ExtProgPathPrompt::~ExtProgPathPrompt() +{ delete ui; } // ============================================================================= // ----------------------------------------------------------------------------- -void ExtProgPathPrompt::findPath() { - str path = QFileDialog::getOpenFileName (null, "", "", g_extProgPathFilter); - +void ExtProgPathPrompt::findPath() +{ str path = QFileDialog::getOpenFileName (null, "", "", g_extProgPathFilter); + if (!path.isEmpty()) ui->m_path->setText (path); } // ============================================================================= // ----------------------------------------------------------------------------- -str ExtProgPathPrompt::getPath() const { - return ui->m_path->text(); +str ExtProgPathPrompt::getPath() const +{ return ui->m_path->text(); } // ============================================================================= // ----------------------------------------------------------------------------- AboutDialog::AboutDialog (QWidget* parent, Qt::WindowFlags f) : QDialog (parent, f) -{ - Ui::AboutUI ui; +{ Ui::AboutUI ui; ui.setupUi (this); ui.versionInfo->setText (fmt (tr ("LDForge %1"), fullVersionString())); - + QPushButton* mailButton = new QPushButton; mailButton->setText ("Contact"); mailButton->setIcon (getIcon ("mail")); ui.buttonBox->addButton (static_cast<QAbstractButton*> (mailButton), QDialogButtonBox::HelpRole); connect (ui.buttonBox, SIGNAL (helpRequested()), this, SLOT (slot_mail())); - + setWindowTitle ("About " APPNAME); } // ============================================================================= // ----------------------------------------------------------------------------- -void AboutDialog::slot_mail() { - QDesktopServices::openUrl (QUrl ("mailto:Santeri Piippo <slatenails64@gmail.com>?subject=LDForge")); +void AboutDialog::slot_mail() +{ QDesktopServices::openUrl (QUrl ("mailto:Santeri Piippo <slatenails64@gmail.com>?subject=LDForge")); } #include "moc_dialogs.cpp"
--- a/src/dialogs.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/dialogs.h Thu Oct 03 20:56:20 2013 +0300 @@ -40,99 +40,99 @@ class Ui_LDPathUI; class Ui_OpenProgressUI; -class OverlayDialog : public QDialog { - Q_OBJECT - -public: - explicit OverlayDialog (QWidget* parent = null, Qt::WindowFlags f = 0); - virtual ~OverlayDialog(); - - str fpath() const; - ushort ofsx() const; - ushort ofsy() const; - double lwidth() const; - double lheight() const; - int camera() const; - -private: - Ui_OverlayUI* ui; - List<pair<QRadioButton*, int>> m_cameraArgs; - -private slots: - void slot_fpath(); - void slot_help(); - void slot_dimensionsChanged(); - void fillDefaults (int newcam); +class OverlayDialog : public QDialog +{ Q_OBJECT + + public: + explicit OverlayDialog (QWidget* parent = null, Qt::WindowFlags f = 0); + virtual ~OverlayDialog(); + + str fpath() const; + ushort ofsx() const; + ushort ofsy() const; + double lwidth() const; + double lheight() const; + int camera() const; + + private: + Ui_OverlayUI* ui; + List<pair<QRadioButton*, int>> m_cameraArgs; + + private slots: + void slot_fpath(); + void slot_help(); + void slot_dimensionsChanged(); + void fillDefaults (int newcam); }; // ============================================================================= -class LDrawPathDialog : public QDialog { - Q_OBJECT - -public: - explicit LDrawPathDialog (const bool validDefault, QWidget* parent = null, Qt::WindowFlags f = 0); - virtual ~LDrawPathDialog(); - str filename() const; - void setPath (str path); - -private: - Q_DISABLE_COPY (LDrawPathDialog) - const bool m_validDefault; - Ui_LDPathUI* ui; - QPushButton* okButton(); - QPushButton* cancelButton(); - -private slots: - void slot_findPath(); - void slot_tryConfigure(); - void slot_exit(); - void slot_accept(); +class LDrawPathDialog : public QDialog +{ Q_OBJECT + + public: + explicit LDrawPathDialog (const bool validDefault, QWidget* parent = null, Qt::WindowFlags f = 0); + virtual ~LDrawPathDialog(); + str filename() const; + void setPath (str path); + + private: + Q_DISABLE_COPY (LDrawPathDialog) + const bool m_validDefault; + Ui_LDPathUI* ui; + QPushButton* okButton(); + QPushButton* cancelButton(); + + private slots: + void slot_findPath(); + void slot_tryConfigure(); + void slot_exit(); + void slot_accept(); }; // ============================================================================= -class OpenProgressDialog : public QDialog { - Q_OBJECT +class OpenProgressDialog : public QDialog +{ Q_OBJECT READ_PROPERTY (ulong, progress, setProgress) DECLARE_PROPERTY (ulong, numLines, setNumLines) -public: - explicit OpenProgressDialog (QWidget* parent = null, Qt::WindowFlags f = 0); - virtual ~OpenProgressDialog(); + public: + explicit OpenProgressDialog (QWidget* parent = null, Qt::WindowFlags f = 0); + virtual ~OpenProgressDialog(); -public slots: - void updateProgress (int progress); + public slots: + void updateProgress (int progress); -private: - Ui_OpenProgressUI* ui; + private: + Ui_OpenProgressUI* ui; - void updateValues(); + void updateValues(); }; // ============================================================================= -class ExtProgPathPrompt : public QDialog { - Q_OBJECT - -public: - explicit ExtProgPathPrompt (str progName, QWidget* parent = 0, Qt::WindowFlags f = 0); - virtual ~ExtProgPathPrompt(); - str getPath() const; - -public slots: - void findPath(); - -private: - Ui_ExtProgPath* ui; +class ExtProgPathPrompt : public QDialog +{ Q_OBJECT + + public: + explicit ExtProgPathPrompt (str progName, QWidget* parent = 0, Qt::WindowFlags f = 0); + virtual ~ExtProgPathPrompt(); + str getPath() const; + + public slots: + void findPath(); + + private: + Ui_ExtProgPath* ui; }; // ============================================================================= -class AboutDialog : public QDialog { - Q_OBJECT - -public: - AboutDialog (QWidget* parent = null, Qt::WindowFlags f = 0); - -private slots: - void slot_mail(); +class AboutDialog : public QDialog +{ Q_OBJECT + + public: + AboutDialog (QWidget* parent = null, Qt::WindowFlags f = 0); + + private slots: + void slot_mail(); }; -#endif // DIALOGS_H \ No newline at end of file +#endif // DIALOGS_H
--- a/src/docs.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/docs.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -25,27 +25,27 @@ // ============================================================================= // ----------------------------------------------------------------------------- -class DocumentViewer : public QDialog { -public: - explicit DocumentViewer (QWidget* parent = null, Qt::WindowFlags f = 0) : QDialog (parent, f) { - te_text = new QTextEdit (this); - te_text->setMinimumSize (QSize (400, 300)); - te_text->setReadOnly (true); - - QDialogButtonBox* bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Close); - QVBoxLayout* layout = new QVBoxLayout (this); - layout->addWidget (te_text); - layout->addWidget (bbx_buttons); - - connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject())); - } - - void setText (const char* text) { - te_text->setText (text); - } - -private: - QTextEdit* te_text; +class DocumentViewer : public QDialog +{ public: + explicit DocumentViewer (QWidget* parent = null, Qt::WindowFlags f = 0) : QDialog (parent, f) + { te_text = new QTextEdit (this); + te_text->setMinimumSize (QSize (400, 300)); + te_text->setReadOnly (true); + + QDialogButtonBox* bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Close); + QVBoxLayout* layout = new QVBoxLayout (this); + layout->addWidget (te_text); + layout->addWidget (bbx_buttons); + + connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject())); + } + + void setText (const char* text) + { te_text->setText (text); + } + + private: + QTextEdit* te_text; }; const char* g_docs_overlays = @@ -65,8 +65,8 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void showDocumentation (const char* text) { - DocumentViewer dlg; +void showDocumentation (const char* text) +{ DocumentViewer dlg; dlg.setText (text); dlg.exec(); -} \ No newline at end of file +}
--- a/src/download.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/download.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -29,114 +29,117 @@ #include "file.h" #include "gldraw.h" #include "configDialog.h" +#include "moc_download.cpp" cfg (String, net_downloadpath, ""); cfg (Bool, net_guesspaths, true); cfg (Bool, net_autoclose, false); -constexpr const char* PartDownloader::k_OfficialURL, - *PartDownloader::k_UnofficialURL; +constexpr const char *PartDownloader::k_UnofficialURL; // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloader::k_download() { - str path = getDownloadPath(); - if (path == "" || QDir (path).exists() == false) { - critical (PartDownloader::tr ("You need to specify a valid path for " +void PartDownloader::k_download() +{ str path = getDownloadPath(); + + if (path == "" || QDir (path).exists() == false) + { critical (PartDownloader::tr ("You need to specify a valid path for " "downloaded files in the configuration to download paths.")); - + (new ConfigDialog (ConfigDialog::DownloadTab, null))->exec(); return; } - + PartDownloader* dlg = new PartDownloader; dlg->exec(); } // ============================================================================= // ----------------------------------------------------------------------------- -str PartDownloader::getDownloadPath() { - str path = net_downloadpath; - +str PartDownloader::getDownloadPath() +{ str path = net_downloadpath; + #if DIRSLASH_CHAR != '/' path.replace (DIRSLASH, "/"); #endif - + return path; } // ============================================================================= // ----------------------------------------------------------------------------- -PartDownloader::PartDownloader (QWidget* parent) : QDialog (parent) { - ui = new Ui_DownloadFrom; +PartDownloader::PartDownloader (QWidget* parent) : QDialog (parent) +{ ui = new Ui_DownloadFrom; ui->setupUi (this); ui->fname->setFocus(); ui->progress->horizontalHeader()->setResizeMode (PartLabelColumn, QHeaderView::Stretch); - + m_downloadButton = new QPushButton (tr ("Download")); ui->buttonBox->addButton (m_downloadButton, QDialogButtonBox::ActionRole); getButton (Abort)->setEnabled (false); - + connect (ui->source, SIGNAL (currentIndexChanged (int)), this, SLOT (sourceChanged (int))); connect (ui->buttonBox, SIGNAL (clicked (QAbstractButton*)), this, SLOT (buttonClicked (QAbstractButton*))); } // ============================================================================= // ----------------------------------------------------------------------------- -PartDownloader::~PartDownloader() { - delete ui; +PartDownloader::~PartDownloader() +{ delete ui; } // ============================================================================= // ----------------------------------------------------------------------------- -str PartDownloader::getURL() const { - const Source src = getSource(); +str PartDownloader::getURL() const +{ const Source src = getSource(); str dest; - - switch (src) { - case PartsTracker: - dest = ui->fname->text(); - modifyDest (dest); - return str (k_UnofficialURL) + dest; - - case CustomURL: - return ui->fname->text(); + + switch (src) + { case PartsTracker: + dest = ui->fname->text(); + modifyDest (dest); + return str (k_UnofficialURL) + dest; + + case CustomURL: + return ui->fname->text(); } - + // Shouldn't happen return ""; } // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloader::modifyDest (str& dest) const { - dest = dest.simplified(); - +void PartDownloader::modifyDest (str& dest) const +{ dest = dest.simplified(); + // If the user doesn't want us to guess, stop right here. if (net_guesspaths == false) return; - + // Ensure .dat extension - if (dest.right (4) != ".dat") { - /* Remove the existing extension, if any. It may be we're here over a - typo in the .dat extension. */ + if (dest.right (4) != ".dat") + { // Remove the existing extension, if any. It may be we're here over a + // typo in the .dat extension. const int dotpos = dest.lastIndexOf ("."); + if (dotpos != -1 && dotpos >= dest.length() - 4) dest.chop (dest.length() - dotpos); - + dest += ".dat"; } - - /* If the part starts with s\ or s/, then use parts/s/. Same goes with - 48\ and p/48/. */ - if (dest.left (2) == "s\\" || dest.left (2) == "s/") { - dest.remove (0, 2); + + // If the part starts with s\ or s/, then use parts/s/. Same goes with + // 48\ and p/48/. + if (dest.left (2) == "s\\" || dest.left (2) == "s/") + { dest.remove (0, 2); dest.prepend ("parts/s/"); - } elif (dest.left (3) == "48\\" || dest.left (3) == "48/") { - dest.remove (0, 3); + } elif (dest.left (3) == "48\\" || dest.left (3) == "48/") + + { dest.remove (0, 3); dest.prepend ("p/48/"); } - + /* Try determine where to put this part. We have four directories: parts/, parts/s/, p/, and p/48/. If we haven't already specified either parts/ or p/, we need to add it automatically. Part files @@ -146,34 +149,35 @@ - d** (formed stickers) - p** (patterns) - a lowercase alphabetic letter for variants - + Subfiles (usually) have an s** prefix, in which case we use parts/s/. Note that the regex starts with a '^' so it won't catch already fully given part file names. */ str partRegex = "^u?[0-9]+(c[0-9][0-9]+)*(d[0-9][0-9]+)*[a-z]?(p[0-9a-z][0-9a-z]+)*"; str subpartRegex = partRegex + "s[0-9][0-9]+"; - + partRegex += "\\.dat$"; subpartRegex += "\\.dat$"; - + if (QRegExp (subpartRegex).exactMatch (dest)) dest.prepend ("parts/s/"); + elif (QRegExp (partRegex).exactMatch (dest)) - dest.prepend ("parts/"); + dest.prepend ("parts/"); elif (dest.left (6) != "parts/" && dest.left (2) != "p/") - dest.prepend ("p/"); + dest.prepend ("p/"); } // ============================================================================= // ----------------------------------------------------------------------------- -PartDownloader::Source PartDownloader::getSource() const { - return (Source) ui->source->currentIndex(); +PartDownloader::Source PartDownloader::getSource() const +{ return (Source) ui->source->currentIndex(); } // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloader::sourceChanged (int i) { - if (i == CustomURL) +void PartDownloader::sourceChanged (int i) +{ if (i == CustomURL) ui->fileNameLabel->setText (tr ("URL:")); else ui->fileNameLabel->setText (tr ("File name:")); @@ -181,31 +185,31 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloader::buttonClicked (QAbstractButton* btn) { - if (btn == getButton (Close)) { - reject(); - } elif (btn == getButton (Abort)) { - setAborted (true); - - for (PartDownloadRequest* req : m_requests) +void PartDownloader::buttonClicked (QAbstractButton* btn) +{ if (btn == getButton (Close)) + { reject(); + } elif (btn == getButton (Abort)) + + { setAborted (true); + + for (PartDownloadRequest * req : m_requests) req->abort(); - } elif (btn == getButton (Download)) { - str dest = ui->fname->text(); + } elif (btn == getButton (Download)) + { str dest = ui->fname->text(); setPrimaryFile (null); setAborted (false); - + if (getSource() == CustomURL) dest = basename (getURL()); - + modifyDest (dest); - - if (QFile::exists (PartDownloader::getDownloadPath() + DIRSLASH + dest)) { - const str overwritemsg = fmt (tr ("%1 already exists in download directory. Overwrite?"), dest); - + + if (QFile::exists (PartDownloader::getDownloadPath() + DIRSLASH + dest)) + { const str overwritemsg = fmt (tr ("%1 already exists in download directory. Overwrite?"), dest); if (!confirm (tr ("Overwrite?"), overwritemsg)) return; } - + m_downloadButton->setEnabled (false); ui->progress->setEnabled (true); ui->fname->setEnabled (false); @@ -219,17 +223,17 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloader::downloadFile (str dest, str url, bool primary) { - const int row = ui->progress->rowCount(); - +void PartDownloader::downloadFile (str dest, str url, bool primary) +{ const int row = ui->progress->rowCount(); + // Don't download files repeadetly. if (m_filesToDownload.find (dest) != -1u) return; - + modifyDest (dest); print ("DOWNLOAD: %1 -> %2\n", url, PartDownloader::getDownloadPath() + DIRSLASH + dest); PartDownloadRequest* req = new PartDownloadRequest (url, dest, primary, this); - + m_filesToDownload << dest; m_requests << req; ui->progress->insertRow (row); @@ -239,36 +243,37 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloader::checkIfFinished() { - bool failed = aborted(); - +void PartDownloader::checkIfFinished() +{ bool failed = aborted(); + // If there is some download still working, we're not finished. - for (PartDownloadRequest* req : m_requests) { - if (!req->isFinished()) + for (PartDownloadRequest* req : m_requests) + { if (!req->isFinished()) return; - + if (req->state() == PartDownloadRequest::Failed) failed = true; } - + for (PartDownloadRequest* req : m_requests) delete req; - + m_requests.clear(); - + // Update everything now - if (primaryFile()) { - LDFile::setCurrent (primaryFile()); + if (primaryFile()) + { LDFile::setCurrent (primaryFile()); reloadAllSubfiles(); g_win->fullRefresh(); g_win->R()->resetAngles(); } - - if (net_autoclose && !failed) { - // Close automatically if desired. + + if (net_autoclose && !failed) + { // Close automatically if desired. accept(); - } else { - // Allow the prompt be closed now. + } + else + { // Allow the prompt be closed now. getButton (Abort)->setEnabled (false); getButton (Close)->setEnabled (true); } @@ -276,21 +281,21 @@ // ============================================================================= // ----------------------------------------------------------------------------- -QPushButton* PartDownloader::getButton (PartDownloader::Button i) { - typedef QDialogButtonBox QDBB; +QPushButton* PartDownloader::getButton (PartDownloader::Button i) +{ typedef QDialogButtonBox QDBB; alias btnbox = ui->buttonBox; - - switch (i) { - case Download: - return m_downloadButton; - - case Abort: - return qobject_cast<QPushButton*> (btnbox->button (QDBB::Abort)); - - case Close: - return qobject_cast<QPushButton*> (btnbox->button (QDBB::Close)); + + switch (i) + { case Download: + return m_downloadButton; + + case Abort: + return qobject_cast<QPushButton*> (btnbox->button (QDBB::Abort)); + + case Close: + return qobject_cast<QPushButton*> (btnbox->button (QDBB::Close)); } - + return null; } @@ -310,14 +315,16 @@ { // Make sure that we have a valid destination. str dirpath = dirname (m_fpath); - + QDir dir (dirpath); - if (!dir.exists()) { - print ("Creating %1...\n", dirpath); + + if (!dir.exists()) + { print ("Creating %1...\n", dirpath); + if (!dir.mkpath (dirpath)) critical (fmt (tr ("Couldn't create the directory %1!"), dirpath)); } - + m_reply = m_nam->get (QNetworkRequest (QUrl (url))); connect (m_reply, SIGNAL (finished()), this, SLOT (downloadFinished())); connect (m_reply, SIGNAL (readyRead()), this, SLOT (readyRead())); @@ -330,111 +337,114 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloadRequest::updateToTable() { - const int labelcol = PartDownloader::PartLabelColumn, - progcol = PartDownloader::ProgressColumn; +void PartDownloadRequest::updateToTable() +{ const int labelcol = PartDownloader::PartLabelColumn, + progcol = PartDownloader::ProgressColumn; QTableWidget* table = m_prompt->ui->progress; QProgressBar* prog; - - switch (m_state) { - case Requesting: - case Downloading: - prog = qobject_cast<QProgressBar*> (table->cellWidget (tableRow(), progcol)); - - if (!prog) { - prog = new QProgressBar; - table->setCellWidget (tableRow(), progcol, prog); - } - - prog->setRange (0, m_bytesTotal); - prog->setValue (m_bytesRead); - break; - - case Finished: - case Failed: - { - QLabel* lb = new QLabel ((m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" : - "<b><span style=\"color: #800\">FAILED</span></b>"); + + switch (m_state) + { case Requesting: + case Downloading: + prog = qobject_cast<QProgressBar*> (table->cellWidget (tableRow(), progcol)); + + if (!prog) + { prog = new QProgressBar; + table->setCellWidget (tableRow(), progcol, prog); + } + + prog->setRange (0, m_bytesTotal); + prog->setValue (m_bytesRead); + break; + + case Finished: + case Failed: + { QLabel* lb = new QLabel ( (m_state == Finished) ? "<b><span style=\"color: #080\">FINISHED</span></b>" : + "<b><span style=\"color: #800\">FAILED</span></b>"); lb->setAlignment (Qt::AlignCenter); table->setCellWidget (tableRow(), progcol, lb); } break; } - + QLabel* lb = qobject_cast<QLabel*> (table->cellWidget (tableRow(), labelcol)); - if (m_firstUpdate) { - lb = new QLabel (fmt ("<b>%1</b>", m_dest), table); + + if (m_firstUpdate) + { lb = new QLabel (fmt ("<b>%1</b>", m_dest), table); table->setCellWidget (tableRow(), labelcol, lb); } - + // Make sure that the cell is big enough to contain the label if (table->columnWidth (labelcol) < lb->width()) table->setColumnWidth (labelcol, lb->width()); - + m_firstUpdate = false; } // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloadRequest::downloadFinished() { - if (m_reply->error() != QNetworkReply::NoError) { - if (m_primary && !m_prompt->aborted()) +void PartDownloadRequest::downloadFinished() +{ if (m_reply->error() != QNetworkReply::NoError) + { if (m_primary && !m_prompt->aborted()) critical (m_reply->errorString()); - + m_state = Failed; } elif (state() != Failed) - m_state = Finished; - + + m_state = Finished; + m_bytesRead = m_bytesTotal; updateToTable(); - - if (m_fp) { - m_fp->close(); + + if (m_fp) + { m_fp->close(); delete m_fp; m_fp = null; - + if (m_state == Failed) QFile::remove (m_fpath); } - - if (m_state != Finished) { - m_prompt->checkIfFinished(); + + if (m_state != Finished) + { m_prompt->checkIfFinished(); return; } - + // Try to load this file now. LDFile* f = openDATFile (m_fpath, false); + if (!f) return; - + f->setImplicit (!m_primary); - + // Iterate through this file and check for errors. If there's any that stems // from unknown file references, try resolve that by downloading the reference. // This is why downloading a part may end up downloading multiple files, as // it resolves dependencies. - for (LDObject* obj : f->objects()) { - LDError* err = dynamic_cast<LDError*> (obj); + for (LDObject* obj : f->objects()) + { LDError* err = dynamic_cast<LDError*> (obj); + if (!err || err->fileRef().isEmpty()) continue; - + str dest = err->fileRef(); m_prompt->modifyDest (dest); m_prompt->downloadFile (dest, str (PartDownloader::k_UnofficialURL) + dest, false); } - - if (m_primary) { - addRecentFile (m_fpath); + + if (m_primary) + { addRecentFile (m_fpath); m_prompt->setPrimaryFile (f); } - + m_prompt->checkIfFinished(); } // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloadRequest::downloadProgress (int64 recv, int64 total) { - m_bytesRead = recv; +void PartDownloadRequest::downloadProgress (int64 recv, int64 total) +{ m_bytesRead = recv; m_bytesTotal = total; m_state = Downloading; updateToTable(); @@ -442,18 +452,19 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloadRequest::readyRead() { - if (state() == Failed) +void PartDownloadRequest::readyRead() +{ if (state() == Failed) return; - - if (m_fp == null) { - m_fpath.replace ("\\", "/"); - + + if (m_fp == null) + { m_fpath.replace ("\\", "/"); + // We have already asked the user whether we can overwrite so we're good // to go here. m_fp = new QFile (m_fpath.toLocal8Bit()); - if (!m_fp->open (QIODevice::WriteOnly)) { - critical (fmt (tr ("Couldn't open %1 for writing: %2"), m_fpath, strerror (errno))); + + if (!m_fp->open (QIODevice::WriteOnly)) + { critical (fmt (tr ("Couldn't open %1 for writing: %2"), m_fpath, strerror (errno))); m_state = Failed; m_reply->abort(); updateToTable(); @@ -461,31 +472,30 @@ return; } } - + m_fp->write (m_reply->readAll()); } // ============================================================================= // ----------------------------------------------------------------------------- -bool PartDownloadRequest::isFinished() const { - return m_state == Finished || m_state == Failed; +bool PartDownloadRequest::isFinished() const +{ return m_state == Finished || m_state == Failed; } // ============================================================================= // ----------------------------------------------------------------------------- -const PartDownloadRequest::State& PartDownloadRequest::state() const { - return m_state; +const PartDownloadRequest::State& PartDownloadRequest::state() const +{ return m_state; } // ============================================================================= // ----------------------------------------------------------------------------- -void PartDownloadRequest::abort() { - m_reply->abort(); +void PartDownloadRequest::abort() +{ m_reply->abort(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (DownloadFrom, 0) { - PartDownloader::k_download(); +DEFINE_ACTION (DownloadFrom, 0) +{ PartDownloader::k_download(); } -#include "moc_download.cpp"
--- a/src/download.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/download.h Thu Oct 03 20:56:20 2013 +0300 @@ -34,95 +34,94 @@ // ============================================================================= // ----------------------------------------------------------------------------- -class PartDownloader : public QDialog { - Q_OBJECT - PROPERTY (LDFile*, primaryFile, setPrimaryFile) - PROPERTY (bool, aborted, setAborted) - -public: - constexpr static const char* k_OfficialURL = "http://ldraw.org/library/official/", - *k_UnofficialURL = "http://ldraw.org/library/unofficial/"; - - enum Source { - PartsTracker, - CustomURL, - }; - - enum Button { - Download, - Abort, - Close - }; - - enum TableColumn { - PartLabelColumn, - ProgressColumn, - }; - - explicit PartDownloader (QWidget* parent = null); - virtual ~PartDownloader(); - str getURL() const; - static str getDownloadPath(); - Source getSource() const; - void downloadFile (str dest, str url, bool primary); - void modifyDest (str& dest) const; - QPushButton* getButton (Button i); - static void k_download(); - -public slots: - void sourceChanged (int i); - void checkIfFinished(); - void buttonClicked (QAbstractButton* btn); - -protected: - Ui_DownloadFrom* ui; - friend class PartDownloadRequest; - -private: - List<str> m_filesToDownload; - List<PartDownloadRequest*> m_requests; - QPushButton* m_downloadButton; +class PartDownloader : public QDialog +{ Q_OBJECT + PROPERTY (LDFile*, primaryFile, setPrimaryFile) + PROPERTY (bool, aborted, setAborted) + + public: + constexpr static const char* k_UnofficialURL = "http://ldraw.org/library/unofficial/"; + + enum Source + { PartsTracker, + CustomURL, + }; + + enum Button + { Download, + Abort, + Close + }; + + enum TableColumn + { PartLabelColumn, + ProgressColumn, + }; + + explicit PartDownloader (QWidget* parent = null); + virtual ~PartDownloader(); + str getURL() const; + static str getDownloadPath(); + Source getSource() const; + void downloadFile (str dest, str url, bool primary); + void modifyDest (str& dest) const; + QPushButton* getButton (Button i); + static void k_download(); + + public slots: + void sourceChanged (int i); + void checkIfFinished(); + void buttonClicked (QAbstractButton* btn); + + protected: + Ui_DownloadFrom* ui; + friend class PartDownloadRequest; + + private: + List<str> m_filesToDownload; + List<PartDownloadRequest*> m_requests; + QPushButton* m_downloadButton; }; // ============================================================================= // ----------------------------------------------------------------------------- -class PartDownloadRequest : public QObject { - Q_OBJECT +class PartDownloadRequest : public QObject +{ Q_OBJECT PROPERTY (int, tableRow, setTableRow) - -public: - enum State { - Requesting, - Downloading, - Finished, - Failed, - }; - - explicit PartDownloadRequest (str url, str dest, bool primary, PartDownloader* parent); - PartDownloadRequest (const PartDownloadRequest&) = delete; - virtual ~PartDownloadRequest(); - void updateToTable(); - bool isFinished() const; - const State& state() const; - - void operator= (const PartDownloadRequest&) = delete; - -public slots: - void downloadFinished(); - void readyRead(); - void downloadProgress (qint64 recv, qint64 total); - void abort(); - -private: - PartDownloader* m_prompt; - str m_url, m_dest, m_fpath; - QNetworkAccessManager* m_nam; - QNetworkReply* m_reply; - bool m_firstUpdate; - State m_state; - int64 m_bytesRead, m_bytesTotal; - bool m_primary; - QFile* m_fp; + + public: + enum State + { Requesting, + Downloading, + Finished, + Failed, + }; + + explicit PartDownloadRequest (str url, str dest, bool primary, PartDownloader* parent); + PartDownloadRequest (const PartDownloadRequest&) = delete; + virtual ~PartDownloadRequest(); + void updateToTable(); + bool isFinished() const; + const State& state() const; + + void operator= (const PartDownloadRequest&) = delete; + + public slots: + void downloadFinished(); + void readyRead(); + void downloadProgress (qint64 recv, qint64 total); + void abort(); + + private: + PartDownloader* m_prompt; + str m_url, m_dest, m_fpath; + QNetworkAccessManager* m_nam; + QNetworkReply* m_reply; + bool m_firstUpdate; + State m_state; + int64 m_bytesRead, m_bytesTotal; + bool m_primary; + QFile* m_fp; }; -#endif // LDFORGE_DOWNLOAD_H \ No newline at end of file +#endif // LDFORGE_DOWNLOAD_H
--- a/src/extprogs.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/extprogs.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -39,8 +39,8 @@ #include "ui_edger2.h" #include "dialogs.h" -enum extprog { - Isecalc, +enum extprog +{ Isecalc, Intersector, Coverer, Ytruder, @@ -57,8 +57,8 @@ cfg (String, prog_rectifier, ""); cfg (String, prog_edger2, ""); -StringConfig* const g_extProgPaths[] = { - &prog_isecalc, +StringConfig* const g_extProgPaths[] = +{ &prog_isecalc, &prog_intersector, &prog_coverer, &prog_ytruder, @@ -74,8 +74,8 @@ cfg (Bool, prog_rectifier_wine, false); cfg (Bool, prog_edger2_wine, false); -BoolConfig* const g_extProgWine[] = { - &prog_isecalc_wine, +BoolConfig* const g_extProgWine[] = +{ &prog_isecalc_wine, &prog_intersector_wine, &prog_coverer_wine, &prog_ytruder_wine, @@ -84,8 +84,8 @@ }; #endif // _WIN32 -const char* g_extProgNames[] = { - "Isecalc", +const char* g_extProgNames[] = +{ "Isecalc", "Intersector", "Coverer", "Ytruder", @@ -95,51 +95,52 @@ // ============================================================================= // ----------------------------------------------------------------------------- -static bool checkProgPath (const extprog prog) { - alias path = g_extProgPaths[prog]->value; - +static bool checkProgPath (const extprog prog) +{ alias path = g_extProgPaths[prog]->value; + if (path.length() > 0) return true; - + ExtProgPathPrompt* dlg = new ExtProgPathPrompt (g_extProgNames[prog]); - if (dlg->exec() && !dlg->getPath().isEmpty()) { - path = dlg->getPath(); + + if (dlg->exec() && !dlg->getPath().isEmpty()) + { path = dlg->getPath(); return true; } - + return false; } // ============================================================================= // ----------------------------------------------------------------------------- -static str processErrorString (QProcess& proc) { - switch (proc.error()) { - case QProcess::FailedToStart: - return "Failed to start (check your permissions)"; - - case QProcess::Crashed: - return "Crashed."; - - case QProcess::WriteError: - case QProcess::ReadError: - return "I/O error."; - - case QProcess::UnknownError: - return "Unknown error"; - - case QProcess::Timedout: - return fmt ("Timed out (30 seconds)"); +static str processErrorString (QProcess& proc) +{ switch (proc.error()) + { case QProcess::FailedToStart: + return "Failed to start (check your permissions)"; + + case QProcess::Crashed: + return "Crashed."; + + case QProcess::WriteError: + case QProcess::ReadError: + return "I/O error."; + + case QProcess::UnknownError: + return "Unknown error"; + + case QProcess::Timedout: + return fmt ("Timed out (30 seconds)"); } - + return ""; } // ============================================================================= // ----------------------------------------------------------------------------- -static bool mkTempFile (QTemporaryFile& tmp, str& fname) { - if (!tmp.open()) +static bool mkTempFile (QTemporaryFile& tmp, str& fname) +{ if (!tmp.open()) return false; - + fname = tmp.fileName(); tmp.close(); return true; @@ -147,192 +148,196 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void writeObjects (List<LDObject*>& objects, File& f) { - for (LDObject* obj : objects) { - if (obj->getType() == LDObject::Subfile) { - LDSubfile* ref = static_cast<LDSubfile*> (obj); +void writeObjects (List<LDObject*>& objects, File& f) +{ for (LDObject * obj : objects) + { if (obj->getType() == LDObject::Subfile) + { LDSubfile* ref = static_cast<LDSubfile*> (obj); List<LDObject*> objs = ref->inlineContents (LDSubfile::DeepInline); - + writeObjects (objs, f); - - for (LDObject* obj : objs) + + for (LDObject * obj : objs) delete obj; - } else + } + else f.write (obj->raw() + "\r\n"); } } // ============================================================================= // ----------------------------------------------------------------------------- -void writeObjects (List<LDObject*>& objects, str fname) { - // Write the input file +void writeObjects (List<LDObject*>& objects, str fname) +{ // Write the input file File f (fname, File::Write); - - if (!f) { - critical (fmt ("Couldn't open temporary file %1 for writing.\n", fname)); + + if (!f) + { critical (fmt ("Couldn't open temporary file %1 for writing.\n", fname)); return; } - + writeObjects (objects, f); f.close(); } // ============================================================================= // ----------------------------------------------------------------------------- -void writeSelection (str fname) { - writeObjects (g_win->sel(), fname); +void writeSelection (str fname) +{ writeObjects (g_win->sel(), fname); } // ============================================================================= // ----------------------------------------------------------------------------- -void writeColorGroup (const short colnum, str fname) { - List<LDObject*> objects; - - for (LDObject* obj : LDFile::current()->objects()) { - if (obj->isColored() == false || obj->color() != colnum) +void writeColorGroup (const short colnum, str fname) +{ List<LDObject*> objects; + +for (LDObject * obj : LDFile::current()->objects()) + { if (obj->isColored() == false || obj->color() != colnum) continue; - + objects << obj; } - + writeObjects (objects, fname); } // ============================================================================= // ----------------------------------------------------------------------------- -bool runUtilityProcess (extprog prog, str path, str argvstr) { - QTemporaryFile input, output; +bool runUtilityProcess (extprog prog, str path, str argvstr) +{ QTemporaryFile input, output; str inputname, outputname; QStringList argv = argvstr.split (" ", QString::SkipEmptyParts); - + #ifndef _WIN32 - if (*g_extProgWine[prog]) { - argv.insert (0, path); + + if (*g_extProgWine[prog]) + { argv.insert (0, path); path = "wine"; } + #endif // _WIN32 - + print ("cmdline: %1 %2\n", path, argv.join (" ")); - + // Temporary files for stdin and stdout if (!mkTempFile (input, inputname) || !mkTempFile (output, outputname)) return false; - + QProcess proc; - + // Init stdin File stdinfp (inputname, File::Write); - + // Begin! proc.setStandardInputFile (inputname); proc.start (path, argv); - + // Write an enter, the utility tools all expect one stdinfp.write ("\n"); - + // Wait while it runs proc.waitForFinished(); - + #ifndef RELEASE print ("%1", str (proc.readAllStandardOutput())); #endif // RELEASE - + str err = ""; - + if (proc.exitStatus() != QProcess::NormalExit) err = processErrorString (proc); - + // Check the return code if (proc.exitCode() != 0) err = fmt ("Program exited abnormally (return code %1).", proc.exitCode()); - - if (err.length() > 0) { - critical (fmt ("%1 failed: %2\n", g_extProgNames[prog], err)); + + if (err.length() > 0) + { critical (fmt ("%1 failed: %2\n", g_extProgNames[prog], err)); return false; } - + return true; } // ============================================================================= // ----------------------------------------------------------------------------- -static void insertOutput (str fname, bool replace, List<short> colorsToReplace) { +static void insertOutput (str fname, bool replace, List<short> colorsToReplace) +{ #ifndef RELEASE QFile::copy (fname, "./debug_lastOutput"); #endif // RELEASE - + // Read the output file File f (fname, File::Read); - - if (!f) { - critical (fmt ("Couldn't open temporary file %1 for reading.\n", fname)); + + if (!f) + { critical (fmt ("Couldn't open temporary file %1 for reading.\n", fname)); return; } - + List<LDObject*> objs = loadFileContents (&f, null); - + // If we replace the objects, delete the selection now. if (replace) g_win->deleteSelection(); - - for (const short colnum : colorsToReplace) + +for (const short colnum : colorsToReplace) g_win->deleteByColor (colnum); - + // Insert the new objects g_win->sel().clear(); - - for (LDObject * obj : objs) { - if (!obj->isScemantic()) { - delete obj; + +for (LDObject * obj : objs) + { if (!obj->isScemantic()) + { delete obj; continue; } - + LDFile::current()->addObject (obj); g_win->sel() << obj; } - + g_win->fullRefresh(); } // ============================================================================= // Interface for Ytruder // ----------------------------------------------------------------------------- -DEFINE_ACTION (Ytruder, 0) { - setlocale (LC_ALL, "C"); - +DEFINE_ACTION (Ytruder, 0) +{ setlocale (LC_ALL, "C"); + if (!checkProgPath (Ytruder)) return; - + QDialog* dlg = new QDialog; Ui::YtruderUI ui; ui.setupUi (dlg); - + if (!dlg->exec()) return; - + // Read the user's choices const enum { Distance, Symmetry, Projection, Radial } mode = ui.mode_distance->isChecked() ? Distance : ui.mode_symmetry->isChecked() ? Symmetry : ui.mode_projection->isChecked() ? Projection : Radial; - + const Axis axis = ui.axis_x->isChecked() ? X : ui.axis_y->isChecked() ? Y : Z; - + const double depth = ui.planeDepth->value(), - condAngle = ui.condAngle->value(); - + condAngle = ui.condAngle->value(); + QTemporaryFile indat, outdat; str inDATName, outDATName; - + // Make temp files for the input and output files if (!mkTempFile (indat, inDATName) || !mkTempFile (outdat, outDATName)) return; - + // Compose the command-line arguments - str argv = join ({ - (axis == X) ? "-x" : (axis == Y) ? "-y" : "-z", + str argv = join ( + { (axis == X) ? "-x" : (axis == Y) ? "-y" : "-z", (mode == Distance) ? "-d" : (mode == Symmetry) ? "-s" : (mode == Projection) ? "-p" : "-r", depth, "-a", @@ -340,41 +345,41 @@ inDATName, outDATName }); - + writeSelection (inDATName); - + if (!runUtilityProcess (Ytruder, prog_ytruder, argv)) return; - + insertOutput (outDATName, false, {}); } // ============================================================================= // Rectifier interface // ----------------------------------------------------------------------------- -DEFINE_ACTION (Rectifier, 0){ - setlocale (LC_ALL, "C"); - +DEFINE_ACTION (Rectifier, 0) +{ setlocale (LC_ALL, "C"); + if (!checkProgPath (Rectifier)) return; - + QDialog* dlg = new QDialog; Ui::RectifierUI ui; ui.setupUi (dlg); - + if (!dlg->exec()) return; - + QTemporaryFile indat, outdat; str inDATName, outDATName; - + // Make temp files for the input and output files if (!mkTempFile (indat, inDATName) || !mkTempFile (outdat, outDATName)) return; - + // Compose arguments - str argv = join ({ - (!ui.cb_condense->isChecked()) ? "-q" : "", + str argv = join ( + { (!ui.cb_condense->isChecked()) ? "-q" : "", (!ui.cb_subst->isChecked()) ? "-r" : "", (ui.cb_condlineCheck->isChecked()) ? "-a" : "", (ui.cb_colorize->isChecked()) ? "-c" : "", @@ -383,52 +388,52 @@ inDATName, outDATName }); - + writeSelection (inDATName); - + if (!runUtilityProcess (Rectifier, prog_rectifier, argv)) return; - + insertOutput (outDATName, true, {}); } // ============================================================================= // Intersector interface // ----------------------------------------------------------------------------- -DEFINE_ACTION (Intersector, 0) { - setlocale (LC_ALL, "C"); - +DEFINE_ACTION (Intersector, 0) +{ setlocale (LC_ALL, "C"); + if (!checkProgPath (Intersector)) return; - + QDialog* dlg = new QDialog; Ui::IntersectorUI ui; ui.setupUi (dlg); - + makeColorSelector (ui.cmb_incol); makeColorSelector (ui.cmb_cutcol); ui.cb_repeat->setWhatsThis ("If this is set, " APPNAME " runs Intersector a second time with inverse files to cut the " - " cutter group with the input group. Both groups are cut by the intersection."); + " cutter group with the input group. Both groups are cut by the intersection."); ui.cb_edges->setWhatsThis ("Makes " APPNAME " try run Isecalc to create edgelines for the intersection."); - + short inCol, cutCol; const bool repeatInverse = ui.cb_repeat->isChecked(); - - for (;;) { - if (!dlg->exec()) + + for (;;) + { if (!dlg->exec()) return; - + inCol = ui.cmb_incol->itemData (ui.cmb_incol->currentIndex()).toInt(); cutCol = ui.cmb_cutcol->itemData (ui.cmb_cutcol->currentIndex()).toInt(); - - if (inCol == cutCol) { - critical ("Cannot use the same color group for both input and cutter!"); + + if (inCol == cutCol) + { critical ("Cannot use the same color group for both input and cutter!"); continue; } - + break; } - + // Five temporary files! // indat = input group file // cutdat = cutter group file @@ -437,91 +442,92 @@ // edgesdat = edges output (isecalc) QTemporaryFile indat, cutdat, outdat, outdat2, edgesdat; str inDATName, cutDATName, outDATName, outDAT2Name, edgesDATName; - + if (!mkTempFile (indat, inDATName) || !mkTempFile (cutdat, cutDATName) || !mkTempFile (outdat, outDATName) || !mkTempFile (outdat2, outDAT2Name) || - !mkTempFile (edgesdat, edgesDATName)) { - return; + !mkTempFile (edgesdat, edgesDATName)) + { return; } - - str parms = join ({ - (ui.cb_colorize->isChecked()) ? "-c" : "", + + str parms = join ( + { (ui.cb_colorize->isChecked()) ? "-c" : "", (ui.cb_nocondense->isChecked()) ? "-t" : "", "-s", ui.dsb_prescale->value() }); - - str argv_normal = join ({ - parms, + + str argv_normal = join ( + { parms, inDATName, cutDATName, outDATName }); - - str argv_inverse = join ({ - parms, + + str argv_inverse = join ( + { parms, cutDATName, inDATName, outDAT2Name }); - + writeColorGroup (inCol, inDATName); writeColorGroup (cutCol, cutDATName); - + if (!runUtilityProcess (Intersector, prog_intersector, argv_normal)) return; - + insertOutput (outDATName, false, {inCol}); - + if (repeatInverse && runUtilityProcess (Intersector, prog_intersector, argv_inverse)) insertOutput (outDAT2Name, false, {cutCol}); - + if ( ui.cb_edges->isChecked() && checkProgPath (Isecalc) && - runUtilityProcess (Isecalc, prog_isecalc, join ({inDATName, cutDATName, edgesDATName})) + runUtilityProcess (Isecalc, prog_isecalc, join ( {inDATName, cutDATName, edgesDATName})) ) insertOutput (edgesDATName, false, {}); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Coverer, 0) { - setlocale (LC_ALL, "C"); - +DEFINE_ACTION (Coverer, 0) +{ setlocale (LC_ALL, "C"); + if (!checkProgPath (Coverer)) return; - + QDialog* dlg = new QDialog; Ui::CovererUI ui; ui.setupUi (dlg); makeColorSelector (ui.cmb_col1); makeColorSelector (ui.cmb_col2); - + short in1Col, in2Col; - - for (;;) { - if (!dlg->exec()) + + for (;;) + { if (!dlg->exec()) return; - + in1Col = ui.cmb_col1->itemData (ui.cmb_col1->currentIndex()).toInt(); in2Col = ui.cmb_col2->itemData (ui.cmb_col2->currentIndex()).toInt(); - - if (in1Col == in2Col) { - critical ("Cannot use the same color group for both input and cutter!"); + + if (in1Col == in2Col) + { critical ("Cannot use the same color group for both input and cutter!"); continue; } + break; } - + QTemporaryFile in1dat, in2dat, outdat; str in1DATName, in2DATName, outDATName; - + if (!mkTempFile (in1dat, in1DATName) || !mkTempFile (in2dat, in2DATName) || !mkTempFile (outdat, outDATName)) return; - - str argv = join ({ - (ui.cb_oldsweep->isChecked() ? "-s" : ""), + + str argv = join ( + { (ui.cb_oldsweep->isChecked() ? "-s" : ""), (ui.cb_reverse->isChecked() ? "-r" : ""), (ui.dsb_segsplit->value() != 0 ? fmt ("-l %1", ui.dsb_segsplit->value()) : ""), (ui.sb_bias->value() != 0 ? fmt ("-s %1", ui.sb_bias->value()) : ""), @@ -529,61 +535,61 @@ in2DATName, outDATName }); - + writeColorGroup (in1Col, in1DATName); writeColorGroup (in2Col, in2DATName); - + if (!runUtilityProcess (Coverer, prog_coverer, argv)) return; - + insertOutput (outDATName, false, {}); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Isecalc, 0) { - setlocale (LC_ALL, "C"); - +DEFINE_ACTION (Isecalc, 0) +{ setlocale (LC_ALL, "C"); + if (!checkProgPath (Isecalc)) return; - + Ui::IsecalcUI ui; QDialog* dlg = new QDialog; ui.setupUi (dlg); - + makeColorSelector (ui.cmb_col1); makeColorSelector (ui.cmb_col2); - + short in1Col, in2Col; - + // Run the dialog and validate input - for (;;) { - if (!dlg->exec()) + for (;;) + { if (!dlg->exec()) return; - + in1Col = ui.cmb_col1->itemData (ui.cmb_col1->currentIndex()).toInt(), in2Col = ui.cmb_col1->itemData (ui.cmb_col2->currentIndex()).toInt(); - - if (in1Col == in2Col) { - critical ("Cannot use the same color group for both input and cutter!"); + + if (in1Col == in2Col) + { critical ("Cannot use the same color group for both input and cutter!"); continue; } - + break; } - + QTemporaryFile in1dat, in2dat, outdat; str in1DATName, in2DATName, outDATName; - + if (!mkTempFile (in1dat, in1DATName) || !mkTempFile (in2dat, in2DATName) || !mkTempFile (outdat, outDATName)) return; - - str argv = join ({ - in1DATName, + + str argv = join ( + { in1DATName, in2DATName, outDATName }); - + writeColorGroup (in1Col, in1DATName); writeColorGroup (in2Col, in2DATName); runUtilityProcess (Isecalc, prog_isecalc, argv); @@ -592,29 +598,29 @@ // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Edger2, 0) { - setlocale (LC_ALL, "C"); - +DEFINE_ACTION (Edger2, 0) +{ setlocale (LC_ALL, "C"); + if (!checkProgPath (Edger2)) return; - + QDialog* dlg = new QDialog; Ui::Edger2Dialog ui; ui.setupUi (dlg); - + if (!dlg->exec()) return; - + QTemporaryFile in, out; str inName, outName; - + if (!mkTempFile (in, inName) || !mkTempFile (out, outName)) return; - + int unmatched = ui.unmatched->currentIndex(); - - str argv = join ({ - fmt ("-p %1", ui.precision->value()), + + str argv = join ( + { fmt ("-p %1", ui.precision->value()), fmt ("-af %1", ui.flatAngle->value()), fmt ("-ac %1", ui.condAngle->value()), fmt ("-ae %1", ui.edgeAngle->value()), @@ -628,11 +634,11 @@ inName, outName, }); - + writeSelection (inName); - + if (!runUtilityProcess (Edger2, prog_edger2, argv)) return; - + insertOutput (outName, true, {}); -} \ No newline at end of file +}
--- a/src/file.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/file.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -33,6 +33,7 @@ #include "history.h" #include "dialogs.h" #include "gldraw.h" +#include "moc_file.cpp" cfg (String, io_ldpath, ""); cfg (List, io_recentfiles, {}); @@ -51,59 +52,68 @@ // ============================================================================= // ----------------------------------------------------------------------------- -namespace LDPaths { +namespace LDPaths +{ static str pathError; - - struct { - str LDConfigPath; + + struct + { str LDConfigPath; str partsPath, primsPath; } pathInfo; - - void initPaths() { - if (!tryConfigure (io_ldpath)) { - LDrawPathDialog dlg (false); - + + void initPaths() + { if (!tryConfigure (io_ldpath)) + { LDrawPathDialog dlg (false); + if (!dlg.exec()) exit (0); - + io_ldpath = dlg.filename(); } } - - bool tryConfigure (str path) { - QDir dir; - - if (!dir.cd (path)) { - pathError = "Directory does not exist."; + + bool tryConfigure (str path) + { QDir dir; + + if (!dir.cd (path)) + { pathError = "Directory does not exist."; return false; } - + QStringList mustHave = { "LDConfig.ldr", "parts", "p" }; QStringList contents = dir.entryList (mustHave); - - if (contents.size() != mustHave.size()) { - pathError = "Not an LDraw directory! Must<br />have LDConfig.ldr, parts/ and p/."; + + if (contents.size() != mustHave.size()) + { pathError = "Not an LDraw directory! Must<br />have LDConfig.ldr, parts/ and p/."; return false; } - + pathInfo.partsPath = fmt ("%1" DIRSLASH "parts", path); pathInfo.LDConfigPath = fmt ("%1" DIRSLASH "LDConfig.ldr", path); pathInfo.primsPath = fmt ("%1" DIRSLASH "p", path); - + return true; } - + // Accessors - str getError() { return pathError; } - str ldconfig() { return pathInfo.LDConfigPath; } - str prims() { return pathInfo.primsPath; } - str parts() { return pathInfo.partsPath; } + str getError() + { return pathError; + } + str ldconfig() + { return pathInfo.LDConfigPath; + } + str prims() + { return pathInfo.primsPath; + } + str parts() + { return pathInfo.partsPath; + } } // ============================================================================= // ----------------------------------------------------------------------------- -LDFile::LDFile() { - setImplicit (true); +LDFile::LDFile() +{ setImplicit (true); setSavePos (-1); setListItem (null); m_history.setFile (this); @@ -111,120 +121,125 @@ // ============================================================================= // ----------------------------------------------------------------------------- -LDFile::~LDFile() { - // Clear everything from the model - for (LDObject* obj : objects()) +LDFile::~LDFile() +{ // Clear everything from the model +for (LDObject * obj : objects()) delete obj; - + // Clear the cache as well - for (LDObject* obj : cache()) +for (LDObject * obj : cache()) delete obj; - + // Remove this file from the list of files - for (ulong i = 0; i < g_loadedFiles.size(); ++i) { - if (g_loadedFiles[i] == this) { - g_loadedFiles.erase (i); + for (ulong i = 0; i < g_loadedFiles.size(); ++i) + { if (g_loadedFiles[i] == this) + { g_loadedFiles.erase (i); break; } } - + // If we just closed the current file, we need to set the current // file as something else. - if (this == LDFile::current()) { - // If we closed the last file, create a blank one. + if (this == LDFile::current()) + { // If we closed the last file, create a blank one. if (countExplicitFiles() == 0) newFile(); - else { - // Find the first explicit file loaded + else + { // Find the first explicit file loaded int idx = 0; + while (g_loadedFiles[idx]->implicit()) idx++; - + LDFile::setCurrent (g_loadedFiles[idx]); } } - + g_win->updateFileList(); } // ============================================================================= // ----------------------------------------------------------------------------- -LDFile* findLoadedFile (str name) { - for (LDFile* file : g_loadedFiles) +LDFile* findLoadedFile (str name) +{ for (LDFile * file : g_loadedFiles) if (!file->name().isEmpty() && file->getShortName() == name) return file; - + return null; } // ============================================================================= // ----------------------------------------------------------------------------- -str dirname (str path) { - long lastpos = path.lastIndexOf (DIRSLASH); - +str dirname (str path) +{ long lastpos = path.lastIndexOf (DIRSLASH); + if (lastpos > 0) return path.left (lastpos); - + #ifndef _WIN32 + if (path[0] == DIRSLASH_CHAR) return DIRSLASH; + #endif // _WIN32 - + return ""; } // ============================================================================= // ----------------------------------------------------------------------------- -str basename (str path) { - long lastpos = path.lastIndexOf (DIRSLASH); - +str basename (str path) +{ long lastpos = path.lastIndexOf (DIRSLASH); + if (lastpos != -1) return path.mid (lastpos + 1); - + return path; } // ============================================================================= // ----------------------------------------------------------------------------- -File* openLDrawFile (str relpath, bool subdirs) { - print ("%1: Try to open %2\n", __func__, relpath); +File* openLDrawFile (str relpath, bool subdirs) +{ print ("%1: Try to open %2\n", __func__, relpath); File* f = new File; str fullPath; - + // LDraw models use Windows-style path separators. If we're not on Windows, // replace the path separator now before opening any files. #ifndef WIN32 relpath.replace ("\\", "/"); #endif // WIN32 - - if (LDFile::current()) { - // First, try find the file in the current model's file path. We want a file + + if (LDFile::current()) + { // First, try find the file in the current model's file path. We want a file // in the immediate vicinity of the current model to override stock LDraw stuff. str partpath = fmt ("%1" DIRSLASH "%2", dirname (LDFile::current()->name()), relpath); - + if (f->open (partpath, File::Read)) return f; } - + if (f->open (relpath, File::Read)) return f; - + // Try with just the LDraw path first fullPath = fmt ("%1" DIRSLASH "%2", io_ldpath, relpath); - + if (f->open (fullPath, File::Read)) return f; - - if (subdirs) { - // Look in sub-directories: parts and p. Also look in net_downloadpath. - for (const str& topdir : initlist<str> ({ io_ldpath, net_downloadpath })) - for (const str& subdir : initlist<str> ({ "parts", "p" })) { - fullPath = fmt ("%1" DIRSLASH "%2" DIRSLASH "%3", topdir, subdir, relpath); - if (f->open (fullPath, File::Read)) - return f; - } + + if (subdirs) + { // Look in sub-directories: parts and p. Also look in net_downloadpath. + for (const str & topdir : initlist<str> ( { io_ldpath, net_downloadpath })) + + for (const str & subdir : initlist<str> ( { "parts", "p" })) + { fullPath = fmt ("%1" DIRSLASH "%2" DIRSLASH "%3", topdir, subdir, relpath); + + if (f->open (fullPath, File::Read)) + return f; + } } - + // Did not find the file. print ("could not find %1\n", relpath); delete f; @@ -233,14 +248,14 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void FileLoader::start() { - setDone (false); +void FileLoader::start() +{ setDone (false); setProgress (0); setAborted (false); - - if (concurrent()) { - g_aborted = false; - + + if (concurrent()) + { g_aborted = false; + // Show a progress dialog if we're loading the main file here so we can // show progress updates and keep the WM posted that we're still here. // Of course we cannot exec() the dialog because then the dialog would @@ -249,70 +264,71 @@ dlg->setNumLines (lines().size()); dlg->setModal (true); dlg->show(); - + // Connect the loader in so we can show updates connect (this, SIGNAL (workDone()), dlg, SLOT (accept())); connect (dlg, SIGNAL (rejected()), this, SLOT (abort())); - } else + } + else dlg = null; - + // Begin working work (0); } // ============================================================================= // ----------------------------------------------------------------------------- -void FileLoader::work (int i) { - // User wishes to abort, so stop here now. - if (aborted()) { - for (LDObject* obj : m_objs) +void FileLoader::work (int i) +{ // User wishes to abort, so stop here now. + if (aborted()) +{ for (LDObject * obj : m_objs) delete obj; - + m_objs.clear(); setDone (true); return; } - + // Parse up to 300 lines per iteration int max = i + 300; - - for (; i < max && i < (int) lines().size(); ++i) { - str line = lines()[i]; - + + for (; i < max && i < (int) lines().size(); ++i) + { str line = lines() [i]; + // Trim the trailing newline qchar c; - - while ((c = line[line.length() - 1]) == '\n' || c == '\r') + + while ( (c = line[line.length() - 1]) == '\n' || c == '\r') line.chop (1); - + LDObject* obj = parseLine (line); - + // Check for parse errors and warn about tthem - if (obj->getType() == LDObject::Error) { - log ("Couldn't parse line #%1: %2", m_progress + 1, static_cast<LDError*> (obj)->reason); - + if (obj->getType() == LDObject::Error) + { log ("Couldn't parse line #%1: %2", m_progress + 1, static_cast<LDError*> (obj)->reason); + if (m_warningsPointer) - (*m_warningsPointer)++; + (*m_warningsPointer) ++; } - + m_objs << obj; setProgress (i); - + // If we have a dialog pointer, update the progress now if (concurrent()) dlg->updateProgress (i); } - + // If we're done now, tell the environment we're done and stop. - if (i >= ((int) lines().size()) - 1) { - emit workDone(); + if (i >= ( (int) lines().size()) - 1) + { emit workDone(); setDone (true); return; } - + // Otherwise, continue, by recursing back. - if (!done()) { - // If we have a dialog to show progress output to, we cannot just call + if (!done()) + { // If we have a dialog to show progress output to, we cannot just call // work() again immediately as the dialog needs some processor cycles as // well. Thus, take a detour through the event loop by using the // meta-object system. @@ -331,166 +347,169 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void FileLoader::abort() { - setAborted (true); - +void FileLoader::abort() +{ setAborted (true); + if (concurrent()) g_aborted = true; } // ============================================================================= // ----------------------------------------------------------------------------- -List<LDObject*> loadFileContents (File* f, ulong* numWarnings, bool* ok) { - List<str> lines; +List<LDObject*> loadFileContents (File* f, ulong* numWarnings, bool* ok) +{ List<str> lines; List<LDObject*> objs; - + if (numWarnings) *numWarnings = 0; - + // Calculate the amount of lines - for (str line : *f) +for (str line : *f) lines << line; - + f->rewind(); - + FileLoader* loader = new FileLoader; loader->setWarningsPointer (numWarnings); loader->setLines (lines); loader->setConcurrent (g_loadingMainFile); loader->start(); - + // After start() returns, if the loader isn't done yet, it's delaying // its next iteration through the event loop. We need to catch this here // by telling the event loop to tick, which will tick the file loader again. // We keep doing this until the file loader is ready. while (loader->done() == false) qApp->processEvents(); - + // If we wanted the success value, supply that now if (ok) *ok = !loader->aborted(); - + objs = loader->objs(); return objs; } // ============================================================================= // ----------------------------------------------------------------------------- -LDFile* openDATFile (str path, bool search) { - // Convert the file name to lowercase since some parts contain uppercase +LDFile* openDATFile (str path, bool search) +{ // Convert the file name to lowercase since some parts contain uppercase // file names. I'll assume here that the library will always use lowercase // file names for the actual parts.. File* f; - + if (search) f = openLDrawFile (path.toLower(), true); - else { - f = new File (path, File::Read); - - if (!*f) { - delete f; + else + { f = new File (path, File::Read); + + if (!*f) + { delete f; return null; } } - + if (!f) return null; - + LDFile* load = new LDFile; load->setName (path); - + ulong numWarnings; bool ok; List<LDObject*> objs = loadFileContents (f, &numWarnings, &ok); - + if (!ok) return null; - - for (LDObject* obj : objs) + +for (LDObject * obj : objs) load->addObject (obj); - + delete f; g_loadedFiles << load; - - if (g_loadingMainFile) { - LDFile::setCurrent (load); + + if (g_loadingMainFile) + { LDFile::setCurrent (load); g_win->R()->setFile (load); log (QObject::tr ("File %1 parsed successfully (%2 errors)."), path, numWarnings); } - + return load; } // ============================================================================= // ----------------------------------------------------------------------------- -bool LDFile::safeToClose() { - typedef QMessageBox msgbox; +bool LDFile::safeToClose() +{ typedef QMessageBox msgbox; setlocale (LC_ALL, "C"); - + // If we have unsaved changes, warn and give the option of saving. - if (hasUnsavedChanges()) { - str message = fmt ("There are unsaved changes to %1. Should it be saved?", + if (hasUnsavedChanges()) + { str message = fmt ("There are unsaved changes to %1. Should it be saved?", (name().length() > 0) ? name() : "<anonymous>"); - + int button = msgbox::question (g_win, "Unsaved Changes", message, - (msgbox::Yes | msgbox::No | msgbox::Cancel), msgbox::Cancel); - - switch (button) { - case msgbox::Yes: - // If we don't have a file path yet, we have to ask the user for one. - if (name().length() == 0) { - str newpath = QFileDialog::getSaveFileName (g_win, "Save As", - LDFile::current()->name(), "LDraw files (*.dat *.ldr)"); - - if (newpath.length() == 0) - return false; - - setName (newpath); - } - - if (!save()) { - message = fmt (QObject::tr ("Failed to save %1: %2\nDo you still want to close?"), - name(), strerror (errno)); - - if (msgbox::critical (g_win, "Save Failure", message, - (msgbox::Yes | msgbox::No), msgbox::No) == msgbox::No) { - return false; + (msgbox::Yes | msgbox::No | msgbox::Cancel), msgbox::Cancel); + + switch (button) + { case msgbox::Yes: + + // If we don't have a file path yet, we have to ask the user for one. + if (name().length() == 0) + { str newpath = QFileDialog::getSaveFileName (g_win, "Save As", + LDFile::current()->name(), "LDraw files (*.dat *.ldr)"); + + if (newpath.length() == 0) + return false; + + setName (newpath); } - } - break; - - case msgbox::Cancel: - return false; - - default: - break; + + if (!save()) + { message = fmt (QObject::tr ("Failed to save %1: %2\nDo you still want to close?"), + name(), strerror (errno)); + + if (msgbox::critical (g_win, "Save Failure", message, + (msgbox::Yes | msgbox::No), msgbox::No) == msgbox::No) + { return false; + } + } + + break; + + case msgbox::Cancel: + return false; + + default: + break; } } - + return true; } // ============================================================================= // ----------------------------------------------------------------------------- -void closeAll() { - // Remove all loaded files and the objects they contain +void closeAll() +{ // Remove all loaded files and the objects they contain List<LDFile*> files = g_loadedFiles; - for (LDFile* file : files) + +for (LDFile * file : files) delete file; } // ============================================================================= // ----------------------------------------------------------------------------- -void newFile() { - // Create a new anonymous file and set it to our current +void newFile() +{ // Create a new anonymous file and set it to our current LDFile* f = new LDFile; f->setName (""); f->setImplicit (false); g_loadedFiles << f; LDFile::setCurrent (f); - + LDFile::closeInitialFile(); - + g_win->R()->setFile (f); g_win->fullRefresh(); g_win->updateTitle(); @@ -499,26 +518,26 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void addRecentFile (str path) { - alias rfiles = io_recentfiles.value; +void addRecentFile (str path) +{ alias rfiles = io_recentfiles.value; int idx = rfiles.indexOf (path); - + // If this file already is in the list, pop it out. - if (idx != -1) { - if (rfiles.size() == 1) + if (idx != -1) + { if (rfiles.size() == 1) return; // only recent file - abort and do nothing - + // Pop it out. rfiles.removeAt (idx); } - + // If there's too many recent files, drop one out. while (rfiles.size() > (g_MaxRecentFiles - 1)) rfiles.removeAt (0); - + // Add the file rfiles << path; - + Config::save(); g_win->updateRecentFilesMenu(); } @@ -526,35 +545,35 @@ // ============================================================================= // Open an LDraw file and set it as the main model // ----------------------------------------------------------------------------- -void openMainFile (str path) { - g_loadingMainFile = true; +void openMainFile (str path) +{ g_loadingMainFile = true; LDFile* file = openDATFile (path, false); - - if (!file) { - // Loading failed, thus drop down to a new file since we + + if (!file) + { // Loading failed, thus drop down to a new file since we // closed everything prior. newFile(); - - if (!g_aborted) { - // Tell the user loading failed. + + if (!g_aborted) + { // Tell the user loading failed. setlocale (LC_ALL, "C"); critical (fmt (QObject::tr ("Failed to open %1: %2"), path, strerror (errno))); } - + g_loadingMainFile = false; return; } - + file->setImplicit (false); - + // If we have an anonymous, unchanged file open as the only open file // (aside of the one we just opened), close it now. LDFile::closeInitialFile(); - + // Rebuild the object tree view now. LDFile::setCurrent (file); g_win->fullRefresh(); - + // Add it to the recent files list. addRecentFile (path); g_loadingMainFile = false; @@ -562,49 +581,49 @@ // ============================================================================= // ----------------------------------------------------------------------------- -bool LDFile::save (str savepath) { - if (!savepath.length()) +bool LDFile::save (str savepath) +{ if (!savepath.length()) savepath = name(); - + File f (savepath, File::Write); - + if (!f) return false; - + // If the second object in the list holds the file name, update that now. // Only do this if the file is explicitly open. If it's saved into a directory // called "s" or "48", prepend that into the name. LDComment* fpathComment = null; LDObject* first = object (1); - - if (!implicit() && first != null && first->getType() == LDObject::Comment) { - fpathComment = static_cast<LDComment*> (first); - - if (fpathComment->text.left (6) == "Name: ") { - str newname; + + if (!implicit() && first != null && first->getType() == LDObject::Comment) + { fpathComment = static_cast<LDComment*> (first); + + if (fpathComment->text.left (6) == "Name: ") + { str newname; str dir = basename (dirname (savepath)); - + if (dir == "s" || dir == "48") newname = dir + "\\"; - + newname += basename (savepath); fpathComment->text = fmt ("Name: %1", newname); g_win->buildObjList(); } } - + // File is open, now save the model to it. Note that LDraw requires files to // have DOS line endings, so we terminate the lines with \r\n. - for (LDObject* obj : objects()) +for (LDObject * obj : objects()) f.write (obj->raw() + "\r\n"); - + // File is saved, now clean up. f.close(); - + // We have successfully saved, update the save position now. setSavePos (history().pos()); setName (savepath); - + g_win->updateFileListItem (this); g_win->updateTitle(); return true; @@ -623,12 +642,12 @@ // ============================================================================= // ----------------------------------------------------------------------------- -static vertex parseVertex (QStringList& s, const ushort n) { - vertex v; - - for (const Axis ax : g_Axes) +static vertex parseVertex (QStringList& s, const ushort n) +{ vertex v; + +for (const Axis ax : g_Axes) v[ax] = atof (s[n + ax]); - + return v; } @@ -637,250 +656,251 @@ // code and returns the object parsed from it. parseLine never returns null, // the object will be LDError if it could not be parsed properly. // ----------------------------------------------------------------------------- -LDObject* parseLine (str line) { - QStringList tokens = line.split (" ", str::SkipEmptyParts); - - if (tokens.size() <= 0) { - // Line was empty, or only consisted of whitespace +LDObject* parseLine (str line) +{ QStringList tokens = line.split (" ", str::SkipEmptyParts); + + if (tokens.size() <= 0) + { // Line was empty, or only consisted of whitespace return new LDEmpty; } - + if (tokens[0].length() != 1 || tokens[0][0].isDigit() == false) return new LDError (line, "Illogical line code"); - + int num = tokens[0][0].digitValue(); - - switch (num) { - case 0: { - // Comment - str comm = line.mid (line.indexOf ("0") + 1); - - // Remove any leading whitespace - while (comm[0] == ' ') - comm.remove (0, 1); - - // Handle BFC statements - if (tokens.size() > 2 && tokens[1] == "BFC") { - for (short i = 0; i < LDBFC::NumStatements; ++i) - if (comm == fmt ("BFC %1", LDBFC::statements [i])) - return new LDBFC ((LDBFC::Type) i); - - // MLCAD is notorious for stuffing these statements in parts it - // creates. The above block only handles valid statements, so we - // need to handle MLCAD-style invertnext, clip and noclip separately. - struct { - const char* a; - LDBFC::Type b; - } BFCData[] = { - { "INVERTNEXT", LDBFC::InvertNext }, - { "NOCLIP", LDBFC::NoClip }, - { "CLIP", LDBFC::Clip } - }; - - for (const auto& i : BFCData) - if (comm == fmt ("BFC CERTIFY %1", i.a)) - return new LDBFC (i.b); + + switch (num) + { case 0: + { // Comment + str comm = line.mid (line.indexOf ("0") + 1); + + // Remove any leading whitespace + while (comm[0] == ' ') + comm.remove (0, 1); + + // Handle BFC statements + if (tokens.size() > 2 && tokens[1] == "BFC") + { for (short i = 0; i < LDBFC::NumStatements; ++i) + if (comm == fmt ("BFC %1", LDBFC::statements [i])) + return new LDBFC ( (LDBFC::Type) i); + + // MLCAD is notorious for stuffing these statements in parts it + // creates. The above block only handles valid statements, so we + // need to handle MLCAD-style invertnext, clip and noclip separately. + struct + { const char* a; + LDBFC::Type b; + } BFCData[] = + { { "INVERTNEXT", LDBFC::InvertNext }, + { "NOCLIP", LDBFC::NoClip }, + { "CLIP", LDBFC::Clip } + }; + + for (const auto & i : BFCData) + if (comm == fmt ("BFC CERTIFY %1", i.a)) + return new LDBFC (i.b); + } + + if (tokens.size() > 2 && tokens[1] == "!LDFORGE") + { // Handle LDForge-specific types, they're embedded into comments too + if (tokens[2] == "VERTEX") + { // Vertex (0 !LDFORGE VERTEX) + CHECK_TOKEN_COUNT (7) + CHECK_TOKEN_NUMBERS (3, 6) + + LDVertex* obj = new LDVertex; + obj->setColor (tokens[3].toLong()); + + for (const Axis ax : g_Axes) + obj->pos[ax] = tokens[4 + ax].toDouble(); // 4 - 6 + + return obj; + } elif (tokens[2] == "OVERLAY") + + { CHECK_TOKEN_COUNT (9); + CHECK_TOKEN_NUMBERS (5, 8) + + LDOverlay* obj = new LDOverlay; + obj->setFilename (tokens[3]); + obj->setCamera (tokens[4].toLong()); + obj->setX (tokens[5].toLong()); + obj->setY (tokens[6].toLong()); + obj->setWidth (tokens[7].toLong()); + obj->setHeight (tokens[8].toLong()); + return obj; + } + } + + // Just a regular comment: + LDComment* obj = new LDComment; + obj->text = comm; + return obj; } - - if (tokens.size() > 2 && tokens[1] == "!LDFORGE") { - // Handle LDForge-specific types, they're embedded into comments too - if (tokens[2] == "VERTEX") { - // Vertex (0 !LDFORGE VERTEX) - CHECK_TOKEN_COUNT (7) - CHECK_TOKEN_NUMBERS (3, 6) - - LDVertex* obj = new LDVertex; - obj->setColor (tokens[3].toLong()); - - for (const Axis ax : g_Axes) - obj->pos[ax] = tokens[4 + ax].toDouble(); // 4 - 6 - - return obj; - } elif (tokens[2] == "OVERLAY") { - CHECK_TOKEN_COUNT (9); - CHECK_TOKEN_NUMBERS (5, 8) - - LDOverlay* obj = new LDOverlay; - obj->setFilename (tokens[3]); - obj->setCamera (tokens[4].toLong()); - obj->setX (tokens[5].toLong()); - obj->setY (tokens[6].toLong()); - obj->setWidth (tokens[7].toLong()); - obj->setHeight (tokens[8].toLong()); + + case 1: + { // Subfile + CHECK_TOKEN_COUNT (15) + CHECK_TOKEN_NUMBERS (1, 13) + + // Try open the file. Disable g_loadingMainFile temporarily since we're + // not loading the main file now, but the subfile in question. + bool tmp = g_loadingMainFile; + g_loadingMainFile = false; + LDFile* load = getFile (tokens[14]); + g_loadingMainFile = tmp; + + // If we cannot open the file, mark it an error + if (!load) + { LDError* obj = new LDError (line, fmt ("Could not open %1", tokens[14])); + obj->setFileRef (tokens[14]); return obj; } + + LDSubfile* obj = new LDSubfile; + obj->setColor (tokens[1].toLong()); + obj->setPosition (parseVertex (tokens, 2)); // 2 - 4 + + matrix transform; + + for (short i = 0; i < 9; ++i) + transform[i] = tokens[i + 5].toDouble(); // 5 - 13 + + obj->setTransform (transform); + obj->setFileInfo (load); + return obj; } - - // Just a regular comment: - LDComment* obj = new LDComment; - obj->text = comm; - return obj; - } - - case 1: { - // Subfile - CHECK_TOKEN_COUNT (15) - CHECK_TOKEN_NUMBERS (1, 13) - - // Try open the file. Disable g_loadingMainFile temporarily since we're - // not loading the main file now, but the subfile in question. - bool tmp = g_loadingMainFile; - g_loadingMainFile = false; - LDFile* load = getFile (tokens[14]); - g_loadingMainFile = tmp; - - // If we cannot open the file, mark it an error - if (!load) { - LDError* obj = new LDError (line, fmt ("Could not open %1", tokens[14])); - obj->setFileRef (tokens[14]); + + case 2: + { CHECK_TOKEN_COUNT (8) + CHECK_TOKEN_NUMBERS (1, 7) + + // Line + LDLine* obj = new LDLine; + obj->setColor (tokens[1].toLong()); + + for (short i = 0; i < 2; ++i) + obj->setVertex (i, parseVertex (tokens, 2 + (i * 3))); // 2 - 7 + return obj; } - - LDSubfile* obj = new LDSubfile; - obj->setColor (tokens[1].toLong()); - obj->setPosition (parseVertex (tokens, 2)); // 2 - 4 - - matrix transform; - - for (short i = 0; i < 9; ++i) - transform[i] = tokens[i + 5].toDouble(); // 5 - 13 - - obj->setTransform (transform); - obj->setFileInfo (load); - return obj; - } - - case 2: { - CHECK_TOKEN_COUNT (8) - CHECK_TOKEN_NUMBERS (1, 7) - - // Line - LDLine* obj = new LDLine; - obj->setColor (tokens[1].toLong()); - - for (short i = 0; i < 2; ++i) - obj->setVertex (i, parseVertex (tokens, 2 + (i * 3))); // 2 - 7 - - return obj; - } - - case 3: { - CHECK_TOKEN_COUNT (11) - CHECK_TOKEN_NUMBERS (1, 10) - - // Triangle - LDTriangle* obj = new LDTriangle; - obj->setColor (tokens[1].toLong()); - - for (short i = 0; i < 3; ++i) - obj->setVertex (i, parseVertex (tokens, 2 + (i * 3))); // 2 - 10 - - return obj; - } - - case 4: - case 5: { - CHECK_TOKEN_COUNT (14) - CHECK_TOKEN_NUMBERS (1, 13) - - // Quadrilateral / Conditional line - LDObject* obj; - - if (num == 4) - obj = new LDQuad; - else - obj = new LDCndLine; - - obj->setColor (tokens[1].toLong()); - - for (short i = 0; i < 4; ++i) - obj->setVertex (i, parseVertex (tokens, 2 + (i * 3))); // 2 - 13 - - return obj; - } - - default: // Strange line we couldn't parse - return new LDError (line, "Unknown line code number"); + + case 3: + { CHECK_TOKEN_COUNT (11) + CHECK_TOKEN_NUMBERS (1, 10) + + // Triangle + LDTriangle* obj = new LDTriangle; + obj->setColor (tokens[1].toLong()); + + for (short i = 0; i < 3; ++i) + obj->setVertex (i, parseVertex (tokens, 2 + (i * 3))); // 2 - 10 + + return obj; + } + + case 4: + case 5: + { CHECK_TOKEN_COUNT (14) + CHECK_TOKEN_NUMBERS (1, 13) + + // Quadrilateral / Conditional line + LDObject* obj; + + if (num == 4) + obj = new LDQuad; + else + obj = new LDCndLine; + + obj->setColor (tokens[1].toLong()); + + for (short i = 0; i < 4; ++i) + obj->setVertex (i, parseVertex (tokens, 2 + (i * 3))); // 2 - 13 + + return obj; + } + + default: // Strange line we couldn't parse + return new LDError (line, "Unknown line code number"); } } // ============================================================================= // ----------------------------------------------------------------------------- -LDFile* getFile (str filename) { - // Try find the file in the list of loaded files +LDFile* getFile (str filename) +{ // Try find the file in the list of loaded files LDFile* load = findLoadedFile (filename); - + // If it's not loaded, try open it if (!load) load = openDATFile (filename, true); - + return load; } // ============================================================================= // ----------------------------------------------------------------------------- -void reloadAllSubfiles() { - if (!LDFile::current()) +void reloadAllSubfiles() +{ if (!LDFile::current()) return; - + g_loadedFiles.clear(); g_loadedFiles << LDFile::current(); - + // Go through all objects in the current file and reload the subfiles - for (LDObject* obj : LDFile::current()->objects()) { - if (obj->getType() == LDObject::Subfile) { - LDSubfile* ref = static_cast<LDSubfile*> (obj); +for (LDObject * obj : LDFile::current()->objects()) + { if (obj->getType() == LDObject::Subfile) + { LDSubfile* ref = static_cast<LDSubfile*> (obj); LDFile* fileInfo = getFile (ref->fileInfo()->name()); - + if (fileInfo) ref->setFileInfo (fileInfo); else ref->replace (new LDError (ref->raw(), "Could not open referred file")); } - + // Reparse gibberish files. It could be that they are invalid because // of loading errors. Circumstances may be different now. if (obj->getType() == LDObject::Error) obj->replace (parseLine (static_cast<LDError*> (obj)->contents)); } - + // Close all files left unused LDFile::closeUnused(); } // ============================================================================= // ----------------------------------------------------------------------------- -ulong LDFile::addObject (LDObject* obj) { - m_history.add (new AddHistory (objects().size(), obj)); +ulong LDFile::addObject (LDObject* obj) +{ m_history.add (new AddHistory (objects().size(), obj)); m_objects << obj; - + if (obj->getType() == LDObject::Vertex) m_vertices << obj; - + obj->setFile (this); return numObjs() - 1; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDFile::addObjects (const List<LDObject*> objs) { - for (LDObject* obj : objs) +void LDFile::addObjects (const List<LDObject*> objs) +{ for (LDObject * obj : objs) if (obj) addObject (obj); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDFile::insertObj (const ulong pos, LDObject* obj) { - m_history.add (new AddHistory (pos, obj)); +void LDFile::insertObj (const ulong pos, LDObject* obj) +{ m_history.add (new AddHistory (pos, obj)); m_objects.insert (pos, obj); obj->setFile (this); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDFile::forgetObject (LDObject* obj) { - ulong idx = obj->getIndex(); +void LDFile::forgetObject (LDObject* obj) +{ ulong idx = obj->getIndex(); m_history.add (new DelHistory (idx, obj)); m_objects.erase (idx); obj->setFile (null); @@ -888,181 +908,184 @@ // ============================================================================= // ----------------------------------------------------------------------------- -bool safeToCloseAll() { - for (LDFile* f : g_loadedFiles) +bool safeToCloseAll() +{ for (LDFile * f : g_loadedFiles) if (!f->safeToClose()) return false; - + return true; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDFile::setObject (ulong idx, LDObject* obj) { - assert (idx < numObjs()); - +void LDFile::setObject (ulong idx, LDObject* obj) +{ assert (idx < numObjs()); + // Mark this change to history str oldcode = object (idx)->raw(); str newcode = obj->raw(); m_history << new EditHistory (idx, oldcode, newcode); - + obj->setFile (this); m_objects[idx] = obj; } // ============================================================================= // ----------------------------------------------------------------------------- -static List<LDFile*> getFilesUsed (LDFile* node) { - List<LDFile*> filesUsed; - - for (LDObject* obj : node->objects()) { - if (obj->getType() != LDObject::Subfile) +static List<LDFile*> getFilesUsed (LDFile* node) +{ List<LDFile*> filesUsed; + +for (LDObject * obj : node->objects()) + { if (obj->getType() != LDObject::Subfile) continue; - + LDSubfile* ref = static_cast<LDSubfile*> (obj); filesUsed << ref->fileInfo(); filesUsed << getFilesUsed (ref->fileInfo()); } - + return filesUsed; } // ============================================================================= // Find out which files are unused and close them. // ----------------------------------------------------------------------------- -void LDFile::closeUnused() { - List<LDFile*> filesUsed = getFilesUsed (LDFile::current()); - +void LDFile::closeUnused() +{ List<LDFile*> filesUsed = getFilesUsed (LDFile::current()); + // Anything that's explicitly opened must not be closed - for (LDFile* file : g_loadedFiles) +for (LDFile * file : g_loadedFiles) if (!file->implicit()) filesUsed << file; - + // Remove duplicated entries filesUsed.makeUnique(); - + // Close all open files that aren't in filesUsed - for (LDFile* file : g_loadedFiles) { - bool isused = false; - - for (LDFile* usedFile : filesUsed) { - if (file == usedFile) { - isused = true; +for (LDFile * file : g_loadedFiles) + { bool isused = false; + + for (LDFile * usedFile : filesUsed) + { if (file == usedFile) + { isused = true; break; } } - + if (!isused) delete file; } - + g_loadedFiles.clear(); g_loadedFiles << filesUsed; } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject* LDFile::object (ulong pos) const { - if (m_objects.size() <= pos) +LDObject* LDFile::object (ulong pos) const +{ if (m_objects.size() <= pos) return null; - + return m_objects[pos]; } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject* LDFile::obj (ulong pos) const { - return object (pos); +LDObject* LDFile::obj (ulong pos) const +{ return object (pos); } // ============================================================================= // ----------------------------------------------------------------------------- -ulong LDFile::numObjs() const { - return objects().size(); +ulong LDFile::numObjs() const +{ return objects().size(); } // ============================================================================= // ----------------------------------------------------------------------------- -bool LDFile::hasUnsavedChanges() const { - return !implicit() && history().pos() != savePos(); +bool LDFile::hasUnsavedChanges() const +{ return !implicit() && history().pos() != savePos(); } // ============================================================================= // ----------------------------------------------------------------------------- -str LDFile::getShortName() { - if (name().length() > 0) +str LDFile::getShortName() +{ if (name().length() > 0) return basename (name()); - + return tr ("<anonymous>"); } // ============================================================================= // ----------------------------------------------------------------------------- -List<LDObject*> LDFile::inlineContents (LDSubfile::InlineFlags flags) { - // Possibly substitute with logoed studs: +List<LDObject*> LDFile::inlineContents (LDSubfile::InlineFlags flags) +{ // Possibly substitute with logoed studs: // stud.dat -> stud-logo.dat // stud2.dat -> stud-logo2.dat - if (gl_logostuds && (flags & LDSubfile::RendererInline)) { - if (name() == "stud.dat" && g_logoedStud) + if (gl_logostuds && (flags & LDSubfile::RendererInline)) + { if (name() == "stud.dat" && g_logoedStud) return g_logoedStud->inlineContents (flags); + elif (name() == "stud2.dat" && g_logoedStud2) - return g_logoedStud2->inlineContents (flags); + return g_logoedStud2->inlineContents (flags); } - + List<LDObject*> objs, objcache; - + bool deep = flags & LDSubfile::DeepInline, - doCache = flags & LDSubfile::CacheInline; - + doCache = flags & LDSubfile::CacheInline; + // If we have this cached, just clone that - if (deep && cache().size()) { - for (LDObject* obj : cache()) + if (deep && cache().size()) +{ for (LDObject * obj : cache()) objs << obj->clone(); - } else { - if (!deep) + } + else + { if (!deep) doCache = false; - - for (LDObject* obj : objects()) { - // Skip those without scemantic meaning + + for (LDObject * obj : objects()) + { // Skip those without scemantic meaning if (!obj->isScemantic()) continue; - + // Got another sub-file reference, inline it if we're deep-inlining. If not, // just add it into the objects normally. Also, we only cache immediate // subfiles and this is not one. Yay, recursion! - if (deep && obj->getType() == LDObject::Subfile) { - LDSubfile* ref = static_cast<LDSubfile*> (obj); - + if (deep && obj->getType() == LDObject::Subfile) + { LDSubfile* ref = static_cast<LDSubfile*> (obj); + // We only want to cache immediate subfiles, so shed the caching // flag when recursing deeper in hierarchy. - List<LDObject*> otherobjs = ref->inlineContents (flags & ~(LDSubfile::CacheInline)); - - for (LDObject* otherobj : otherobjs) { - // Cache this object, if desired + List<LDObject*> otherobjs = ref->inlineContents (flags & ~ (LDSubfile::CacheInline)); + + for (LDObject * otherobj : otherobjs) + { // Cache this object, if desired if (doCache) objcache << otherobj->clone(); - + objs << otherobj; } - } else { - if (doCache) + } + else + { if (doCache) objcache << obj->clone(); - + objs << obj->clone(); } } - + if (doCache) setCache (objcache); } - + return objs; } // ============================================================================= // ----------------------------------------------------------------------------- -LDFile* LDFile::current() { - return m_curfile; +LDFile* LDFile::current() +{ return m_curfile; } // ============================================================================= @@ -1071,16 +1094,16 @@ // // FIXME: f can be temporarily null. This probably should not be the case. // ----------------------------------------------------------------------------- -void LDFile::setCurrent (LDFile* f) { - // Implicit files were loaded for caching purposes and must never be set +void LDFile::setCurrent (LDFile* f) +{ // Implicit files were loaded for caching purposes and must never be set // current. if (f && f->implicit()) return; - + m_curfile = f; - - if (g_win && f) { - // A ton of stuff needs to be updated + + if (g_win && f) + { // A ton of stuff needs to be updated g_win->clearSelection(); g_win->updateFileListItem (f); g_win->buildObjList(); @@ -1088,20 +1111,20 @@ g_win->R()->setFile (f); g_win->R()->resetAngles(); g_win->R()->repaint(); - + log ("Changed file to %1", f->getShortName()); } } // ============================================================================= // ----------------------------------------------------------------------------- -int LDFile::countExplicitFiles() { - int count = 0; - - for (LDFile* f : g_loadedFiles) +int LDFile::countExplicitFiles() +{ int count = 0; + +for (LDFile * f : g_loadedFiles) if (f->implicit() == false) count++; - + return count; } @@ -1109,8 +1132,8 @@ // This little beauty closes the initial file that was open at first when opening // a new file over it. // ----------------------------------------------------------------------------- -void LDFile::closeInitialFile() { - if ( +void LDFile::closeInitialFile() +{ if ( countExplicitFiles() == 2 && g_loadedFiles[0]->name() == "" && !g_loadedFiles[0]->hasUnsavedChanges() @@ -1120,13 +1143,12 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void loadLogoedStuds() { - print ("Loading logoed studs...\n"); - +void loadLogoedStuds() +{ print ("Loading logoed studs...\n"); + delete g_logoedStud; delete g_logoedStud2; - + g_logoedStud = openDATFile ("stud-logo.dat", true); g_logoedStud2 = openDATFile ("stud2-logo.dat", true); } -#include "moc_file.cpp"
--- a/src/file.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/file.h Thu Oct 03 20:56:20 2013 +0300 @@ -29,10 +29,10 @@ class History; class OpenProgressDialog; -namespace LDPaths { - void initPaths(); +namespace LDPaths +{ void initPaths(); bool tryConfigure (str path); - + str ldconfig(); str prims(); str parts(); @@ -48,54 +48,75 @@ // A file is implicit when they are opened automatically for caching purposes // and are hidden from the user. User-opened files are explicit (not implicit). // ============================================================================= -class LDFile : public QObject { - Q_OBJECT - READ_PROPERTY (List<LDObject*>, objects, setObjects) - READ_PROPERTY (History, history, setHistory) - READ_PROPERTY (List<LDObject*>, vertices, setVertices) - PROPERTY (str, name, setName) - PROPERTY (bool, implicit, setImplicit) - PROPERTY (List<LDObject*>, cache, setCache) - PROPERTY (long, savePos, setSavePos) - DECLARE_PROPERTY (QListWidgetItem*, listItem, setListItem) - -public: - typedef List<LDObject*>::it it; - typedef List<LDObject*>::c_it c_it; - - LDFile(); - ~LDFile(); - - ulong addObject (LDObject* obj); // Adds an object to this file at the end of the file. - void addObjects (const List<LDObject*> objs); - void forgetObject (LDObject* obj); // Deletes the given object from the object chain. - str getShortName(); - bool hasUnsavedChanges() const; // Does this file have unsaved changes? - List<LDObject*> inlineContents (LDSubfile::InlineFlags flags); - void insertObj (const ulong pos, LDObject* obj); - ulong numObjs() const; - LDObject* object (ulong pos) const; - LDObject* obj (ulong pos) const; - bool save (str path = ""); // Saves this file to disk. - bool safeToClose(); // Perform safety checks. Do this before closing any files! - void setObject (ulong idx, LDObject* obj); +class LDFile : public QObject +{ Q_OBJECT + READ_PROPERTY (List<LDObject*>, objects, setObjects) + READ_PROPERTY (History, history, setHistory) + READ_PROPERTY (List<LDObject*>, vertices, setVertices) + PROPERTY (str, name, setName) + PROPERTY (bool, implicit, setImplicit) + PROPERTY (List<LDObject*>, cache, setCache) + PROPERTY (long, savePos, setSavePos) + DECLARE_PROPERTY (QListWidgetItem*, listItem, setListItem) + + public: + typedef List<LDObject*>::it it; + typedef List<LDObject*>::c_it c_it; + + LDFile(); + ~LDFile(); + + ulong addObject (LDObject* obj); // Adds an object to this file at the end of the file. + void addObjects (const List<LDObject*> objs); + void forgetObject (LDObject* obj); // Deletes the given object from the object chain. + str getShortName(); + bool hasUnsavedChanges() const; // Does this file have unsaved changes? + List<LDObject*> inlineContents (LDSubfile::InlineFlags flags); + void insertObj (const ulong pos, LDObject* obj); + ulong numObjs() const; + LDObject* object (ulong pos) const; + LDObject* obj (ulong pos) const; + bool save (str path = ""); // Saves this file to disk. + bool safeToClose(); // Perform safety checks. Do this before closing any files! + void setObject (ulong idx, LDObject* obj); - inline LDFile& operator<< (LDObject* obj) { addObject (obj); return *this; } - inline void openHistory() { m_history.open(); } - inline void closeHistory() { m_history.close(); } - inline void undo() { m_history.undo(); } - inline void redo() { m_history.redo(); } - inline void clearHistory() { m_history.clear(); } - inline void addToHistory (AbstractHistoryEntry* entry) { m_history << entry; } - - static void closeUnused(); - static LDFile* current(); - static void setCurrent (LDFile* f); - static void closeInitialFile(); - static int countExplicitFiles(); - -private: - static LDFile* m_curfile; + inline LDFile& operator<< (LDObject* obj) + { addObject (obj); + return *this; + } + + inline void openHistory() + { m_history.open(); + } + + inline void closeHistory() + { m_history.close(); + } + + inline void undo() + { m_history.undo(); + } + + inline void redo() + { m_history.redo(); + } + + inline void clearHistory() + { m_history.clear(); + } + + inline void addToHistory (AbstractHistoryEntry* entry) + { m_history << entry; + } + + static void closeUnused(); + static LDFile* current(); + static void setCurrent (LDFile* f); + static void closeInitialFile(); + static int countExplicitFiles(); + + private: + static LDFile* m_curfile; }; // Close all current loaded files and start off blank. @@ -148,29 +169,29 @@ // Loads the given file and parses it to LDObjects using parseLine. It's a // separate class so as to be able to do the work in a separate thread. // ============================================================================= -class FileLoader : public QObject { - Q_OBJECT - READ_PROPERTY (List<LDObject*>, objs, setObjects) - READ_PROPERTY (bool, done, setDone) - READ_PROPERTY (ulong, progress, setProgress) - READ_PROPERTY (bool, aborted, setAborted) - PROPERTY (List<str>, lines, setLines) - PROPERTY (ulong*, warningsPointer, setWarningsPointer) - PROPERTY (bool, concurrent, setConcurrent) - -public slots: - void start(); - void abort(); - -private: - OpenProgressDialog* dlg; - -private slots: - void work (int i); - -signals: - void progressUpdate (int progress); - void workDone(); +class FileLoader : public QObject +{ Q_OBJECT + READ_PROPERTY (List<LDObject*>, objs, setObjects) + READ_PROPERTY (bool, done, setDone) + READ_PROPERTY (ulong, progress, setProgress) + READ_PROPERTY (bool, aborted, setAborted) + PROPERTY (List<str>, lines, setLines) + PROPERTY (ulong*, warningsPointer, setWarningsPointer) + PROPERTY (bool, concurrent, setConcurrent) + + public slots: + void start(); + void abort(); + + private: + OpenProgressDialog* dlg; + + private slots: + void work (int i); + + signals: + void progressUpdate (int progress); + void workDone(); }; -#endif // FILE_H \ No newline at end of file +#endif // FILE_H
--- a/src/gldraw.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/gldraw.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -36,13 +36,14 @@ #include "dialogs.h" #include "addObjectDialog.h" #include "messagelog.h" +#include "moc_gldraw.cpp" -static const struct staticCameraMeta { - const char glrotate[3]; +static const struct staticCameraMeta +{ const char glrotate[3]; const Axis axisX, axisY; const bool negX, negY; -} g_staticCameras[6] = { - {{ 1, 0, 0 }, X, Z, false, false }, +} g_staticCameras[6] = +{ {{ 1, 0, 0 }, X, Z, false, false }, {{ 0, 0, 0 }, X, Y, false, true }, {{ 0, 1, 0 }, Z, Y, true, true }, {{ -1, 0, 0 }, X, Z, false, true }, @@ -50,8 +51,8 @@ {{ 0, -1, 0 }, Z, Y, false, true }, }; -static const matrix g_circleDrawTransforms[3] = { - { 2, 0, 0, 0, 1, 0, 0, 0, 2 }, +static const matrix g_circleDrawTransforms[3] = +{ { 2, 0, 0, 0, 1, 0, 0, 0, 2 }, { 2, 0, 0, 0, 0, 2, 0, 1, 0 }, { 0, 1, 0, 2, 0, 0, 0, 0, 2 }, }; @@ -68,8 +69,8 @@ cfg (Bool, gl_logostuds, false); // argh -const char* g_CameraNames[7] = { - QT_TRANSLATE_NOOP ("GLRenderer", "Top"), +const char* g_CameraNames[7] = +{ QT_TRANSLATE_NOOP ("GLRenderer", "Top"), QT_TRANSLATE_NOOP ("GLRenderer", "Front"), QT_TRANSLATE_NOOP ("GLRenderer", "Left"), QT_TRANSLATE_NOOP ("GLRenderer", "Bottom"), @@ -78,8 +79,8 @@ QT_TRANSLATE_NOOP ("GLRenderer", "Free") }; -const GL::Camera g_Cameras[7] = { - GL::Top, +const GL::Camera g_Cameras[7] = +{ GL::Top, GL::Front, GL::Left, GL::Bottom, @@ -88,11 +89,11 @@ GL::Free }; -const struct GLAxis { - const QColor col; +const struct GLAxis +{ const QColor col; const vertex vert; -} g_GLAxes[3] = { - { QColor (255, 0, 0), vertex (10000, 0, 0) }, +} g_GLAxes[3] = +{ { QColor (255, 0, 0), vertex (10000, 0, 0) }, { QColor (80, 192, 0), vertex (0, 10000, 0) }, { QColor (0, 160, 192), vertex (0, 0, 10000) }, }; @@ -102,8 +103,8 @@ // ============================================================================= // ----------------------------------------------------------------------------- -GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent) { - m_picking = m_rangepick = false; +GLRenderer::GLRenderer (QWidget* parent) : QGLWidget (parent) +{ m_picking = m_rangepick = false; m_camera = (GL::Camera) gl_camera.value; m_drawToolTip = false; m_editMode = Select; @@ -113,79 +114,79 @@ setDrawOnly (false); resetAngles(); setMessageLog (null); - + m_toolTipTimer = new QTimer (this); m_toolTipTimer->setSingleShot (true); connect (m_toolTipTimer, SIGNAL (timeout()), this, SLOT (slot_toolTipTimer())); - + m_thickBorderPen = QPen (QColor (0, 0, 0, 208), 2, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); m_thinBorderPen = m_thickBorderPen; m_thinBorderPen.setWidth (1); - + // Init camera icons - for (const GL::Camera cam : g_Cameras) { - str iconname = fmt ("camera-%1", tr (g_CameraNames[cam]).toLower()); - +for (const GL::Camera cam : g_Cameras) + { str iconname = fmt ("camera-%1", tr (g_CameraNames[cam]).toLower()); + CameraIcon* info = &m_cameraIcons[cam]; info->img = new QPixmap (getIcon (iconname)); info->cam = cam; } - - for (int i = 0; i < 6; ++i) { - m_overlays[i].img = null; + + for (int i = 0; i < 6; ++i) + { m_overlays[i].img = null; m_depthValues[i] = 0.0f; } - + calcCameraIcons(); } // ============================================================================= // ----------------------------------------------------------------------------- -GLRenderer::~GLRenderer() { - for (int i = 0; i < 6; ++i) +GLRenderer::~GLRenderer() +{ for (int i = 0; i < 6; ++i) delete m_overlays[i].img; - - for (CameraIcon& info : m_cameraIcons) + +for (CameraIcon & info : m_cameraIcons) delete info.img; } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::calcCameraIcons() { - ushort i = 0; - - for (CameraIcon& info : m_cameraIcons) { - const long x1 = (m_width - (info.cam != Free ? 48 : 16)) + ((i % 3) * 16) - 1, - y1 = ((i / 3) * 16) + 1; - +void GLRenderer::calcCameraIcons() +{ ushort i = 0; + +for (CameraIcon & info : m_cameraIcons) + { const long x1 = (m_width - (info.cam != Free ? 48 : 16)) + ( (i % 3) * 16) - 1, + y1 = ( (i / 3) * 16) + 1; + info.srcRect = QRect (0, 0, 16, 16); info.destRect = QRect (x1, y1, 16, 16); info.selRect = QRect (info.destRect.x(), info.destRect.y(), - info.destRect.width() + 1, info.destRect.height() + 1); + info.destRect.width() + 1, info.destRect.height() + 1); ++i; } } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::initGLData() { - glEnable (GL_BLEND); +void GLRenderer::initGLData() +{ glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable (GL_POLYGON_OFFSET_FILL); glPolygonOffset (1.0f, 1.0f); - + glEnable (GL_DEPTH_TEST); glShadeModel (GL_SMOOTH); glEnable (GL_MULTISAMPLE); - + glEnable (GL_LINE_SMOOTH); glHint (GL_LINE_SMOOTH_HINT, GL_NICEST); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::resetAngles() { - m_rotX = 30.0f; +void GLRenderer::resetAngles() +{ m_rotX = 30.0f; m_rotY = 325.f; m_panX = m_panY = m_rotZ = 0.0f; zoomToFit(); @@ -193,11 +194,11 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::initializeGL() { - setBackground(); - +void GLRenderer::initializeGL() +{ setBackground(); + glLineWidth (gl_linethickness); - + setAutoFillBackground (false); setMouseTracking (true); setFocusPolicy (Qt::WheelFocus); @@ -206,26 +207,26 @@ // ============================================================================= // ----------------------------------------------------------------------------- -QColor GLRenderer::getMainColor() { - QColor col (gl_maincolor); - +QColor GLRenderer::getMainColor() +{ QColor col (gl_maincolor); + if (!col.isValid()) return QColor (0, 0, 0); - + col.setAlpha (gl_maincolor_alpha * 255.f); return col; } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::setBackground() { - QColor col (gl_bgcolor); - +void GLRenderer::setBackground() +{ QColor col (gl_bgcolor); + if (!col.isValid()) return; - + col.setAlpha (255); - + m_darkbg = luma (col) < 80; m_bgcolor = col; qglClearColor (col); @@ -233,118 +234,120 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::setObjectColor (LDObject* obj, const ListType list) { - QColor qcol; - +void GLRenderer::setObjectColor (LDObject* obj, const ListType list) +{ QColor qcol; + if (!obj->isColored()) return; - - if (list == GL::PickList) { - // Make the color by the object's ID if we're picking, so we can make the + + if (list == GL::PickList) + { // Make the color by the object's ID if we're picking, so we can make the // ID again from the color we get from the picking results. Be sure to use // the top level parent's index since we want a subfile's children point // to the subfile itself. long i = obj->topLevelParent()->id(); - + // Calculate a color based from this index. This method caters for // 16777216 objects. I don't think that'll be exceeded anytime soon. :) // ATM biggest is 53588.dat with 12600 lines. double r = (i / (256 * 256)) % 256, - g = (i / 256) % 256, - b = i % 256; - + g = (i / 256) % 256, + b = i % 256; + qglColor (QColor (r, g, b)); return; } - - if ((list == BFCFrontList || list == BFCBackList) && - obj->getType() != LDObject::Line && - obj->getType() != LDObject::CndLine) { - + + if ( (list == BFCFrontList || list == BFCBackList) && + obj->getType() != LDObject::Line && + obj->getType() != LDObject::CndLine) + { + if (list == GL::BFCFrontList) qcol = QColor (40, 192, 0); else qcol = QColor (224, 0, 0); - } else { - if (obj->color() == maincolor) + } + else + { if (obj->color() == maincolor) qcol = getMainColor(); - else { - LDColor* col = getColor (obj->color()); - + else + { LDColor* col = getColor (obj->color()); + if (col) qcol = col->faceColor; } - - if (obj->color() == edgecolor) { - qcol = luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black; + + if (obj->color() == edgecolor) + { qcol = luma (m_bgcolor) < 40 ? QColor (64, 64, 64) : Qt::black; LDColor* col; - + if (!gl_blackedges && obj->parent() && (col = getColor (obj->parent()->color()))) qcol = col->edgeColor; } - - if (qcol.isValid() == false) { - // The color was unknown. Use main color to make the object at least + + if (qcol.isValid() == false) + { // The color was unknown. Use main color to make the object at least // not appear pitch-black. if (obj->color() != edgecolor) qcol = getMainColor(); - + // Warn about the unknown colors, but only once. - for (short i : g_warnedColors) + for (short i : g_warnedColors) if (obj->color() == i) return; - + printf ("%s: Unknown color %d!\n", __func__, obj->color()); g_warnedColors << obj->color(); return; } } - + long r = qcol.red(), - g = qcol.green(), - b = qcol.blue(), - a = qcol.alpha(); - - if (obj->topLevelParent()->selected()) { - // Brighten it up for the select list. + g = qcol.green(), + b = qcol.blue(), + a = qcol.alpha(); + + if (obj->topLevelParent()->selected()) + { // Brighten it up for the select list. const uchar add = 51; - + r = min (r + add, 255l); g = min (g + add, 255l); b = min (b + add, 255l); } - + glColor4f ( - ((double) r) / 255.0f, - ((double) g) / 255.0f, - ((double) b) / 255.0f, - ((double) a) / 255.0f); + ( (double) r) / 255.0f, + ( (double) g) / 255.0f, + ( (double) b) / 255.0f, + ( (double) a) / 255.0f); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::refresh() { - update(); +void GLRenderer::refresh() +{ update(); swapBuffers(); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::hardRefresh() { - compileAllObjects(); +void GLRenderer::hardRefresh() +{ compileAllObjects(); refresh(); - + glLineWidth (gl_linethickness); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::resizeGL (int w, int h) { - m_width = w; +void GLRenderer::resizeGL (int w, int h) +{ m_width = w; m_height = h; - + calcCameraIcons(); - + glViewport (0, 0, w, h); glMatrixMode (GL_PROJECTION); glLoadIdentity(); @@ -354,76 +357,78 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::drawGLScene() { - if (file() == null) +void GLRenderer::drawGLScene() +{ if (file() == null) return; - + if (gl_wireframe && !picking()) glPolygonMode (GL_FRONT_AND_BACK, GL_LINE); - + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable (GL_DEPTH_TEST); - - if (m_camera != Free) { - glMatrixMode (GL_PROJECTION); + + if (m_camera != Free) + { glMatrixMode (GL_PROJECTION); glPushMatrix(); - + glLoadIdentity(); glOrtho (-m_virtWidth, m_virtWidth, -m_virtHeight, m_virtHeight, -100.0f, 100.0f); glTranslatef (m_panX, m_panY, 0.0f); - - if (m_camera != Front && m_camera != Back) { - glRotatef (90.0f, g_staticCameras[m_camera].glrotate[0], - g_staticCameras[m_camera].glrotate[1], - g_staticCameras[m_camera].glrotate[2]); + + if (m_camera != Front && m_camera != Back) + { glRotatef (90.0f, g_staticCameras[m_camera].glrotate[0], + g_staticCameras[m_camera].glrotate[1], + g_staticCameras[m_camera].glrotate[2]); } - + // Back camera needs to be handled differently - if (m_camera == GLRenderer::Back) { - glRotatef (180.0f, 1.0f, 0.0f, 0.0f); + if (m_camera == GLRenderer::Back) + { glRotatef (180.0f, 1.0f, 0.0f, 0.0f); glRotatef (180.0f, 0.0f, 0.0f, 1.0f); } - } else { - glMatrixMode (GL_MODELVIEW); + } + else + { glMatrixMode (GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - + glTranslatef (0.0f, 0.0f, -2.0f); glTranslatef (m_panX, m_panY, -zoom()); glRotatef (m_rotX, 1.0f, 0.0f, 0.0f); glRotatef (m_rotY, 0.0f, 1.0f, 0.0f); glRotatef (m_rotZ, 0.0f, 0.0f, 1.0f); } - + const GL::ListType list = (!drawOnly() && m_picking) ? PickList : NormalList; - - if (gl_colorbfc && !m_picking && !drawOnly()) { - glEnable (GL_CULL_FACE); - - for (LDObject* obj : file()->objects()) { - if (obj->hidden()) + + if (gl_colorbfc && !m_picking && !drawOnly()) + { glEnable (GL_CULL_FACE); + + for (LDObject * obj : file()->objects()) + { if (obj->hidden()) continue; - + glCullFace (GL_BACK); glCallList (obj->glLists[BFCFrontList]); - + glCullFace (GL_FRONT); glCallList (obj->glLists[BFCBackList]); } - + glDisable (GL_CULL_FACE); - } else { - for (LDObject* obj : file()->objects()) { - if (obj->hidden()) + } + else +{ for (LDObject * obj : file()->objects()) + { if (obj->hidden()) continue; - + glCallList (obj->glLists[list]); } } - + if (gl_axes && !m_picking && !drawOnly()) glCallList (m_axeslist); - + glPopMatrix(); glMatrixMode (GL_MODELVIEW); glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); @@ -434,28 +439,28 @@ // This converts a 2D point on the screen to a 3D point in the model. If 'snap' // is true, the 3D point will snap to the current grid. // ----------------------------------------------------------------------------- -vertex GLRenderer::coordconv2_3 (const QPoint& pos2d, bool snap) const { - assert (camera() != Free); - +vertex GLRenderer::coordconv2_3 (const QPoint& pos2d, bool snap) const +{ assert (camera() != Free); + vertex pos3d; const staticCameraMeta* cam = &g_staticCameras[m_camera]; const Axis axisX = cam->axisX; const Axis axisY = cam->axisY; const short negXFac = cam->negX ? -1 : 1, - negYFac = cam->negY ? -1 : 1; - + negYFac = cam->negY ? -1 : 1; + // Calculate cx and cy - these are the LDraw unit coords the cursor is at. - double cx = (-m_virtWidth + ((2 * pos2d.x() * m_virtWidth) / m_width) - m_panX); - double cy = (m_virtHeight - ((2 * pos2d.y() * m_virtHeight) / m_height) - m_panY); - - if (snap) { - cx = Grid::snap (cx, (Grid::Config) axisX); + double cx = (-m_virtWidth + ( (2 * pos2d.x() * m_virtWidth) / m_width) - m_panX); + double cy = (m_virtHeight - ( (2 * pos2d.y() * m_virtHeight) / m_height) - m_panY); + + if (snap) + { cx = Grid::snap (cx, (Grid::Config) axisX); cy = Grid::snap (cy, (Grid::Config) axisY); } - + cx *= negXFac; cy *= negYFac; - + str tmp; // Create the vertex from the coordinates pos3d[axisX] = tmp.sprintf ("%.3f", cx).toDouble(); @@ -469,112 +474,117 @@ // Inverse operation for the above - convert a 3D position to a 2D screen // position // ----------------------------------------------------------------------------- -QPoint GLRenderer::coordconv3_2 (const vertex& pos3d) const { - GLfloat m[16]; +QPoint GLRenderer::coordconv3_2 (const vertex& pos3d) const +{ GLfloat m[16]; const staticCameraMeta* cam = &g_staticCameras[m_camera]; const Axis axisX = cam->axisX; const Axis axisY = cam->axisY; const short negXFac = cam->negX ? -1 : 1, - negYFac = cam->negY ? -1 : 1; - + negYFac = cam->negY ? -1 : 1; + glGetFloatv (GL_MODELVIEW_MATRIX, m); - + const double x = pos3d.x(); const double y = pos3d.y(); const double z = pos3d.z(); - + vertex transformed; transformed[X] = (m[0] * x) + (m[1] * y) + (m[2] * z) + m[3]; transformed[Y] = (m[4] * x) + (m[5] * y) + (m[6] * z) + m[7]; transformed[Z] = (m[8] * x) + (m[9] * y) + (m[10] * z) + m[11]; - - double rx = (((transformed[axisX] * negXFac) + m_virtWidth + m_panX) * m_width) / (2 * m_virtWidth); - double ry = (((transformed[axisY] * negYFac) - m_virtHeight + m_panY) * m_height) / (2 * m_virtHeight); - + + double rx = ( ( (transformed[axisX] * negXFac) + m_virtWidth + m_panX) * m_width) / (2 * m_virtWidth); + double ry = ( ( (transformed[axisY] * negYFac) - m_virtHeight + m_panY) * m_height) / (2 * m_virtHeight); + return QPoint (rx, -ry); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::paintEvent (QPaintEvent* ev) { - Q_UNUSED (ev) - +void GLRenderer::paintEvent (QPaintEvent* ev) +{ Q_UNUSED (ev) + makeCurrent(); m_virtWidth = zoom(); m_virtHeight = (m_height * m_virtWidth) / m_width; - + initGLData(); drawGLScene(); - + QPainter paint (this); QFontMetrics metrics = QFontMetrics (QFont()); paint.setRenderHint (QPainter::HighQualityAntialiasing); - + // If we wish to only draw the brick, stop here if (drawOnly()) return; - - if (m_camera != Free && !picking()) { - // Paint the overlay image if we have one + + if (m_camera != Free && !picking()) + { // Paint the overlay image if we have one const overlayMeta& overlay = m_overlays[m_camera]; - if (overlay.img != null) { - QPoint v0 = coordconv3_2 (m_overlays[m_camera].v0), - v1 = coordconv3_2 (m_overlays[m_camera].v1); - + + if (overlay.img != null) + { QPoint v0 = coordconv3_2 (m_overlays[m_camera].v0), + v1 = coordconv3_2 (m_overlays[m_camera].v1); + QRect targRect (v0.x(), v0.y(), abs (v1.x() - v0.x()), abs (v1.y() - v0.y())), - srcRect (0, 0, overlay.img->width(), overlay.img->height()); + srcRect (0, 0, overlay.img->width(), overlay.img->height()); paint.drawImage (targRect, *overlay.img, srcRect); } - + // Paint the coordinates onto the screen. str text = fmt (tr ("X: %1, Y: %2, Z: %3"), m_hoverpos[X], m_hoverpos[Y], m_hoverpos[Z]); - + QFontMetrics metrics = QFontMetrics (font()); QRect textSize = metrics.boundingRect (0, 0, m_width, m_height, Qt::AlignCenter, text); - + paint.setPen (getTextPen()); paint.drawText (m_width - textSize.width(), m_height - 16, textSize.width(), - textSize.height(), Qt::AlignCenter, text); - + textSize.height(), Qt::AlignCenter, text); + // If we're drawing, draw the vertices onto the screen. - if (editMode() == Draw) { - int numverts = 4; - + if (editMode() == Draw) + { int numverts = 4; + if (!m_rectdraw) numverts = m_drawedVerts.size() + 1; - - if (numverts > 0) { - QPoint poly[4]; + + if (numverts > 0) + { QPoint poly[4]; vertex polyverts[4]; - - if (!m_rectdraw) { - uchar i = 0; - for (vertex& vert : m_drawedVerts) { - poly[i] = coordconv3_2 (vert); + + if (!m_rectdraw) + { uchar i = 0; + + for (vertex & vert : m_drawedVerts) + { poly[i] = coordconv3_2 (vert); polyverts[i] = vert; ++i; } - + // Draw the cursor vertex as the last one in the list. - if (numverts <= 4) { - poly[i] = coordconv3_2 (m_hoverpos); + if (numverts <= 4) + { poly[i] = coordconv3_2 (m_hoverpos); polyverts[i] = m_hoverpos; - } else { - numverts = 4; + } + else + { numverts = 4; } - } else { - if (m_drawedVerts.size() > 0) { - // Get vertex information from m_rectverts - for (int i = 0; i < numverts; ++i) { - polyverts[i] = m_rectverts[i]; + } + else + { if (m_drawedVerts.size() > 0) + { // Get vertex information from m_rectverts + for (int i = 0; i < numverts; ++i) + { polyverts[i] = m_rectverts[i]; poly[i] = coordconv3_2 (polyverts[i]); } - } else { - poly[0] = coordconv3_2 (m_hoverpos); + } + else + { poly[0] = coordconv3_2 (m_hoverpos); polyverts[0] = m_hoverpos; } } - + // Draw the polygon-to-be QPen pen = m_thinBorderPen; pen.setWidth (2); @@ -582,10 +592,10 @@ paint.setPen (pen); paint.setBrush (QColor (64, 192, 0, 128)); paint.drawPolygon (poly, numverts); - + // Draw vertex blips - for (int i = 0; i < numverts; ++i) { - QPoint& blip = poly[i]; + for (int i = 0; i < numverts; ++i) + { QPoint& blip = poly[i]; drawBlip (paint, blip); // Draw their coordinates @@ -593,6 +603,7 @@ } } } + elif (editMode() == CircleMode) { // If we have not specified the center point of the circle yet, preview it on the screen. if (m_drawedVerts.size() == 0) @@ -613,7 +624,8 @@ } QVector<QPoint> points; - for (const vertex& v : verts) + + for (const vertex & v : verts) { QPoint point = coordconv3_2 (v); drawBlip (paint, point); points << point; @@ -628,71 +640,70 @@ } } } - + // Camera icons - if (!m_picking) { - // Draw a background for the selected camera + if (!m_picking) + { // Draw a background for the selected camera paint.setPen (m_thinBorderPen); paint.setBrush (QBrush (QColor (0, 128, 160, 128))); paint.drawRect (m_cameraIcons[camera()].selRect); - + // Draw the actual icons - for (CameraIcon& info : m_cameraIcons) { - // Don't draw the free camera icon when in draw mode + for (CameraIcon & info : m_cameraIcons) + { // Don't draw the free camera icon when in draw mode if (&info == &m_cameraIcons[GL::Free] && editMode() != Select) continue; - + paint.drawPixmap (info.destRect, *info.img, info.srcRect); } - + str fmtstr = tr ("%1 Camera"); - + // Draw a label for the current camera in the bottom left corner - { - const ushort margin = 4; - + { const ushort margin = 4; + str label; label = fmt (fmtstr, tr (g_CameraNames[camera()])); paint.setPen (getTextPen()); - paint.drawText (QPoint (margin, height() - (margin + metrics.descent())), label); + paint.drawText (QPoint (margin, height() - (margin + metrics.descent())), label); } - + // Tool tips - if (m_drawToolTip) { - if (m_cameraIcons[m_toolTipCamera].destRect.contains (m_pos) == false) + if (m_drawToolTip) + { if (m_cameraIcons[m_toolTipCamera].destRect.contains (m_pos) == false) m_drawToolTip = false; - else { - str label = fmt (fmtstr, tr (g_CameraNames[m_toolTipCamera])); + else + { str label = fmt (fmtstr, tr (g_CameraNames[m_toolTipCamera])); QToolTip::showText (m_globalpos, label); } } } - + // Message log - if (msglog()) { - int y = 0; + if (msglog()) + { int y = 0; const int margin = 2; QColor penColor = getTextPen(); - - for (const MessageManager::Line& line : msglog()->getLines()) { - penColor.setAlphaF (line.alpha); + + for (const MessageManager::Line & line : msglog()->getLines()) + { penColor.setAlphaF (line.alpha); paint.setPen (penColor); paint.drawText (QPoint (margin, y + margin + metrics.ascent()), line.text); y += metrics.height(); } } - + // If we're range-picking, draw a rectangle encompassing the selection area. - if (m_rangepick && !m_picking && m_totalmove >= 10) { - const short x0 = m_rangeStart.x(), - y0 = m_rangeStart.y(), - x1 = m_pos.x(), - y1 = m_pos.y(); - + if (m_rangepick && !m_picking && m_totalmove >= 10) + { const short x0 = m_rangeStart.x(), + y0 = m_rangeStart.y(), + x1 = m_pos.x(), + y1 = m_pos.y(); + QRect rect (x0, y0, x1 - x0, y1 - y0); QColor fillColor = (m_addpick ? "#40FF00" : "#00CCFF"); fillColor.setAlphaF (0.2f); - + paint.setPen (m_thickBorderPen); paint.setBrush (QBrush (fillColor)); paint.drawRect (rect); @@ -712,263 +723,270 @@ // ============================================================================= // ----------------------------------------------------------------------------- -QColor GLRenderer::getTextPen () const { - return m_darkbg ? Qt::white : Qt::black; +QColor GLRenderer::getTextPen () const +{ return m_darkbg ? Qt::white : Qt::black; } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::compileAllObjects() { - if (!file()) +void GLRenderer::compileAllObjects() +{ if (!file()) return; - + // Compiling all is a big job, use a busy cursor setCursor (Qt::BusyCursor); - + m_knownVerts.clear(); - - for (LDObject* obj : file()->objects()) + +for (LDObject * obj : file()->objects()) compileObject (obj); - + // Compile axes glDeleteLists (m_axeslist, 1); m_axeslist = glGenLists (1); glNewList (m_axeslist, GL_COMPILE); glBegin (GL_LINES); - - for (const GLAxis& ax : g_GLAxes) { - qglColor (ax.col); + +for (const GLAxis & ax : g_GLAxes) + { qglColor (ax.col); compileVertex (ax.vert); compileVertex (-ax.vert); } - + glEnd(); glEndList(); - + setCursor (Qt::ArrowCursor); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::compileSubObject (LDObject* obj, const GLenum gltype) { - glBegin (gltype); - +void GLRenderer::compileSubObject (LDObject* obj, const GLenum gltype) +{ glBegin (gltype); + const short numverts = (obj->getType() != LDObject::CndLine) ? obj->vertices() : 2; - + if (g_glInvert == false) for (short i = 0; i < numverts; ++i) compileVertex (obj->m_coords[i]); else for (short i = numverts - 1; i >= 0; --i) compileVertex (obj->m_coords[i]); - + glEnd(); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::compileList (LDObject* obj, const GLRenderer::ListType list) { - setObjectColor (obj, list); - - switch (obj->getType()) { - case LDObject::Line: - compileSubObject (obj, GL_LINES); - break; - - case LDObject::CndLine: - // Draw conditional lines with a dash pattern - however, use a full - // line when drawing a pick list to make selecting them easier. - if (list != GL::PickList) { - glLineStipple (1, 0x6666); - glEnable (GL_LINE_STIPPLE); - } - - compileSubObject (obj, GL_LINES); - - glDisable (GL_LINE_STIPPLE); - break; - - case LDObject::Triangle: - compileSubObject (obj, GL_TRIANGLES); - break; - - case LDObject::Quad: - compileSubObject (obj, GL_QUADS); - break; - - case LDObject::Subfile: { - LDSubfile* ref = static_cast<LDSubfile*> (obj); +void GLRenderer::compileList (LDObject* obj, const GLRenderer::ListType list) +{ setObjectColor (obj, list); + + switch (obj->getType()) + { case LDObject::Line: + compileSubObject (obj, GL_LINES); + break; + + case LDObject::CndLine: + + // Draw conditional lines with a dash pattern - however, use a full + // line when drawing a pick list to make selecting them easier. + if (list != GL::PickList) + { glLineStipple (1, 0x6666); + glEnable (GL_LINE_STIPPLE); + } + + compileSubObject (obj, GL_LINES); + + glDisable (GL_LINE_STIPPLE); + break; + + case LDObject::Triangle: + compileSubObject (obj, GL_TRIANGLES); + break; + + case LDObject::Quad: + compileSubObject (obj, GL_QUADS); + break; + + case LDObject::Subfile: + { LDSubfile* ref = static_cast<LDSubfile*> (obj); List<LDObject*> objs; - + objs = ref->inlineContents ( - LDSubfile::DeepInline | - LDSubfile::CacheInline | - LDSubfile::RendererInline); + LDSubfile::DeepInline | + LDSubfile::CacheInline | + LDSubfile::RendererInline); bool oldinvert = g_glInvert; - + if (ref->transform().determinant() < 0) g_glInvert = !g_glInvert; - + LDObject* prev = ref->prev(); + if (prev && prev->getType() == LDObject::BFC && static_cast<LDBFC*> (prev)->type == LDBFC::InvertNext) g_glInvert = !g_glInvert; - - for (LDObject* obj : objs) { - compileList (obj, list); + + for (LDObject * obj : objs) + { compileList (obj, list); delete obj; } - + g_glInvert = oldinvert; } break; - - default: - break; + + default: + break; } } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::compileVertex (const vertex& vrt) { - glVertex3d (vrt[X], -vrt[Y], -vrt[Z]); +void GLRenderer::compileVertex (const vertex& vrt) +{ glVertex3d (vrt[X], -vrt[Y], -vrt[Z]); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::clampAngle (double& angle) const { - while (angle < 0) +void GLRenderer::clampAngle (double& angle) const +{ while (angle < 0) angle += 360.0; + while (angle > 360.0) angle -= 360.0; } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::addDrawnVertex (vertex pos) { - // If we picked an already-existing vertex, stop drawing - for (vertex& vert : m_drawedVerts) { - if (vert == pos) { - endDraw (true); +void GLRenderer::addDrawnVertex (vertex pos) +{ // If we picked an already-existing vertex, stop drawing +for (vertex & vert : m_drawedVerts) + { if (vert == pos) + { endDraw (true); return; } } - + m_drawedVerts << pos; } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::mouseReleaseEvent (QMouseEvent* ev) { - const bool wasLeft = (m_lastButtons & Qt::LeftButton) && !(ev->buttons() & Qt::LeftButton), - wasRight = (m_lastButtons & Qt::RightButton) && !(ev->buttons() & Qt::RightButton), - wasMid = (m_lastButtons & Qt::MidButton) && !(ev->buttons() & Qt::MidButton); - +void GLRenderer::mouseReleaseEvent (QMouseEvent* ev) +{ const bool wasLeft = (m_lastButtons & Qt::LeftButton) && ! (ev->buttons() & Qt::LeftButton), + wasRight = (m_lastButtons & Qt::RightButton) && ! (ev->buttons() & Qt::RightButton), + wasMid = (m_lastButtons & Qt::MidButton) && ! (ev->buttons() & Qt::MidButton); + if (m_panning) m_panning = false; - - if (wasLeft) { - // Check if we selected a camera icon - if (!m_rangepick) { - for (CameraIcon& info : m_cameraIcons) { - if (info.destRect.contains (ev->pos())) { - setCamera (info.cam); + + if (wasLeft) + { // Check if we selected a camera icon + if (!m_rangepick) + { for (CameraIcon & info : m_cameraIcons) + { if (info.destRect.contains (ev->pos())) + { setCamera (info.cam); goto end; } } } - - switch (editMode()) { - case Draw: - if (m_rectdraw) { - if (m_drawedVerts.size() == 2) { - endDraw (true); - return; + + switch (editMode()) + { case Draw: + + if (m_rectdraw) + { if (m_drawedVerts.size() == 2) + { endDraw (true); + return; + } } - } else { - // If we have 4 verts, stop drawing. - if (m_drawedVerts.size() >= 4) { - endDraw (true); + else + { // If we have 4 verts, stop drawing. + if (m_drawedVerts.size() >= 4) + { endDraw (true); + return; + } + + if (m_drawedVerts.size() == 0 && ev->modifiers() & Qt::ShiftModifier) + { m_rectdraw = true; + updateRectVerts(); + } + } + + addDrawnVertex (m_hoverpos); + break; + + case CircleMode: + + if (m_drawedVerts.size() == 2) + { endDraw (true); return; } - - if (m_drawedVerts.size() == 0 && ev->modifiers() & Qt::ShiftModifier) { - m_rectdraw = true; - updateRectVerts(); - } - } - - addDrawnVertex (m_hoverpos); - break; + + addDrawnVertex (m_hoverpos); + break; - case CircleMode: - if (m_drawedVerts.size() == 2) - { endDraw (true); - return; - } + case Select: + + if (!drawOnly()) + { if (m_totalmove < 10) + m_rangepick = false; - addDrawnVertex (m_hoverpos); - break; + if (!m_rangepick) + m_addpick = (m_keymods & Qt::ControlModifier); - case Select: - if (!drawOnly()) { - if (m_totalmove < 10) - m_rangepick = false; - - if (!m_rangepick) - m_addpick = (m_keymods & Qt::ControlModifier); - - if (m_totalmove < 10 || m_rangepick) - pick (ev->x(), ev->y()); - } - - break; + if (m_totalmove < 10 || m_rangepick) + pick (ev->x(), ev->y()); + } + + break; } - + m_rangepick = false; } - - if (wasMid && editMode() == Draw && m_drawedVerts.size() < 4 && m_totalmove < 10) { - // Find the closest vertex to our cursor + + if (wasMid && editMode() != Select && m_drawedVerts.size() < 4 && m_totalmove < 10) + { // Find the closest vertex to our cursor double mindist = 1024.0f; vertex closest; bool valid = false; - + QPoint curspos = coordconv3_2 (m_hoverpos); - - for (const vertex& pos3d: m_knownVerts) { - QPoint pos2d = coordconv3_2 (pos3d); - + + for (const vertex & pos3d: m_knownVerts) + { QPoint pos2d = coordconv3_2 (pos3d); + // Measure squared distance const double dx = abs (pos2d.x() - curspos.x()), - dy = abs (pos2d.y() - curspos.y()), - distsq = (dx * dx) + (dy * dy); - + dy = abs (pos2d.y() - curspos.y()), + distsq = (dx * dx) + (dy * dy); + if (distsq >= 1024.0f) // 32.0f ** 2 continue; // too far away - - if (distsq < mindist) { - mindist = distsq; + + if (distsq < mindist) + { mindist = distsq; closest = pos3d; valid = true; - + // If it's only 4 pixels away, I think we found our vertex now. if (distsq <= 16.0f) // 4.0f ** 2 break; } } - + if (valid) addDrawnVertex (closest); } - - if (wasRight && m_drawedVerts.size() > 0) { - // Remove the last vertex + + if (wasRight && m_drawedVerts.size() > 0) + { // Remove the last vertex m_drawedVerts.erase (m_drawedVerts.size() - 1); - + if (m_drawedVerts.size() == 0) m_rectdraw = false; } - + end: update(); m_totalmove = 0; @@ -976,89 +994,90 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::mousePressEvent (QMouseEvent* ev) { - m_totalmove = 0; - - if (ev->modifiers() & Qt::ControlModifier) { - m_rangepick = true; +void GLRenderer::mousePressEvent (QMouseEvent* ev) +{ m_totalmove = 0; + + if (ev->modifiers() & Qt::ControlModifier) + { m_rangepick = true; m_rangeStart.setX (ev->x()); m_rangeStart.setY (ev->y()); m_addpick = (m_keymods & Qt::AltModifier); ev->accept(); } - + m_lastButtons = ev->buttons(); } // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -void GLRenderer::mouseMoveEvent (QMouseEvent* ev) { - int dx = ev->x() - m_pos.x(); +void GLRenderer::mouseMoveEvent (QMouseEvent* ev) +{ int dx = ev->x() - m_pos.x(); int dy = ev->y() - m_pos.y(); m_totalmove += abs (dx) + abs (dy); - + const bool left = ev->buttons() & Qt::LeftButton, - mid = ev->buttons() & Qt::MidButton, - shift = ev->modifiers() & Qt::ShiftModifier; - - if (mid || (left && shift)) { - m_panX += 0.03f * dx * (zoom() / 7.5f); + mid = ev->buttons() & Qt::MidButton, + shift = ev->modifiers() & Qt::ShiftModifier; + + if (mid || (left && shift)) + { m_panX += 0.03f * dx * (zoom() / 7.5f); m_panY -= 0.03f * dy * (zoom() / 7.5f); m_panning = true; - } elif (left && !m_rangepick && camera() == Free) { - m_rotX = m_rotX + (dy); + } elif (left && !m_rangepick && camera() == Free) + + { m_rotX = m_rotX + (dy); m_rotY = m_rotY + (dx); - + clampAngle (m_rotX); clampAngle (m_rotY); } - + // Start the tool tip timer if (!m_drawToolTip) m_toolTipTimer->start (500); - + // Update 2d position m_pos = ev->pos(); m_globalpos = ev->globalPos(); - + // Calculate 3d position of the cursor m_hoverpos = (camera() != Free) ? coordconv2_3 (m_pos, true) : g_origin; - + // Update rect vertices since m_hoverpos may have changed updateRectVerts(); - + update(); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::keyPressEvent (QKeyEvent* ev) { - m_keymods = ev->modifiers(); +void GLRenderer::keyPressEvent (QKeyEvent* ev) +{ m_keymods = ev->modifiers(); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::keyReleaseEvent (QKeyEvent* ev) { - m_keymods = ev->modifiers(); +void GLRenderer::keyReleaseEvent (QKeyEvent* ev) +{ m_keymods = ev->modifiers(); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::wheelEvent (QWheelEvent* ev) { - makeCurrent(); - +void GLRenderer::wheelEvent (QWheelEvent* ev) +{ makeCurrent(); + zoomNotch (ev->delta() > 0); setZoom (clamp<double> (zoom(), 0.01f, 10000.0f)); - + update(); ev->accept(); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::leaveEvent (QEvent* ev) { - (void) ev; +void GLRenderer::leaveEvent (QEvent* ev) +{ (void) ev; m_drawToolTip = false; m_toolTipTimer->stop(); update(); @@ -1066,269 +1085,278 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::contextMenuEvent (QContextMenuEvent* ev) { - g_win->spawnContextMenu (ev->globalPos()); +void GLRenderer::contextMenuEvent (QContextMenuEvent* ev) +{ g_win->spawnContextMenu (ev->globalPos()); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::setCamera (const GL::Camera cam) { - m_camera = cam; +void GLRenderer::setCamera (const GL::Camera cam) +{ m_camera = cam; gl_camera = (int) cam; g_win->updateEditModeActions(); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::pick (uint mouseX, uint mouseY) { - GLint viewport[4]; +void GLRenderer::pick (uint mouseX, uint mouseY) +{ GLint viewport[4]; makeCurrent(); - + // Use particularly thick lines while picking ease up selecting lines. glLineWidth (max<double> (gl_linethickness, 6.5f)); - + // Clear the selection if we do not wish to add to it. - if (!m_addpick) { - List<LDObject*> oldsel = g_win->sel(); + if (!m_addpick) + { List<LDObject*> oldsel = g_win->sel(); g_win->sel().clear(); - - for (LDObject* obj : oldsel) { - obj->setSelected (false); + + for (LDObject * obj : oldsel) + { obj->setSelected (false); compileObject (obj); } } - + m_picking = true; - + // Paint the picking scene glDisable (GL_DITHER); glClearColor (1.0f, 1.0f, 1.0f, 1.0f); - + drawGLScene(); - + glGetIntegerv (GL_VIEWPORT, viewport); - + short x0 = mouseX, - y0 = mouseY; + y0 = mouseY; short x1, y1; - + // Determine how big an area to read - with range picking, we pick by // the area given, with single pixel picking, we use an 1 x 1 area. - if (m_rangepick) { - x1 = m_rangeStart.x(); + if (m_rangepick) + { x1 = m_rangeStart.x(); y1 = m_rangeStart.y(); - } else { - x1 = x0 + 1; + } + else + { x1 = x0 + 1; y1 = y0 + 1; } - + // x0 and y0 must be less than x1 and y1, respectively. if (x0 > x1) dataswap (x0, x1); - + if (y0 > y1) dataswap (y0, y1); - + // Clamp the values to ensure they're within bounds x0 = max<short> (0, x0); y0 = max<short> (0, y0); x1 = min<short> (x1, m_width); y1 = min<short> (y1, m_height); - + const short areawidth = (x1 - x0); const short areaheight = (y1 - y0); const long numpixels = areawidth * areaheight; - + // Allocate space for the pixel data. uchar* const pixeldata = new uchar[4 * numpixels]; uchar* pixelptr = &pixeldata[0]; - + assert (viewport[3] == m_height); - + // Read pixels from the color buffer. glReadPixels (x0, viewport[3] - y1, areawidth, areaheight, GL_RGBA, GL_UNSIGNED_BYTE, pixeldata); - + LDObject* removedObj = null; - + // Go through each pixel read and add them to the selection. - for (long i = 0; i < numpixels; ++i) { - long idx = - (*(pixelptr + 0) * 0x10000) + - (*(pixelptr + 1) * 0x00100) + - (*(pixelptr + 2) * 0x00001); + for (long i = 0; i < numpixels; ++i) + { long idx = + (* (pixelptr + 0) * 0x10000) + + (* (pixelptr + 1) * 0x00100) + + (* (pixelptr + 2) * 0x00001); pixelptr += 4; - + if (idx == 0xFFFFFF) continue; // White is background; skip - + LDObject* obj = LDObject::fromID (idx); - + // If this is an additive single pick and the object is currently selected, // we remove it from selection instead. - if (!m_rangepick && m_addpick) { - bool removed = false; - - for (ulong i = 0; i < g_win->sel().size(); ++i) { - if (g_win->sel()[i] == obj) { - g_win->sel().erase (i); + if (!m_rangepick && m_addpick) + { bool removed = false; + + for (ulong i = 0; i < g_win->sel().size(); ++i) + { if (g_win->sel() [i] == obj) + { g_win->sel().erase (i); obj->setSelected (false); removed = true; removedObj = obj; } } - + if (removed) break; } - + g_win->sel() << obj; } - + delete[] pixeldata; - + // Remove duplicated entries g_win->sel().makeUnique(); - + // Update everything now. g_win->updateSelection(); - + // Recompile the objects now to update their color - for (LDObject* obj : g_win->sel()) +for (LDObject * obj : g_win->sel()) compileObject (obj); - + if (removedObj) compileObject (removedObj); - + // Restore line thickness glLineWidth (gl_linethickness); - + m_picking = false; m_rangepick = false; glEnable (GL_DITHER); - + setBackground(); repaint(); } // ============================================================================= // ----------------------------------------------------------------------------- -READ_ACCESSOR (EditMode, GLRenderer::editMode) { - return m_editMode; +READ_ACCESSOR (EditMode, GLRenderer::editMode) +{ return m_editMode; } // ============================================================================= // ----------------------------------------------------------------------------- -SET_ACCESSOR (EditMode, GLRenderer::setEditMode) { - m_editMode = val; - - switch (editMode()) { - case Select: - unsetCursor(); - setContextMenuPolicy (Qt::DefaultContextMenu); - break; - - case Draw: - case CircleMode: - // Cannot draw into the free camera - use top instead. - if (m_camera == Free) - setCamera (Top); - - // Disable the context menu - we need the right mouse button - // for removing vertices. - setContextMenuPolicy (Qt::NoContextMenu); - - // Use the crosshair cursor when drawing. - setCursor (Qt::CrossCursor); - - // Clear the selection when beginning to draw. - // FIXME: make the selection clearing stuff in ::pick a method and use it - // here! This code doesn't update the GL lists. - g_win->sel().clear(); - g_win->updateSelection(); - m_drawedVerts.clear(); - break; +SET_ACCESSOR (EditMode, GLRenderer::setEditMode) +{ m_editMode = val; + + switch (editMode()) + { case Select: + unsetCursor(); + setContextMenuPolicy (Qt::DefaultContextMenu); + break; + + case Draw: + case CircleMode: + + // Cannot draw into the free camera - use top instead. + if (m_camera == Free) + setCamera (Top); + + // Disable the context menu - we need the right mouse button + // for removing vertices. + setContextMenuPolicy (Qt::NoContextMenu); + + // Use the crosshair cursor when drawing. + setCursor (Qt::CrossCursor); + + // Clear the selection when beginning to draw. + // FIXME: make the selection clearing stuff in ::pick a method and use it + // here! This code doesn't update the GL lists. + g_win->sel().clear(); + g_win->updateSelection(); + m_drawedVerts.clear(); + break; } - + g_win->updateEditModeActions(); update(); } // ============================================================================= // ----------------------------------------------------------------------------- -READ_ACCESSOR (LDFile*, GLRenderer::file) { - return m_file; +READ_ACCESSOR (LDFile*, GLRenderer::file) +{ return m_file; } // ============================================================================= // ----------------------------------------------------------------------------- -SET_ACCESSOR (LDFile*, GLRenderer::setFile) { - m_file = val; - +SET_ACCESSOR (LDFile*, GLRenderer::setFile) +{ m_file = val; + if (val != null) overlaysFromObjects(); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::endDraw (bool accept) { - (void) accept; - +void GLRenderer::endDraw (bool accept) +{ (void) accept; + // Clean the selection and create the object List<vertex>& verts = m_drawedVerts; LDObject* obj = null; switch (editMode()) { case Draw: - if (m_rectdraw) { - LDQuad* quad = new LDQuad; - - // Copy the vertices from m_rectverts - updateRectVerts(); - - for (int i = 0; i < quad->vertices(); ++i) - quad->setVertex (i, m_rectverts[i]); - - quad->setColor (maincolor); - obj = quad; - } else { - switch (verts.size()) { - case 1: - // 1 vertex - add a vertex object - obj = new LDVertex; - static_cast<LDVertex*> (obj)->pos = verts[0]; - obj->setColor (maincolor); - break; - - case 2: - // 2 verts - make a line - obj = new LDLine (verts[0], verts[1]); - obj->setColor (edgecolor); - break; - - case 3: - case 4: - obj = (verts.size() == 3) ? - static_cast<LDObject*> (new LDTriangle) : - static_cast<LDObject*> (new LDQuad); - - obj->setColor (maincolor); - for (ushort i = 0; i < obj->vertices(); ++i) - obj->setVertex (i, verts[i]); - break; + + if (m_rectdraw) + { LDQuad* quad = new LDQuad; + + // Copy the vertices from m_rectverts + updateRectVerts(); + + for (int i = 0; i < quad->vertices(); ++i) + quad->setVertex (i, m_rectverts[i]); + + quad->setColor (maincolor); + obj = quad; } - } - break; + else + { switch (verts.size()) + { case 1: + // 1 vertex - add a vertex object + obj = new LDVertex; + static_cast<LDVertex*> (obj)->pos = verts[0]; + obj->setColor (maincolor); + break; + + case 2: + // 2 verts - make a line + obj = new LDLine (verts[0], verts[1]); + obj->setColor (edgecolor); + break; + + case 3: + case 4: + obj = (verts.size() == 3) ? + static_cast<LDObject*> (new LDTriangle) : + static_cast<LDObject*> (new LDQuad); + + obj->setColor (maincolor); + + for (ushort i = 0; i < obj->vertices(); ++i) + obj->setVertex (i, verts[i]); + + break; + } + } + + break; case CircleMode: { const staticCameraMeta* cam = &g_staticCameras[m_camera]; const double dist = circleDrawDist(); matrix transform = g_circleDrawTransforms[camera() % 3]; + for (int i = 0; i < 9; ++i) { if (transform[i] == 2) transform[i] = dist; + elif (transform[i] == 1 && camera() >= 3) - transform[i] = -1; + transform[i] = -1; } LDSubfile* ref = new LDSubfile; @@ -1341,18 +1369,18 @@ break; case Select: - assert (false); - return; + assert (false); + return; } - if (obj) { - g_win->beginAction (null); + if (obj) + { g_win->beginAction (null); file()->addObject (obj); compileObject (obj); g_win->fullRefresh(); g_win->endAction(); } - + m_drawedVerts.clear(); m_rectdraw = false; } @@ -1367,7 +1395,7 @@ const double dx = m_drawedVerts[0][relX] - v1[relX]; const double dy = m_drawedVerts[0][relY] - v1[relY]; - return sqrt ((dx * dx) + (dy * dy)); + return sqrt ( (dx * dx) + (dy * dy)); } // ============================================================================= @@ -1380,77 +1408,78 @@ // ============================================================================= // ----------------------------------------------------------------------------- -static List<vertex> getVertices (LDObject* obj) { - List<vertex> verts; - - if (obj->vertices() >= 2) { - for (int i = 0; i < obj->vertices(); ++i) +static List<vertex> getVertices (LDObject* obj) +{ List<vertex> verts; + + if (obj->vertices() >= 2) + { for (int i = 0; i < obj->vertices(); ++i) verts << obj->getVertex (i); - } elif (obj->getType() == LDObject::Subfile) { - LDSubfile* ref = static_cast<LDSubfile*> (obj); + } elif (obj->getType() == LDObject::Subfile) + + { LDSubfile* ref = static_cast<LDSubfile*> (obj); List<LDObject*> objs = ref->inlineContents (LDSubfile::DeepCacheInline); - - for(LDObject* obj : objs) { - verts << getVertices (obj); + + for (LDObject * obj : objs) + { verts << getVertices (obj); delete obj; } } - + return verts; } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::compileObject (LDObject* obj) { - deleteLists (obj); - - for (const GL::ListType listType : g_glListTypes) { - if (drawOnly() && listType != GL::NormalList) +void GLRenderer::compileObject (LDObject* obj) +{ deleteLists (obj); + +for (const GL::ListType listType : g_glListTypes) + { if (drawOnly() && listType != GL::NormalList) continue; - + GLuint list = glGenLists (1); glNewList (list, GL_COMPILE); - + obj->glLists[listType] = list; compileList (obj, listType); - + glEndList(); } - + // Mark in known vertices of this object List<vertex> verts = getVertices (obj); m_knownVerts << verts; m_knownVerts.makeUnique(); - + obj->m_glinit = true; } // ============================================================================= // ----------------------------------------------------------------------------- -uchar* GLRenderer::screencap (ushort& w, ushort& h) { - w = m_width; +uchar* GLRenderer::screencap (ushort& w, ushort& h) +{ w = m_width; h = m_height; uchar* cap = new uchar[4 * w * h]; - + m_screencap = true; update(); m_screencap = false; - + // Capture the pixels glReadPixels (0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, cap); - + return cap; } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::slot_toolTipTimer() { - // We come here if the cursor has stayed in one place for longer than a +void GLRenderer::slot_toolTipTimer() +{ // We come here if the cursor has stayed in one place for longer than a // a second. Check if we're holding it over a camera icon - if so, draw // a tooltip. - for (CameraIcon& icon : m_cameraIcons) { - if (icon.destRect.contains (m_pos)) { - m_toolTipCamera = icon.cam; +for (CameraIcon & icon : m_cameraIcons) + { if (icon.destRect.contains (m_pos)) + { m_toolTipCamera = icon.cam; m_drawToolTip = true; update(); break; @@ -1460,119 +1489,120 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::deleteLists (LDObject* obj) { - // Delete the lists but only if they have been initialized +void GLRenderer::deleteLists (LDObject* obj) +{ // Delete the lists but only if they have been initialized if (!obj->m_glinit) return; - - for (const GL::ListType listType : g_glListTypes) + +for (const GL::ListType listType : g_glListTypes) glDeleteLists (obj->glLists[listType], 1); - + obj->m_glinit = false; } // ============================================================================= // ----------------------------------------------------------------------------- -Axis GLRenderer::cameraAxis (bool y, GL::Camera camid) { - if (camid == (GL::Camera) -1) +Axis GLRenderer::cameraAxis (bool y, GL::Camera camid) +{ if (camid == (GL::Camera) - 1) camid = m_camera; - + const staticCameraMeta* cam = &g_staticCameras[camid]; return (y) ? cam->axisY : cam->axisX; } // ============================================================================= // ----------------------------------------------------------------------------- -bool GLRenderer::setupOverlay (GL::Camera cam, str file, int x, int y, int w, int h) { - QImage* img = new QImage (file); +bool GLRenderer::setupOverlay (GL::Camera cam, str file, int x, int y, int w, int h) +{ QImage* img = new QImage (file); overlayMeta& info = getOverlay (cam); - - if (img->isNull()) { - critical (tr ("Failed to load overlay image!")); + + if (img->isNull()) + { critical (tr ("Failed to load overlay image!")); delete img; return false; } - + delete info.img; // delete the old image - + info.fname = file; info.lw = w; info.lh = h; info.ox = x; info.oy = y; info.img = img; - + if (info.lw == 0) info.lw = (info.lh * img->width()) / img->height(); + elif (info.lh == 0) - info.lh = (info.lw * img->height()) / img->width(); - + info.lh = (info.lw * img->height()) / img->width(); + const Axis x2d = cameraAxis (false, cam), - y2d = cameraAxis (true, cam); - + y2d = cameraAxis (true, cam); + double negXFac = g_staticCameras[cam].negX ? -1 : 1, - negYFac = g_staticCameras[cam].negY ? -1 : 1; - + negYFac = g_staticCameras[cam].negY ? -1 : 1; + info.v0 = info.v1 = g_origin; info.v0[x2d] = - (info.ox * info.lw * negXFac) / img->width(); info.v0[y2d] = (info.oy * info.lh * negYFac) / img->height(); info.v1[x2d] = info.v0[x2d] + info.lw; info.v1[y2d] = info.v0[y2d] + info.lh; - + // Set alpha of all pixels to 0.5 for (long i = 0; i < img->width(); ++i) - for (long j = 0; j < img->height(); ++j) { - uint32 pixel = img->pixel (i, j); - img->setPixel (i, j, 0x80000000 | (pixel & 0x00FFFFFF)); - } - + for (long j = 0; j < img->height(); ++j) + { uint32 pixel = img->pixel (i, j); + img->setPixel (i, j, 0x80000000 | (pixel & 0x00FFFFFF)); + } + updateOverlayObjects(); return true; } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::clearOverlay() { - if (camera() == Free) +void GLRenderer::clearOverlay() +{ if (camera() == Free) return; - + overlayMeta& info = m_overlays[camera()]; delete info.img; info.img = null; - + updateOverlayObjects(); } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::setDepthValue (double depth) { - assert (camera() < Free); +void GLRenderer::setDepthValue (double depth) +{ assert (camera() < Free); m_depthValues[camera()] = depth; } // ============================================================================= // ----------------------------------------------------------------------------- -double GLRenderer::depthValue() const { - assert (camera() < Free); +double GLRenderer::depthValue() const +{ assert (camera() < Free); return m_depthValues[camera()]; } // ============================================================================= // ----------------------------------------------------------------------------- -const char* GLRenderer::cameraName() const { - return g_CameraNames[camera()]; +const char* GLRenderer::cameraName() const +{ return g_CameraNames[camera()]; } // ============================================================================= // ----------------------------------------------------------------------------- -overlayMeta& GLRenderer::getOverlay (int newcam) { - return m_overlays[newcam]; +overlayMeta& GLRenderer::getOverlay (int newcam) +{ return m_overlays[newcam]; } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::zoomNotch (bool inward) { - if (zoom() > 15) +void GLRenderer::zoomNotch (bool inward) +{ if (zoom() > 15) setZoom (zoom() * (inward ? 0.833f : 1.2f)); else setZoom (zoom() + (inward ? -1.2f : 1.2f)); @@ -1580,106 +1610,107 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::zoomToFit() { - if (file() == null) { - setZoom (30.0f); +void GLRenderer::zoomToFit() +{ if (file() == null) + { setZoom (30.0f); return; } - + bool lastfilled = false; bool firstrun = true; const uint32 white = 0xFFFFFFFF; bool inward = true; ulong run = 0; const ushort w = m_width, h = m_height; - + glClearColor (1.0, 1.0, 1.0, 1.0); glDisable (GL_DITHER); - + // Use the pick list while drawing the scene, this way we can tell whether borders // are background or not. m_picking = true; - - for (;;) { - if (zoom() > 10000.0f || zoom() < 0.0f) { - // Obviously, there's nothing to draw if we get here. + + for (;;) + { if (zoom() > 10000.0f || zoom() < 0.0f) + { // Obviously, there's nothing to draw if we get here. // Default to 30.0f and break out. setZoom (30.0f); break; } - + zoomNotch (inward); - + uchar* cap = new uchar[4 * w * h]; drawGLScene(); glReadPixels (0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, cap); uint32* imgdata = reinterpret_cast<uint32*> (cap); bool filled = false; - + // Check the top and bottom rows for (ushort i = 0; i < w && !filled; ++i) - if (imgdata[i] != white || imgdata[((h - 1) * w) + i] != white) + if (imgdata[i] != white || imgdata[ ( (h - 1) * w) + i] != white) filled = true; - + // Left and right edges for (ushort i = 0; i < h && !filled; ++i) - if (imgdata[i * w] != white || imgdata[(i * w) + (w - 1)] != white) + if (imgdata[i * w] != white || imgdata[ (i * w) + (w - 1)] != white) filled = true; - - if (firstrun) { - // If this is the first run, we don't know enough to determine + + if (firstrun) + { // If this is the first run, we don't know enough to determine // whether the zoom was to fit, so we mark in our knowledge so // far and start over. inward = !filled; firstrun = false; - } else { - // If this run filled the screen and the last one did not, the + } + else + { // If this run filled the screen and the last one did not, the // last run had ideal zoom - zoom a bit back and we should reach it. - if (filled && !lastfilled) { - zoomNotch (false); + if (filled && !lastfilled) + { zoomNotch (false); break; } - + // If this run did not fill the screen and the last one did, we've // now reached ideal zoom so we're done here. if (!filled && lastfilled) break; - + inward = !filled; } - + delete[] cap; lastfilled = filled; ++run; } - + setBackground(); m_picking = false; } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::updateRectVerts() { - if (!m_rectdraw) +void GLRenderer::updateRectVerts() +{ if (!m_rectdraw) return; - - if (m_drawedVerts.size() == 0) { - for (int i = 0; i < 4; ++i) + + if (m_drawedVerts.size() == 0) + { for (int i = 0; i < 4; ++i) m_rectverts[i] = m_hoverpos; - + return; } - + vertex v0 = m_drawedVerts[0], - v1 = (m_drawedVerts.size() >= 2) ? m_drawedVerts[1] : m_hoverpos; - + v1 = (m_drawedVerts.size() >= 2) ? m_drawedVerts[1] : m_hoverpos; + const Axis ax = cameraAxis (false), - ay = cameraAxis (true), - az = (Axis) (3 - ax - ay); - + ay = cameraAxis (true), + az = (Axis) (3 - ax - ay); + for (int i = 0; i < 4; ++i) m_rectverts[i][az] = depthValue(); - + m_rectverts[0][ax] = v0[ax]; m_rectverts[0][ay] = v0[ay]; m_rectverts[1][ax] = v1[ax]; @@ -1692,17 +1723,17 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::mouseDoubleClickEvent (QMouseEvent* ev) { - if (!(ev->buttons() & Qt::LeftButton) || editMode() != Select) +void GLRenderer::mouseDoubleClickEvent (QMouseEvent* ev) +{ if (! (ev->buttons() & Qt::LeftButton) || editMode() != Select) return; - + pick (ev->x(), ev->y()); - + if (g_win->sel().size() == 0) return; - + g_win->beginAction (null); - LDObject* obj = g_win->sel()[0]; + LDObject* obj = g_win->sel() [0]; AddObjectDialog::staticDialog (obj->getType(), obj); g_win->endAction(); ev->accept(); @@ -1710,16 +1741,16 @@ // ============================================================================= // ----------------------------------------------------------------------------- -LDOverlay* GLRenderer::findOverlayObject (GLRenderer::Camera cam) { - LDOverlay* ovlobj = null; - - for (LDObject * obj : file()->objects()) { - if (obj->getType() == LDObject::Overlay && static_cast<LDOverlay*> (obj)->camera() == cam) { - ovlobj = static_cast<LDOverlay*> (obj); +LDOverlay* GLRenderer::findOverlayObject (GLRenderer::Camera cam) +{ LDOverlay* ovlobj = null; + +for (LDObject * obj : file()->objects()) + { if (obj->getType() == LDObject::Overlay && static_cast<LDOverlay*> (obj)->camera() == cam) + { ovlobj = static_cast<LDOverlay*> (obj); break; } } - + return ovlobj; } @@ -1727,50 +1758,52 @@ // ----------------------------------------------------------------------------- // Read in overlays from the current file and update overlay info accordingly. // ----------------------------------------------------------------------------- -void GLRenderer::overlaysFromObjects() { - for (Camera cam : g_Cameras) { - if (cam == Free) +void GLRenderer::overlaysFromObjects() +{ for (Camera cam : g_Cameras) + { if (cam == Free) continue; - + overlayMeta& meta = m_overlays[cam]; LDOverlay* ovlobj = findOverlayObject (cam); - - if (!ovlobj && meta.img) { - delete meta.img; + + if (!ovlobj && meta.img) + { delete meta.img; meta.img = null; } elif (ovlobj && (!meta.img || meta.fname != ovlobj->filename())) - setupOverlay (cam, ovlobj->filename(), ovlobj->x(), ovlobj->y(), ovlobj->width(), ovlobj->height()); + + setupOverlay (cam, ovlobj->filename(), ovlobj->x(), ovlobj->y(), ovlobj->width(), ovlobj->height()); } } // ============================================================================= // ----------------------------------------------------------------------------- -void GLRenderer::updateOverlayObjects() { - for (Camera cam : g_Cameras) { - if (cam == Free) +void GLRenderer::updateOverlayObjects() +{ for (Camera cam : g_Cameras) + { if (cam == Free) continue; - + overlayMeta& meta = m_overlays[cam]; LDOverlay* ovlobj = findOverlayObject (cam); - - if (!meta.img && ovlobj) { - // If this is the last overlay image, we need to remove the empty space after it as well. + + if (!meta.img && ovlobj) + { // If this is the last overlay image, we need to remove the empty space after it as well. LDObject* nextobj = ovlobj->next(); - - if (nextobj && nextobj->getType() == LDObject::Empty) { - m_file->forgetObject (nextobj); + + if (nextobj && nextobj->getType() == LDObject::Empty) + { m_file->forgetObject (nextobj); delete nextobj; } - + // If the overlay object was there and the overlay itself is // not, remove the object. m_file->forgetObject (ovlobj); delete ovlobj; - } elif (meta.img && !ovlobj) { - // Inverse case: image is there but the overlay object is + } elif (meta.img && !ovlobj) + + { // Inverse case: image is there but the overlay object is // not, thus create the object. ovlobj = new LDOverlay; - + // Find a suitable position to place this object. We want to place // this into the header, which is everything up to the first scemantic // object. If we find another overlay object, place this object after @@ -1779,31 +1812,31 @@ // there was no schemantic elements at all) ulong i, lastOverlay = -1u; bool found = false; - - for (i = 0; i < file()->numObjs(); ++i) { - LDObject* obj = file()->obj (i); - - if (obj->isScemantic()) { - found = true; + + for (i = 0; i < file()->numObjs(); ++i) + { LDObject* obj = file()->obj (i); + + if (obj->isScemantic()) + { found = true; break; } - + if (obj->getType() == LDObject::Overlay) lastOverlay = i; } - + if (lastOverlay != -1u) file()->insertObj (lastOverlay + 1, ovlobj); - else { - file()->insertObj (i, ovlobj); - + else + { file()->insertObj (i, ovlobj); + if (found) file()->insertObj (i + 1, new LDEmpty); } } - - if (meta.img && ovlobj) { - ovlobj->setCamera (cam); + + if (meta.img && ovlobj) + { ovlobj->setCamera (cam); ovlobj->setFilename (meta.fname); ovlobj->setX (meta.ox); ovlobj->setY (meta.oy); @@ -1811,8 +1844,7 @@ ovlobj->setHeight (meta.lh); } } - + if (g_win->R() == this) g_win->refresh(); } -#include "moc_gldraw.cpp"
--- a/src/gldraw.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/gldraw.h Thu Oct 03 20:56:20 2013 +0300 @@ -32,15 +32,15 @@ class LDFile; class QTimer; -enum EditMode { - Select, +enum EditMode +{ Select, Draw, CircleMode, }; // Meta for overlays -struct overlayMeta { - vertex v0, v1; +struct overlayMeta +{ vertex v0, v1; ushort ox, oy; double lw, lh; str fname; @@ -49,127 +49,130 @@ // ============================================================================= // GLRenderer -// +// // The main renderer object, draws the brick on the screen, manages the camera // and selection picking. The instance of GLRenderer is accessible as // g_win->R() // ============================================================================= -class GLRenderer : public QGLWidget { - Q_OBJECT - +class GLRenderer : public QGLWidget +{ Q_OBJECT + PROPERTY (bool, drawOnly, setDrawOnly) PROPERTY (double, zoom, setZoom) PROPERTY (MessageManager*, msglog, setMessageLog) READ_PROPERTY (bool, picking, setPicking) DECLARE_PROPERTY (LDFile*, file, setFile) DECLARE_PROPERTY (EditMode, editMode, setEditMode) - -public: - enum Camera { Top, Front, Left, Bottom, Back, Right, Free }; - enum ListType { NormalList, PickList, BFCFrontList, BFCBackList }; - - GLRenderer (QWidget* parent = null); - ~GLRenderer(); - - Camera camera() const { return m_camera; } - Axis cameraAxis (bool y, Camera camid = (Camera) -1); - const char* cameraName() const; - void clearOverlay(); - void compileObject (LDObject* obj); - void compileAllObjects(); - double depthValue() const; - void drawGLScene(); - void endDraw (bool accept); - QColor getMainColor(); - overlayMeta& getOverlay (int newcam); - void hardRefresh(); - void initGLData(); - void overlaysFromObjects(); - void refresh(); - void resetAngles(); - uchar* screencap (ushort& w, ushort& h); - void setBackground(); - void setCamera (const Camera cam); - void setDepthValue (double depth); - bool setupOverlay (GLRenderer::Camera cam, str file, int x, int y, int w, int h); - void updateOverlayObjects(); - void zoomNotch (bool inward); - void zoomToFit(); - - static void deleteLists (LDObject* obj); + + public: + enum Camera { Top, Front, Left, Bottom, Back, Right, Free }; + enum ListType { NormalList, PickList, BFCFrontList, BFCBackList }; + + GLRenderer (QWidget* parent = null); + ~GLRenderer(); + + inline Camera camera() const + { return m_camera; + } -protected: - void contextMenuEvent (QContextMenuEvent* ev); - void initializeGL(); - void keyPressEvent (QKeyEvent* ev); - void keyReleaseEvent (QKeyEvent* ev); - void leaveEvent (QEvent* ev); - void mouseDoubleClickEvent (QMouseEvent* ev); - void mousePressEvent (QMouseEvent* ev); - void mouseMoveEvent (QMouseEvent* ev); - void mouseReleaseEvent (QMouseEvent* ev); - void paintEvent (QPaintEvent* ev); - void resizeGL (int w, int h); - void wheelEvent (QWheelEvent* ev); + Axis cameraAxis (bool y, Camera camid = (Camera) - 1); + const char* cameraName() const; + void clearOverlay(); + void compileObject (LDObject* obj); + void compileAllObjects(); + double depthValue() const; + void drawGLScene(); + void endDraw (bool accept); + QColor getMainColor(); + overlayMeta& getOverlay (int newcam); + void hardRefresh(); + void initGLData(); + void overlaysFromObjects(); + void refresh(); + void resetAngles(); + uchar* screencap (ushort& w, ushort& h); + void setBackground(); + void setCamera (const Camera cam); + void setDepthValue (double depth); + bool setupOverlay (GLRenderer::Camera cam, str file, int x, int y, int w, int h); + void updateOverlayObjects(); + void zoomNotch (bool inward); + void zoomToFit(); + + static void deleteLists (LDObject* obj); + + protected: + void contextMenuEvent (QContextMenuEvent* ev); + void initializeGL(); + void keyPressEvent (QKeyEvent* ev); + void keyReleaseEvent (QKeyEvent* ev); + void leaveEvent (QEvent* ev); + void mouseDoubleClickEvent (QMouseEvent* ev); + void mousePressEvent (QMouseEvent* ev); + void mouseMoveEvent (QMouseEvent* ev); + void mouseReleaseEvent (QMouseEvent* ev); + void paintEvent (QPaintEvent* ev); + void resizeGL (int w, int h); + void wheelEvent (QWheelEvent* ev); -private: - // CameraIcon::img is a heap-allocated QPixmap because otherwise it gets - // initialized before program gets to main() and constructs a QApplication - // and Qt doesn't like that. - struct CameraIcon { - QPixmap* img; - QRect srcRect, destRect, selRect; - Camera cam; - } m_cameraIcons[7]; - - QTimer* m_toolTipTimer; - Qt::MouseButtons m_lastButtons; - Qt::KeyboardModifiers m_keymods; - ulong m_totalmove; - vertex m_hoverpos; - double m_virtWidth, m_virtHeight, m_rotX, m_rotY, m_rotZ, m_panX, m_panY; - bool m_darkbg, m_rangepick, m_addpick, m_drawToolTip, m_screencap; - QPoint m_pos, m_globalpos, m_rangeStart; - QPen m_thickBorderPen, m_thinBorderPen; - Camera m_camera, m_toolTipCamera; - uint m_axeslist; - ushort m_width, m_height; - List<vertex> m_drawedVerts; - bool m_rectdraw; - vertex m_rectverts[4]; - QColor m_bgcolor; - double m_depthValues[6]; - overlayMeta m_overlays[6]; - List<vertex> m_knownVerts; - bool m_panning; - - void addDrawnVertex (vertex m_hoverpos); - void calcCameraIcons(); // Compute geometry for camera icons - void clampAngle (double& angle) const; // Clamps an angle to [0, 360] - void compileList (LDObject* obj, const ListType list); // Compile one of the lists of an object - void compileSubObject (LDObject* obj, const GLenum gltype); // Sub-routine for object compiling - void compileVertex (const vertex& vrt); // Compile a single vertex to a list - vertex coordconv2_3 (const QPoint& pos2d, bool snap) const; // Convert a 2D point to a 3D point - QPoint coordconv3_2 (const vertex& pos3d) const; // Convert a 3D point to a 2D point - LDOverlay* findOverlayObject (Camera cam); - void updateRectVerts(); - void pick (uint mouseX, uint mouseY); // Perform object selection - void setObjectColor (LDObject* obj, const ListType list); // Set the color to an object list - QColor getTextPen() const; // Determine which color to draw text with - void getRelativeAxes (Axis& relX, Axis& relY) const; + private: + // CameraIcon::img is a heap-allocated QPixmap because otherwise it gets + // initialized before program gets to main() and constructs a QApplication + // and Qt doesn't like that. + struct CameraIcon + { QPixmap* img; + QRect srcRect, destRect, selRect; + Camera cam; + } m_cameraIcons[7]; - void drawBlip (QPainter& paint, QPoint pos) const; - double circleDrawDist() const; + QTimer* m_toolTipTimer; + Qt::MouseButtons m_lastButtons; + Qt::KeyboardModifiers m_keymods; + ulong m_totalmove; + vertex m_hoverpos; + double m_virtWidth, m_virtHeight, m_rotX, m_rotY, m_rotZ, m_panX, m_panY; + bool m_darkbg, m_rangepick, m_addpick, m_drawToolTip, m_screencap; + QPoint m_pos, m_globalpos, m_rangeStart; + QPen m_thickBorderPen, m_thinBorderPen; + Camera m_camera, m_toolTipCamera; + uint m_axeslist; + ushort m_width, m_height; + List<vertex> m_drawedVerts; + bool m_rectdraw; + vertex m_rectverts[4]; + QColor m_bgcolor; + double m_depthValues[6]; + overlayMeta m_overlays[6]; + List<vertex> m_knownVerts; + bool m_panning; -private slots: - void slot_toolTipTimer(); + void addDrawnVertex (vertex m_hoverpos); + void calcCameraIcons(); // Compute geometry for camera icons + void clampAngle (double& angle) const; // Clamps an angle to [0, 360] + void compileList (LDObject* obj, const ListType list); // Compile one of the lists of an object + void compileSubObject (LDObject* obj, const GLenum gltype); // Sub-routine for object compiling + void compileVertex (const vertex& vrt); // Compile a single vertex to a list + vertex coordconv2_3 (const QPoint& pos2d, bool snap) const; // Convert a 2D point to a 3D point + QPoint coordconv3_2 (const vertex& pos3d) const; // Convert a 3D point to a 2D point + LDOverlay* findOverlayObject (Camera cam); + void updateRectVerts(); + void pick (uint mouseX, uint mouseY); // Perform object selection + void setObjectColor (LDObject* obj, const ListType list); // Set the color to an object list + QColor getTextPen() const; // Determine which color to draw text with + void getRelativeAxes (Axis& relX, Axis& relY) const; + + void drawBlip (QPainter& paint, QPoint pos) const; + double circleDrawDist() const; + + private slots: + void slot_toolTipTimer(); }; // Alias for short namespaces typedef GLRenderer GL; -static const GLRenderer::ListType g_glListTypes[] = { - GL::NormalList, +static const GLRenderer::ListType g_glListTypes[] = +{ GL::NormalList, GL::PickList, GL::BFCFrontList, GL::BFCBackList, @@ -178,4 +181,4 @@ extern const GL::Camera g_Cameras[7]; extern const char* g_CameraNames[7]; -#endif // GLDRAW_H \ No newline at end of file +#endif // GLDRAW_H
--- a/src/gui.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/gui.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -48,6 +48,7 @@ #include "messagelog.h" #include "config.h" #include "ui_ldforge.h" +#include "moc_gui.cpp" static bool g_bSelectionLocked = false; @@ -66,21 +67,21 @@ // ============================================================================= // ----------------------------------------------------------------------------- -ForgeWindow::ForgeWindow() { - g_win = this; +ForgeWindow::ForgeWindow() +{ g_win = this; m_renderer = new GLRenderer; - + ui = new Ui_LDForgeUI; ui->setupUi (this); - + // Stuff the renderer into its frame QVBoxLayout* rendererLayout = new QVBoxLayout (ui->rendererFrame); rendererLayout->addWidget (R()); - + connect (ui->objectList, SIGNAL (itemSelectionChanged()), this, SLOT (slot_selectionChanged())); connect (ui->objectList, SIGNAL (itemDoubleClicked (QListWidgetItem*)), this, SLOT (slot_editObject (QListWidgetItem*))); connect (ui->fileList, SIGNAL (currentItemChanged (QListWidgetItem*, QListWidgetItem*)), this, SLOT (changeCurrentFile())); - + // Init message log manager m_msglog = new MessageManager; m_msglog->setRenderer (R()); @@ -88,7 +89,7 @@ m_quickColors = quickColorsFromConfig(); slot_selectionChanged(); setStatusBar (new QStatusBar); - + // Init primitive loader task stuff m_primLoaderBar = new QProgressBar; m_primLoaderWidget = new QWidget; @@ -97,7 +98,7 @@ primLoaderLayout->addWidget (m_primLoaderBar); statusBar()->addPermanentWidget (m_primLoaderWidget); m_primLoaderWidget->hide(); - + // Make certain actions checkable ui->actionAxes->setChecked (gl_axes); ui->actionWireframe->setChecked (gl_wireframe); @@ -107,11 +108,11 @@ updateRecentFilesMenu(); updateToolBars(); updateTitle(); - + setMinimumSize (300, 200); - + connect (qApp, SIGNAL (aboutToQuit()), this, SLOT (slot_lastSecondCleanup())); - + // Connect all actions and set shortcuts #define act(N) \ connect (ui->action##N, SIGNAL (triggered()), this, SLOT (slot_action())); \ @@ -121,41 +122,42 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::slot_action() { - // Find out which action triggered this +void ForgeWindow::slot_action() +{ // Find out which action triggered this #define act(N) if (sender() == ui->action##N) invokeAction (ui->action##N, &actiondef_##N); #include "actions.h" } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::invokeAction (QAction* act, void (*func)()) { - beginAction (act); - (*func)(); +void ForgeWindow::invokeAction (QAction* act, void (*func) ()) +{ beginAction (act); + (*func) (); endAction(); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::slot_lastSecondCleanup() { - delete m_renderer; +void ForgeWindow::slot_lastSecondCleanup() +{ delete m_renderer; delete ui; } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::updateRecentFilesMenu() { - // First, clear any items in the recent files menu - for (QAction* recent : m_recentFiles) +void ForgeWindow::updateRecentFilesMenu() +{ // First, clear any items in the recent files menu +for (QAction * recent : m_recentFiles) delete recent; + m_recentFiles.clear(); - + QAction* first = null; - - for (const QVariant& it : io_recentfiles) { - str file = it.toString(); + +for (const QVariant & it : io_recentfiles) + { str file = it.toString(); QAction* recent = new QAction (getIcon ("open-recent"), file, this); - + connect (recent, SIGNAL (triggered()), this, SLOT (slot_recentFile())); ui->menuOpenRecent->insertAction (first, recent); m_recentFiles << recent; @@ -165,53 +167,53 @@ // ============================================================================= // ----------------------------------------------------------------------------- -List<LDQuickColor> quickColorsFromConfig() { - List<LDQuickColor> colors; - - for (str colorname : gui_colortoolbar.value.split (":")) { - if (colorname == "|") +List<LDQuickColor> quickColorsFromConfig() +{ List<LDQuickColor> colors; + +for (str colorname : gui_colortoolbar.value.split (":")) + { if (colorname == "|") colors << LDQuickColor::getSeparator(); - else { - LDColor* col = getColor (colorname.toLong()); - + else + { LDColor* col = getColor (colorname.toLong()); + if (col != null) colors << LDQuickColor (col, null); } } - + return colors; } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::updateToolBars() { - m_colorButtons.clear(); +void ForgeWindow::updateToolBars() +{ m_colorButtons.clear(); ui->colorToolbar->clear(); - - for (LDQuickColor& entry : m_quickColors) { - if (entry.isSeparator()) + +for (LDQuickColor & entry : m_quickColors) + { if (entry.isSeparator()) ui->colorToolbar->addSeparator(); - else { - QToolButton* colorButton = new QToolButton; + else + { QToolButton* colorButton = new QToolButton; colorButton->setIcon (makeColorIcon (entry.color(), 22)); colorButton->setIconSize (QSize (22, 22)); colorButton->setToolTip (entry.color()->name); - + connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor())); ui->colorToolbar->addWidget (colorButton); m_colorButtons << colorButton; - + entry.setToolButton (colorButton); } } - + updateGridToolBar(); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::updateGridToolBar() { - // Ensure that the current grid - and only the current grid - is selected. +void ForgeWindow::updateGridToolBar() +{ // Ensure that the current grid - and only the current grid - is selected. ui->actionGridCoarse->setChecked (grid == Grid::Coarse); ui->actionGridMedium->setChecked (grid == Grid::Medium); ui->actionGridFine->setChecked (grid == Grid::Fine); @@ -219,159 +221,160 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::updateTitle() { - str title = fmt (APPNAME " %1", fullVersionString()); - +void ForgeWindow::updateTitle() +{ str title = fmt (APPNAME " %1", fullVersionString()); + // Append our current file if we have one - if (LDFile::current()) { - if (LDFile::current()->name().length() > 0) + if (LDFile::current()) + { if (LDFile::current()->name().length() > 0) title += fmt (": %1", basename (LDFile::current()->name())); else title += fmt (": <anonymous>"); - + if (LDFile::current()->numObjs() > 0 && - LDFile::current()->obj (0)->getType() == LDObject::Comment) - { - // Append title + LDFile::current()->obj (0)->getType() == LDObject::Comment) + { // Append title LDComment* comm = static_cast<LDComment*> (LDFile::current()->obj (0)); title += fmt (": %1", comm->text); } - + if (LDFile::current()->history().pos() != LDFile::current()->savePos()) title += '*'; } - + setWindowTitle (title); } // ============================================================================= // ----------------------------------------------------------------------------- -int ForgeWindow::deleteSelection() { - if (m_sel.size() == 0) +int ForgeWindow::deleteSelection() +{ if (m_sel.size() == 0) return 0; - + List<LDObject*> selCopy = m_sel; int num = 0; - + // Delete the objects that were being selected - for (LDObject* obj : selCopy) { - LDFile::current()->forgetObject (obj); +for (LDObject * obj : selCopy) + { LDFile::current()->forgetObject (obj); ++num; delete obj; } - + refresh(); return num; } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::buildObjList() { - if (!LDFile::current()) +void ForgeWindow::buildObjList() +{ if (!LDFile::current()) return; - + // Lock the selection while we do this so that refreshing the object list // doesn't trigger selection updating so that the selection doesn't get lost // while this is done. g_bSelectionLocked = true; - + for (int i = 0; i < ui->objectList->count(); ++i) delete ui->objectList->item (i); - + ui->objectList->clear(); - - for (LDObject* obj : LDFile::current()->objects()) { - str descr; - - switch (obj->getType()) { - case LDObject::Comment: - descr = static_cast<LDComment*> (obj)->text; - - // Remove leading whitespace - while (descr[0] == ' ') - descr.remove (0, 1); - break; - - case LDObject::Empty: - break; // leave it empty - - case LDObject::Line: - case LDObject::Triangle: - case LDObject::Quad: - case LDObject::CndLine: - for (short i = 0; i < obj->vertices(); ++i) { - if (i != 0) - descr += ", "; - - descr += obj->getVertex (i).stringRep (true); - } - break; - - case LDObject::Error: - descr = fmt ("ERROR: %1", obj->raw()); - break; - - case LDObject::Vertex: - descr = static_cast<LDVertex*> (obj)->pos.stringRep (true); - break; - - case LDObject::Subfile: - { - LDSubfile* ref = static_cast<LDSubfile*> (obj); - + +for (LDObject * obj : LDFile::current()->objects()) + { str descr; + + switch (obj->getType()) + { case LDObject::Comment: + descr = static_cast<LDComment*> (obj)->text; + + // Remove leading whitespace + while (descr[0] == ' ') + descr.remove (0, 1); + + break; + + case LDObject::Empty: + break; // leave it empty + + case LDObject::Line: + case LDObject::Triangle: + case LDObject::Quad: + case LDObject::CndLine: + + for (short i = 0; i < obj->vertices(); ++i) + { if (i != 0) + descr += ", "; + + descr += obj->getVertex (i).stringRep (true); + } + + break; + + case LDObject::Error: + descr = fmt ("ERROR: %1", obj->raw()); + break; + + case LDObject::Vertex: + descr = static_cast<LDVertex*> (obj)->pos.stringRep (true); + break; + + case LDObject::Subfile: + { LDSubfile* ref = static_cast<LDSubfile*> (obj); + descr = fmt ("%1 %2, (", ref->fileInfo()->name(), - ref->position().stringRep (true)); - + ref->position().stringRep (true)); + for (short i = 0; i < 9; ++i) - descr += fmt ("%1%2", ftoa (ref->transform()[i]), - (i != 8) ? " " : ""); - + descr += fmt ("%1%2", ftoa (ref->transform() [i]), + (i != 8) ? " " : ""); + descr += ')'; } break; - - case LDObject::BFC: - descr = LDBFC::statements[static_cast<LDBFC*> (obj)->type]; - break; - - case LDObject::Overlay: - { - LDOverlay* ovl = static_cast<LDOverlay*> (obj); + + case LDObject::BFC: + descr = LDBFC::statements[static_cast<LDBFC*> (obj)->type]; + break; + + case LDObject::Overlay: + { LDOverlay* ovl = static_cast<LDOverlay*> (obj); descr = fmt ("[%1] %2 (%3, %4), %5 x %6", g_CameraNames[ovl->camera()], - basename (ovl->filename()), ovl->x(), ovl->y(), ovl->width(), ovl->height()); + basename (ovl->filename()), ovl->x(), ovl->y(), ovl->width(), ovl->height()); } break; - - default: - descr = obj->typeName(); - break; + + default: + descr = obj->typeName(); + break; } - + // Put it into brackets if it's hidden if (obj->hidden()) descr = fmt ("[[ %1 ]]", descr); - + QListWidgetItem* item = new QListWidgetItem (descr); item->setIcon (getIcon (obj->typeName())); - + // Color gibberish orange on red so it stands out. - if (obj->getType() == LDObject::Error) { - item->setBackground (QColor ("#AA0000")); + if (obj->getType() == LDObject::Error) + { item->setBackground (QColor ("#AA0000")); item->setForeground (QColor ("#FFAA00")); } elif (lv_colorize && obj->isColored() && - obj->color() != maincolor && obj->color() != edgecolor) - { - // If the object isn't in the main or edge color, draw this + + obj->color() != maincolor && obj->color() != edgecolor) + { // If the object isn't in the main or edge color, draw this // list entry in said color. LDColor* col = getColor (obj->color()); + if (col) item->setForeground (col->faceColor); } - + obj->qObjListEntry = item; ui->objectList->insertItem (ui->objectList->count(), item); } - + g_bSelectionLocked = false; updateSelection(); scrollToSelection(); @@ -379,265 +382,267 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::scrollToSelection() { - if (m_sel.size() == 0) +void ForgeWindow::scrollToSelection() +{ if (m_sel.size() == 0) return; - + LDObject* obj = m_sel[m_sel.size() - 1]; ui->objectList->scrollToItem (obj->qObjListEntry); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::slot_selectionChanged() { - if (g_bSelectionLocked == true || LDFile::current() == null) +void ForgeWindow::slot_selectionChanged() +{ if (g_bSelectionLocked == true || LDFile::current() == null) return; - + // Update the shared selection array, though don't do this if this was // called during GL picking, in which case the GL renderer takes care // of the selection. if (m_renderer->picking()) return; - + List<LDObject*> priorSelection = m_sel; - + // Get the objects from the object list selection m_sel.clear(); const QList<QListWidgetItem*> items = ui->objectList->selectedItems(); - - for (LDObject* obj : LDFile::current()->objects()) - for (QListWidgetItem* item : items) { - if (item == obj->qObjListEntry) { - m_sel << obj; - break; + +for (LDObject * obj : LDFile::current()->objects()) + for (QListWidgetItem * item : items) + { if (item == obj->qObjListEntry) + { m_sel << obj; + break; + } } - } - + // Update the GL renderer - for (LDObject* obj : priorSelection) { - obj->setSelected (false); +for (LDObject * obj : priorSelection) + { obj->setSelected (false); m_renderer->compileObject (obj); } - - for (LDObject* obj : m_sel) { - obj->setSelected (true); + +for (LDObject * obj : m_sel) + { obj->setSelected (true); m_renderer->compileObject (obj); } - + m_renderer->update(); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::slot_recentFile() { - QAction* qAct = static_cast<QAction*> (sender()); +void ForgeWindow::slot_recentFile() +{ QAction* qAct = static_cast<QAction*> (sender()); openMainFile (qAct->text()); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::slot_quickColor() { - beginAction (null); +void ForgeWindow::slot_quickColor() +{ beginAction (null); QToolButton* button = static_cast<QToolButton*> (sender()); LDColor* col = null; - - for (const LDQuickColor& entry : m_quickColors) { - if (entry.toolButton() == button) { - col = entry.color(); + +for (const LDQuickColor & entry : m_quickColors) + { if (entry.toolButton() == button) + { col = entry.color(); break; } } - + if (col == null) return; - + short newColor = col->index; - - for (LDObject* obj : m_sel) { - if (obj->isColored() == false) + +for (LDObject * obj : m_sel) + { if (obj->isColored() == false) continue; // uncolored object - + obj->setColor (newColor); R()->compileObject (obj); } - + refresh(); endAction(); } // ============================================================================= // ----------------------------------------------------------------------------- -ulong ForgeWindow::getInsertionPoint() { - if (m_sel.size() > 0) { - // If we have a selection, put the item after it. +ulong ForgeWindow::getInsertionPoint() +{ if (m_sel.size() > 0) + { // If we have a selection, put the item after it. return (m_sel[m_sel.size() - 1]->getIndex()) + 1; } - + // Otherwise place the object at the end. return LDFile::current()->numObjs(); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::fullRefresh() { - buildObjList(); +void ForgeWindow::fullRefresh() +{ buildObjList(); m_renderer->hardRefresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::refresh() { - buildObjList(); +void ForgeWindow::refresh() +{ buildObjList(); m_renderer->update(); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::updateSelection() { - g_bSelectionLocked = true; - - for (LDObject* obj : LDFile::current()->objects()) +void ForgeWindow::updateSelection() +{ g_bSelectionLocked = true; + +for (LDObject * obj : LDFile::current()->objects()) obj->setSelected (false); - + ui->objectList->clearSelection(); - for (LDObject* obj : m_sel) { - if (obj->qObjListEntry == null) + +for (LDObject * obj : m_sel) + { if (obj->qObjListEntry == null) continue; - + obj->qObjListEntry->setSelected (true); obj->setSelected (true); } - + g_bSelectionLocked = false; slot_selectionChanged(); } // ============================================================================= // ----------------------------------------------------------------------------- -bool ForgeWindow::isSelected (LDObject* obj) { - LDObject* needle = obj->topLevelParent(); - - for (LDObject* hay : m_sel) +bool ForgeWindow::isSelected (LDObject* obj) +{ LDObject* needle = obj->topLevelParent(); + +for (LDObject * hay : m_sel) if (hay == needle) return true; - + return false; } -short ForgeWindow::getSelectedColor() { - short result = -1; - - for (LDObject* obj : m_sel) { - if (obj->isColored() == false) +short ForgeWindow::getSelectedColor() +{ short result = -1; + +for (LDObject * obj : m_sel) + { if (obj->isColored() == false) continue; // doesn't use color - + if (result != -1 && obj->color() != result) return -1; // No consensus in object color - + if (result == -1) result = obj->color(); } - + return result; } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject::Type ForgeWindow::uniformSelectedType() { - LDObject::Type result = LDObject::Unidentified; - - for (LDObject* obj : m_sel) { - if (result != LDObject::Unidentified && obj->color() != result) +LDObject::Type ForgeWindow::uniformSelectedType() +{ LDObject::Type result = LDObject::Unidentified; + +for (LDObject * obj : m_sel) + { if (result != LDObject::Unidentified && obj->color() != result) return LDObject::Unidentified; - + if (result == LDObject::Unidentified) result = obj->getType(); } - + return result; } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::closeEvent (QCloseEvent* ev) { - // Check whether it's safe to close all files. - if (!safeToCloseAll()) { - ev->ignore(); +void ForgeWindow::closeEvent (QCloseEvent* ev) +{ // Check whether it's safe to close all files. + if (!safeToCloseAll()) + { ev->ignore(); return; } - + // Save the configuration before leaving so that, for instance, grid choice // is preserved across instances. Config::save(); - + ev->accept(); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::spawnContextMenu (const QPoint pos) { - const bool single = (g_win->sel().size() == 1); - LDObject* singleObj = (single) ? g_win->sel()[0] : null; - +void ForgeWindow::spawnContextMenu (const QPoint pos) +{ const bool single = (g_win->sel().size() == 1); + LDObject* singleObj = (single) ? g_win->sel() [0] : null; + QMenu* contextMenu = new QMenu; - - if (single && singleObj->getType() != LDObject::Empty) { - contextMenu->addAction (ACTION (Edit)); + + if (single && singleObj->getType() != LDObject::Empty) + { contextMenu->addAction (ACTION (Edit)); contextMenu->addSeparator(); } - + contextMenu->addAction (ACTION (Cut)); contextMenu->addAction (ACTION (Copy)); contextMenu->addAction (ACTION (Paste)); contextMenu->addAction (ACTION (Delete)); contextMenu->addSeparator(); contextMenu->addAction (ACTION (SetColor)); - + if (single) contextMenu->addAction (ACTION (EditRaw)); - + contextMenu->addAction (ACTION (Borders)); contextMenu->addAction (ACTION (SetOverlay)); contextMenu->addAction (ACTION (ClearOverlay)); contextMenu->addAction (ACTION (ModeSelect)); contextMenu->addAction (ACTION (ModeDraw)); contextMenu->addAction (ACTION (ModeCircle)); - - if (R()->camera() != GL::Free) { - contextMenu->addSeparator(); + + if (R()->camera() != GL::Free) + { contextMenu->addSeparator(); contextMenu->addAction (ACTION (SetDrawDepth)); } - + contextMenu->exec (pos); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::deleteObjVector (List<LDObject*> objs) { - for (LDObject* obj : objs) { - LDFile::current()->forgetObject (obj); +void ForgeWindow::deleteObjVector (List<LDObject*> objs) +{ for (LDObject * obj : objs) + { LDFile::current()->forgetObject (obj); delete obj; } } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::deleteByColor (const short colnum) { - List<LDObject*> objs; - for (LDObject* obj : LDFile::current()->objects()) { - if (!obj->isColored() || obj->color() != colnum) +void ForgeWindow::deleteByColor (const short colnum) +{ List<LDObject*> objs; + +for (LDObject * obj : LDFile::current()->objects()) + { if (!obj->isColored() || obj->color() != colnum) continue; - + objs << obj; } - + deleteObjVector (objs); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::updateEditModeActions() { - const EditMode mode = R()->editMode(); +void ForgeWindow::updateEditModeActions() +{ const EditMode mode = R()->editMode(); ACTION (ModeSelect)->setChecked (mode == Select); ACTION (ModeDraw)->setChecked (mode == Draw); ACTION (ModeCircle)->setChecked (mode == CircleMode); @@ -645,22 +650,23 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::slot_editObject (QListWidgetItem* listitem) { - LDObject* obj = null; - for (LDObject* it : LDFile::current()->objects()) { - if (it->qObjListEntry == listitem) { - obj = it; +void ForgeWindow::slot_editObject (QListWidgetItem* listitem) +{ LDObject* obj = null; + +for (LDObject * it : LDFile::current()->objects()) + { if (it->qObjListEntry == listitem) + { obj = it; break; } } - + AddObjectDialog::staticDialog (obj->getType(), obj); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::primitiveLoaderStart (ulong max) { - m_primLoaderWidget->show(); +void ForgeWindow::primitiveLoaderStart (ulong max) +{ m_primLoaderWidget->show(); m_primLoaderBar->setRange (0, max); m_primLoaderBar->setValue (0); m_primLoaderBar->setFormat ("%p%"); @@ -668,14 +674,14 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::primitiveLoaderUpdate (ulong prog) { - m_primLoaderBar->setValue (prog); +void ForgeWindow::primitiveLoaderUpdate (ulong prog) +{ m_primLoaderBar->setValue (prog); } // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::primitiveLoaderEnd() { - QTimer* hidetimer = new QTimer; +void ForgeWindow::primitiveLoaderEnd() +{ QTimer* hidetimer = new QTimer; connect (hidetimer, SIGNAL (timeout()), m_primLoaderWidget, SLOT (hide())); hidetimer->setSingleShot (true); hidetimer->start (1500); @@ -685,92 +691,94 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void ForgeWindow::save (LDFile* f, bool saveAs) { - str path = f->name(); - - if (path.length() == 0 || saveAs) { - path = QFileDialog::getSaveFileName (g_win, tr ("Save As"), - LDFile::current()->name(), tr ("LDraw files (*.dat *.ldr)")); - - if (path.length() == 0) { - // User didn't give a file name. This happens if the user cancelled +void ForgeWindow::save (LDFile* f, bool saveAs) +{ str path = f->name(); + + if (path.length() == 0 || saveAs) + { path = QFileDialog::getSaveFileName (g_win, tr ("Save As"), + LDFile::current()->name(), tr ("LDraw files (*.dat *.ldr)")); + + if (path.length() == 0) + { // User didn't give a file name. This happens if the user cancelled // saving in the save file dialog. Abort. return; } } - - if (f->save (path)) { - f->setName (path); - + + if (f->save (path)) + { f->setName (path); + if (f == LDFile::current()) g_win->updateTitle(); - + log ("Saved to %1.", path); - + // Add it to recent files addRecentFile (path); - } else { - str message = fmt (tr ("Failed to save to %1: %2"), path, strerror (errno)); - + } + else + { str message = fmt (tr ("Failed to save to %1: %2"), path, strerror (errno)); + // Tell the user the save failed, and give the option for saving as with it. QMessageBox dlg (QMessageBox::Critical, tr ("Save Failure"), message, QMessageBox::Close, g_win); - + // Add a save-as button QPushButton* saveAsBtn = new QPushButton (tr ("Save As")); saveAsBtn->setIcon (getIcon ("file-save-as")); dlg.addButton (saveAsBtn, QMessageBox::ActionRole); dlg.setDefaultButton (QMessageBox::Close); dlg.exec(); - + if (dlg.clickedButton() == saveAsBtn) save (f, true); // yay recursion! } } -void ForgeWindow::addMessage (str msg) { - m_msglog->addLine (msg); +void ForgeWindow::addMessage (str msg) +{ m_msglog->addLine (msg); } // ============================================================================ -void ObjectList::contextMenuEvent (QContextMenuEvent* ev) { - g_win->spawnContextMenu (ev->globalPos()); +void ObjectList::contextMenuEvent (QContextMenuEvent* ev) +{ g_win->spawnContextMenu (ev->globalPos()); } // ============================================================================= // ----------------------------------------------------------------------------- -QPixmap getIcon (str iconName) { - return (QPixmap (fmt (":/icons/%1.png", iconName))); +QPixmap getIcon (str iconName) +{ return (QPixmap (fmt (":/icons/%1.png", iconName))); } // ============================================================================= -bool confirm (str msg) { - return confirm (ForgeWindow::tr ("Confirm"), msg); +bool confirm (str msg) +{ return confirm (ForgeWindow::tr ("Confirm"), msg); } -bool confirm (str title, str msg) { - return QMessageBox::question (g_win, title, msg, - (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes; +bool confirm (str title, str msg) +{ return QMessageBox::question (g_win, title, msg, + (QMessageBox::Yes | QMessageBox::No), QMessageBox::No) == QMessageBox::Yes; } // ============================================================================= -void critical (str msg) { - QMessageBox::critical (g_win, ForgeWindow::tr("Error"), msg, - (QMessageBox::Close), QMessageBox::Close); +void critical (str msg) +{ QMessageBox::critical (g_win, ForgeWindow::tr ("Error"), msg, + (QMessageBox::Close), QMessageBox::Close); } // ============================================================================= -QIcon makeColorIcon (LDColor* colinfo, const ushort size) { - // Create an image object and link a painter to it. +QIcon makeColorIcon (LDColor* colinfo, const ushort size) +{ // Create an image object and link a painter to it. QImage img (size, size, QImage::Format_ARGB32); QPainter paint (&img); - + QColor col = colinfo->faceColor; - if (colinfo->index == maincolor) { - // Use the user preferences for main color here + + if (colinfo->index == maincolor) + { // Use the user preferences for main color here col = gl_maincolor.value; col.setAlphaF (gl_maincolor_alpha); } - + // Paint the icon paint.fillRect (QRect (0, 0, size, size), colinfo->edgeColor); paint.drawPixmap (QRect (1, 1, size - 2, size - 2), getIcon ("checkerboard"), QRect (0, 0, 8, 8)); @@ -779,101 +787,102 @@ } // ============================================================================= -void makeColorSelector (QComboBox* box) { - std::map<short, ulong> counts; - - for (LDObject* obj : LDFile::current()->objects()) { - if (!obj->isColored()) +void makeColorSelector (QComboBox* box) +{ std::map<short, ulong> counts; + +for (LDObject * obj : LDFile::current()->objects()) + { if (!obj->isColored()) continue; - + if (counts.find (obj->color()) == counts.end()) counts[obj->color()] = 1; else counts[obj->color()]++; } - + box->clear(); ulong row = 0; - for (const auto& pair : counts) { - LDColor* col = getColor (pair.first); + +for (const auto & pair : counts) + { LDColor* col = getColor (pair.first); assert (col != null); - + QIcon ico = makeColorIcon (col, 16); box->addItem (ico, fmt ("[%1] %2 (%3 object%4)", - pair.first, col->name, pair.second, plural (pair.second))); + pair.first, col->name, pair.second, plural (pair.second))); box->setItemData (row, pair.first); - + ++row; } } -void ForgeWindow::setStatusBarText (str text) { - statusBar()->showMessage (text); +void ForgeWindow::setStatusBarText (str text) +{ statusBar()->showMessage (text); } -void ForgeWindow::clearSelection() { - m_sel.clear(); +void ForgeWindow::clearSelection() +{ m_sel.clear(); } -Ui_LDForgeUI* ForgeWindow::interface() const { - return ui; +Ui_LDForgeUI* ForgeWindow::interface() const +{ return ui; } #define act(N) QAction* ForgeWindow::action##N() { return ui->action##N; } #include "actions.h" -void ForgeWindow::updateFileList() { - ui->fileList->clear(); - - for (LDFile* f : g_loadedFiles) { - // Don't list implicit files unless explicitly desired. +void ForgeWindow::updateFileList() +{ ui->fileList->clear(); + +for (LDFile * f : g_loadedFiles) + { // Don't list implicit files unless explicitly desired. if (f->implicit() && !gui_implicitfiles) continue; - + // Add an item to the list for this file and store a pointer to it in // the file, so we can find files by the list item. ui->fileList->addItem (""); QListWidgetItem* item = ui->fileList->item (ui->fileList->count() - 1); f->setListItem (item); - + updateFileListItem (f); } } -void ForgeWindow::updateFileListItem (LDFile* f) { - if (f->listItem() == null) { - // We don't have a list item for this file, so the list either doesn't +void ForgeWindow::updateFileListItem (LDFile* f) +{ if (f->listItem() == null) + { // We don't have a list item for this file, so the list either doesn't // exist yet or is out of date. Build the list now. updateFileList(); return; } - + // If this is the current file, it also needs to be the selected item on // the list. if (f == LDFile::current()) ui->fileList->setCurrentItem (f->listItem()); - + // If we list implicit files, draw them with a shade of gray to make them // distinct. if (f->implicit()) f->listItem()->setForeground (QColor (96, 96, 96)); - + f->listItem()->setText (f->getShortName()); - + // If the file has unsaved changes, draw a little icon next to it to mark that. f->listItem()->setIcon (f->hasUnsavedChanges() ? getIcon ("file-save") : QIcon()); } -void ForgeWindow::beginAction (QAction* act) { - // Open the history so we can record the edits done during this action. +void ForgeWindow::beginAction (QAction* act) +{ // Open the history so we can record the edits done during this action. if (act != ACTION (Undo) && act != ACTION (Redo) && act != ACTION (Open)) LDFile::current()->openHistory(); } -void ForgeWindow::endAction() { - // Close the history now. +void ForgeWindow::endAction() +{ // Close the history now. LDFile::current()->closeHistory(); - + // Update the list item of the current file - we may need to draw an icon // now that marks it as having unsaved changes. updateFileListItem (LDFile::current()); @@ -882,40 +891,42 @@ // ============================================================================= // A file is selected from the list of files on the left of the screen. Find out // which file was picked and change to it. -void ForgeWindow::changeCurrentFile() { - LDFile* f = null; +void ForgeWindow::changeCurrentFile() +{ LDFile* f = null; QListWidgetItem* item = ui->fileList->currentItem(); - + // Find the file pointer of the item that was selected. - for (LDFile* it : g_loadedFiles) { - if (it->listItem() == item) { - f = it; +for (LDFile * it : g_loadedFiles) + { if (it->listItem() == item) + { f = it; break; } } - + // If we picked the same file we're currently on, we don't need to do // anything. if (!f || f == LDFile::current()) return; - + LDFile::setCurrent (f); } -void ForgeWindow::refreshObjectList() { +void ForgeWindow::refreshObjectList() +{ #if 0 ui->objectList->clear(); LDFile* f = LDFile::current(); - - for (LDObject* obj : *f) + +for (LDObject * obj : *f) ui->objectList->addItem (obj->qObjListEntry); + #endif - + buildObjList(); } -QImage imageFromScreencap (uchar* data, ushort w, ushort h) { - // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well. +QImage imageFromScreencap (uchar* data, ushort w, ushort h) +{ // GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well. return QImage (data, w, h, QImage::Format_ARGB32).rgbSwapped().mirrored(); } @@ -925,11 +936,10 @@ m_color (color), m_toolButton (toolButton) {} -LDQuickColor LDQuickColor::getSeparator() { - return LDQuickColor (null, null); +LDQuickColor LDQuickColor::getSeparator() +{ return LDQuickColor (null, null); } -bool LDQuickColor::isSeparator() const { - return color() == null; +bool LDQuickColor::isSeparator() const +{ return color() == null; } -#include "moc_gui.cpp"
--- a/src/gui.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/gui.h Thu Oct 03 20:56:20 2013 +0300 @@ -41,7 +41,7 @@ bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); \ connect (bbx_buttons, SIGNAL (accepted()), this, SLOT (accept())); \ connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject())); \ - + // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= @@ -58,106 +58,116 @@ #define CTRL_SHIFT(N) (Qt::CTRL | Qt::SHIFT | Qt::Key_##N) // ============================================================================= -class LDQuickColor { - PROPERTY (LDColor*, color, setColor) +class LDQuickColor +{ PROPERTY (LDColor*, color, setColor) PROPERTY (QToolButton*, toolButton, setToolButton) - -public: - LDQuickColor (LDColor* color, QToolButton* toolButton); - bool isSeparator() const; - - static LDQuickColor getSeparator(); + + public: + LDQuickColor (LDColor* color, QToolButton* toolButton); + bool isSeparator() const; + + static LDQuickColor getSeparator(); }; // ============================================================================= // ObjectList -// +// // Object list class for ForgeWindow // ============================================================================= -class ObjectList : public QListWidget { - Q_OBJECT - -protected: - void contextMenuEvent (QContextMenuEvent* ev); +class ObjectList : public QListWidget +{ Q_OBJECT + + protected: + void contextMenuEvent (QContextMenuEvent* ev); }; // ============================================================================= // ForgeWindow -// +// // The one main GUI class. Hosts the renderer, object list, message log. Contains // slot_action, which is what all actions connect to. Manages menus and toolbars. // Large and in charge. // ============================================================================= -class ForgeWindow : public QMainWindow { - Q_OBJECT - -public: - ForgeWindow(); - void buildObjList(); - void updateTitle(); - void fullRefresh(); - void refresh(); - ulong getInsertionPoint(); - void updateToolBars(); - void updateRecentFilesMenu(); - void updateSelection(); - void updateGridToolBar(); - void updateEditModeActions(); - void updateFileList(); - void updateFileListItem (LDFile* f); - bool isSelected (LDObject* obj); - short getSelectedColor(); - LDObject::Type uniformSelectedType(); - void scrollToSelection(); - void spawnContextMenu (const QPoint pos); - void deleteObjVector (List< LDObject* > objs); - int deleteSelection(); - void deleteByColor (const short int colnum); - void save (LDFile* f, bool saveAs); - GLRenderer* R() { return m_renderer; } - List<LDObject*>& sel() { return m_sel; } - void setQuickColors (List<LDQuickColor>& colors) { m_quickColors = colors; } - void setStatusBarText (str text); - void addMessage (str msg); - Ui_LDForgeUI* interface() const; - void refreshObjectList(); - void beginAction(QAction* act); - void endAction(); - +class ForgeWindow : public QMainWindow +{ Q_OBJECT + + public: + ForgeWindow(); + void buildObjList(); + void updateTitle(); + void fullRefresh(); + void refresh(); + ulong getInsertionPoint(); + void updateToolBars(); + void updateRecentFilesMenu(); + void updateSelection(); + void updateGridToolBar(); + void updateEditModeActions(); + void updateFileList(); + void updateFileListItem (LDFile* f); + bool isSelected (LDObject* obj); + short getSelectedColor(); + LDObject::Type uniformSelectedType(); + void scrollToSelection(); + void spawnContextMenu (const QPoint pos); + void deleteObjVector (List< LDObject* > objs); + int deleteSelection(); + void deleteByColor (const short int colnum); + void save (LDFile* f, bool saveAs); + + inline GLRenderer* R() + { return m_renderer; + } + + inline List<LDObject*>& sel() + { return m_sel; + } + + inline void setQuickColors (List<LDQuickColor>& colors) + { m_quickColors = colors; + } + + void setStatusBarText (str text); + void addMessage (str msg); + Ui_LDForgeUI* interface() const; + void refreshObjectList(); + void beginAction (QAction* act); + void endAction(); + #define act(N) QAction* action##N(); #include "actions.h" - -public slots: - void primitiveLoaderStart (ulong max); - void primitiveLoaderUpdate (ulong prog); - void primitiveLoaderEnd(); - void clearSelection(); - void slot_action(); - void changeCurrentFile(); - -protected: - void closeEvent (QCloseEvent* ev); - -private: - GLRenderer* m_renderer; - QProgressBar* m_primLoaderBar; - QWidget* m_primLoaderWidget; - List<LDObject*> m_sel; - List<LDQuickColor> m_quickColors; - List<QToolButton*> m_colorButtons; - List<QAction*> m_recentFiles; - MessageManager* m_msglog; - Ui_LDForgeUI* ui; - - void invokeAction (QAction* act, void (*func)()); - + + public slots: + void primitiveLoaderStart (ulong max); + void primitiveLoaderUpdate (ulong prog); + void primitiveLoaderEnd(); + void clearSelection(); + void slot_action(); + void changeCurrentFile(); + + protected: + void closeEvent (QCloseEvent* ev); -private slots: - void slot_selectionChanged(); - void slot_recentFile(); - void slot_quickColor(); - void slot_lastSecondCleanup(); - void slot_editObject (QListWidgetItem* listitem); + private: + GLRenderer* m_renderer; + QProgressBar* m_primLoaderBar; + QWidget* m_primLoaderWidget; + List<LDObject*> m_sel; + List<LDQuickColor> m_quickColors; + List<QToolButton*> m_colorButtons; + List<QAction*> m_recentFiles; + MessageManager* m_msglog; + Ui_LDForgeUI* ui; + + void invokeAction (QAction* act, void (*func) ()); + + + private slots: + void slot_selectionChanged(); + void slot_recentFile(); + void slot_quickColor(); + void slot_lastSecondCleanup(); + void slot_editObject (QListWidgetItem* listitem); }; #define INVOKE_ACTION(N) actiondef_##N(); @@ -184,11 +194,11 @@ // Takes in pairs of radio buttons and respective values and returns the value of // the first found radio button that was checked. // ============================================================================= -template<class T> T radioSwitch (const T& defval, List<pair<QRadioButton*, T>> haystack) { - for (pair<QRadioButton*, const T&> i : haystack) +template<class T> T radioSwitch (const T& defval, List<pair<QRadioButton*, T>> haystack) +{ for (pair<QRadioButton*, const T&> i : haystack) if (i.first->isChecked()) return i.second; - + return defval; } @@ -197,13 +207,13 @@ // Takes in pairs of radio buttons and respective values and checks the first // found radio button to have the given value. // ============================================================================= -template<class T> void radioDefault (const T& expr, List<pair<QRadioButton*, T>> haystack) { - for (pair<QRadioButton*, const T&> i : haystack) { - if (i.second == expr) { - i.first->setChecked (true); +template<class T> void radioDefault (const T& expr, List<pair<QRadioButton*, T>> haystack) +{ for (pair<QRadioButton*, const T&> i : haystack) + { if (i.second == expr) + { i.first->setChecked (true); return; } } } -#endif // GUI_H \ No newline at end of file +#endif // GUI_H
--- a/src/gui_actions.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/gui_actions.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -44,361 +44,367 @@ // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (New, CTRL_SHIFT (N)) { - QDialog* dlg = new QDialog (g_win); +DEFINE_ACTION (New, CTRL_SHIFT (N)) +{ QDialog* dlg = new QDialog (g_win); Ui::NewPartUI ui; ui.setupUi (dlg); - + str authortext = ld_defaultname; - + if (!ld_defaultuser.value.isEmpty()) authortext.append (fmt (" [%1]", ld_defaultuser)); - + ui.le_author->setText (authortext); - - switch (ld_defaultlicense) { - case 0: - ui.rb_license_ca->setChecked (true); - break; - - case 1: - ui.rb_license_nonca->setChecked (true); - break; - - case 2: - ui.rb_license_none->setChecked (true); - break; - - default: - QMessageBox::warning (null, "Warning", - fmt ("Unknown ld_defaultlicense value %1!", ld_defaultlicense)); - break; + + switch (ld_defaultlicense) + { case 0: + ui.rb_license_ca->setChecked (true); + break; + + case 1: + ui.rb_license_nonca->setChecked (true); + break; + + case 2: + ui.rb_license_none->setChecked (true); + break; + + default: + QMessageBox::warning (null, "Warning", + fmt ("Unknown ld_defaultlicense value %1!", ld_defaultlicense)); + break; } - + if (dlg->exec() == false) return; - + newFile(); - + const LDBFC::Type BFCType = ui.rb_bfc_ccw->isChecked() ? LDBFC::CertifyCCW : ui.rb_bfc_cw->isChecked() ? LDBFC::CertifyCW : LDBFC::NoCertify; - + const str license = ui.rb_license_ca->isChecked() ? CALicense : ui.rb_license_nonca->isChecked() ? NonCALicense : ""; - - LDFile::current()->addObjects ({ - new LDComment (ui.le_title->text()), - new LDComment ("Name: <untitled>.dat" ), + + LDFile::current()->addObjects ( + { new LDComment (ui.le_title->text()), + new LDComment ("Name: <untitled>.dat"), new LDComment (fmt ("Author: %1", ui.le_author->text())), new LDComment (fmt ("!LDRAW_ORG Unofficial_Part")), (license != "" ? - new LDComment (license) : - null), + new LDComment (license) : + null), new LDEmpty, new LDBFC (BFCType), new LDEmpty, }); - + g_win->fullRefresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (NewFile, CTRL (N)) { - newFile(); +DEFINE_ACTION (NewFile, CTRL (N)) +{ newFile(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Open, CTRL (O)) { - str name = QFileDialog::getOpenFileName (g_win, "Open File", "", "LDraw files (*.dat *.ldr)"); - +DEFINE_ACTION (Open, CTRL (O)) +{ str name = QFileDialog::getOpenFileName (g_win, "Open File", "", "LDraw files (*.dat *.ldr)"); + if (name.length() == 0) return; - + openMainFile (name); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Save, CTRL (S)) { - g_win->save (LDFile::current(), false); +DEFINE_ACTION (Save, CTRL (S)) +{ g_win->save (LDFile::current(), false); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (SaveAs, CTRL_SHIFT (S)) { - g_win->save (LDFile::current(), true); +DEFINE_ACTION (SaveAs, CTRL_SHIFT (S)) +{ g_win->save (LDFile::current(), true); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (SaveAll, CTRL (L)) { - for (LDFile* file : g_loadedFiles) { - if (file->implicit()) +DEFINE_ACTION (SaveAll, CTRL (L)) +{ for (LDFile* file : g_loadedFiles) + { if (file->implicit()) continue; - + g_win->save (file, false); } } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Close, CTRL (W)) { - if (!LDFile::current()->safeToClose()) +DEFINE_ACTION (Close, CTRL (W)) +{ if (!LDFile::current()->safeToClose()) return; - + delete LDFile::current(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (CloseAll, 0) { - if (!safeToCloseAll()) +DEFINE_ACTION (CloseAll, 0) +{ if (!safeToCloseAll()) return; - + closeAll(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Settings, 0) { - (new ConfigDialog)->exec(); +DEFINE_ACTION (Settings, 0) +{ (new ConfigDialog)->exec(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (SetLDrawPath, 0) { - (new LDrawPathDialog (true))->exec(); +DEFINE_ACTION (SetLDrawPath, 0) +{ (new LDrawPathDialog (true))->exec(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Exit, CTRL (Q)) { - exit (0); +DEFINE_ACTION (Exit, CTRL (Q)) +{ exit (0); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (NewSubfile, 0) { - AddObjectDialog::staticDialog (LDObject::Subfile, null); +DEFINE_ACTION (NewSubfile, 0) +{ AddObjectDialog::staticDialog (LDObject::Subfile, null); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (NewLine, 0) { - AddObjectDialog::staticDialog (LDObject::Line, null); +DEFINE_ACTION (NewLine, 0) +{ AddObjectDialog::staticDialog (LDObject::Line, null); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (NewTriangle, 0) { - AddObjectDialog::staticDialog (LDObject::Triangle, null); +DEFINE_ACTION (NewTriangle, 0) +{ AddObjectDialog::staticDialog (LDObject::Triangle, null); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (NewQuad, 0) { - AddObjectDialog::staticDialog (LDObject::Quad, null); +DEFINE_ACTION (NewQuad, 0) +{ AddObjectDialog::staticDialog (LDObject::Quad, null); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (NewCLine, 0) { - AddObjectDialog::staticDialog (LDObject::CndLine, null); +DEFINE_ACTION (NewCLine, 0) +{ AddObjectDialog::staticDialog (LDObject::CndLine, null); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (NewComment, 0) { - AddObjectDialog::staticDialog (LDObject::Comment, null); +DEFINE_ACTION (NewComment, 0) +{ AddObjectDialog::staticDialog (LDObject::Comment, null); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (NewBFC, 0) { - AddObjectDialog::staticDialog (LDObject::BFC, null); +DEFINE_ACTION (NewBFC, 0) +{ AddObjectDialog::staticDialog (LDObject::BFC, null); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (NewVertex, 0) { - AddObjectDialog::staticDialog (LDObject::Vertex, null); +DEFINE_ACTION (NewVertex, 0) +{ AddObjectDialog::staticDialog (LDObject::Vertex, null); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (MakePrimitive, 0) { - generatePrimitive(); +DEFINE_ACTION (MakePrimitive, 0) +{ generatePrimitive(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Edit, 0) { - if (g_win->sel().size() != 1) +DEFINE_ACTION (Edit, 0) +{ if (g_win->sel().size() != 1) return; - - LDObject* obj = g_win->sel()[0]; + + LDObject* obj = g_win->sel() [0]; AddObjectDialog::staticDialog (obj->getType(), obj); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Help, KEY (F1)) { - +DEFINE_ACTION (Help, KEY (F1)) +{ + } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (About, 0) { - AboutDialog().exec(); +DEFINE_ACTION (About, 0) +{ AboutDialog().exec(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (AboutQt, 0) { - QMessageBox::aboutQt (g_win); +DEFINE_ACTION (AboutQt, 0) +{ QMessageBox::aboutQt (g_win); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (SelectAll, CTRL (A)) { - g_win->sel().clear(); - +DEFINE_ACTION (SelectAll, CTRL (A)) +{ g_win->sel().clear(); + for (LDObject* obj : LDFile::current()->objects()) g_win->sel() << obj; - + g_win->updateSelection(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (SelectByColor, CTRL_SHIFT (A)) { - short colnum = g_win->getSelectedColor(); - +DEFINE_ACTION (SelectByColor, CTRL_SHIFT (A)) +{ short colnum = g_win->getSelectedColor(); + if (colnum == -1) return; // no consensus on color - + g_win->sel().clear(); + for (LDObject* obj : LDFile::current()->objects()) if (obj->color() == colnum) g_win->sel() << obj; - + g_win->updateSelection(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (SelectByType, 0) { - if (g_win->sel().size() == 0) +DEFINE_ACTION (SelectByType, 0) +{ if (g_win->sel().size() == 0) return; - + LDObject::Type type = g_win->uniformSelectedType(); - + if (type == LDObject::Unidentified) return; - + // If we're selecting subfile references, the reference filename must also // be uniform. str refName; - - if (type == LDObject::Subfile) { - refName = static_cast<LDSubfile*> (g_win->sel()[0])->fileInfo()->name(); - + + if (type == LDObject::Subfile) + { refName = static_cast<LDSubfile*> (g_win->sel() [0])->fileInfo()->name(); + for (LDObject* obj : g_win->sel()) if (static_cast<LDSubfile*> (obj)->fileInfo()->name() != refName) return; } - + g_win->sel().clear(); - for (LDObject* obj : LDFile::current()->objects()) { - if (obj->getType() != type) + + for (LDObject* obj : LDFile::current()->objects()) + { if (obj->getType() != type) continue; - + if (type == LDObject::Subfile && static_cast<LDSubfile*> (obj)->fileInfo()->name() != refName) continue; - + g_win->sel() << obj; } - + g_win->updateSelection(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (GridCoarse, 0) { - grid = Grid::Coarse; +DEFINE_ACTION (GridCoarse, 0) +{ grid = Grid::Coarse; g_win->updateGridToolBar(); } -DEFINE_ACTION (GridMedium, 0) { - grid = Grid::Medium; +DEFINE_ACTION (GridMedium, 0) +{ grid = Grid::Medium; g_win->updateGridToolBar(); } -DEFINE_ACTION (GridFine, 0) { - grid = Grid::Fine; +DEFINE_ACTION (GridFine, 0) +{ grid = Grid::Fine; g_win->updateGridToolBar(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (ResetView, CTRL (0)) { - g_win->R()->resetAngles(); +DEFINE_ACTION (ResetView, CTRL (0)) +{ g_win->R()->resetAngles(); g_win->R()->update(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (InsertFrom, 0) { - str fname = QFileDialog::getOpenFileName(); +DEFINE_ACTION (InsertFrom, 0) +{ str fname = QFileDialog::getOpenFileName(); ulong idx = g_win->getInsertionPoint(); - + if (!fname.length()) return; - + File f (fname, File::Read); - if (!f) { - critical (fmt ("Couldn't open %1 (%2)", fname, strerror (errno))); + + if (!f) + { critical (fmt ("Couldn't open %1 (%2)", fname, strerror (errno))); return; } - + List<LDObject*> objs = loadFileContents (&f, null); - + g_win->sel().clear(); - - for (LDObject* obj : objs) { - LDFile::current()->insertObj (idx, obj); + + for (LDObject* obj : objs) + { LDFile::current()->insertObj (idx, obj); g_win->sel() << obj; g_win->R()->compileObject (obj); - + idx++; } - + g_win->refresh(); g_win->scrollToSelection(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (ExportTo, 0) { - if (g_win->sel().size() == 0) +DEFINE_ACTION (ExportTo, 0) +{ if (g_win->sel().size() == 0) return; - + str fname = QFileDialog::getSaveFileName(); + if (fname.length() == 0) return; - + QFile file (fname); - if (!file.open (QIODevice::WriteOnly | QIODevice::Text)) { - critical (fmt ("Unable to open %1 for writing (%2)", fname, strerror (errno))); + + if (!file.open (QIODevice::WriteOnly | QIODevice::Text)) + { critical (fmt ("Unable to open %1 for writing (%2)", fname, strerror (errno))); return; } - - for (LDObject* obj : g_win->sel()) { - str contents = obj->raw(); + + for (LDObject* obj : g_win->sel()) + { str contents = obj->raw(); QByteArray data = contents.toUtf8(); file.write (data, data.size()); file.write ("\r\n", 2); @@ -407,115 +413,116 @@ // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (InsertRaw, 0) { - ulong idx = g_win->getInsertionPoint(); - +DEFINE_ACTION (InsertRaw, 0) +{ ulong idx = g_win->getInsertionPoint(); + QDialog* const dlg = new QDialog; QVBoxLayout* const layout = new QVBoxLayout; QTextEdit* const te_edit = new QTextEdit; QDialogButtonBox* const bbx_buttons = new QDialogButtonBox (QDialogButtonBox::Ok | QDialogButtonBox::Cancel); - + layout->addWidget (te_edit); layout->addWidget (bbx_buttons); dlg->setLayout (layout); dlg->setWindowTitle (APPNAME ": Insert Raw"); dlg->connect (bbx_buttons, SIGNAL (accepted()), dlg, SLOT (accept())); dlg->connect (bbx_buttons, SIGNAL (rejected()), dlg, SLOT (reject())); - + if (dlg->exec() == false) return; - + g_win->sel().clear(); - - for (str line : str (te_edit->toPlainText()).split ("\n")) { - LDObject* obj = parseLine (line); - + + for (str line : str (te_edit->toPlainText()).split ("\n")) + { LDObject* obj = parseLine (line); + LDFile::current()->insertObj (idx, obj); g_win->sel() << obj; g_win->R()->compileObject (obj); idx++; } - + g_win->refresh(); g_win->scrollToSelection(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Screenshot, 0) { - setlocale (LC_ALL, "C"); - +DEFINE_ACTION (Screenshot, 0) +{ setlocale (LC_ALL, "C"); + ushort w, h; uchar* imgdata = g_win->R()->screencap (w, h); QImage img = imageFromScreencap (imgdata, w, h); - + str root = basename (LDFile::current()->name()); + if (root.right (4) == ".dat") root.chop (4); - + str defaultname = (root.length() > 0) ? fmt ("%1.png", root) : ""; str fname = QFileDialog::getSaveFileName (g_win, "Save Screencap", defaultname, - "PNG images (*.png);;JPG images (*.jpg);;BMP images (*.bmp);;All Files (*.*)"); - + "PNG images (*.png);;JPG images (*.jpg);;BMP images (*.bmp);;All Files (*.*)"); + if (fname.length() > 0 && !img.save (fname)) critical (fmt ("Couldn't open %1 for writing to save screencap: %2", fname, strerror (errno))); - + delete[] imgdata; } // ============================================================================= // ----------------------------------------------------------------------------- extern_cfg (Bool, gl_axes); -DEFINE_ACTION (Axes, 0) { - gl_axes = !gl_axes; +DEFINE_ACTION (Axes, 0) +{ gl_axes = !gl_axes; ACTION (Axes)->setChecked (gl_axes); g_win->R()->update(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Visibility, 0) { - for (LDObject* obj : g_win->sel()) +DEFINE_ACTION (Visibility, 0) +{ for (LDObject* obj : g_win->sel()) obj->setHidden (!obj->hidden()); - + g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Wireframe, 0) { - gl_wireframe = !gl_wireframe; +DEFINE_ACTION (Wireframe, 0) +{ gl_wireframe = !gl_wireframe; g_win->R()->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (SetOverlay, 0) { - OverlayDialog dlg; - +DEFINE_ACTION (SetOverlay, 0) +{ OverlayDialog dlg; + if (!dlg.exec()) return; - - g_win->R()->setupOverlay ((GL::Camera) dlg.camera(), dlg.fpath(), dlg.ofsx(), - dlg.ofsy(), dlg.lwidth(), dlg.lheight() ); + + g_win->R()->setupOverlay ( (GL::Camera) dlg.camera(), dlg.fpath(), dlg.ofsx(), + dlg.ofsy(), dlg.lwidth(), dlg.lheight()); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (ClearOverlay, 0) { - g_win->R()->clearOverlay(); +DEFINE_ACTION (ClearOverlay, 0) +{ g_win->R()->clearOverlay(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (ModeSelect, CTRL (1)) { - g_win->R()->setEditMode (Select); +DEFINE_ACTION (ModeSelect, CTRL (1)) +{ g_win->R()->setEditMode (Select); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (ModeDraw, CTRL (2)) { - g_win->R()->setEditMode (Draw); +DEFINE_ACTION (ModeDraw, CTRL (2)) +{ g_win->R()->setEditMode (Draw); } // ============================================================================= @@ -526,15 +533,15 @@ // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (SetDrawDepth, 0) { - if (g_win->R()->camera() == GL::Free) +DEFINE_ACTION (SetDrawDepth, 0) +{ if (g_win->R()->camera() == GL::Free) return; - + bool ok; double depth = QInputDialog::getDouble (g_win, "Set Draw Depth", - fmt ("Depth value for %1 Camera:", g_win->R()->cameraName()), - g_win->R()->depthValue(), -10000.0f, 10000.0f, 3, &ok); - + fmt ("Depth value for %1 Camera:", g_win->R()->cameraName()), + g_win->R()->depthValue(), -10000.0f, 10000.0f, 3, &ok); + if (ok) g_win->R()->setDepthValue (depth); } @@ -543,17 +550,17 @@ // This is a test to draw a dummy axle. Meant to be used as a primitive gallery, // but I can't figure how to generate these pictures properly. Multi-threading // these is an immense pain. -DEFINE_ACTION (testpic, "Test picture", "", "", (0)) { - LDFile* file = getFile ("axle.dat"); +DEFINE_ACTION (testpic, "Test picture", "", "", (0)) +{ LDFile* file = getFile ("axle.dat"); setlocale (LC_ALL, "C"); - - if (!file) { - critical ("couldn't load axle.dat"); + + if (!file) + { critical ("couldn't load axle.dat"); return; } - + ushort w, h; - + GLRenderer* rend = new GLRenderer; rend->resize (64, 64); rend->setAttribute (Qt::WA_DontShowOnScreen); @@ -563,21 +570,22 @@ rend->compileAllObjects(); rend->initGLData(); rend->drawGLScene(); - + uchar* imgdata = rend->screencap (w, h); QImage img = imageFromScreencap (imgdata, w, h); - - if (img.isNull()) { - critical ("Failed to create the image!\n"); - } else { - QLabel* label = new QLabel; + + if (img.isNull()) + { critical ("Failed to create the image!\n"); + } + else + { QLabel* label = new QLabel; QDialog* dlg = new QDialog; label->setPixmap (QPixmap::fromImage (img)); QVBoxLayout* layout = new QVBoxLayout (dlg); layout->addWidget (label); dlg->exec(); } - + delete[] imgdata; rend->deleteLater(); } @@ -585,35 +593,35 @@ // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (ScanPrimitives, 0) { - PrimitiveLister::start(); +DEFINE_ACTION (ScanPrimitives, 0) +{ PrimitiveLister::start(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (BFCView, SHIFT (B)) { - gl_colorbfc = !gl_colorbfc; +DEFINE_ACTION (BFCView, SHIFT (B)) +{ gl_colorbfc = !gl_colorbfc; ACTION (BFCView)->setChecked (gl_colorbfc); g_win->R()->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (JumpTo, CTRL (G)) { - bool ok; +DEFINE_ACTION (JumpTo, CTRL (G)) +{ bool ok; int defval = 0; LDObject* obj; - + if (g_win->sel().size() == 1) - defval = g_win->sel()[0]->getIndex(); - + defval = g_win->sel() [0]->getIndex(); + int idx = QInputDialog::getInt (null, "Go to line", "Go to line:", defval, - 1, LDFile::current()->numObjs(), 1, &ok); - + 1, LDFile::current()->numObjs(), 1, &ok); + if (!ok || (obj = LDFile::current()->object (idx - 1)) == null) return; - + g_win->clearSelection(); g_win->sel() << obj; g_win->updateSelection(); -} \ No newline at end of file +}
--- a/src/gui_editactions.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/gui_editactions.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -40,59 +40,59 @@ // ============================================================================= // ----------------------------------------------------------------------------- -static int copyToClipboard() { - List<LDObject*> objs = g_win->sel(); +static int copyToClipboard() +{ List<LDObject*> objs = g_win->sel(); int num = 0; - + // Clear the clipboard first. qApp->clipboard()->clear(); - + // Now, copy the contents into the clipboard. str data; - - for (LDObject* obj : objs) { - if (data.length() > 0) + + for (LDObject* obj : objs) + { if (data.length() > 0) data += "\n"; - + data += obj->raw(); ++num; } - + qApp->clipboard()->setText (data); return num; } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Cut, CTRL (X)) { - int num = copyToClipboard(); +DEFINE_ACTION (Cut, CTRL (X)) +{ int num = copyToClipboard(); g_win->deleteSelection(); log (ForgeWindow::tr ("%1 objects cut"), num); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Copy, CTRL (C)) { - int num = copyToClipboard(); +DEFINE_ACTION (Copy, CTRL (C)) +{ int num = copyToClipboard(); log (ForgeWindow::tr ("%1 objects copied"), num); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Paste, CTRL (V)) { - const str clipboardText = qApp->clipboard()->text(); +DEFINE_ACTION (Paste, CTRL (V)) +{ const str clipboardText = qApp->clipboard()->text(); ulong idx = g_win->getInsertionPoint(); g_win->sel().clear(); int num = 0; - - for (str line : clipboardText.split ("\n")) { - LDObject* pasted = parseLine (line); + + for (str line : clipboardText.split ("\n")) + { LDObject* pasted = parseLine (line); LDFile::current()->insertObj (idx++, pasted); g_win->sel() << pasted; g_win->R()->compileObject (pasted); ++num; } - + log (ForgeWindow::tr ("%1 objects pasted"), num); g_win->refresh(); g_win->scrollToSelection(); @@ -100,127 +100,127 @@ // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Delete, KEY (Delete)) { - int num = g_win->deleteSelection(); +DEFINE_ACTION (Delete, KEY (Delete)) +{ int num = g_win->deleteSelection(); log (ForgeWindow::tr ("%1 objects deleted"), num); } // ============================================================================= // ----------------------------------------------------------------------------- -static void doInline (bool deep) { - List<LDObject*> sel = g_win->sel(); - - for (LDObject* obj : sel) { - // Get the index of the subfile so we know where to insert the +static void doInline (bool deep) +{ List<LDObject*> sel = g_win->sel(); + + for (LDObject* obj : sel) + { // Get the index of the subfile so we know where to insert the // inlined contents. long idx = obj->getIndex(); - + if (idx == -1) continue; - + List<LDObject*> objs; - + if (obj->getType() == LDObject::Subfile) objs = static_cast<LDSubfile*> (obj)->inlineContents ( - (LDSubfile::InlineFlags) - ((deep) ? LDSubfile::DeepInline : 0) | - LDSubfile::CacheInline - ); + (LDSubfile::InlineFlags) + ( (deep) ? LDSubfile::DeepInline : 0) | + LDSubfile::CacheInline + ); else continue; - + // Merge in the inlined objects - for (LDObject* inlineobj : objs) { - str line = inlineobj->raw(); + for (LDObject * inlineobj : objs) + { str line = inlineobj->raw(); delete inlineobj; - + LDObject* newobj = parseLine (line); LDFile::current()->insertObj (idx++, newobj); g_win->sel() << newobj; g_win->R()->compileObject (newobj); } - + // Delete the subfile now as it's been inlined. LDFile::current()->forgetObject (obj); delete obj; } - + g_win->refresh(); } -DEFINE_ACTION (Inline, CTRL (I)) { - doInline (false); +DEFINE_ACTION (Inline, CTRL (I)) +{ doInline (false); } -DEFINE_ACTION (InlineDeep, CTRL_SHIFT (I)) { - doInline (true); +DEFINE_ACTION (InlineDeep, CTRL_SHIFT (I)) +{ doInline (true); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (SplitQuads, 0) { - List<LDObject*> objs = g_win->sel(); +DEFINE_ACTION (SplitQuads, 0) +{ List<LDObject*> objs = g_win->sel(); int num = 0; - - for (LDObject* obj : objs) { - if (obj->getType() != LDObject::Quad) + + for (LDObject* obj : objs) + { if (obj->getType() != LDObject::Quad) continue; - + // Find the index of this quad long index = obj->getIndex(); - + if (index == -1) return; - + List<LDTriangle*> triangles = static_cast<LDQuad*> (obj)->splitToTriangles(); - + // Replace the quad with the first triangle and add the second triangle // after the first one. LDFile::current()->setObject (index, triangles[0]); LDFile::current()->insertObj (index + 1, triangles[1]); - - for (LDTriangle * t : triangles) + + for (LDTriangle* t : triangles) g_win->R()->compileObject (t); - + // Delete this quad now, it has been split. delete obj; - + num++; } - + log ("%1 quadrilaterals split", num); g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (EditRaw, KEY (F9)) { - if (g_win->sel().size() != 1) +DEFINE_ACTION (EditRaw, KEY (F9)) +{ if (g_win->sel().size() != 1) return; - + LDObject* obj = g_win->sel() [0]; QDialog* dlg = new QDialog; Ui::EditRawUI ui; - + ui.setupUi (dlg); ui.code->setText (obj->raw()); - + if (obj->getType() == LDObject::Error) ui.errorDescription->setText (static_cast<LDError*> (obj)->reason); - else { - ui.errorDescription->hide(); + else + { ui.errorDescription->hide(); ui.errorIcon->hide(); } - + if (!dlg->exec()) return; - + LDObject* oldobj = obj; - + // Reinterpret it from the text of the input field obj = parseLine (ui.code->text()); oldobj->replace (obj); - + // Refresh g_win->R()->compileObject (obj); g_win->refresh(); @@ -228,494 +228,512 @@ // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (SetColor, KEY (C)) { - if (g_win->sel().size() <= 0) +DEFINE_ACTION (SetColor, KEY (C)) +{ if (g_win->sel().size() <= 0) return; - + short colnum; short defcol = -1; - + List<LDObject*> objs = g_win->sel(); - + // If all selected objects have the same color, said color is our default // value to the color selection dialog. defcol = g_win->getSelectedColor(); - + // Show the dialog to the user now and ask for a color. - if (ColorSelector::getColor (colnum, defcol, g_win)) { - for (LDObject* obj : objs) { - if (obj->isColored() == false) + if (ColorSelector::getColor (colnum, defcol, g_win)) + { for (LDObject* obj : objs) + { if (obj->isColored() == false) continue; - + obj->setColor (colnum); g_win->R()->compileObject (obj); } - + g_win->refresh(); } } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Borders, CTRL_SHIFT (B)) { - List<LDObject*> objs = g_win->sel(); +DEFINE_ACTION (Borders, CTRL_SHIFT (B)) +{ List<LDObject*> objs = g_win->sel(); int num = 0; - - for (LDObject* obj : objs) { - if (obj->getType() != LDObject::Quad && obj->getType() != LDObject::Triangle) + + for (LDObject* obj : objs) + { if (obj->getType() != LDObject::Quad && obj->getType() != LDObject::Triangle) continue; - + short numLines; LDLine* lines[4]; - - if (obj->getType() == LDObject::Quad) { - numLines = 4; - + + if (obj->getType() == LDObject::Quad) + { numLines = 4; + LDQuad* quad = static_cast<LDQuad*> (obj); lines[0] = new LDLine (quad->getVertex (0), quad->getVertex (1)); lines[1] = new LDLine (quad->getVertex (1), quad->getVertex (2)); lines[2] = new LDLine (quad->getVertex (2), quad->getVertex (3)); lines[3] = new LDLine (quad->getVertex (3), quad->getVertex (0)); - } else { - numLines = 3; - + } + else + { numLines = 3; + LDTriangle* tri = static_cast<LDTriangle*> (obj); lines[0] = new LDLine (tri->getVertex (0), tri->getVertex (1)); lines[1] = new LDLine (tri->getVertex (1), tri->getVertex (2)); lines[2] = new LDLine (tri->getVertex (2), tri->getVertex (0)); } - - for (short i = 0; i < numLines; ++i) { - ulong idx = obj->getIndex() + i + 1; - + + for (short i = 0; i < numLines; ++i) + { long idx = obj->getIndex() + i + 1; + lines[i]->setColor (edgecolor); LDFile::current()->insertObj (idx, lines[i]); g_win->R()->compileObject (lines[i]); } - + num += numLines; } - + log (ForgeWindow::tr ("Added %1 border lines"), num); g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (CornerVerts, 0) { - int num = 0; - - for (LDObject* obj : g_win->sel()) { - if (obj->vertices() < 2) +DEFINE_ACTION (CornerVerts, 0) +{ int num = 0; + + for (LDObject* obj : g_win->sel()) + { if (obj->vertices() < 2) continue; - + ulong idx = obj->getIndex(); - - for (short i = 0; i < obj->vertices(); ++i) { - LDVertex* vert = new LDVertex; + + for (short i = 0; i < obj->vertices(); ++i) + { LDVertex* vert = new LDVertex; vert->pos = obj->getVertex (i); vert->setColor (obj->color()); - + LDFile::current()->insertObj (++idx, vert); g_win->R()->compileObject (vert); ++num; } } - + log (ForgeWindow::tr ("Added %1 vertices"), num); g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -static void doMoveSelection (const bool up) { - List<LDObject*> objs = g_win->sel(); +static void doMoveSelection (const bool up) +{ List<LDObject*> objs = g_win->sel(); LDObject::moveObjects (objs, up); g_win->buildObjList(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (MoveUp, KEY (PageUp)) { - doMoveSelection (true); +DEFINE_ACTION (MoveUp, KEY (PageUp)) +{ doMoveSelection (true); } -DEFINE_ACTION (MoveDown, KEY (PageDown)) { - doMoveSelection (false); +DEFINE_ACTION (MoveDown, KEY (PageDown)) +{ doMoveSelection (false); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Undo, CTRL (Z)) { - LDFile::current()->undo(); +DEFINE_ACTION (Undo, CTRL (Z)) +{ LDFile::current()->undo(); } -DEFINE_ACTION (Redo, CTRL_SHIFT (Z)) { - LDFile::current()->redo(); +DEFINE_ACTION (Redo, CTRL_SHIFT (Z)) +{ LDFile::current()->redo(); } // ============================================================================= // ----------------------------------------------------------------------------- -void doMoveObjects (vertex vect) { - // Apply the grid values +void doMoveObjects (vertex vect) +{ // Apply the grid values vect[X] *= currentGrid().confs[Grid::X]->value; vect[Y] *= currentGrid().confs[Grid::Y]->value; vect[Z] *= currentGrid().confs[Grid::Z]->value; - - for (LDObject* obj : g_win->sel()) { - obj->move (vect); + + for (LDObject* obj : g_win->sel()) + { obj->move (vect); g_win->R()->compileObject (obj); } - + g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (MoveXNeg, KEY (Left)) { - doMoveObjects ({-1, 0, 0}); +DEFINE_ACTION (MoveXNeg, KEY (Left)) +{ doMoveObjects ( { -1, 0, 0}); } -DEFINE_ACTION (MoveYNeg, KEY (Home)) { - doMoveObjects ({0, -1, 0}); +DEFINE_ACTION (MoveYNeg, KEY (Home)) +{ doMoveObjects ( {0, -1, 0}); } -DEFINE_ACTION (MoveZNeg, KEY (Down)) { - doMoveObjects ({0, 0, -1}); +DEFINE_ACTION (MoveZNeg, KEY (Down)) +{ doMoveObjects ( {0, 0, -1}); } -DEFINE_ACTION (MoveXPos, KEY (Right)) { - doMoveObjects ({1, 0, 0}); +DEFINE_ACTION (MoveXPos, KEY (Right)) +{ doMoveObjects ( {1, 0, 0}); } -DEFINE_ACTION (MoveYPos, KEY (End)) { - doMoveObjects ({0, 1, 0}); +DEFINE_ACTION (MoveYPos, KEY (End)) +{ doMoveObjects ( {0, 1, 0}); } -DEFINE_ACTION (MoveZPos, KEY (Up)) { - doMoveObjects ({0, 0, 1}); +DEFINE_ACTION (MoveZPos, KEY (Up)) +{ doMoveObjects ( {0, 0, 1}); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Invert, CTRL_SHIFT (W)) { - List<LDObject*> sel = g_win->sel(); - - for (LDObject* obj : sel) { - obj->invert(); +DEFINE_ACTION (Invert, CTRL_SHIFT (W)) +{ List<LDObject*> sel = g_win->sel(); + + for (LDObject* obj : sel) + { obj->invert(); g_win->R()->compileObject (obj); } - + g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -static void rotateVertex (vertex& v, const vertex& rotpoint, const matrix& transform) { - v.move (-rotpoint); +static void rotateVertex (vertex& v, const vertex& rotpoint, const matrix& transform) +{ v.move (-rotpoint); v.transform (transform, g_origin); v.move (rotpoint); } // ============================================================================= // ----------------------------------------------------------------------------- -static void doRotate (const short l, const short m, const short n) { - List<LDObject*> sel = g_win->sel(); +static void doRotate (const short l, const short m, const short n) +{ List<LDObject*> sel = g_win->sel(); List<vertex*> queue; const vertex rotpoint = rotPoint (sel); const double angle = (pi * currentGrid().confs[Grid::Angle]->value) / 180, - cosangle = cos (angle), - sinangle = sin (angle); - + cosangle = cos (angle), + sinangle = sin (angle); + // ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2 - matrix transform ({ - (l * l * (1 - cosangle)) + cosangle, - (m * l * (1 - cosangle)) - (n * sinangle), - (n * l * (1 - cosangle)) + (m * sinangle), - - (l * m * (1 - cosangle)) + (n * sinangle), - (m * m * (1 - cosangle)) + cosangle, - (n * m * (1 - cosangle)) - (l * sinangle), - - (l * n * (1 - cosangle)) - (m * sinangle), - (m * n * (1 - cosangle)) + (l * sinangle), - (n * n * (1 - cosangle)) + cosangle + matrix transform ( + { (l* l * (1 - cosangle)) + cosangle, + (m* l * (1 - cosangle)) - (n* sinangle), + (n* l * (1 - cosangle)) + (m* sinangle), + + (l* m * (1 - cosangle)) + (n* sinangle), + (m* m * (1 - cosangle)) + cosangle, + (n* m * (1 - cosangle)) - (l* sinangle), + + (l* n * (1 - cosangle)) - (m* sinangle), + (m* n * (1 - cosangle)) + (l* sinangle), + (n* n * (1 - cosangle)) + cosangle }); - + // Apply the above matrix to everything - for (LDObject* obj : sel) { - if (obj->vertices()) { - for (short i = 0; i < obj->vertices(); ++i) { - vertex v = obj->getVertex (i); + for (LDObject* obj : sel) + { if (obj->vertices()) + { for (short i = 0; i < obj->vertices(); ++i) + { vertex v = obj->getVertex (i); rotateVertex (v, rotpoint, transform); obj->setVertex (i, v); } - } elif (obj->hasMatrix()) { - LDMatrixObject* mo = dynamic_cast<LDMatrixObject*> (obj); - + } elif (obj->hasMatrix()) + + { LDMatrixObject* mo = dynamic_cast<LDMatrixObject*> (obj); + // Transform the position vertex v = mo->position(); rotateVertex (v, rotpoint, transform); mo->setPosition (v); - + // Transform the matrix mo->setTransform (mo->transform() * transform); - } elif (obj->getType() == LDObject::Vertex) { - LDVertex* vert = static_cast<LDVertex*> (obj); + } elif (obj->getType() == LDObject::Vertex) + { LDVertex* vert = static_cast<LDVertex*> (obj); vertex v = vert->pos; rotateVertex (v, rotpoint, transform); vert->pos = v; } - + g_win->R()->compileObject (obj); } - + g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (RotateXPos, CTRL (Right)) { doRotate (1, 0, 0); } -DEFINE_ACTION (RotateYPos, CTRL (End)) { doRotate (0, 1, 0); } -DEFINE_ACTION (RotateZPos, CTRL (Up)) { doRotate (0, 0, 1); } -DEFINE_ACTION (RotateXNeg, CTRL (Left)) { doRotate (-1, 0, 0); } -DEFINE_ACTION (RotateYNeg, CTRL (Home)) { doRotate (0, -1, 0); } -DEFINE_ACTION (RotateZNeg, CTRL (Down)) { doRotate (0, 0, -1); } +DEFINE_ACTION (RotateXPos, CTRL (Right)) +{ doRotate (1, 0, 0); +} +DEFINE_ACTION (RotateYPos, CTRL (End)) +{ doRotate (0, 1, 0); +} +DEFINE_ACTION (RotateZPos, CTRL (Up)) +{ doRotate (0, 0, 1); +} +DEFINE_ACTION (RotateXNeg, CTRL (Left)) +{ doRotate (-1, 0, 0); +} +DEFINE_ACTION (RotateYNeg, CTRL (Home)) +{ doRotate (0, -1, 0); +} +DEFINE_ACTION (RotateZNeg, CTRL (Down)) +{ doRotate (0, 0, -1); +} -DEFINE_ACTION (RotationPoint, (0)) { - configRotationPoint(); +DEFINE_ACTION (RotationPoint, (0)) +{ configRotationPoint(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (RoundCoordinates, 0) { - setlocale (LC_ALL, "C"); +DEFINE_ACTION (RoundCoordinates, 0) +{ setlocale (LC_ALL, "C"); int num = 0; - + for (LDObject* obj : g_win->sel()) - for (short i = 0; i < obj->vertices(); ++i) { - vertex v = obj->getVertex (i); - - for (const Axis ax : g_Axes) { - // HACK: .. should find a better way to do this - char valstr[64]; - sprintf (valstr, "%.3f", v[ax]); - v[ax] = atof (valstr); + for (short i = 0; i < obj->vertices(); ++i) + { vertex v = obj->getVertex (i); + + for (const Axis ax : g_Axes) + { // HACK: .. should find a better way to do this + char valstr[64]; + sprintf (valstr, "%.3f", v[ax]); + v[ax] = atof (valstr); + } + + obj->setVertex (i, v); + g_win->R()->compileObject (obj); + num += 3; } - - obj->setVertex (i, v); - g_win->R()->compileObject (obj); - num += 3; - } - + log (ForgeWindow::tr ("Rounded %1 coordinates"), num); g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Uncolorize, 0) { - int num = 0; - - for (LDObject* obj : g_win->sel()) { - if (obj->isColored() == false) +DEFINE_ACTION (Uncolorize, 0) +{ int num = 0; + + for (LDObject* obj : g_win->sel()) + { if (obj->isColored() == false) continue; - + int col = maincolor; - + if (obj->getType() == LDObject::Line || obj->getType() == LDObject::CndLine) col = edgecolor; - + obj->setColor (col); g_win->R()->compileObject (obj); num++; } - + log (ForgeWindow::tr ("%1 objects uncolored"), num); g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (ReplaceCoords, CTRL (R)) { - QDialog* dlg = new QDialog (g_win); +DEFINE_ACTION (ReplaceCoords, CTRL (R)) +{ QDialog* dlg = new QDialog (g_win); Ui::ReplaceCoordsUI ui; ui.setupUi (dlg); - + if (!dlg->exec()) return; - + const double search = ui.search->value(), - replacement = ui.replacement->value(); + replacement = ui.replacement->value(); const bool any = ui.any->isChecked(), - rel = ui.relative->isChecked(); - + rel = ui.relative->isChecked(); + List<Axis> sel; int num = 0; - + if (ui.x->isChecked()) sel << X; + if (ui.y->isChecked()) sel << Y; + if (ui.z->isChecked()) sel << Z; for (LDObject* obj : g_win->sel()) - for (short i = 0; i < obj->vertices(); ++i) { - vertex v = obj->getVertex (i); - - for (Axis ax : sel) { - double& coord = v[ax]; - - if (any || coord == search) { - if (!rel) - coord = 0; - - coord += replacement; - num++; + for (short i = 0; i < obj->vertices(); ++i) + { vertex v = obj->getVertex (i); + + for (Axis ax : sel) + { double& coord = v[ax]; + + if (any || coord == search) + { if (!rel) + coord = 0; + + coord += replacement; + num++; + } } + + obj->setVertex (i, v); + g_win->R()->compileObject (obj); } - - obj->setVertex (i, v); - g_win->R()->compileObject (obj); - } - + log (ForgeWindow::tr ("Altered %1 values"), num); g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Flip, CTRL_SHIFT (F)) { - QDialog* dlg = new QDialog; +DEFINE_ACTION (Flip, CTRL_SHIFT (F)) +{ QDialog* dlg = new QDialog; Ui::FlipUI ui; ui.setupUi (dlg); - + if (!dlg->exec()) return; - + List<Axis> sel; + if (ui.x->isChecked()) sel << X; if (ui.y->isChecked()) sel << Y; if (ui.z->isChecked()) sel << Z; - + for (LDObject* obj : g_win->sel()) - for (short i = 0; i < obj->vertices(); ++i) { - vertex v = obj->getVertex (i); - + for (short i = 0; i < obj->vertices(); ++i) + { vertex v = obj->getVertex (i); + for (Axis ax : sel) - v[ax] *= -1; + v[ax] *= -1; - obj->setVertex (i, v); - g_win->R()->compileObject (obj); - } - + obj->setVertex (i, v); + g_win->R()->compileObject (obj); + } + g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Demote, 0) { - List<LDObject*> sel = g_win->sel(); +DEFINE_ACTION (Demote, 0) +{ List<LDObject*> sel = g_win->sel(); int num = 0; - - for (LDObject* obj : sel) { - if (obj->getType() != LDObject::CndLine) + + for (LDObject* obj : sel) + { if (obj->getType() != LDObject::CndLine) continue; - + LDLine* repl = static_cast<LDCndLine*> (obj)->demote(); g_win->R()->compileObject (repl); ++num; } - + log (ForgeWindow::tr ("Demoted %1 conditional lines"), num); g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -static bool isColorUsed (short colnum) { - for (LDObject* obj : LDFile::current()->objects()) +static bool isColorUsed (short colnum) +{ for (LDObject* obj : LDFile::current()->objects()) if (obj->isColored() && obj->color() == colnum) return true; - + return false; } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (Autocolor, 0) { - short colnum = 0; - +DEFINE_ACTION (Autocolor, 0) +{ short colnum = 0; + while (colnum < MAX_COLORS && (getColor (colnum) == null || isColorUsed (colnum))) colnum++; - - if (colnum >= MAX_COLORS) { - log (ForgeWindow::tr ("Cannot auto-color: all colors are in use!")); + + if (colnum >= MAX_COLORS) + { log (ForgeWindow::tr ("Cannot auto-color: all colors are in use!")); return; } - - for (LDObject* obj : g_win->sel()) { - if (obj->isColored() == false) + + for (LDObject* obj : g_win->sel()) + { if (obj->isColored() == false) continue; - + obj->setColor (colnum); g_win->R()->compileObject (obj); } - + log (ForgeWindow::tr ("Auto-colored: new color is [%1] %2"), colnum, getColor (colnum)->name); g_win->refresh(); } // ============================================================================= // ----------------------------------------------------------------------------- -DEFINE_ACTION (AddHistoryLine, 0) { - LDObject* obj; +DEFINE_ACTION (AddHistoryLine, 0) +{ LDObject* obj; bool ishistory = false, - prevIsHistory = false; - + prevIsHistory = false; + QDialog* dlg = new QDialog; Ui_AddHistoryLine* ui = new Ui_AddHistoryLine; ui->setupUi (dlg); ui->m_username->setText (ld_defaultuser); ui->m_date->setDate (QDate::currentDate()); ui->m_comment->setFocus(); - + if (!dlg->exec()) return; - + // Create the comment object based on input str commentText = fmt ("!HISTORY %1 [%2] %3", - ui->m_date->date().toString("yyyy-MM-dd"), - ui->m_username->text(), - ui->m_comment->text()); - + ui->m_date->date().toString ("yyyy-MM-dd"), + ui->m_username->text(), + ui->m_comment->text()); + LDComment* comm = new LDComment (commentText); - + // Find a spot to place the new comment for ( obj = LDFile::current()->object (0); obj && obj->next() && !obj->next()->isScemantic(); obj = obj->next() - ) { - LDComment* comm = dynamic_cast<LDComment*> (obj); + ) + { LDComment* comm = dynamic_cast<LDComment*> (obj); + if (comm && comm->text.startsWith ("!HISTORY ")) ishistory = true; - - if (prevIsHistory && !ishistory) { - // Last line was history, this isn't, thus insert the new history + + if (prevIsHistory && !ishistory) + { // Last line was history, this isn't, thus insert the new history // line here. break; } - + prevIsHistory = ishistory; } - + int idx = obj ? obj->getIndex() : 0; LDFile::current()->insertObj (idx++, comm); - + // If we're adding a history line right before a scemantic object, pad it // an empty line if (obj && obj->next() && obj->next()->isScemantic()) LDFile::current()->insertObj (idx, new LDEmpty); - + g_win->buildObjList(); delete ui; -} \ No newline at end of file +}
--- a/src/history.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/history.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -33,90 +33,90 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void History::undo() { - if (m_changesets.size() == 0 || pos() == -1) +void History::undo() +{ if (m_changesets.size() == 0 || pos() == -1) return; - + const list& set = changeset (pos()); g_fullRefresh = false; - + // Iterate the list in reverse and undo all actions - for (const AbstractHistoryEntry * change : c_rev<AbstractHistoryEntry*> (set)) + for (const AbstractHistoryEntry* change : c_rev<AbstractHistoryEntry*> (set)) change->undo(); - + setPos (pos() - 1); - + if (!g_fullRefresh) g_win->refresh(); else g_win->fullRefresh(); - + updateActions(); } // ============================================================================= // ----------------------------------------------------------------------------- -void History::redo() { - if (pos() == (long) m_changesets.size()) +void History::redo() +{ if (pos() == (long) m_changesets.size()) return; - + const list& set = changeset (pos() + 1); g_fullRefresh = false; - + // Redo things - in the order as they were done in the first place - for (const AbstractHistoryEntry * change : set) + for (const AbstractHistoryEntry* change : set) change->redo(); - + setPos (pos() + 1); - + if (!g_fullRefresh) g_win->refresh(); else g_win->fullRefresh(); - + updateActions(); } // ============================================================================= // ----------------------------------------------------------------------------- -void History::clear() { - for (List<AbstractHistoryEntry*> set : m_changesets) - for (AbstractHistoryEntry * change : set) +void History::clear() +{ for (List<AbstractHistoryEntry*> set : m_changesets) + for (AbstractHistoryEntry* change : set) delete change; - + m_changesets.clear(); } // ============================================================================= // ----------------------------------------------------------------------------- -void History::updateActions() const { - ACTION (Undo)->setEnabled (pos() != -1); +void History::updateActions() const +{ ACTION (Undo)->setEnabled (pos() != -1); ACTION (Redo)->setEnabled (pos() < (long) m_changesets.size() - 1); } // ============================================================================= // ----------------------------------------------------------------------------- -void History::open() { - if (opened()) +void History::open() +{ if (opened()) return; - + setOpened (true); } // ============================================================================= // ----------------------------------------------------------------------------- -void History::close() { - if (!opened()) +void History::close() +{ if (!opened()) return; - + setOpened (false); - + if (m_currentArchive.size() == 0) return; - + while (pos() < size() - 1) m_changesets.erase (size() - 1); - + m_changesets << m_currentArchive; m_currentArchive.clear(); setPos (pos() + 1); @@ -125,31 +125,31 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void History::add (AbstractHistoryEntry* entry) { - if (!opened()) { - delete entry; +void History::add (AbstractHistoryEntry* entry) +{ if (!opened()) + { delete entry; return; } - + entry->setParent (this); m_currentArchive << entry; } // ============================================================================= // ----------------------------------------------------------------------------- -void AddHistory::undo() const { - LDFile* f = parent()->file(); +void AddHistory::undo() const +{ LDFile* f = parent()->file(); LDObject* obj = f->object (index()); f->forgetObject (obj); delete obj; - + g_fullRefresh = true; } // ============================================================================= // ----------------------------------------------------------------------------- -void AddHistory::redo() const { - LDFile* f = parent()->file(); +void AddHistory::redo() const +{ LDFile* f = parent()->file(); LDObject* obj = parseLine (code()); f->insertObj (index(), obj); g_win->R()->compileObject (obj); @@ -160,8 +160,8 @@ // ============================================================================= // heh // ----------------------------------------------------------------------------- -void DelHistory::undo() const { - LDFile* f = parent()->file(); +void DelHistory::undo() const +{ LDFile* f = parent()->file(); LDObject* obj = parseLine (code()); f->insertObj (index(), obj); g_win->R()->compileObject (obj); @@ -169,12 +169,12 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void DelHistory::redo() const { - LDFile* f = parent()->file(); +void DelHistory::redo() const +{ LDFile* f = parent()->file(); LDObject* obj = f->object (index()); f->forgetObject (obj); delete obj; - + g_fullRefresh = true; } @@ -182,8 +182,8 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void EditHistory::undo() const { - LDObject* obj = LDFile::current()->object (index()); +void EditHistory::undo() const +{ LDObject* obj = LDFile::current()->object (index()); LDObject* newobj = parseLine (oldCode()); obj->replace (newobj); g_win->R()->compileObject (newobj); @@ -191,8 +191,8 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void EditHistory::redo() const { - LDObject* obj = LDFile::current()->object (index()); +void EditHistory::redo() const +{ LDObject* obj = LDFile::current()->object (index()); LDObject* newobj = parseLine (newCode()); obj->replace (newobj); g_win->R()->compileObject (newobj); @@ -202,12 +202,12 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void SwapHistory::undo() const { - LDObject::fromID (a)->swap (LDObject::fromID (b)); +void SwapHistory::undo() const +{ LDObject::fromID (a)->swap (LDObject::fromID (b)); } -void SwapHistory::redo() const { - undo(); // :v +void SwapHistory::redo() const +{ undo(); // :v } -SwapHistory::~SwapHistory() {} \ No newline at end of file +SwapHistory::~SwapHistory() {}
--- a/src/history.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/history.h Thu Oct 03 20:56:20 2013 +0300 @@ -31,146 +31,151 @@ class AbstractHistoryEntry; // ============================================================================= -class History { - PROPERTY (long, pos, setPos) +class History +{ PROPERTY (long, pos, setPos) PROPERTY (LDFile*, file, setFile) READ_PROPERTY (bool, opened, setOpened) - -public: - typedef List<AbstractHistoryEntry*> list; - - enum Type { - Del, - Edit, - Add, - Move, - Swap, - }; - - History(); - void undo(); - void redo(); - void clear(); - void updateActions() const; - - void open(); - void close(); - void add (AbstractHistoryEntry* entry); - long size() const { return m_changesets.size(); } - - History& operator<< (AbstractHistoryEntry* entry) { - add (entry); - return *this; - } - - const list& changeset (long pos) const { - return m_changesets[pos]; - } - -private: - list m_currentArchive; - List<list> m_changesets; + + public: + typedef List<AbstractHistoryEntry*> list; + + enum Type + { Del, + Edit, + Add, + Move, + Swap, + }; + + History(); + void undo(); + void redo(); + void clear(); + void updateActions() const; + + void open(); + void close(); + void add (AbstractHistoryEntry* entry); + + inline long size() const + { return m_changesets.size(); + } + + inline History& operator<< (AbstractHistoryEntry* entry) + { add (entry); + return *this; + } + + inline const list& changeset (long pos) const + { return m_changesets[pos]; + } + + private: + list m_currentArchive; + List<list> m_changesets; }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -class AbstractHistoryEntry { - PROPERTY (History*, parent, setParent) - -public: - virtual void undo() const {} - virtual void redo() const {} - virtual ~AbstractHistoryEntry() {} - virtual History::Type getType() const { return (History::Type) 0; } +class AbstractHistoryEntry +{ PROPERTY (History*, parent, setParent) + + public: + virtual void undo() const {} + virtual void redo() const {} + virtual ~AbstractHistoryEntry() {} + virtual History::Type getType() const + { return (History::Type) 0; + } }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -class DelHistory : public AbstractHistoryEntry { -public: - enum Type { - Cut, // was deleted with a cut operation - Other, // was deleted witout specific reason - }; - - PROPERTY (ulong, index, setIndex) - PROPERTY (str, code, setCode) - PROPERTY (DelHistory::Type, type, setType) - -public: - IMPLEMENT_HISTORY_TYPE (Del) - - DelHistory (ulong idx, LDObject* obj, Type type = Other) : - m_index (idx), - m_code (obj->raw()), - m_type (type) {} +class DelHistory : public AbstractHistoryEntry +{ public: + enum Type + { Cut, // was deleted with a cut operation + Other, // was deleted witout specific reason + }; + + PROPERTY (ulong, index, setIndex) + PROPERTY (str, code, setCode) + PROPERTY (DelHistory::Type, type, setType) + + public: + IMPLEMENT_HISTORY_TYPE (Del) + + DelHistory (ulong idx, LDObject* obj, Type type = Other) : + m_index (idx), + m_code (obj->raw()), + m_type (type) {} }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -class EditHistory : public AbstractHistoryEntry { - PROPERTY (ulong, index, setIndex) +class EditHistory : public AbstractHistoryEntry +{ PROPERTY (ulong, index, setIndex) PROPERTY (str, oldCode, setOldCode) PROPERTY (str, newCode, setNewCode) - -public: - IMPLEMENT_HISTORY_TYPE (Edit) - - EditHistory (ulong idx, str oldCode, str newCode) : - m_index (idx), - m_oldCode (oldCode), - m_newCode (newCode) {} + + public: + IMPLEMENT_HISTORY_TYPE (Edit) + + EditHistory (ulong idx, str oldCode, str newCode) : + m_index (idx), + m_oldCode (oldCode), + m_newCode (newCode) {} }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -class AddHistory : public AbstractHistoryEntry { -public: - enum Type { - Other, // was "just added" - Paste, // was added through a paste operation - }; - - PROPERTY (ulong, index, setIndex) - PROPERTY (str, code, setCode) - PROPERTY (AddHistory::Type, type, setType) - -public: - IMPLEMENT_HISTORY_TYPE (Add) - - AddHistory (ulong idx, LDObject* obj, Type type = Other) : - m_index (idx), - m_code (obj->raw()), - m_type (type) {} +class AddHistory : public AbstractHistoryEntry +{ public: + enum Type + { Other, // was "just added" + Paste, // was added through a paste operation + }; + + PROPERTY (ulong, index, setIndex) + PROPERTY (str, code, setCode) + PROPERTY (AddHistory::Type, type, setType) + + public: + IMPLEMENT_HISTORY_TYPE (Add) + + AddHistory (ulong idx, LDObject* obj, Type type = Other) : + m_index (idx), + m_code (obj->raw()), + m_type (type) {} }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= -class MoveHistory : public AbstractHistoryEntry { -public: - IMPLEMENT_HISTORY_TYPE (Move) - - List<ulong> indices; - vertex dest; - - MoveHistory (List<ulong> indices, vertex dest) : - indices (indices), - dest (dest) {} +class MoveHistory : public AbstractHistoryEntry +{ public: + IMPLEMENT_HISTORY_TYPE (Move) + + List<ulong> indices; + vertex dest; + + MoveHistory (List<ulong> indices, vertex dest) : + indices (indices), + dest (dest) {} }; -class SwapHistory : public AbstractHistoryEntry { -public: - IMPLEMENT_HISTORY_TYPE (Swap) - ulong a, b; - - SwapHistory (ulong a, ulong b) : - a (a), - b (b) {} +class SwapHistory : public AbstractHistoryEntry +{ public: + IMPLEMENT_HISTORY_TYPE (Swap) + ulong a, b; + + SwapHistory (ulong a, ulong b) : + a (a), + b (b) {} }; -#endif // HISTORY_H \ No newline at end of file +#endif // HISTORY_H
--- a/src/ldconfig.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/ldconfig.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -25,78 +25,78 @@ // ============================================================================= // Helper function for parseLDConfig // ----------------------------------------------------------------------------- -static bool parseLDConfigTag (LDConfigParser& pars, char const* tag, str& val) { - short pos; - +static bool parseLDConfigTag (LDConfigParser& pars, char const* tag, str& val) +{ short pos; + // Try find the token and get its position if (!pars.findToken (pos, tag, 1)) return false; - + // Get the token after it and store it into val return pars.getToken (val, pos + 1); } // ============================================================================= // ----------------------------------------------------------------------------- -void parseLDConfig() { - File* f = openLDrawFile ("LDConfig.ldr", false); - - if (!f) { - critical (fmt (QObject::tr ("Unable to open LDConfig.ldr for parsing! (%1)"), +void parseLDConfig() +{ File* f = openLDrawFile ("LDConfig.ldr", false); + + if (!f) + { critical (fmt (QObject::tr ("Unable to open LDConfig.ldr for parsing! (%1)"), strerror (errno))); return; } - + // Read in the lines - for (str line : *f) { - if (line.length() == 0 || line[0] != '0') + for (str line : *f) + { if (line.length() == 0 || line[0] != '0') continue; // empty or illogical - + line.remove ('\r'); line.remove ('\n'); - + // Parse the line LDConfigParser pars (line, ' '); - + short code = 0, alpha = 255; str name, facename, edgename, valuestr; - + // Check 0 !COLOUR, parse the name if (!pars.tokenCompare (0, "0") || !pars.tokenCompare (1, "!COLOUR") || !pars.getToken (name, 2)) continue; - + // Replace underscores in the name with spaces for readability name.replace ("_", " "); - + // Get the CODE tag if (!parseLDConfigTag (pars, "CODE", valuestr)) continue; - + if (!isNumber (valuestr)) continue; // not a number - + // Ensure that the code is within [0 - 511] bool ok; code = valuestr.toShort (&ok); - + if (!ok || code < 0 || code >= 512) continue; - + // VALUE and EDGE tags if (!parseLDConfigTag (pars, "VALUE", facename) || !parseLDConfigTag (pars, "EDGE", edgename)) continue; - + // Ensure that our colors are correct QColor faceColor (facename), edgeColor (edgename); - + if (!faceColor.isValid() || !edgeColor.isValid()) continue; - + // Parse alpha if given. if (parseLDConfigTag (pars, "ALPHA", valuestr)) alpha = clamp<short> (valuestr.toShort(), 0, 255); - + LDColor* col = new LDColor; col->name = name; col->faceColor = faceColor; @@ -106,88 +106,89 @@ col->index = code; setColor (code, col); } - + delete f; } // ============================================================================= // ----------------------------------------------------------------------------- -LDConfigParser::LDConfigParser (str inText, char sep) { - m_tokens = container_cast<QStringList, List<str>> (inText.split (sep, QString::SkipEmptyParts)); +LDConfigParser::LDConfigParser (str inText, char sep) +{ m_tokens = container_cast<QStringList, List<str>> (inText.split (sep, QString::SkipEmptyParts)); m_pos = -1; } // ============================================================================= // ----------------------------------------------------------------------------- -bool LDConfigParser::atBeginning() { - return (m_pos == -1); +bool LDConfigParser::atBeginning() +{ return (m_pos == -1); } // ============================================================================= // ----------------------------------------------------------------------------- -bool LDConfigParser::atEnd() { - return (m_pos == (signed) m_tokens.size() - 1); +bool LDConfigParser::atEnd() +{ return (m_pos == (signed) m_tokens.size() - 1); } // ============================================================================= // ----------------------------------------------------------------------------- -bool LDConfigParser::getToken (str& val, const ushort pos) { - if (pos >= m_tokens.size()) +bool LDConfigParser::getToken (str& val, const ushort pos) +{ if (pos >= m_tokens.size()) return false; - + val = m_tokens[pos]; return true; } // ============================================================================= // ----------------------------------------------------------------------------- -bool LDConfigParser::next (str& val) { - return getToken (val, ++m_pos); +bool LDConfigParser::next (str& val) +{ return getToken (val, ++m_pos); } // ============================================================================= // ----------------------------------------------------------------------------- -bool LDConfigParser::peekNext (str& val) { - return getToken (val, m_pos + 1); +bool LDConfigParser::peekNext (str& val) +{ return getToken (val, m_pos + 1); } // ============================================================================= // ----------------------------------------------------------------------------- -bool LDConfigParser::findToken (short& result, char const* needle, short args) { - for (ushort i = 0; i < (m_tokens.size() - args); ++i) { - if (m_tokens[i] == needle) { - result = i; +bool LDConfigParser::findToken (short& result, char const* needle, short args) +{ for (ushort i = 0; i < (m_tokens.size() - args); ++i) + { if (m_tokens[i] == needle) + { result = i; return true; } } - + return false; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDConfigParser::rewind() { - m_pos = -1; +void LDConfigParser::rewind() +{ m_pos = -1; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDConfigParser::seek (short amount, bool rel) { - m_pos = (rel ? m_pos : 0) + amount; +void LDConfigParser::seek (short amount, bool rel) +{ m_pos = (rel ? m_pos : 0) + amount; } // ============================================================================= // ----------------------------------------------------------------------------- -size_t LDConfigParser::size() { - return m_tokens.size(); +size_t LDConfigParser::size() +{ return m_tokens.size(); } // ============================================================================= // ----------------------------------------------------------------------------- -bool LDConfigParser::tokenCompare (short inPos, const char* sOther) { - str tok; +bool LDConfigParser::tokenCompare (short inPos, const char* sOther) +{ str tok; + if (!getToken (tok, inPos)) return false; - + return (tok == sOther); -} \ No newline at end of file +}
--- a/src/ldconfig.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/ldconfig.h Thu Oct 03 20:56:20 2013 +0300 @@ -26,30 +26,30 @@ // // String parsing utility // ============================================================================= -class LDConfigParser { -public: - LDConfigParser (str inText, char sep); - - bool atEnd(); - bool atBeginning(); - bool next (str& val); - bool peekNext (str& val); - bool getToken (str& val, const ushort pos); - bool findToken (short& result, char const* needle, short args); - size_t size(); - void rewind(); - void seek (short amount, bool rel); - bool tokenCompare (short inPos, const char* sOther); - - str operator[] (const size_t idx) { - return m_tokens[idx]; - } - -private: - List<str> m_tokens; - short m_pos; +class LDConfigParser +{ public: + LDConfigParser (str inText, char sep); + + bool atEnd(); + bool atBeginning(); + bool next (str& val); + bool peekNext (str& val); + bool getToken (str& val, const ushort pos); + bool findToken (short& result, char const* needle, short args); + size_t size(); + void rewind(); + void seek (short amount, bool rel); + bool tokenCompare (short inPos, const char* sOther); + + str operator[] (const size_t idx) + { return m_tokens[idx]; + } + + private: + List<str> m_tokens; + short m_pos; }; void parseLDConfig(); -#endif // LDCONFIG_H \ No newline at end of file +#endif // LDCONFIG_H
--- a/src/ldtypes.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/ldtypes.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -42,14 +42,13 @@ m_file (null), qObjListEntry (null), m_glinit (false) -{ - // Determine ID +{ // Determine ID int32 id = 1; // 0 is invalid - - for (LDObject* obj : g_LDObjects) + +for (LDObject * obj : g_LDObjects) if (obj->id() >= id) id = obj->id() + 1; - + setID (id); g_LDObjects << this; } @@ -59,34 +58,34 @@ // actually called, for a subclass-less LDObject should never come into existance. // These exist only to satisfy the linker. // ----------------------------------------------------------------------------- -LDObject::Type LDObject::getType() const { - return LDObject::Unidentified; +LDObject::Type LDObject::getType() const +{ return LDObject::Unidentified; } -bool LDObject::hasMatrix() const { - return false; +bool LDObject::hasMatrix() const +{ return false; } -bool LDObject::isColored() const { - return false; +bool LDObject::isColored() const +{ return false; } -bool LDObject::isScemantic() const { - return false; +bool LDObject::isScemantic() const +{ return false; } -str LDObject::typeName() const { - return ""; +str LDObject::typeName() const +{ return ""; } -short LDObject::vertices() const { - return 0; +short LDObject::vertices() const +{ return 0; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDObject::setVertexCoord (int i, Axis ax, double value) { - vertex v = getVertex (i); +void LDObject::setVertexCoord (int i, Axis ax, double value) +{ vertex v = getVertex (i); v[ax] = value; setVertex (i, v); } @@ -95,14 +94,14 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDComment::raw() { - return fmt ("0 %1", text); +str LDComment::raw() +{ return fmt ("0 %1", text); } // ============================================================================= // ----------------------------------------------------------------------------- -str LDSubfile::raw() { - str val = fmt ("1 %1 %2 ", color(), position()); +str LDSubfile::raw() +{ str val = fmt ("1 %1 %2 ", color(), position()); val += transform().stringRep(); val += ' '; val += fileInfo()->name(); @@ -111,71 +110,71 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDLine::raw() { - str val = fmt ("2 %1", color()); - +str LDLine::raw() +{ str val = fmt ("2 %1", color()); + for (ushort i = 0; i < 2; ++i) val += fmt (" %1", getVertex (i)); - + return val; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDTriangle::raw() { - str val = fmt ("3 %1", color()); - +str LDTriangle::raw() +{ str val = fmt ("3 %1", color()); + for (ushort i = 0; i < 3; ++i) val += fmt (" %1", getVertex (i)); - + return val; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDQuad::raw() { - str val = fmt ("4 %1", color()); - +str LDQuad::raw() +{ str val = fmt ("4 %1", color()); + for (ushort i = 0; i < 4; ++i) val += fmt (" %1", getVertex (i)); - + return val; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDCndLine::raw() { - str val = fmt ("5 %1", color()); - +str LDCndLine::raw() +{ str val = fmt ("5 %1", color()); + // Add the coordinates for (ushort i = 0; i < 4; ++i) val += fmt (" %1", getVertex (i)); - + return val; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDError::raw() { - return contents; +str LDError::raw() +{ return contents; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDVertex::raw() { - return fmt ("0 !LDFORGE VERTEX %1 %2", color(), pos); +str LDVertex::raw() +{ return fmt ("0 !LDFORGE VERTEX %1 %2", color(), pos); } // ============================================================================= // ----------------------------------------------------------------------------- -str LDEmpty::raw() { - return ""; +str LDEmpty::raw() +{ return ""; } // ============================================================================= // ----------------------------------------------------------------------------- -const char* LDBFC::statements[] = { - "CERTIFY CCW", +const char* LDBFC::statements[] = +{ "CERTIFY CCW", "CCW", "CERTIFY CW", "CW", @@ -187,14 +186,14 @@ "NOCLIP", }; -str LDBFC::raw() { - return fmt ("0 BFC %1", LDBFC::statements[type]); +str LDBFC::raw() +{ return fmt ("0 BFC %1", LDBFC::statements[type]); } // ============================================================================= // ----------------------------------------------------------------------------- -List<LDTriangle*> LDQuad::splitToTriangles() { - // Create the two triangles based on this quadrilateral: +List<LDTriangle*> LDQuad::splitToTriangles() +{ // Create the two triangles based on this quadrilateral: // 0---3 0---3 3 // | | | / /| // | | ==> | / / | @@ -202,11 +201,11 @@ // 1---2 1 1---2 LDTriangle* tri1 = new LDTriangle (getVertex (0), getVertex (1), getVertex (3)); LDTriangle* tri2 = new LDTriangle (getVertex (1), getVertex (2), getVertex (3)); - + // The triangles also inherit the quad's color tri1->setColor (color()); tri2->setColor (color()); - + List<LDTriangle*> triangles; triangles << tri1; triangles << tri2; @@ -215,27 +214,29 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void LDObject::replace (LDObject* other) { - long idx = getIndex(); +void LDObject::replace (LDObject* other) +{ long idx = getIndex(); assert (idx != -1); - + // Replace the instance of the old object with the new object file()->setObject (idx, other); - + // Remove the old object delete this; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDObject::swap (LDObject* other) { - int i = 0; - for (LDObject* obj : file()->objects()) { - if (obj == this) +void LDObject::swap (LDObject* other) +{ int i = 0; + +for (LDObject * obj : file()->objects()) + { if (obj == this) file()->setObject (i, other); + elif (obj == other) - file()->setObject (i, this); - + file()->setObject (i, this); + ++i; } @@ -244,139 +245,140 @@ // ============================================================================= // ----------------------------------------------------------------------------- -LDLine::LDLine (vertex v1, vertex v2) { - setVertex (0, v1); +LDLine::LDLine (vertex v1, vertex v2) +{ setVertex (0, v1); setVertex (1, v2); } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject::~LDObject() { - // Remove this object from the selection array if it is there. +LDObject::~LDObject() +{ // Remove this object from the selection array if it is there. for (ulong i = 0; i < g_win->sel().size(); ++i) if (g_win->sel() [i] == this) g_win->sel().erase (i); - + // Delete the GL lists GL::deleteLists (this); - + // Remove this object from the list of LDObjects ulong pos = g_LDObjects.find (this); - + if (pos < g_LDObjects.size()) g_LDObjects.erase (pos); } // ============================================================================= // ----------------------------------------------------------------------------- -static void transformObject (LDObject* obj, matrix transform, vertex pos, short parentcolor) { - switch (obj->getType()) { - case LDObject::Line: - case LDObject::CndLine: - case LDObject::Triangle: - case LDObject::Quad: - for (short i = 0; i < obj->vertices(); ++i) { - vertex v = obj->getVertex (i); - v.transform (transform, pos); - obj->setVertex (i, v); - } +static void transformObject (LDObject* obj, matrix transform, vertex pos, short parentcolor) +{ switch (obj->getType()) + { case LDObject::Line: + case LDObject::CndLine: + case LDObject::Triangle: + case LDObject::Quad: - break; + for (short i = 0; i < obj->vertices(); ++i) + { vertex v = obj->getVertex (i); + v.transform (transform, pos); + obj->setVertex (i, v); + } - case LDObject::Subfile: - { - LDSubfile* ref = static_cast<LDSubfile*> (obj); + break; + + case LDObject::Subfile: + { LDSubfile* ref = static_cast<LDSubfile*> (obj); matrix newMatrix = transform * ref->transform(); vertex newpos = ref->position(); - + newpos.transform (transform, pos); ref->setPosition (newpos); ref->setTransform (newMatrix); } break; - default: - break; + default: + break; } - + if (obj->color() == maincolor) obj->setColor (parentcolor); } // ============================================================================= // ----------------------------------------------------------------------------- -List<LDObject*> LDSubfile::inlineContents (InlineFlags flags) { - List<LDObject*> objs = fileInfo()->inlineContents (flags); - +List<LDObject*> LDSubfile::inlineContents (InlineFlags flags) +{ List<LDObject*> objs = fileInfo()->inlineContents (flags); + // Transform the objects - for (LDObject* obj : objs) { - // Set the parent now so we know what inlined this. +for (LDObject * obj : objs) + { // Set the parent now so we know what inlined this. obj->setParent (this); transformObject (obj, transform(), position(), color()); } - + return objs; } // ============================================================================= // ----------------------------------------------------------------------------- -long LDObject::getIndex() const { +long LDObject::getIndex() const +{ #ifndef RELEASE assert (file() != null); #endif - + for (ulong i = 0; i < file()->numObjs(); ++i) if (file()->obj (i) == this) return i; - + return -1; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDObject::moveObjects (List<LDObject*> objs, const bool up) { - if (objs.size() == 0) +void LDObject::moveObjects (List<LDObject*> objs, const bool up) +{ if (objs.size() == 0) return; - + // If we move down, we need to iterate the array in reverse order. const long start = up ? 0 : (objs.size() - 1); const long end = up ? objs.size() : -1; const long incr = up ? 1 : -1; List<LDObject*> objsToCompile; LDFile* file = objs[0]->file(); - - for (long i = start; i != end; i += incr) { - LDObject* obj = objs[i]; - + + for (long i = start; i != end; i += incr) + { LDObject* obj = objs[i]; + const long idx = obj->getIndex(), - target = idx + (up ? -1 : 1); - - if ((up && idx == 0) || (!up && idx == (long) (file->objects().size() - 1))) { - // One of the objects hit the extrema. If this happens, this should be the first + target = idx + (up ? -1 : 1); + + if ( (up && idx == 0) || (!up && idx == (long) (file->objects().size() - 1))) + { // One of the objects hit the extrema. If this happens, this should be the first // object to be iterated on. Thus, nothing has changed yet and it's safe to just // abort the entire operation. assert (i == start); return; } - + objsToCompile << obj; objsToCompile << file->obj (target); - + obj->swap (file->obj (target)); } - + objsToCompile.makeUnique(); - + // The objects need to be recompiled, otherwise their pick lists are left with // the wrong index colors which messes up selection. - for (LDObject* obj : objsToCompile) +for (LDObject * obj : objsToCompile) g_win->R()->compileObject (obj); } // ============================================================================= // ----------------------------------------------------------------------------- -str LDObject::typeName (LDObject::Type type) { - LDObject* obj = LDObject::getDefault (type); +str LDObject::typeName (LDObject::Type type) +{ LDObject* obj = LDObject::getDefault (type); str name = obj->typeName(); delete obj; return name; @@ -384,48 +386,48 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str LDObject::objectListContents (const List<LDObject*>& objs) { - bool firstDetails = true; +str LDObject::objectListContents (const List<LDObject*>& objs) +{ bool firstDetails = true; str text = ""; - + if (objs.size() == 0) return "nothing"; // :) - - for (long i = 0; i < LDObject::NumTypes; ++i) { - LDObject::Type objType = (LDObject::Type) i; + + for (long i = 0; i < LDObject::NumTypes; ++i) + { LDObject::Type objType = (LDObject::Type) i; ulong objCount = 0; - - for (LDObject* obj : objs) + + for (LDObject * obj : objs) if (obj->getType() == objType) objCount++; - + if (objCount == 0) continue; - + if (!firstDetails) text += ", "; - + str noun = fmt ("%1%2", typeName (objType), plural (objCount)); - + // Plural of "vertex" is "vertices". Stupid English. if (objType == LDObject::Vertex && objCount != 1) noun = "vertices"; - + text += fmt ("%1 %2", objCount, noun); firstDetails = false; } - + return text; } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject* LDObject::topLevelParent() { - if (!parent()) +LDObject* LDObject::topLevelParent() +{ if (!parent()) return this; - + LDObject* it = this; - + while (it->parent()) it = it->parent(); @@ -434,73 +436,83 @@ // ============================================================================= // ----------------------------------------------------------------------------- -LDObject* LDObject::next() const { - long idx = getIndex(); +LDObject* LDObject::next() const +{ long idx = getIndex(); assert (idx != -1); - + if (idx == (long) file()->numObjs() - 1) return null; - + return file()->obj (idx + 1); } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject* LDObject::prev() const { - long idx = getIndex(); +LDObject* LDObject::prev() const +{ long idx = getIndex(); assert (idx != -1); - + if (idx == 0) return null; - + return file()->obj (idx - 1); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDObject::move (vertex vect) { (void) vect; } -void LDEmpty::move (vertex vect) { (void) vect; } -void LDBFC::move (vertex vect) { (void) vect; } -void LDComment::move (vertex vect) { (void) vect; } -void LDError::move (vertex vect) { (void) vect; } - -// ============================================================================= -// ----------------------------------------------------------------------------- -void LDVertex::move (vertex vect) { - pos += vect; +void LDObject::move (vertex vect) +{ (void) vect; +} +void LDEmpty::move (vertex vect) +{ (void) vect; +} +void LDBFC::move (vertex vect) +{ (void) vect; +} +void LDComment::move (vertex vect) +{ (void) vect; +} +void LDError::move (vertex vect) +{ (void) vect; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDSubfile::move (vertex vect) { - setPosition (position() + vect); +void LDVertex::move (vertex vect) +{ pos += vect; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDLine::move (vertex vect) { - for (short i = 0; i < 2; ++i) +void LDSubfile::move (vertex vect) +{ setPosition (position() + vect); +} + +// ============================================================================= +// ----------------------------------------------------------------------------- +void LDLine::move (vertex vect) +{ for (short i = 0; i < 2; ++i) setVertex (i, getVertex (i) + vect); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDTriangle::move (vertex vect) { - for (short i = 0; i < 3; ++i) +void LDTriangle::move (vertex vect) +{ for (short i = 0; i < 3; ++i) setVertex (i, getVertex (i) + vect); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDQuad::move (vertex vect) { - for (short i = 0; i < 4; ++i) +void LDQuad::move (vertex vect) +{ for (short i = 0; i < 4; ++i) setVertex (i, getVertex (i) + vect); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDCndLine::move (vertex vect) { - for (short i = 0; i < 4; ++i) +void LDCndLine::move (vertex vect) +{ for (short i = 0; i < 4; ++i) setVertex (i, getVertex (i) + vect); } @@ -510,8 +522,8 @@ if (type == LDObject::N) \ return new LD##N; -LDObject* LDObject::getDefault (const LDObject::Type type) { - CHECK_FOR_OBJ (Comment) +LDObject* LDObject::getDefault (const LDObject::Type type) +{ CHECK_FOR_OBJ (Comment) CHECK_FOR_OBJ (BFC) CHECK_FOR_OBJ (Line) CHECK_FOR_OBJ (CndLine) @@ -536,8 +548,8 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void LDTriangle::invert() { - // Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1. +void LDTriangle::invert() +{ // Triangle goes 0 -> 1 -> 2, reversed: 0 -> 2 -> 1. // Thus, we swap 1 and 2. vertex tmp = getVertex (1); setVertex (1, getVertex (2)); @@ -548,8 +560,8 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void LDQuad::invert() { - // Quad: 0 -> 1 -> 2 -> 3 +void LDQuad::invert() +{ // Quad: 0 -> 1 -> 2 -> 3 // rev: 0 -> 3 -> 2 -> 1 // Thus, we swap 1 and 3. vertex tmp = getVertex (1); @@ -559,26 +571,26 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void LDSubfile::invert() { - // Subfiles are inverted when they're prefixed with +void LDSubfile::invert() +{ // Subfiles are inverted when they're prefixed with // a BFC INVERTNEXT statement. Thus we need to toggle this status. // For flat primitives it's sufficient that the determinant is // flipped but I don't have a method for checking flatness yet. // Food for thought... - + ulong idx = getIndex(); - - if (idx > 0) { - LDBFC* bfc = dynamic_cast<LDBFC*> (prev()); - - if (bfc && bfc->type == LDBFC::InvertNext) { - // This is prefixed with an invertnext, thus remove it. + + if (idx > 0) + { LDBFC* bfc = dynamic_cast<LDBFC*> (prev()); + + if (bfc && bfc->type == LDBFC::InvertNext) + { // This is prefixed with an invertnext, thus remove it. file()->forgetObject (bfc); delete bfc; return; } } - + // Not inverted, thus prefix it with a new invertnext. LDBFC* bfc = new LDBFC (LDBFC::InvertNext); file()->insertObj (idx, bfc); @@ -586,57 +598,57 @@ // ============================================================================= // ----------------------------------------------------------------------------- -static void invertLine (LDObject* line) { - // For lines, we swap the vertices. I don't think that a +static void invertLine (LDObject* line) +{ // For lines, we swap the vertices. I don't think that a // cond-line's control points need to be swapped, do they? vertex tmp = line->getVertex (0); line->setVertex (0, line->getVertex (1)); line->setVertex (1, tmp); } -void LDLine::invert() { - invertLine (this); +void LDLine::invert() +{ invertLine (this); } -void LDCndLine::invert() { - invertLine (this); +void LDCndLine::invert() +{ invertLine (this); } void LDVertex::invert() {} // ============================================================================= // ----------------------------------------------------------------------------- -LDLine* LDCndLine::demote() { - LDLine* repl = new LDLine; - +LDLine* LDCndLine::demote() +{ LDLine* repl = new LDLine; + for (int i = 0; i < repl->vertices(); ++i) repl->setVertex (i, getVertex (i)); - + repl->setColor (color()); - + replace (repl); return repl; } // ============================================================================= // ----------------------------------------------------------------------------- -LDObject* LDObject::fromID (int id) { - for (LDObject* obj : g_LDObjects) +LDObject* LDObject::fromID (int id) +{ for (LDObject * obj : g_LDObjects) if (obj->id() == id) return obj; - + return null; } // ============================================================================= // ----------------------------------------------------------------------------- -str LDOverlay::raw() { - return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", - filename(), camera(), x(), y(), width(), height()); +str LDOverlay::raw() +{ return fmt ("0 !LDFORGE OVERLAY %1 %2 %3 %4 %5 %6", + filename(), camera(), x(), y(), width(), height()); } -void LDOverlay::move (vertex vect) { - Q_UNUSED (vect) +void LDOverlay::move (vertex vect) +{ Q_UNUSED (vect) } void LDOverlay::invert() {} @@ -646,55 +658,56 @@ // It takes care of history management so we can capture low-level changes, this // makes history stuff work out of the box. // ----------------------------------------------------------------------------- -template<class T> void changeProperty (LDObject* obj, T* ptr, const T& val) { - long idx; - - if (obj->file() && (idx = obj->getIndex()) != -1) { - str before = obj->raw(); +template<class T> void changeProperty (LDObject* obj, T* ptr, const T& val) +{ long idx; + + if (obj->file() && (idx = obj->getIndex()) != -1) + { str before = obj->raw(); *ptr = val; str after = obj->raw(); - + obj->file()->addToHistory (new EditHistory (idx, before, after)); - } else + } + else *ptr = val; } // ============================================================================= // ----------------------------------------------------------------------------- -READ_ACCESSOR (short, LDObject::color) { - return m_color; +READ_ACCESSOR (short, LDObject::color) +{ return m_color; } -SET_ACCESSOR (short, LDObject::setColor) { - changeProperty (this, &m_color, val); +SET_ACCESSOR (short, LDObject::setColor) +{ changeProperty (this, &m_color, val); } // ============================================================================= // ----------------------------------------------------------------------------- -const vertex& LDObject::getVertex (int i) const { - return m_coords[i]; +const vertex& LDObject::getVertex (int i) const +{ return m_coords[i]; } -void LDObject::setVertex (int i, const vertex& vert) { - changeProperty (this, &m_coords[i], vert); +void LDObject::setVertex (int i, const vertex& vert) +{ changeProperty (this, &m_coords[i], vert); } // ============================================================================= // ----------------------------------------------------------------------------- -READ_ACCESSOR (vertex, LDMatrixObject::position) { - return m_position; +READ_ACCESSOR (vertex, LDMatrixObject::position) +{ return m_position; } -SET_ACCESSOR (vertex, LDMatrixObject::setPosition) { - changeProperty (linkPointer(), &m_position, val); +SET_ACCESSOR (vertex, LDMatrixObject::setPosition) +{ changeProperty (linkPointer(), &m_position, val); } // ============================================================================= // ----------------------------------------------------------------------------- -READ_ACCESSOR (matrix, LDMatrixObject::transform) { - return m_transform; +READ_ACCESSOR (matrix, LDMatrixObject::transform) +{ return m_transform; } -SET_ACCESSOR (matrix, LDMatrixObject::setTransform) { - changeProperty (linkPointer(), &m_transform, val); -} \ No newline at end of file +SET_ACCESSOR (matrix, LDMatrixObject::setTransform) +{ changeProperty (linkPointer(), &m_transform, val); +}
--- a/src/ldtypes.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/ldtypes.h Thu Oct 03 20:56:20 2013 +0300 @@ -61,74 +61,78 @@ // which is a token of the object's type. The object can be casted into // sub-classes based on this enumerator. // ============================================================================= -class LDObject { - PROPERTY (bool, hidden, setHidden) +class LDObject +{ PROPERTY (bool, hidden, setHidden) PROPERTY (bool, selected, setSelected) PROPERTY (LDObject*, parent, setParent) PROPERTY (LDFile*, file, setFile) READ_PROPERTY (int32, id, setID) DECLARE_PROPERTY (short, color, setColor) -public: - // Object type codes. Codes are sorted in order of significance. - enum Type { - Subfile, // Object represents a sub-file reference - Quad, // Object represents a quadrilateral - Triangle, // Object represents a triangle - Line, // Object represents a line - CndLine, // Object represents a conditional line - Vertex, // Object is a vertex, LDForge extension object - BFC, // Object represents a BFC statement - Overlay, // Object contains meta-info about an overlay image. - Comment, // Object represents a comment - Error, // Object is the result of failed parsing - Empty, // Object represents an empty line - Unidentified, // Object is an uninitialized (SHOULD NEVER HAPPEN) - NumTypes // Amount of object types - }; + public: + // Object type codes. Codes are sorted in order of significance. + enum Type + { Subfile, // Object represents a sub-file reference + Quad, // Object represents a quadrilateral + Triangle, // Object represents a triangle + Line, // Object represents a line + CndLine, // Object represents a conditional line + Vertex, // Object is a vertex, LDForge extension object + BFC, // Object represents a BFC statement + Overlay, // Object contains meta-info about an overlay image. + Comment, // Object represents a comment + Error, // Object is the result of failed parsing + Empty, // Object represents an empty line + Unidentified, // Object is an uninitialized (SHOULD NEVER HAPPEN) + NumTypes // Amount of object types + }; + + LDObject(); + virtual ~LDObject(); - LDObject(); - virtual ~LDObject(); - - virtual LDObject* clone() {return 0;} // Creates a new LDObject identical to this one. - long getIndex() const; // Index (i.e. line number) of this object - virtual LDObject::Type getType() const; // Type enumerator of this object - const vertex& getVertex (int i) const; // Get a vertex by index - virtual bool hasMatrix() const; // Does this object have a matrix and position? (see LDMatrixObject) - virtual void invert(); // Inverts this object (winding is reversed) - virtual bool isColored() const; // Is this object colored? - virtual bool isScemantic() const; // Does this object have meaning in the part model? - virtual void move (vertex vect); // Moves this object using the given vertex as a movement List - LDObject* next() const; // Object after this in the current file - LDObject* prev() const; // Object prior to this in the current file - virtual str raw() { return ""; } // This object as LDraw code - void replace (LDObject* other); // Replace this LDObject with another LDObject. Object is deleted in the process. - void setVertex (int i, const vertex& vert); // Set a vertex to the given value - void setVertexCoord (int i, Axis ax, double value); // Set a single coordinate of a vertex - void swap (LDObject* other); // Swap this object with another. - LDObject* topLevelParent(); // What object in the current file ultimately references this? - virtual str typeName() const; // Type name of this object - virtual short vertices() const; // Number of vertices this object has - - static str typeName (LDObject::Type type); // Get type name by enumerator - static LDObject* getDefault (const LDObject::Type type); // Returns a sample object by the given enumerator - static void moveObjects (List<LDObject*> objs, const bool up); // TODO: move this to LDFile? - static str objectListContents (const List<LDObject*>& objs); // Get a description of a list of LDObjects - static LDObject* fromID (int id); - - // TODO: make these private! - // OpenGL list for this object - uint glLists[4]; - - // Object list entry for this object - QListWidgetItem* qObjListEntry; + virtual LDObject* clone() + { return 0; // Creates a new LDObject identical to this one. + } + long getIndex() const; // Index (i.e. line number) of this object + virtual LDObject::Type getType() const; // Type enumerator of this object + const vertex& getVertex (int i) const; // Get a vertex by index + virtual bool hasMatrix() const; // Does this object have a matrix and position? (see LDMatrixObject) + virtual void invert(); // Inverts this object (winding is reversed) + virtual bool isColored() const; // Is this object colored? + virtual bool isScemantic() const; // Does this object have meaning in the part model? + virtual void move (vertex vect); // Moves this object using the given vertex as a movement List + LDObject* next() const; // Object after this in the current file + LDObject* prev() const; // Object prior to this in the current file + virtual str raw() + { return ""; // This object as LDraw code + } + void replace (LDObject* other); // Replace this LDObject with another LDObject. Object is deleted in the process. + void setVertex (int i, const vertex& vert); // Set a vertex to the given value + void setVertexCoord (int i, Axis ax, double value); // Set a single coordinate of a vertex + void swap (LDObject* other); // Swap this object with another. + LDObject* topLevelParent(); // What object in the current file ultimately references this? + virtual str typeName() const; // Type name of this object + virtual short vertices() const; // Number of vertices this object has -protected: - bool m_glinit; - friend class GLRenderer; + static str typeName (LDObject::Type type); // Get type name by enumerator + static LDObject* getDefault (const LDObject::Type type); // Returns a sample object by the given enumerator + static void moveObjects (List<LDObject*> objs, const bool up); // TODO: move this to LDFile? + static str objectListContents (const List<LDObject*>& objs); // Get a description of a list of LDObjects + static LDObject* fromID (int id); + + // TODO: make these private! + // OpenGL list for this object + uint glLists[4]; -private: - vertex m_coords[4]; + // Object list entry for this object + QListWidgetItem* qObjListEntry; + + protected: + bool m_glinit; + friend class GLRenderer; + + private: + vertex m_coords[4]; }; // ============================================================================= @@ -146,23 +150,23 @@ // matrix as well. Even though right now only LDSubfile uses this, I'm keeping // this class distinct in case I get new extension ideas. :) // ============================================================================= -class LDMatrixObject { - DECLARE_PROPERTY (matrix, transform, setTransform) +class LDMatrixObject +{ DECLARE_PROPERTY (matrix, transform, setTransform) DECLARE_PROPERTY (vertex, position, setPosition) PROPERTY (LDObject*, linkPointer, setLinkPointer) -public: - LDMatrixObject() {} - LDMatrixObject (const matrix& transform, const vertex& pos) : - PROP_NAME (transform) (transform), PROP_NAME (position) (pos) {} + public: + LDMatrixObject() {} + LDMatrixObject (const matrix& transform, const vertex& pos) : + PROP_NAME (transform) (transform), PROP_NAME (position) (pos) {} - const double& setCoordinate (const Axis ax, double value) { - vertex v = position(); - v[ax] = value; - setPosition (v); + const double& setCoordinate (const Axis ax, double value) + { vertex v = position(); + v[ax] = value; + setPosition (v); - return position() [ax]; - } + return position() [ax]; + } }; // ============================================================================= @@ -173,8 +177,8 @@ // allowing garbage lines be debugged and corrected within LDForge. The member // zContent contains the contents of the unparsable line. // ============================================================================= -class LDError : public LDObject { - LDOBJ (Error) +class LDError : public LDObject +{ LDOBJ (Error) LDOBJ_NAME (error) LDOBJ_VERTICES (0) LDOBJ_UNCOLORED @@ -182,15 +186,15 @@ LDOBJ_NO_MATRIX PROPERTY (str, fileRef, setFileRef) -public: - LDError(); - LDError (str contents, str reason) : contents (contents), reason (reason) {} + public: + LDError(); + LDError (str contents, str reason) : contents (contents), reason (reason) {} - // Content of this unknown line - str contents; + // Content of this unknown line + str contents; - // Why is this gibberish? - str reason; + // Why is this gibberish? + str reason; }; // ============================================================================= @@ -198,8 +202,8 @@ // // Represents an empty line in the LDraw code file. // ============================================================================= -class LDEmpty : public LDObject { - LDOBJ (Empty) +class LDEmpty : public LDObject +{ LDOBJ (Empty) LDOBJ_VERTICES (0) LDOBJ_UNCOLORED LDOBJ_NON_SCEMANTIC @@ -212,19 +216,19 @@ // Represents a code-0 comment in the LDraw code file. Member text contains // the text of the comment. // ============================================================================= -class LDComment : public LDObject { - LDOBJ (Comment) +class LDComment : public LDObject +{ LDOBJ (Comment) LDOBJ_NAME (comment) LDOBJ_VERTICES (0) LDOBJ_UNCOLORED LDOBJ_NON_SCEMANTIC LDOBJ_NO_MATRIX -public: - LDComment() {} - LDComment (str text) : text (text) {} + public: + LDComment() {} + LDComment (str text) : text (text) {} - str text; // The text of this comment + str text; // The text of this comment }; // ============================================================================= @@ -233,37 +237,37 @@ // Represents a 0 BFC statement in the LDraw code. eStatement contains the type // of this statement. // ============================================================================= -class LDBFC : public LDObject { -public: - enum Type { - CertifyCCW, - CCW, - CertifyCW, - CW, - NoCertify, - InvertNext, - Clip, - ClipCCW, - ClipCW, - NoClip, - NumStatements - }; - - LDOBJ (BFC) - LDOBJ_NAME (bfc) - LDOBJ_VERTICES (0) - LDOBJ_UNCOLORED - LDOBJ_CUSTOM_SCEMANTIC { return (type == InvertNext); } - LDOBJ_NO_MATRIX - -public: - LDBFC() {} - LDBFC (const LDBFC::Type type) : type (type) {} +class LDBFC : public LDObject +{ public: + enum Type + { CertifyCCW, + CCW, + CertifyCW, + CW, + NoCertify, + InvertNext, + Clip, + ClipCCW, + ClipCW, + NoClip, + NumStatements + }; - // Statement strings - static const char* statements[]; + LDOBJ (BFC) + LDOBJ_NAME (bfc) + LDOBJ_VERTICES (0) + LDOBJ_UNCOLORED + LDOBJ_CUSTOM_SCEMANTIC { return (type == InvertNext); } + LDOBJ_NO_MATRIX - Type type; + public: + LDBFC() {} + LDBFC (const LDBFC::Type type) : type (type) {} + + // Statement strings + static const char* statements[]; + + Type type; }; // ============================================================================= @@ -271,8 +275,8 @@ // // Represents a single code-1 subfile reference. // ============================================================================= -class LDSubfile : public LDObject, public LDMatrixObject { - LDOBJ (Subfile) +class LDSubfile : public LDObject, public LDMatrixObject +{ LDOBJ (Subfile) LDOBJ_NAME (subfile) LDOBJ_VERTICES (0) LDOBJ_COLORED @@ -280,24 +284,24 @@ LDOBJ_HAS_MATRIX PROPERTY (LDFile*, fileInfo, setFileInfo) -public: - enum InlineFlag { - DeepInline = (1 << 0), - CacheInline = (1 << 1), - RendererInline = (1 << 2), - - DeepCacheInline = DeepInline | CacheInline, - }; - - Q_DECLARE_FLAGS (InlineFlags, InlineFlag) - - LDSubfile() { - setLinkPointer (this); - } - - // Inlines this subfile. Note that return type is an array of heap-allocated - // LDObject-clones, they must be deleted one way or another. - List<LDObject*> inlineContents (InlineFlags flags); + public: + enum InlineFlag + { DeepInline = (1 << 0), + CacheInline = (1 << 1), + RendererInline = (1 << 2), + + DeepCacheInline = DeepInline | CacheInline, + }; + + Q_DECLARE_FLAGS (InlineFlags, InlineFlag) + + LDSubfile() + { setLinkPointer (this); + } + + // Inlines this subfile. Note that return type is an array of heap-allocated + // LDObject-clones, they must be deleted one way or another. + List<LDObject*> inlineContents (InlineFlags flags); }; Q_DECLARE_OPERATORS_FOR_FLAGS (LDSubfile::InlineFlags) @@ -309,17 +313,17 @@ // points of the line. The line is colored with dColor unless uncolored mode is // set. // ============================================================================= -class LDLine : public LDObject { - LDOBJ (Line) +class LDLine : public LDObject +{ LDOBJ (Line) LDOBJ_NAME (line) LDOBJ_VERTICES (2) LDOBJ_COLORED LDOBJ_SCEMANTIC LDOBJ_NO_MATRIX -public: - LDLine() {} - LDLine (vertex v1, vertex v2); + public: + LDLine() {} + LDLine (vertex v1, vertex v2); }; // ============================================================================= @@ -328,17 +332,17 @@ // Represents a single code-5 conditional line. The end-points v0 and v1 are // inherited from LDLine, c0 and c1 are the control points of this line. // ============================================================================= -class LDCndLine : public LDLine { - LDOBJ (CndLine) +class LDCndLine : public LDLine +{ LDOBJ (CndLine) LDOBJ_NAME (condline) LDOBJ_VERTICES (4) LDOBJ_COLORED LDOBJ_SCEMANTIC LDOBJ_NO_MATRIX -public: - LDCndLine() {} - LDLine* demote(); + public: + LDCndLine() {} + LDLine* demote(); }; // ============================================================================= @@ -348,21 +352,21 @@ // and v2 contain the end-points of this triangle. dColor is the color the // triangle is colored with. // ============================================================================= -class LDTriangle : public LDObject { - LDOBJ (Triangle) +class LDTriangle : public LDObject +{ LDOBJ (Triangle) LDOBJ_NAME (triangle) LDOBJ_VERTICES (3) LDOBJ_COLORED LDOBJ_SCEMANTIC LDOBJ_NO_MATRIX -public: - LDTriangle() {} - LDTriangle (vertex v0, vertex v1, vertex v2) { - setVertex (0, v0); - setVertex (1, v1); - setVertex (2, v2); - } + public: + LDTriangle() {} + LDTriangle (vertex v0, vertex v1, vertex v2) + { setVertex (0, v0); + setVertex (1, v1); + setVertex (2, v2); + } }; // ============================================================================= @@ -371,19 +375,19 @@ // Represents a single code-4 quadrilateral. v0, v1, v2 and v3 are the end points // of the quad, dColor is the color used for the quad. // ============================================================================= -class LDQuad : public LDObject { -public: - LDOBJ (Quad) +class LDQuad : public LDObject +{ LDOBJ (Quad) LDOBJ_NAME (quad) LDOBJ_VERTICES (4) LDOBJ_COLORED LDOBJ_SCEMANTIC LDOBJ_NO_MATRIX - LDQuad() {} + public: + LDQuad() {} - // Split this quad into two triangles (note: heap-allocated) - List<LDTriangle*> splitToTriangles(); + // Split this quad into two triangles (note: heap-allocated) + List<LDTriangle*> splitToTriangles(); }; // ============================================================================= @@ -394,18 +398,18 @@ // with. Vertices are a part authoring tool and they should not appear in // finished parts. // ============================================================================= -class LDVertex : public LDObject { -public: - LDOBJ (Vertex) +class LDVertex : public LDObject +{ LDOBJ (Vertex) LDOBJ_NAME (vertex) LDOBJ_VERTICES (0) // TODO: move pos to vaCoords[0] LDOBJ_COLORED LDOBJ_NON_SCEMANTIC LDOBJ_NO_MATRIX - LDVertex() {} + public: + LDVertex() {} - vertex pos; + vertex pos; }; // ============================================================================= @@ -414,8 +418,8 @@ // Overlay image meta, stored in the header of parts so as to preserve overlay // information. // ============================================================================= -class LDOverlay : public LDObject { - LDOBJ (Overlay) +class LDOverlay : public LDObject +{ LDOBJ (Overlay) LDOBJ_NAME (overlay) LDOBJ_VERTICES (0) LDOBJ_UNCOLORED @@ -431,8 +435,8 @@ // Other common LDraw stuff static const str CALicense = "!LICENSE Redistributable under CCAL version 2.0 : see CAreadme.txt", - NonCALicense = "!LICENSE Not redistributable : see NonCAreadme.txt"; + NonCALicense = "!LICENSE Not redistributable : see NonCAreadme.txt"; static const short lores = 16; static const short hires = 48; -#endif // LDTYPES_H \ No newline at end of file +#endif // LDTYPES_H
--- a/src/main.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/main.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -32,92 +32,96 @@ #include "configDialog.h" List<LDFile*> g_loadedFiles; -ForgeWindow* g_win = null; +ForgeWindow* g_win = null; const QApplication* g_app = null; File g_file_stdout (stdout, File::Write); File g_file_stderr (stderr, File::Write); static str g_versionString, g_fullVersionString; const vertex g_origin (0.0f, 0.0f, 0.0f); -const matrix g_identity ({1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}); +const matrix g_identity ( {1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}); cfg (Bool, firststart, true); // ============================================================================= // ----------------------------------------------------------------------------- -int main (int argc, char* argv[]) { - QApplication app (argc, argv); +int main (int argc, char* argv[]) +{ QApplication app (argc, argv); app.setOrganizationName (APPNAME); app.setApplicationName (APPNAME); - + g_app = &app; LDFile::setCurrent (null); - + // Load or create the configuration - if (!Config::load()) { - print ("Creating configuration file...\n"); + if (!Config::load()) + { print ("Creating configuration file...\n"); + if (Config::save()) print ("Configuration file successfully created.\n"); else print ("failed to create configuration file!\n"); } - + LDPaths::initPaths(); initColors(); loadLogoedStuds(); - + ForgeWindow* win = new ForgeWindow; newFile(); win->show(); - + // If this is the first start, get the user to configuration. Especially point // them to the profile tab, it's the most important form to fill in. - if (firststart) { - (new ConfigDialog (ConfigDialog::ProfileTab))->exec(); + if (firststart) + { (new ConfigDialog (ConfigDialog::ProfileTab))->exec(); firststart = false; Config::save(); } - + loadPrimitives(); return app.exec(); } // ============================================================================= // ----------------------------------------------------------------------------- -void doPrint (File& f, initlist<StringFormatArg> args) { - str msg = DoFormat (args); +void doPrint (File& f, initlist<StringFormatArg> args) +{ str msg = DoFormat (args); f.write (msg.toUtf8()); f.flush(); } // ============================================================================= // ----------------------------------------------------------------------------- -void doPrint (FILE* fp, initlist<StringFormatArg> args) { - if (fp == stdout) +void doPrint (FILE* fp, initlist<StringFormatArg> args) +{ if (fp == stdout) doPrint (g_file_stdout, args); + elif (fp == stderr) - doPrint (g_file_stderr, args); + doPrint (g_file_stderr, args); else fatal ("unknown FILE* argument"); } // ============================================================================= // ----------------------------------------------------------------------------- -str versionString() { - if (g_versionString.length() == 0) { +str versionString() +{ if (g_versionString.length() == 0) + { #if VERSION_PATCH == 0 g_versionString = fmt ("%1.%2", VERSION_MAJOR, VERSION_MINOR); #else g_versionString = fmt ("%1.%2.%3", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH); #endif // VERSION_PATCH } - + return g_versionString; } // ============================================================================= // ----------------------------------------------------------------------------- -str versionMoniker() { +str versionMoniker() +{ #if BUILD_ID == BUILD_INTERNAL return "Internal"; #elif BUILD_ID == BUILD_ALPHA @@ -133,15 +137,15 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str fullVersionString() { - return fmt ("v%1 %2", versionString(), versionMoniker()); +str fullVersionString() +{ return fmt ("v%1 %2", versionString(), versionMoniker()); } // ============================================================================= // ----------------------------------------------------------------------------- -static void bombBox (str msg) { - msg.replace ("\n", "<br />"); - +static void bombBox (str msg) +{ msg.replace ("\n", "<br />"); + QMessageBox box (null); const QMessageBox::StandardButton btn = QMessageBox::Close; box.setWindowTitle ("Fatal Error"); @@ -156,22 +160,23 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void assertionFailure (const char* file, const ulong line, const char* funcname, const char* expr) { - str errmsg = fmt ("File: %1\nLine: %2:\nFunction %3:\n\nAssertion `%4' failed", - file, line, funcname, expr); - +void assertionFailure (const char* file, const ulong line, const char* funcname, const char* expr) +{ str errmsg = fmt ("File: %1\nLine: %2:\nFunction %3:\n\nAssertion `%4' failed", + file, line, funcname, expr); + #if BUILD_ID == BUILD_INTERNAL errmsg += ", aborting."; #else errmsg += "."; #endif - + printf ("%s\n", errmsg.toStdString().c_str()); - + #if BUILD_ID == BUILD_INTERNAL + if (g_win) g_win->deleteLater(); - + bombBox (errmsg); abort(); #endif @@ -179,15 +184,15 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void fatalError (const char* file, const ulong line, const char* funcname, str msg) { - str errmsg = fmt ("Aborting over a call to fatal():\nFile: %1\nLine: %2\nFunction: %3\n\n%4", - file, line, funcname, msg); - +void fatalError (const char* file, const ulong line, const char* funcname, str msg) +{ str errmsg = fmt ("Aborting over a call to fatal():\nFile: %1\nLine: %2\nFunction: %3\n\n%4", + file, line, funcname, msg); + print ("%1\n", errmsg); - + if (g_win) g_win->deleteLater(); - + bombBox (errmsg); abort(); -} \ No newline at end of file +}
--- a/src/messagelog.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/messagelog.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -21,6 +21,7 @@ #include "messagelog.h" #include "gldraw.h" #include "gui.h" +#include "moc_messagelog.cpp" static const unsigned int g_maxMessages = 5; static const int g_expiry = 5; @@ -29,8 +30,8 @@ // ============================================================================= // ----------------------------------------------------------------------------- MessageManager::MessageManager (QObject* parent) : - QObject (parent) { - m_ticker = new QTimer; + QObject (parent) +{ m_ticker = new QTimer; m_ticker->start (100); connect (m_ticker, SIGNAL (timeout()), this, SLOT (tick())); } @@ -38,45 +39,45 @@ // ============================================================================= // ----------------------------------------------------------------------------- MessageManager::Line::Line (str text) : - text (text), - alpha (1.0f), - expiry (QDateTime::currentDateTime().addSecs (g_expiry)) {} + text (text), + alpha (1.0f), + expiry (QDateTime::currentDateTime().addSecs (g_expiry)) {} // ============================================================================= // Check this line's expiry and update alpha accordingly. Returns true if the // line is to still stick around, false if it expired. 'changed' is updated to // whether the line has somehow changed since the last update. // ----------------------------------------------------------------------------- -bool MessageManager::Line::update (bool& changed) { - changed = false; +bool MessageManager::Line::update (bool& changed) +{ changed = false; QDateTime now = QDateTime::currentDateTime(); int msec = now.msecsTo (expiry); - - if (now >= expiry) { - // Message line has expired + + if (now >= expiry) + { // Message line has expired changed = true; return false; } - - if (msec <= g_fadeTime) { - // Message line has not expired but is fading out - alpha = ((float) msec) / g_fadeTime; + + if (msec <= g_fadeTime) + { // Message line has not expired but is fading out + alpha = ( (float) msec) / g_fadeTime; changed = true; } - + return true; } // ============================================================================= // Add a line to the message manager. // ----------------------------------------------------------------------------- -void MessageManager::addLine (str line) { - // If there's too many entries, pop the excess out +void MessageManager::addLine (str line) +{ // If there's too many entries, pop the excess out while (m_lines.size() >= g_maxMessages) m_lines.erase (0); - + m_lines << Line (line); - + // Update the renderer view if (renderer()) renderer()->update(); @@ -86,40 +87,39 @@ // Ticks the message manager. All lines are ticked and the renderer scene is // redrawn if something changed. // ----------------------------------------------------------------------------- -void MessageManager::tick() { - if (m_lines.size() == 0) +void MessageManager::tick() +{ if (m_lines.size() == 0) return; - + bool changed = false; - - for (uint i = 0; i < m_lines.size(); ++i) { - bool lineChanged; - + + for (uint i = 0; i < m_lines.size(); ++i) + { bool lineChanged; + if (!m_lines[i].update (lineChanged)) m_lines.erase (i--); - + changed |= lineChanged; } - + if (changed && renderer()) renderer()->update(); } // ============================================================================= // ----------------------------------------------------------------------------- -const List<MessageManager::Line>& MessageManager::getLines() const { - return m_lines; +const List<MessageManager::Line>& MessageManager::getLines() const +{ return m_lines; } // ============================================================================= // log() interface - format the argument list and add the resulting string to // the main message manager. // ----------------------------------------------------------------------------- -void DoLog (std::initializer_list<StringFormatArg> args) { - const str msg = DoFormat (args); +void DoLog (std::initializer_list<StringFormatArg> args) +{ const str msg = DoFormat (args); g_win->addMessage (msg); - + // Also print it to stdout print ("%1\n", msg); } -#include "moc_messagelog.cpp"
--- a/src/messagelog.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/messagelog.h Thu Oct 03 20:56:20 2013 +0300 @@ -37,32 +37,32 @@ * their expiry. If the message manager's lines change, the renderer undergoes * repainting. */ -class MessageManager : public QObject { - Q_OBJECT - PROPERTY (GLRenderer*, renderer, setRenderer) - -public: - // Single line of the message log. - class Line { +class MessageManager : public QObject +{ Q_OBJECT + PROPERTY (GLRenderer*, renderer, setRenderer) + public: - Line (str text); - bool update (bool& changed); - - str text; - float alpha; - QDateTime expiry; - }; - - explicit MessageManager (QObject* parent = 0); - void addLine (str line); - const List<Line>& getLines() const; - -private: - List<Line> m_lines; - QTimer* m_ticker; - -private slots: - void tick(); + // Single line of the message log. + class Line + { public: + Line (str text); + bool update (bool& changed); + + str text; + float alpha; + QDateTime expiry; + }; + + explicit MessageManager (QObject* parent = 0); + void addLine (str line); + const List<Line>& getLines() const; + + private: + List<Line> m_lines; + QTimer* m_ticker; + + private slots: + void tick(); }; -#endif // MESSAGELOG_H \ No newline at end of file +#endif // MESSAGELOG_H
--- a/src/misc.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/misc.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -26,57 +26,57 @@ #include "ui_rotpoint.h" // Prime number table. -const ushort g_primes[NUM_PRIMES] = { - 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, - 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, - 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, - 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, - 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, - 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, - 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, - 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, - 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, - 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, - 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, - 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, - 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, - 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, - 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, - 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, - 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, - 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, - 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, - 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, - 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, - 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, - 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, - 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, - 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, - 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, - 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, - 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, - 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, - 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, - 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, - 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, - 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, - 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, - 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, - 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, - 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, - 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, - 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, - 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, - 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, - 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, - 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, - 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, - 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, - 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, - 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, - 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, - 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, - 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, +const ushort g_primes[NUM_PRIMES] = +{ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, + 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, + 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, + 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, + 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, + 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, + 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, + 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, + 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, + 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, + 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, + 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, + 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, + 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, + 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, + 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, + 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, + 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, + 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, + 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, + 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, + 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, + 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, + 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, + 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, + 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, + 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, + 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, + 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, + 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, + 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, + 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, + 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, + 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, + 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, + 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, + 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, + 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, + 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, + 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, + 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, + 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, + 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, + 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, + 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, + 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571, }; // ============================================================================= @@ -101,8 +101,8 @@ cfg (Float, edit_rotpoint_y, 0.0f); cfg (Float, edit_rotpoint_z, 0.0f); -const gridinfo g_GridInfo[3] = { - { "Coarse", { &grid_coarse_x, &grid_coarse_y, &grid_coarse_z, &grid_coarse_angle }}, +const gridinfo g_GridInfo[3] = +{ { "Coarse", { &grid_coarse_x, &grid_coarse_y, &grid_coarse_z, &grid_coarse_angle }}, { "Medium", { &grid_medium_x, &grid_medium_y, &grid_medium_z, &grid_medium_angle }}, { "Fine", { &grid_fine_x, &grid_fine_y, &grid_fine_z, &grid_fine_angle }} }; @@ -110,18 +110,18 @@ // ============================================================================= // Snap the given coordinate value on the current grid's given axis. // ----------------------------------------------------------------------------- -double Grid::snap (double in, const Grid::Config axis) { - const double gridval = currentGrid().confs[axis]->value; +double Grid::snap (double in, const Grid::Config axis) +{ const double gridval = currentGrid().confs[axis]->value; const long mult = abs (in / gridval); const bool neg = (in < 0); double out = mult * gridval; - + if (abs<double> (in) - (mult * gridval) > gridval / 2) out += gridval; - + if (neg && out != 0) out *= -1; - + return out; } @@ -129,139 +129,141 @@ // Float to string. Removes trailing zeroes and is locale-independant. // TODO: Replace with QString::number() // ----------------------------------------------------------------------------- -str ftoa (double num) { - // Disable the locale first so that the decimal point will not +str ftoa (double num) +{ // Disable the locale first so that the decimal point will not // turn into anything weird (like commas) setlocale (LC_NUMERIC, "C"); - + str rep; rep.sprintf ("%f", num); - + // Remove trailing zeroes while (rep.right (1) == "0") rep.chop (1); - + // If there were only zeroes in the decimal place, remove // the decimal point now. if (rep.right (1) == ".") rep.chop (1); - + return rep; } // ============================================================================= // TODO: I guess Qt must have something like this stashed somewhere? // ----------------------------------------------------------------------------- -bool isNumber (const str& tok) { - bool gotDot = false; - - for (int i = 0; i < tok.length(); ++i) { - const qchar c = tok[i]; - +bool isNumber (const str& tok) +{ bool gotDot = false; + + for (int i = 0; i < tok.length(); ++i) + { const qchar c = tok[i]; + // Allow leading hyphen for negatives if (i == 0 && c == '-') continue; - + // Check for decimal point - if (!gotDot && c == '.') { - gotDot = true; + if (!gotDot && c == '.') + { gotDot = true; continue; } - + if (c >= '0' && c <= '9') continue; // Digit - + // If the above cases didn't catch this character, it was // illegal and this is therefore not a number. return false; } - + return true; } // ============================================================================= // ----------------------------------------------------------------------------- -void simplify (short& numer, short& denom) { - bool repeat; - - do { - repeat = false; - - for (ushort x = 0; x < NUM_PRIMES; x++) { - const ushort prime = g_primes[NUM_PRIMES - x - 1]; - +void simplify (short& numer, short& denom) +{ bool repeat; + + do + { repeat = false; + + for (ushort x = 0; x < NUM_PRIMES; x++) + { const ushort prime = g_primes[NUM_PRIMES - x - 1]; + if (numer <= prime || denom <= prime) continue; - - if ((numer % prime == 0) && (denom % prime == 0)) { - numer /= prime; + + if ( (numer % prime == 0) && (denom % prime == 0)) + { numer /= prime; denom /= prime; repeat = true; break; } } - } while (repeat); + } + while (repeat); } // ============================================================================= // ----------------------------------------------------------------------------- -vertex rotPoint (const List<LDObject*>& objs) { - LDBoundingBox box; - - switch (edit_rotpoint) { - case ObjectOrigin: - // Calculate center vertex +vertex rotPoint (const List<LDObject*>& objs) +{ LDBoundingBox box; + + switch (edit_rotpoint) + { case ObjectOrigin: + + // Calculate center vertex for (LDObject * obj : objs) - if (obj->hasMatrix()) - box << dynamic_cast<LDMatrixObject*>(obj)->position(); - else - box << obj; - - return box.center(); - - case WorldOrigin: - return g_origin; - - case CustomPoint: - return vertex (edit_rotpoint_x, edit_rotpoint_y, edit_rotpoint_z); + if (obj->hasMatrix()) + box << dynamic_cast<LDMatrixObject*> (obj)->position(); + else + box << obj; + + return box.center(); + + case WorldOrigin: + return g_origin; + + case CustomPoint: + return vertex (edit_rotpoint_x, edit_rotpoint_y, edit_rotpoint_z); } - + return vertex(); } // ============================================================================= // ----------------------------------------------------------------------------- -void configRotationPoint() { - QDialog* dlg = new QDialog; +void configRotationPoint() +{ QDialog* dlg = new QDialog; Ui::RotPointUI ui; ui.setupUi (dlg); - - switch (edit_rotpoint) { - case ObjectOrigin: - ui.objectPoint->setChecked (true); - break; - - case WorldOrigin: - ui.worldPoint->setChecked (true); - break; - - case CustomPoint: - ui.customPoint->setChecked (true); - break; + + switch (edit_rotpoint) + { case ObjectOrigin: + ui.objectPoint->setChecked (true); + break; + + case WorldOrigin: + ui.worldPoint->setChecked (true); + break; + + case CustomPoint: + ui.customPoint->setChecked (true); + break; } - + ui.customX->setValue (edit_rotpoint_x); ui.customY->setValue (edit_rotpoint_y); ui.customZ->setValue (edit_rotpoint_z); - + if (!dlg->exec()) return; - + edit_rotpoint = (ui.objectPoint->isChecked()) ? ObjectOrigin : (ui.worldPoint->isChecked()) ? WorldOrigin : - CustomPoint; - + CustomPoint; + edit_rotpoint_x = ui.customX->value(); edit_rotpoint_y = ui.customY->value(); edit_rotpoint_z = ui.customZ->value(); @@ -269,31 +271,33 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str join (initlist<StringFormatArg> vals, str delim) { - QStringList list; - for (const StringFormatArg& arg : vals) +str join (initlist<StringFormatArg> vals, str delim) +{ QStringList list; + +for (const StringFormatArg & arg : vals) list << arg.value(); - + return list.join (delim); } // ============================================================================= // TODO: I'm quite sure Qt has this covered as well. // ----------------------------------------------------------------------------- -double atof (str val) { - // Disable the locale while parsing the line or atof's behavior changes +double atof (str val) +{ // Disable the locale while parsing the line or atof's behavior changes // between locales (i.e. fails to read decimals properly). That is // quite undesired... setlocale (LC_NUMERIC, "C"); - + char* buf = new char[val.length()]; char* bufptr = &buf[0]; - - for (qchar& c : val) + + for (QChar& c : val) *bufptr++ = c.toLatin1(); + *bufptr = '\0'; - + double fval = atof (buf); delete[] buf; return fval; -} \ No newline at end of file +}
--- a/src/misc.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/misc.h Thu Oct 03 20:56:20 2013 +0300 @@ -45,23 +45,22 @@ str join (initlist<StringFormatArg> vals, str delim = " "); // Grid stuff -typedef struct { - const char* const name; +struct gridinfo +{ const char* const name; FloatConfig* const confs[4]; -} gridinfo; +}; extern_cfg (Int, grid); static const short g_NumGrids = 3; extern const gridinfo g_GridInfo[3]; -inline const gridinfo& currentGrid() { - return g_GridInfo[grid]; +inline const gridinfo& currentGrid() +{ return g_GridInfo[grid]; } // ============================================================================= enum RotationPoint -{ - ObjectOrigin, +{ ObjectOrigin, WorldOrigin, CustomPoint }; @@ -69,65 +68,65 @@ vertex rotPoint (const List<LDObject*>& objs); void configRotationPoint(); -template<class T, class R> R container_cast (const T& a) { - R b; - +template<class T, class R> R container_cast (const T& a) +{ R b; + for (auto i : a) b << i; - + return b; } // ============================================================================= -namespace Grid { - enum Type { - Coarse, +namespace Grid +{ enum Type + { Coarse, Medium, Fine }; - - enum Config { - X, + + enum Config + { X, Y, Z, Angle }; - + double snap (double value, const Grid::Config axis); } // ============================================================================= -template<class T> void dataswap (T& a, T& b) { - T c = a; +template<class T> void dataswap (T& a, T& b) +{ T c = a; a = b; b = c; } // ----------------------------------------------------------------------------- // Plural expression -template<class T> static inline const char* plural (T n) { - return (n != 1) ? "s" : ""; +template<class T> static inline const char* plural (T n) +{ return (n != 1) ? "s" : ""; } // ----------------------------------------------------------------------------- // Templated clamp -template<class T> static inline T clamp (T a, T min, T max) { - return (a > max) ? max : (a < min) ? min : a; +template<class T> static inline T clamp (T a, T min, T max) +{ return (a > max) ? max : (a < min) ? min : a; } // Templated minimum -template<class T> static inline T min (T a, T b) { - return (a < b) ? a : b; +template<class T> static inline T min (T a, T b) +{ return (a < b) ? a : b; } // Templated maximum -template<class T> static inline T max (T a, T b) { - return (a > b) ? a : b; +template<class T> static inline T max (T a, T b) +{ return (a > b) ? a : b; } // Templated absolute value -template<class T> static inline T abs (T a) { - return (a >= 0) ? a : -a; +template<class T> static inline T abs (T a) +{ return (a >= 0) ? a : -a; } -#endif // MISC_H \ No newline at end of file +#endif // MISC_H
--- a/src/primitives.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/primitives.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -26,16 +26,16 @@ #include "ui_makeprim.h" #include "misc.h" #include "colors.h" +#include "moc_primitives.cpp" List<PrimitiveCategory> g_PrimitiveCategories; +List<Primitive> g_primitives; static PrimitiveLister* g_activePrimLister = null; static bool g_primListerMutex = false; -List<Primitive> g_primitives; - static const str g_Other = PrimitiveLister::tr ("Other"); -static const str g_radialNameRoots[] = { - "edge", +static const str g_radialNameRoots[] = +{ "edge", "cyli", "disc", "ndis", @@ -48,43 +48,44 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void loadPrimitives() { - print ("Loading primitives...\n"); +void loadPrimitives() +{ print ("Loading primitives...\n"); loadPrimitiveCatgories(); - + // Try to load prims.cfg File conf (Config::filepath ("prims.cfg"), File::Read); - - if (!conf) { - // No prims.cfg, build it + + if (!conf) + { // No prims.cfg, build it PrimitiveLister::start(); - } else { - // Read primitives from prims.cfg - for (str line : conf) { - int space = line.indexOf (" "); - + } + else + { // Read primitives from prims.cfg + for (str line : conf) + { int space = line.indexOf (" "); + if (space == -1) continue; - + Primitive info; info.name = line.left (space); info.title = line.mid (space + 1); g_primitives << info; } - + populateCategories(); } } // ============================================================================= // ----------------------------------------------------------------------------- -static void recursiveGetFilenames (QDir dir, List<str>& fnames) { - QFileInfoList flist = dir.entryInfoList(); - - for (const QFileInfo & info : flist) { - if (info.fileName() == "." || info.fileName() == "..") +static void recursiveGetFilenames (QDir dir, List<str>& fnames) +{ QFileInfoList flist = dir.entryInfoList(); + +for (const QFileInfo & info : flist) + { if (info.fileName() == "." || info.fileName() == "..") continue; // skip . and .. - + if (info.isDir()) recursiveGetFilenames (QDir (info.absoluteFilePath()), fnames); else @@ -94,49 +95,49 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void PrimitiveLister::work() { - g_activePrimLister = this; +void PrimitiveLister::work() +{ g_activePrimLister = this; m_prims.clear(); - + QDir dir (LDPaths::prims()); ulong baselen = dir.absolutePath().length(); ulong i = 0; List<str> fnames; - + assert (dir.exists()); recursiveGetFilenames (dir, fnames); emit starting (fnames.size()); - - for (str fname : fnames) { - File f (fname, File::Read); - + + for (str fname : fnames) + { File f (fname, File::Read); + Primitive info; info.name = fname.mid (baselen + 1); // make full path relative info.name.replace ('/', '\\'); // use DOS backslashes, they're expected info.cat = null; - + if (!f.readLine (info.title)) info.title = ""; - + info.title = info.title.simplified(); - - if (info.title[0] == '0') { - info.title.remove (0, 1); // remove 0 + + if (info.title[0] == '0') + { info.title.remove (0, 1); // remove 0 info.title = info.title.simplified(); } - + m_prims << info; emit update (++i); } - + // Save to a config file File conf (Config::filepath ("prims.cfg"), File::Write); - + for (Primitive & info : m_prims) fprint (conf, "%1 %2\n", info.name, info.title); - + conf.close(); - + g_primListerMutex = true; g_primitives = m_prims; populateCategories(); @@ -147,10 +148,10 @@ // ============================================================================= // ----------------------------------------------------------------------------- -void PrimitiveLister::start() { - if (g_activePrimLister) +void PrimitiveLister::start() +{ if (g_activePrimLister) return; - + PrimitiveLister* lister = new PrimitiveLister; QThread* listerThread = new QThread; lister->moveToThread (listerThread); @@ -164,60 +165,60 @@ // ============================================================================= // ----------------------------------------------------------------------------- -static PrimitiveCategory* findCategory (str name) { - for (PrimitiveCategory& cat : g_PrimitiveCategories) +static PrimitiveCategory* findCategory (str name) +{ for (PrimitiveCategory& cat : g_PrimitiveCategories) if (cat.name() == name) return &cat; - + return null; } // ============================================================================= // ----------------------------------------------------------------------------- -static void populateCategories() { - for (PrimitiveCategory& cat : g_PrimitiveCategories) +static void populateCategories() +{ for (PrimitiveCategory & cat : g_PrimitiveCategories) cat.prims.clear(); - + PrimitiveCategory* unmatched = findCategory (g_Other); - - if (!unmatched) { - // Shouldn't happen.. but catch it anyway. + + if (!unmatched) + { // Shouldn't happen.. but catch it anyway. PrimitiveCategory cat; cat.setName (g_Other); unmatched = & (g_PrimitiveCategories << cat); } - - for (Primitive& prim : g_primitives) { - bool matched = false; + + for (Primitive& prim : g_primitives) + { bool matched = false; prim.cat = null; - + // Go over the categories and their regexes, if and when there's a match, // the primitive's category is set to the category the regex beloings to. - for (PrimitiveCategory& cat : g_PrimitiveCategories) { - for (PrimitiveCategory::RegexEntry& entry : cat.regexes) { - switch (entry.type) { - case PrimitiveCategory::Filename: + for (PrimitiveCategory & cat : g_PrimitiveCategories) + { for (PrimitiveCategory::RegexEntry & entry : cat.regexes) + { switch (entry.type) + { case PrimitiveCategory::Filename: // f-regex, check against filename matched = entry.regex.exactMatch (prim.name); break; - - case PrimitiveCategory::Title: + + case PrimitiveCategory::Title: // t-regex, check against title matched = entry.regex.exactMatch (prim.title); break; } - - if (matched) { - prim.cat = &cat; + + if (matched) + { prim.cat = &cat; break; } } - + // Drop out if a category was decided on. if (prim.cat) break; } - + // If there was a match, add the primitive to the category. // Otherwise, add it to the list of unmatched primitives. if (prim.cat) @@ -229,53 +230,54 @@ // ============================================================================= // ----------------------------------------------------------------------------- -static void loadPrimitiveCatgories() { - g_PrimitiveCategories.clear(); +static void loadPrimitiveCatgories() +{ g_PrimitiveCategories.clear(); File f (Config::dirpath() + "primregexps.cfg", File::Read); - + if (!f) f.open (":/data/primitive-categories.cfg", File::Read); - + if (!f) critical (QObject::tr ("Failed to open primitive categories!")); - - if (f) { - PrimitiveCategory cat; - - for (str line : f) { - int colon; - + + if (f) + { PrimitiveCategory cat; + + for (str line : f) + { int colon; + if (line.length() == 0 || line[0] == '#') continue; - - if ((colon = line.indexOf (":")) == -1) { - if (cat.regexes.size() > 0) + + if ( (colon = line.indexOf (":")) == -1) + { if (cat.regexes.size() > 0) g_PrimitiveCategories << cat; - + cat.regexes.clear(); cat.prims.clear(); cat.setName (line); - } else { - str cmd = line.left (colon); + } + else + { str cmd = line.left (colon); PrimitiveCategory::Type type = PrimitiveCategory::Filename; - + if (cmd == "f") type = PrimitiveCategory::Filename; elif (cmd == "t") type = PrimitiveCategory::Title; else continue; - + QRegExp regex (line.mid (colon + 1)); PrimitiveCategory::RegexEntry entry = { regex, type }; cat.regexes << entry; } } - + if (cat.regexes.size() > 0) g_PrimitiveCategories << cat; } - + // Add a category for unmatched primitives PrimitiveCategory cat; cat.setName (g_Other); @@ -284,113 +286,112 @@ // ============================================================================= // ----------------------------------------------------------------------------- -bool primitiveLoaderBusy() { - return g_primListerMutex; +bool primitiveLoaderBusy() +{ return g_primListerMutex; } // ============================================================================= // ----------------------------------------------------------------------------- -static double radialPoint (int i, int divs, double (*func) (double)) { - return (*func) ((i * 2 * pi) / divs); +static double radialPoint (int i, int divs, double (*func) (double)) +{ return (*func) ((i * 2 * pi) / divs); } // ============================================================================= // ----------------------------------------------------------------------------- -List<LDObject*> makePrimitive (PrimitiveType type, int segs, int divs, int num) { - List<LDObject*> objs; +List<LDObject*> makePrimitive (PrimitiveType type, int segs, int divs, int num) +{ List<LDObject*> objs; List<int> condLineSegs; - - for (int i = 0; i < segs; ++i) { - double x0 = radialPoint (i, divs, cos), + + for (int i = 0; i < segs; ++i) + { double x0 = radialPoint (i, divs, cos), x1 = radialPoint (i + 1, divs, cos), z0 = radialPoint (i, divs, sin), z1 = radialPoint (i + 1, divs, sin); - - switch (type) { - case Circle: { - vertex v0 (x0, 0.0f, z0), - v1 (x1, 0.0f, z1); - - LDLine* line = new LDLine; - line->setVertex (0, v0); - line->setVertex (1, v1); - line->setColor (edgecolor); - objs << line; - } - break; - - case Cylinder: - case Ring: - case Cone: - { - double x2, x3, z2, z3; + + switch (type) + { case Circle: + { vertex v0 (x0, 0.0f, z0), + v1 (x1, 0.0f, z1); + + LDLine* line = new LDLine; + line->setVertex (0, v0); + line->setVertex (1, v1); + line->setColor (edgecolor); + objs << line; + } + break; + + case Cylinder: + case Ring: + case Cone: + { double x2, x3, z2, z3; double y0, y1, y2, y3; - - if (type == Cylinder) { - x2 = x1; + + if (type == Cylinder) + { x2 = x1; x3 = x0; z2 = z1; z3 = z0; - + y0 = y1 = 0.0f; y2 = y3 = 1.0f; - } else { - x2 = x1 * (num + 1); + } + else + { x2 = x1 * (num + 1); x3 = x0 * (num + 1); z2 = z1 * (num + 1); z3 = z0 * (num + 1); - + x0 *= num; x1 *= num; z0 *= num; z1 *= num; - + if (type == Ring) y0 = y1 = y2 = y3 = 0.0f; - else { - y0 = y1 = 1.0f; + else + { y0 = y1 = 1.0f; y2 = y3 = 0.0f; } } - + vertex v0 (x0, y0, z0), - v1 (x1, y1, z1), - v2 (x2, y2, z2), - v3 (x3, y3, z3); - + v1 (x1, y1, z1), + v2 (x2, y2, z2), + v3 (x3, y3, z3); + LDQuad* quad = new LDQuad; quad->setColor (maincolor); quad->setVertex (0, v0); quad->setVertex (1, v1); quad->setVertex (2, v2); quad->setVertex (3, v3); - + if (type == Cylinder) quad->invert(); - + objs << quad; - + if (type == Cylinder || type == Cone) condLineSegs << i; } break; - - case Disc: - case DiscNeg: - { - double x2, z2; - + + case Disc: + case DiscNeg: + { double x2, z2; + if (type == Disc) x2 = z2 = 0.0f; - else { - x2 = (x0 >= 0.0f) ? 1.0f : -1.0f; + else + { x2 = (x0 >= 0.0f) ? 1.0f : -1.0f; z2 = (z0 >= 0.0f) ? 1.0f : -1.0f; } - + vertex v0 (x0, 0.0f, z0), - v1 (x1, 0.0f, z1), - v2 (x2, 0.0f, z2); - + v1 (x1, 0.0f, z1), + v2 (x2, 0.0f, z2); + // Disc negatives need to go the other way around, otherwise // they'll end up upside-down. LDTriangle* seg = new LDTriangle; @@ -400,33 +401,33 @@ seg->setVertex (type == Disc ? 2 : 0, v2); objs << seg; } - break; - - default: + break; + + default: break; } } - + // If this is not a full circle, we need a conditional line at the other // end, too. if (segs < divs && condLineSegs.size() != 0) condLineSegs << segs; - - for (int i : condLineSegs) { - vertex v0 (radialPoint (i, divs, cos), 0.0f, radialPoint (i, divs, sin)), - v1, - v2 (radialPoint (i + 1, divs, cos), 0.0f, radialPoint (i + 1, divs, sin)), - v3 (radialPoint (i - 1, divs, cos), 0.0f, radialPoint (i - 1, divs, sin)); - + + for (int i : condLineSegs) + { vertex v0 (radialPoint (i, divs, cos), 0.0f, radialPoint (i, divs, sin)), + v1, + v2 (radialPoint (i + 1, divs, cos), 0.0f, radialPoint (i + 1, divs, sin)), + v3 (radialPoint (i - 1, divs, cos), 0.0f, radialPoint (i - 1, divs, sin)); + if (type == Cylinder) v1 = vertex (v0[X], 1.0f, v0[Z]); - elif (type == Cone) { - v1 = vertex (v0[X] * (num + 1), 0.0f, v0[Z] * (num + 1)); + elif (type == Cone) + { v1 = vertex (v0[X] * (num + 1), 0.0f, v0[Z] * (num + 1)); v0[X] *= num; v0[Y] = 1.0f; v0[Z] *= num; } - + LDCndLine* line = new LDCndLine; line->setColor (edgecolor); line->setVertex (0, v0); @@ -435,60 +436,60 @@ line->setVertex (3, v3); objs << line; } - + return objs; } // ============================================================================= // ----------------------------------------------------------------------------- -static str primitiveTypeName (PrimitiveType type) { - // Not translated as primitives are in English. +static str primitiveTypeName (PrimitiveType type) +{ // Not translated as primitives are in English. return type == Circle ? "Circle" : - type == Cylinder ? "Cylinder" : - type == Disc ? "Disc" : - type == DiscNeg ? "Disc Negative" : - type == Ring ? "Ring" : "Cone"; + type == Cylinder ? "Cylinder" : + type == Disc ? "Disc" : + type == DiscNeg ? "Disc Negative" : + type == Ring ? "Ring" : "Cone"; } // ============================================================================= // ----------------------------------------------------------------------------- -str radialFileName (PrimitiveType type, int segs, int divs, int num) { - short numer = segs, - denom = divs; - +str radialFileName (PrimitiveType type, int segs, int divs, int num) +{ short numer = segs, + denom = divs; + // Simplify the fractional part, but the denominator must be at least 4. simplify (numer, denom); - - if (denom < 4) { - const short factor = 4 / denom; - + + if (denom < 4) + { const short factor = 4 / denom; + numer *= factor; denom *= factor; } - + // Compose some general information: prefix, fraction, root, ring number str prefix = (divs == lores) ? "" : fmt ("%1/", divs); str frac = fmt ("%1-%2", numer, denom); str root = g_radialNameRoots[type]; str numstr = (type == Ring || type == Cone) ? fmt ("%1", num) : ""; - + // Truncate the root if necessary (7-16rin4.dat for instance). // However, always keep the root at least 2 characters. int extra = (frac.length() + numstr.length() + root.length()) - 8; root.chop (min<short> (max<short> (extra, 0), 2)); - + // Stick them all together and return the result. return prefix + frac + root + numstr + ".dat"; } // ============================================================================= // ----------------------------------------------------------------------------- -void generatePrimitive() { - PrimitivePrompt* dlg = new PrimitivePrompt (g_win); - +void generatePrimitive() +{ PrimitivePrompt* dlg = new PrimitivePrompt (g_win); + if (!dlg->exec()) return; - + int segs = dlg->ui->sb_segs->value(); int divs = dlg->ui->cb_hires->isChecked() ? hires : lores; int num = dlg->ui->sb_ringnum->value(); @@ -498,34 +499,35 @@ dlg->ui->rb_disc->isChecked() ? Disc : dlg->ui->rb_ndisc->isChecked() ? DiscNeg : dlg->ui->rb_ring->isChecked() ? Ring : Cone; - + // Make the description - str frac = ftoa (((float) segs) / divs); + str frac = ftoa ( ( (float) segs) / divs); str name = radialFileName (type, segs, divs, num); str descr; - + // Ensure that there's decimals, even if they're 0. if (frac.indexOf (".") == -1) frac += ".0"; - - if (type == Ring || type == Cone) { - str spacing = - (num < 10 ) ? " " : - (num < 100) ? " " : ""; - + + if (type == Ring || type == Cone) + { str spacing = + (num < 10) ? " " : + (num < 100) ? " " : ""; + descr = fmt ("%1 %2%3 x %4", primitiveTypeName (type), spacing, num, frac); - } else + } + else descr = fmt ("%1 %2", primitiveTypeName (type), frac); - + // Prepend "Hi-Res" if 48/ primitive. if (divs == hires) descr.insert (0, "Hi-Res "); - + LDFile* f = new LDFile; f->setName (QFileDialog::getSaveFileName (null, QObject::tr ("Save Primitive"), name)); - - f->addObjects ({ - new LDComment (descr), + + f->addObjects ( + { new LDComment (descr), new LDComment (fmt ("Name: %1", name)), new LDComment (fmt ("Author: LDForge")), new LDComment (fmt ("!LDRAW_ORG Unofficial_%1Primitive", divs == hires ? "48_" : "")), @@ -534,9 +536,9 @@ new LDBFC (LDBFC::CertifyCCW), new LDEmpty, }); - + f->addObjects (makePrimitive (type, segs, divs, num)); - + g_win->save (f, false); delete f; } @@ -544,27 +546,27 @@ // ============================================================================= // ----------------------------------------------------------------------------- PrimitivePrompt::PrimitivePrompt (QWidget* parent, Qt::WindowFlags f) : - QDialog (parent, f) { - + QDialog (parent, f) +{ + ui = new Ui_MakePrimUI; ui->setupUi (this); - connect (ui->cb_hires, SIGNAL (toggled(bool)), this, SLOT (hiResToggled (bool))); + connect (ui->cb_hires, SIGNAL (toggled (bool)), this, SLOT (hiResToggled (bool))); } // ============================================================================= // ----------------------------------------------------------------------------- -PrimitivePrompt::~PrimitivePrompt() { - delete ui; +PrimitivePrompt::~PrimitivePrompt() +{ delete ui; } // ============================================================================= // ----------------------------------------------------------------------------- -void PrimitivePrompt::hiResToggled (bool on) { - ui->sb_segs->setMaximum (on ? hires : lores); - +void PrimitivePrompt::hiResToggled (bool on) +{ ui->sb_segs->setMaximum (on ? hires : lores); + // If the current value is 16 and we switch to hi-res, default the // spinbox to 48. if (on && ui->sb_segs->value() == lores) ui->sb_segs->setValue (hires); } -#include "moc_primitives.cpp"
--- a/src/primitives.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/primitives.h Thu Oct 03 20:56:20 2013 +0300 @@ -26,57 +26,57 @@ class Ui_MakePrimUI; class PrimitiveCategory; -struct Primitive { - str name, title; +struct Primitive +{ str name, title; PrimitiveCategory* cat; }; -class PrimitiveCategory { - PROPERTY (str, name, setName) - -public: - enum Type { - Filename, - Title - }; - - struct RegexEntry { - QRegExp regex; - Type type; - }; - - typedef List<RegexEntry>::it it; - typedef List<RegexEntry>::c_it c_it; - - List<RegexEntry> regexes; - List<Primitive> prims; - static List<Primitive> uncat; +class PrimitiveCategory +{ PROPERTY (str, name, setName) + + public: + enum Type + { Filename, + Title + }; + + struct RegexEntry + { QRegExp regex; + Type type; + }; + + typedef List<RegexEntry>::it it; + typedef List<RegexEntry>::c_it c_it; + + List<RegexEntry> regexes; + List<Primitive> prims; + static List<Primitive> uncat; }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= // PrimitiveLister -// +// // Worker object that scans the primitives folder for primitives and // builds an index of them. // ============================================================================= -class PrimitiveLister : public QObject { - Q_OBJECT - -public: - static void start(); - -public slots: - void work(); - -signals: - void starting (ulong num); - void workDone(); - void update (ulong i); - -private: - List<Primitive> m_prims; +class PrimitiveLister : public QObject +{ Q_OBJECT + + public: + static void start(); + + public slots: + void work(); + + signals: + void starting (ulong num); + void workDone(); + void update (ulong i); + + private: + List<Primitive> m_prims; }; extern List<PrimitiveCategory> g_PrimitiveCategories; @@ -85,8 +85,7 @@ bool primitiveLoaderBusy(); enum PrimitiveType -{ - Circle, +{ Circle, Cylinder, Disc, DiscNeg, @@ -95,18 +94,18 @@ }; // ============================================================================= -class PrimitivePrompt : public QDialog { - Q_OBJECT - -public: - explicit PrimitivePrompt (QWidget* parent = null, Qt::WindowFlags f = 0); - virtual ~PrimitivePrompt(); - Ui_MakePrimUI* ui; - -public slots: - void hiResToggled (bool on); +class PrimitivePrompt : public QDialog +{ Q_OBJECT + + public: + explicit PrimitivePrompt (QWidget* parent = null, Qt::WindowFlags f = 0); + virtual ~PrimitivePrompt(); + Ui_MakePrimUI* ui; + + public slots: + void hiResToggled (bool on); }; void generatePrimitive(); -#endif // PRIMITIVES_H \ No newline at end of file +#endif // PRIMITIVES_H
--- a/src/types.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/types.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -29,59 +29,60 @@ // ============================================================================= // ----------------------------------------------------------------------------- -str DoFormat (List<StringFormatArg> args) { - assert (args.size() >= 1); +str DoFormat (List<StringFormatArg> args) +{ assert (args.size() >= 1); str text = args[0].value(); - + for (uchar i = 1; i < args.size(); ++i) text = text.arg (args[i].value()); - + return text; } // ============================================================================= // ----------------------------------------------------------------------------- -vertex::vertex (double x, double y, double z) { - m_coords[X] = x; +vertex::vertex (double x, double y, double z) +{ m_coords[X] = x; m_coords[Y] = y; m_coords[Z] = z; } // ============================================================================= // ----------------------------------------------------------------------------- -void vertex::move (const vertex& other) { - for (const Axis ax : g_Axes) +void vertex::move (const vertex& other) +{ for (const Axis ax : g_Axes) m_coords[ax] += other[ax]; } // ============================================================================= // ----------------------------------------------------------------------------- -vertex vertex::midpoint (const vertex& other) { - vertex mid; - - for (const Axis ax : g_Axes) +vertex vertex::midpoint (const vertex& other) +{ vertex mid; + +for (const Axis ax : g_Axes) mid[ax] = (m_coords[ax] + other[ax]) / 2; - + return mid; } // ============================================================================= // ----------------------------------------------------------------------------- -str vertex::stringRep (bool mangled) const { - str fmtstr = "%1 %2 %3"; +str vertex::stringRep (bool mangled) const +{ str fmtstr = "%1 %2 %3"; + if (mangled) fmtstr = "(%1, %2, %3)"; - + return fmt (fmtstr, coord (X), coord (Y), coord (Z)); } // ============================================================================= // ----------------------------------------------------------------------------- -void vertex::transform (matrix matr, vertex pos) { - double x2 = (matr[0] * x()) + (matr[1] * y()) + (matr[2] * z()) + pos[X]; +void vertex::transform (matrix matr, vertex pos) +{ double x2 = (matr[0] * x()) + (matr[1] * y()) + (matr[2] * z()) + pos[X]; double y2 = (matr[3] * x()) + (matr[4] * y()) + (matr[5] * z()) + pos[Y]; double z2 = (matr[6] * x()) + (matr[7] * y()) + (matr[8] * z()) + pos[Z]; - + x() = x2; y() = y2; z() = z2; @@ -89,258 +90,258 @@ // ============================================================================= // ----------------------------------------------------------------------------- -vertex vertex::operator-() const { - return vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]); +vertex vertex::operator-() const +{ return vertex (-m_coords[X], -m_coords[Y], -m_coords[Z]); } // ============================================================================= // ----------------------------------------------------------------------------- -bool vertex::operator!= (const vertex& other) const { - return !operator== (other); +bool vertex::operator!= (const vertex& other) const +{ return !operator== (other); } // ============================================================================= // ----------------------------------------------------------------------------- -double& vertex::operator[] (const Axis ax) { - return coord ((ushort) ax); +double& vertex::operator[] (const Axis ax) +{ return coord ( (ushort) ax); } -const double& vertex::operator[] (const Axis ax) const { - return coord ((ushort) ax); +const double& vertex::operator[] (const Axis ax) const +{ return coord ( (ushort) ax); } -double& vertex::operator[] (const int ax) { - return coord (ax); +double& vertex::operator[] (const int ax) +{ return coord (ax); } -const double& vertex::operator[] (const int ax) const { - return coord (ax); +const double& vertex::operator[] (const int ax) const +{ return coord (ax); } // ============================================================================= // ----------------------------------------------------------------------------- -bool vertex::operator== (const vertex& other) const { - return coord (X) == other[X] && - coord (Y) == other[Y] && - coord (Z) == other[Z]; +bool vertex::operator== (const vertex& other) const +{ return coord (X) == other[X] && + coord (Y) == other[Y] && + coord (Z) == other[Z]; } // ============================================================================= // ----------------------------------------------------------------------------- -vertex& vertex::operator/= (const double d) { - for (const Axis ax : g_Axes) +vertex& vertex::operator/= (const double d) +{ for (const Axis ax : g_Axes) m_coords[ax] /= d; - + return *this; } // ============================================================================= // ----------------------------------------------------------------------------- -vertex vertex::operator/ (const double d) const { - vertex other (*this); +vertex vertex::operator/ (const double d) const +{ vertex other (*this); return other /= d; } // ============================================================================= // ----------------------------------------------------------------------------- -vertex& vertex::operator+= (const vertex& other) { - move (other); +vertex& vertex::operator+= (const vertex& other) +{ move (other); return *this; } // ============================================================================= // ----------------------------------------------------------------------------- -vertex vertex::operator+ (const vertex& other) const { - vertex newvert (*this); +vertex vertex::operator+ (const vertex& other) const +{ vertex newvert (*this); newvert.move (other); return newvert; } // ============================================================================= // ----------------------------------------------------------------------------- -int vertex::operator< (const vertex& other) const { - if (operator== (other)) +int vertex::operator< (const vertex& other) const +{ if (operator== (other)) return false; - + if (coord (X) < other[X]) return true; - + if (coord (X) > other[X]) return false; - + if (coord (Y) < other[Y]) return true; - + if (coord (Y) > other[Y]) return false; - + return coord (Z) < other[Z]; } // ============================================================================= // ----------------------------------------------------------------------------- -matrix::matrix (double vals[]) { - for (short i = 0; i < 9; ++i) +matrix::matrix (double vals[]) +{ for (short i = 0; i < 9; ++i) m_vals[i] = vals[i]; } // ============================================================================= // ----------------------------------------------------------------------------- -matrix::matrix (double fillval) { - for (short i = 0; i < 9; ++i) +matrix::matrix (double fillval) +{ for (short i = 0; i < 9; ++i) m_vals[i] = fillval; } // ============================================================================= // ----------------------------------------------------------------------------- -matrix::matrix (initlist<double> vals) { - assert (vals.size() == 9); +matrix::matrix (initlist<double> vals) +{ assert (vals.size() == 9); memcpy (&m_vals[0], & (*vals.begin()), sizeof m_vals); } // ============================================================================= // ----------------------------------------------------------------------------- -void matrix::puts() const { - for (short i = 0; i < 3; ++i) { - for (short j = 0; j < 3; ++j) +void matrix::puts() const +{ for (short i = 0; i < 3; ++i) + { for (short j = 0; j < 3; ++j) print ("%1\t", m_vals[ (i * 3) + j]); - + print ("\n"); } } // ============================================================================= // ----------------------------------------------------------------------------- -str matrix::stringRep() const { - str val; - - for (short i = 0; i < 9; ++i) { - if (i > 0) +str matrix::stringRep() const +{ str val; + + for (short i = 0; i < 9; ++i) + { if (i > 0) val += ' '; - + val += ftoa (m_vals[i]); } - + return val; } // ============================================================================= // ----------------------------------------------------------------------------- -void matrix::zero() { - memset (&m_vals[0], 0, sizeof m_vals); +void matrix::zero() +{ memset (&m_vals[0], 0, sizeof m_vals); } // ============================================================================= // ----------------------------------------------------------------------------- -matrix matrix::mult (matrix other) const { - matrix val; +matrix matrix::mult (matrix other) const +{ matrix val; val.zero(); - + for (short i = 0; i < 3; ++i) - for (short j = 0; j < 3; ++j) - for (short k = 0; k < 3; ++k) - val[ (i * 3) + j] += m_vals[(i * 3) + k] * other[(k * 3) + j]; - + for (short j = 0; j < 3; ++j) + for (short k = 0; k < 3; ++k) + val[ (i * 3) + j] += m_vals[ (i * 3) + k] * other[ (k * 3) + j]; + return val; } // ============================================================================= // ----------------------------------------------------------------------------- -matrix& matrix::operator= (matrix other) { - memcpy (&m_vals[0], &other.m_vals[0], sizeof m_vals); +matrix& matrix::operator= (matrix other) +{ memcpy (&m_vals[0], &other.m_vals[0], sizeof m_vals); return *this; } // ============================================================================= // ----------------------------------------------------------------------------- -double matrix::determinant() const { - return (val (0) * val (4) * val (8)) + - (val (1) * val (5) * val (6)) + - (val (2) * val (3) * val (7)) - - (val (2) * val (4) * val (6)) - - (val (1) * val (3) * val (8)) - - (val (0) * val (5) * val (7)); +double matrix::determinant() const +{ return (val (0) * val (4) * val (8)) + + (val (1) * val (5) * val (6)) + + (val (2) * val (3) * val (7)) - + (val (2) * val (4) * val (6)) - + (val (1) * val (3) * val (8)) - + (val (0) * val (5) * val (7)); } // ============================================================================= // ----------------------------------------------------------------------------- -StringFormatArg::StringFormatArg (const str& v) { - m_val = v; +StringFormatArg::StringFormatArg (const str& v) +{ m_val = v; } -StringFormatArg::StringFormatArg (const char& v) { - m_val = v; +StringFormatArg::StringFormatArg (const char& v) +{ m_val = v; } -StringFormatArg::StringFormatArg (const uchar& v) { - m_val = v; +StringFormatArg::StringFormatArg (const uchar& v) +{ m_val = v; } -StringFormatArg::StringFormatArg (const qchar& v) { - m_val = v; +StringFormatArg::StringFormatArg (const qchar& v) +{ m_val = v; } -StringFormatArg::StringFormatArg (const float& v) { - m_val = ftoa (v); +StringFormatArg::StringFormatArg (const float& v) +{ m_val = ftoa (v); } -StringFormatArg::StringFormatArg (const double& v) { - m_val = ftoa (v); +StringFormatArg::StringFormatArg (const double& v) +{ m_val = ftoa (v); } -StringFormatArg::StringFormatArg (const vertex& v) { - m_val = v.stringRep (false); +StringFormatArg::StringFormatArg (const vertex& v) +{ m_val = v.stringRep (false); } -StringFormatArg::StringFormatArg (const matrix& v) { - m_val = v.stringRep(); +StringFormatArg::StringFormatArg (const matrix& v) +{ m_val = v.stringRep(); } -StringFormatArg::StringFormatArg (const char* v) { - m_val = v; +StringFormatArg::StringFormatArg (const char* v) +{ m_val = v; } -StringFormatArg::StringFormatArg (const StringConfig& v) { - m_val = v.value; +StringFormatArg::StringFormatArg (const StringConfig& v) +{ m_val = v.value; } -StringFormatArg::StringFormatArg (const IntConfig& v) { - m_val.number (v.value); +StringFormatArg::StringFormatArg (const IntConfig& v) +{ m_val.number (v.value); } -StringFormatArg::StringFormatArg (const FloatConfig& v) { - m_val.number (v.value); +StringFormatArg::StringFormatArg (const FloatConfig& v) +{ m_val.number (v.value); } -StringFormatArg::StringFormatArg (const void* v) { - m_val.sprintf ("%p", v); +StringFormatArg::StringFormatArg (const void* v) +{ m_val.sprintf ("%p", v); } // ============================================================================= // ----------------------------------------------------------------------------- -File::File() { - // Make a null file +File::File() +{ // Make a null file m_file = null; m_textstream = null; } -File::File (str path, OpenType rtype) { - m_file = null; +File::File (str path, OpenType rtype) +{ m_file = null; open (path, rtype); } -File::File (FILE* fp, OpenType rtype) { - m_file = null; +File::File (FILE* fp, OpenType rtype) +{ m_file = null; open (fp, rtype); } // ============================================================================= // ----------------------------------------------------------------------------- -File::~File() { - if (m_file) { - m_file->close(); +File::~File() +{ if (m_file) + { m_file->close(); delete m_file; - + if (m_textstream) delete m_textstream; } @@ -348,34 +349,34 @@ // ============================================================================= // ----------------------------------------------------------------------------- -bool File::open (FILE* fp, OpenType rtype) { - return open ("", rtype, fp); +bool File::open (FILE* fp, OpenType rtype) +{ return open ("", rtype, fp); } -bool File::open (str path, OpenType rtype, FILE* fp) { - close(); - +bool File::open (str path, OpenType rtype, FILE* fp) +{ close(); + if (!m_file) m_file = new QFile; - + m_file->setFileName (path); - + bool result; - + QIODevice::OpenMode mode = - (rtype == Read) ? QIODevice::ReadOnly : - (rtype == Write) ? QIODevice::WriteOnly : QIODevice::Append; - + (rtype == Read) ? QIODevice::ReadOnly : + (rtype == Write) ? QIODevice::WriteOnly : QIODevice::Append; + if (fp) result = m_file->open (fp, mode); else result = m_file->open (mode); - - if (result) { - m_textstream = new QTextStream (m_file); + + if (result) + { m_textstream = new QTextStream (m_file); return true; } - + delete m_file; m_file = null; return false; @@ -383,222 +384,224 @@ // ============================================================================= // ----------------------------------------------------------------------------- -File::iterator File::begin() { - return iterator (this); +File::iterator File::begin() +{ return iterator (this); } -File::iterator& File::end() { - return m_endIterator; +File::iterator& File::end() +{ return m_endIterator; } // ============================================================================= // ----------------------------------------------------------------------------- -void File::write (str msg) { - m_file->write (msg.toUtf8(), msg.length()); +void File::write (str msg) +{ m_file->write (msg.toUtf8(), msg.length()); } // ============================================================================= // ----------------------------------------------------------------------------- -bool File::readLine (str& line) { - if (!m_textstream || m_textstream->atEnd()) +bool File::readLine (str& line) +{ if (!m_textstream || m_textstream->atEnd()) return false; - + line = m_textstream->readLine(); return true; } // ============================================================================= // ----------------------------------------------------------------------------- -bool File::atEnd() const { - if (!m_textstream) +bool File::atEnd() const +{ if (!m_textstream) fatal ("cannot use atEnd on a null file"); - + return m_textstream->atEnd(); } // ============================================================================= // ----------------------------------------------------------------------------- -bool File::isNull() const { - return m_file == null; +bool File::isNull() const +{ return m_file == null; } -bool File::operator!() const { - return isNull(); +bool File::operator!() const +{ return isNull(); } // ============================================================================= // ----------------------------------------------------------------------------- -void File::close() { - if (!m_file) +void File::close() +{ if (!m_file) return; - + delete m_file; m_file = null; - - if (m_textstream) { - delete m_textstream; + + if (m_textstream) + { delete m_textstream; m_textstream = null; } } // ============================================================================= // ----------------------------------------------------------------------------- -bool File::flush() { - return m_file->flush(); +bool File::flush() +{ return m_file->flush(); } // ============================================================================= // ----------------------------------------------------------------------------- -File::operator bool() const { - return !isNull(); +File::operator bool() const +{ return !isNull(); } // ============================================================================= // ----------------------------------------------------------------------------- -void File::rewind() { - m_file->seek (0); +void File::rewind() +{ m_file->seek (0); } // ============================================================================= // ----------------------------------------------------------------------------- -File::iterator::iterator (File* f) : m_file (f) { - operator++(); +File::iterator::iterator (File* f) : m_file (f) +{ operator++(); } // ============================================================================= // ----------------------------------------------------------------------------- -void File::iterator::operator++() { - m_gotdata = m_file->readLine (m_text); +void File::iterator::operator++() +{ m_gotdata = m_file->readLine (m_text); } // ============================================================================= // ----------------------------------------------------------------------------- -str File::iterator::operator*() { - return m_text; +str File::iterator::operator*() +{ return m_text; } // ============================================================================= // The prime contestant for the weirdest operator== 2013 award? // ----------------------------------------------------------------------------- -bool File::iterator::operator== (File::iterator& other) { - return (other.m_file == null && !m_gotdata); +bool File::iterator::operator== (File::iterator& other) +{ return (other.m_file == null && !m_gotdata); } // ============================================================================= // ----------------------------------------------------------------------------- -bool File::iterator::operator!= (File::iterator& other) { - return !operator== (other); +bool File::iterator::operator!= (File::iterator& other) +{ return !operator== (other); } // ============================================================================= // ----------------------------------------------------------------------------- -LDBoundingBox::LDBoundingBox() { - reset(); +LDBoundingBox::LDBoundingBox() +{ reset(); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDBoundingBox::calculate() { - reset(); - +void LDBoundingBox::calculate() +{ reset(); + if (!LDFile::current()) return; - - for (LDObject* obj : LDFile::current()->objects()) + +for (LDObject * obj : LDFile::current()->objects()) calcObject (obj); } // ============================================================================= // ----------------------------------------------------------------------------- -void LDBoundingBox::calcObject (LDObject* obj) { - switch (obj->getType()) { - case LDObject::Line: - case LDObject::Triangle: - case LDObject::Quad: - case LDObject::CndLine: - for (short i = 0; i < obj->vertices(); ++i) - calcVertex (obj->getVertex (i)); - +void LDBoundingBox::calcObject (LDObject* obj) +{ switch (obj->getType()) + { case LDObject::Line: + case LDObject::Triangle: + case LDObject::Quad: + case LDObject::CndLine: + + for (short i = 0; i < obj->vertices(); ++i) + calcVertex (obj->getVertex (i)); + + break; + + case LDObject::Subfile: + { LDSubfile* ref = static_cast<LDSubfile*> (obj); + List<LDObject*> objs = ref->inlineContents (LDSubfile::DeepCacheInline); + + for (LDObject * obj : objs) + { calcObject (obj); + delete obj; + } + } break; - case LDObject::Subfile: { - LDSubfile* ref = static_cast<LDSubfile*> (obj); - List<LDObject*> objs = ref->inlineContents (LDSubfile::DeepCacheInline); - - for (LDObject* obj : objs) { - calcObject (obj); - delete obj; - } - } - break; - - default: - break; + default: + break; } } // ============================================================================= // ----------------------------------------------------------------------------- -LDBoundingBox& LDBoundingBox::operator<< (const vertex& v) { - calcVertex (v); +LDBoundingBox& LDBoundingBox::operator<< (const vertex& v) +{ calcVertex (v); return *this; } // ============================================================================= // ----------------------------------------------------------------------------- -LDBoundingBox& LDBoundingBox::operator<< (LDObject* obj) { - calcObject (obj); +LDBoundingBox& LDBoundingBox::operator<< (LDObject* obj) +{ calcObject (obj); return *this; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDBoundingBox::calcVertex (const vertex& v) { - for (const Axis ax : g_Axes) { - if (v[ax] < m_v0[ax]) +void LDBoundingBox::calcVertex (const vertex& v) +{ for (const Axis ax : g_Axes) + { if (v[ax] < m_v0[ax]) m_v0[ax] = v[ax]; - + if (v[ax] > m_v1[ax]) m_v1[ax] = v[ax]; } - + m_empty = false; } // ============================================================================= // ----------------------------------------------------------------------------- -void LDBoundingBox::reset() { - m_v0[X] = m_v0[Y] = m_v0[Z] = 0x7FFFFFFF; +void LDBoundingBox::reset() +{ m_v0[X] = m_v0[Y] = m_v0[Z] = 0x7FFFFFFF; m_v1[X] = m_v1[Y] = m_v1[Z] = 0xFFFFFFFF; - + m_empty = true; } // ============================================================================= // ----------------------------------------------------------------------------- -double LDBoundingBox::size() const { - double xscale = (m_v0[X] - m_v1[X]); +double LDBoundingBox::size() const +{ double xscale = (m_v0[X] - m_v1[X]); double yscale = (m_v0[Y] - m_v1[Y]); double zscale = (m_v0[Z] - m_v1[Z]); double size = zscale; - - if (xscale > yscale) { - if (xscale > zscale) + + if (xscale > yscale) + { if (xscale > zscale) size = xscale; } elif (yscale > zscale) - size = yscale; - + + size = yscale; + if (abs (size) >= 2.0f) return abs (size / 2); - + return 1.0f; } // ============================================================================= // ----------------------------------------------------------------------------- -vertex LDBoundingBox::center() const { - return vertex ( +vertex LDBoundingBox::center() const +{ return vertex ( (m_v0[X] + m_v1[X]) / 2, (m_v0[Y] + m_v1[Y]) / 2, (m_v0[Z] + m_v1[Z]) / 2); -} \ No newline at end of file +}
--- a/src/types.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/types.h Thu Oct 03 20:56:20 2013 +0300 @@ -62,275 +62,311 @@ // // A mathematical 3 x 3 matrix // ============================================================================= -class matrix { -public: - matrix() {} - matrix (initlist<double> vals); - matrix (double fillval); - matrix (double vals[]); - - double determinant () const; - matrix mult (matrix other) const; - void puts () const; - str stringRep () const; - void zero (); - double& val (const uint idx) { return m_vals[idx]; } - const double& val (const uint idx) const { return m_vals[idx]; } - - matrix& operator= (matrix other); - matrix operator* (matrix other) const { return mult (other); } - double& operator[] (const uint idx) { return m_vals[idx]; } - const double& operator[] (const uint idx) const { return m_vals[idx]; } +class matrix +{ public: + matrix() {} + matrix (initlist<double> vals); + matrix (double fillval); + matrix (double vals[]); + + double determinant () const; + matrix mult (matrix other) const; + void puts () const; + str stringRep () const; + void zero (); + matrix& operator= (matrix other); + + inline double& val (const uint idx) + { return m_vals[idx]; + } -private: - double m_vals[9]; + inline const double val (const uint idx) const + { return m_vals[idx]; + } + + inline matrix operator* (matrix other) const + { return mult (other); + } + + inline double& operator[] (const uint idx) + { return val (idx); + } + inline const double& operator[] (const uint idx) const + { return val (idx); + } + + private: + double m_vals[9]; }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= // vertex -// +// // Vertex class, contains a single point in 3D space. Not to be confused with // LDVertex, which is a vertex used in an LDraw part file. // ============================================================================= -class vertex { -public: - vertex() {} - vertex (double x, double y, double z); - - double& coord (const ushort n) { return m_coords[n]; } - const double& coord (const ushort n) const { return m_coords[n]; } - vertex midpoint (const vertex& other); - void move (const vertex& other); - str stringRep (bool mangled) const; - void transform (matrix matr, vertex pos); - double& x () { return m_coords[X]; } - const double& x () const { return m_coords[X]; } - double& y () { return m_coords[Y]; } - const double& y () const { return m_coords[Y]; } - double& z () { return m_coords[Z]; } - const double& z () const { return m_coords[Z]; } - - vertex& operator+= (const vertex& other); - vertex operator+ (const vertex& other) const; - vertex operator/ (const double d) const; - vertex& operator/= (const double d); - bool operator== (const vertex& other) const; - bool operator!= (const vertex& other) const; - vertex operator- () const; - int operator< (const vertex& other) const; - double& operator[] (const Axis ax); - const double& operator[] (const Axis ax) const; - double& operator[] (const int ax); - const double& operator[] (const int ax) const; +class vertex +{ public: + vertex() {} + vertex (double x, double y, double z); + + double& coord (const ushort n) + { return m_coords[n]; + } + const double& coord (const ushort n) const + { return m_coords[n]; + } + vertex midpoint (const vertex& other); + void move (const vertex& other); + str stringRep (bool mangled) const; + void transform (matrix matr, vertex pos); + + inline double& x () + { return m_coords[X]; + } + + inline const double& x () const + { return m_coords[X]; + } + + inline double& y () + { return m_coords[Y]; + } -private: - double m_coords[3]; + inline const double& y () const + { return m_coords[Y]; + } + + inline double& z () + { return m_coords[Z]; + } + + inline const double& z () const + { return m_coords[Z]; + } + + vertex& operator+= (const vertex& other); + vertex operator+ (const vertex& other) const; + vertex operator/ (const double d) const; + vertex& operator/= (const double d); + bool operator== (const vertex& other) const; + bool operator!= (const vertex& other) const; + vertex operator- () const; + int operator< (const vertex& other) const; + double& operator[] (const Axis ax); + const double& operator[] (const Axis ax) const; + double& operator[] (const int ax); + const double& operator[] (const int ax) const; + + private: + double m_coords[3]; }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= // List -// +// // Array class that wraps around std::deque // ============================================================================= -template<class T> class List { -public: - typedef typename std::deque<T>::iterator it; - typedef typename std::deque<T>::const_iterator c_it; - typedef typename std::deque<T>::reverse_iterator r_it; - typedef typename std::deque<T>::const_reverse_iterator cr_it; - - List() {} - List (initlist<T> vals) { - m_vect = vals; - } - - it begin() { - return m_vect.begin(); - } - - c_it begin() const { - return m_vect.cbegin(); - } - - it end() { - return m_vect.end(); - } - - c_it end() const { - return m_vect.cend(); - } - - r_it rbegin() { - return m_vect.rbegin(); - } - - cr_it crbegin() const { - return m_vect.crbegin(); - } - - r_it rend() { - return m_vect.rend(); - } - - cr_it crend() const { - return m_vect.crend(); - } - - void erase (ulong pos) { - assert (pos < size()); - m_vect.erase (m_vect.begin() + pos); - } - - T& push_back (const T& value) { - m_vect.push_back (value); - return m_vect[m_vect.size() - 1]; - } - - void push_back (const List<T>& vals) { - for (const T& val : vals) - push_back (val); - } - - bool pop (T& val) { - if (size() == 0) - return false; - - val = m_vect[size() - 1]; - erase (size() - 1); - return true; - } - - T& operator<< (const T& value) { - return push_back (value); - } - - void operator<< (const List<T>& vals) { - push_back (vals); - } - - bool operator>> (T& value) { - return pop (value); - } - - List<T> reverse() const { - List<T> rev; - - for (const T& val : c_rev<T> (*this)) - rev << val; - - return rev; - } - - void clear() { - m_vect.clear(); - } - - void insert (ulong pos, const T& value) { - m_vect.insert (m_vect.begin() + pos, value); - } - - void makeUnique() { - // Remove duplicate entries. For this to be effective, the List must be - // sorted first. - sort(); - it pos = std::unique (begin(), end()); - resize (std::distance (begin(), pos)); - } - - ulong size() const { - return m_vect.size(); - } - - T& operator[] (ulong n) { - assert (n < size()); - return m_vect[n]; - } - - const T& operator[] (ulong n) const { - assert (n < size()); - return m_vect[n]; - } - - void resize (std::ptrdiff_t size) { - m_vect.resize (size); - } - - void sort() { - std::sort (begin(), end()); - } - - ulong find (const T& needle) { - ulong i = 0; - for (const T& hay : *this) { - if (hay == needle) - return i; - - i++; +template<class T> class List +{ public: + typedef typename std::deque<T>::iterator it; + typedef typename std::deque<T>::const_iterator c_it; + typedef typename std::deque<T>::reverse_iterator r_it; + typedef typename std::deque<T>::const_reverse_iterator cr_it; + + List() {} + List (initlist<T> vals) + { m_vect = vals; + } + + inline it begin() + { return m_vect.begin(); + } + + inline c_it begin() const + { return m_vect.cbegin(); + } + + inline it end() + { return m_vect.end(); + } + + inline c_it end() const + { return m_vect.cend(); + } + + inline r_it rbegin() + { return m_vect.rbegin(); + } + + inline cr_it crbegin() const + { return m_vect.crbegin(); + } + + inline r_it rend() + { return m_vect.rend(); + } + + inline cr_it crend() const + { return m_vect.crend(); + } + + void erase (ulong pos) + { assert (pos < size()); + m_vect.erase (m_vect.begin() + pos); + } + + T& push_back (const T& value) + { m_vect.push_back (value); + return m_vect[m_vect.size() - 1]; + } + + void push_back (const List<T>& vals) + { for (const T& val : vals) + push_back (val); + } + + bool pop (T& val) + { if (size() == 0) + return false; + + val = m_vect[size() - 1]; + erase (size() - 1); + return true; + } + + T& operator<< (const T& value) + { return push_back (value); } - - return -1u; - } - -private: - std::deque<T> m_vect; + + void operator<< (const List<T>& vals) + { push_back (vals); + } + + bool operator>> (T& value) + { return pop (value); + } + + List<T> reverse() const + { List<T> rev; + + for (const T& val : c_rev<T> (*this)) + rev << val; + + return rev; + } + + void clear() + { m_vect.clear(); + } + + void insert (ulong pos, const T& value) + { m_vect.insert (m_vect.begin() + pos, value); + } + + void makeUnique() + { // Remove duplicate entries. For this to be effective, the List must be + // sorted first. + sort(); + it pos = std::unique (begin(), end()); + resize (std::distance (begin(), pos)); + } + + ulong size() const + { return m_vect.size(); + } + + T& operator[] (ulong n) + { assert (n < size()); + return m_vect[n]; + } + + const T& operator[] (ulong n) const + { assert (n < size()); + return m_vect[n]; + } + + void resize (std::ptrdiff_t size) + { m_vect.resize (size); + } + + void sort() + { std::sort (begin(), end()); + } + + ulong find (const T& needle) + { ulong i = 0; + + for (const T & hay : *this) + { if (hay == needle) + return i; + + i++; + } + + return -1u; + } + + private: + std::deque<T> m_vect; }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= // ListReverser (aka rev) -// +// // Helper class used to reverse-iterate Lists in range-for-loops. // ============================================================================= -template<class T> class ListReverser { -public: - typedef typename List<T>::r_it it; - - ListReverser (List<T>& vect) { - m_vect = &vect; - } - - it begin() { - return m_vect->rbegin(); - } - - it end() { - return m_vect->rend(); - } - -private: - List<T>* m_vect; +template<class T> class ListReverser +{ public: + typedef typename List<T>::r_it it; + + ListReverser (List<T>& vect) + { m_vect = &vect; + } + + it begin() + { return m_vect->rbegin(); + } + + it end() + { return m_vect->rend(); + } + + private: + List<T>* m_vect; }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= // ConstListReverser (aka c_rev) -// +// // Like ListReverser, except works on const Lists. // ============================================================================= -template<class T> class ConstListReverser { -public: - typedef typename List<T>::cr_it it; - - ConstListReverser (const List<T>& vect) { - m_vect = &vect; - } - - it begin() const { - return m_vect->crbegin(); - } - - it end() const { - return m_vect->crend(); - } - -private: - const List<T>* m_vect; +template<class T> class ConstListReverser +{ public: + typedef typename List<T>::cr_it it; + + ConstListReverser (const List<T>& vect) + { m_vect = &vect; + } + + it begin() const + { return m_vect->crbegin(); + } + + it end() const + { return m_vect->crend(); + } + + private: + const List<T>* m_vect; }; template<class T> using rev = ListReverser<T>; @@ -340,120 +376,123 @@ // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= // StringFormatArg -// +// // Converts a given value into a string that can be retrieved with ::value(). // Used as the argument type to the formatting functions, hence its name. // ============================================================================= -class StringFormatArg { -public: - StringFormatArg (const str& v); - StringFormatArg (const char& v); - StringFormatArg (const uchar& v); - StringFormatArg (const qchar& v); - +class StringFormatArg +{ public: + StringFormatArg (const str& v); + StringFormatArg (const char& v); + StringFormatArg (const uchar& v); + StringFormatArg (const qchar& v); + #define NUMERIC_FORMAT_ARG(T,C) \ StringFormatArg (const T& v) { \ char valstr[32]; \ sprintf (valstr, "%" #C, v); \ m_val = valstr; \ } - - NUMERIC_FORMAT_ARG (int, d) - NUMERIC_FORMAT_ARG (short, d) - NUMERIC_FORMAT_ARG (long, ld) - NUMERIC_FORMAT_ARG (uint, u) - NUMERIC_FORMAT_ARG (ushort, u) - NUMERIC_FORMAT_ARG (ulong, lu) - - StringFormatArg (const float& v); - StringFormatArg (const double& v); - StringFormatArg (const vertex& v); - StringFormatArg (const matrix& v); - StringFormatArg (const char* v); - StringFormatArg (const StringConfig& v); - StringFormatArg (const IntConfig& v); - StringFormatArg (const FloatConfig& v); - StringFormatArg (const void* v); - - template<class T> StringFormatArg (const List<T>& v) { - m_val = "{ "; - - uint i = 0; - for (const T& it : v) { - if (i++) - m_val += ", "; - - StringFormatArg arg (it); - m_val += arg.value(); + + NUMERIC_FORMAT_ARG (int, d) + NUMERIC_FORMAT_ARG (short, d) + NUMERIC_FORMAT_ARG (long, ld) + NUMERIC_FORMAT_ARG (uint, u) + NUMERIC_FORMAT_ARG (ushort, u) + NUMERIC_FORMAT_ARG (ulong, lu) + + StringFormatArg (const float& v); + StringFormatArg (const double& v); + StringFormatArg (const vertex& v); + StringFormatArg (const matrix& v); + StringFormatArg (const char* v); + StringFormatArg (const StringConfig& v); + StringFormatArg (const IntConfig& v); + StringFormatArg (const FloatConfig& v); + StringFormatArg (const void* v); + + template<class T> StringFormatArg (const List<T>& v) + { m_val = "{ "; + + uint i = 0; + + for (const T & it : v) + { if (i++) + m_val += ", "; + + StringFormatArg arg (it); + m_val += arg.value(); + } + + if (i) + m_val += " "; + + m_val += "}"; } - - if (i) - m_val += " "; - - m_val += "}"; - } - - str value() const { return m_val; } -private: - str m_val; + + str value() const + { return m_val; + } + private: + str m_val; }; // ============================================================================= // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ============================================================================= // File -// +// // A file interface with simple interface and support for range-for-loops. // ============================================================================= -class File { -private: - // Iterator class to enable range-for-loop support. Rough hack.. don't use directly! - class iterator { +class File +{ private: + // Iterator class to enable range-for-loop support. Rough hack.. don't use directly! + class iterator + { public: + iterator() : m_file (null) {} // end iterator has m_file == null + iterator (File* f); + void operator++(); + str operator*(); + bool operator== (iterator& other); + bool operator!= (iterator& other); + + private: + File* m_file; + str m_text; + bool m_gotdata = false; + }; + public: - iterator() : m_file (null) {} // end iterator has m_file == null - iterator (File* f); - void operator++(); - str operator*(); - bool operator== (iterator& other); - bool operator!= (iterator& other); - - private: - File* m_file; - str m_text; - bool m_gotdata = false; - }; + enum OpenType + { Read, + Write, + Append + }; -public: - enum OpenType { - Read, - Write, - Append - }; - - File(); - File (str path, File::OpenType rtype); - File (FILE* fp, File::OpenType rtype); - ~File(); - - bool atEnd() const; - iterator begin(); - void close(); - iterator& end(); - bool flush(); - bool isNull() const; - bool readLine (str& line); - void rewind(); - bool open (FILE* fp, OpenType rtype); - bool open (str path, OpenType rtype, FILE* fp = null); - void write (str msg); - - bool operator!() const; - operator bool() const; - -private: - QFile* m_file; - QTextStream* m_textstream; - iterator m_endIterator; + File(); + File (str path, File::OpenType rtype); + File (FILE* fp, File::OpenType rtype); + ~File(); + + bool atEnd() const; + iterator begin(); + void close(); + iterator& end(); + bool flush(); + bool isNull() const; + bool readLine (str& line); + void rewind(); + bool open (FILE* fp, OpenType rtype); + bool open (str path, OpenType rtype, FILE* fp = null); + void write (str msg); + + bool operator!() const; + operator bool() const; + + private: + QFile* m_file; + QTextStream* m_textstream; + iterator m_endIterator; }; // ============================================================================= @@ -462,22 +501,22 @@ // The bounding box is the box that encompasses a given set of objects. // v0 is the minimum vertex, v1 is the maximum vertex. // ============================================================================= -class LDBoundingBox { - READ_PROPERTY (bool, empty, setEmpty) +class LDBoundingBox +{ READ_PROPERTY (bool, empty, setEmpty) READ_PROPERTY (vertex, v0, setV0) READ_PROPERTY (vertex, v1, setV1) - -public: - LDBoundingBox(); - void reset(); - void calculate(); - double size() const; - void calcObject (LDObject* obj); - void calcVertex (const vertex& v); - vertex center() const; - - LDBoundingBox& operator<< (LDObject* obj); - LDBoundingBox& operator<< (const vertex& v); + + public: + LDBoundingBox(); + void reset(); + void calculate(); + double size() const; + void calcObject (LDObject* obj); + void calcVertex (const vertex& v); + vertex center() const; + + LDBoundingBox& operator<< (LDObject* obj); + LDBoundingBox& operator<< (const vertex& v); }; // Formatter function @@ -511,4 +550,4 @@ static const double pi = 3.14159265358979323846; -#endif // TYPES_H \ No newline at end of file +#endif // TYPES_H
--- a/src/widgets.cpp Thu Oct 03 18:07:06 2013 +0300 +++ b/src/widgets.cpp Thu Oct 03 20:56:20 2013 +0300 @@ -27,151 +27,151 @@ #include <map> #include "widgets.h" +#include "moc_widgets.cpp" // ============================================================================= // ----------------------------------------------------------------------------- -RadioGroup::RadioGroup (const QString& title, QWidget* parent) : QGroupBox (title, parent) { - init (Qt::Vertical); +RadioGroup::RadioGroup (const QString& title, QWidget* parent) : QGroupBox (title, parent) +{ init (Qt::Vertical); } // ============================================================================= // ----------------------------------------------------------------------------- -QBoxLayout::Direction makeDirection (Qt::Orientation orient, bool invert = false) { - return (orient == (invert ? Qt::Vertical : Qt::Horizontal)) ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom; +QBoxLayout::Direction makeDirection (Qt::Orientation orient, bool invert = false) +{ return (orient == (invert ? Qt::Vertical : Qt::Horizontal)) ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom; } // ============================================================================= // ----------------------------------------------------------------------------- -bool RadioGroup::isChecked (int n) const { - return m_buttonGroup->checkedId() == n; +bool RadioGroup::isChecked (int n) const +{ return m_buttonGroup->checkedId() == n; } // ============================================================================= // ----------------------------------------------------------------------------- -void RadioGroup::init (Qt::Orientation orient) { - m_vert = orient == Qt::Vertical; - +void RadioGroup::init (Qt::Orientation orient) +{ m_vert = orient == Qt::Vertical; + m_buttonGroup = new QButtonGroup; m_oldId = m_curId = 0; m_coreLayout = null; - - m_coreLayout = new QBoxLayout ((orient == Qt::Vertical) ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom); + + m_coreLayout = new QBoxLayout ( (orient == Qt::Vertical) ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom); setLayout (m_coreLayout); - + // Init the first row with a break rowBreak(); - + connect (m_buttonGroup, SIGNAL (buttonPressed (int)), this, SLOT (slot_buttonPressed (int))); connect (m_buttonGroup, SIGNAL (buttonReleased (int)), this, SLOT (slot_buttonReleased (int))); } // ============================================================================= // ----------------------------------------------------------------------------- -RadioGroup::RadioGroup (const QString& title, initlist<char const*> entries, int const defaultId, - const Qt::Orientation orient, QWidget* parent) : QGroupBox (title, parent), m_defId (defaultId) -{ - init (orient); +RadioGroup::RadioGroup (const QString& title, initlist<char const*> entries, int const defaultId, const Qt::Orientation orient, QWidget* parent) : + QGroupBox (title, parent), + m_defId (defaultId) +{ init (orient); m_oldId = m_defId; - - for (char const* entry : entries) + + for (const char* entry : entries) addButton (entry); } // ============================================================================= // ----------------------------------------------------------------------------- -void RadioGroup::rowBreak() { - QBoxLayout* newLayout = new QBoxLayout (m_vert ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); +void RadioGroup::rowBreak() +{ QBoxLayout* newLayout = new QBoxLayout (m_vert ? QBoxLayout::TopToBottom : QBoxLayout::LeftToRight); m_currentLayout = newLayout; m_layouts << newLayout; - + m_coreLayout->addLayout (newLayout); } // ============================================================================= // ----------------------------------------------------------------------------- -void RadioGroup::addButton (const char* entry) { - QRadioButton* button = new QRadioButton (entry); +void RadioGroup::addButton (const char* entry) +{ QRadioButton* button = new QRadioButton (entry); addButton (button); } // ============================================================================= // ----------------------------------------------------------------------------- -void RadioGroup::addButton (QRadioButton* button) { - bool const selectThis = (m_curId == m_defId); - +void RadioGroup::addButton (QRadioButton* button) +{ bool const selectThis = (m_curId == m_defId); + m_objects << button; m_buttonGroup->addButton (button, m_curId++); m_currentLayout->addWidget (button); - + if (selectThis) button->setChecked (true); } // ============================================================================= // ----------------------------------------------------------------------------- -RadioGroup& RadioGroup::operator<< (QRadioButton* button) { - addButton (button); +RadioGroup& RadioGroup::operator<< (QRadioButton* button) +{ addButton (button); return *this; } // ============================================================================= // ----------------------------------------------------------------------------- -RadioGroup& RadioGroup::operator<< (const char* entry) { - addButton (entry); +RadioGroup& RadioGroup::operator<< (const char* entry) +{ addButton (entry); return *this; } // ============================================================================= // ----------------------------------------------------------------------------- -void RadioGroup::setCurrentRow (uint row) { - m_currentLayout = m_layouts[row]; +void RadioGroup::setCurrentRow (uint row) +{ m_currentLayout = m_layouts[row]; } // ============================================================================= // ----------------------------------------------------------------------------- -int RadioGroup::value() const { - return m_buttonGroup->checkedId(); +int RadioGroup::value() const +{ return m_buttonGroup->checkedId(); } // ============================================================================= // ----------------------------------------------------------------------------- -void RadioGroup::setValue (int val) { - m_buttonGroup->button (val)->setChecked (true); +void RadioGroup::setValue (int val) +{ m_buttonGroup->button (val)->setChecked (true); } // ============================================================================= // ----------------------------------------------------------------------------- -QRadioButton* RadioGroup::operator[] (uint n) const { - return m_objects[n]; +QRadioButton* RadioGroup::operator[] (uint n) const +{ return m_objects[n]; } // ============================================================================= // ----------------------------------------------------------------------------- -void RadioGroup::slot_buttonPressed (int btn) { - emit buttonPressed (btn); - +void RadioGroup::slot_buttonPressed (int btn) +{ emit buttonPressed (btn); + m_oldId = m_buttonGroup->checkedId(); } // ============================================================================= // ----------------------------------------------------------------------------- -void RadioGroup::slot_buttonReleased (int btn) { - emit buttonReleased (btn); +void RadioGroup::slot_buttonReleased (int btn) +{ emit buttonReleased (btn); int newid = m_buttonGroup->checkedId(); - + if (m_oldId != newid) emit valueChanged (newid); } // ============================================================================= // ----------------------------------------------------------------------------- -RadioGroup::it RadioGroup::begin() { - return m_objects.begin(); +RadioGroup::it RadioGroup::begin() +{ return m_objects.begin(); } // ============================================================================= // ----------------------------------------------------------------------------- -RadioGroup::it RadioGroup::end() { - return m_objects.end(); +RadioGroup::it RadioGroup::end() +{ return m_objects.end(); } -#include "moc_widgets.cpp"
--- a/src/widgets.h Thu Oct 03 18:07:06 2013 +0300 +++ b/src/widgets.h Thu Oct 03 20:56:20 2013 +0300 @@ -36,52 +36,58 @@ // // Convenience widget - is a groupbox of radio buttons. // ============================================================================= -class RadioGroup : public QGroupBox { - Q_OBJECT - -public: - typedef List<QRadioButton*>::it it; - - explicit RadioGroup() { init (Qt::Vertical); } - explicit RadioGroup (QWidget* parent = null) : QGroupBox (parent) { init (Qt::Vertical); } - explicit RadioGroup (const QString& title, QWidget* parent = null); - explicit RadioGroup (const QString& title, initlist<char const*> entries, int const defaultId, - const Qt::Orientation orient = Qt::Vertical, QWidget* parent = null); - - void addButton (const char* entry); - void addButton (QRadioButton* button); - it begin (); - it end (); - void init (Qt::Orientation orient); - bool isChecked (int n) const; - void rowBreak (); - void setCurrentRow (uint row); - void setValue (int val); - int value () const; - - QRadioButton* operator[] (uint n) const; - RadioGroup& operator<< (QRadioButton* button); - RadioGroup& operator<< (const char* entry); +class RadioGroup : public QGroupBox +{ Q_OBJECT + + public: + typedef List<QRadioButton*>::it it; + + explicit RadioGroup() + { init (Qt::Vertical); + } + + explicit RadioGroup (QWidget* parent = null) : QGroupBox (parent) + { init (Qt::Vertical); + } + + explicit RadioGroup (const QString& title, QWidget* parent = null); + explicit RadioGroup (const QString& title, initlist<char const*> entries, int const defaultId, + const Qt::Orientation orient = Qt::Vertical, QWidget* parent = null); -signals: - void buttonPressed (int btn); - void buttonReleased (int btn); - void valueChanged (int val); + void addButton (const char* entry); + void addButton (QRadioButton* button); + it begin (); + it end (); + void init (Qt::Orientation orient); + bool isChecked (int n) const; + void rowBreak (); + void setCurrentRow (uint row); + void setValue (int val); + int value () const; + + QRadioButton* operator[] (uint n) const; + RadioGroup& operator<< (QRadioButton* button); + RadioGroup& operator<< (const char* entry); -private: - List<QRadioButton*> m_objects; - List<QBoxLayout*> m_layouts; - QBoxLayout* m_coreLayout; - QBoxLayout* m_currentLayout; - bool m_vert; - int m_curId, m_defId, m_oldId; - QButtonGroup* m_buttonGroup; - - Q_DISABLE_COPY (RadioGroup) + signals: + void buttonPressed (int btn); + void buttonReleased (int btn); + void valueChanged (int val); -private slots: - void slot_buttonPressed (int btn); - void slot_buttonReleased (int btn); + private: + List<QRadioButton*> m_objects; + List<QBoxLayout*> m_layouts; + QBoxLayout* m_coreLayout; + QBoxLayout* m_currentLayout; + bool m_vert; + int m_curId, m_defId, m_oldId; + QButtonGroup* m_buttonGroup; + + Q_DISABLE_COPY (RadioGroup) + + private slots: + void slot_buttonPressed (int btn); + void slot_buttonReleased (int btn); }; -#endif // WIDGETS_H \ No newline at end of file +#endif // WIDGETS_H