Browse Source

added rich text, html format, cf_hdrop to multiclip pastes
[SAB]


git-svn-id: svn://svn.code.sf.net/p/ditto-cp/code/trunk@381 595ec19a-5cb4-439b-94a8-42fb3063c22c

sabrogden 18 years ago
parent
commit
5edebc3222
23 changed files with 245 additions and 139 deletions
  1. 1 0
      CP_Main.cpp
  2. 1 0
      CP_Main.h
  3. 6 3
      CP_Main.rc
  4. 35 2
      CP_Main.vcproj
  5. 94 94
      ClipIds.cpp
  6. 3 4
      ClipIds.h
  7. BIN
      Debug/focus.dll
  8. BIN
      Debug/focus.lib
  9. 1 1
      FileRecieve.cpp
  10. 1 0
      FileRecieve.h
  11. 1 0
      FileTransferProgressDlg.h
  12. 2 2
      Misc.cpp
  13. 1 1
      Misc.h
  14. 53 31
      OleClipSource.cpp
  15. 18 0
      Options.cpp
  16. 3 0
      Options.h
  17. 6 0
      OptionsGeneral.cpp
  18. 1 0
      OptionsGeneral.h
  19. 5 0
      QPasteWnd.cpp
  20. 3 1
      Resource.h
  21. 9 0
      TextConvert.cpp
  22. 1 0
      TextConvert.h
  23. BIN
      UEncryptDecryptD.lib

+ 1 - 0
CP_Main.cpp

@@ -119,6 +119,7 @@ CCP_MainApp::CCP_MainApp()
 
 	m_lLastGoodIndexForNextworkPassword = -2;
 
+	m_RTFFormat = ::RegisterClipboardFormat(_T("Rich Text Format"));
 	m_HTML_Format = ::RegisterClipboardFormat(_T("HTML Format"));
 	m_PingFormat = ::RegisterClipboardFormat(_T("Ditto Ping Format"));
 	m_cfIgnoreClipboard = ::RegisterClipboardFormat(_T("Clipboard Viewer Ignore"));

+ 1 - 0
CP_Main.h

@@ -174,6 +174,7 @@ public:
 	CLIPFORMAT m_PingFormat;
 	CLIPFORMAT m_HTML_Format;
 	CLIPFORMAT m_RemoteCF_HDROP;
+	CLIPFORMAT m_RTFFormat;
 
 	COleDateTime m_oldtStartUp;
 

+ 6 - 3
CP_Main.rc

@@ -579,7 +579,7 @@ BEGIN
                     SS_CENTERIMAGE
 END
 
-IDD_OPTIONS_GENERAL DIALOGEX 0, 0, 351, 254
+IDD_OPTIONS_GENERAL DIALOGEX 0, 0, 351, 259
 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | 
     WS_SYSMENU
 CAPTION "General"
@@ -640,6 +640,9 @@ BEGIN
     CONTROL         "Ensure Ditto is always connected to the clipboard",
                     IDC_ENSURE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,23,228,
                     306,10
+    LTEXT           "Multi-Paste clip separator ([LF] = line feed)",
+                    IDC_STATIC_CLIP_SEPARATOR,23,242,161,8
+    EDITTEXT        IDC_EDIT_CLIP_SEPARATOR,187,240,106,12,ES_AUTOHSCROLL
 END
 
 IDD_SELECT_DB DIALOGEX 0, 0, 276, 46
@@ -838,7 +841,7 @@ BEGIN
     LTEXT           "a",IDC_STATIC_1,7,33,270,10,SS_CENTERIMAGE
     LTEXT           "",IDC_STATIC_2,7,59,270,16,SS_CENTERIMAGE
     CONTROL         "Animate1",IDC_FILE_COPY,"SysAnimate32",ACS_CENTER | 
-                    ACS_TRANSPARENT | WS_TABSTOP,7,4,270,26
+                    ACS_TRANSPARENT | WS_TABSTOP,7,3,270,26
 END
 
 IDD_OPTIONS_COPY_BUFFERS DIALOGEX 0, 0, 287, 250
@@ -995,7 +998,7 @@ BEGIN
         LEFTMARGIN, 7
         RIGHTMARGIN, 344
         TOPMARGIN, 7
-        BOTTOMMARGIN, 246
+        BOTTOMMARGIN, 254
     END
 
     IDD_SELECT_DB, DIALOG

+ 35 - 2
CP_Main.vcproj

@@ -441,6 +441,15 @@
 						BasicRuntimeChecks="3"/>
 				</FileConfiguration>
 			</File>
+			<File
+				RelativePath=".\CF_HDropAggregator.cpp">
+			</File>
+			<File
+				RelativePath=".\CF_TextAggregator.cpp">
+			</File>
+			<File
+				RelativePath=".\CF_UnicodeTextAggregator.cpp">
+			</File>
 			<File
 				RelativePath="Clip.cpp">
 				<FileConfiguration
@@ -1056,6 +1065,9 @@
 						BasicRuntimeChecks="3"/>
 				</FileConfiguration>
 			</File>
+			<File
+				RelativePath=".\HTMLFormatAggregator.cpp">
+			</File>
 			<File
 				RelativePath="InternetUpdate.cpp">
 				<FileConfiguration
@@ -1802,6 +1814,9 @@
 						BasicRuntimeChecks="3"/>
 				</FileConfiguration>
 			</File>
+			<File
+				RelativePath=".\RichTextAggregator.cpp">
+			</File>
 			<File
 				RelativePath=".\SaveAnimation.cpp">
 			</File>
@@ -2627,6 +2642,15 @@
 			<File
 				RelativePath="BitmapHelper.h">
 			</File>
+			<File
+				RelativePath=".\CF_HDropAggregator.h">
+			</File>
+			<File
+				RelativePath=".\CF_TextAggregator.h">
+			</File>
+			<File
+				RelativePath=".\CF_UnicodeTextAggregator.h">
+			</File>
 			<File
 				RelativePath="Clip.h">
 			</File>
@@ -2696,9 +2720,15 @@
 			<File
 				RelativePath="GroupTree.h">
 			</File>
+			<File
+				RelativePath=".\HTMLFormatAggregator.h">
+			</File>
 			<File
 				RelativePath="HyperLink.h">
 			</File>
+			<File
+				RelativePath=".\IClipAggregator.h">
+			</File>
 			<File
 				RelativePath="InternetUpdate.h">
 			</File>
@@ -2768,6 +2798,9 @@
 			<File
 				RelativePath="Resource.h">
 			</File>
+			<File
+				RelativePath=".\RichTextAggregator.h">
+			</File>
 			<File
 				RelativePath=".\SaveAnimation.h">
 			</File>
@@ -2936,7 +2969,7 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="Debug\focus.dll">
+				RelativePath="Release\focus.dll">
 				<FileConfiguration
 					Name="Release|Win32"
 					ExcludedFromBuild="TRUE">
@@ -2963,7 +2996,7 @@
 				</FileConfiguration>
 			</File>
 			<File
-				RelativePath="Release\focus.dll">
+				RelativePath="Debug\focus.dll">
 				<FileConfiguration
 					Name="Release|Win32"
 					ExcludedFromBuild="TRUE">

+ 94 - 94
ClipIds.cpp

@@ -4,6 +4,11 @@
 #include "tinyxml.h"
 #include "TextConvert.h"
 #include "Clip_ImportExport.h"
+#include "CF_HDropAggregator.h"
+#include "CF_UnicodeTextAggregator.h"
+#include "CF_TextAggregator.h"
+#include "richtextaggregator.h"
+#include "htmlformataggregator.h"
 
 // allocate an HGLOBAL of the given Format Type representing these Clip IDs.
 HGLOBAL CClipIDs::Render(UINT cfType)
@@ -19,97 +24,106 @@ HGLOBAL CClipIDs::Render(UINT cfType)
 		return CClip::LoadFormat(ElementAt(0), cfType);
 	}
 
-	CStringA csText;
-	if(AggregateText(CF_TEXT, "\r\n", g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop, csText))
+	CStringA SepA = CTextConvert::ConvertToChar(g_Opt.GetMultiPasteSeparator());
+	CStringW SepW = CTextConvert::ConvertToUnicode(g_Opt.GetMultiPasteSeparator());
+
+	if(cfType == CF_TEXT)
+	{
+		CCF_TextAggregator CFText(SepA);
+		if(AggregateData(CFText, CF_TEXT, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop))
+		{
+			return CFText.GetHGlobal();
+		}
+	}
+	else if(cfType == CF_UNICODETEXT)
+	{
+		CCF_UnicodeTextAggregator CFUnicodeText(SepW);
+		if(AggregateData(CFUnicodeText, CF_UNICODETEXT, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop))
+		{
+			return CFUnicodeText.GetHGlobal();
+		}
+	}
+	else if(cfType == CF_HDROP)
+	{
+		CCF_HDropAggregator HDrop;
+		if(AggregateData(HDrop, CF_HDROP, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop))
+		{
+			return HDrop.GetHGlobal();
+		}
+	}
+	else if(cfType == theApp.m_HTML_Format)
+	{
+		CHTMLFormatAggregator Html(SepA);
+		if(AggregateData(Html, theApp.m_HTML_Format, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop))
+		{
+			return Html.GetHGlobal();
+		}
+	}
+	else if(cfType == theApp.m_RTFFormat)
 	{
-		long lLen = csText.GetLength();
-		HGLOBAL h = NewGlobalP(csText.GetBuffer(lLen), lLen+1);
-		return h;
+		CRichTextAggregator RichText(SepA);
+		if(AggregateData(RichText, theApp.m_RTFFormat, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop))
+		{
+			return RichText.GetHGlobal();
+		}
 	}
+	
 	return NULL;
 }
 
 void CClipIDs::GetTypes(CClipTypes& types)
 {
-	int count = GetSize();
+	int IDCount = GetSize();
 	types.RemoveAll();
-	if(count > 1)
-	{
-		types.Add(CF_TEXT);
-	}
-	else if(count == 1)
+
+	if(IDCount == 1)
 	{
 		CClip::LoadTypes(ElementAt(0), types);
 	}
-}
-
-// Aggregates the cfType Format Data of the Clip IDs in this array, assuming
-//  each Format is NULL terminated and placing pSeparator between them.
-// This assumes that the given cfType is a null terminated text type.
-bool CClipIDs::AggregateText(UINT cfType, LPCSTR lpSep, BOOL bReverse, CStringA &csNewText)
-{
-	CString csSQL;
-	int numIDs = GetSize();
-	int* pIDs = GetData();
-	bool bRet = false;
-	
-	try
+	else if(IDCount > 1)
 	{
-		int nIndex;
-		for(int i=0; i < numIDs; i++)
-		{
-			nIndex = i;
-			if(bReverse)
-			{
-				nIndex = numIDs - i - 1;
-			}
-
-			csSQL.Format(_T("SELECT Data.ooData FROM Data ")
-							_T("INNER JOIN Main ON Main.lID = Data.lParentID ")
-							_T("WHERE Data.strClipBoardFormat = '%s' ")
-							_T("AND Main.lID = %d"),
-							GetFormatName(cfType),
-							pIDs[nIndex]);
+		//Add the types that are common accross all paste ids
+		long lCount;
+		CMap<CLIPFORMAT, CLIPFORMAT, long, long> RenderTypes;
 
-			CppSQLite3Query q = theApp.m_db.execQuery(csSQL);
+		for(int nIDPos = 0; nIDPos < IDCount; nIDPos++)
+		{
+			CClipTypes CurrTypes;
+			CClip::LoadTypes(ElementAt(nIDPos), CurrTypes);
 
-			if(q.eof() == false)
-			{
-				int nDataLen = 0;
-				const unsigned char *cData = q.getBlobField(_T("ooData"), nDataLen);
-				if(cData == NULL)
-				{
-					continue;
-				}
+			int nTypeCount = CurrTypes.GetSize();
 
-				//Ensure it's null terminated
-				if(cData[nDataLen-1] != '\0')
+			for(int nType = 0; nType < nTypeCount; nType++)
+			{	
+				lCount = 0;
+				if(nIDPos == 0 || RenderTypes.Lookup(CurrTypes[nType], lCount) == TRUE)
 				{
-					int len = 0;
-					for(len = 0; len < nDataLen && cData[len] != '\0'; len++ )
-					{
-					}
-					// if it is not null terminated, skip this item
-					if(len >= nDataLen)
-						continue;
+					lCount++;
+					RenderTypes.SetAt(CurrTypes[nType], lCount);
 				}
+			}
+		}
 
-				csNewText += (LPSTR)cData;
-				csNewText += lpSep;
+		CLIPFORMAT Format;
+		POSITION pos = RenderTypes.GetStartPosition();
+		while(pos)
+		{
+			RenderTypes.GetNextAssoc(pos, Format, lCount);
+			if(lCount == IDCount)
+			{
+				types.Add(Format);
+			}			
+		}
 
-				bRet = true;
-			}
+		//If there were no common types add the first clip
+		if(types.GetSize() <= 0)
+		{
+			CClip::LoadTypes(ElementAt(0), types);
 		}
 	}
-	CATCH_SQLITE_EXCEPTION
-	catch(...  ) 
-	{
-	}
-
-	return bRet;
 }
- 
-bool CClipIDs::AggregateUnicodeText(UINT cfType, CStringW cWSep, BOOL bReverse, CStringW &csWNewString)
+
+bool CClipIDs::AggregateData(IClipAggregator &Aggregator, UINT cfType, BOOL bReverse)
 {
 	CString csSQL;
 	LPWSTR Text = NULL;
@@ -117,7 +131,7 @@ bool CClipIDs::AggregateUnicodeText(UINT cfType, CStringW cWSep, BOOL bReverse,
 	int numIDs = GetSize();
 	int* pIDs = GetData();
 	bool bRet = false;
-	
+
 	try
 	{
 		int nIndex;
@@ -128,52 +142,38 @@ bool CClipIDs::AggregateUnicodeText(UINT cfType, CStringW cWSep, BOOL bReverse,
 			{
 				nIndex = numIDs - i - 1;
 			}
-			
+
 			csSQL.Format(_T("SELECT * FROM Data ")
 				_T("INNER JOIN Main ON Main.lID = Data.lParentID ")
 				_T("WHERE Data.strClipBoardFormat = '%s' ")
 				_T("AND Main.lID = %d"),
 				GetFormatName(cfType),
 				pIDs[nIndex]);
-			
+
 			CppSQLite3Query q = theApp.m_db.execQuery(csSQL);
-			
+
 			if(q.eof() == false)
 			{
 				int nDataLen = 0;
-				const unsigned char *cData = q.getBlobField(_T("ooData"), nDataLen);
-				if(cData == NULL)
+				LPVOID pData = (LPVOID)q.getBlobField(_T("ooData"), nDataLen);
+				if(pData == NULL)
 				{
 					continue;
 				}
-				
-				//Ensure it's null terminated
-				if(cData[nDataLen-1] != '\0')
+
+				if(Aggregator.AddClip(pData, nDataLen, i, numIDs))
 				{
-					int len = 0;
-					for(len = 0; len < nDataLen && cData[len] != '\0'; len++ )
-					{
-					}
-					// if it is not null terminated, skip this item
-					if(len >= nDataLen)
-						continue;
+					bRet = true;
 				}
-				
-				nTextSize += nDataLen;
-
-				csWNewString += (LPWSTR)cData;
-				csWNewString += cWSep;
-
-				bRet = true;
 			}
 		}
 	}
 	CATCH_SQLITE_EXCEPTION
-	catch(...)
+		catch(...)
 	{
 
 	}
-		
+
 	return bRet;
 }
 

+ 3 - 4
ClipIds.h

@@ -1,5 +1,7 @@
 #pragma once
 
+#include "IClipAggregator.h"
+
 class CClipIDs : public CArrayEx<int>
 {
 public:
@@ -9,10 +11,7 @@ public:
 	HGLOBAL	Render(UINT cfType);
 	// Fills "types" with the Format Types corresponding to the Clip IDs in this array.
 	void GetTypes(CClipTypes& types);
-	// Aggregates the cfType Format Data of the Clip IDs in this array, assuming
-	//  each Format is NULL terminated and placing pSeparator between them.
-	bool AggregateText(UINT cfType, LPCSTR lpSep, BOOL bReverse, CStringA &csNewText);
-	bool AggregateUnicodeText(UINT cfType, CStringW Separator, BOOL bReverse, CStringW &csWNewString);
+	bool AggregateData(IClipAggregator &Aggregator, UINT cfType, BOOL bReverse);
 
 // MANAGEMENT FUNCTIONS
 

BIN
Debug/focus.dll


BIN
Debug/focus.lib


+ 1 - 1
FileRecieve.cpp

@@ -224,7 +224,7 @@ HGLOBAL CFileRecieve::CreateCF_HDROPBuffer()
 	{
 		STRCPY(pCurrent, (LPCTSTR)m_RecievedFiles[n]);
 
-		pCurrent += m_RecievedFiles[n].GetLength()*sizeof(TCHAR); 
+		pCurrent += m_RecievedFiles[n].GetLength(); 
 		*pCurrent = 0;
 		pCurrent++;
 	}

+ 1 - 0
FileRecieve.h

@@ -13,6 +13,7 @@ public:
 
 	long RecieveFiles(SOCKET sock, CString csIP, CFileTransferProgressDlg *pProgress);
 	HGLOBAL CreateCF_HDROPBuffer();
+	void AddFile(CString csFile)	{ m_RecievedFiles.Add(csFile); }
 
 protected:
 	long RecieveFileData(ULONG lFileSize, CString csFileName);

+ 1 - 0
FileTransferProgressDlg.h

@@ -6,6 +6,7 @@
 #endif // _MSC_VER > 1000
 // FileTransferProgressDlg.h : header file
 //
+#include "Resource.h"
 
 /////////////////////////////////////////////////////////////////////////////
 // CFileTransferProgressDlg dialog

+ 2 - 2
Misc.cpp

@@ -1063,12 +1063,12 @@ bool CTokenizer::Next(CString& cs)
 	return true;
 }
 
-CString	CTokenizer::Tail() const
+CString	CTokenizer::Tail()
 {
 	int len = m_cs.GetLength();
 	int nCurPos = m_nCurPos;
 	
-	while(nCurPos < len && m_delim[static_cast<BYTE>(m_cs[nCurPos])])
+	while(nCurPos < len && m_delim.Find(m_cs[nCurPos]))
 		++nCurPos;
 	
 	CString csResult;

+ 1 - 1
Misc.h

@@ -255,7 +255,7 @@ public:
 	void SetDelimiters(const CString& csDelim);
 
 	bool Next(CString& cs);
-	CString	Tail() const;
+	CString	Tail();
 };
 
 

+ 53 - 31
OleClipSource.cpp

@@ -2,6 +2,11 @@
 #include "CP_Main.h"
 #include "OleClipSource.h"
 #include "TextConvert.h"
+#include "CF_HDropAggregator.h"
+#include "CF_UnicodeTextAggregator.h"
+#include "CF_TextAggregator.h"
+#include "richtextaggregator.h"
+#include "htmlformataggregator.h"
 
 /*------------------------------------------------------------------*\
 COleClipSource
@@ -44,7 +49,52 @@ BOOL COleClipSource::DoImmediateRender()
 	if(count <= 0)
 		return 0;
 
-	if(count == 1)
+	BOOL bProcessedMult = FALSE;
+
+	if(count > 1)
+	{
+		CStringA SepA = CTextConvert::ConvertToChar(g_Opt.GetMultiPasteSeparator());
+		CCF_TextAggregator CFText(SepA);
+		if(m_ClipIDs.AggregateData(CFText, CF_TEXT, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop))
+		{
+			CacheGlobalData(CF_TEXT, CFText.GetHGlobal());
+			bProcessedMult = TRUE;
+		}
+
+		CStringW SepW = CTextConvert::ConvertToUnicode(g_Opt.GetMultiPasteSeparator());
+		CCF_UnicodeTextAggregator CFUnicodeText(SepW);
+		if(m_ClipIDs.AggregateData(CFUnicodeText, CF_UNICODETEXT, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop))
+		{
+			CacheGlobalData(CF_UNICODETEXT, CFUnicodeText.GetHGlobal());
+			bProcessedMult = TRUE;
+		}
+
+		if(m_bOnlyPaste_CF_TEXT == false)
+		{
+			CCF_HDropAggregator HDrop;
+			if(m_ClipIDs.AggregateData(HDrop, CF_HDROP, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop))
+			{
+				CacheGlobalData(CF_HDROP, HDrop.GetHGlobal());
+				bProcessedMult = TRUE;
+			}
+
+			CRichTextAggregator RichText(SepA);
+			if(m_ClipIDs.AggregateData(RichText, theApp.m_RTFFormat, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop))
+			{
+				CacheGlobalData(theApp.m_RTFFormat, RichText.GetHGlobal());
+				bProcessedMult = TRUE;
+			}
+
+			CHTMLFormatAggregator Html(SepA);
+			if(m_ClipIDs.AggregateData(Html, theApp.m_HTML_Format, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop))
+			{
+				CacheGlobalData(theApp.m_HTML_Format, Html.GetHGlobal());
+				bProcessedMult = TRUE;
+			}
+		}
+	}
+
+	if(count >= 1 && bProcessedMult == FALSE)
 	{
 		CClip clip;
 		CClipFormats formats;
@@ -52,37 +102,9 @@ BOOL COleClipSource::DoImmediateRender()
 		clip.LoadFormats(m_ClipIDs[0], m_bOnlyPaste_CF_TEXT);
 		
 		return PutFormatOnClipboard(&clip.m_Formats, m_bPasteHTMLFormatAs_CF_TEXT);
-	}
-	
-	HGLOBAL hGlobal;
-
-	CStringA csAText;
-	if(m_ClipIDs.AggregateText(CF_TEXT, "\r\n", g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop, csAText))
-	{
-		long lLen = csAText.GetLength();
-		hGlobal = NewGlobalP(csAText.GetBuffer(lLen), lLen+sizeof(char));
-		csAText.ReleaseBuffer();
-		CacheGlobalData(CF_TEXT, hGlobal);
-	}
-	
-	CStringW Sep = _T("\r\n");
-	CStringW csWText;
-	if(m_ClipIDs.AggregateUnicodeText(CF_UNICODETEXT, Sep, g_Opt.m_bMultiPasteReverse && g_Opt.m_bHistoryStartTop, csWText))
-	{
-		long lLen = csWText.GetLength() * sizeof(wchar_t);
-		hGlobal = NewGlobalP(csWText.GetBuffer(lLen), lLen+sizeof(wchar_t));
-		csWText.ReleaseBuffer();
-		CacheGlobalData(CF_UNICODETEXT, hGlobal);
-	}
-
-//	text = "{\rtf1";
-//	text += m_ClipIDs.AggregateText(GetFormatID(CF_RTF), "\r\n", true);
-//	text += "}";
-//	
-//	hGlobal = NewGlobalP((void*)(LPCSTR) text, text.GetLength()+1);
-//	CacheGlobalData(GetFormatID(CF_RTF), hGlobal);
+	}		
 
-	return hGlobal != 0;
+	return bProcessedMult;
 }
 
 long COleClipSource::PutFormatOnClipboard(CClipFormats *pFormats, bool bPasteHTMLFormatAs_CF_TEXT)

+ 18 - 0
Options.cpp

@@ -1651,4 +1651,22 @@ void CGetSetOptions::SetCopyBufferItem(int nPos, CCopyBufferItem &Item)
 	SetProfileLong(StrF(_T("CopyBufferPasteHotKey_%d"), nPos), Item.m_lPasteHotKey);
 	SetProfileLong(StrF(_T("CopyBufferCutHotKey_%d"), nPos), Item.m_lCutHotKey);
 	SetProfileLong(StrF(_T("CopyBufferPlaySound_%d"), nPos), Item.m_bPlaySoundOnCopy);
+}
+
+CString CGetSetOptions::GetMultiPasteSeparator(bool bConvertToLineFeeds)
+{
+	CString csSep = GetProfileString(_T("MultiPasteSeparator"), _T("[LF]"));
+	if(bConvertToLineFeeds)
+	{
+		CString csLineFeed(_T("\r\n"));
+		csSep.Replace(_T("[LF]"), csLineFeed);
+		csSep.Replace(_T("[lf]"), csLineFeed);
+	}
+
+	return csSep;
+}
+
+void CGetSetOptions::SetMultiPasteSeparator(CString csSep)
+{
+	SetProfileString(_T("MultiPasteSeparator"), csSep);
 }

+ 3 - 0
Options.h

@@ -346,6 +346,9 @@ public:
 
 	static void		GetCopyBufferItem(int nPos, CCopyBufferItem &Item);
 	static void		SetCopyBufferItem(int nPos, CCopyBufferItem &Item);
+
+	static CString  GetMultiPasteSeparator(bool bConvertToLineFeeds = true);
+	static void		SetMultiPasteSeparator(CString csSep);
 };
 
 // global for easy access and for initialization of fast access variables

+ 6 - 0
OptionsGeneral.cpp

@@ -60,6 +60,7 @@ void COptionsGeneral::DoDataExchange(CDataExchange* pDX)
 	DDX_Control(pDX, IDC_DISPLAY_IN_SYSTEMTRAY, m_btShowIconInSysTray);
 	DDX_Control(pDX, IDC_START_ON_STARTUP, m_btRunOnStartup);
 	DDX_Text(pDX, IDC_EDIT_PLAY_SOUND, m_csPlaySound);
+	DDX_Control(pDX, IDC_EDIT_CLIP_SEPARATOR, m_ClipSeparator);
 	//}}AFX_DATA_MAP
 	DDX_Control(pDX, IDC_ALLOW_DUPLICATES, m_btAllowDuplicates);
 	DDX_Control(pDX, IDC_UPDATE_TIME_ON_PASTE, m_btUpdateTimeOnPaste);
@@ -106,6 +107,8 @@ BOOL COptionsGeneral::OnInitDialog()
 	m_btSendPasteMessage.SetCheck(g_Opt.m_bSendPasteMessageAfterSelection);
 	m_EnsureConnected.SetCheck(g_Opt.m_bEnsureConnectToClipboard);
 
+	m_ClipSeparator.SetWindowText(g_Opt.GetMultiPasteSeparator(false));
+
 	if(g_Opt.m_lMaxClipSizeInBytes > 0)
 	{
 		CString csMax;
@@ -213,6 +216,9 @@ BOOL COptionsGeneral::OnApply()
 	g_Opt.SetAllowDuplicates(m_btAllowDuplicates.GetCheck());
 	g_Opt.SetUpdateTimeOnPaste(m_btUpdateTimeOnPaste.GetCheck());
 	g_Opt.SetSaveMultiPaste(m_btSaveMultiPaste.GetCheck());
+	CString csSep;
+	m_ClipSeparator.GetWindowText(csSep);
+	g_Opt.SetMultiPasteSeparator(csSep);
 
 	CString csLanguage;
 	if(m_cbLanguage.GetCurSel() >= 0)

+ 1 - 0
OptionsGeneral.h

@@ -48,6 +48,7 @@ public:
 	CButton m_btUpdateTimeOnPaste;
 	CButton m_btSaveMultiPaste;
 	CString	m_csPlaySound;
+	CEdit m_ClipSeparator;
 	//}}AFX_DATA
 
 

+ 5 - 0
QPasteWnd.cpp

@@ -574,6 +574,11 @@ BOOL CQPasteWnd::OpenSelection(bool bOnlyLoad_CF_TEXT, bool bPasteHTMLAs_CF_TEXT
 	
 	if(count == 1)
 		return OpenID(IDs[0], bOnlyLoad_CF_TEXT, bPasteHTMLAs_CF_TEXT);
+
+	if(GetKeyState(VK_SHIFT) & 0x8000)
+	{
+		bOnlyLoad_CF_TEXT = true;
+	}
 	
 	CProcessPaste paste;
 

+ 3 - 1
Resource.h

@@ -211,7 +211,9 @@
 #define IDC_WIN_CUT_1                   2087
 #define IDC_BUFFER_GROUP_1              2088
 #define IDC_COPY_2                      2089
+#define IDC_EDIT_CLIP_SEPARATOR         2089
 #define IDC_WIN_COPY_2                  2090
+#define IDC_STATIC_CLIP_SEPARATOR       2090
 #define IDC_PASTE_2                     2091
 #define IDC_WIN_PASTE_2                 2092
 #define IDC_STATIC_COPY_2               2093
@@ -329,7 +331,7 @@
 #define _APS_3D_CONTROLS                     1
 #define _APS_NEXT_RESOURCE_VALUE        167
 #define _APS_NEXT_COMMAND_VALUE         32871
-#define _APS_NEXT_CONTROL_VALUE         2089
+#define _APS_NEXT_CONTROL_VALUE         2091
 #define _APS_NEXT_SYMED_VALUE           101
 #endif
 #endif

+ 9 - 0
TextConvert.cpp

@@ -51,6 +51,15 @@ CStringA CTextConvert::ConvertToChar(const CString &src)
 #endif
 }
 
+CStringW CTextConvert::ConvertToUnicode(const CString &src)
+{
+#ifdef _UNICODE
+	return src;
+#else
+	return MultiByteToUnicodeString(src);
+#endif
+}
+
 bool CTextConvert::ConvertFromUTF8(const CStringA &src, CString &dest)
 {
 #ifdef _UNICODE	

+ 1 - 0
TextConvert.h

@@ -14,6 +14,7 @@ public:
 	static CStringW MultiByteToUnicodeString(const CStringA &srcString);
 
 	static CStringA ConvertToChar(const CString &src);
+	static CStringW ConvertToUnicode(const CString &src);
 
 protected:
 };

BIN
UEncryptDecryptD.lib