Pārlūkot izejas kodu

Added new add in functions to set clip as sticky by default based on parameters

sabrogden 6 gadi atpakaļ
vecāks
revīzija
7eddec67eb

+ 13 - 11
CP_Main.rc

@@ -969,7 +969,7 @@ BEGIN
     PUSHBUTTON      "On Paste Scripts",IDC_BUTTON_PASTE_SCRIPTS,7,237,108,11
 END
 
-IDD_SCRIPT_EDITOR DIALOGEX 0, 0, 435, 314
+IDD_SCRIPT_EDITOR DIALOGEX 0, 0, 435, 324
 STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
 CAPTION "Scripts"
 FONT 8, "MS Shell Dlg", 400, 0, 0x1
@@ -977,25 +977,27 @@ BEGIN
     EDITTEXT        IDC_EDIT_NAME,142,7,284,14,ES_AUTOHSCROLL
     EDITTEXT        IDC_EDIT_DESC,142,24,284,14,ES_AUTOHSCROLL
     CONTROL         "",IDC_CHECK_ACTIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,142,42,16,10
-    EDITTEXT        IDC_EDIT_SCRIPT,100,67,326,102,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
-    EDITTEXT        IDC_EDIT_INPUT,100,195,265,40,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
-    EDITTEXT        IDC_EDIT_OUTPUT,100,250,326,40,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
-    PUSHBUTTON      "Run",IDC_BUTTON_RUN,376,205,50,14
-    DEFPUSHBUTTON   "OK",IDOK,321,293,50,14
-    PUSHBUTTON      "Cancel",IDCANCEL,376,293,50,14
+    EDITTEXT        IDC_EDIT_INPUT,100,195,265,50,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
+    EDITTEXT        IDC_EDIT_OUTPUT,100,259,326,40,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_VSCROLL | WS_HSCROLL
+    PUSHBUTTON      "Run",IDC_BUTTON_RUN,371,231,55,14
+    DEFPUSHBUTTON   "OK",IDOK,321,303,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,376,303,50,14
     LISTBOX         IDC_LIST_SCRIPTS,7,7,83,281,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
-    PUSHBUTTON      "Add",IDC_BUTTON_ADD_SCRIPT,7,293,32,14
-    PUSHBUTTON      "Delete",IDC_BUTTON_DELETE_SCRIPT,58,293,32,14
+    PUSHBUTTON      "Add",IDC_BUTTON_ADD_SCRIPT,7,303,32,14
+    PUSHBUTTON      "Delete",IDC_BUTTON_DELETE_SCRIPT,58,303,32,14
     LTEXT           "Name",IDC_STATIC_NAME,100,7,19,14,SS_CENTERIMAGE
     LTEXT           "Desciption",IDC_STATIC_DESC,100,24,34,14,SS_CENTERIMAGE
     LTEXT           "Sample Input",IDC_STATIC_INPUT,100,185,43,8
-    LTEXT           "Sample Output",IDC_STATIC_OUTPUT,100,238,48,8
+    LTEXT           "Sample Output",IDC_STATIC_OUTPUT,100,248,48,8
     LTEXT           "All function must return true/false.  Return true to cancel saving the copy or cancel the paste.",IDC_STATIC_RETURN_DESC,100,174,326,8
     LTEXT           "Script",IDC_STATIC_SCRIPT,100,56,30,10
     LTEXT           "Active",IDC_STATIC_ACTIVE,100,42,21,14
     CONTROL         "ChaiScript (http://chaiscript.com/)",IDC_MFCLINK_CHAISCRIPT,
                     "MfcLink",WS_TABSTOP,142,54,119,10
     CONTROL         "Examples",IDC_MFCLINK2_EXAMPLES,"MfcLink",WS_TABSTOP,294,54,60,10
+    CONTROL         "",IDC_RICHEDIT21,"RichEdit20W",ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP,100,66,326,105
+    EDITTEXT        IDC_EDIT_ACTIVE_APP,371,196,55,14,ES_AUTOHSCROLL
+    EDITTEXT        IDC_EDIT_ACTIVE_APP_TITLE,371,213,55,14,ES_AUTOHSCROLL
 END
 
 
@@ -1222,7 +1224,7 @@ BEGIN
         LEFTMARGIN, 7
         RIGHTMARGIN, 426
         TOPMARGIN, 7
-        BOTTOMMARGIN, 307
+        BOTTOMMARGIN, 317
     END
 END
 #endif    // APSTUDIO_INVOKED

+ 6 - 0
ChaiScriptOnCopy.cpp

@@ -32,6 +32,12 @@ bool ChaiScriptOnCopy::ProcessScript(CDittoChaiScript &clipData, std::string scr
 		chai.add(chaiscript::fun(&CDittoChaiScript::SetAsciiString), "SetAsciiString");
 		chai.add(chaiscript::fun(&CDittoChaiScript::GetActiveApp), "GetActiveApp");
 
+		chai.add(chaiscript::fun(&CDittoChaiScript::GetActiveAppTitle), "GetActiveAppTitle");
+
+		chai.add(chaiscript::fun(&CDittoChaiScript::SetMakeTopSticky), "SetMakeTopSticky");
+		chai.add(chaiscript::fun(&CDittoChaiScript::SetMakeLastSticky), "SetMakeLastSticky");
+		chai.add(chaiscript::fun(&CDittoChaiScript::SetReplaceTopSticky), "SetReplaceTopSticky");
+
 		chai.add(chaiscript::fun(&CDittoChaiScript::FormatExists), "FormatExists");
 		chai.add(chaiscript::fun(&CDittoChaiScript::RemoveFormat), "RemoveFormat");
 		chai.add(chaiscript::fun(&CDittoChaiScript::SetParentId), "SetParentId");

+ 72 - 4
Clip.cpp

@@ -251,6 +251,7 @@ CClip::CClip() :
 	m_globalMoveToGroupShortCut(FALSE)
 {
 	m_copyReason = CopyReasonEnum::COPY_TO_UNKOWN;
+	m_addToDbStickyEnum = AddToDbStickyEnum::INVALID;
 }
 
 CClip::~CClip()
@@ -359,7 +360,7 @@ bool CClip::AddFormat(CLIPFORMAT cfType, void* pData, UINT nLen, bool setDesc)
 }
 
 // Fills this CClip with the contents of the clipboard.
-int CClip::LoadFromClipboard(CClipTypes* pClipTypes, bool checkClipboardIgnore, CString activeApp)
+int CClip::LoadFromClipboard(CClipTypes* pClipTypes, bool checkClipboardIgnore, CString activeApp, CString activeAppTitle)
 {
 	COleDataObjectEx oleData;
 	CClipTypes defaultTypes;
@@ -602,7 +603,7 @@ int CClip::LoadFromClipboard(CClipTypes* pClipTypes, bool checkClipboardIgnore,
 				Log(StrF(_T("Start of process copy name: %s, script: %s"), listItem.m_name, listItem.m_script));
 
 				ChaiScriptOnCopy onCopy;
-				CDittoChaiScript clipData(this, (LPCSTR)CTextConvert::ConvertToChar(activeApp));
+				CDittoChaiScript clipData(this, (LPCSTR)CTextConvert::ConvertToChar(activeApp), (LPCSTR)CTextConvert::ConvertToChar(activeAppTitle));
 				if (onCopy.ProcessScript(clipData, (LPCSTR)CTextConvert::ConvertToChar(listItem.m_script)) == false)
 				{
 					Log(StrF(_T("End of process copy name: %s, returned false, not saving this copy to Ditto, last Error: %s"), listItem.m_name, onCopy.m_lastError));
@@ -767,6 +768,22 @@ bool CClip::AddToDB(bool bCheckForDuplicates)
 		}
 	}
 	CATCH_SQLITE_EXCEPTION_AND_RETURN(false)
+
+	int removeStickySettingClipId = -1;
+
+	if (m_addToDbStickyEnum == AddToDbStickyEnum::MAKE_TOP_STICKY)
+	{
+		m_stickyClipOrder = this->GetNewTopSticky(m_parentId, -1);
+	}
+	else if (m_addToDbStickyEnum == AddToDbStickyEnum::MAKE_LAST_STICKY)
+	{
+		m_stickyClipOrder = this->GetNewLastSticky(m_parentId, -1);
+	}
+	else if (m_addToDbStickyEnum == AddToDbStickyEnum::REPLACE_TOP_STICKY)
+	{
+		m_stickyClipOrder = this->GetNewTopSticky(m_parentId, -1);
+		removeStickySettingClipId = GetExistingTopStickyClipId(m_parentId);
+	}
 	
 	bResult = false;
 	if(AddToMainTable())
@@ -778,6 +795,11 @@ bool CClip::AddToDB(bool bCheckForDuplicates)
 	{
 		if(g_Opt.m_csPlaySoundOnCopy.IsEmpty() == FALSE)
 			PlaySound(g_Opt.m_csPlaySoundOnCopy, NULL, SND_FILENAME|SND_ASYNC);
+
+		if (removeStickySettingClipId > 0)
+		{
+			RemoveStickySetting(removeStickySettingClipId, m_parentId);
+		}
 	}
 	
 	// should be emptied by AddToDataTable
@@ -1272,6 +1294,52 @@ bool CClip::RemoveStickySetting(int parentId)
 	return reset;
 }
 
+bool CClip::RemoveStickySetting(int clipId, int parentId)
+{
+	bool reset = false;
+	if (parentId < 0)
+	{
+		int c = theApp.m_db.execDMLEx(_T("UPDATE Main SET stickyClipOrder = %f WHERE lID = %d"), (double)INVALID_STICKY, clipId);
+		int y = 0;
+	}
+	else
+	{
+		int c = theApp.m_db.execDMLEx(_T("UPDATE Main SET stickyClipGroupOrder = %f WHERE lID = %d"), (double)INVALID_STICKY, clipId);
+		int y = 0;
+	}
+
+	return reset;
+}
+
+double CClip::GetExistingTopStickyClipId(int parentId)
+{
+	int existingTopClipId = -1;
+
+	try
+	{
+		if (parentId < 0)
+		{
+			CppSQLite3Query q = theApp.m_db.execQuery(_T("SELECT lID FROM Main WHERE stickyClipOrder <> -(2147483647) ORDER BY stickyClipOrder DESC LIMIT 1"));
+			if (q.eof() == false)
+			{
+				existingTopClipId = q.getIntField(_T("lID"));
+			}
+		}
+		else
+		{
+			CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID FROM Main WHERE lParentID = %d AND stickyClipGroupOrder <> -(2147483647) ORDER BY stickyClipGroupOrder DESC LIMIT 1"), parentId);
+			if (q.eof() == false)
+			{
+				existingTopClipId = q.getIntField(_T("lID"));
+			}
+		}
+
+	}
+	CATCH_SQLITE_EXCEPTION
+
+	return existingTopClipId;
+}
+
 double CClip::GetNewTopSticky(int parentId, int clipId)
 {
 	double newOrder = 1;
@@ -1282,7 +1350,7 @@ double CClip::GetNewTopSticky(int parentId, int clipId)
 	{
 		if (parentId < 0)
 		{
-			CppSQLite3Query q = theApp.m_db.execQuery(_T("SELECT stickyClipOrder, mText FROM Main WHERE stickyClipOrder <> -(2147483647) ORDER BY stickyClipOrder DESC LIMIT 1"));
+			CppSQLite3Query q = theApp.m_db.execQuery(_T("SELECT lID, stickyClipOrder, mText FROM Main WHERE stickyClipOrder <> -(2147483647) ORDER BY stickyClipOrder DESC LIMIT 1"));
 			if (q.eof() == false)
 			{
 				existingMaxOrder = q.getFloatField(_T("stickyClipOrder"));
@@ -1292,7 +1360,7 @@ double CClip::GetNewTopSticky(int parentId, int clipId)
 		}
 		else
 		{
-			CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT stickyClipGroupOrder, mText FROM Main WHERE lParentID = %d AND stickyClipGroupOrder <> -(2147483647) ORDER BY stickyClipGroupOrder DESC LIMIT 1"), parentId);
+			CppSQLite3Query q = theApp.m_db.execQueryEx(_T("SELECT lID, stickyClipGroupOrder, mText FROM Main WHERE lParentID = %d AND stickyClipGroupOrder <> -(2147483647) ORDER BY stickyClipGroupOrder DESC LIMIT 1"), parentId);
 			if (q.eof() == false)
 			{
 				existingMaxOrder = q.getFloatField(_T("stickyClipGroupOrder"));

+ 7 - 1
Clip.h

@@ -124,12 +124,14 @@ public:
 	virtual CString QuickPaste() { return m_csQuickPaste; }
 	virtual void QuickPaste(CString csValue) { m_csQuickPaste = csValue; }
 
+	virtual void SetSaveToDbSticky(AddToDbStickyEnum::AddToDbSticky option) { m_addToDbStickyEnum = option; }
+
 	virtual IClipFormats *Clips() { return (IClipFormats*)&m_Formats; }
 
 	void Clear();
 	void EmptyFormats();
 	bool AddFormat(CLIPFORMAT cfType, void* pData, UINT nLen, bool setDesc = false);
-	int LoadFromClipboard(CClipTypes* pClipTypes, bool checkClipboardIgnore = true, CString activeApp = _T(""));
+	int LoadFromClipboard(CClipTypes* pClipTypes, bool checkClipboardIgnore = true, CString activeApp = _T(""), CString activeAppTitle = _T(""));
 	bool SetDescFromText(HGLOBAL hgData, bool unicode);
 	bool SetDescFromType();
 	bool AddToDB(bool bCheckForDuplicates = true);
@@ -166,6 +168,8 @@ public:
 	double GetNewLastOrder(int parentId, int clipId);
 	static double GetNewTopSticky(int parentId, int clipId);
 	static double GetNewLastSticky(int parentId, int clipId);
+	static double GetExistingTopStickyClipId(int parentId);
+	static bool RemoveStickySetting(int clipId, int parentId);
 
 	bool AddFileDataToData(CString &errorMessage);
 
@@ -175,6 +179,8 @@ protected:
 	bool AddToMainTable();
 	bool AddToDataTable();
 	int FindDuplicate();
+
+	AddToDbStickyEnum::AddToDbSticky m_addToDbStickyEnum;
 };
 
 

+ 7 - 2
ClipboardViewer.cpp

@@ -27,7 +27,8 @@ CClipboardViewer::CClipboardViewer(CCopyThread* pHandler) :
 	m_dwLastCopy(0),
 	m_connectOnStartup(true)
 {
-
+	m_activeWindowTitle = _T("");
+	m_activeWindow = _T("");
 }
 
 CClipboardViewer::~CClipboardViewer()
@@ -293,6 +294,7 @@ void CClipboardViewer::OnDrawClipboard()
 bool CClipboardViewer::ValidActiveWnd()
 {
 	m_activeWindow = _T("");
+	m_activeWindowTitle = _T("";)
 
 	HWND owner = ::GetClipboardOwner();
 	if (owner != NULL)
@@ -303,6 +305,7 @@ bool CClipboardViewer::ValidActiveWnd()
 		if (PID != 0)
 		{
 			m_activeWindow = GetProcessName(NULL, PID);
+			m_activeWindowTitle = TopLevelWindowText(PID);			
 		}
 	}
 
@@ -311,6 +314,7 @@ bool CClipboardViewer::ValidActiveWnd()
 	{
 		HWND active = ::GetForegroundWindow();
 		m_activeWindow = GetProcessName(active, 0);
+		m_activeWindowTitle = GetWndText(active);
 	}
 
 	m_activeWindow = m_activeWindow.MakeLower();
@@ -391,7 +395,7 @@ void CClipboardViewer::OnTimer(UINT_PTR nIDEvent)
 				{
 					Log(StrF(_T("OnDrawClipboard::OnTimer %d"), dwNow));
 
-					m_pHandler->OnClipboardChange(m_activeWindow);
+					m_pHandler->OnClipboardChange(m_activeWindow, m_activeWindowTitle);
 
 					m_dwLastCopy = dwNow;
 				}
@@ -402,6 +406,7 @@ void CClipboardViewer::OnTimer(UINT_PTR nIDEvent)
 			}
 
 			m_activeWindow = _T("");
+			m_activeWindowTitle = _T("");
 		}
 		break;
 

+ 1 - 0
ClipboardViewer.h

@@ -33,6 +33,7 @@ public:
 	bool	m_bIsConnected;
 	bool	m_connectOnStartup;
 	CString m_activeWindow;
+	CString m_activeWindowTitle;
 
 	// m_pHandler->OnClipboardChange is called when the clipboard changes.
 	CCopyThread*	m_pHandler;

+ 2 - 2
CopyThread.cpp

@@ -51,7 +51,7 @@ int CCopyThread::ExitInstance()
 }
 
 // Called within Copy Thread:
-void CCopyThread::OnClipboardChange(CString activeWindow)
+void CCopyThread::OnClipboardChange(CString activeWindow, CString activeWindowTitle)
 {
 	Log(_T("OnClipboardChange - Start"));
 
@@ -107,7 +107,7 @@ void CCopyThread::OnClipboardChange(CString activeWindow)
 	}
 
 	Log(_T("LoadFromClipboard - Before"));
-	int bResult = pClip->LoadFromClipboard(pSupportedTypes, true, activeWindow);
+	int bResult = pClip->LoadFromClipboard(pSupportedTypes, true, activeWindow, activeWindowTitle);
 	Log(_T("LoadFromClipboard - After"));
 
 	if(bResult == FALSE)

+ 1 - 1
CopyThread.h

@@ -62,7 +62,7 @@ public:
 	CCopyConfig         m_LocalConfig;
 
 	// Called within Copy Thread:
-	void OnClipboardChange(CString activeWindow); // called by ClipboardViewer
+	void OnClipboardChange(CString activeWindow, CString activeWindowTitle); // called by ClipboardViewer
 	void SyncConfig(); // safely syncs m_LocalConfig with m_SharedConfig
 
 // Shared (use thread-safe access functions below)

+ 18 - 1
DittoChaiScript.cpp

@@ -7,10 +7,11 @@
 
 #include <regex>
 
-CDittoChaiScript::CDittoChaiScript(IClip *pClip, std::string activeApp)
+CDittoChaiScript::CDittoChaiScript(IClip *pClip, std::string activeApp, std::string activeAppTitle)
 {
 	m_pClip = pClip;
 	m_activeApp = activeApp;
+	m_activeAppTitle = activeAppTitle;
 }
 
 
@@ -159,4 +160,20 @@ BOOL CDittoChaiScript::AsciiTextMatchesRegex(std::string regex)
 		matches = true;
 	}
 	return matches;
+}
+
+
+void CDittoChaiScript::SetMakeTopSticky()
+{
+	m_pClip->SetSaveToDbSticky(AddToDbStickyEnum::MAKE_LAST_STICKY);
+}
+
+void CDittoChaiScript::SetMakeLastSticky()
+{
+	m_pClip->SetSaveToDbSticky(AddToDbStickyEnum::MAKE_LAST_STICKY);
+}
+
+void CDittoChaiScript::SetReplaceTopSticky()
+{
+	m_pClip->SetSaveToDbSticky(AddToDbStickyEnum::REPLACE_TOP_STICKY);
 }

+ 7 - 1
DittoChaiScript.h

@@ -7,11 +7,12 @@
 class CDittoChaiScript
 {
 public:
-	CDittoChaiScript(IClip *pClip, std::string activeApp);
+	CDittoChaiScript(IClip *pClip, std::string activeApp, std::string activeAppTitle);
 	~CDittoChaiScript();
 
 	IClip *m_pClip;
 	std::string m_activeApp;
+	std::string m_activeAppTitle;
 
 	std::string GetAsciiString();
 	void SetAsciiString(std::string stringVal);
@@ -20,10 +21,15 @@ public:
 	SIZE_T GetClipSize(std::string clipboardFormat);
 
 	std::string GetActiveApp() { return m_activeApp; }
+	std::string GetActiveAppTitle() { return m_activeAppTitle; }
 
 	BOOL RemoveFormat(std::string clipboardFormat);
 	BOOL FormatExists(std::string clipboardFormat);
 	BOOL SetParentId(int parentId);
 	BOOL AsciiTextMatchesRegex(std::string regex);
+
+	void SetMakeTopSticky();
+	void SetMakeLastSticky();
+	void SetReplaceTopSticky();
 };
 

+ 56 - 7
Misc.cpp

@@ -228,14 +228,63 @@ CString RemoveEscapes( const TCHAR* str )
 	return ret;
 }
 
-CString GetWndText( HWND hWnd )
+CString GetWndText(HWND hWnd)
 {
-	CString text;
-	if( !IsWindow(hWnd) )
-		return "! NOT A VALID WINDOW !";
-	CWnd* pWnd = CWnd::FromHandle(hWnd);
-	pWnd->GetWindowText(text);
-	return text;
+	TCHAR cWindowText[200];
+	HWND hParent = hWnd;
+
+	::GetWindowText(hParent, cWindowText, 100);
+
+	int nCount = 0;
+
+	while (STRLEN(cWindowText) <= 0)
+	{
+		hParent = ::GetParent(hParent);
+		if (hParent == NULL)
+			break;
+
+		::GetWindowText(hParent, cWindowText, 100);
+
+		nCount++;
+		if (nCount > 100)
+		{
+			Log(_T("GetTargetName reached maximum search depth of 100"));
+			break;
+		}
+	}
+
+	return cWindowText;
+}
+
+CString TopLevelWindowText(DWORD pid)
+{
+	std::pair<CString, DWORD> params = { _T(""), pid };
+
+	// Enumerate the windows using a lambda to process each window
+	BOOL bResult = EnumWindows([](HWND hwnd, LPARAM lParam) -> BOOL
+	{
+		auto pParams = (std::pair<CString, DWORD>*)(lParam);
+
+		DWORD processId;
+		if (GetWindowThreadProcessId(hwnd, &processId) &&
+			processId == pParams->second &&
+			::GetWindow(hwnd, GW_OWNER) == 0)
+		{
+			TCHAR cWindowText[500];
+			::GetWindowText(hwnd, cWindowText, 500);
+
+			if (STRLEN(cWindowText) > 0)
+			{
+				pParams->first = cWindowText;
+				return FALSE;
+			}
+		}
+
+		// Continue enumerating
+		return TRUE;
+	}, (LPARAM)&params);
+
+	return params.first;
 }
 
 bool IsAppWnd( HWND hWnd )

+ 2 - 0
Misc.h

@@ -196,4 +196,6 @@ CString NewGuidString();
 
 CString FolderPath(int folderId);
 
+CString TopLevelWindowText(DWORD pid);
+
 #endif // !defined(AFX_CP_GUI_GLOBALS__FBCDED09_A6F2_47EB_873F_50A746EBC86B__INCLUDED_)

+ 1 - 1
OleClipSource.cpp

@@ -206,7 +206,7 @@ BOOL COleClipSource::DoImmediateRender()
 					Log(StrF(_T("Start of paste script name: %s, script: %s"), element.m_name, element.m_script));
 
 					ChaiScriptOnCopy onPaste;
-					CDittoChaiScript clipData(&clip, "");
+					CDittoChaiScript clipData(&clip, "", "");
 					if (onPaste.ProcessScript(clipData, (LPCSTR)CTextConvert::ConvertToChar(element.m_script)) == false)
 					{
 						Log(StrF(_T("End of paste script name: %s, returned false, not saving this copy to Ditto, last Error: %s"), element.m_name, onPaste.m_lastError));

+ 4 - 1
Resource.h

@@ -262,6 +262,7 @@
 #define IDC_EDIT_DESCRIP                1018
 #define IDC_EDIT_DESC                   1018
 #define IDC_ADD_1                       1019
+#define IDC_EDIT_ACTIVE_APP_TITLE       1019
 #define IDC_ADD_2                       1020
 #define IDC_EDIT_DISPLAY_TEXT           1020
 #define IDC_ADD_3                       1021
@@ -595,6 +596,8 @@
 #define IDC_MFCLINK2_EXAMPLES           2166
 #define IDC_STATIC_MD5                  2167
 #define IDC_EDIT_MD5                    2168
+#define IDC_RICHEDIT21                  2172
+#define IDC_EDIT_ACTIVE_APP             2173
 #define ID_FIRST_OPTION                 32771
 #define ID_FIRST_EXIT                   32772
 #define ID_FIRST_SHOWQUICKPASTE         32773
@@ -781,7 +784,7 @@
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        383
 #define _APS_NEXT_COMMAND_VALUE         32958
-#define _APS_NEXT_CONTROL_VALUE         2172
+#define _APS_NEXT_CONTROL_VALUE         2174
 #define _APS_NEXT_SYMED_VALUE           104
 #endif
 #endif

+ 47 - 9
ScriptEditor.cpp

@@ -28,6 +28,7 @@ void CScriptEditor::DoDataExchange(CDataExchange* pDX)
 {
 	CDialogEx::DoDataExchange(pDX);
 	DDX_Control(pDX, IDC_LIST_SCRIPTS, m_scriptsList);
+	DDX_Control(pDX, IDC_RICHEDIT21, m_rich);
 }
 
 
@@ -36,7 +37,7 @@ BEGIN_MESSAGE_MAP(CScriptEditor, CDialogEx)
 	ON_BN_CLICKED(IDC_BUTTON_ADD_SCRIPT, &CScriptEditor::OnBnClickedButtonAddScript)
 	ON_EN_KILLFOCUS(IDC_EDIT_NAME, &CScriptEditor::OnEnKillfocusEditName)
 	ON_EN_KILLFOCUS(IDC_EDIT_DESC, &CScriptEditor::OnEnKillfocusEditDesc)
-	ON_EN_KILLFOCUS(IDC_EDIT_SCRIPT, &CScriptEditor::OnEnKillfocusEditScript)
+	ON_EN_KILLFOCUS(IDC_RICHEDIT21, &CScriptEditor::OnEnKillfocusEditScript)
 	ON_BN_CLICKED(IDC_CHECK_ACTIVE, &CScriptEditor::OnBnClickedCheckActive)
 	ON_WM_SIZE()
 	ON_BN_CLICKED(IDC_BUTTON_DELETE_SCRIPT, &CScriptEditor::OnBnClickedButtonDeleteScript)
@@ -52,6 +53,8 @@ BOOL CScriptEditor::OnInitDialog()
 
 	SetWindowText(m_title);
 
+	
+
 	int index = 0;
 	for (auto & listItem : m_xml.m_list)
 	{
@@ -81,7 +84,7 @@ BOOL CScriptEditor::OnInitDialog()
 	m_resize.AddControl(IDC_LIST_SCRIPTS, DR_SizeHeight);
 	m_resize.AddControl(IDC_EDIT_DESC, DR_SizeWidth);
 	m_resize.AddControl(IDC_EDIT_NAME, DR_SizeWidth);
-	m_resize.AddControl(IDC_EDIT_SCRIPT, DR_SizeWidth | DR_SizeHeight);
+	m_resize.AddControl(IDC_RICHEDIT21, DR_SizeWidth | DR_SizeHeight);
 
 	m_resize.AddControl(IDC_STATIC_RETURN_DESC, DR_MoveTop | DR_SizeWidth);
 	m_resize.AddControl(IDC_STATIC_INPUT, DR_MoveTop);
@@ -92,9 +95,14 @@ BOOL CScriptEditor::OnInitDialog()
 
 	m_resize.AddControl(IDC_BUTTON_RUN, DR_MoveTop | DR_MoveLeft);
 
+	m_resize.AddControl(IDC_EDIT_ACTIVE_APP, DR_MoveTop | DR_MoveLeft);
+	m_resize.AddControl(IDC_EDIT_ACTIVE_APP_TITLE, DR_MoveTop | DR_MoveLeft);
+
 	m_resize.AddControl(IDC_BUTTON_DELETE_SCRIPT, DR_MoveTop);
 	m_resize.AddControl(IDC_BUTTON_ADD_SCRIPT, DR_MoveTop);	
-	
+
+	SetDlgItemText(IDC_EDIT_ACTIVE_APP, _T("App name"));
+	SetDlgItemText(IDC_EDIT_ACTIVE_APP_TITLE, _T("App Title"));	
 
 	return FALSE;
 }
@@ -114,7 +122,7 @@ void CScriptEditor::OnLbnSelchangeListScripts()
 		{
 			this->CheckDlgButton(IDC_CHECK_ACTIVE, BST_UNCHECKED);
 		}
-		this->SetDlgItemText(IDC_EDIT_SCRIPT, m_xml.m_list[listIndex].m_script);
+		this->SetDlgItemText(IDC_RICHEDIT21, m_xml.m_list[listIndex].m_script);
 
 		this->GetDlgItem(IDC_EDIT_NAME)->SetFocus();
 	}
@@ -137,7 +145,7 @@ void CScriptEditor::OnBnClickedButtonAddScript()
 
 	this->SetDlgItemText(IDC_EDIT_NAME, newItem.m_name);
 	this->SetDlgItemText(IDC_EDIT_DESC, _T(""));
-	this->SetDlgItemText(IDC_EDIT_SCRIPT, _T(""));
+	this->SetDlgItemText(IDC_RICHEDIT21, _T(""));
 	this->CheckDlgButton(IDC_CHECK_ACTIVE, BST_CHECKED);
 
 	this->GetDlgItem(IDC_EDIT_NAME)->SetFocus();
@@ -188,7 +196,7 @@ void CScriptEditor::OnEnKillfocusEditScript()
 	if (listIndex >= 0 && listIndex < m_xml.m_list.size())
 	{
 		CString script;
-		this->GetDlgItemText(IDC_EDIT_SCRIPT, script);
+		this->GetDlgItemText(IDC_RICHEDIT21, script);
 		m_xml.m_list[listIndex].m_script = script;
 	}
 }
@@ -250,7 +258,7 @@ void CScriptEditor::EnableDisable(BOOL enable)
 {
 	::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT_NAME), enable);
 	::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT_DESC), enable);
-	::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT_SCRIPT), enable);
+	::EnableWindow(::GetDlgItem(m_hWnd, IDC_RICHEDIT21), enable);
 	::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT_INPUT), enable);
 	::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT_OUTPUT), enable);
 	::EnableWindow(::GetDlgItem(m_hWnd, IDC_BUTTON_RUN), enable);
@@ -264,11 +272,18 @@ void CScriptEditor::OnBnClickedButtonRun()
 	CString input;
 	GetDlgItemText(IDC_EDIT_INPUT, input);
 	CString script;
-	GetDlgItemText(IDC_EDIT_SCRIPT, script);
+	GetDlgItemText(IDC_RICHEDIT21, script);
+
+	CString app;
+	GetDlgItemText(IDC_EDIT_ACTIVE_APP, app);
+
+	CString appTitle;
+	GetDlgItemText(IDC_EDIT_ACTIVE_APP_TITLE, appTitle);
 
 	CClip clip;
+
 	ChaiScriptOnCopy test;
-	CDittoChaiScript clipData(&clip, "");
+	CDittoChaiScript clipData(&clip, (LPCSTR)CTextConvert::UnicodeStringToMultiByte(app), (LPCSTR)CTextConvert::UnicodeStringToMultiByte(appTitle));
 	clipData.SetAsciiString((LPCSTR)CTextConvert::UnicodeStringToMultiByte(input));
 	
 	test.ProcessScript(clipData, (LPCSTR)CTextConvert::UnicodeStringToMultiByte(script));
@@ -282,3 +297,26 @@ void CScriptEditor::OnBnClickedButtonRun()
 		SetDlgItemText(IDC_EDIT_OUTPUT, test.m_lastError);
 	}
 }
+
+
+BOOL CScriptEditor::PreTranslateMessage(MSG* pMsg)
+{
+	// TODO: Add your specialized code here and/or call the base class
+
+	if ((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_TAB) && (pMsg->hwnd == m_rich.GetSafeHwnd()))
+	{
+		long lStart, lEnd;
+		m_rich.GetSel(lStart, lEnd);
+		
+		// select zero chars
+		m_rich.SetSel(lStart, lStart);
+		// then replace that selection with a TAB
+		m_rich.ReplaceSel(_T("\t"), TRUE);
+
+		// no need to do a msg translation, so quit. 
+		// that way no further processing gets done
+		return TRUE;
+	}
+
+	return CDialogEx::PreTranslateMessage(pMsg);
+}

+ 2 - 0
ScriptEditor.h

@@ -44,4 +44,6 @@ public:
 	afx_msg void OnSize(UINT nType, int cx, int cy);
 	afx_msg void OnBnClickedButtonDeleteScript();
 	afx_msg void OnBnClickedButtonRun();
+	CRichEditCtrl m_rich;
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
 };

+ 12 - 0
Shared/DittoDefines.h

@@ -193,4 +193,16 @@ public:
 
 		return _T("ERROR");
 	}
+};
+
+class AddToDbStickyEnum
+{
+public:
+	enum AddToDbSticky
+	{
+		INVALID,
+		MAKE_TOP_STICKY,
+		MAKE_LAST_STICKY,
+		REPLACE_TOP_STICKY
+	};
 };

+ 3 - 0
Shared/IClip.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include "DittoDefines.h"
+
 //Contains the actual data of a clip format
 // Type is the type of clipboard format
 // Data is a HGLOBAL object pointing to the clipboard format data
@@ -42,6 +44,7 @@ public:
 	virtual void DontAutoDelete(int Dont) = 0;
 	virtual CString QuickPaste() = 0;
 	virtual void QuickPaste(CString csValue) = 0;
+	virtual void SetSaveToDbSticky(AddToDbStickyEnum::AddToDbSticky option) = 0;
 
 	virtual IClipFormats *Clips() = 0;
 };

+ 2 - 0
chaiscript/dispatchkit/bootstrap_stl.hpp

@@ -719,6 +719,8 @@ namespace chaiscript
 		  m.add(fun([](const String *s, typename String::value_type c, size_t pos) { return s->find_first_not_of(c, pos); } ), "find_first_not_of");
 
 		  m.add(fun([](String *s, typename String::value_type c) -> decltype(auto) { return (*s += c); } ), "+=");
+		  
+		  m.add(fun([](String *s) { std::reverse(s->begin(), s->end()); } ), "reverse");
 
 
           m.add(fun([](String *s) { s->clear(); } ), "clear");