[gelöst] Drag & Drop für QListView anpassen

Alles rund um die Programmierung mit Qt
Antworten
hakaishi
Beiträge: 62
Registriert: 8. Dezember 2009 18:25

[gelöst] Drag & Drop für QListView anpassen

Beitrag von hakaishi »

Hallo zusammen!

Für ein Notizprogramm habe muss ich das Drag 'n Drop etwas anpassen. Ich möchte Dateien von einer QViewList in die andere verschieben (Model ist QFileSystemModel).
Jetzt habe ich zwei Probleme. Das eine ist, dass es nur möglich sein soll Dateien von der einen QViewList in einen beliebigen Ordner der anderen QViewList zu verschieben. Man sollte in den leeren weißen Bereich also keine Objekte droppen können. Das andere Problem ist, dass es eventuell bereits eine Datei mit einem bestimmten Namen gibt. In diesem Fall sollen alle Dateien bis auf die bereits vorhandenen Titel verschoben werden und dann soll sich ein Dialog zum umbenennen der Datei(en) öffnen.
Hierzu habe ich die Klasse QListView neu erstellt und den dropEvent reimplementiert. Damit kann man die Daten erst mal nicht mehr verschieben. Die Zeile "QAbstractItemView::dropEvent(e);" ermöglicht dies wieder.
Mit "qDebug()<<event->mimeData()->formats(); habe ich herausgefunden, dass das Datenformat "text/uri-list" ist. Mit qDebug()<<event->mimeData()->data("text/uri-list");" bekomme ich beim Droppen die URLs der Dateien ausgegeben.
Hat jemand vielleicht eine Idee, wie ich jetzt herausbekommen kann, welche Dateien nicht verschoben werden können bzw. wie ich an eine URL-Liste der in dem Zielordner befindlichen Dateien komme?
Gibt es vielleicht auch einen viel einfacheren Weg dies alles zu erreichen?
Vielen Dank im Voraus :D

Viele Grüße, Hakaishi
Zuletzt geändert von hakaishi am 28. September 2012 20:12, insgesamt 1-mal geändert.
hakaishi
Beiträge: 62
Registriert: 8. Dezember 2009 18:25

Re: Drag & Drop für QListView anpassen

Beitrag von hakaishi »

Fast gelöst. Wir benutzen das QFileSystemModel und überschreiben dropMimeData.

Code: Alles auswählen

    bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
    {
        // is drop into "emtpy space"
        bool isRootFolder = this->index(QSettings().value("root_path").toString()) == parent;

        // row == -1 && column == -1 dropped directly on item or on "empty space"
        if((row == -1 && column == -1)  && !isRootFolder)
//usw.
Nur beim überprüfen des Dateinamens klappt es noch nicht ganz.
--> http://qtforum.de/forum/viewtopic.php?f=1&t=15202
hakaishi
Beiträge: 62
Registriert: 8. Dezember 2009 18:25

Re: Drag & Drop für QListView anpassen

Beitrag von hakaishi »

Hier ist meine Lösung:

Code: Alles auswählen

    bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent)
    {
        // is drop into "emtpy space"
        bool isRootFolder = this->index(QSettings().value("root_path").toString()) == parent;

        // row == -1 && column == -1 dropped directly on item or on "empty space"
        if((row == -1 && column == -1)  && !isRootFolder)
        {
            if(!data->hasFormat("text/uri-list"))
              return false;

            QStringList files;
            foreach(QUrl url, data->urls())
            files << url.toLocalFile();

            if(this->index(QFileInfo(files.first()).absolutePath()) == parent)
              return false; //dropped in the same folder they are in

            QDir dirs(QSettings().value("root_path").toString());
            QList<QFileInfo> dirList = dirs.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot, QDir::Name);

            //Search for the right dir
            QString parentPath;
            foreach(QFileInfo file, dirList)
                   if(this->index(QFileInfo(file).absoluteFilePath()) == parent)
                     parentPath = QFileInfo(file).absoluteFilePath();

            //remove all file titles that don't exist in the target folder, because they will be sucessfully dropped
            foreach(QString file, files)
            {
                QString path = parentPath + "/" + QFileInfo(file).fileName();
                if(!QFileInfo(path).exists())
                   files.removeOne(file);
            }

            bool dropped = QFileSystemModel::dropMimeData(data,action,row,column,parent);
            if(!dropped)
            {
                QString existingFiles;
                foreach(QString file, files)
                       existingFiles += file + "\n";
                if(!existingFiles.isEmpty())
                  QMessageBox::warning(0,tr("Couldn't drop some file(s)"), tr("File(s) of the same name(s) are already existing in this folder:\n%1").arg(existingFiles));

                return false;
            }
            else
               return true; //files sucessfully dropped
        }
        return false; // dropped between items
    }
Wenn man etwas vereinfachen kann oder verbessern sollte, bin ich gerne für Vorschläge offen :mrgreen:

Viele Grüße, Hakaishi
Antworten