← Back to team overview

linuxdcpp-team team mailing list archive

[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();