krita

kis_clipboard.cc

00001 /*
00002  *  Copyright (c) 2004 Boudewijn Rempt <boud@valdyas.org>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 #include <qapplication.h>
00019 #include <qclipboard.h>
00020 #include <qobject.h>
00021 #include <qimage.h>
00022 #include <qmessagebox.h>
00023 #include <qbuffer.h>
00024 #include <kmultipledrag.h>
00025 #include <klocale.h>
00026 
00027 #include "kdebug.h"
00028 
00029 #include "KoStore.h"
00030 #include "KoStoreDrag.h"
00031 
00032 #include "kis_types.h"
00033 #include "kis_paint_device.h"
00034 #include "kis_config.h"
00035 #include "kis_colorspace_factory_registry.h"
00036 #include "kis_factory.h"
00037 #include <kis_meta_registry.h>
00038 #include "kis_clipboard.h"
00039 
00040 KisClipboard *KisClipboard::m_singleton = 0;
00041 
00042 KisClipboard::KisClipboard()
00043 {
00044     Q_ASSERT(KisClipboard::m_singleton == 0);
00045     KisClipboard::m_singleton = this;
00046 
00047     m_pushedClipboard = false;
00048     m_hasClip = false;
00049     m_clip = 0;
00050 
00051     // Check that we don't already have a clip ready
00052     clipboardDataChanged();
00053 
00054     // Make sure we are notified when clipboard changes
00055     connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
00056          this, SLOT( clipboardDataChanged() ) );
00057 }
00058 
00059 KisClipboard::~KisClipboard()
00060 {
00061 }
00062 
00063 KisClipboard* KisClipboard::instance()
00064 {
00065     if(KisClipboard::m_singleton == 0)
00066     {
00067         KisClipboard::m_singleton = new KisClipboard();
00068         Q_CHECK_PTR(KisClipboard::m_singleton);
00069     }
00070     return KisClipboard::m_singleton;
00071 }
00072 
00073 void KisClipboard::setClip(KisPaintDeviceSP selection)
00074 {
00075     m_clip = selection;
00076 
00077     if (!selection)
00078         return;
00079 
00080     m_hasClip = true;
00081 
00082     // We'll create a store (ZIP format) in memory
00083     QBuffer buffer;
00084     QCString mimeType("application/x-krita-selection");
00085     KoStore* store = KoStore::createStore( &buffer, KoStore::Write, mimeType );
00086     Q_ASSERT( store );
00087     Q_ASSERT( !store->bad() );
00088 
00089     // Layer data
00090     if (store->open("layerdata")) {
00091         if (!selection->write(store)) {
00092             selection->disconnect();
00093             store->close();
00094             return;
00095         }
00096         store->close();
00097     }
00098 
00099     // ColorSpace id of layer data
00100     if (store->open("colorspace")) {
00101         QString csName = selection->colorSpace()->id().id();
00102         store->write(csName.ascii(), strlen(csName.ascii()));
00103         store->close();
00104     }
00105 
00106     if (selection->colorSpace()->getProfile()) {
00107         KisAnnotationSP annotation = selection->colorSpace()->getProfile()->annotation();
00108          if (annotation) {
00109             // save layer profile
00110              if (store->open("profile.icc")) {
00111                 store->write(annotation->annotation());
00112                 store->close();
00113             }
00114         }
00115     }
00116 
00117     delete store;
00118 
00119     // We also create a QImage so we can interchange with other applications
00120     QImage qimg;
00121     KisConfig cfg;
00122     QString monitorProfileName = cfg.monitorProfile();
00123     KisProfile *  monitorProfile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName);
00124     qimg = selection->convertToQImage(monitorProfile);
00125 
00126     QImageDrag *qimgDrag = new QImageDrag(qimg);
00127     KMultipleDrag *multiDrag = new KMultipleDrag();
00128     if ( !qimg.isNull() )
00129         multiDrag->addDragObject( qimgDrag );
00130     KoStoreDrag* storeDrag = new KoStoreDrag( mimeType, 0 );
00131     storeDrag->setEncodedData( buffer.buffer() );
00132     multiDrag->addDragObject( storeDrag );
00133 
00134 
00135     QClipboard *cb = QApplication::clipboard();
00136     cb->setData(multiDrag);
00137     m_pushedClipboard = true;
00138 }
00139 
00140 KisPaintDeviceSP KisClipboard::clip()
00141 {
00142     QClipboard *cb = QApplication::clipboard();
00143     QCString mimeType("application/x-krita-selection");
00144     QMimeSource *cbData = cb->data();
00145 
00146     if(cbData && cbData->provides(mimeType))
00147     {
00148         QBuffer buffer(cbData->encodedData(mimeType));
00149         KoStore* store = KoStore::createStore( &buffer, KoStore::Read, mimeType );
00150         KisProfile *profile=0;
00151 
00152         if (store->hasFile("profile.icc")) {
00153             QByteArray data;
00154             store->open("profile.icc");
00155             data = store->read(store->size());
00156             store->close();
00157            profile = new KisProfile(data);
00158         }
00159 
00160         QString csName;
00161         // ColorSpace id of layer data
00162         if (store->hasFile("colorspace")) {
00163             store->open("colorspace");
00164             csName = QString(store->read(store->size()));
00165             store->close();
00166         }
00167 
00168         KisColorSpace *cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName, ""), profile);
00169 
00170         m_clip = new KisPaintDevice(cs, "clip");
00171 
00172         if (store->hasFile("layerdata")) {
00173             store->open("layerdata");
00174             m_clip->read(store);
00175             store->close();
00176         }
00177         delete store;
00178     }
00179     else
00180     {
00181         QImage qimg = cb->image();
00182 
00183         if (qimg.isNull())
00184             return 0;
00185 
00186         KisConfig cfg;
00187 
00188         Q_UINT32 behaviour = cfg.pasteBehaviour();
00189 
00190         if(behaviour==2)
00191         {
00192             // Ask user each time
00193             behaviour = QMessageBox::question(0,i18n("Pasting data from simple source"),i18n("The image data you are trying to paste has no colour profile information.\n\nOn the web and in simple applications the data are supposed to be in sRGB color format.\nImporting as web will show it as it is supposed to look.\nMost monitors are not perfect though so if you made the image yourself\nyou might want to import it as it looked on you monitor.\n\nHow do you want to interpret these data?"),i18n("As &Web"),i18n("As on &Monitor"));
00194         }
00195 
00196         KisColorSpace * cs;
00197         QString profileName("");
00198         if(behaviour==1)
00199             profileName = cfg.monitorProfile();
00200 
00201         cs = KisMetaRegistry::instance()->csRegistry() ->getColorSpace(KisID("RGBA",""), profileName);
00202         m_clip = new KisPaintDevice(cs, "from paste");
00203         Q_CHECK_PTR(m_clip);
00204         m_clip->convertFromQImage(qimg, profileName);
00205     }
00206 
00207     return m_clip;
00208 }
00209 
00210 void KisClipboard::clipboardDataChanged()
00211 {
00212     if (!m_pushedClipboard) {
00213         m_hasClip = false;
00214         QClipboard *cb = QApplication::clipboard();
00215         QImage qimg = cb->image();
00216         QMimeSource *cbData = cb->data();
00217         QCString mimeType("application/x-krita-selection");
00218 
00219         if(cbData && cbData->provides(mimeType))
00220             m_hasClip = true;
00221 
00222         if (!qimg.isNull())
00223             m_hasClip = true;
00224     }
00225 
00226     m_pushedClipboard = false;
00227 }
00228 
00229 
00230 bool KisClipboard::hasClip()
00231 {
00232     return m_hasClip;
00233 }
00234 
00235 QSize KisClipboard::clipSize()
00236 {
00237 
00238     QClipboard *cb = QApplication::clipboard();
00239     QCString mimeType("application/x-krita-selection");
00240     QMimeSource *cbData = cb->data();
00241 
00242     KisPaintDeviceSP clip;
00243     
00244     if(cbData && cbData->provides(mimeType)) {
00245         
00246         QBuffer buffer(cbData->encodedData(mimeType));
00247         KoStore* store = KoStore::createStore( &buffer, KoStore::Read, mimeType );
00248         KisProfile *profile=0;
00249 
00250         if (store->hasFile("profile.icc")) {
00251             QByteArray data;
00252             store->open("profile.icc");
00253             data = store->read(store->size());
00254             store->close();
00255             profile = new KisProfile(data);
00256         }
00257 
00258         QString csName;
00259         // ColorSpace id of layer data
00260         if (store->hasFile("colorspace")) {
00261             store->open("colorspace");
00262             csName = QString(store->read(store->size()));
00263             store->close();
00264         }
00265 
00266         KisColorSpace *cs = KisMetaRegistry::instance()->csRegistry()->getColorSpace(KisID(csName, ""), profile);
00267 
00268         clip = new KisPaintDevice(cs, "clip");
00269 
00270         if (store->hasFile("layerdata")) {
00271             store->open("layerdata");
00272             clip->read(store);
00273             store->close();
00274         }
00275         delete store;
00276 
00277         return clip->exactBounds().size();
00278     }
00279     else {
00280         QImage qimg = cb->image();
00281         return qimg.size();
00282     }
00283 ;
00284 
00285 }
00286 
00287 #include "kis_clipboard.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys