- moved most of LDColorData API into LDColor

Sun, 22 Jun 2014 03:55:56 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sun, 22 Jun 2014 03:55:56 +0300
changeset 806
4240f47aa2d4
parent 805
d88c0354de97
child 807
2a8889692c25

- moved most of LDColorData API into LDColor
- finally removed the DEFINE_ACTION macro, shortcut management stuff migrated to use the Qt meta system

src/actions.cc file | annotate | diff | comparison | revisions
src/actionsEdit.cc file | annotate | diff | comparison | revisions
src/addObjectDialog.cc file | annotate | diff | comparison | revisions
src/colorSelector.cc file | annotate | diff | comparison | revisions
src/colors.cc file | annotate | diff | comparison | revisions
src/colors.h file | annotate | diff | comparison | revisions
src/configDialog.cc file | annotate | diff | comparison | revisions
src/configDialog.h file | annotate | diff | comparison | revisions
src/configuration.cc file | annotate | diff | comparison | revisions
src/configuration.h file | annotate | diff | comparison | revisions
src/extPrograms.cc file | annotate | diff | comparison | revisions
src/format.h file | annotate | diff | comparison | revisions
src/glCompiler.cc file | annotate | diff | comparison | revisions
src/ldConfig.cc file | annotate | diff | comparison | revisions
src/ldObject.cc file | annotate | diff | comparison | revisions
src/mainWindow.cc file | annotate | diff | comparison | revisions
src/mainWindow.h file | annotate | diff | comparison | revisions
src/partDownloader.cc file | annotate | diff | comparison | revisions
src/primitives.cc file | annotate | diff | comparison | revisions
ui/ldforge.ui file | annotate | diff | comparison | revisions
--- a/src/actions.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/actions.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -48,7 +48,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (New, CTRL_SHIFT (N))
+void MainWindow::slot_actionNew()
 {
 	QDialog* dlg = new QDialog (g_win);
 	Ui::NewPartUI ui;
@@ -114,14 +114,14 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (NewFile, CTRL (N))
+void MainWindow::slot_actionNewFile()
 {
 	newFile();
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (Open, CTRL (O))
+void MainWindow::slot_actionOpen()
 {
 	QString name = QFileDialog::getOpenFileName (g_win, "Open File", "", "LDraw files (*.dat *.ldr)");
 
@@ -133,21 +133,21 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Save, CTRL (S))
+void MainWindow::slot_actionSave()
 {
 	save (getCurrentDocument(), false);
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (SaveAs, CTRL_SHIFT (S))
+void MainWindow::slot_actionSaveAs()
 {
 	save (getCurrentDocument(), true);
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (SaveAll, CTRL (L))
+void MainWindow::slot_actionSaveAll()
 {
 	for (LDDocumentPtr file : LDDocument::explicitDocuments())
 		save (file, false);
@@ -155,7 +155,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Close, CTRL (W))
+void MainWindow::slot_actionClose()
 {
 	if (not getCurrentDocument()->isSafeToClose())
 		return;
@@ -165,7 +165,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (CloseAll, 0)
+void MainWindow::slot_actionCloseAll()
 {
 	if (not safeToCloseAll())
 		return;
@@ -175,84 +175,84 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Settings, 0)
+void MainWindow::slot_actionSettings()
 {
 	(new ConfigDialog)->exec();
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (SetLDrawPath, 0)
+void MainWindow::slot_actionSetLDrawPath()
 {
 	(new LDrawPathDialog (true))->exec();
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (Exit, CTRL (Q))
+void MainWindow::slot_actionExit()
 {
 	exit (0);
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (NewSubfile, 0)
+void MainWindow::slot_actionNewSubfile()
 {
 	AddObjectDialog::staticDialog (OBJ_Subfile, LDObjectPtr());
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (NewLine, 0)
+void MainWindow::slot_actionNewLine()
 {
 	AddObjectDialog::staticDialog (OBJ_Line, LDObjectPtr());
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (NewTriangle, 0)
+void MainWindow::slot_actionNewTriangle()
 {
 	AddObjectDialog::staticDialog (OBJ_Triangle, LDObjectPtr());
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (NewQuad, 0)
+void MainWindow::slot_actionNewQuad()
 {
 	AddObjectDialog::staticDialog (OBJ_Quad, LDObjectPtr());
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (NewCLine, 0)
+void MainWindow::slot_actionNewCLine()
 {
 	AddObjectDialog::staticDialog (OBJ_CondLine, LDObjectPtr());
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (NewComment, 0)
+void MainWindow::slot_actionNewComment()
 {
 	AddObjectDialog::staticDialog (OBJ_Comment, LDObjectPtr());
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (NewBFC, 0)
+void MainWindow::slot_actionNewBFC()
 {
 	AddObjectDialog::staticDialog (OBJ_BFC, LDObjectPtr());
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (NewVertex, 0)
+void MainWindow::slot_actionNewVertex()
 {
 	AddObjectDialog::staticDialog (OBJ_Vertex, LDObjectPtr());
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (Edit, 0)
+void MainWindow::slot_actionEdit()
 {
 	if (selection().size() != 1)
 		return;
@@ -263,27 +263,27 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Help, KEY (F1))
+void MainWindow::slot_actionHelp()
 {
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (About, 0)
+void MainWindow::slot_actionAbout()
 {
 	AboutDialog().exec();
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (AboutQt, 0)
+void MainWindow::slot_actionAboutQt()
 {
 	QMessageBox::aboutQt (g_win);
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (SelectAll, CTRL (A))
+void MainWindow::slot_actionSelectAll()
 {
 	for (LDObjectPtr obj : getCurrentDocument()->objects())
 		obj->select();
@@ -294,7 +294,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (SelectByColor, CTRL_SHIFT (A))
+void MainWindow::slot_actionSelectByColor()
 {
 	if (selection().isEmpty())
 		return;
@@ -322,7 +322,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (SelectByType, 0)
+void MainWindow::slot_actionSelectByType()
 {
 	if (selection().isEmpty())
 		return;
@@ -362,19 +362,19 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (GridCoarse, 0)
+void MainWindow::slot_actionGridCoarse()
 {
 	cfg::grid = Grid::Coarse;
 	updateGridToolBar();
 }
 
-DEFINE_ACTION (GridMedium, 0)
+void MainWindow::slot_actionGridMedium()
 {
 	cfg::grid = Grid::Medium;
 	updateGridToolBar();
 }
 
-DEFINE_ACTION (GridFine, 0)
+void MainWindow::slot_actionGridFine()
 {
 	cfg::grid = Grid::Fine;
 	updateGridToolBar();
@@ -382,7 +382,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (ResetView, CTRL (0))
+void MainWindow::slot_actionResetView()
 {
 	R()->resetAngles();
 	R()->update();
@@ -390,7 +390,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (InsertFrom, 0)
+void MainWindow::slot_actionInsertFrom()
 {
 	QString fname = QFileDialog::getOpenFileName();
 	int idx = getInsertionPoint();
@@ -425,7 +425,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (ExportTo, 0)
+void MainWindow::slot_actionExportTo()
 {
 	if (selection().isEmpty())
 		return;
@@ -454,7 +454,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (InsertRaw, 0)
+void MainWindow::slot_actionInsertRaw()
 {
 	int idx = getInsertionPoint();
 
@@ -490,7 +490,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Screenshot, 0)
+void MainWindow::slot_actionScreenshot()
 {
 	setlocale (LC_ALL, "C");
 
@@ -516,7 +516,7 @@
 // =============================================================================
 //
 EXTERN_CFGENTRY (Bool, drawAxes);
-DEFINE_ACTION (Axes, 0)
+void MainWindow::slot_actionAxes()
 {
 	cfg::drawAxes = not cfg::drawAxes;
 	updateActions();
@@ -525,7 +525,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (VisibilityToggle, 0)
+void MainWindow::slot_actionVisibilityToggle()
 {
 	for (LDObjectPtr obj : selection())
 		obj->setHidden (not obj->isHidden());
@@ -535,7 +535,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (VisibilityHide, 0)
+void MainWindow::slot_actionVisibilityHide()
 {
 	for (LDObjectPtr obj : selection())
 		obj->setHidden (true);
@@ -545,7 +545,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (VisibilityReveal, 0)
+void MainWindow::slot_actionVisibilityReveal()
 {
 	for (LDObjectPtr obj : selection())
 	obj->setHidden (false);
@@ -554,7 +554,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Wireframe, 0)
+void MainWindow::slot_actionWireframe()
 {
 	cfg::drawWireframe = not cfg::drawWireframe;
 	R()->refresh();
@@ -562,7 +562,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (SetOverlay,  0)
+void MainWindow::slot_actionSetOverlay()
 {
 	OverlayDialog dlg;
 
@@ -575,35 +575,35 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (ClearOverlay, 0)
+void MainWindow::slot_actionClearOverlay()
 {
 	R()->clearOverlay();
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (ModeSelect, CTRL (1))
+void MainWindow::slot_actionModeSelect()
 {
 	R()->setEditMode (ESelectMode);
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (ModeDraw, CTRL (2))
+void MainWindow::slot_actionModeDraw()
 {
 	R()->setEditMode (EDrawMode);
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (ModeCircle, CTRL (3))
+void MainWindow::slot_actionModeCircle()
 {
 	R()->setEditMode (ECircleMode);
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (DrawAngles, 0)
+void MainWindow::slot_actionDrawAngles()
 {
 	cfg::drawAngles = not cfg::drawAngles;
 	R()->refresh();
@@ -611,7 +611,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (SetDrawDepth, 0)
+void MainWindow::slot_actionSetDrawDepth()
 {
 	if (R()->camera() == EFreeCamera)
 		return;
@@ -629,7 +629,7 @@
 // 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))
+void MainWindow::slot_actiontestpic()
 {
 	LDDocumentPtr file = getFile ("axle.dat");
 	setlocale (LC_ALL, "C");
@@ -676,14 +676,14 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (ScanPrimitives, 0)
+void MainWindow::slot_actionScanPrimitives()
 {
 	PrimitiveScanner::start();
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (BFCView, SHIFT (B))
+void MainWindow::slot_actionBFCView()
 {
 	cfg::bfcRedGreenView = not cfg::bfcRedGreenView;
 
@@ -696,7 +696,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (JumpTo, CTRL (G))
+void MainWindow::slot_actionJumpTo()
 {
 	bool ok;
 	int defval = 0;
@@ -718,7 +718,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (SubfileSelection, 0)
+void MainWindow::slot_actionSubfileSelection()
 {
 	if (selection().size() == 0)
 		return;
@@ -886,7 +886,7 @@
 	}
 }
 
-DEFINE_ACTION (RandomColors, CTRL_SHIFT (R))
+void MainWindow::slot_actionRandomColors()
 {
 	cfg::randomColors = not cfg::randomColors;
 
@@ -897,7 +897,7 @@
 	R()->refresh();
 }
 
-DEFINE_ACTION (OpenSubfiles, 0)
+void MainWindow::slot_actionOpenSubfiles()
 {
 	for (LDObjectPtr obj : selection())
 	{
--- a/src/actionsEdit.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/actionsEdit.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -70,7 +70,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Cut, CTRL (X))
+void MainWindow::slot_actionCut()
 {
 	int num = copyToClipboard();
 	deleteSelection();
@@ -79,7 +79,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Copy, CTRL (C))
+void MainWindow::slot_actionCopy()
 {
 	int num = copyToClipboard();
 	print (tr ("%1 objects copied"), num);
@@ -87,7 +87,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Paste, CTRL (V))
+void MainWindow::slot_actionPaste()
 {
 	const QString clipboardText = qApp->clipboard()->text();
 	int idx = getInsertionPoint();
@@ -109,7 +109,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Delete, KEY (Delete))
+void MainWindow::slot_actionDelete()
 {
 	int num = deleteSelection();
 	print (tr ("%1 objects deleted"), num);
@@ -149,19 +149,19 @@
 	g_win->refresh();
 }
 
-DEFINE_ACTION (Inline, CTRL (I))
+void MainWindow::slot_actionInline()
 {
 	doInline (false);
 }
 
-DEFINE_ACTION (InlineDeep, CTRL_SHIFT (I))
+void MainWindow::slot_actionInlineDeep()
 {
 	doInline (true);
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (SplitQuads, 0)
+void MainWindow::slot_actionSplitQuads()
 {
 	int num = 0;
 
@@ -191,7 +191,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (EditRaw, KEY (F9))
+void MainWindow::slot_actionEditRaw()
 {
 	if (selection().size() != 1)
 		return;
@@ -222,7 +222,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (SetColor, KEY (C))
+void MainWindow::slot_actionSetColor()
 {
 	if (selection().isEmpty())
 		return;
@@ -249,7 +249,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Borders, CTRL_SHIFT (B))
+void MainWindow::slot_actionBorders()
 {
 	LDObjectList objs = selection();
 	int num = 0;
@@ -297,7 +297,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (CornerVerts, 0)
+void MainWindow::slot_actionCornerVerts()
 {
 	int num = 0;
 
@@ -333,24 +333,24 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (MoveUp, KEY (PageUp))
+void MainWindow::slot_actionMoveUp()
 {
 	doMoveSelection (true);
 }
 
-DEFINE_ACTION (MoveDown, KEY (PageDown))
+void MainWindow::slot_actionMoveDown()
 {
 	doMoveSelection (false);
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (Undo, CTRL (Z))
+void MainWindow::slot_actionUndo()
 {
 	getCurrentDocument()->undo();
 }
 
-DEFINE_ACTION (Redo, CTRL_SHIFT (Z))
+void MainWindow::slot_actionRedo()
 {
 	getCurrentDocument()->redo();
 }
@@ -370,39 +370,39 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (MoveXNeg, KEY (Left))
+void MainWindow::slot_actionMoveXNeg()
 {
 	doMoveObjects ({-1, 0, 0});
 }
 
-DEFINE_ACTION (MoveYNeg, KEY (Home))
+void MainWindow::slot_actionMoveYNeg()
 {
 	doMoveObjects ({0, -1, 0});
 }
 
-DEFINE_ACTION (MoveZNeg, KEY (Down))
+void MainWindow::slot_actionMoveZNeg()
 {
 	doMoveObjects ({0, 0, -1});
 }
 
-DEFINE_ACTION (MoveXPos, KEY (Right))
+void MainWindow::slot_actionMoveXPos()
 {
 	doMoveObjects ({1, 0, 0});
 }
 
-DEFINE_ACTION (MoveYPos, KEY (End))
+void MainWindow::slot_actionMoveYPos()
 {
 	doMoveObjects ({0, 1, 0});
 }
 
-DEFINE_ACTION (MoveZPos, KEY (Up))
+void MainWindow::slot_actionMoveZPos()
 {
 	doMoveObjects ({0, 0, 1});
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (Invert, CTRL_SHIFT (W))
+void MainWindow::slot_actionInvert()
 {
 	for (LDObjectPtr obj : selection())
 		obj->invert();
@@ -484,39 +484,39 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (RotateXPos, CTRL (Right))
+void MainWindow::slot_actionRotateXPos()
 {
 	doRotate (1, 0, 0);
 }
-DEFINE_ACTION (RotateYPos, CTRL (End))
+void MainWindow::slot_actionRotateYPos()
 {
 	doRotate (0, 1, 0);
 }
-DEFINE_ACTION (RotateZPos, CTRL (Up))
+void MainWindow::slot_actionRotateZPos()
 {
 	doRotate (0, 0, 1);
 }
-DEFINE_ACTION (RotateXNeg, CTRL (Left))
+void MainWindow::slot_actionRotateXNeg()
 {
 	doRotate (-1, 0, 0);
 }
-DEFINE_ACTION (RotateYNeg, CTRL (Home))
+void MainWindow::slot_actionRotateYNeg()
 {
 	doRotate (0, -1, 0);
 }
-DEFINE_ACTION (RotateZNeg, CTRL (Down))
+void MainWindow::slot_actionRotateZNeg()
 {
 	doRotate (0, 0, -1);
 }
 
-DEFINE_ACTION (RotationPoint, (0))
+void MainWindow::slot_actionRotationPoint()
 {
 	configRotationPoint();
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (RoundCoordinates, 0)
+void MainWindow::slot_actionRoundCoordinates()
 {
 	setlocale (LC_ALL, "C");
 	int num = 0;
@@ -557,7 +557,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Uncolor, 0)
+void MainWindow::slot_actionUncolor()
 {
 	int num = 0;
 
@@ -576,7 +576,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (ReplaceCoords, CTRL (R))
+void MainWindow::slot_actionReplaceCoords()
 {
 	QDialog* dlg = new QDialog (g_win);
 	Ui::ReplaceCoordsUI ui;
@@ -628,7 +628,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Flip, CTRL_SHIFT (F))
+void MainWindow::slot_actionFlip()
 {
 	QDialog* dlg = new QDialog;
 	Ui::FlipUI ui;
@@ -664,7 +664,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Demote, 0)
+void MainWindow::slot_actionDemote()
 {
 	LDObjectList sel = selection();
 	int num = 0;
@@ -697,7 +697,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Autocolor, 0)
+void MainWindow::slot_actionAutocolor()
 {
 	int colnum = 0;
 	LDColor color;
@@ -719,13 +719,13 @@
 		obj->setColor (color);
 	}
 
-	print (tr ("Auto-colored: new color is [%1] %2"), colnum, color->name());
+	print (tr ("Auto-colored: new color is [%1] %2"), colnum, color.name());
 	refresh();
 }
 
 // =============================================================================
 //
-DEFINE_ACTION (AddHistoryLine, 0)
+void MainWindow::slot_actionAddHistoryLine()
 {
 	LDObjectPtr obj;
 	bool ishistory = false,
@@ -781,7 +781,7 @@
 	delete ui;
 }
 
-DEFINE_ACTION (SplitLines, 0)
+void MainWindow::slot_actionSplitLines()
 {
 	bool ok;
 	int segments = QInputDialog::getInt (g_win, APPNAME, "Amount of segments:", cfg::splitLinesSegments, 0,
--- a/src/addObjectDialog.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/addObjectDialog.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -240,7 +240,7 @@
 	button->setAutoFillBackground (true);
 
 	if (color != null)
-		button->setStyleSheet (format ("background-color: %1", color->hexcode()));
+		button->setStyleSheet (format ("background-color: %1", color.hexcode()));
 }
 
 // =============================================================================
--- a/src/colorSelector.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/colorSelector.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -104,7 +104,7 @@
 		const double y = (i / numCols) * square;
 		const double w = square - (penWidth / 2);
 
-		QColor col (info->faceColor());
+		QColor col (info.faceColor());
 
 		if (i == mainColorIndex)
 		{
@@ -113,13 +113,13 @@
 			col.setAlpha (cfg::mainColorAlpha * 255.0f);
 		}
 
-		QPen pen (info->edgeColor(), penWidth, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		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 (format ("%1", i));
 		numtext->setDefaultTextColor ((luma (col) < 80) ? Qt::white : Qt::black);
 		numtext->setPos (x, y);
 
-		if (selection() && i == selection()->index())
+		if (selection() && i == selection().index())
 		{
 			auto curspic = m_scene->addPixmap (getIcon ("colorcursor"));
 			curspic->setPos (x, y);
@@ -153,13 +153,13 @@
 		return;
 	}
 
-	ui->colorLabel->setText (format ("%1 - %2", selection()->indexString(),
-		(selection()->isDirect() ? "<direct color>" : selection()->name())));
+	ui->colorLabel->setText (format ("%1 - %2", selection().indexString(),
+		(selection().isDirect() ? "<direct color>" : selection().name())));
 	ui->iconLabel->setPixmap (makeColorIcon (selection(), 16).pixmap (16, 16));
 
 #ifdef TRANSPARENT_DIRECT_COLORS
-	ui->transparentDirectColor->setEnabled (selection()->isDirect());
-	ui->transparentDirectColor->setChecked (selection()->isDirect() && selection()->faceColor().alphaF() < 1.0);
+	ui->transparentDirectColor->setEnabled (selection().isDirect());
+	ui->transparentDirectColor->setChecked (selection().isDirect() && selection().faceColor().alphaF() < 1.0);
 #else
 	ui->transparentDirectColor->setChecked (false);
 	ui->transparentDirectColor->setEnabled (false);
@@ -174,13 +174,13 @@
 	// currently selected color. We cannot do this in the constructor because the
 	// height is not set properly there. Though don't do this if we selected a
 	// direct color.
-	if (m_firstResize && selection()->index() >= numLDConfigColors())
+	if (m_firstResize && selection().index() >= numLDConfigColors())
 	{
 		int visibleColors = (ui->viewport->height() / g_squareSize) * g_numColumns;
 
-		if (selection() && selection()->index() >= visibleColors)
+		if (selection() && selection().index() >= visibleColors)
 		{
-			int y = (selection()->index() / g_numColumns) * g_squareSize;
+			int y = (selection().index() / g_numColumns) * g_squareSize;
 			ui->viewport->verticalScrollBar()->setValue (y);
 		}
 	}
@@ -223,7 +223,7 @@
 //
 void ColorSelector::chooseDirectColor()
 {
-	QColor defcolor = selection() != null ? selection()->faceColor() : Qt::white;
+	QColor defcolor = selection() != null ? selection().faceColor() : Qt::white;
 	QColor newcolor = QColorDialog::getColor (defcolor);
 
 	if (not newcolor.isValid())
@@ -236,10 +236,10 @@
 //
 void ColorSelector::transparentCheckboxClicked()
 {
-	if (selection() == null || not selection()->isDirect())
+	if (selection() == null || not selection().isDirect())
 		return;
 
-	selectDirectColor (selection()->faceColor());
+	selectDirectColor (selection().faceColor());
 }
 
 // =============================================================================
--- a/src/colors.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/colors.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -28,7 +28,7 @@
 
 void initColors()
 {
-	LDColor col;
+	LDColorData* col;
 	print ("Initializing color information.\n");
 
 	// Always make sure there's 16 and 24 available. They're special like that.
@@ -79,18 +79,43 @@
 		if (index > 0x3000000)
 			col.setAlpha (128);
 
-		LDColor color (new LDColorData);
+		LDColorData* color = new LDColorData;
 		color->_name = "0x" + QString::number (index, 16).toUpper();
 		color->_faceColor = col;
 		color->_edgeColor = luma(col) < 48 ? Qt::white : Qt::black;
 		color->_hexcode = col.name();
 		color->_index = index;
-		return color;
+		return LDColor (color);
 	}
 
 	return null;
 }
 
+QString LDColor::indexString() const
+{
+	if (isDirect())
+		return "0x" + QString::number (index(), 16).toUpper();
+
+	return QString::number (index());
+}
+
+bool LDColor::isDirect() const
+{
+	return index() >= 0x02000000;
+}
+
+bool LDColor::operator== (LDColor const& other)
+{
+	if ((data() == nullptr) ^ (other == nullptr))
+		return false;
+
+	if (data() != nullptr)
+		return index() == other.index();
+
+	// both are null
+	return true;
+}
+
 int luma (const QColor& col)
 {
 	return (0.2126f * col.red()) +
@@ -102,16 +127,3 @@
 {
 	return countof (g_LDConfigColors);
 }
-
-QString LDColorData::indexString() const
-{
-	if (isDirect())
-		return "0x" + QString::number (_index, 16).toUpper();
-
-	return QString::number (_index);
-}
-
-bool LDColorData::isDirect() const
-{
-	return _index >= 0x02000000;
-}
--- a/src/colors.h	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/colors.h	Sun Jun 22 03:55:56 2014 +0300
@@ -20,6 +20,27 @@
 #include <QColor>
 #include "main.h"
 
+#define SHARED_POINTER_DERIVATIVE(T) \
+public: \
+	using Self = T; \
+	using DataType = T##Data; \
+	using Super = QSharedPointer<DataType>; \
+	\
+	T() : Super() {} \
+	T (DataType* data) : Super (data) {} \
+	T (Super const& other) : Super (other) {} \
+	T (QWeakPointer<DataType> const& other) : Super (other) {} \
+	\
+	template <typename Deleter> \
+	T (DataType* data, Deleter dlt) : Super (data, dlt) {} \
+	\
+	inline bool			operator== (decltype(nullptr)) { return data() == nullptr; } \
+	inline bool			operator!= (decltype(nullptr)) { return data() != nullptr; } \
+	inline DataType*	operator->() const = delete;
+
+#define SHARED_POINTER_DATA_ACCESS(N) \
+	public: inline decltype(DataType::_##N) const& N() const { return data()->_##N; }
+
 class LDColor;
 
 class LDColorData
@@ -36,36 +57,23 @@
 
 public:
 	LDColorData(){}
-
-	readAccess (edgeColor)
-	readAccess (faceColor)
-	readAccess (hexcode)
-	readAccess (index)
-	QString		indexString() const;
-	bool		isDirect() const;
-	readAccess (name)
 };
 
 
 class LDColor : public QSharedPointer<LDColorData>
 {
-public:
-	using Super = QSharedPointer<LDColorData>;
-	using Self = LDColor;
-
-	LDColor() : Super() {}
-	LDColor (LDColorData* data) : Super (data) {}
-	LDColor (Super const& other) : Super (other) {}
-	LDColor (QWeakPointer<LDColorData> const& other) : Super (other) {}
+	SHARED_POINTER_DERIVATIVE (LDColor)
+	SHARED_POINTER_DATA_ACCESS (edgeColor)
+	SHARED_POINTER_DATA_ACCESS (faceColor)
+	SHARED_POINTER_DATA_ACCESS (hexcode)
+	SHARED_POINTER_DATA_ACCESS (index)
+	SHARED_POINTER_DATA_ACCESS (name)
 
-	template <typename Deleter>
-	LDColor (LDColorData* data, Deleter dlt) : Super (data, dlt) {}
+public:
+	QString				indexString() const;
+	bool				isDirect() const;
 
-	inline bool			operator== (Self const& other);
-	inline bool			operator== (decltype(nullptr)) { return data() == nullptr; }
-	inline bool			operator!= (decltype(nullptr)) { return data() != nullptr; }
-	inline LDColorData*	operator->() const { return data(); }
-
+	bool				operator== (Self const& other);
 	static void			addLDConfigColor (qint32 index, LDColor color);
 	static LDColor		fromIndex (qint32 index);
 };
@@ -79,15 +87,3 @@
 LDColor edgecolor();
 static constexpr int mainColorIndex = 16;
 static constexpr int edgeColorIndex = 24;
-
-bool LDColor::operator== (LDColor const& other)
-{
-	if ((data() == nullptr) ^ (other == nullptr))
-		return false;
-
-	if (data() != nullptr)
-		return data()->index() == other->index();
-
-	// both are null
-	return true;
-}
--- a/src/configDialog.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/configDialog.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -122,15 +122,10 @@
 	ui->roundPosition->setValue (cfg::roundPosition);
 	ui->roundMatrix->setValue (cfg::roundMatrix);
 
-	int i = 0;
-
-	for (QAction* act : g_win->findChildren<QAction*>())
+	g_win->applyToActions ([&](QAction* act)
 	{
-		KeySequenceConfigEntry* cfg = g_win->shortcutForAction (act);
-
-		if (cfg)
-			addShortcut (*cfg, act, i);
-	}
+		addShortcut (act);
+	});
 
 	ui->shortcutsList->setSortingEnabled (true);
 	ui->shortcutsList->sortItems();
@@ -197,12 +192,12 @@
 // =============================================================================
 // Adds a shortcut entry to the list of shortcuts.
 // =============================================================================
-void ConfigDialog::addShortcut (KeySequenceConfigEntry& cfg, QAction* act, int& i)
+void ConfigDialog::addShortcut (QAction* act)
 {
 	ShortcutListItem* item = new ShortcutListItem;
 	item->setIcon (act->icon());
-	item->setKeyConfig (&cfg);
 	item->setAction (act);
+	item->setSequence (act->shortcut());
 	setShortcutText (item);
 
 	// If the action doesn't have a valid icon, use an empty one
@@ -210,7 +205,7 @@
 	if (act->icon().isNull())
 		item->setIcon (getIcon ("empty"));
 
-	ui->shortcutsList->insertItem (i++, item);
+	ui->shortcutsList->insertItem (ui->shortcutsList->count(), item);
 }
 
 // =============================================================================
@@ -320,9 +315,6 @@
 	cfg::gridFineCoordinateSnap = ui->gridFineCoordinateSnap->value();
 	cfg::gridFineAngleSnap = ui->gridFineAngleSnap->value();
 
-	// Apply key shortcuts
-	g_win->updateActionShortcuts();
-
 	// Ext program settings
 	for (const LDExtProgInfo& info : g_LDExtProgInfo)
 	{
@@ -333,6 +325,13 @@
 #endif // _WIN32
 	}
 
+	// Apply shortcuts
+	for (int i = 0; i < ui->shortcutsList->count(); ++i)
+	{
+		auto item = static_cast<ShortcutListItem*> (ui->shortcutsList->item (i));
+		item->action()->setShortcut (item->sequence());
+	}
+
 	Config::save();
 	reloadAllSubfiles();
 	loadLogoedStuds();
@@ -393,7 +392,7 @@
 			}
 			else
 			{
-				item->setText (col->name());
+				item->setText (col.name());
 				item->setIcon (makeColorIcon (col, 16));
 			}
 		}
@@ -617,7 +616,7 @@
 
 	ShortcutListItem* item = sel[0];
 
-	if (KeySequenceDialog::staticDialog (item->keyConfig(), this))
+	if (KeySequenceDialog::staticDialog (item, this))
 		setShortcutText (item);
 }
 
@@ -630,7 +629,7 @@
 
 	for (ShortcutListItem* item : sel)
 	{
-		item->keyConfig()->resetValue();
+		item->setSequence (MainWindow::defaultShortcut (item->action()));
 		setShortcutText (item);
 	}
 }
@@ -644,7 +643,7 @@
 
 	for (ShortcutListItem* item : sel)
 	{
-		item->keyConfig()->setValue (QKeySequence());
+		item->setSequence (QKeySequence());
 		setShortcutText (item);
 	}
 }
@@ -692,7 +691,7 @@
 {
 	QAction* act = item->action();
 	QString label = act->iconText();
-	QString keybind = item->keyConfig()->getValue().toString();
+	QString keybind = item->sequence().toString();
 	item->setText (format ("%1 (%2)", label, keybind));
 }
 
@@ -711,7 +710,7 @@
 		if (entry.isSeparator())
 			val += '|';
 		else
-			val += format ("%1", entry.color()->index());
+			val += format ("%1", entry.color().index());
 	}
 
 	return val;
@@ -744,14 +743,14 @@
 
 // =============================================================================
 // =============================================================================
-bool KeySequenceDialog::staticDialog (KeySequenceConfigEntry* cfg, QWidget* parent)
+bool KeySequenceDialog::staticDialog (ShortcutListItem* item, QWidget* parent)
 {
-	KeySequenceDialog dlg (cfg->getValue(), parent);
+	KeySequenceDialog dlg (item->sequence(), parent);
 
 	if (dlg.exec() == QDialog::Rejected)
 		return false;
 
-	cfg->setValue (dlg.seq);
+	item->setSequence (dlg.seq);
 	return true;
 }
 
--- a/src/configDialog.h	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/configDialog.h	Sun Jun 22 03:55:56 2014 +0300
@@ -27,8 +27,8 @@
 // =============================================================================
 class ShortcutListItem : public QListWidgetItem
 {
-	PROPERTY (public,	KeySequenceConfigEntry*,	keyConfig,	setKeyConfig,	STOCK_WRITE)
-	PROPERTY (public,	QAction*,					action,		setAction,		STOCK_WRITE)
+	PROPERTY (public,	QAction*,		action,		setAction,		STOCK_WRITE)
+	PROPERTY (public,	QKeySequence,	sequence,	setSequence,	STOCK_WRITE)
 
 public:
 	explicit ShortcutListItem (QListWidget* view = null, int type = Type) :
@@ -63,7 +63,7 @@
 	QList<QListWidgetItem*> quickColorItems;
 
 	void applySettings();
-	void addShortcut (KeySequenceConfigEntry& cfg, QAction* act, int& i);
+	void addShortcut (QAction* act);
 	void setButtonBackground (QPushButton* button, QString value);
 	void pickColor (QString& conf, QPushButton* button);
 	void updateQuickColorList (LDQuickColor* sel = null);
@@ -100,7 +100,7 @@
 
 public:
 	explicit KeySequenceDialog (QKeySequence seq, QWidget* parent = null, Qt::WindowFlags f = 0);
-	static bool staticDialog (KeySequenceConfigEntry* cfg, QWidget* parent = null);
+	static bool staticDialog (ShortcutListItem* item, QWidget* parent = null);
 
 	QLabel* lb_output;
 	QDialogButtonBox* bbx_buttons;
--- a/src/configuration.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/configuration.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -45,15 +45,6 @@
 static QMap<QString, ConfigEntry*>	g_configsByName;
 static QList<ConfigEntry*>			g_configs;
 
-//
-// Get the QSettings object.
-//
-static QSettings* getSettingsObject()
-{
-	QString path = qApp->applicationDirPath() + "/" UNIXNAME EXTENSION;
-	return new QSettings (path, QSettings::IniFormat);
-}
-
 ConfigEntry::ConfigEntry (QString name) :
 	m_name (name) {}
 
@@ -62,12 +53,12 @@
 //
 bool Config::load()
 {
-	QSettings* settings = getSettingsObject();
+	QSettings* settings = settingsObject();
 	print ("config::load: Loading configuration file from %1\n", settings->fileName());
 
 	for (ConfigEntry* cfg : g_configPointers)
 	{
-		if (not cfg)
+		if (cfg == null)
 			break;
 
 		QVariant val = settings->value (cfg->name(), cfg->getDefaultAsVariant());
@@ -76,7 +67,10 @@
 		g_configs << cfg;
 	}
 
-	settings->deleteLater();
+	if (g_win != null)
+		g_win->loadShortcuts (settings);
+
+	delete settings;
 	return true;
 }
 
@@ -85,7 +79,7 @@
 //
 bool Config::save()
 {
-	QSettings* settings = getSettingsObject();
+	QSettings* settings = settingsObject();
 
 	for (ConfigEntry* cfg : g_configs)
 	{
@@ -95,9 +89,12 @@
 			settings->remove (cfg->name());
 	}
 
+	if (g_win != null)
+		g_win->saveShortcuts (settings);
+
 	settings->sync();
 	print ("Configuration saved to %1.\n", settings->fileName());
-	settings->deleteLater();
+	delete settings;
 	return true;
 }
 
@@ -123,8 +120,19 @@
 //
 QString Config::dirpath()
 {
-	QSettings* cfg = getSettingsObject();
-	return dirname (cfg->fileName());
+	QSettings* settings = settingsObject();
+	QString result = dirname (settings->fileName());
+	delete settings;
+	return result;
+}
+
+//
+// Accessor to the settings object
+//
+QSettings* Config::settingsObject()
+{
+	QString path = qApp->applicationDirPath() + "/" UNIXNAME EXTENSION;
+	return new QSettings (path, QSettings::IniFormat);
 }
 
 //
--- a/src/configuration.h	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/configuration.h	Sun Jun 22 03:55:56 2014 +0300
@@ -45,6 +45,7 @@
 	void reset();
 	QString dirpath();
 	QString filepath (QString file);
+	QSettings* settingsObject();
 }
 
 class ConfigEntry
@@ -80,6 +81,7 @@
 	virtual void		resetValue() = 0;
 	virtual QVariant	toVariant() const = 0;
 
+
 protected:
 	static void addToArray (ConfigEntry* ptr);
 };
--- a/src/extPrograms.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/extPrograms.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -333,7 +333,7 @@
 // =============================================================================
 // Interface for Ytruder
 // =============================================================================
-DEFINE_ACTION (Ytruder, 0)
+void MainWindow::slot_actionYtruder()
 {
 	setlocale (LC_ALL, "C");
 
@@ -390,7 +390,7 @@
 // =============================================================================
 // Rectifier interface
 // =============================================================================
-DEFINE_ACTION (Rectifier, 0)
+void MainWindow::slot_actionRectifier()
 {
 	setlocale (LC_ALL, "C");
 
@@ -435,7 +435,7 @@
 // =============================================================================
 // Intersector interface
 // =============================================================================
-DEFINE_ACTION (Intersector, 0)
+void MainWindow::slot_actionIntersector()
 {
 	setlocale (LC_ALL, "C");
 
@@ -534,7 +534,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Coverer, 0)
+void MainWindow::slot_actionCoverer()
 {
 	setlocale (LC_ALL, "C");
 
@@ -598,7 +598,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Isecalc, 0)
+void MainWindow::slot_actionIsecalc()
 {
 	setlocale (LC_ALL, "C");
 
@@ -657,7 +657,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (Edger2, 0)
+void MainWindow::slot_actionEdger2()
 {
 	setlocale (LC_ALL, "C");
 
--- a/src/format.h	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/format.h	Sun Jun 22 03:55:56 2014 +0300
@@ -38,7 +38,7 @@
 	StringFormatArg (const Vertex& a) : m_text (a.toString()) {}
 	StringFormatArg (const Matrix& a) : m_text (a.toString()) {}
 	StringFormatArg (const char* a) : m_text (a) {}
-	StringFormatArg (LDColor a) : m_text (a->indexString()) {}
+	StringFormatArg (LDColor a) : m_text (a.indexString()) {}
 
 	StringFormatArg (const void* a)
 	{
--- a/src/glCompiler.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/glCompiler.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -160,7 +160,7 @@
 				if (topobj->color() == maincolor())
 					qcol = GLRenderer::getMainColor();
 				else
-					qcol = topobj->color()->faceColor();
+					qcol = topobj->color().faceColor();
 			}
 			elif (poly.color == edgeColorIndex)
 			{
@@ -171,7 +171,7 @@
 				LDColor col = LDColor::fromIndex (poly.color);
 
 				if (col)
-					qcol = col->faceColor();
+					qcol = col.faceColor();
 			}
 			break;
 	}
--- a/src/ldConfig.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/ldConfig.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -105,14 +105,14 @@
 		if (parseLDConfigTag (pars, "ALPHA", valuestr))
 			alpha = clamp (valuestr.toInt(), 0, 255);
 
-		LDColor col (new LDColorData);
+		LDColorData* col = new LDColorData;
 		col->_name = name;
 		col->_faceColor = faceColor;
 		col->_edgeColor = edgeColor;
 		col->_hexcode = facename;
 		col->_faceColor.setAlpha (alpha);
 		col->_index = code;
-		LDColor::addLDConfigColor (code, col);
+		LDColor::addLDConfigColor (code, LDColor (col));
 	}
 
 	fp->close();
--- a/src/ldObject.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/ldObject.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -406,7 +406,7 @@
 	LDPolygon* data = new LDPolygon;
 	data->id = id();
 	data->num = num;
-	data->color = color()->index();
+	data->color = color().index();
 
 	for (int i = 0; i < data->numVertices(); ++i)
 		data->vertices[i] = vertex (i);
--- a/src/mainWindow.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/mainWindow.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -35,6 +35,7 @@
 #include <QCoreApplication>
 #include <QTimer>
 #include <QMetaMethod>
+#include <QSettings>
 #include "main.h"
 #include "glRenderer.h"
 #include "mainWindow.h"
@@ -51,6 +52,7 @@
 #include "primitives.h"
 
 static bool g_isSelectionLocked = false;
+static QMap<QAction*, QKeySequence> g_defaultShortcuts;
 
 CFGENTRY (Bool, colorizeObjectsList, true);
 CFGENTRY (String, quickColorToolbar, "4:25:14:27:2:3:11:1:22:|:0:72:71:15");
@@ -102,40 +104,22 @@
 	ui->actionWireframe->setChecked (cfg::drawWireframe);
 	ui->actionBFCView->setChecked (cfg::bfcRedGreenView);
 	ui->actionRandomColors->setChecked (cfg::randomColors);
+
+	// Connect all actions and save default sequences
+	applyToActions ([&](QAction* act)
+	{
+		connect (act, SIGNAL (triggered()), this, SLOT (slot_action()));
+		g_defaultShortcuts[act] = act->shortcut();
+	});
+
 	updateGridToolBar();
 	updateEditModeActions();
 	updateRecentFilesMenu();
 	updateColorToolbar();
 	updateTitle();
-	updateActionShortcuts();
+	loadShortcuts (Config::settingsObject());
 	setMinimumSize (300, 200);
 	connect (qApp, SIGNAL (aboutToQuit()), this, SLOT (slot_lastSecondCleanup()));
-
-	// Connect all actions
-	for (QAction* act : findChildren<QAction*>())
-		if (not act->objectName().isEmpty())
-			connect (act, SIGNAL (triggered()), this, SLOT (slot_action()));
-}
-
-// =============================================================================
-//
-KeySequenceConfigEntry* MainWindow::shortcutForAction (QAction* action)
-{
-	QString keycfgname = action->objectName() + "Shortcut";
-	return KeySequenceConfigEntry::getByName (keycfgname);
-}
-
-// =============================================================================
-//
-void MainWindow::updateActionShortcuts()
-{
-	for (QAction* act : findChildren<QAction*>())
-	{
-		KeySequenceConfigEntry* cfg = shortcutForAction (act);
-
-		if (cfg)
-			act->setShortcut (cfg->getValue());
-	}
 }
 
 // =============================================================================
@@ -233,7 +217,7 @@
 			QToolButton* colorButton = new QToolButton;
 			colorButton->setIcon (makeColorIcon (entry.color(), 16));
 			colorButton->setIconSize (QSize (16, 16));
-			colorButton->setToolTip (entry.color()->name());
+			colorButton->setToolTip (entry.color().name());
 
 			connect (colorButton, SIGNAL (clicked()), this, SLOT (slot_quickColor()));
 			ui->colorToolbar->addWidget (colorButton);
@@ -430,7 +414,7 @@
 		{
 			// If the object isn't in the main or edge color, draw this
 			// list entry in said color.
-			item->setForeground (obj->color()->faceColor());
+			item->setForeground (obj->color().faceColor());
 		}
 
 		obj->qObjListEntry = item;
@@ -830,7 +814,7 @@
 	// Create an image object and link a painter to it.
 	QImage img (size, size, QImage::Format_ARGB32);
 	QPainter paint (&img);
-	QColor col = colinfo->faceColor();
+	QColor col = colinfo.faceColor();
 
 	if (colinfo == maincolor())
 	{
@@ -840,7 +824,7 @@
 	}
 
 	// Paint the icon border
-	paint.fillRect (QRect (0, 0, size, size), colinfo->edgeColor());
+	paint.fillRect (QRect (0, 0, size, size), colinfo.edgeColor());
 
 	// Paint the checkerboard background, visible with translucent icons
 	paint.drawPixmap (QRect (1, 1, size - 2, size - 2), getIcon ("checkerboard"), QRect (0, 0, 8, 8));
@@ -874,8 +858,8 @@
 	{
 		QIcon ico = makeColorIcon (pair.first, 16);
 		box->addItem (ico, format ("[%1] %2 (%3 object%4)",
-			pair.first, pair.first->name(), pair.second, plural (pair.second)));
-		box->setItemData (row, pair.first->index());
+			pair.first, pair.first.name(), pair.second, plural (pair.second)));
+		box->setItemData (row, pair.first.index());
 
 		++row;
 	}
@@ -1011,6 +995,50 @@
 
 // =============================================================================
 //
+void MainWindow::loadShortcuts (QSettings const* settings)
+{
+	for (QAction* act : findChildren<QAction*>())
+	{
+		QKeySequence seq = settings->value ("shortcut_" + act->objectName(), act->shortcut()).value<QKeySequence>();
+		act->setShortcut (seq);
+	}
+}
+
+// =============================================================================
+//
+void MainWindow::saveShortcuts (QSettings* settings)
+{
+	applyToActions ([&](QAction* act)
+	{
+		QString const key = "shortcut_" + act->objectName();
+
+		if (g_defaultShortcuts[act] != act->shortcut())
+			settings->setValue (key, act->shortcut());
+		else
+			settings->remove (key);
+	});
+}
+
+// =============================================================================
+//
+void MainWindow::applyToActions (std::function<void(QAction*)> function)
+{
+	for (QAction* act : findChildren<QAction*>())
+	{
+		if (not act->objectName().isEmpty())
+			function (act);
+	}
+}
+
+// =============================================================================
+//
+QKeySequence MainWindow::defaultShortcut (QAction* act) // [static]
+{
+	return g_defaultShortcuts[act];
+}
+
+// =============================================================================
+//
 QImage imageFromScreencap (uchar* data, int w, int h)
 {
 	// GL and Qt formats have R and B swapped. Also, GL flips Y - correct it as well.
--- a/src/mainWindow.h	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/mainWindow.h	Sun Jun 22 03:55:56 2014 +0300
@@ -17,6 +17,7 @@
  */
 
 #pragma once
+#include <functional>
 #include <QMainWindow>
 #include <QAction>
 #include <QListWidget>
@@ -43,20 +44,6 @@
 	connect (bbx_buttons, SIGNAL (accepted()), this, SLOT (accept())); \
 	connect (bbx_buttons, SIGNAL (rejected()), this, SLOT (reject())); \
 
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-#define DEFINE_ACTION(NAME, DEFSHORTCUT) \
-	CFGENTRY (KeySequence, action##NAME##Shortcut, DEFSHORTCUT); \
-	void MainWindow::slot_action##NAME()
-
-// Convenience macros for key sequences.
-#define KEY(N) (Qt::Key_##N)
-#define CTRL(N) (Qt::CTRL | Qt::Key_##N)
-#define SHIFT(N) (Qt::SHIFT | Qt::Key_##N)
-#define CTRL_SHIFT(N) (Qt::CTRL | Qt::SHIFT | Qt::Key_##N)
-
-// =============================================================================
 class LDQuickColor
 {
 	PROPERTY (public,	LDColor,		color,		setColor,		STOCK_WRITE)
@@ -85,7 +72,7 @@
 //
 class MainWindow : public QMainWindow
 {
-Q_OBJECT
+	Q_OBJECT
 
 public:
 	explicit MainWindow (QWidget* parent = null, Qt::WindowFlags flags = 0);
@@ -172,13 +159,6 @@
 	// Updates the object list. Right now this just rebuilds it.
 	void refreshObjectList();
 
-	// Updates all actions to ensure they have the correct shortcut as
-	// defined in the configuration entries.
-	void updateActionShortcuts();
-
-	// Gets the shortcut configuration for the given \c action
-	KeySequenceConfigEntry* shortcutForAction (QAction* action);
-
 	void endAction();
 
 	inline QTreeWidget* getPrimitivesTree() const
@@ -186,6 +166,11 @@
 		return ui->primitives;
 	}
 
+	static QKeySequence defaultShortcut (QAction* act);
+	void loadShortcuts (QSettings const* settings);
+	void saveShortcuts (QSettings* settings);
+	void applyToActions (std::function<void(QAction*)> function);
+
 public slots:
 	void updatePrimitives();
 	void changeCurrentFile();
--- a/src/partDownloader.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/partDownloader.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -531,7 +531,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (DownloadFrom, 0)
+void MainWindow::slot_actionDownloadFrom()
 {
 	PartDownloader::staticBegin();
 }
--- a/src/primitives.cc	Mon Jun 16 18:31:13 2014 +0300
+++ b/src/primitives.cc	Sun Jun 22 03:55:56 2014 +0300
@@ -688,7 +688,7 @@
 
 // =============================================================================
 //
-DEFINE_ACTION (MakePrimitive, 0)
+void MainWindow::slot_actionMakePrimitive()
 {
 	PrimitivePrompt* dlg = new PrimitivePrompt (g_win);
 
--- a/ui/ldforge.ui	Mon Jun 16 18:31:13 2014 +0300
+++ b/ui/ldforge.ui	Sun Jun 22 03:55:56 2014 +0300
@@ -75,8 +75,8 @@
           <rect>
            <x>0</x>
            <y>0</y>
-           <width>99</width>
-           <height>99</height>
+           <width>233</width>
+           <height>436</height>
           </rect>
          </property>
          <attribute name="label">
@@ -520,6 +520,9 @@
    <property name="whatsThis">
     <string/>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+S</string>
+   </property>
   </action>
   <action name="actionSaveAs">
    <property name="icon">
@@ -532,6 +535,9 @@
    <property name="whatsThis">
     <string>Save the part model to a specific file.</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Shift+S</string>
+   </property>
   </action>
   <action name="actionInsertFrom">
    <property name="icon">
@@ -645,6 +651,9 @@
    <property name="text">
     <string>BFC Red/Green View</string>
    </property>
+   <property name="shortcut">
+    <string>Shift+B</string>
+   </property>
   </action>
   <action name="actionSetOverlay">
    <property name="icon">
@@ -761,6 +770,9 @@
    <property name="statusTip">
     <string>Undo a step.</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Z</string>
+   </property>
   </action>
   <action name="actionRedo">
    <property name="icon">
@@ -773,6 +785,9 @@
    <property name="statusTip">
     <string>Redo a step.</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Shift+Z</string>
+   </property>
   </action>
   <action name="actionCut">
    <property name="icon">
@@ -785,6 +800,9 @@
    <property name="statusTip">
     <string>Cut the current selection to clipboard.</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+X</string>
+   </property>
   </action>
   <action name="actionCopy">
    <property name="icon">
@@ -800,6 +818,9 @@
    <property name="whatsThis">
     <string/>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+C</string>
+   </property>
   </action>
   <action name="actionPaste">
    <property name="icon">
@@ -812,6 +833,9 @@
    <property name="statusTip">
     <string>Paste clipboard contents.</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+V</string>
+   </property>
   </action>
   <action name="actionDelete">
    <property name="icon">
@@ -824,6 +848,9 @@
    <property name="statusTip">
     <string>Delete the selection</string>
    </property>
+   <property name="shortcut">
+    <string>Del</string>
+   </property>
   </action>
   <action name="actionSelectAll">
    <property name="icon">
@@ -833,6 +860,9 @@
    <property name="text">
     <string>Select All</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+A</string>
+   </property>
   </action>
   <action name="actionSelectByColor">
    <property name="icon">
@@ -866,6 +896,9 @@
    <property name="text">
     <string>Select Mode</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+1</string>
+   </property>
   </action>
   <action name="actionModeDraw">
    <property name="checkable">
@@ -878,11 +911,17 @@
    <property name="text">
     <string>Draw Mode</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+2</string>
+   </property>
   </action>
   <action name="actionSetDrawDepth">
    <property name="text">
     <string>Set Draw Depth</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+3</string>
+   </property>
   </action>
   <action name="actionSetColor">
    <property name="icon">
@@ -895,6 +934,9 @@
    <property name="statusTip">
     <string>Set the color on given objects.</string>
    </property>
+   <property name="shortcut">
+    <string>C</string>
+   </property>
   </action>
   <action name="actionAutocolor">
    <property name="icon">
@@ -907,6 +949,9 @@
    <property name="statusTip">
     <string>Set the color of the given object to the first found unused color.</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Shift+C</string>
+   </property>
   </action>
   <action name="actionUncolor">
    <property name="icon">
@@ -934,6 +979,9 @@
    <property name="statusTip">
     <string>Inline selected subfiles.</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+I</string>
+   </property>
   </action>
   <action name="actionInlineDeep">
    <property name="icon">
@@ -946,6 +994,9 @@
    <property name="statusTip">
     <string>Recursively inline selected subfiles down to polygons only.</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Shift+I</string>
+   </property>
   </action>
   <action name="actionInvert">
    <property name="icon">
@@ -955,6 +1006,9 @@
    <property name="text">
     <string>Invert</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Shift+W</string>
+   </property>
   </action>
   <action name="actionMakePrimitive">
    <property name="icon">
@@ -1145,6 +1199,9 @@
    <property name="text">
     <string>Help</string>
    </property>
+   <property name="shortcut">
+    <string>F1</string>
+   </property>
   </action>
   <action name="actionAbout">
    <property name="icon">
@@ -1212,6 +1269,9 @@
    <property name="text">
     <string>Move Up</string>
    </property>
+   <property name="shortcut">
+    <string>PgUp</string>
+   </property>
   </action>
   <action name="actionMoveDown">
    <property name="icon">
@@ -1221,6 +1281,9 @@
    <property name="text">
     <string>Move Down</string>
    </property>
+   <property name="shortcut">
+    <string>PgDown</string>
+   </property>
   </action>
   <action name="actionMoveXNeg">
    <property name="icon">
@@ -1230,6 +1293,9 @@
    <property name="text">
     <string>Move -X</string>
    </property>
+   <property name="shortcut">
+    <string>Left</string>
+   </property>
   </action>
   <action name="actionMoveXPos">
    <property name="icon">
@@ -1239,6 +1305,9 @@
    <property name="text">
     <string>Move +X</string>
    </property>
+   <property name="shortcut">
+    <string>Right</string>
+   </property>
   </action>
   <action name="actionMoveYNeg">
    <property name="icon">
@@ -1248,6 +1317,9 @@
    <property name="text">
     <string>Move -Y</string>
    </property>
+   <property name="shortcut">
+    <string>Home</string>
+   </property>
   </action>
   <action name="actionMoveYPos">
    <property name="icon">
@@ -1257,6 +1329,9 @@
    <property name="text">
     <string>Move +Y</string>
    </property>
+   <property name="shortcut">
+    <string>End</string>
+   </property>
   </action>
   <action name="actionMoveZNeg">
    <property name="icon">
@@ -1266,6 +1341,9 @@
    <property name="text">
     <string>Move -Z</string>
    </property>
+   <property name="shortcut">
+    <string>Down</string>
+   </property>
   </action>
   <action name="actionMoveZPos">
    <property name="icon">
@@ -1275,36 +1353,57 @@
    <property name="text">
     <string>Move +Z</string>
    </property>
+   <property name="shortcut">
+    <string>Up</string>
+   </property>
   </action>
   <action name="actionRotateXNeg">
    <property name="text">
     <string>Rotate -X</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Left</string>
+   </property>
   </action>
   <action name="actionRotateXPos">
    <property name="text">
     <string>Rotate +X</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Right</string>
+   </property>
   </action>
   <action name="actionRotateYNeg">
    <property name="text">
     <string>Rotate -Y</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+End</string>
+   </property>
   </action>
   <action name="actionRotateYPos">
    <property name="text">
     <string>Rotate +Y</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Home</string>
+   </property>
   </action>
   <action name="actionRotateZNeg">
    <property name="text">
     <string>Rotate -Z</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Down</string>
+   </property>
   </action>
   <action name="actionRotateZPos">
    <property name="text">
     <string>Rotate +Z</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Up</string>
+   </property>
   </action>
   <action name="actionRotationPoint">
    <property name="text">
@@ -1315,16 +1414,25 @@
    <property name="text">
     <string>Save All</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Shift+S</string>
+   </property>
   </action>
   <action name="actionClose">
    <property name="text">
     <string>Close</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+W</string>
+   </property>
   </action>
   <action name="actionCloseAll">
    <property name="text">
     <string>Close All</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+Shift+W</string>
+   </property>
   </action>
   <action name="actionNewFile">
    <property name="icon">
@@ -1334,6 +1442,9 @@
    <property name="text">
     <string>New File</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+N</string>
+   </property>
   </action>
   <action name="actionDownloadFrom">
    <property name="text">
@@ -1349,6 +1460,9 @@
    <property name="text">
     <string>Go to Line...</string>
    </property>
+   <property name="shortcut">
+    <string>Ctrl+G</string>
+   </property>
   </action>
   <action name="actionModeCircle">
    <property name="checkable">
@@ -1417,6 +1531,9 @@
    <property name="text">
     <string>Random colors</string>
    </property>
+   <property name="shortcut">
+    <string>Shift+R</string>
+   </property>
   </action>
   <action name="actionOpenSubfiles">
    <property name="text">

mercurial