00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "CClipboard.h"
00016 #include "COSXClipboard.h"
00017 #include "COSXClipboardUTF16Converter.h"
00018 #include "COSXClipboardTextConverter.h"
00019 #include "CLog.h"
00020 #include "XArch.h"
00021
00022
00023
00024
00025
00026 COSXClipboard::COSXClipboard() :
00027 m_time(0),
00028 m_pboard(NULL)
00029 {
00030 m_converters.push_back(new COSXClipboardUTF16Converter);
00031 m_converters.push_back(new COSXClipboardTextConverter);
00032 PasteboardCreate( kPasteboardClipboard, &m_pboard);
00033 PasteboardSynchronize(m_pboard);
00034 }
00035
00036 COSXClipboard::~COSXClipboard()
00037 {
00038 clearConverters();
00039 }
00040
00041 bool
00042 COSXClipboard::empty()
00043 {
00044 LOG((CLOG_DEBUG "empty clipboard"));
00045 assert(m_pboard != NULL);
00046
00047 OSStatus err = PasteboardClear(m_pboard);
00048 if (err != noErr) {
00049 LOG((CLOG_DEBUG "failed to grab clipboard"));
00050 return false;
00051 }
00052
00053
00054 return true;
00055 }
00056
00057 bool
00058 COSXClipboard::synchronize()
00059 {
00060 PasteboardSyncFlags flags = PasteboardSynchronize(m_pboard);
00061 LOG((CLOG_DEBUG "flags: %x", flags));
00062
00063 if (flags & kPasteboardModified) {
00064 return true;
00065 }
00066 return false;
00067 }
00068
00069 void
00070 COSXClipboard::add(EFormat format, const CString & data)
00071 {
00072 LOG((CLOG_DEBUG "add %d bytes to clipboard format: %d", data.size(), format));
00073
00074 for (ConverterList::const_iterator index = m_converters.begin();
00075 index != m_converters.end(); ++index) {
00076
00077 IOSXClipboardConverter* converter = *index;
00078
00079
00080 if (converter->getFormat() == format) {
00081 CString osXData = converter->fromIClipboard(data);
00082 CFStringRef flavorType = converter->getOSXFormat();
00083 CFDataRef dataRef = CFDataCreate(kCFAllocatorDefault, (UInt8 *)osXData.data(), osXData.size());
00084
00085 PasteboardPutItemFlavor(
00086 m_pboard,
00087 (PasteboardItemID) 0,
00088 flavorType,
00089 dataRef,
00090 kPasteboardFlavorNoFlags);
00091 LOG((CLOG_DEBUG "added %d bytes to clipboard format: %d", data.size(), format));
00092 }
00093 }
00094 }
00095
00096 bool
00097 COSXClipboard::open(Time time) const
00098 {
00099 LOG((CLOG_DEBUG "opening clipboard"));
00100 m_time = time;
00101 return true;
00102 }
00103
00104 void
00105 COSXClipboard::close() const
00106 {
00107 LOG((CLOG_DEBUG "closing clipboard"));
00108
00109 }
00110
00111 IClipboard::Time
00112 COSXClipboard::getTime() const
00113 {
00114 return m_time;
00115 }
00116
00117 bool
00118 COSXClipboard::has(EFormat format) const
00119 {
00120 assert(m_pboard != NULL);
00121
00122 PasteboardItemID item;
00123 PasteboardGetItemIdentifier(m_pboard, (CFIndex) 1, &item);
00124
00125 for (ConverterList::const_iterator index = m_converters.begin();
00126 index != m_converters.end(); ++index) {
00127 IOSXClipboardConverter* converter = *index;
00128 if (converter->getFormat() == format) {
00129 PasteboardFlavorFlags flags;
00130 CFStringRef type = converter->getOSXFormat();
00131
00132 OSStatus res;
00133
00134 if ((res = PasteboardGetItemFlavorFlags(m_pboard, item, type, &flags)) == noErr) {
00135 return true;
00136 }
00137 }
00138 }
00139
00140 return false;
00141 }
00142
00143 CString
00144 COSXClipboard::get(EFormat format) const
00145 {
00146 CString result;
00147 CFStringRef type;
00148
00149 PasteboardItemID item;
00150 PasteboardGetItemIdentifier(m_pboard, (CFIndex) 1, &item);
00151
00152
00153
00154 IOSXClipboardConverter* converter = NULL;
00155 for (ConverterList::const_iterator index = m_converters.begin();
00156 index != m_converters.end(); ++index) {
00157 converter = *index;
00158
00159 PasteboardFlavorFlags flags;
00160 type = converter->getOSXFormat();
00161
00162 if (converter->getFormat() == format &&
00163 PasteboardGetItemFlavorFlags(m_pboard, item, type, &flags) == noErr) {
00164 break;
00165 }
00166 converter = NULL;
00167 }
00168
00169
00170 if (converter == NULL) {
00171 LOG((CLOG_DEBUG "Unable to find converter for data"));
00172 return result;
00173 }
00174
00175
00176 CFDataRef buffer = NULL;
00177 try {
00178 OSStatus err = PasteboardCopyItemFlavorData(m_pboard, item, type, &buffer);
00179
00180 if (err != noErr) {
00181 throw err;
00182 }
00183
00184 result = CString((char *) CFDataGetBytePtr(buffer), CFDataGetLength(buffer));
00185 }
00186 catch (OSStatus err) {
00187 LOG((CLOG_DEBUG "exception thrown in COSXClipboard::get MacError (%d)", err));
00188 }
00189 catch (...) {
00190 LOG((CLOG_DEBUG "unknown exception in COSXClipboard::get"));
00191 RETHROW_XTHREAD
00192 }
00193
00194 if (buffer != NULL)
00195 CFRelease(buffer);
00196
00197 return converter->toIClipboard(result);
00198 }
00199
00200 void
00201 COSXClipboard::clearConverters()
00202 {
00203 for (ConverterList::iterator index = m_converters.begin();
00204 index != m_converters.end(); ++index) {
00205 delete *index;
00206 }
00207 m_converters.clear();
00208 }