+++ /dev/null
-// drawing.cpp
-//
-// Part of the Architektonas Project
-// Originally part of QCad Community Edition by Andrew Mustun
-// Extensively rewritten and refactored by James L. Hammons
-// Portions copyright (C) 2001-2003 RibbonSoft
-// Copyright (C) 2010 Underground Software
-// See the README and GPLv2 files for licensing and warranty information
-//
-// JLH = James L. Hammons <jlhamm@acm.org>
-//
-// Who When What
-// --- ---------- -----------------------------------------------------------
-// JLH 05/21/2010 Added this text. :-)
-// JLH 06/02/2010 Changed all references of this class from RS_Graphic to
-// Drawing, as that makes it more clear that this is what it
-// is (a CAD drawing, not a bitmap).
-//
-
-#include "drawing.h"
-
-#include "debug.h"
-#include "fileio.h"
-#include "mathextra.h"
-#include "units.h"
-#include "settings.h"
-
-/**
- * Default constructor.
- */
-Drawing::Drawing(EntityContainer * parent): Document(parent), layerList(),
- blockList(true)
-#ifdef RS_CAM
- , camData()
-#endif
-{
- settings.beginGroup("Defaults");
- setUnit(Units::stringToUnit(settings.value("Unit", "None").toString()));
- settings.endGroup();
-
- RS2::Unit unit = getUnit();
-
- if (unit == RS2::Inch)
- {
- addVariable("$DIMASZ", 0.1, 40);
- addVariable("$DIMEXE", 0.05, 40);
- addVariable("$DIMEXO", 0.025, 40);
- addVariable("$DIMGAP", 0.025, 40);
- addVariable("$DIMTXT", 0.1, 40);
- }
- else
- {
- addVariable("$DIMASZ", Units::convert(2.5, RS2::Millimeter, unit), 40);
- addVariable("$DIMEXE", Units::convert(1.25, RS2::Millimeter, unit), 40);
- addVariable("$DIMEXO", Units::convert(0.625, RS2::Millimeter, unit), 40);
- addVariable("$DIMGAP", Units::convert(0.625, RS2::Millimeter, unit), 40);
- addVariable("$DIMTXT", Units::convert(2.5, RS2::Millimeter, unit), 40);
- }
-
- setModified(false);
-}
-
-/**
- * Destructor.
- */
-Drawing::~Drawing()
-{
-}
-
-/** @return RS2::EntityDrawing */
-/*virtual*/ RS2::EntityType Drawing::rtti() const
-{
- return RS2::EntityDrawing;
-}
-
-/**
- * Counts the entities on the given layer.
- */
-unsigned long int Drawing::countLayerEntities(Layer * layer)
-{
- int c = 0;
-
- if (layer != NULL)
- {
- for(Entity * t=firstEntity(RS2::ResolveNone); t!=NULL; t=nextEntity(RS2::ResolveNone))
- {
- if (t->getLayer() != NULL && t->getLayer()->getName() == layer->getName())
- {
- c += t->countDeep();
- }
- }
- }
-
- return c;
-}
-
-/*virtual*/ LayerList * Drawing::getLayerList()
-{
- return &layerList;
-}
-
-/*virtual*/ BlockList * Drawing::getBlockList()
-{
- return &blockList;
-}
-
-/**
- * Clears all layers, blocks and entities of this graphic.
- * A default layer (0) is created.
- */
-void Drawing::newDoc()
-{
- DEBUG->print("Drawing::newDoc");
-
- clear();
- clearLayers();
- clearBlocks();
- addLayer(new Layer("0"));
- setModified(false);
-}
-
-/**
- * Saves this graphic with the current filename and settings.
- */
-bool Drawing::save()
-{
- bool ret = false;
-
- DEBUG->print("Drawing::save");
- DEBUG->print(" file: %s", filename.toLatin1().data());
- DEBUG->print(" format: %d", (int)formatType);
- DEBUG->print(" export...");
- ret = FILEIO->fileExport(*this, filename, formatType);
-
- if (ret)
- {
- setModified(false);
- layerList.setModified(false);
- blockList.setModified(false);
- }
-
- DEBUG->print("Drawing::save ok");
-
- return ret;
-}
-
-/**
- * Saves this graphic with the given filename and current settings.
- */
-bool Drawing::saveAs(const QString & filename, RS2::FormatType type)
-{
- DEBUG->print("Drawing::saveAs");
-
- this->filename = filename;
- this->formatType = type;
-
- return save();
-}
-
-/**
- * Loads the given file into this graphic.
- */
-bool Drawing::open(const QString & filename, RS2::FormatType type)
-{
- DEBUG->print("Drawing::open(%s)", filename.toLatin1().data());
- bool ret = false;
- this->filename = filename;
- // clean all:
- newDoc();
- // import file:
- ret = FILEIO->fileImport(*this, filename, type);
- setModified(false);
- layerList.setModified(false);
- blockList.setModified(false);
-
- //cout << *((Drawing*)graphic);
- //calculateBorders();
- DEBUG->print("Drawing::open(%s): OK", filename.toLatin1().data());
-
- return ret;
-}
-
-// Wrappers for Layer functions:
-void Drawing::clearLayers()
-{
- layerList.clear();
-}
-
-uint Drawing::countLayers() const
-{
- return layerList.count();
-}
-
-Layer * Drawing::layerAt(uint i)
-{
- return layerList.at(i);
-}
-
-void Drawing::activateLayer(const QString & name)
-{
- layerList.activate(name);
-}
-
-void Drawing::activateLayer(Layer * layer)
-{
- layerList.activate(layer);
-}
-
-Layer * Drawing::getActiveLayer()
-{
- return layerList.getActive();
-}
-
-/*virtual*/ void Drawing::addLayer(Layer * layer)
-{
- layerList.add(layer);
-}
-
-/**
- * Removes the given layer and undoes all entities on it.
- */
-/*virtual*/ void Drawing::removeLayer(Layer * layer)
-{
- if (layer != NULL && layer->getName() != "0")
- {
- // remove all entities on that layer:
- startUndoCycle();
-
- for(Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone))
- {
- if (e->getLayer() && e->getLayer()->getName() == layer->getName())
- {
- e->setUndoState(true);
- e->setLayer("0");
- addUndoable(e);
- }
- }
-
- endUndoCycle();
-
- // remove all entities in blocks that are on that layer:
- for(uint bi=0; bi<blockList.count(); bi++)
- {
- Block * blk = blockList.at(bi);
-
- if (blk)
- {
- for(Entity * e=blk->firstEntity(RS2::ResolveNone); e!=NULL; e=blk->nextEntity(RS2::ResolveNone))
- {
- if (e->getLayer() != NULL && e->getLayer()->getName() == layer->getName())
- {
- e->setUndoState(true);
- e->setLayer("0");
- //addUndoable(e);
- }
- }
- }
- }
-
- layerList.remove(layer);
- }
-}
-
-/*virtual*/ void Drawing::editLayer(Layer * layer, const Layer & source)
-{
- layerList.edit(layer, source);
-}
-
-Layer * Drawing::findLayer(const QString & name)
-{
- return layerList.find(name);
-}
-
-void Drawing::toggleLayer(const QString & name)
-{
- layerList.toggle(name);
-}
-
-void Drawing::toggleLayer(Layer * layer)
-{
- layerList.toggle(layer);
-}
-
-void Drawing::toggleLayerLock(Layer * layer)
-{
- layerList.toggleLock(layer);
-}
-
-void Drawing::freezeAllLayers(bool freeze)
-{
- layerList.freezeAll(freeze);
-}
-
-#if 0
-void Drawing::addLayerListListener(LayerListListener * listener)
-{
- layerList.addListener(listener);
-}
-
-void Drawing::removeLayerListListener(LayerListListener * listener)
-{
- layerList.removeListener(listener);
-}
-#endif
-
-// Wrapper for block functions:
-
-void Drawing::clearBlocks()
-{
- blockList.clear();
-}
-
-uint Drawing::countBlocks()
-{
- return blockList.count();
-}
-
-Block * Drawing::blockAt(uint i)
-{
- return blockList.at(i);
-}
-
-void Drawing::activateBlock(const QString & name)
-{
- blockList.activate(name);
-}
-
-void Drawing::activateBlock(Block * block)
-{
- blockList.activate(block);
-}
-
-Block * Drawing::getActiveBlock()
-{
- return blockList.getActive();
-}
-
-/*virtual*/ bool Drawing::addBlock(Block * block, bool notify/*= true*/)
-{
- return blockList.add(block, notify);
-}
-
-/*virtual*/ void Drawing::addBlockNotification()
-{
- blockList.addNotification();
-}
-
-/*virtual*/ void Drawing::removeBlock(Block * block)
-{
- blockList.remove(block);
-}
-
-Block * Drawing::findBlock(const QString & name)
-{
- return blockList.find(name);
-}
-
-QString Drawing::newBlockName()
-{
- return blockList.newName();
-}
-
-void Drawing::toggleBlock(const QString & name)
-{
- blockList.toggle(name);
-}
-
-void Drawing::toggleBlock(Block * block)
-{
- blockList.toggle(block);
-}
-
-void Drawing::freezeAllBlocks(bool freeze)
-{
- blockList.freezeAll(freeze);
-}
-
-#if 0
-void Drawing::addBlockListListener(BlockListListener * listener)
-{
- blockList.addListener(listener);
-}
-
-void Drawing::removeBlockListListener(BlockListListener * listener)
-{
- blockList.removeListener(listener);
-}
-#endif
-
-// Wrappers for variable functions:
-void Drawing::clearVariables()
-{
- variableDict.clear();
-}
-
-int Drawing::countVariables()
-{
- return variableDict.count();
-}
-
-void Drawing::addVariable(const QString & key, const Vector & value, int code)
-{
- variableDict.add(key, value, code);
-}
-
-void Drawing::addVariable(const QString & key, const QString & value, int code)
-{
- variableDict.add(key, value, code);
-}
-
-void Drawing::addVariable(const QString & key, int value, int code)
-{
- variableDict.add(key, value, code);
-}
-
-void Drawing::addVariable(const QString & key, double value, int code)
-{
- variableDict.add(key, value, code);
-}
-
-Vector Drawing::getVariableVector(const QString & key, const Vector & def)
-{
- return variableDict.getVector(key, def);
-}
-
-QString Drawing::getVariableString(const QString & key, const QString & def)
-{
- return variableDict.getString(key, def);
-}
-
-int Drawing::getVariableInt(const QString & key, int def)
-{
- return variableDict.getInt(key, def);
-}
-
-double Drawing::getVariableDouble(const QString & key, double def)
-{
- return variableDict.getDouble(key, def);
-}
-
-void Drawing::removeVariable(const QString & key)
-{
- variableDict.remove(key);
-}
-
-//Q3Dict<Variable> & getVariableDict()
-QMultiHash<QString, Variable *> & Drawing::getVariableDict()
-{
- return variableDict.getVariableDict();
-}
-
-/**
- * @return true if the grid is switched on (visible).
- */
-bool Drawing::isGridOn()
-{
- int on = getVariableInt("$GRIDMODE", 1);
-
- return (on != 0);
-}
-
-/**
- * Enables / disables the grid.
- */
-void Drawing::setGridOn(bool on)
-{
- addVariable("$GRIDMODE", (int)on, 70);
-}
-
-/**
- * Sets the unit of this graphic to 'u'
- */
-void Drawing::setUnit(RS2::Unit u)
-{
- setPaperSize(Units::convert(getPaperSize(), getUnit(), u));
- addVariable("$INSUNITS", (int)u, 70);
- //unit = u;
-}
-
-/**
- * Gets the unit of this graphic
- */
-RS2::Unit Drawing::getUnit()
-{
- return (RS2::Unit)getVariableInt("$INSUNITS", 0);
- //return unit;
-}
-
-/**
- * @return The linear format type for this document.
- * This is determined by the variable "$LUNITS".
- */
-RS2::LinearFormat Drawing::getLinearFormat()
-{
- int lunits = getVariableInt("$LUNITS", 2);
-
- switch (lunits)
- {
- default:
- case 2:
- return RS2::Decimal;
- break;
-
- case 1:
- return RS2::Scientific;
- break;
-
- case 3:
- return RS2::Engineering;
- break;
-
- case 4:
- return RS2::Architectural;
- break;
-
- case 5:
- return RS2::Fractional;
- break;
- }
-
- return RS2::Decimal;
-}
-
-/**
- * @return The linear precision for this document.
- * This is determined by the variable "$LUPREC".
- */
-int Drawing::getLinearPrecision()
-{
- return getVariableInt("$LUPREC", 4);
-}
-
-/**
- * @return The angle format type for this document.
- * This is determined by the variable "$AUNITS".
- */
-RS2::AngleFormat Drawing::getAngleFormat()
-{
- int aunits = getVariableInt("$AUNITS", 0);
-
- switch (aunits)
- {
- default:
- case 0:
- return RS2::DegreesDecimal;
- break;
-
- case 1:
- return RS2::DegreesMinutesSeconds;
- break;
-
- case 2:
- return RS2::Gradians;
- break;
-
- case 3:
- return RS2::Radians;
- break;
-
- case 4:
- return RS2::Surveyors;
- break;
- }
-
- return RS2::DegreesDecimal;
-}
-
-/**
- * @return The linear precision for this document.
- * This is determined by the variable "$LUPREC".
- */
-int Drawing::getAnglePrecision()
-{
- return getVariableInt("$AUPREC", 4);
-}
-
-/**
- * @return The insertion point of the drawing into the paper space.
- * This is the distance from the lower left paper edge to the zero
- * point of the drawing. DXF: $PINSBASE.
- */
-Vector Drawing::getPaperInsertionBase()
-{
- return getVariableVector("$PINSBASE", Vector(0.0,0.0));
-}
-
-/**
- * Sets the PINSBASE variable.
- */
-void Drawing::setPaperInsertionBase(const Vector & p)
-{
- addVariable("$PINSBASE", p, 10);
-}
-
-/**
- * @return Paper size in graphic units.
- */
-Vector Drawing::getPaperSize()
-{
- Vector def = Units::convert(Vector(210.0, 297.0), RS2::Millimeter, getUnit());
- Vector v1 = getVariableVector("$PLIMMIN", Vector(0.0, 0.0));
- Vector v2 = getVariableVector("$PLIMMAX", def);
-
- return v2 - v1;
-}
-
-/**
- * Sets a new paper size.
- */
-void Drawing::setPaperSize(const Vector & s)
-{
- addVariable("$PLIMMIN", Vector(0.0, 0.0), 10);
- addVariable("$PLIMMAX", s, 10);
-}
-
-/**
- * @return Paper format.
- * This is determined by the variables "$PLIMMIN" and "$PLIMMAX".
- *
- * @param landscape will be set to true for landscape and false for portrait if not NULL.
- */
-RS2::PaperFormat Drawing::getPaperFormat(bool * landscape)
-{
- Vector size = Units::convert(getPaperSize(), getUnit(), RS2::Millimeter);
-
- if (landscape != NULL)
- *landscape = (size.x > size.y);
-
- return Units::paperSizeToFormat(size);
-}
-
-/**
- * Sets the paper format to the given format.
- */
-void Drawing::setPaperFormat(RS2::PaperFormat f, bool landscape)
-{
- Vector size = Units::paperFormatToSize(f);
-
- if (landscape)
- {
- double tmp = size.x;
- size.x = size.y;
- size.y = tmp;
- }
-
- if (f != RS2::Custom)
- setPaperSize(Units::convert(size, RS2::Millimeter, getUnit()));
-}
-
-/**
- * @return Paper space scaling (DXF: $PSVPSCALE).
- */
-double Drawing::getPaperScale()
-{
- double ret;
-
- ret = getVariableDouble("$PSVPSCALE", 1.0);
-
- if (ret < 1.0e-6)
- ret = 1.0;
-
- return ret;
-}
-
-/**
- * Sets a new scale factor for the paper space.
- */
-void Drawing::setPaperScale(double s)
-{
- addVariable("$PSVPSCALE", s, 40);
-}
-
-/**
- * Centers drawing on page. Affects DXF variable $PINSBASE.
- */
-void Drawing::centerToPage()
-{
- Vector size = getPaperSize();
- double scale = getPaperScale();
- Vector pinsbase = (size - getSize() * scale) / 2.0 - getMin() * scale;
- setPaperInsertionBase(pinsbase);
-}
-
-/**
- * Fits drawing on page. Affects DXF variable $PINSBASE.
- */
-void Drawing::fitToPage()
-{
- double border = Units::convert(25.0, RS2::Millimeter, getUnit());
- Vector ps = getPaperSize() - Vector(border, border);
- Vector s = getSize();
- double fx = RS_MAXDOUBLE;
- double fy = RS_MAXDOUBLE;
- //double factor = 1.0;
-
- //ps = Units::convert(ps, getUnit(), RS2::Millimeter);
-
- if (fabs(s.x) > 1.0e-6)
- fx = ps.x / s.x;
-
- if (fabs(s.y) > 1.0e-6)
- fy = ps.y / s.y;
-
- setPaperScale(std::min(fx, fy));
- centerToPage();
-}
-
-/**
- * @retval true The document has been modified since it was last saved.
- * @retval false The document has not been modified since it was last saved.
- */
-/*virtual*/ bool Drawing::isModified() const
-{
- return modified || layerList.isModified() || blockList.isModified();
-}
-
-/**
- * Sets the documents modified status to 'm'.
- */
-/*virtual*/ void Drawing::setModified(bool m)
-{
- modified = m;
- layerList.setModified(m);
- blockList.setModified(m);
-}
-
-#ifdef RS_CAM
-RS_CamData & Drawing::getCamData()
-{
- return camData;
-}
-
-void Drawing::setCamData(const RS_CamData & d)
-{
- camData = d;
-}
-#endif
-
-/**
- * Dumps the entities to stdout.
- */
-std::ostream & operator<<(std::ostream & os, Drawing & g)
-{
- os << "--- Drawing: \n";
- os << "---" << *g.getLayerList() << "\n";
- os << "---" << *g.getBlockList() << "\n";
- os << "---" << (Undo &)g << "\n";
- os << "---" << (EntityContainer &)g << "\n";
-
- return os;
-}