fb2temp.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. #include "fb2temp.hpp"
  2. #include <QCryptographicHash>
  3. #include <QFileInfo>
  4. #include <QImageReader>
  5. #include <QUrl>
  6. #include <QVBoxLayout>
  7. #include <QtDebug>
  8. #include "fb2text.hpp"
  9. //---------------------------------------------------------------------------
  10. // FbTemporaryFile
  11. //---------------------------------------------------------------------------
  12. FbTemporaryFile::FbTemporaryFile(const QString &name)
  13. : QTemporaryFile()
  14. , m_name(name)
  15. {
  16. }
  17. qint64 FbTemporaryFile::write(const QByteArray &data)
  18. {
  19. open();
  20. if (m_hash.isEmpty()) m_hash = md5(data);
  21. qint64 size = QTemporaryFile::write(data);
  22. close();
  23. return size;
  24. }
  25. QString FbTemporaryFile::md5(const QByteArray &data)
  26. {
  27. return QCryptographicHash::hash(data, QCryptographicHash::Md5).toBase64();
  28. }
  29. QByteArray FbTemporaryFile::data()
  30. {
  31. open();
  32. QByteArray data = readAll();
  33. close();
  34. return data;
  35. }
  36. //---------------------------------------------------------------------------
  37. // FbTemporaryList
  38. //---------------------------------------------------------------------------
  39. FbTemporaryList::FbTemporaryList()
  40. {
  41. }
  42. FbTemporaryList::~FbTemporaryList()
  43. {
  44. FbTemporaryIterator it(*this);
  45. while (it.hasNext()) delete it.next();
  46. }
  47. QString FbTemporaryList::add(const QString &path, const QByteArray &data)
  48. {
  49. QString hash = FbTemporaryFile::md5(data);
  50. QString name = this->name(hash);
  51. if (name.isEmpty()) {
  52. name = newName(path);
  53. FbTemporaryFile * temp = new FbTemporaryFile(name);
  54. temp->setHash(hash);
  55. temp->write(data);
  56. append(temp);
  57. }
  58. return name;
  59. }
  60. QString FbTemporaryList::newName(const QString &path)
  61. {
  62. QFileInfo info(path);
  63. QString name = info.fileName();
  64. if (!exists(name)) return name;
  65. QString base = info.baseName();
  66. QString suff = info.suffix();
  67. for (int i = 1; ; i++) {
  68. QString name = QString("%1(%2).%3").arg(base).arg(i).arg(suff);
  69. if (exists(name)) continue;
  70. return name;
  71. }
  72. }
  73. FbTemporaryFile * FbTemporaryList::get(const QString &name) const
  74. {
  75. FbTemporaryIterator it(*this);
  76. while (it.hasNext()) {
  77. FbTemporaryFile * file = it.next();
  78. if (file->name() == name) return file;
  79. }
  80. return NULL;
  81. }
  82. QByteArray FbTemporaryList::data(const QString &name) const
  83. {
  84. FbTemporaryIterator it(*this);
  85. while (it.hasNext()) {
  86. FbTemporaryFile *file = it.next();
  87. if (file->name() == name) return file->data();
  88. }
  89. return QByteArray();
  90. }
  91. const QString & FbTemporaryList::set(const QString &name, const QByteArray &data, const QString &hash)
  92. {
  93. FbTemporaryFile * file = get(name);
  94. if (!file) append(file = new FbTemporaryFile(name));
  95. file->setHash(hash);
  96. file->write(data);
  97. return file->hash();
  98. }
  99. QString FbTemporaryList::name(const QString &hash) const
  100. {
  101. FbTemporaryIterator it(*this);
  102. while (it.hasNext()) {
  103. FbTemporaryFile *file = it.next();
  104. if (file->hash() == hash) return file->name();
  105. }
  106. return QString();
  107. }
  108. bool FbTemporaryList::exists(const QString &name) const
  109. {
  110. FbTemporaryIterator it(*this);
  111. while (it.hasNext()) {
  112. FbTemporaryFile *file = it.next();
  113. if (file->name() == name) return true;
  114. }
  115. return false;
  116. }
  117. #if 0
  118. //---------------------------------------------------------------------------
  119. // FbNetworkDiskCache
  120. //---------------------------------------------------------------------------
  121. QNetworkCacheMetaData FbNetworkDiskCache::metaData(const QUrl &url)
  122. {
  123. qCritical() << url.toString();
  124. return QNetworkDiskCache::metaData(url);
  125. }
  126. QIODevice * FbNetworkDiskCache::data(const QUrl &url)
  127. {
  128. qCritical() << url.toString();
  129. return QNetworkDiskCache::data(url);
  130. }
  131. #endif
  132. //---------------------------------------------------------------------------
  133. // FbImageReply
  134. //---------------------------------------------------------------------------
  135. FbImageReply::FbImageReply(QNetworkAccessManager::Operation op, const QNetworkRequest &request, const QByteArray &data)
  136. : QNetworkReply()
  137. , content(data)
  138. , offset(0)
  139. {
  140. setOperation(op);
  141. setRequest(request);
  142. setUrl(request.url());
  143. open(ReadOnly | Unbuffered);
  144. setHeader(QNetworkRequest::ContentLengthHeader, QVariant(content.size()));
  145. setAttribute(QNetworkRequest::CacheSaveControlAttribute, QVariant(false));
  146. QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
  147. QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection);
  148. }
  149. qint64 FbImageReply::readData(char *data, qint64 maxSize)
  150. {
  151. if (offset >= content.size()) return -1;
  152. QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection);
  153. qint64 number = qMin(maxSize, content.size() - offset);
  154. memcpy(data, content.constData() + offset, number);
  155. offset += number;
  156. return number;
  157. }
  158. //---------------------------------------------------------------------------
  159. // FbNetworkAccessManager
  160. //
  161. // http://doc.trolltech.com/qq/32/qq32-webkit-protocols.html
  162. //---------------------------------------------------------------------------
  163. FbNetworkAccessManager::FbNetworkAccessManager(FbTextEdit &view)
  164. : QNetworkAccessManager(&view)
  165. , m_view(view)
  166. {
  167. }
  168. QNetworkReply * FbNetworkAccessManager::createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData)
  169. {
  170. if (request.url().scheme() == "fb2" && request.url().path() == m_view.url().path()) return imageRequest(op, request);
  171. return QNetworkAccessManager::createRequest(op, request, outgoingData);
  172. }
  173. QNetworkReply * FbNetworkAccessManager::imageRequest(Operation op, const QNetworkRequest &request)
  174. {
  175. QString name = request.url().fragment();
  176. QByteArray data = m_view.files().data(name);
  177. return new FbImageReply(op, request, data);
  178. }
  179. //---------------------------------------------------------------------------
  180. // FbListWidget
  181. //---------------------------------------------------------------------------
  182. FbListWidget::FbListWidget(FbTextEdit &view, QWidget* parent)
  183. {
  184. QVBoxLayout * layout = new QVBoxLayout(this);
  185. layout->setSpacing(0);
  186. layout->setContentsMargins(0, 0, 0, 0);
  187. m_list = new QListView(this);
  188. layout->addWidget(m_list);
  189. m_tool = new QToolBar(this);
  190. layout->addWidget(m_tool);
  191. }