- migrated selection from ForgeWindow to individual LDFiles. Should've done this long ago.

Tue, 22 Oct 2013 13:40:16 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Tue, 22 Oct 2013 13:40:16 +0300
changeset 522
afa691788bdb
parent 521
b85554206155
child 523
a12e36f2db5f

- migrated selection from ForgeWindow to individual LDFiles. Should've done this long ago.
- added an operator== for matrix to make stuff actually compile

src/extprogs.cpp file | annotate | diff | comparison | revisions
src/file.cpp file | annotate | diff | comparison | revisions
src/file.h file | annotate | diff | comparison | revisions
src/gldraw.cpp file | annotate | diff | comparison | revisions
src/gui.cpp file | annotate | diff | comparison | revisions
src/gui.h file | annotate | diff | comparison | revisions
src/gui_actions.cpp file | annotate | diff | comparison | revisions
src/gui_editactions.cpp file | annotate | diff | comparison | revisions
src/ldtypes.cpp file | annotate | diff | comparison | revisions
src/ldtypes.h file | annotate | diff | comparison | revisions
src/types.cpp file | annotate | diff | comparison | revisions
src/types.h file | annotate | diff | comparison | revisions
--- a/src/extprogs.cpp	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/extprogs.cpp	Tue Oct 22 13:40:16 2013 +0300
@@ -148,15 +148,15 @@
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-void writeObjects (QList<LDObject*>& objects, File& f)
-{	for (LDObject * obj : objects)
+static void writeObjects (const QList<LDObject*>& objects, File& f)
+{	for (LDObject* obj : objects)
 	{	if (obj->getType() == LDObject::Subfile)
 		{	LDSubfile* ref = static_cast<LDSubfile*> (obj);
 			QList<LDObject*> objs = ref->inlineContents (LDSubfile::DeepInline);
 
 			writeObjects (objs, f);
 
-		for (LDObject * obj : objs)
+			for (LDObject* obj : objs)
 				delete obj;
 		}
 		else
@@ -166,7 +166,7 @@
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-void writeObjects (QList<LDObject*>& objects, str fname)
+static void writeObjects (const QList<LDObject*>& objects, str fname)
 {	// Write the input file
 	File f (fname, File::Write);
 
@@ -182,7 +182,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void writeSelection (str fname)
-{	writeObjects (g_win->sel(), fname);
+{	writeObjects (selection(), fname);
 }
 
 // =============================================================================
@@ -190,7 +190,7 @@
 void writeColorGroup (const short colnum, str fname)
 {	QList<LDObject*> objects;
 
-for (LDObject * obj : LDFile::current()->objects())
+	for (LDObject* obj : LDFile::current()->objects())
 	{	if (obj->isColored() == false || obj->color() != colnum)
 			continue;
 
@@ -280,20 +280,20 @@
 	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();
+	LDFile::current()->clearSelection();
 
-for (LDObject * obj : objs)
+	for (LDObject * obj : objs)
 	{	if (!obj->isScemantic())
 		{	delete obj;
 			continue;
 		}
 
 		LDFile::current()->addObject (obj);
-		g_win->sel() << obj;
+		obj->select();
 	}
 
 	g_win->fullRefresh();
--- a/src/file.cpp	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/file.cpp	Tue Oct 22 13:40:16 2013 +0300
@@ -364,7 +364,7 @@
 		*numWarnings = 0;
 
 	// Calculate the amount of lines
-for (str line : *f)
+	for (str line : *f)
 		lines << line;
 
 	f->rewind();
@@ -1107,7 +1107,6 @@
 
 	if (g_win && f)
 	{	// A ton of stuff needs to be updated
-		g_win->clearSelection();
 		g_win->updateFileListItem (f);
 		g_win->buildObjList();
 		g_win->updateTitle();
@@ -1124,7 +1123,7 @@
 int LDFile::countExplicitFiles()
 {	int count = 0;
 
-for (LDFile * f : g_loadedFiles)
+	for (LDFile* f : g_loadedFiles)
 		if (f->implicit() == false)
 			count++;
 
@@ -1155,3 +1154,40 @@
 	g_logoedStud = openDATFile ("stud-logo.dat", true);
 	g_logoedStud2 = openDATFile ("stud2-logo.dat", true);
 }
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void LDFile::addToSelection (LDObject* obj) // [protected]
+{	if (obj->selected())
+		return;
+
+	assert (obj->file() == this);
+	m_sel << obj;
+	obj->setSelected (true);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void LDFile::removeFromSelection (LDObject* obj) // [protected]
+{	if (!obj->selected())
+		return;
+
+	assert (obj->file() == this);
+	m_sel.removeOne (obj);
+	obj->setSelected (false);
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void LDFile::clearSelection()
+{	for (LDObject* obj : m_sel)
+		removeFromSelection (obj);
+
+	assert (m_sel.isEmpty());
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+const QList<LDObject*>& LDFile::selection() const
+{	return m_sel;
+}
\ No newline at end of file
--- a/src/file.h	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/file.h	Tue Oct 22 13:40:16 2013 +0300
@@ -69,8 +69,10 @@
 
 		int addObject (LDObject* obj);                 // Adds an object to this file at the end of the file.
 		void addObjects (const QList<LDObject*> objs);
+		void clearSelection();
 		void forgetObject (LDObject* obj);               // Deletes the given object from the object chain.
 		str getShortName();
+		const QList<LDObject*>& selection() const;
 		bool hasUnsavedChanges() const;                  // Does this file have unsaved changes?
 		QList<LDObject*> inlineContents (LDSubfile::InlineFlags flags);
 		void insertObj (int pos, LDObject* obj);
@@ -116,8 +118,15 @@
 		static void closeInitialFile();
 		static int countExplicitFiles();
 
+	protected:
+		void addToSelection (LDObject* obj);
+		void removeFromSelection (LDObject* obj);
+		friend class LDObject;
+
 	private:
-		static LDFile* m_curfile;
+		QList<LDObject*>   m_sel;
+
+		static LDFile*     m_curfile;
 };
 
 // Close all current loaded files and start off blank.
@@ -155,6 +164,10 @@
 
 extern QList<LDFile*> g_loadedFiles;
 
+inline const QList<LDObject*>& selection()
+{	return LDFile::current()->selection();
+}
+
 void addRecentFile (str path);
 void loadLogoedStuds();
 str basename (str path);
@@ -168,7 +181,8 @@
 // FileLoader
 //
 // 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.
+// separate class so as to be able to do the work progressively through the
+// event loop, allowing the program to maintain responsivity during loading.
 // =============================================================================
 class FileLoader : public QObject
 {		Q_OBJECT
--- a/src/gldraw.cpp	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/gldraw.cpp	Tue Oct 22 13:40:16 2013 +0300
@@ -1163,13 +1163,11 @@
 
 	// Clear the selection if we do not wish to add to it.
 	if (!m_addpick)
-	{	QList<LDObject*> oldsel = g_win->sel();
-		g_win->sel().clear();
+	{	QList<LDObject*> oldsel = selection();
+		LDFile::current()->clearSelection();
 
 		for (LDObject* obj : oldsel)
-		{	obj->setSelected (false);
 			compileObject (obj);
-		}
 	}
 
 	m_picking = true;
@@ -1241,29 +1239,23 @@
 		// If this is an additive single pick and the object is currently selected,
 		// we remove it from selection instead.
 		if (!m_rangepick && m_addpick)
-		{	int pos = g_win->sel().indexOf (obj);
-
-			if (pos != -1)
-			{	g_win->sel().removeAt (i);
-				obj->setSelected (false);
+		{	if (obj->selected())
+			{	obj->unselect();
 				removedObj = obj;
 				break;
 			}
 		}
 
-		g_win->sel() << obj;
+		obj->select();
 	}
 
 	delete[] pixeldata;
 
-	// Remove duplicated entries
-	removeDuplicates (g_win->sel());
-
 	// Update everything now.
 	g_win->updateSelection();
 
 	// Recompile the objects now to update their color
-	for (LDObject* obj : g_win->sel())
+	for (LDObject* obj : selection())
 		compileObject (obj);
 
 	if (removedObj)
@@ -1311,9 +1303,12 @@
 			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();
+			QList<LDObject*> priorsel = selection();
+			LDFile::current()->clearSelection();
+
+			for (LDObject* obj : priorsel)
+				compileObject (obj);
+
 			g_win->updateSelection();
 			m_drawedVerts.clear();
 		} break;
@@ -1865,11 +1860,11 @@
 
 	pick (ev->x(), ev->y());
 
-	if (g_win->sel().size() == 0)
+	if (selection().isEmpty())
 		return;
 
 	g_win->beginAction (null);
-	LDObject* obj = g_win->sel() [0];
+	LDObject* obj = selection().first();
 	AddObjectDialog::staticDialog (obj->getType(), obj);
 	g_win->endAction();
 	ev->accept();
@@ -1880,7 +1875,7 @@
 LDOverlay* GLRenderer::findOverlayObject (GLRenderer::Camera cam)
 {	LDOverlay* ovlobj = null;
 
-for (LDObject * obj : file()->objects())
+	for (LDObject * obj : file()->objects())
 	{	if (obj->getType() == LDObject::Overlay && static_cast<LDOverlay*> (obj)->camera() == cam)
 		{	ovlobj = static_cast<LDOverlay*> (obj);
 			break;
--- a/src/gui.cpp	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/gui.cpp	Tue Oct 22 13:40:16 2013 +0300
@@ -254,14 +254,14 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 int ForgeWindow::deleteSelection()
-{	if (m_sel.size() == 0)
+{	if (selection().isEmpty())
 		return 0;
 
-	QList<LDObject*> selCopy = m_sel;
+	QList<LDObject*> selCopy = selection();
 	int num = 0;
 
 	// Delete the objects that were being selected
-for (LDObject * obj : selCopy)
+	for (LDObject* obj : selCopy)
 	{	LDFile::current()->forgetObject (obj);
 		++num;
 		delete obj;
@@ -382,10 +382,10 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void ForgeWindow::scrollToSelection()
-{	if (m_sel.size() == 0)
+{	if (selection().isEmpty())
 		return;
 
-	LDObject* obj = m_sel[m_sel.size() - 1];
+	LDObject* obj = selection().last();
 	ui->objectList->scrollToItem (obj->qObjListEntry);
 }
 
@@ -401,30 +401,27 @@
 	if (m_renderer->picking())
 		return;
 
-	QList<LDObject*> priorSelection = m_sel;
+	QList<LDObject*> priorSelection = selection();
 
 	// Get the objects from the object list selection
-	m_sel.clear();
+	LDFile::current()->clearSelection();
 	const QList<QListWidgetItem*> items = ui->objectList->selectedItems();
 
 	for (LDObject* obj : LDFile::current()->objects())
-		for (QListWidgetItem* item : items)
+	{	for (QListWidgetItem* item : items)
 		{	if (item == obj->qObjListEntry)
-			{	m_sel << obj;
+			{	obj->select();
 				break;
 			}
 		}
+	}
 
 	// Update the GL renderer
-	for (LDObject* obj : priorSelection)
-	{	obj->setSelected (false);
-		m_renderer->compileObject (obj);
-	}
+	QList<LDObject*> compound = priorSelection + selection();
+	removeDuplicates (compound);
 
-	for (LDObject* obj : m_sel)
-	{	obj->setSelected (true);
+	for (LDObject* obj : compound)
 		m_renderer->compileObject (obj);
-	}
 
 	m_renderer->update();
 }
@@ -443,7 +440,7 @@
 	QToolButton* button = static_cast<QToolButton*> (sender());
 	LDColor* col = null;
 
-for (const LDQuickColor & entry : m_quickColors)
+	for (const LDQuickColor & entry : m_quickColors)
 	{	if (entry.toolButton() == button)
 		{	col = entry.color();
 			break;
@@ -455,7 +452,7 @@
 
 	short newColor = col->index;
 
-	for (LDObject * obj : m_sel)
+	for (LDObject* obj : selection())
 	{	if (obj->isColored() == false)
 			continue; // uncolored object
 
@@ -470,10 +467,9 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 int 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;
-	}
+{	// If we have a selection, put the item after it.
+	if (!selection().isEmpty())
+		return selection().last()->getIndex() + 1;
 
 	// Otherwise place the object at the end.
 	return LDFile::current()->numObjs();
@@ -498,12 +494,12 @@
 void ForgeWindow::updateSelection()
 {	g_bSelectionLocked = true;
 
-for (LDObject * obj : LDFile::current()->objects())
+	for (LDObject* obj : LDFile::current()->objects())
 		obj->setSelected (false);
 
 	ui->objectList->clearSelection();
 
-for (LDObject * obj : m_sel)
+	for (LDObject* obj : selection())
 	{	if (obj->qObjListEntry == null)
 			continue;
 
@@ -517,20 +513,10 @@
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-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)
+	for (LDObject* obj : selection())
 	{	if (obj->isColored() == false)
 			continue; // doesn't use color
 
@@ -549,7 +535,7 @@
 LDObject::Type ForgeWindow::uniformSelectedType()
 {	LDObject::Type result = LDObject::Unidentified;
 
-for (LDObject * obj : m_sel)
+	for (LDObject * obj : selection())
 	{	if (result != LDObject::Unidentified && obj->color() != result)
 			return LDObject::Unidentified;
 
@@ -579,8 +565,8 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 void ForgeWindow::spawnContextMenu (const QPoint pos)
-{	const bool single = (g_win->sel().size() == 1);
-	LDObject* singleObj = (single) ? g_win->sel() [0] : null;
+{	const bool single = (selection().size() == 1);
+	LDObject* singleObj = (single) ? selection()[0] : null;
 
 	QMenu* contextMenu = new QMenu;
 
@@ -818,10 +804,6 @@
 {	statusBar()->showMessage (text);
 }
 
-void ForgeWindow::clearSelection()
-{	m_sel.clear();
-}
-
 Ui_LDForgeUI* ForgeWindow::interface() const
 {	return ui;
 }
--- a/src/gui.h	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/gui.h	Tue Oct 22 13:40:16 2013 +0300
@@ -105,7 +105,6 @@
 		void updateEditModeActions();
 		void updateFileList();
 		void updateFileListItem (LDFile* f);
-		bool isSelected (LDObject* obj);
 		short getSelectedColor();
 		LDObject::Type uniformSelectedType();
 		void scrollToSelection();
@@ -119,10 +118,6 @@
 		{	return m_renderer;
 		}
 
-		inline QList<LDObject*>& sel()
-		{	return m_sel;
-		}
-
 		inline void setQuickColors (QList<LDQuickColor>& colors)
 		{	m_quickColors = colors;
 		}
@@ -141,7 +136,6 @@
 		void primitiveLoaderStart (int max);
 		void primitiveLoaderUpdate (int prog);
 		void primitiveLoaderEnd();
-		void clearSelection();
 		void slot_action();
 		void changeCurrentFile();
 
--- a/src/gui_actions.cpp	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/gui_actions.cpp	Tue Oct 22 13:40:16 2013 +0300
@@ -231,10 +231,10 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (Edit, 0)
-{	if (g_win->sel().size() != 1)
+{	if (selection().size() != 1)
 		return;
 
-	LDObject* obj = g_win->sel() [0];
+	LDObject* obj = selection() [0];
 	AddObjectDialog::staticDialog (obj->getType(), obj);
 }
 
@@ -259,10 +259,8 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (SelectAll, CTRL (A))
-{	g_win->sel().clear();
-
-	for (LDObject* obj : LDFile::current()->objects())
-		g_win->sel() << obj;
+{	for (LDObject* obj : LDFile::current()->objects())
+		obj->select();
 
 	g_win->updateSelection();
 }
@@ -275,11 +273,11 @@
 	if (colnum == -1)
 		return; // no consensus on color
 
-	g_win->sel().clear();
+	LDFile::current()->clearSelection();
 
 	for (LDObject* obj : LDFile::current()->objects())
 		if (obj->color() == colnum)
-			g_win->sel() << obj;
+			obj->select();
 
 	g_win->updateSelection();
 }
@@ -287,7 +285,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (SelectByType, 0)
-{	if (g_win->sel().size() == 0)
+{	if (selection().isEmpty())
 		return;
 
 	LDObject::Type type = g_win->uniformSelectedType();
@@ -300,14 +298,14 @@
 	str refName;
 
 	if (type == LDObject::Subfile)
-	{	refName = static_cast<LDSubfile*> (g_win->sel() [0])->fileInfo()->name();
+	{	refName = static_cast<LDSubfile*> (selection()[0])->fileInfo()->name();
 
-		for (LDObject* obj : g_win->sel())
+		for (LDObject* obj : selection())
 			if (static_cast<LDSubfile*> (obj)->fileInfo()->name() != refName)
 				return;
 	}
 
-	g_win->sel().clear();
+	LDFile::current()->clearSelection();
 
 	for (LDObject* obj : LDFile::current()->objects())
 	{	if (obj->getType() != type)
@@ -316,7 +314,7 @@
 		if (type == LDObject::Subfile && static_cast<LDSubfile*> (obj)->fileInfo()->name() != refName)
 			continue;
 
-		g_win->sel() << obj;
+		obj->select();
 	}
 
 	g_win->updateSelection();
@@ -364,11 +362,11 @@
 
 	QList<LDObject*> objs = loadFileContents (&f, null);
 
-	g_win->sel().clear();
+	LDFile::current()->clearSelection();
 
 	for (LDObject* obj : objs)
 	{	LDFile::current()->insertObj (idx, obj);
-		g_win->sel() << obj;
+		obj->select();
 		g_win->R()->compileObject (obj);
 
 		idx++;
@@ -381,7 +379,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (ExportTo, 0)
-{	if (g_win->sel().size() == 0)
+{	if (selection().isEmpty())
 		return;
 
 	str fname = QFileDialog::getSaveFileName();
@@ -396,7 +394,7 @@
 		return;
 	}
 
-	for (LDObject* obj : g_win->sel())
+	for (LDObject* obj : selection())
 	{	str contents = obj->raw();
 		QByteArray data = contents.toUtf8();
 		file.write (data, data.size());
@@ -424,13 +422,13 @@
 	if (dlg->exec() == false)
 		return;
 
-	g_win->sel().clear();
+	LDFile::current()->clearSelection();
 
 	for (str line : str (te_edit->toPlainText()).split ("\n"))
 	{	LDObject* obj = parseLine (line);
 
 		LDFile::current()->insertObj (idx, obj);
-		g_win->sel() << obj;
+		obj->select();
 		g_win->R()->compileObject (obj);
 		idx++;
 	}
@@ -475,7 +473,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (Visibility, 0)
-{	for (LDObject* obj : g_win->sel())
+{	for (LDObject* obj : selection())
 		obj->setHidden (!obj->hidden());
 
 	g_win->refresh();
@@ -605,16 +603,16 @@
 	int defval = 0;
 	LDObject* obj;
 
-	if (g_win->sel().size() == 1)
-		defval = g_win->sel() [0]->getIndex();
+	if (selection().size() == 1)
+		defval = selection()[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;
+	LDFile::current()->clearSelection();
+	obj->select();
 	g_win->updateSelection();
 }
--- a/src/gui_editactions.cpp	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/gui_editactions.cpp	Tue Oct 22 13:40:16 2013 +0300
@@ -41,7 +41,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 static int copyToClipboard()
-{	QList<LDObject*> objs = g_win->sel();
+{	QList<LDObject*> objs = selection();
 	int num = 0;
 
 	// Clear the clipboard first.
@@ -82,13 +82,13 @@
 DEFINE_ACTION (Paste, CTRL (V))
 {	const str clipboardText = qApp->clipboard()->text();
 	int idx = g_win->getInsertionPoint();
-	g_win->sel().clear();
+	LDFile::current()->clearSelection();
 	int num = 0;
 
 	for (str line : clipboardText.split ("\n"))
 	{	LDObject* pasted = parseLine (line);
 		LDFile::current()->insertObj (idx++, pasted);
-		g_win->sel() << pasted;
+		pasted->select();
 		g_win->R()->compileObject (pasted);
 		++num;
 	}
@@ -108,7 +108,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 static void doInline (bool deep)
-{	QList<LDObject*> sel = g_win->sel();
+{	QList<LDObject*> sel = selection();
 
 	for (LDObject* obj : sel)
 	{	// Get the index of the subfile so we know where to insert the
@@ -136,7 +136,7 @@
 
 			LDObject* newobj = parseLine (line);
 			LDFile::current()->insertObj (idx++, newobj);
-			g_win->sel() << newobj;
+			newobj->select();
 			g_win->R()->compileObject (newobj);
 		}
 
@@ -159,7 +159,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (SplitQuads, 0)
-{	QList<LDObject*> objs = g_win->sel();
+{	QList<LDObject*> objs = selection();
 	int num = 0;
 
 	for (LDObject* obj : objs)
@@ -195,10 +195,10 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (EditRaw, KEY (F9))
-{	if (g_win->sel().size() != 1)
+{	if (selection().size() != 1)
 		return;
 
-	LDObject* obj = g_win->sel() [0];
+	LDObject* obj = selection()[0];
 	QDialog* dlg = new QDialog;
 	Ui::EditRawUI ui;
 
@@ -229,13 +229,13 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (SetColor, KEY (C))
-{	if (g_win->sel().size() <= 0)
+{	if (selection().isEmpty())
 		return;
 
 	short colnum;
 	short defcol = -1;
 
-	QList<LDObject*> objs = g_win->sel();
+	QList<LDObject*> objs = selection();
 
 	// If all selected objects have the same color, said color is our default
 	// value to the color selection dialog.
@@ -258,17 +258,18 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (Borders, CTRL_SHIFT (B))
-{	QList<LDObject*> objs = g_win->sel();
+{	QList<LDObject*> objs = selection();
 	int num = 0;
 
 	for (LDObject* obj : objs)
-	{	if (obj->getType() != LDObject::Quad && obj->getType() != LDObject::Triangle)
+	{	const LDObject::Type type = obj->getType();
+		if (type != LDObject::Quad && type != LDObject::Triangle)
 			continue;
 
 		short numLines;
 		LDLine* lines[4];
 
-		if (obj->getType() == LDObject::Quad)
+		if (type == LDObject::Quad)
 		{	numLines = 4;
 
 			LDQuad* quad = static_cast<LDQuad*> (obj);
@@ -306,7 +307,7 @@
 DEFINE_ACTION (CornerVerts, 0)
 {	int num = 0;
 
-	for (LDObject* obj : g_win->sel())
+	for (LDObject* obj : selection())
 	{	if (obj->vertices() < 2)
 			continue;
 
@@ -330,7 +331,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 static void doMoveSelection (const bool up)
-{	QList<LDObject*> objs = g_win->sel();
+{	QList<LDObject*> objs = selection();
 	LDObject::moveObjects (objs, up);
 	g_win->buildObjList();
 }
@@ -363,7 +364,7 @@
 	vect[Y] *= currentGrid().confs[Grid::Y]->value;
 	vect[Z] *= currentGrid().confs[Grid::Z]->value;
 
-	for (LDObject* obj : g_win->sel())
+	for (LDObject* obj : selection())
 	{	obj->move (vect);
 		g_win->R()->compileObject (obj);
 	}
@@ -400,7 +401,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (Invert, CTRL_SHIFT (W))
-{	QList<LDObject*> sel = g_win->sel();
+{	QList<LDObject*> sel = selection();
 
 	for (LDObject* obj : sel)
 	{	obj->invert();
@@ -421,7 +422,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 static void doRotate (const short l, const short m, const short n)
-{	QList<LDObject*> sel = g_win->sel();
+{	QList<LDObject*> sel = selection();
 	QList<vertex*> queue;
 	const vertex rotpoint = rotPoint (sel);
 	const double angle = (pi * currentGrid().confs[Grid::Angle]->value) / 180,
@@ -506,7 +507,7 @@
 {	setlocale (LC_ALL, "C");
 	int num = 0;
 
-	for (LDObject* obj : g_win->sel())
+	for (LDObject* obj : selection())
 	{	for (short i = 0; i < obj->vertices(); ++i)
 		{	vertex v = obj->getVertex (i);
 
@@ -532,7 +533,7 @@
 DEFINE_ACTION (Uncolorize, 0)
 {	int num = 0;
 
-	for (LDObject* obj : g_win->sel())
+	for (LDObject* obj : selection())
 	{	if (obj->isColored() == false)
 			continue;
 
@@ -561,21 +562,19 @@
 		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();
 
 	QList<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)
+	for (LDObject* obj : selection())
+	{	for (short i = 0; i < obj->vertices(); ++i)
 		{	vertex v = obj->getVertex (i);
 
 			for (Axis ax : sel)
@@ -593,6 +592,7 @@
 			obj->setVertex (i, v);
 			g_win->R()->compileObject (obj);
 		}
+	}
 
 	log (ForgeWindow::tr ("Altered %1 values"), num);
 	g_win->refresh();
@@ -614,16 +614,17 @@
 	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)
+	for (LDObject* obj : selection())
+	{	for (short i = 0; i < obj->vertices(); ++i)
 		{	vertex v = obj->getVertex (i);
 
-		for (Axis ax : sel)
+			for (Axis ax : sel)
 				v[ax] *= -1;
 
 			obj->setVertex (i, v);
 			g_win->R()->compileObject (obj);
 		}
+	}
 
 	g_win->refresh();
 }
@@ -631,7 +632,7 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 DEFINE_ACTION (Demote, 0)
-{	QList<LDObject*> sel = g_win->sel();
+{	QList<LDObject*> sel = selection();
 	int num = 0;
 
 	for (LDObject* obj : sel)
@@ -670,7 +671,7 @@
 		return;
 	}
 
-	for (LDObject* obj : g_win->sel())
+	for (LDObject* obj : selection())
 	{	if (obj->isColored() == false)
 			continue;
 
--- a/src/ldtypes.cpp	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/ldtypes.cpp	Tue Oct 22 13:40:16 2013 +0300
@@ -264,8 +264,9 @@
 // =============================================================================
 // -----------------------------------------------------------------------------
 LDObject::~LDObject()
-{	// Remove this object from the selection array if it is there.
-	g_win->sel().removeOne (this);
+{	// If this object was selected, unselect it now
+	if (selected())
+		unselect();
 
 	// Delete the GL lists
 	GL::deleteLists (this);
@@ -735,7 +736,7 @@
 
 // =============================================================================
 // -----------------------------------------------------------------------------
-void LDSharedVertex::addRef(LDObject* a)
+void LDSharedVertex::addRef (LDObject* a)
 {	m_refs << a;
 }
 
@@ -748,4 +749,24 @@
 	{	g_sharedVerts.remove (m_data);
 		delete this;
 	}
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
+void LDObject::select()
+{	if (!file())
+	{	log ("Warning: Object #%1 cannot be selected as it is not assigned a file!\n", id());
+		return;
+	}
+
+	file()->addToSelection (this);
+}
+
+void LDObject::unselect()
+{	if (!file())
+	{	log ("Warning: Object #%1 cannot be unselected as it is not assigned a file!\n", id());
+		return;
+	}
+
+	file()->removeFromSelection (this);
 }
\ No newline at end of file
--- a/src/ldtypes.h	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/ldtypes.h	Tue Oct 22 13:40:16 2013 +0300
@@ -96,7 +96,7 @@
 		}
 		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
+		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?
@@ -104,16 +104,16 @@
 		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
-		}
+		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 select();
 		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?
+		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
+		void unselect();
+		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
--- a/src/types.cpp	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/types.cpp	Tue Oct 22 13:40:16 2013 +0300
@@ -265,6 +265,16 @@
 
 // =============================================================================
 // -----------------------------------------------------------------------------
+bool matrix::operator== (const matrix& other) const
+{	for (int i = 0; i < 9; ++i)
+		if (val (i) != other[i])
+			return false;
+
+	return true;
+}
+
+// =============================================================================
+// -----------------------------------------------------------------------------
 StringFormatArg::StringFormatArg (const str& v)
 {	m_val = v;
 }
--- a/src/types.h	Sat Oct 19 02:33:08 2013 +0300
+++ b/src/types.h	Tue Oct 22 13:40:16 2013 +0300
@@ -93,6 +93,8 @@
 		{	return val (idx);
 		}
 
+		bool operator== (const matrix& other) const;
+
 	private:
 		double m_vals[9];
 };

mercurial