Implement cut and copy
diff --git a/src/LoggerApp.cpp b/src/LoggerApp.cpp
index fc29708..8c7989b 100644
--- a/src/LoggerApp.cpp
+++ b/src/LoggerApp.cpp
@@ -6,6 +6,7 @@
 
 #include <private/interface/AboutWindow.h>
 #include <Application.h>
+#include <Clipboard.h>
 #include <private/interface/ColumnListView.h>
 #include <private/interface/ColumnTypes.h>
 #include <GroupLayout.h>
@@ -93,12 +94,12 @@
 				.AddItem("Quit", new BMessage(B_QUIT_REQUESTED), 'Q')
 			.End()
 			.AddMenu("Edit")
-				.AddItem("Cut", new BMessage(), 'X')
-				.AddItem("Copy", new BMessage(), 'C')
+				.AddItem("Cut", new BMessage(B_CUT), 'X')
+				.AddItem("Copy", new BMessage(B_COPY), 'C')
 				.AddItem("Delete", new BMessage(), 'D')
 				.AddSeparator()
 				.AddItem("Clear", clearMessage, 'E')
-				.AddItem("Select all", new BMessage(), 'A')
+				.AddItem("Select all", new BMessage(B_SELECT_ALL), 'A')
 				.AddSeparator()
 				.AddItem("Preferences", new BMessage())
 			.End()
@@ -294,6 +295,39 @@
 
 				break;
 			}
+			case B_CUT:
+			case B_COPY:
+			{
+				BRow* row = nullptr;
+
+				BString fullMessage;
+
+				// TODO copy all if selection is empty
+				while (row = fEventList->CurrentSelection(row)) {
+					BStringField* field = dynamic_cast<BStringField*>(row->GetField(1));
+					const char* string = field->String();
+					fullMessage.Prepend("\n");
+					fullMessage.Prepend(string);
+				}
+
+				be_clipboard->Lock();
+				be_clipboard->Clear();
+				BMessage* clip = be_clipboard->Data();
+
+				clip->AddData("text/plain", B_MIME_TYPE, fullMessage.String(), fullMessage.Length());
+
+				be_clipboard->Commit();
+				be_clipboard->Unlock();
+
+				if (message->what == B_CUT) {
+					while (row = fEventList->CurrentSelection(nullptr)) {
+							fEventList->RemoveRow(row);
+							delete row;
+					}
+				}
+
+				break;
+			}
 			case B_ABOUT_REQUESTED:
 			{
 				be_app_messenger.SendMessage(B_ABOUT_REQUESTED);