linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #05153
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 2788: Save and restore file lists dl'd with "browse file list"
------------------------------------------------------------
revno: 2788
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Sat 2012-01-07 00:14:39 +0100
message:
Save and restore file lists dl'd with "browse file list"
modified:
changelog.txt
dcpp/DirectoryListing.cpp
dcpp/DirectoryListing.h
dcpp/QueueManager.cpp
dcpp/QueueManager.h
dcpp/ShareManager.cpp
dcpp/ZUtils.cpp
dwt/include/dwt/CanvasClasses.h
dwt/src/CanvasClasses.cpp
win32/DirectoryListingFrame.cpp
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt 2012-01-01 21:25:05 +0000
+++ changelog.txt 2012-01-06 23:14:39 +0000
@@ -1,4 +1,4 @@
-* Prevent crashes when closing hub, PM or file list windows (poy)
+* Save and restore file lists dl'd with "browse file list" (poy)
-- 0.790 2011-12-29 --
* Fav users frame becomes users frame and shows all users
=== modified file 'dcpp/DirectoryListing.cpp'
--- dcpp/DirectoryListing.cpp 2011-12-27 22:02:43 +0000
+++ dcpp/DirectoryListing.cpp 2012-01-06 23:14:39 +0000
@@ -19,17 +19,17 @@
#include "stdinc.h"
#include "DirectoryListing.h"
-#include "QueueManager.h"
+#include "BZUtils.h"
#include "ClientManager.h"
-
-#include "StringTokenizer.h"
-#include "SimpleXML.h"
+#include "CryptoManager.h"
+#include "File.h"
#include "FilteredFile.h"
-#include "BZUtils.h"
-#include "CryptoManager.h"
+#include "QueueManager.h"
#include "ShareManager.h"
+#include "SimpleXML.h"
#include "SimpleXMLReader.h"
-#include "File.h"
+#include "StringTokenizer.h"
+#include "version.h"
#ifdef ff
#undef ff
@@ -214,9 +214,13 @@
}
} else if(name == sFileListing) {
const string& b = getAttrib(attribs, sBase, 2);
- if(b.size() >= 1 && b[0] == '/' && b[b.size()-1] == '/') {
+ if(b.size() >= 1 && b[0] == '/' && *(b.end() - 1) == '/') {
base = b;
+ if(list->base.empty() || base.size() < list->base.size()) {
+ list->base = base;
+ }
}
+
StringList sl = StringTokenizer<string>(base.substr(1), '/').getTokens();
for(auto i = sl.begin(); i != sl.end(); ++i) {
DirectoryListing::Directory* d = NULL;
@@ -253,6 +257,67 @@
}
}
+void DirectoryListing::save(const string& path) const {
+ dcassert(!base.empty());
+ dcpp::File stream(path, dcpp::File::WRITE, dcpp::File::CREATE | dcpp::File::TRUNCATE);
+ stream.write(SimpleXML::utf8Header);
+ string indent("\t"), tmp;
+ stream.write("<FileListing Version=\"1\" CID=\"" + user.user->getCID().toBase32() + "\" Base=\"" + SimpleXML::escape(base, tmp, true) + "\" Generator=\"" APPNAME " " VERSIONSTRING "\">\r\n");
+ auto start = find(Util::toNmdcFile(base), root);
+ if(start) {
+ std::for_each(start->directories.cbegin(), start->directories.cend(), [&](Directory* d) {
+ d->save(stream, indent, tmp);
+ });
+ std::for_each(start->files.cbegin(), start->files.cend(), [&](File* f) {
+ f->save(stream, indent, tmp);
+ });
+ }
+ stream.write("</FileListing>");
+}
+
+void DirectoryListing::Directory::save(OutputStream& stream, string& indent, string& tmp) const {
+ if(adls)
+ return;
+
+ stream.write(indent);
+ stream.write(LIT("<Directory Name=\""));
+ stream.write(SimpleXML::escape(name, tmp, true));
+
+ if(!getComplete()) {
+ stream.write(LIT("\" Incomplete=\"1"));
+ }
+
+ if(directories.empty() && files.empty()) {
+ stream.write(LIT("\" />\r\n"));
+ } else {
+ stream.write(LIT("\">\r\n"));
+ indent += '\t';
+
+ std::for_each(directories.cbegin(), directories.cend(), [&](Directory* d) {
+ d->save(stream, indent, tmp);
+ });
+ std::for_each(files.cbegin(), files.cend(), [&](File* f) {
+ f->save(stream, indent, tmp);
+ });
+
+ indent.erase(indent.end() - 1);
+ stream.write(indent);
+ stream.write(LIT("</Directory>\r\n"));
+ }
+}
+
+void DirectoryListing::File::save(OutputStream& stream, string& indent, string& tmp) const {
+ stream.write(indent);
+ stream.write(LIT("<File Name=\""));
+ stream.write(SimpleXML::escape(getName(), tmp, true));
+ stream.write(LIT("\" Size=\""));
+ stream.write(Util::toString(getSize()));
+ stream.write(LIT("\" TTH=\""));
+ tmp.clear();
+ stream.write(getTTH().toBase32(tmp));
+ stream.write(LIT("\"/>\r\n"));
+}
+
string DirectoryListing::getPath(const Directory* d) const {
if(d == root)
return "";
@@ -327,13 +392,13 @@
QueueManager::getInstance()->setPriority(aTarget, QueueItem::HIGHEST);
}
-DirectoryListing::Directory* DirectoryListing::find(const string& aName, Directory* current) {
+DirectoryListing::Directory* DirectoryListing::find(const string& aName, Directory* current) const {
auto end = aName.find('\\');
dcassert(end != string::npos);
auto name = aName.substr(0, end);
- auto i = std::find(current->directories.begin(), current->directories.end(), name);
- if(i != current->directories.end()) {
+ auto i = std::find(current->directories.cbegin(), current->directories.cend(), name);
+ if(i != current->directories.cend()) {
if(end == (aName.size() - 1))
return *i;
else
=== modified file 'dcpp/DirectoryListing.h'
--- dcpp/DirectoryListing.h 2011-12-27 22:02:43 +0000
+++ dcpp/DirectoryListing.h 2012-01-06 23:14:39 +0000
@@ -64,6 +64,8 @@
~File() { }
+ void save(OutputStream& stream, string& indent, string& tmp) const;
+
GETSET(string, name, Name);
GETSET(int64_t, size, Size);
GETSET(Directory*, parent, Parent);
@@ -97,10 +99,11 @@
void filterList(DirectoryListing& dirList);
void filterList(TTHSet& l);
void getHashList(TTHSet& l);
-
- size_t getFileCount() { return files.size(); }
-
- int64_t getSize() {
+ void save(OutputStream& stream, string& indent, string& tmp) const;
+
+ size_t getFileCount() const { return files.size(); }
+
+ int64_t getSize() const {
int64_t x = 0;
for(auto i = files.begin(); i != files.end(); ++i) {
x+=(*i)->getSize();
@@ -129,6 +132,9 @@
string updateXML(const std::string&);
string loadXML(InputStream& xml, bool updating);
+ /** write an XML representation of this file list to the specified file. */
+ void save(const string& path) const;
+
void download(const string& aDir, const string& aTarget, bool highPrio);
void download(Directory* aDir, const string& aTarget, bool highPrio);
void download(File* aFile, const string& aTarget, bool view, bool highPrio);
@@ -156,8 +162,9 @@
friend class ListLoader;
Directory* root;
+ string base;
- Directory* find(const string& aName, Directory* current);
+ Directory* find(const string& aName, Directory* current) const;
};
inline bool operator==(DirectoryListing::Directory::Ptr a, const string& b) { return Util::stricmp(a->getName(), b) == 0; }
=== modified file 'dcpp/QueueManager.cpp'
--- dcpp/QueueManager.cpp 2012-01-02 10:59:22 +0000
+++ dcpp/QueueManager.cpp 2012-01-06 23:14:39 +0000
@@ -471,7 +471,7 @@
std::sort(protectedFileLists.begin(), protectedFileLists.end());
- StringList filelists = File::findFiles(path, "*.xml.bz2");
+ auto filelists = File::findFiles(path, "*.xml*");
std::sort(filelists.begin(), filelists.end());
std::for_each(filelists.begin(), std::set_difference(filelists.begin(), filelists.end(),
protectedFileLists.begin(), protectedFileLists.end(), filelists.begin()), &File::deleteFile);
=== modified file 'dcpp/QueueManager.h'
--- dcpp/QueueManager.h 2011-12-29 19:05:08 +0000
+++ dcpp/QueueManager.h 2012-01-06 23:14:39 +0000
@@ -134,10 +134,12 @@
void loadQueue() noexcept;
void saveQueue(bool force = false) noexcept;
+ string getListPath(const HintedUser& user);
void noDeleteFileList(const string& path);
GETSET(uint64_t, lastSave, LastSave);
GETSET(string, queueFile, QueueFile);
+
private:
enum { MOVER_LIMIT = 10*1024*1024 };
class FileMover : public Thread {
@@ -267,8 +269,6 @@
void setDirty();
- string getListPath(const HintedUser& user);
-
bool checkSfv(QueueItem* qi, Download* d);
uint32_t calcCrc32(const string& file);
=== modified file 'dcpp/ShareManager.cpp'
--- dcpp/ShareManager.cpp 2011-12-22 22:14:45 +0000
+++ dcpp/ShareManager.cpp 2012-01-06 23:14:39 +0000
@@ -886,7 +886,7 @@
string xml = SimpleXML::utf8Header;
string tmp;
- xml += "<FileListing Version=\"1\" CID=\"" + ClientManager::getInstance()->getMe()->getCID().toBase32() + "\" Base=\"" + SimpleXML::escape(dir, tmp, false) + "\" Generator=\"" APPNAME " " VERSIONSTRING "\">\r\n";
+ xml += "<FileListing Version=\"1\" CID=\"" + ClientManager::getInstance()->getMe()->getCID().toBase32() + "\" Base=\"" + SimpleXML::escape(dir, tmp, true) + "\" Generator=\"" APPNAME " " VERSIONSTRING "\">\r\n";
StringOutputStream sos(xml);
string indent = "\t";
=== modified file 'dcpp/ZUtils.cpp'
--- dcpp/ZUtils.cpp 2011-10-01 14:33:43 +0000
+++ dcpp/ZUtils.cpp 2012-01-06 23:14:39 +0000
@@ -19,9 +19,10 @@
#include "stdinc.h"
#include "ZUtils.h"
-#include "format.h"
#include "Exception.h"
#include "File.h"
+#include "format.h"
+#include "ScopedFunctor.h"
namespace dcpp {
@@ -135,6 +136,8 @@
if(!gz) {
throw Exception(_("Error during decompression"));
}
+ ScopedFunctor([&gz] { gzclose(gz); });
+
File f(target, File::WRITE, File::CREATE | File::TRUNCATE);
const size_t BUF_SIZE = 64 * 1024;
@@ -149,8 +152,6 @@
break;
}
}
-
- gzclose(gz);
}
} // namespace dcpp
=== modified file 'dwt/include/dwt/CanvasClasses.h'
--- dwt/include/dwt/CanvasClasses.h 2011-05-31 17:39:38 +0000
+++ dwt/include/dwt/CanvasClasses.h 2012-01-06 23:14:39 +0000
@@ -154,7 +154,7 @@
class Canvas : private boost::noncopyable
{
- class Selector {
+ class Selector : boost::noncopyable {
public:
template<typename T>
Selector(Canvas& canvas_, T& t) : canvas(canvas_), h(::SelectObject(canvas.handle(), t.handle())) { }
@@ -166,7 +166,7 @@
HGDIOBJ h;
};
- class BkMode {
+ class BkMode : boost::noncopyable {
public:
BkMode(Canvas& canvas_, int mode);
~BkMode();
@@ -524,95 +524,6 @@
virtual ~CompatibleCanvas();
};
-#ifndef WINCE
-// TODO: Create custom enums for typesafety... ?
-/// Helper class for setting and resetting the ROP2 mode
-/** The ROP2 mode is used for telling windows which type of brush you want while
- * painting. <br>
- * this class ensures we reset the ROP2 mode after we have fiinished with it. <br>
- * Used in combination with e.g. UpdateCanvas or PaintCanvas. <br>
- * Supported modes are those supported in Windows API
- * <ul>
- * <li>R2_BLACK Pixel is always 0. </li>
- * <li>R2_COPYPEN Pixel is the pen color. </li>
- * <li>R2_MASKNOTPEN Pixel is a combination of the colors common to both the screen and the inverse of the pen. </li>
- * <li>R2_MASKPEN Pixel is a combination of the colors common to both the pen and the screen. </li>
- * <li>R2_MASKPENNOT Pixel is a combination of the colors common to both the pen and the inverse of the screen. </li>
- * <li>R2_MERGENOTPEN Pixel is a combination of the screen color and the inverse of the pen color. </li>
- * <li>R2_MERGEPEN Pixel is a combination of the pen color and the screen color. </li>
- * <li>R2_MERGEPENNOT Pixel is a combination of the pen color and the inverse of the screen color. </li>
- * <li>R2_NOP Pixel remains unchanged. </li>
- * <li>R2_NOT Pixel is the inverse of the screen color. </li>
- * <li>R2_NOTCOPYPEN Pixel is the inverse of the pen color. </li>
- * <li>R2_NOTMASKPEN Pixel is the inverse of the R2_MASKPEN color. </li>
- * <li>R2_NOTMERGEPEN Pixel is the inverse of the R2_MERGEPEN color. </li>
- * <li>R2_NOTXORPEN Pixel is the inverse of the R2_XORPEN color. </li>
- * <li>R2_WHITE Pixel is always 1. </li>
- * <li>R2_XORPEN Pixel is a combination of the colors in the pen and in the screen, but not in both.</li>
- * </ul>
- * Related classes
- * <ul>
- * <li>UpdateCanvas</li>
- * <li>PaintCanvas</li>
- * <li>FreeCanvas</li>
- * <li>Canvas</li>
- * <li>Pen</li>
- * </ul>
- */
-class HdcModeSetter
-{
-public:
- /// Constructor setting the ROP2 of the given Device Context.
- /** The mode is any of the above enums.
- */
- HdcModeSetter( Canvas & canvas, int mode );
-
- /// Automatically resets the ROP2
- /** Resets the mode back to what it was before this object was created. Note this
- * object cannot have longer lifetime than the Canvas given to the Constructor
- * since this will cause undefined behavior.
- */
- ~HdcModeSetter();
-
-private:
- int itsOldMode;
- Canvas & itsCanvas;
-};
-#endif //! WINCE
-
-/// Class for control of the text color lifetime
-/** Constructor takes a COLORREF. (Use the RGB macro. <br>
- * Class ensures that the previous text color is restored on object destruction.
- * <br>
- * Related classes<br>
- * <ul>
- * <li>Canvas</li>
- * <li>Pen</li>
- * </ul>
- */
-class TextPen
-{
-public:
- /// Constructor taking a Canvas and a COLORREF
- /** Build a COLORREF argument with windows.h's RGB( red, green, blue )
- */
- TextPen( Canvas & canvas, COLORREF color );
-
- /// Automatically restores the old TextColor.
- /** Since this is a RAII structure it ensures the old pen is restored upon
- * destruction. Be careful though since if this oulives the Canvas object given
- * undefined behaviour will occur!
- */
- ~TextPen();
-
-private:
- // Handle to the old color which will be restored in the DTOR of the object)
- COLORREF itsColorOld;
-
- // Handle to its Device Context.
- Canvas & itsCanvas;
-};
-
inline HDC Canvas::handle() const { return itsHdc; }
}
=== modified file 'dwt/src/CanvasClasses.cpp'
--- dwt/src/CanvasClasses.cpp 2011-05-31 17:39:38 +0000
+++ dwt/src/CanvasClasses.cpp 2012-01-06 23:14:39 +0000
@@ -344,29 +344,4 @@
::DeleteDC(itsHdc);
}
-#ifndef WINCE
-HdcModeSetter::HdcModeSetter( Canvas & canvas, int mode )
- : itsOldMode( ::GetROP2( canvas.handle() ) ),
- itsCanvas( canvas )
-{
- ::SetROP2( itsCanvas.handle(), mode );
-}
-
-HdcModeSetter::~HdcModeSetter()
-{
- ::SetROP2( itsCanvas.handle(), itsOldMode );
-}
-#endif //! WINCE
-
-TextPen::TextPen( Canvas & canvas, COLORREF color )
- : itsCanvas( canvas )
-{
- itsColorOld = itsCanvas.setTextColor( color );
-}
-
-TextPen::~TextPen()
-{
- ::SetTextColor( itsCanvas.handle(), itsColorOld );
-}
-
}
=== modified file 'win32/DirectoryListingFrame.cpp'
--- win32/DirectoryListingFrame.cpp 2012-01-01 21:25:05 +0000
+++ win32/DirectoryListingFrame.cpp 2012-01-06 23:14:39 +0000
@@ -482,10 +482,13 @@
}
void DirectoryListingFrame::loadXML(const string& txt) {
- loaded = true;
-
try {
- refreshTree(Text::toT(Util::toNmdcFile(dl->updateXML(txt))));
+ path = QueueManager::getInstance()->getListPath(dl->getUser()) + ".xml";
+ auto base = dl->updateXML(txt);
+ dl->save(path);
+ loaded = true;
+ addRecent();
+ refreshTree(Text::toT(Util::toNmdcFile(base)));
} catch(const Exception& e) {
error = Text::toT(e.getError());
updateTitle();