Index: common/project.cpp
===================================================================
--- common/project.cpp	(revision 1287)
+++ common/project.cpp	(working copy)
@@ -6886,6 +6886,19 @@
 		}
 		else
 		{
+			if (m_nCurAction == LC_ACTION_INSERT)
+			{
+				m_pCurPiece->Release();
+				m_pCurPiece = m_PreviousPiece;
+				m_PreviousPiece = NULL;
+
+				if (m_RestoreAction)
+				{
+					SetAction(m_PreviousAction);
+					m_RestoreAction = false;
+				}
+			}
+
 			DeleteContents (true);
 			FileLoad (m_pTrackFile, true, false);
 			delete m_pTrackFile;
Index: linux/main.h
===================================================================
--- linux/main.h	(revision 1287)
+++ linux/main.h	(working copy)
@@ -12,6 +12,11 @@
 void OnCommand(GtkWidget *w, gpointer data);
 void OnCommandDirect(GtkWidget *w, gpointer data);

+class PieceInfo;
+extern PieceInfo *dragged_piece;
+extern bool dragging_color;
+extern const GtkTargetEntry drag_target_list[];
+
 #define ID_FILE_RECENT1            1
 #define ID_FILE_RECENT2            2
 #define ID_FILE_RECENT3            3
Index: linux/glwindow.cpp
===================================================================
--- linux/glwindow.cpp	(revision 1287)
+++ linux/glwindow.cpp	(working copy)
@@ -2,9 +2,12 @@
 #include <gtk/gtk.h>
 #include <gdk/gdkx.h>
 #include "lc_global.h"
+#include "lc_application.h"
 #include "opengl.h"
 #include "glwindow.h"
 #include "defines.h"
+#include "main.h"
+#include "project.h"
 #include "system.h"

 struct GLWindowPrivate
@@ -19,6 +22,7 @@
 static bool WindowMultisample = false;
 static GLXContext WindowContext;
 static int WindowContextCount;
+static bool dragging;

 // =============================================================================
 // static functions
@@ -119,6 +123,52 @@
 	return TRUE;
 }

+static gboolean drag_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer data)
+{
+	if (!dragged_piece)
+	{
+		return FALSE;
+	}
+
+	GLWindow *wnd = (GLWindow*)data;
+	y = widget->allocation.height - y - 1;
+	lcGetActiveProject()->BeginPieceDrop(dragged_piece);
+	wnd->OnLeftButtonUp(x, y, FALSE, FALSE);
+	gtk_drag_finish(context, TRUE, FALSE, time);
+	return TRUE;
+}
+
+static void drag_leave(GtkWidget *widget, GdkDragContext *context, guint time, gpointer data)
+{
+	if (dragging)
+	{
+		dragging = false;
+		lcGetActiveProject()->HandleNotify(LC_CAPTURE_LOST, 0);
+	}
+}
+
+static gboolean drag_motion(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer data)
+{
+	if (!dragged_piece)
+	{
+		return FALSE;
+	}
+
+	GLWindow *wnd = (GLWindow*)data;
+	y = widget->allocation.height - y - 1;
+
+	if (!dragging)
+	{
+		dragging = true;
+		lcGetActiveProject()->BeginPieceDrop(dragged_piece);
+	}
+
+	wnd->OnMouseMove(x, y, FALSE, FALSE);
+
+	gdk_drag_status(context, GDK_ACTION_COPY, time);
+	return TRUE;
+}
+
 static gboolean scroll_event(GtkWidget *widget, GdkEventScroll *event, gpointer data)
 {
 	GLWindow *wnd = (GLWindow*)data;
@@ -258,6 +308,8 @@

 	gtk_widget_set_events(GTK_WIDGET(prv->widget), GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);

+	gtk_drag_dest_set(prv->widget, GTK_DEST_DEFAULT_MOTION, drag_target_list, 1, GDK_ACTION_COPY);
+
 	// Connect signal handlers
 	gtk_signal_connect(GTK_OBJECT(prv->widget), "expose_event", GTK_SIGNAL_FUNC(expose_event), this);
 //	gtk_signal_connect(GTK_OBJECT(prv->widget), "destroy", GTK_SIGNAL_FUNC(destroy_event), this);
@@ -265,6 +317,9 @@
 	gtk_signal_connect(GTK_OBJECT(prv->widget), "motion_notify_event", GTK_SIGNAL_FUNC(pointer_motion_event), this);
 	gtk_signal_connect(GTK_OBJECT(prv->widget), "button_press_event", GTK_SIGNAL_FUNC(button_press_event), this);
 	gtk_signal_connect(GTK_OBJECT(prv->widget), "button_release_event", GTK_SIGNAL_FUNC(button_release_event), this);
+	gtk_signal_connect(GTK_OBJECT(prv->widget), "drag_drop", GTK_SIGNAL_FUNC(drag_drop), this);
+	gtk_signal_connect(GTK_OBJECT(prv->widget), "drag_leave", GTK_SIGNAL_FUNC(drag_leave), this);
+	gtk_signal_connect(GTK_OBJECT(prv->widget), "drag_motion", GTK_SIGNAL_FUNC(drag_motion), this);
 	gtk_signal_connect(GTK_OBJECT(prv->widget), "scroll_event", GTK_SIGNAL_FUNC(scroll_event), this);
 	gtk_signal_connect(GTK_OBJECT(prv->widget), "realize", GTK_SIGNAL_FUNC(realize_event), this);

Index: linux/toolbar.cpp
===================================================================
--- linux/toolbar.cpp	(revision 1287)
+++ linux/toolbar.cpp	(working copy)
@@ -285,6 +285,11 @@
      new_pixmap (window, an_key), GTK_SIGNAL_FUNC (OnCommandDirect), (void*)LC_TOOLBAR_ADDKEYS);
 }

+static void drag_end(GtkWidget *widget, GdkDragContext *context, gpointer data)
+{
+	dragged_piece = NULL;
+}
+
 // =========================================================
 // Pieces toolbar

@@ -398,6 +403,18 @@
   }
 }

+static void piecetree_drag_begin(GtkWidget *widget, GdkDragContext *context, gpointer data)
+{
+	GtkTreeIter iter;
+	GtkTreeModel *model;
+
+	dragged_piece = NULL;
+	if (gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(widget)), &model, &iter))
+	{
+		gtk_tree_model_get(model, &iter, 1, &dragged_piece, -1);
+	}
+}
+
 static void piececombo_popup_position (GtkMenu *menu, gint *x, gint *y, gboolean* push, gpointer data)
 {
   gdk_window_get_origin (pieceentry->window, x, y);
@@ -1007,6 +1024,10 @@
   gtk_tree_selection_set_mode(select, GTK_SELECTION_SINGLE);
   g_signal_connect(G_OBJECT(select), "changed", G_CALLBACK(piecetree_changed), NULL);

+  gtk_drag_source_set(GTK_WIDGET(piecetree), GDK_BUTTON1_MASK, drag_target_list, 1, GDK_ACTION_COPY);
+  g_signal_connect(G_OBJECT(piecetree), "drag_begin", G_CALLBACK(piecetree_drag_begin), NULL);
+  g_signal_connect(G_OBJECT(piecetree), "drag_end", G_CALLBACK(drag_end), NULL);
+
   gtk_container_add(GTK_CONTAINER(scroll_win), piecetree);
   gtk_widget_show(piecetree);

@@ -1044,6 +1065,7 @@
   gtk_signal_connect(GTK_OBJECT(colorlist), "realize", GTK_SIGNAL_FUNC(colorlist_realize), NULL);
   gtk_signal_connect(GTK_OBJECT(colorlist), "unrealize", GTK_SIGNAL_FUNC(colorlist_unrealize), NULL);
   gtk_signal_connect(GTK_OBJECT(colorlist), "query-tooltip", GTK_SIGNAL_FUNC(colorlist_tooltip), NULL);
+  gtk_signal_connect(GTK_OBJECT(colorlist), "drag_end", G_CALLBACK(drag_end), NULL);

   gtk_widget_show(colorlist);

Index: linux/main.cpp
===================================================================
--- linux/main.cpp	(revision 1287)
+++ linux/main.cpp	(working copy)
@@ -44,6 +44,9 @@
 static char lib_path[] = LC_INSTALL_PREFIX"/share/leocad/";
 bool ignore_commands = false;

+PieceInfo *dragged_piece;
+const GtkTargetEntry drag_target_list[] = {{ (gchar*)"application/x-leocat", GTK_TARGET_SAME_APP, 0}};
+
 static void update_window_layout ();
 static gint main_quit (GtkWidget *widget, GdkEvent* event, gpointer data);

