# # # add_file "guitone/src/monotone/FileExporter.cpp" # content [8d796b49755d5498781271b4a3e3145e3b010c36] # # add_file "guitone/src/monotone/FileExporter.h" # content [0db9abfd0c7c716ee600c8c7024e198f1b7a7034] # # patch "guitone/guitone.pro" # from [44d8f3da6f663e6629152c60eb49744b28527c34] # to [9498bf3718baefb221af5a0a302a9f1accf4cfcc] # # patch "guitone/src/view/dialogs/RevisionManifest.cpp" # from [6618e4735bfb185c6b262ed646b0b0d83fa65e3c] # to [94c245e7f47f66b41818e43ef3d4a081cd1cab4c] # # patch "guitone/src/view/dialogs/RevisionManifest.h" # from [b80762f7d4c1d059349eefdfcb2e69fa8c175842] # to [54a0eed45ca8feea0df87f5e46f9821e493a876d] # ============================================================ --- guitone/src/monotone/FileExporter.cpp 8d796b49755d5498781271b4a3e3145e3b010c36 +++ guitone/src/monotone/FileExporter.cpp 8d796b49755d5498781271b4a3e3145e3b010c36 @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2007 by Thomas Keller * + * address@hidden * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "FileExporter.h" +#include "Guitone.h" + +#include + +FileExporter::FileExporter(QObject * parent, QString rev, FileEntryList en) + : QObject(parent), revision(rev), entries(en) +{} + +FileExporter::~FileExporter() +{ +} + +bool FileExporter::run(QString exportDir) +{ + rootDir = QDir(exportDir); + Q_ASSERT(rootDir.exists()); + + QProgressDialog progress( + tr("Exporting files..."), tr("Abort"), 0, entries.size() + ); + progress.setWindowModality(Qt::WindowModal); + + bool success = true; + bool cleanup = false; + for (int i=0, j=entries.size(); i < j; i++) + { + if (!exportFile(entries.at(i))) + { + success = false; + cleanup = true; + break; + } + + APP->processEvents(); + if (progress.wasCanceled()) + { + cleanup = true; + break; + } + progress.setValue(i + 1); + } + + if (cleanup) + { + qDebug("FileExporter::run: TODO: clean up written files"); + } + return success; +} + +bool FileExporter::exportFile(FileEntry entry) +{ + if (entry.second) + { + if (!rootDir.mkpath(entry.first)) + { + qCritical("FileExporter::exportFile: cannot create directory"); + return false; + } + return true; + } + + Monotone * mtn = MTN(this); + + int commandNumber; + if (!mtn->executeCommand( + QStringList() << "get_file_of" << entry.first, + QStringList() << "r" << revision, commandNumber) || + mtn->getReturnCode(commandNumber) > 0) + { + qCritical("FileExporter::exportFile: cannot execute get_file_of"); + return false; + } + + QFile file(rootDir.filePath(entry.first)); + if (file.exists()) file.remove(); + + if (!file.open(QIODevice::WriteOnly)) + { + qCritical("FileExporter::exportFile: can't open file for writing"); + return false; + } + + file.write(mtn->getRawData(commandNumber)); + file.close(); + + return true; +} + ============================================================ --- guitone/src/monotone/FileExporter.h 0db9abfd0c7c716ee600c8c7024e198f1b7a7034 +++ guitone/src/monotone/FileExporter.h 0db9abfd0c7c716ee600c8c7024e198f1b7a7034 @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2007 by Thomas Keller * + * address@hidden * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef FILE_EXPORTER_H +#define FILE_EXPORTER_H + +#include + +#include "MonotoneDelegate.h" +#include "RevisionManifest.h" + +class FileExporter : public QObject +{ + Q_OBJECT +public: + FileExporter(QObject *, QString, FileEntryList); + ~FileExporter(); + bool run(QString); + +private: + bool exportFile(FileEntry); + + QDir rootDir; + QString revision; + FileEntryList entries; +}; + +#endif ============================================================ --- guitone/guitone.pro 44d8f3da6f663e6629152c60eb49744b28527c34 +++ guitone/guitone.pro 9498bf3718baefb221af5a0a302a9f1accf4cfcc @@ -34,6 +34,7 @@ HEADERS += src/view/MainWindow.h \ src/view/dialogs/RevisionManifest.h \ src/monotone/Monotone.h \ src/monotone/MonotoneDelegate.h \ + src/monotone/FileExporter.h \ src/model/Inventory.h \ src/model/InventoryItem.h \ src/model/InventoryProxyModel.h \ @@ -84,6 +85,7 @@ SOURCES += src/view/MainWindow.cpp \ src/view/dialogs/RevisionManifest.cpp \ src/monotone/Monotone.cpp \ src/monotone/MonotoneDelegate.cpp \ + src/monotone/FileExporter.cpp \ src/model/Inventory.cpp \ src/model/InventoryItem.cpp \ src/model/InventoryProxyModel.cpp \ ============================================================ --- guitone/src/view/dialogs/RevisionManifest.cpp 6618e4735bfb185c6b262ed646b0b0d83fa65e3c +++ guitone/src/view/dialogs/RevisionManifest.cpp 94c245e7f47f66b41818e43ef3d4a081cd1cab4c @@ -21,11 +21,13 @@ #include "RevisionManifest.h" #include "Guitone.h" #include "Platform.h" +#include "FileExporter.h" #include #include #include #include +#include RevisionManifest::RevisionManifest(QWidget* parent, QString rev) : Dialog(parent), revision(rev) @@ -70,29 +72,6 @@ RevisionManifest::~RevisionManifest() delete manifestModel; } -void RevisionManifest::saveAllFiles() -{ - qDebug("TODO: query all file names"); -} - -void RevisionManifest::saveSelectedFiles() -{ - QModelIndexList indexes = manifestView->selectionModel()->selectedIndexes(); - if (indexes.size() == 0) - { - qDebug("RevisionManifest::saveSelectedFiles: no files selected"); - return; - } - - ManifestEntry * entry; - for (int i=0, j=indexes.size(); i(indexes.at(i).internalPointer()); - qDebug(qPrintable(entry->path)); - } -} - void RevisionManifest::openFile(const QModelIndex & index) { if (!index.isValid()) return; @@ -141,9 +120,7 @@ void RevisionManifest::openFile(const QM qCritical("RevisionManifest::openFile: can't open temporary file for writing"); return; } - // FIXME: we must write the original QByteArray here instead of messing - // around with strings, but for this the Monotone wrapper has - once again - - // to be rewritten first... + file.write(mtn->getRawData(commandNumber)); file.close(); @@ -198,11 +175,113 @@ void RevisionManifest::contextMenuReques } else if (act == actSaveSelected) { - // TODO: some method call + saveSelectedFiles(); } else if (act == actSaveAll) { - // TODO: some method call + saveAllFiles(); } } + +void RevisionManifest::saveAllFiles() +{ + QModelIndexList list; + int row = 0; + while (true) + { + QModelIndex index(manifestModel->index(row++, 0, QModelIndex())); + if (!index.isValid()) break; + list.append(index); + } + FileEntryList entries = extractSelectedEntries(list); + + QString exportDir = + QFileDialog::getExistingDirectory(0, tr("Select your export directory...")); + if (!exportDir.isEmpty()) + { + FileExporter exporter(this, revision, entries); + if (!exporter.run(exportDir)) + { + QMessageBox::critical( + this, + tr("Error"), + tr("The file export was aborted - please look in the log for more details.") + ); + return; + } + } +} + +void RevisionManifest::saveSelectedFiles() +{ + QModelIndexList indexes = manifestView->selectionModel()->selectedIndexes(); + FileEntryList entries = extractSelectedEntries(indexes); + + if (entries.size() == 0) + { + QMessageBox::information( + this, + tr("Information"), + tr("Please select one or more files you want to save locally.") + ); + return; + } + + QString exportDir = + QFileDialog::getExistingDirectory(0, tr("Select your export directory...")); + if (!exportDir.isEmpty()) + { + FileExporter exporter(this, revision, entries); + if (!exporter.run(exportDir)) + { + QMessageBox::critical( + this, + tr("Error"), + tr("The file export was aborted - please look in the log for more details.") + ); + return; + } + } +} + +FileEntryList RevisionManifest::extractSelectedEntries(const QModelIndexList & indexList) +{ + FileEntryList entries; + for (int i=0, j=indexList.size(); i(indexList.at(i).internalPointer()); + + if (entry->is_directory) + { + entries.append(FileEntry(entry->path, true)); + entries += addEntriesRecursive(entry); + } + else + { + entries.append(FileEntry(entry->path, false)); + } + } + + return entries; +} + +FileEntryList RevisionManifest::addEntriesRecursive(ManifestEntry * entry) +{ + FileEntryList entries; + for (int i=0, j=entry->childCount(); ichildren.at(i)->is_directory) + { + entries.append(FileEntry(entry->children.at(i)->path, true)); + entries += addEntriesRecursive(entry->children.at(i)); + } + else + { + entries.append(FileEntry(entry->children.at(i)->path, false)); + } + } + return entries; +} + ============================================================ --- guitone/src/view/dialogs/RevisionManifest.h b80762f7d4c1d059349eefdfcb2e69fa8c175842 +++ guitone/src/view/dialogs/RevisionManifest.h 54a0eed45ca8feea0df87f5e46f9821e493a876d @@ -25,6 +25,12 @@ #include "ui_manifest.h" #include "Manifest.h" +#include + +// FIXME: this should be removed into some vocab.h file +typedef QPair FileEntry; +typedef QList FileEntryList; + class RevisionManifest : public Dialog, private Ui::ManifestDialog { Q_OBJECT @@ -34,6 +40,9 @@ private: ~RevisionManifest(); private: + FileEntryList extractSelectedEntries(const QModelIndexList &); + FileEntryList addEntriesRecursive(ManifestEntry *); + Manifest * manifestModel; QString revision;