------------------------------------------------------------ revno: 2788 committer: poy <p...@123gen.com> 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();
_______________________________________________ Mailing list: https://launchpad.net/~linuxdcpp-team Post to : linuxdcpp-team@lists.launchpad.net Unsubscribe : https://launchpad.net/~linuxdcpp-team More help : https://help.launchpad.net/ListHelp