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. :-)
15 #include "rs_graphic.h"
18 #include "rs_fileio.h"
24 * Default constructor.
26 RS_Graphic::RS_Graphic(RS_EntityContainer * parent): RS_Document(parent), layerList(),
32 settings.beginGroup("Defaults");
33 setUnit(RS_Units::stringToUnit(settings.value("Unit", "None").toString()));
36 RS2::Unit unit = getUnit();
38 if (unit == RS2::Inch)
40 addVariable("$DIMASZ", 0.1, 40);
41 addVariable("$DIMEXE", 0.05, 40);
42 addVariable("$DIMEXO", 0.025, 40);
43 addVariable("$DIMGAP", 0.025, 40);
44 addVariable("$DIMTXT", 0.1, 40);
48 addVariable("$DIMASZ", RS_Units::convert(2.5, RS2::Millimeter, unit), 40);
49 addVariable("$DIMEXE", RS_Units::convert(1.25, RS2::Millimeter, unit), 40);
50 addVariable("$DIMEXO", RS_Units::convert(0.625, RS2::Millimeter, unit), 40);
51 addVariable("$DIMGAP", RS_Units::convert(0.625, RS2::Millimeter, unit), 40);
52 addVariable("$DIMTXT", RS_Units::convert(2.5, RS2::Millimeter, unit), 40);
61 RS_Graphic::~RS_Graphic()
65 /** @return RS2::EntityGraphic */
66 /*virtual*/ RS2::EntityType RS_Graphic::rtti() const
68 return RS2::EntityGraphic;
72 * Counts the entities on the given layer.
74 unsigned long int RS_Graphic::countLayerEntities(RS_Layer * layer)
80 for(RS_Entity * t=firstEntity(RS2::ResolveNone); t!=NULL; t=nextEntity(RS2::ResolveNone))
82 if (t->getLayer()!=NULL && t->getLayer()->getName()==layer->getName())
92 /*virtual*/ RS_LayerList * RS_Graphic::getLayerList()
97 /*virtual*/ RS_BlockList * RS_Graphic::getBlockList()
103 * Clears all layers, blocks and entities of this graphic.
104 * A default layer (0) is created.
106 void RS_Graphic::newDoc()
108 RS_DEBUG->print("RS_Graphic::newDoc");
115 addLayer(new RS_Layer("0"));
116 //addLayer(new RS_Layer("ByBlock"));
122 * Saves this graphic with the current filename and settings.
124 bool RS_Graphic::save()
128 RS_DEBUG->print("RS_Graphic::save");
129 RS_DEBUG->print(" file: %s", filename.toLatin1().data());
130 RS_DEBUG->print(" format: %d", (int)formatType);
132 RS_DEBUG->print(" export...");
133 ret = RS_FILEIO->fileExport(*this, filename, formatType);
138 layerList.setModified(false);
139 blockList.setModified(false);
142 RS_DEBUG->print("RS_Graphic::save ok");
148 * Saves this graphic with the given filename and current settings.
150 bool RS_Graphic::saveAs(const QString & filename, RS2::FormatType type)
152 RS_DEBUG->print("RS_Graphic::saveAs");
154 this->filename = filename;
155 this->formatType = type;
161 * Loads the given fils into this graphic.
163 bool RS_Graphic::open(const QString &filename, RS2::FormatType type)
165 RS_DEBUG->print("RS_Graphic::open(%s)", filename.toLatin1().data());
169 this->filename = filename;
175 ret = RS_FILEIO->fileImport(*this, filename, type);
178 layerList.setModified(false);
179 blockList.setModified(false);
181 //cout << *((RS_Graphic*)graphic);
182 //calculateBorders();
184 RS_DEBUG->print("RS_Graphic::open(%s): OK", filename.toLatin1().data());
189 // Wrappers for Layer functions:
190 void RS_Graphic::clearLayers()
195 uint RS_Graphic::countLayers() const
197 return layerList.count();
200 RS_Layer * RS_Graphic::layerAt(uint i)
202 return layerList.at(i);
205 void RS_Graphic::activateLayer(const QString & name)
207 layerList.activate(name);
210 void RS_Graphic::activateLayer(RS_Layer * layer)
212 layerList.activate(layer);
215 RS_Layer * RS_Graphic::getActiveLayer()
217 return layerList.getActive();
220 /*virtual*/ void RS_Graphic::addLayer(RS_Layer * layer)
222 layerList.add(layer);
226 * Removes the given layer and undoes all entities on it.
228 /*virtual*/ void RS_Graphic::removeLayer(RS_Layer * layer)
230 if (layer != NULL && layer->getName() != "0")
232 // remove all entities on that layer:
235 for(RS_Entity * e=firstEntity(RS2::ResolveNone); e!=NULL; e=nextEntity(RS2::ResolveNone))
237 if (e->getLayer() != NULL && e->getLayer()->getName() == layer->getName())
239 e->setUndoState(true);
247 // remove all entities in blocks that are on that layer:
248 for(uint bi=0; bi<blockList.count(); bi++)
250 RS_Block * blk = blockList.at(bi);
254 for(RS_Entity * e=blk->firstEntity(RS2::ResolveNone); e!=NULL; e=blk->nextEntity(RS2::ResolveNone))
256 if (e->getLayer() != NULL && e->getLayer()->getName() == layer->getName())
258 e->setUndoState(true);
266 layerList.remove(layer);
270 /*virtual*/ void RS_Graphic::editLayer(RS_Layer * layer, const RS_Layer & source)
272 layerList.edit(layer, source);
275 RS_Layer * RS_Graphic::findLayer(const QString & name)
277 return layerList.find(name);
280 void RS_Graphic::toggleLayer(const QString & name)
282 layerList.toggle(name);
285 void RS_Graphic::toggleLayer(RS_Layer * layer)
287 layerList.toggle(layer);
290 void RS_Graphic::toggleLayerLock(RS_Layer * layer)
292 layerList.toggleLock(layer);
295 void RS_Graphic::freezeAllLayers(bool freeze)
297 layerList.freezeAll(freeze);
300 void RS_Graphic::addLayerListListener(RS_LayerListListener * listener)
302 layerList.addListener(listener);
305 void RS_Graphic::removeLayerListListener(RS_LayerListListener * listener)
307 layerList.removeListener(listener);
310 // Wrapper for block functions:
312 void RS_Graphic::clearBlocks()
317 uint RS_Graphic::countBlocks()
319 return blockList.count();
322 RS_Block * RS_Graphic::blockAt(uint i)
324 return blockList.at(i);
327 void RS_Graphic::activateBlock(const QString & name)
329 blockList.activate(name);
332 void RS_Graphic::activateBlock(RS_Block * block)
334 blockList.activate(block);
337 RS_Block * RS_Graphic::getActiveBlock()
339 return blockList.getActive();
342 /*virtual*/ bool RS_Graphic::addBlock(RS_Block * block, bool notify/*= true*/)
344 return blockList.add(block, notify);
347 /*virtual*/ void RS_Graphic::addBlockNotification()
349 blockList.addNotification();
352 /*virtual*/ void RS_Graphic::removeBlock(RS_Block * block)
354 blockList.remove(block);
357 RS_Block * RS_Graphic::findBlock(const QString & name)
359 return blockList.find(name);
362 QString RS_Graphic::newBlockName()
364 return blockList.newName();
367 void RS_Graphic::toggleBlock(const QString & name)
369 blockList.toggle(name);
372 void RS_Graphic::toggleBlock(RS_Block * block)
374 blockList.toggle(block);
377 void RS_Graphic::freezeAllBlocks(bool freeze)
379 blockList.freezeAll(freeze);
382 void RS_Graphic::addBlockListListener(RS_BlockListListener * listener)
384 blockList.addListener(listener);
387 void RS_Graphic::removeBlockListListener(RS_BlockListListener * listener)
389 blockList.removeListener(listener);
392 // Wrappers for variable functions:
393 void RS_Graphic::clearVariables()
395 variableDict.clear();
398 int RS_Graphic::countVariables()
400 return variableDict.count();
403 void RS_Graphic::addVariable(const QString & key, const Vector & value, int code)
405 variableDict.add(key, value, code);
408 void RS_Graphic::addVariable(const QString & key, const QString & value, int code)
410 variableDict.add(key, value, code);
413 void RS_Graphic::addVariable(const QString & key, int value, int code)
415 variableDict.add(key, value, code);
418 void RS_Graphic::addVariable(const QString & key, double value, int code)
420 variableDict.add(key, value, code);
423 Vector RS_Graphic::getVariableVector(const QString & key, const Vector & def)
425 return variableDict.getVector(key, def);
428 QString RS_Graphic::getVariableString(const QString & key, const QString & def)
430 return variableDict.getString(key, def);
433 int RS_Graphic::getVariableInt(const QString & key, int def)
435 return variableDict.getInt(key, def);
438 double RS_Graphic::getVariableDouble(const QString & key, double def)
440 return variableDict.getDouble(key, def);
443 void RS_Graphic::removeVariable(const QString & key)
445 variableDict.remove(key);
448 //Q3Dict<RS_Variable> & getVariableDict()
449 QMultiHash<QString, RS_Variable *> & RS_Graphic::getVariableDict()
451 return variableDict.getVariableDict();
455 * @return true if the grid is switched on (visible).
457 bool RS_Graphic::isGridOn()
459 int on = getVariableInt("$GRIDMODE", 1);
464 * Enables / disables the grid.
466 void RS_Graphic::setGridOn(bool on)
468 addVariable("$GRIDMODE", (int)on, 70);
472 * Sets the unit of this graphic to 'u'
474 void RS_Graphic::setUnit(RS2::Unit u)
476 setPaperSize(RS_Units::convert(getPaperSize(), getUnit(), u));
478 addVariable("$INSUNITS", (int)u, 70);
484 * Gets the unit of this graphic
486 RS2::Unit RS_Graphic::getUnit()
488 return (RS2::Unit)getVariableInt("$INSUNITS", 0);
493 * @return The linear format type for this document.
494 * This is determined by the variable "$LUNITS".
496 RS2::LinearFormat RS_Graphic::getLinearFormat()
498 int lunits = getVariableInt("$LUNITS", 2);
508 return RS2::Scientific;
512 return RS2::Engineering;
516 return RS2::Architectural;
520 return RS2::Fractional;
528 * @return The linear precision for this document.
529 * This is determined by the variable "$LUPREC".
531 int RS_Graphic::getLinearPrecision()
533 return getVariableInt("$LUPREC", 4);
537 * @return The angle format type for this document.
538 * This is determined by the variable "$AUNITS".
540 RS2::AngleFormat RS_Graphic::getAngleFormat()
542 int aunits = getVariableInt("$AUNITS", 0);
548 return RS2::DegreesDecimal;
552 return RS2::DegreesMinutesSeconds;
556 return RS2::Gradians;
564 return RS2::Surveyors;
568 return RS2::DegreesDecimal;
572 * @return The linear precision for this document.
573 * This is determined by the variable "$LUPREC".
575 int RS_Graphic::getAnglePrecision()
577 return getVariableInt("$AUPREC", 4);
581 * @return The insertion point of the drawing into the paper space.
582 * This is the distance from the lower left paper edge to the zero
583 * point of the drawing. DXF: $PINSBASE.
585 Vector RS_Graphic::getPaperInsertionBase()
587 return getVariableVector("$PINSBASE", Vector(0.0,0.0));
591 * Sets the PINSBASE variable.
593 void RS_Graphic::setPaperInsertionBase(const Vector & p)
595 addVariable("$PINSBASE", p, 10);
599 * @return Paper size in graphic units.
601 Vector RS_Graphic::getPaperSize()
603 Vector def = RS_Units::convert(Vector(210.0, 297.0), RS2::Millimeter, getUnit());
605 Vector v1 = getVariableVector("$PLIMMIN", Vector(0.0, 0.0));
606 Vector v2 = getVariableVector("$PLIMMAX", def);
612 * Sets a new paper size.
614 void RS_Graphic::setPaperSize(const Vector & s)
616 addVariable("$PLIMMIN", Vector(0.0, 0.0), 10);
617 addVariable("$PLIMMAX", s, 10);
621 * @return Paper format.
622 * This is determined by the variables "$PLIMMIN" and "$PLIMMAX".
624 * @param landscape will be set to true for landscape and false for portrait if not NULL.
626 RS2::PaperFormat RS_Graphic::getPaperFormat(bool * landscape)
628 Vector size = RS_Units::convert(getPaperSize(), getUnit(), RS2::Millimeter);
630 if (landscape != NULL)
631 *landscape = (size.x > size.y);
633 return RS_Units::paperSizeToFormat(size);
637 * Sets the paper format to the given format.
639 void RS_Graphic::setPaperFormat(RS2::PaperFormat f, bool landscape)
641 Vector size = RS_Units::paperFormatToSize(f);
650 if (f != RS2::Custom)
651 setPaperSize(RS_Units::convert(size, RS2::Millimeter, getUnit()));
655 * @return Paper space scaling (DXF: $PSVPSCALE).
657 double RS_Graphic::getPaperScale()
661 ret = getVariableDouble("$PSVPSCALE", 1.0);
670 * Sets a new scale factor for the paper space.
672 void RS_Graphic::setPaperScale(double s)
674 addVariable("$PSVPSCALE", s, 40);
678 * Centers drawing on page. Affects DXF variable $PINSBASE.
680 void RS_Graphic::centerToPage()
682 Vector size = getPaperSize();
683 double scale = getPaperScale();
684 Vector pinsbase = (size - getSize() * scale) / 2.0 - getMin() * scale;
685 setPaperInsertionBase(pinsbase);
689 * Fits drawing on page. Affects DXF variable $PINSBASE.
691 void RS_Graphic::fitToPage()
693 double border = RS_Units::convert(25.0, RS2::Millimeter, getUnit());
694 Vector ps = getPaperSize() - Vector(border, border);
695 Vector s = getSize();
696 double fx = RS_MAXDOUBLE;
697 double fy = RS_MAXDOUBLE;
698 //double factor = 1.0;
700 //ps = RS_Units::convert(ps, getUnit(), RS2::Millimeter);
702 if (fabs(s.x) > 1.0e-6)
705 if (fabs(s.y) > 1.0e-6)
708 setPaperScale(std::min(fx, fy));
713 * @retval true The document has been modified since it was last saved.
714 * @retval false The document has not been modified since it was last saved.
716 /*virtual*/ bool RS_Graphic::isModified() const
718 return modified || layerList.isModified() || blockList.isModified();
722 * Sets the documents modified status to 'm'.
724 /*virtual*/ void RS_Graphic::setModified(bool m)
727 layerList.setModified(m);
728 blockList.setModified(m);
732 RS_CamData & RS_Graphic::getCamData()
737 void RS_Graphic::setCamData(const RS_CamData & d)
744 * Dumps the entities to stdout.
746 std::ostream & operator<<(std::ostream & os, RS_Graphic & g)
748 os << "--- Graphic: \n";
749 os << "---" << *g.getLayerList() << "\n";
750 os << "---" << *g.getBlockList() << "\n";
751 os << "---" << (RS_Undo&)g << "\n";
752 os << "---" << (RS_EntityContainer&)g << "\n";