Logo Search packages:      
Sourcecode: basket version File versions  Download package

void ItemFactory::dropItem ( QMimeSource *  source,
Basket parent,
bool  fromDrop = false,
QDropEvent::Action  action = QDropEvent::Copy,
Item itemSource = 0 
)

Functions to create a new item from a drop or past event

Definition at line 296 of file itemfactory.cpp.

References Basket::changeItemPlace(), Global::debugWindow, ExtendedTextDrag::decode(), Basket::insertItem(), Basket::isLocked(), Item::parentBasket(), Basket::save(), and Item::type().

{
      Item *item = 0L;

      /* No data */
      if (source->format(0) == 0L) {
            // TODO: add a parameter to say if it's from a clipboard paste, a selection paste, or a drop
            //       To be able to say "The clipboard/selection/drop is empty".
//          KMessageBox::error(parent, i18n("There is no data to insert."), i18n("No Data"));
            return;
      }

      /* Debug */
      if (Global::debugWindow) {
            *Global::debugWindow << "<b>Drop :</b>";
            for(int i = 0; source->format(i); ++i)
                  if ( *(source->format(i)) )
                        *Global::debugWindow << "\t[" + QString::number(i) + "] " + QString(source->format(i));
            switch (action) { // The source want that we:
                  case QDropEvent::Copy:       *Global::debugWindow << ">> Drop action: Copy";       break;
                  case QDropEvent::Move:       *Global::debugWindow << ">> Drop action: Move";       break;
                  case QDropEvent::Link:       *Global::debugWindow << ">> Drop action: Link";       break;
                  case QDropEvent::Private:    *Global::debugWindow << ">> Drop action: Private";    break; // What is it? (Copy?)
                  case QDropEvent::UserAction: *Global::debugWindow << ">> Drop action: UserAction"; break; // Not currently
                  default:                     *Global::debugWindow << ">> Drop action: Unknown";           //  supported by QT!
            }
      }

      /* Copy or move an Item */
      if (ItemDrag::canDecode(source)) {
            if (Global::debugWindow)
                  *Global::debugWindow << ">> Drop an item";

            if ( action == QDropEvent::Move && itemSource != 0 &&     // We *move* an *item* : just reinsert it to well place
                 ! itemSource->parentBasket()->isLocked()    ) { //  Unless parent source is locked : then it's a copy
                                                                      //  TODO: Copy the file ??? Not for the moment !
                  if (itemSource->parentBasket() == parent) { // If drop in the same basket : keep the file and just move the item
                        if (Global::debugWindow)
                              *Global::debugWindow << ">> DROP : Just move the item to its new position";
                        parent->changeItemPlace(itemSource); //Just remove and reinsert
                        return;
                  } else { // Drop to another basket
                         // Another way to do the thing : move the file (eventually rename it) : will be deleted
                         //  for the original basket (so, old item deleted) and insert the new item.
                        if (Global::debugWindow)
                              *Global::debugWindow << ">> DROP : Move to another basket";
                        item = ItemDrag::decode(source, parent, /*move=*/true); // Filename will be kept
                        parent->insertItem(item);                               // (eventualy with a number added)
                        parent->save();
                        //if (!item->useFile()) // If useFile(), ItemDrag::decode() will move the file!
                        // FIXME: text/html/image items aren't managed the same way other useFile() items are :-/
                        if (item->type() != Item::Animation && item->type() != Item::Sound    &&
                            item->type() != Item::File      && item->type() != Item::Launcher &&
                            item->type() != Item::Unknow)
                              ((Item*)itemSource)->parentBasket()->delItem(itemSource, false); // Delete the item, & file whereas it's a mirror
                        return;
                  }
            } // Else, at this point it's a copy (link an item not supported : act as a copy !)

            // Do not try to copy the file, because if it is a cut and paste, item file could be deleted and then re-created
            item = ItemDrag::decode(source, parent, /*move=*/false);
            parent->insertItem(item);
            parent->save();
            return;
      }

      /* Else : Drop object to item */

      QPixmap pixmap;
      if ( QImageDrag::decode(source, pixmap) ) {
            createItemImage(pixmap, parent);
            return;
      }

      // KColorDrag::decode() is buggy and can trheat strings like "#include <foo.h>" as a black color
      // The correct "ideal" code:
      /*QColor color;
      if ( KColorDrag::decode(source, color) ) {
            createItemColor(color, parent);
            return;
      }*/
      // And then the hack (if provide color MIME type or a text that contains color), using createItem Color RegExp:
      QString hack;
      QRegExp exp("^#(?:[a-fA-F\\d]{3}){1,4}$");
      if (source->provides("application/x-color") ||
           (QTextDrag::decode(source, hack) && (exp.search(hack) != -1)) ) {
            QColor color;
            if ( KColorDrag::decode(source, color) )
                  if (createItemColor(color, parent))
                        return;
                  // Theorically it should be returned. If not, continue by dropping other things
      }

      KURL::List urls;
      if ( KURLDrag::decode(source, urls) ) {
            if (!fromDrop) // If it's a Paste, we should know if files should be copied (copy&paste) or moved (cut&paste)
                  if (source->provides("application/x-kde-cutselection")) {
                        QByteArray array = source->encodedData("application/x-kde-cutselection");
                        if ( !array.isEmpty() && QCString(array.data(), array.size() + 1).at(0) == '1' )
                              action = QDropEvent::Move;
                  }
            dropURLs(urls, parent, action, fromDrop);
            return;
      }

      // FIXME: use dropURLs() also from Mozilla?

      /*
       * Mozilla's stuff sometimes uses utf-16-le - little-endian UTF-16.
       *
       * This has the property that for the ASCII subset case (And indeed, the
       * ISO-8859-1 subset, I think), if you treat it as a C-style string,
       * it'll come out to one character long in most cases, since it looks
       * like:
       *
       * "<\0H\0T\0M\0L\0>\0"
       *
       * A strlen() call on that will give you 1, which simply isn't correct.
       * That might, I suppose, be the answer, or something close.
       *
       * Also, Mozilla's drag/drop code predates the use of MIME types in XDnD
       * - hence it'll throw about STRING and UTF8_STRING quite happily, hence
       * the odd named types.
       *
       * Thanks to Dave Cridland for having said me that.
       */
      if (source->provides("text/x-moz-url")) { // FOR MOZILLA
            // Get the array and create a QChar array of 1/2 of the size
            QByteArray mozilla = source->encodedData("text/x-moz-url");
            QMemArray<QChar> chars( mozilla.count() / 2 );
            // A small debug work to know the value of each bytes
            if (Global::debugWindow)
                  for (uint i = 0; i < mozilla.count(); i++)
                        *Global::debugWindow << QString("'") + QChar(mozilla[i]) + "' " + QString::number(int(mozilla[i]));
            // text/x-moz-url give the URL followed by the link title and separed by OxOA (10 decimal: new line?)
            uint size   = 0;
            QChar *name = 0L;
            // For each little endian mozilla chars, copy it to the array of QChars
            for (uint i = 0; i < mozilla.count(); i += 2) {
                  chars[i/2] = QChar(mozilla[i], mozilla[i+1]);
                  if (mozilla[i] == 0x0A) {
                        size = i/2;
                        name = &(chars[i/2+1]);
                  }
            }
            // Create a QString that take the address of the first QChar and a length
            if (name == 0L) { // We haven't found name (FIXME: Is it possible ?)
                  QString normalHtml(&(chars[0]), chars.size());
                  createItemLink(normalHtml, parent);
            } else {
                  QString normalHtml(  &(chars[0]), size               );
                  QString normalTitle( name,        chars.size()-size-1);
                  createItemLink(normalHtml, normalTitle, parent);
            }
            return;
      }

      if (source->provides("text/html")) {
            QString html;
            QCString subtype("html");
            // If the text/html comes from Mozilla or GNOME it can be UTF-16 encoded: we need ExtendedTextDrag to check that
            ExtendedTextDrag::decode(source, html, subtype);
            createItemHtml(html, parent);
            return;
      }

      QString text;
      // If the text/plain comes from GEdit or GNOME it can be empty: we need ExtendedTextDrag to check other MIME types
      if ( ExtendedTextDrag::decode(source, text) ) {
            createItem(text, parent);
            return;
      }

      /* Unsucceful drop */
      createItemUnknow(source, parent, "");
      QString message = i18n("<p>BasKet doesn't support the data you've dropped.<br>"
                             "It however created a generic item, allowing you to drag or copy "
                             "them to an application that understand them.</p>"
                             "If you want BasKet to support them, please contact developer or visit the "
                             "<a href=\"http://basket.kde.org/dropdb.php\">BasKet Drop Database</a>.</p>");
      KMessageBox::information(parent, message, i18n("Unsupported MIME Type(s)"),
                               "unsupportedDropInfo", KMessageBox::AllowLink);
      return;
}


Generated by  Doxygen 1.6.0   Back to index