3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // (C) 2010 Underground Software
8 // JLH = James L. Hammons <jlhamm@acm.org>
11 // --- ---------- -----------------------------------------------------------
12 // JLH 05/21/2010 Added this text. :-)
13 // JLH 06/02/2010 Changed all references of this class from RS_Graphic to
14 // Drawing, as that makes it more clear that this is what it
15 // is (a CAD drawing, not a bitmap).
21 #include "rs_fileio.h"
27 * Default constructor.
29 Drawing::Drawing(RS_EntityContainer * parent): RS_Document(parent), layerList(),
35 settings.beginGroup("Defaults");
36 setUnit(RS_Units::stringToUnit(settings.value("Unit", "None").toString()));
39 RS2::Unit unit = getUnit();
41 if (unit == RS2::Inch)
43 addVariable("$DIMASZ", 0.1, 40);
44 addVariable("$DIMEXE", 0.05, 40);
45 addVariable("$DIMEXO", 0.025, 40);
46 addVariable("$DIMGAP", 0.025, 40);
47 addVariable("$DIMTXT", 0.1, 40);
51 addVariable("$DIMASZ", RS_Units::convert(2.5, RS2::Millimeter, unit), 40);
52 addVariable("$DIMEXE", RS_Units::convert(1.25, RS2::Millimeter, unit), 40);
53 addVariable("$DIMEXO", RS_Units::convert(0.625, RS2::Millimeter, unit), 40);
54 addVariable("$DIMGAP", RS_Units::convert(0.625, RS2::Millimeter, unit), 40);
55 addVariable("$DIMTXT", RS_Units::convert(2.5, RS2::Millimeter, unit), 40);
68 /** @return RS2::EntityGraphic */
69 /*virtual*/ RS2::EntityType Drawing::rtti() const
71 return RS2::EntityGraphic;
75 * Counts the entities on the given layer.
77 unsigned long int Drawing::countLayerEntities(RS_Layer * layer)
83 for(RS_Entity * t=firstEntity(RS2::ResolveNone); t!=NULL; t=nextEntity(RS2::ResolveNone))
85 if (t->getLayer()!=NULL && t->getLayer()->getName()==layer->getName())
95 /*virtual*/ RS_LayerList * Drawing::getLayerList()
100 /*virtual*/ RS_BlockList * Drawing::getBlockList()
106 * Clears all layers, blocks and entities of this graphic.
107 * A default layer (0) is created.
109 void Drawing::newDoc()
111 RS_DEBUG->print("Drawing::newDoc");
118 addLayer(new RS_Layer("0"));
119 //addLayer(new RS_Layer("ByBlock"));
125 * Saves this graphic with the current filename and settings.
131 RS_DEBUG->print("Drawing::save");
132 RS_DEBUG->print(" file: %s", filename.toLatin1().data());
133 RS_DEBUG->print(" format: %d", (int)formatType);
135 RS_DEBUG->print(" export...");
136 ret = RS_FILEIO->fileExport(*this, filename, formatType);
141 layerList.setModified(false);
142 blockList.setModified(false);
145 RS_DEBUG->print("Drawing::save ok");
151 * Saves this graphic with the given filename and current settings.
153 bool Drawing::saveAs(const QString & filename, RS2::FormatType type)
155 RS_DEBUG->print("Drawing::saveAs");
157 this->filename = filename;
158 this->formatType = type;
164 * Loads the given fils into this graphic.
166 bool Drawing::open(const QString &filename, RS2::FormatType type)
168 RS_DEBUG->print("Drawing::open(%s)", filename.toLatin1().data());
172 this->filename = filename;
178 ret = RS_FILEIO->fileImport(*this, filename, type);
181 layerList.setModified(false);
182 blockList.setModified(false);
184 //cout << *((Drawing*)graphic);
185 //calculateBorders();
187 RS_DEBUG->print("Drawing::open(%s): OK", filename.toLatin1().data());
192 // Wrappers for Layer functions:
193 void Drawing::clearLayers()
198 uint Drawing::countLayers() const
200 return layerList.count();
203 RS_Layer * Drawing::layerAt(uint i)
205 return layerList.at(i);
208 void Drawing::activateLayer(const QString & name)
210 layerList.activate(name);
213 void Drawing::activateLayer(RS_Layer * layer)
215 layerList.activate(layer);
218 RS_Layer * Drawing::getActiveLayer()
220 return layerList.getActive();
223 /*virtual*/ void Drawing::addLayer(RS_Layer * layer)
225 layerList.add(layer);
229 * Removes the given layer and undoes all entities on it.
231 /*virtual*/ void Drawing::removeLayer(RS_Layer * layer)
233 if (layer != NULL && layer->getName() != "0")
235 // remove all entities on that layer:
238 for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone))
240 if (e->getLayer() != NULL && e->getLayer()->getName() == layer->getName())
242 e->setUndoState(true);
250 // remove all entities in blocks that are on that layer:
251 for(uint bi=0; bi<blockList.count(); bi++)
253 RS_Block * blk = blockList.at(bi);
257 for(RS_Entity * e=blk->firstEntity(RS2::ResolveNone); e!=NULL; e=blk->nextEntity(RS2::ResolveNone))
259 if (e->getLayer() != NULL && e->getLayer()->getName() == layer->getName())
261 e->setUndoState(true);
269 layerList.remove(layer);
273 /*virtual*/ void Drawing::editLayer(RS_Layer * layer, const RS_Layer & source)
275 layerList.edit(layer, source);
278 RS_Layer * Drawing::findLayer(const QString & name)
280 return layerList.find(name);
283 void Drawing::toggleLayer(const QString & name)
285 layerList.toggle(name);
288 void Drawing::toggleLayer(RS_Layer * layer)
290 layerList.toggle(layer);
293 void Drawing::toggleLayerLock(RS_Layer * layer)
295 layerList.toggleLock(layer);
298 void Drawing::freezeAllLayers(bool freeze)
300 layerList.freezeAll(freeze);
303 void Drawing::addLayerListListener(RS_LayerListListener * listener)
305 layerList.addListener(listener);
308 void Drawing::removeLayerListListener(RS_LayerListListener * listener)
310 layerList.removeListener(listener);
313 // Wrapper for block functions:
315 void Drawing::clearBlocks()
320 uint Drawing::countBlocks()
322 return blockList.count();
325 RS_Block * Drawing::blockAt(uint i)
327 return blockList.at(i);
330 void Drawing::activateBlock(const QString & name)
332 blockList.activate(name);
335 void Drawing::activateBlock(RS_Block * block)
337 blockList.activate(block);
340 RS_Block * Drawing::getActiveBlock()
342 return blockList.getActive();
345 /*virtual*/ bool Drawing::addBlock(RS_Block * block, bool notify/*= true*/)
347 return blockList.add(block, notify);
350 /*virtual*/ void Drawing::addBlockNotification()
352 blockList.addNotification();
355 /*virtual*/ void Drawing::removeBlock(RS_Block * block)
357 blockList.remove(block);
360 RS_Block * Drawing::findBlock(const QString & name)
362 return blockList.find(name);
365 QString Drawing::newBlockName()
367 return blockList.newName();
370 void Drawing::toggleBlock(const QString & name)
372 blockList.toggle(name);
375 void Drawing::toggleBlock(RS_Block * block)
377 blockList.toggle(block);
380 void Drawing::freezeAllBlocks(bool freeze)
382 blockList.freezeAll(freeze);
385 void Drawing::addBlockListListener(RS_BlockListListener * listener)
387 blockList.addListener(listener);
390 void Drawing::removeBlockListListener(RS_BlockListListener * listener)
392 blockList.removeListener(listener);
395 // Wrappers for variable functions:
396 void Drawing::clearVariables()
398 variableDict.clear();
401 int Drawing::countVariables()
403 return variableDict.count();
406 void Drawing::addVariable(const QString & key, const Vector & value, int code)
408 variableDict.add(key, value, code);
411 void Drawing::addVariable(const QString & key, const QString & value, int code)
413 variableDict.add(key, value, code);
416 void Drawing::addVariable(const QString & key, int value, int code)
418 variableDict.add(key, value, code);
421 void Drawing::addVariable(const QString & key, double value, int code)
423 variableDict.add(key, value, code);
426 Vector Drawing::getVariableVector(const QString & key, const Vector & def)
428 return variableDict.getVector(key, def);
431 QString Drawing::getVariableString(const QString & key, const QString & def)
433 return variableDict.getString(key, def);
436 int Drawing::getVariableInt(const QString & key, int def)
438 return variableDict.getInt(key, def);
441 double Drawing::getVariableDouble(const QString & key, double def)
443 return variableDict.getDouble(key, def);
446 void Drawing::removeVariable(const QString & key)
448 variableDict.remove(key);
451 //Q3Dict<RS_Variable> & getVariableDict()
452 QMultiHash<QString, RS_Variable *> & Drawing::getVariableDict()
454 return variableDict.getVariableDict();
458 * @return true if the grid is switched on (visible).
460 bool Drawing::isGridOn()
462 int on = getVariableInt("$GRIDMODE", 1);
467 * Enables / disables the grid.
469 void Drawing::setGridOn(bool on)
471 addVariable("$GRIDMODE", (int)on, 70);
475 * Sets the unit of this graphic to 'u'
477 void Drawing::setUnit(RS2::Unit u)
479 setPaperSize(RS_Units::convert(getPaperSize(), getUnit(), u));
481 addVariable("$INSUNITS", (int)u, 70);
487 * Gets the unit of this graphic
489 RS2::Unit Drawing::getUnit()
491 return (RS2::Unit)getVariableInt("$INSUNITS", 0);
496 * @return The linear format type for this document.
497 * This is determined by the variable "$LUNITS".
499 RS2::LinearFormat Drawing::getLinearFormat()
501 int lunits = getVariableInt("$LUNITS", 2);
511 return RS2::Scientific;
515 return RS2::Engineering;
519 return RS2::Architectural;
523 return RS2::Fractional;
531 * @return The linear precision for this document.
532 * This is determined by the variable "$LUPREC".
534 int Drawing::getLinearPrecision()
536 return getVariableInt("$LUPREC", 4);
540 * @return The angle format type for this document.
541 * This is determined by the variable "$AUNITS".
543 RS2::AngleFormat Drawing::getAngleFormat()
545 int aunits = getVariableInt("$AUNITS", 0);
551 return RS2::DegreesDecimal;
555 return RS2::DegreesMinutesSeconds;
559 return RS2::Gradians;
567 return RS2::Surveyors;
571 return RS2::DegreesDecimal;
575 * @return The linear precision for this document.
576 * This is determined by the variable "$LUPREC".
578 int Drawing::getAnglePrecision()
580 return getVariableInt("$AUPREC", 4);
584 * @return The insertion point of the drawing into the paper space.
585 * This is the distance from the lower left paper edge to the zero
586 * point of the drawing. DXF: $PINSBASE.
588 Vector Drawing::getPaperInsertionBase()
590 return getVariableVector("$PINSBASE", Vector(0.0,0.0));
594 * Sets the PINSBASE variable.
596 void Drawing::setPaperInsertionBase(const Vector & p)
598 addVariable("$PINSBASE", p, 10);
602 * @return Paper size in graphic units.
604 Vector Drawing::getPaperSize()
606 Vector def = RS_Units::convert(Vector(210.0, 297.0), RS2::Millimeter, getUnit());
608 Vector v1 = getVariableVector("$PLIMMIN", Vector(0.0, 0.0));
609 Vector v2 = getVariableVector("$PLIMMAX", def);
615 * Sets a new paper size.
617 void Drawing::setPaperSize(const Vector & s)
619 addVariable("$PLIMMIN", Vector(0.0, 0.0), 10);
620 addVariable("$PLIMMAX", s, 10);
624 * @return Paper format.
625 * This is determined by the variables "$PLIMMIN" and "$PLIMMAX".
627 * @param landscape will be set to true for landscape and false for portrait if not NULL.
629 RS2::PaperFormat Drawing::getPaperFormat(bool * landscape)
631 Vector size = RS_Units::convert(getPaperSize(), getUnit(), RS2::Millimeter);
633 if (landscape != NULL)
634 *landscape = (size.x > size.y);
636 return RS_Units::paperSizeToFormat(size);
640 * Sets the paper format to the given format.
642 void Drawing::setPaperFormat(RS2::PaperFormat f, bool landscape)
644 Vector size = RS_Units::paperFormatToSize(f);
653 if (f != RS2::Custom)
654 setPaperSize(RS_Units::convert(size, RS2::Millimeter, getUnit()));
658 * @return Paper space scaling (DXF: $PSVPSCALE).
660 double Drawing::getPaperScale()
664 ret = getVariableDouble("$PSVPSCALE", 1.0);
673 * Sets a new scale factor for the paper space.
675 void Drawing::setPaperScale(double s)
677 addVariable("$PSVPSCALE", s, 40);
681 * Centers drawing on page. Affects DXF variable $PINSBASE.
683 void Drawing::centerToPage()
685 Vector size = getPaperSize();
686 double scale = getPaperScale();
687 Vector pinsbase = (size - getSize() * scale) / 2.0 - getMin() * scale;
688 setPaperInsertionBase(pinsbase);
692 * Fits drawing on page. Affects DXF variable $PINSBASE.
694 void Drawing::fitToPage()
696 double border = RS_Units::convert(25.0, RS2::Millimeter, getUnit());
697 Vector ps = getPaperSize() - Vector(border, border);
698 Vector s = getSize();
699 double fx = RS_MAXDOUBLE;
700 double fy = RS_MAXDOUBLE;
701 //double factor = 1.0;
703 //ps = RS_Units::convert(ps, getUnit(), RS2::Millimeter);
705 if (fabs(s.x) > 1.0e-6)
708 if (fabs(s.y) > 1.0e-6)
711 setPaperScale(std::min(fx, fy));
716 * @retval true The document has been modified since it was last saved.
717 * @retval false The document has not been modified since it was last saved.
719 /*virtual*/ bool Drawing::isModified() const
721 return modified || layerList.isModified() || blockList.isModified();
725 * Sets the documents modified status to 'm'.
727 /*virtual*/ void Drawing::setModified(bool m)
730 layerList.setModified(m);
731 blockList.setModified(m);
735 RS_CamData & Drawing::getCamData()
740 void Drawing::setCamData(const RS_CamData & d)
747 * Dumps the entities to stdout.
749 std::ostream & operator<<(std::ostream & os, Drawing & g)
751 os << "--- Drawing: \n";
752 os << "---" << *g.getLayerList() << "\n";
753 os << "---" << *g.getBlockList() << "\n";
754 os << "---" << (RS_Undo&)g << "\n";
755 os << "---" << (RS_EntityContainer&)g << "\n";