Added new Patch from Phenom (AddRSCollectionEditor_v0.6_7386)

Some Improvements : added submenu, Edit and view mode.


git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@7388 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
defnax 2014-05-29 14:49:45 +00:00
parent 5e1099f47f
commit e65f73a44d
23 changed files with 2693 additions and 811 deletions

File diff suppressed because it is too large Load diff

View file

@ -23,31 +23,67 @@
#include "ui_RsCollectionDialog.h"
#include "RsCollectionFile.h"
#include <QFileSystemModel>
#include <QSortFilterProxyModel>
class QCheckBox ;
class RsCollectionDialog: public QDialog, public Ui::RsCollectionDialog
class RsCollectionDialog: public QDialog
{
Q_OBJECT
public:
RsCollectionDialog(const QString& filename,const std::vector<RsCollectionFile::DLinfo>& dlinfos) ;
private slots:
void download() ;
void selectAll() ;
void deselectAll() ;
void cancel() ;
void updateSizes() ;
void itemChanged(QTreeWidgetItem *item, int column);
RsCollectionDialog(const QString& filename
, const std::vector<ColFileInfo> &colFileInfos
, const bool& creation
, const bool& readOnly = false) ;
virtual ~RsCollectionDialog();
protected:
bool eventFilter(QObject *obj, QEvent *ev);
private:
void selectDeselectAll(bool select);
void connectUpdate(bool doConnect);
private slots:
void directoryLoaded(QString dirLoaded);
void updateSizes() ;
void changeFileName() ;
void add() ;
void addRecursive() ;
void remove() ;
void processItem(QMap<QString, QString> &dirToAdd
, int &index
, ColFileInfo &parent
) ;
void makeDir() ;
void fileHashingFinished(QList<HashedFile> hashedFiles) ;
void itemChanged(QTreeWidgetItem* item,int col) ;
void cancel() ;
void download() ;
void save() ;
const std::vector<RsCollectionFile::DLinfo>& _dlinfos ;
QString _filename ;
signals:
void saveColl(std::vector<ColFileInfo>, QString);
private:
void processSettings(bool bLoad) ;
QTreeWidgetItem* getRootItem();
bool updateList();
bool addChild(QTreeWidgetItem *parent, const std::vector<ColFileInfo> &child);
void addRecursive(bool recursive) ;
bool addAllChild(QFileInfo &fileInfoParent
, QMap<QString, QString > &dirToAdd
, QStringList &fileToHash
, int &count);
void saveChild(QTreeWidgetItem *parentItem, ColFileInfo *parentInfo = NULL);
Ui::RsCollectionDialog ui;
QString _fileName ;
const bool _creationMode ;
const bool _readOnly;
std::vector<ColFileInfo> _newColFileInfos ;
QFileSystemModel *_dirModel;
QSortFilterProxyModel *_tree_proxyModel;
QItemSelectionModel *_selectionProxy;
bool _dirLoaded;
QHash<QString,QString> _listOfFilesAddedInDir;
};

View file

@ -3,73 +3,138 @@
<class>RsCollectionDialog</class>
<widget class="QDialog" name="RsCollectionDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>434</width>
<height>310</height>
</rect>
</property>
<property name="windowTitle">
<rect>
<x>0</x>
<y>0</y>
<width>693</width>
<height>331</height>
</rect>
</property>
<property name="windowTitle">
<string>Collection</string>
</property>
<property name="windowIcon">
<iconset resource="../images.qrc">
<normaloff>:/images/mimetypes/rscollection-16.png</normaloff>:/images/mimetypes/rscollection-16.png</iconset>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>File name :</string>
</property>
<property name="sizeGripEnabled">
<bool>true</bool>
</property>
<layout class="QVBoxLayout">
<item>
<widget class="QSplitter" name="_mainSplitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QFrame" name="_FrameEdit">
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<layout class="QVBoxLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="_frameInfo">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="lineWidth">
<number>0</number>
</property>
<layout class="QHBoxLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<layout class="QHBoxLayout">
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<layout class="QVBoxLayout">
<item>
<widget class="QLabel" name="label_filename">
<property name="text">
<string>File name :</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Total size :</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_totalsize">
<property name="text">
<string>Total size :</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Selected files:</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</widget>
</item>
<item>
<widget class="QLabel" name="label_selectedFiles">
<property name="text">
<string>Selected files :</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="_filename_TL">
<property name="text">
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="_filename_TL">
<property name="text">
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="_totalSize_TL">
<property name="text">
<string notr="true">TextLabel</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="_changeFile">
<property name="maximumSize">
<size>
<width>21</width>
<height>14</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Change the file were collection will be saved.&lt;/p&gt;&lt;p&gt;If you select an existing file, you could merge it.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="_totalSize_TL">
<property name="text">
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
@ -80,88 +145,252 @@
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</layout>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QTreeWidget" name="_fileEntriesTW">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="_frameLists">
<property name="lineWidth">
<number>0</number>
</property>
<layout class="QVBoxLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QSplitter" name="_listSplitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QFrame" name="_treeViewFrame">
<layout class="QHBoxLayout">
<property name="margin">
<number>0</number>
</property>
<item>
<widget class="QTreeView" name="_systemFileTW">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout">
<item>
<widget class="QPushButton" name="_add_PB">
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>17</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Add selected item to collection one by one.&lt;/p&gt;&lt;p&gt;Select parent dir to add this too.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic; vertical-align:sub;&quot;&gt;&amp;lt;Enter&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string notr="true">&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_addRecur_PB">
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Add selected item to collection.&lt;/p&gt;&lt;p&gt;If a directory is selected, all of his children will be added.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; text-decoration: underline; vertical-align:sub;&quot;&gt;&amp;lt;Shift + Enter&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>&gt;&gt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_remove_PB">
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Remove selected item of collection.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic; vertical-align:sub;&quot;&gt;&amp;lt;Del&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string notr="true">&lt;</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_makeDir_PB">
<property name="minimumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>21</width>
<height>21</height>
</size>
</property>
<property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Make a new directory in the collection.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot; font-style:italic; vertical-align:sub;&quot;&gt;&amp;lt;+&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="text">
<string>+</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QTreeWidget" name="_fileEntriesTW">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::ExtendedSelection</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="_selectAll_PB">
<property name="text">
<string>Select all</string>
</spacer>
</item>
<item>
<widget class="QPushButton" name="_cancel_PB">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_deselectAll_PB">
<property name="text">
<string>Deselect all</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_cancel_PB">
<property name="text">
<string>Cancel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_download_PB">
<property name="text">
<string>Download!</string>
</widget>
</item>
<item>
<widget class="QPushButton" name="_save_PB">
<property name="text">
<string>Save</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="_download_PB">
<property name="text">
<string>Download!</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../images.qrc"/>
</resources>
</item>
</layout>
</widget>
<widget class="HashBox" name="_hashBox">
<property name="widgetResizable">
<bool>true</bool>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>HashBox</class>
<extends>QScrollArea</extends>
<header location="global">gui/common/HashBox.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources>
<include location="../images.qrc"/>
</resources>
<connections/>
</ui>

View file

@ -28,7 +28,6 @@
#include "RsCollectionDialog.h"
#include "util/misc.h"
#include <QFile>
#include <QDir>
#include <QObject>
#include <QTextStream>
@ -39,8 +38,22 @@
const QString RsCollectionFile::ExtensionString = QString("rscollection") ;
RsCollectionFile::RsCollectionFile()
: _xml_doc("RsCollection")
RsCollectionFile::RsCollectionFile(QObject *parent)
: QObject(parent), _xml_doc("RsCollection")
{
}
RsCollectionFile::RsCollectionFile(const std::vector<DirDetails>& file_infos, QObject *parent)
: QObject(parent), _xml_doc("RsCollection")
{
QDomElement root = _xml_doc.createElement("RsCollection");
_xml_doc.appendChild(root);
for(uint32_t i = 0;i<file_infos.size();++i)
recursAddElements(_xml_doc,file_infos[i],root) ;
}
RsCollectionFile::~RsCollectionFile()
{
}
@ -50,11 +63,11 @@ void RsCollectionFile::downloadFiles() const
// of the outermost element.
QDomElement docElem = _xml_doc.documentElement();
std::vector<DLinfo> dlinfos ;
std::vector<ColFileInfo> colFileInfos ;
recursCollectDLinfos(docElem,dlinfos,QString(),false) ;
recursCollectColFileInfos(docElem,colFileInfos,QString(),false) ;
RsCollectionDialog(_filename, dlinfos).exec() ;
RsCollectionDialog(_fileName, colFileInfos, false).exec() ;
}
static QString purifyFileName(const QString& input,bool& bad)
@ -74,7 +87,7 @@ static QString purifyFileName(const QString& input,bool& bad)
return output ;
}
void RsCollectionFile::recursCollectDLinfos(const QDomElement& e,std::vector<DLinfo>& dlinfos,const QString& current_path, bool bad_chars_in_parent) const
void RsCollectionFile::recursCollectColFileInfos(const QDomElement& e,std::vector<ColFileInfo>& colFileInfos,const QString& current_path, bool bad_chars_in_parent) const
{
QDomNode n = e.firstChild() ;
@ -88,22 +101,37 @@ void RsCollectionFile::recursCollectDLinfos(const QDomElement& e,std::vector<DLi
if(ee.tagName() == QString("File"))
{
DLinfo i ;
i.hash = ee.attribute(QString("sha1")) ;
ColFileInfo newChild ;
newChild.hash = ee.attribute(QString("sha1")) ;
bool bad_chars_detected = false ;
i.name = purifyFileName(ee.attribute(QString("name")), bad_chars_detected) ;
i.filename_has_wrong_characters = bad_chars_detected || bad_chars_in_parent ;
i.size = ee.attribute(QString("size")).toULongLong() ;
i.path = current_path ;
newChild.name = purifyFileName(ee.attribute(QString("name")), bad_chars_detected) ;
newChild.filename_has_wrong_characters = bad_chars_detected || bad_chars_in_parent ;
newChild.size = ee.attribute(QString("size")).toULongLong() ;
newChild.path = current_path ;
newChild.type = DIR_TYPE_FILE ;
dlinfos.push_back(i) ;
colFileInfos.push_back(newChild) ;
}
else if(ee.tagName() == QString("Directory"))
{
ColFileInfo newParent ;
bool bad_chars_detected = false ;
QString cleanDirName = purifyFileName(ee.attribute(QString("name")),bad_chars_detected) ;
newParent.name=cleanDirName;
newParent.filename_has_wrong_characters = bad_chars_detected || bad_chars_in_parent ;
newParent.size = 0;
newParent.path = current_path ;
newParent.type = DIR_TYPE_DIR ;
recursCollectDLinfos(ee,dlinfos,current_path + "/" + cleanDirName, bad_chars_in_parent || bad_chars_detected) ;
recursCollectColFileInfos(ee,newParent.children,current_path + "/" + cleanDirName, bad_chars_in_parent || bad_chars_detected) ;
uint32_t size = newParent.children.size();
for(uint32_t i=0;i<size;++i)
{
const ColFileInfo &colFileInfo = newParent.children[i];
newParent.size +=colFileInfo.size ;
}
colFileInfos.push_back(newParent) ;
}
n = n.nextSibling() ;
@ -147,41 +175,84 @@ void RsCollectionFile::recursAddElements(QDomDocument& doc,const DirDetails& det
}
}
RsCollectionFile::RsCollectionFile(const std::vector<DirDetails>& file_infos)
: _xml_doc("RsCollection")
void RsCollectionFile::recursAddElements(QDomDocument& doc,const ColFileInfo& colFileInfo,QDomElement& e) const
{
QDomElement root = _xml_doc.createElement("RsCollection");
_xml_doc.appendChild(root);
if (colFileInfo.type == DIR_TYPE_FILE)
{
QDomElement f = doc.createElement("File") ;
for(uint32_t i = 0;i<file_infos.size();++i)
recursAddElements(_xml_doc,file_infos[i],root) ;
f.setAttribute(QString("name"),colFileInfo.name) ;
f.setAttribute(QString("sha1"),colFileInfo.hash) ;
f.setAttribute(QString("size"),QString::number(colFileInfo.size)) ;
e.appendChild(f) ;
}
else if (colFileInfo.type == DIR_TYPE_DIR)
{
QDomElement d = doc.createElement("Directory") ;
d.setAttribute(QString("name"),colFileInfo.name) ;
for (std::vector<ColFileInfo>::const_iterator it = colFileInfo.children.begin(); it != colFileInfo.children.end(); it++)
{
recursAddElements(doc,(*it),d) ;
}
e.appendChild(d) ;
}
}
static void showErrorBox(const QString& filename, const QString& error)
static void showErrorBox(const QString& fileName, const QString& error)
{
QMessageBox mb(QMessageBox::Warning, QObject::tr("Failed to process collection file"), QObject::tr("The collection file %1 could not be opened.\nReported error is: \n\n%2").arg(filename).arg(error), QMessageBox::Ok);
QMessageBox mb(QMessageBox::Warning, QObject::tr("Failed to process collection file"), QObject::tr("The collection file %1 could not be opened.\nReported error is: \n\n%2").arg(fileName).arg(error), QMessageBox::Ok);
mb.setWindowIcon(QIcon(":/images/rstray3.png"));
mb.exec();
}
bool RsCollectionFile::load(const QString& filename, bool showError /* = true*/)
bool RsCollectionFile::load(const QString& fileName, bool showError /* = true*/)
{
QFile file(filename);
if (!checkFile(fileName,showError)) return false;
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly))
{
std::cerr << "Cannot open file " << filename.toStdString() << " !!" << std::endl;
std::cerr << "Cannot open file " << fileName.toStdString() << " !!" << std::endl;
if (showError) {
showErrorBox(filename, QApplication::translate("RsCollectionFile", "Cannot open file %1").arg(filename));
showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Cannot open file %1").arg(fileName));
}
return false;
}
// check that the file is a valid rscollection file, and not a lol bomb or some shit like this
std::cerr << "Checking this file for bomb elements and various wrong stuff" << std::endl;
bool ok = _xml_doc.setContent(&file) ;
file.close();
FILE *f = fopen(filename.toStdString().c_str(),"r") ;
if (ok) {
_fileName = fileName;
} else {
if (showError) {
showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Error parsing xml file"));
}
}
return ok;
}
// check that the file is a valid rscollection file, and not a lol bomb or some shit like this
bool RsCollectionFile::checkFile(const QString& fileName, bool showError)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly))
{
std::cerr << "Cannot open file " << fileName.toStdString() << " !!" << std::endl;
if (showError) {
showErrorBox(fileName, QApplication::translate("RsCollectionFile", "Cannot open file %1").arg(fileName));
}
return false;
}
if (file.reset()){
std::cerr << "Checking this file for bomb elements and various wrong stuff" << std::endl;
char c ;
std::vector<std::string> bad_strings ;
@ -189,13 +260,18 @@ bool RsCollectionFile::load(const QString& filename, bool showError /* = true*/)
static const int max_size = 12 ; // should be as large as the largest element in bad_strings
char current[max_size] = { 0,0,0,0,0,0,0,0,0,0,0,0 } ;
int n=0 ;
while( (c = fgetc(f)) != EOF || n >= 0)
while( !file.atEnd() || n >= 0)
{
if (!file.atEnd())
file.getChar(&c);
else
c=0;
if(c == '\t' || c == '\n' || c == '\b' || c == '\r')
continue ;
if(n == max_size || c==EOF)
if(n == max_size || file.atEnd())
for(int i=0;i<n-1;++i)
current[i] = current[i+1] ;
@ -204,63 +280,51 @@ bool RsCollectionFile::load(const QString& filename, bool showError /* = true*/)
if(c >= 'A' && c <= 'Z') c += 'a' - 'A' ;
if(c != EOF)
if(!file.atEnd())
current[n] = c ;
else
current[n] = 0 ;
//std::cerr << "n==" << n <<" Checking string " << std::string(current,n+1) << " c = " << std::hex << (int)c << std::dec << std::endl;
for(int i=0;i<bad_strings.size();++i)
for(uint i=0;i<bad_strings.size();++i)
if(std::string(current,bad_strings[i].length()) == bad_strings[i])
{
showErrorBox(filename, QApplication::translate("RsCollectionFile", "This file contains the string \"%1\" and is therefore an invalid collection file. \n\nIf you believe it is correct, remove the corresponding line from the file and re-open it with Retroshare.").arg(bad_strings[i].c_str()));
showErrorBox(file.fileName(), QApplication::translate("RsCollectionFile", "This file contains the string \"%1\" and is therefore an invalid collection file. \n\nIf you believe it is correct, remove the corresponding line from the file and re-open it with Retroshare.").arg(bad_strings[i].c_str()));
file.close();
return false ;
//std::cerr << "Bad string detected" << std::endl;
}
if(c == EOF)
if(file.atEnd())
n-- ;
else if(n < max_size)
n++ ;
}
fclose(f) ;
// std::cerr << "File is clean!" << std::endl;
// return false ;
bool ok = _xml_doc.setContent(&file) ;
file.close();
if (ok) {
_filename = filename;
} else {
if (showError) {
showErrorBox(filename, QApplication::translate("RsCollectionFile", "Error parsing xml file"));
return true;
}
}
return ok;
return false;
}
bool RsCollectionFile::load(QWidget *parent)
{
QString filename;
if (!misc::getOpenFileName(parent, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollectionFile::ExtensionString + ")", filename))
QString fileName;
if (!misc::getOpenFileName(parent, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Open collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollectionFile::ExtensionString + ")", fileName))
return false;
std::cerr << "Got file name: " << filename.toStdString() << std::endl;
std::cerr << "Got file name: " << fileName.toStdString() << std::endl;
return load(filename, true);
return load(fileName, true);
}
bool RsCollectionFile::save(const QString& filename) const
bool RsCollectionFile::save(const QString& fileName) const
{
QFile file(filename);
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly))
{
std::cerr << "Cannot write to file " << filename.toStdString() << " !!" << std::endl;
std::cerr << "Cannot write to file " << fileName.toStdString() << " !!" << std::endl;
return false;
}
@ -276,37 +340,135 @@ bool RsCollectionFile::save(const QString& filename) const
bool RsCollectionFile::save(QWidget *parent) const
{
QString filename;
if(!misc::getSaveFileName(parent, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Create collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollectionFile::ExtensionString + ")", filename))
QString fileName;
if(!misc::getSaveFileName(parent, RshareSettings::LASTDIR_EXTRAFILE, QApplication::translate("RsCollectionFile", "Create collection file"), QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollectionFile::ExtensionString + ")", fileName))
return false;
if (!filename.endsWith("." + RsCollectionFile::ExtensionString))
filename += "." + RsCollectionFile::ExtensionString ;
if (!fileName.endsWith("." + RsCollectionFile::ExtensionString))
fileName += "." + RsCollectionFile::ExtensionString ;
std::cerr << "Got file name: " << filename.toStdString() << std::endl;
std::cerr << "Got file name: " << fileName.toStdString() << std::endl;
return save(filename);
return save(fileName);
}
bool RsCollectionFile::openNewColl(QWidget *parent)
{
QString fileName;
if(!misc::getSaveFileName(parent, RshareSettings::LASTDIR_EXTRAFILE
, QApplication::translate("RsCollectionFile", "Create collection file")
, QApplication::translate("RsCollectionFile", "Collection files") + " (*." + RsCollectionFile::ExtensionString + ")"
, fileName,0, QFileDialog::DontConfirmOverwrite))
return false;
if (!fileName.endsWith("." + RsCollectionFile::ExtensionString))
fileName += "." + RsCollectionFile::ExtensionString ;
std::cerr << "Got file name: " << fileName.toStdString() << std::endl;
QFile file(fileName) ;
if(file.exists())
{
if (!checkFile(fileName,true)) return false;
QMessageBox mb;
mb.setText(tr("Save Collection File."));
mb.setInformativeText(tr("File already exist.")+"\n"+tr("What do you want to do?"));
QAbstractButton *btnOwerWrite = mb.addButton(tr("Overwrite"), QMessageBox::YesRole);
QAbstractButton *btnMerge = mb.addButton(tr("Merge"), QMessageBox::NoRole);
QAbstractButton *btnCancel = mb.addButton(tr("Cancel"), QMessageBox::ResetRole);
mb.setIcon(QMessageBox::Question);
mb.exec();
if (mb.clickedButton()==btnOwerWrite) {
//Nothing to do _xml_doc already up to date
} else if (mb.clickedButton()==btnMerge) {
//Open old file to merge it with _xml_doc
QDomDocument qddOldFile("RsCollection");
if (qddOldFile.setContent(&file)) {
QDomElement docOldElem = qddOldFile.elementsByTagName("RsCollection").at(0).toElement();
std::vector<ColFileInfo> colOldFileInfos;
recursCollectColFileInfos(docOldElem,colOldFileInfos,QString(),false);
QDomElement root = _xml_doc.elementsByTagName("RsCollection").at(0).toElement();
for(uint32_t i = 0;i<colOldFileInfos.size();++i){
recursAddElements(_xml_doc,colOldFileInfos[i],root) ;
}
}
} else if (mb.clickedButton()==btnCancel) {
return false;
} else {
return false;
}
}//if(file.exists())
_fileName=fileName;
std::vector<ColFileInfo> colFileInfos ;
recursCollectColFileInfos(_xml_doc.documentElement(),colFileInfos,QString(),false) ;
RsCollectionDialog* rcd = new RsCollectionDialog(fileName, colFileInfos,true);
connect(rcd,SIGNAL(saveColl(std::vector<ColFileInfo>, QString)),this,SLOT(saveColl(std::vector<ColFileInfo>, QString))) ;
_saved=false;
rcd->exec() ;
delete rcd;
return _saved;
}
bool RsCollectionFile::openColl(const QString& fileName, bool readOnly /* = false */, bool showError /* = true*/)
{
if (load(fileName, showError)) {
std::vector<ColFileInfo> colFileInfos ;
recursCollectColFileInfos(_xml_doc.documentElement(),colFileInfos,QString(),false) ;
RsCollectionDialog* rcd = new RsCollectionDialog(fileName, colFileInfos, true, readOnly);
connect(rcd,SIGNAL(saveColl(std::vector<ColFileInfo>, QString)),this,SLOT(saveColl(std::vector<ColFileInfo>, QString))) ;
_saved=false;
rcd->exec() ;
delete rcd;
return _saved;
}//if (load(fileName, showError))
return false;
}
qulonglong RsCollectionFile::size()
{
QDomElement docElem = _xml_doc.documentElement();
std::vector<DLinfo> dlinfos;
recursCollectDLinfos(docElem, dlinfos, QString(),false);
std::vector<ColFileInfo> colFileInfos;
recursCollectColFileInfos(docElem, colFileInfos, QString(),false);
uint64_t size = 0;
for (uint32_t i = 0; i < dlinfos.size(); ++i) {
size += dlinfos[i].size;
for (uint32_t i = 0; i < colFileInfos.size(); ++i) {
size += colFileInfos[i].size;
}
return size;
}
bool RsCollectionFile::isCollectionFile(const QString &filename)
bool RsCollectionFile::isCollectionFile(const QString &fileName)
{
QString ext = QFileInfo(filename).suffix().toLower();
QString ext = QFileInfo(fileName).suffix().toLower();
return (ext == RsCollectionFile::ExtensionString);
}
void RsCollectionFile::saveColl(std::vector<ColFileInfo> colFileInfos, const QString &fileName)
{
QDomElement root = _xml_doc.elementsByTagName("RsCollection").at(0).toElement();
while (root.childNodes().count()>0) root.removeChild(root.firstChild());
for(uint32_t i = 0;i<colFileInfos.size();++i)
recursAddElements(_xml_doc,colFileInfos[i],root) ;
_saved=save(fileName);
}

View file

@ -29,53 +29,82 @@
#pragma once
#include <QObject>
#include <QString>
#include <QDomDocument>
#include <QFile>
#include <retroshare/rsfiles.h>
#include <QMetaType>
class QDomElement ;
class QWidget;
class RsCollectionFile
class ColFileInfo
{
public:
static const QString ExtensionString ;
ColFileInfo(): name(""), size(0), path(""), hash(""), type(0), filename_has_wrong_characters(false), checked(false) {}
RsCollectionFile() ;
public:
QString name ;
qulonglong size ;
QString path ;
QString hash ;
uint8_t type;
bool filename_has_wrong_characters ;
std::vector<ColFileInfo> children;
bool checked;
};
Q_DECLARE_METATYPE(ColFileInfo)
class RsCollectionFile : public QObject
{
Q_OBJECT
public:
RsCollectionFile(QObject *parent = 0) ;
// create from list of files and directories
RsCollectionFile(const std::vector<DirDetails>& file_entries) ;
RsCollectionFile(const std::vector<DirDetails>& file_entries, QObject *parent = 0) ;
virtual ~RsCollectionFile() ;
static const QString ExtensionString ;
// Loads file from disk.
bool load(QWidget *parent);
bool load(const QString& filename, bool showError = true);
bool load(const QString& fileName, bool showError = true);
// Save to disk
bool save(QWidget *parent) const ;
bool save(const QString& filename) const ;
bool save(const QString& fileName) const ;
// Open new collection
bool openNewColl(QWidget *parent);
// Open existing collection
bool openColl(const QString& fileName, bool readOnly = false, bool showError = true);
// Download the content.
void downloadFiles() const ;
qulonglong size();
static bool isCollectionFile(const QString& filename);
static bool isCollectionFile(const QString& fileName);
private slots:
void saveColl(std::vector<ColFileInfo> colFileInfos, const QString& fileName);
private:
struct DLinfo
{
QString name ;
qulonglong size ;
QString path ;
QString hash ;
bool filename_has_wrong_characters ;
};
void recursAddElements(QDomDocument&,const DirDetails&,QDomElement&) const ;
void recursCollectDLinfos(const QDomElement&,std::vector<DLinfo>& dlinfos,const QString& current_dir,bool bad_chars_in_parent) const ;
void recursAddElements(QDomDocument&,const ColFileInfo&,QDomElement&) const;
void recursCollectColFileInfos(const QDomElement&,std::vector<ColFileInfo>& colFileInfos,const QString& current_dir,bool bad_chars_in_parent) const ;
// check that the file is a valid rscollection file, and not a lol bomb or some shit like this
static bool checkFile(const QString &fileName, bool showError);
QDomDocument _xml_doc ;
QString _filename ;
QString _fileName ;
bool _saved;
friend class RsCollectionDialog ;
};