commit 92d60745a879dc4f29f1340d0995991f6bb576f6
parent fe2b4183c0f508b51bcd6528e40ee6b14bd3a580
Author: cfillion <cfillion@users.noreply.github.com>
Date: Wed, 3 Feb 2016 23:52:53 -0500
add a Package History dialog
Diffstat:
6 files changed, 158 insertions(+), 50 deletions(-)
diff --git a/src/about.cpp b/src/about.cpp
@@ -29,10 +29,13 @@
#include "tabbar.hpp"
#include <boost/algorithm/string/replace.hpp>
+#include <boost/range/adaptor/reversed.hpp>
#include <sstream>
using namespace std;
+enum { ACTION_HISTORY = 300 };
+
About::About(const Remote *remote, const RemoteIndex *index)
: Dialog(IDD_ABOUT_DIALOG), m_remote(remote), m_index(index),
m_currentCat(-255)
@@ -64,6 +67,7 @@ void About::onInit()
});
m_packages->sortByColumn(0);
+ m_packages->onActivate(bind(&About::packageHistory, this));
m_installedFiles = getControl(IDC_LIST);
@@ -93,6 +97,9 @@ void About::onCommand(const int id)
case IDC_ENABLE:
close(EnableResult);
break;
+ case ACTION_HISTORY:
+ packageHistory();
+ break;
case IDOK:
case IDCANCEL:
close();
@@ -105,6 +112,21 @@ void About::onCommand(const int id)
}
}
+void About::onContextMenu(HWND target, const int x, const int y)
+{
+ if(target != m_packages->handle())
+ return;
+
+ const int packageIndex = m_packages->currentIndex();
+
+ if(packageIndex < 0)
+ return;
+
+ Menu menu;
+ menu.addAction(AUTO_STR("Package &History"), ACTION_HISTORY);
+ menu.show(x, y, handle());
+}
+
void About::populate()
{
auto_char title[255] = {};
@@ -129,7 +151,7 @@ void About::populate()
m_tabs->setCurrentIndex(0);
}
- m_cats->addRow({AUTO_STR("<All Categories>")});
+ m_cats->addRow({AUTO_STR("<All Packages>")});
for(const Category *cat : m_index->categories())
m_cats->addRow({make_autostring(cat->name())});
@@ -149,21 +171,20 @@ void About::updatePackages()
if(index == -1 && m_currentCat >= -1)
return;
- // -1: all categories, >0 selected category
+ // -1: all packages, >0 selected category
const int catIndex = max(-1, index - 1);
- const PackageList *pkgList;
if(catIndex == m_currentCat)
return;
else if(catIndex < 0)
- pkgList = &m_index->packages();
+ m_packagesData = &m_index->packages();
else
- pkgList = &m_index->category(catIndex)->packages();
+ m_packagesData = &m_index->category(catIndex)->packages();
InhibitControl lock(m_packages);
m_packages->clear();
- for(const Package *pkg : *pkgList) {
+ for(const Package *pkg : *m_packagesData) {
const Version *lastVer = pkg->lastVersion();
const auto_string &name = make_autostring(pkg->name());
const auto_string &version = make_autostring(lastVer->name());
@@ -245,3 +266,44 @@ void About::openLink(const Link *link)
const auto_string &url = make_autostring(link->url);
ShellExecute(nullptr, AUTO_STR("open"), url.c_str(), nullptr, nullptr, SW_SHOW);
}
+
+void About::packageHistory()
+{
+ const int index = m_packages->currentIndex();
+
+ if(index < 0)
+ return;
+
+ const Package *pkg = m_packagesData->at(index);
+ Dialog::Show<History>(instance(), handle(), pkg);
+}
+
+History::History(const Package *pkg)
+ : ReportDialog(), m_package(pkg)
+{
+}
+
+void History::fillReport()
+{
+ SetWindowText(handle(), AUTO_STR("Package History"));
+ SetWindowText(getControl(IDC_LABEL),
+ make_autostring(m_package->name()).c_str());
+
+ for(const Version *ver : m_package->versions() | boost::adaptors::reversed) {
+ if(stream().tellp())
+ stream() << NL;
+
+ stream() << ver->name();
+
+ if(!ver->author().empty())
+ stream() << " by " << ver->author();
+
+ stream() << NL;
+
+ const string &changelog = ver->changelog();
+ if(changelog.empty())
+ printChangelog("No changelog");
+ else
+ printChangelog(changelog);
+ }
+}
diff --git a/src/about.hpp b/src/about.hpp
@@ -22,9 +22,13 @@
#include <vector>
+#include "report.hpp"
+
class ListView;
+class Package;
class Remote;
class RemoteIndex;
+class ReportBase;
class RichEdit;
class TabBar;
struct Link;
@@ -37,6 +41,7 @@ public:
protected:
void onInit() override;
void onCommand(int) override;
+ void onContextMenu(HWND, int x, int y) override;
private:
void populate();
@@ -44,6 +49,7 @@ private:
void updateInstalledFiles();
void selectLink(int control, const std::vector<const Link *> &);
void openLink(const Link *);
+ void packageHistory();
const Remote *m_remote;
const RemoteIndex *m_index;
@@ -57,6 +63,18 @@ private:
std::vector<const Link *> m_websiteLinks;
std::vector<const Link *> m_donationLinks;
+ const std::vector<const Package *> *m_packagesData;
+};
+
+class History : public ReportDialog {
+public:
+ History(const Package *);
+
+protected:
+ void fillReport() override;
+
+private:
+ const Package *m_package;
};
#endif
diff --git a/src/dialog.cpp b/src/dialog.cpp
@@ -184,6 +184,10 @@ HWND Dialog::getControl(const int idc)
return GetDlgItem(m_handle, idc);
}
+void Dialog::onInit()
+{
+}
+
void Dialog::onShow()
{
center();
@@ -197,8 +201,13 @@ void Dialog::onTimer()
{
}
-void Dialog::onCommand(int)
+void Dialog::onCommand(const int id)
{
+ switch(id) {
+ case IDOK:
+ case IDCANCEL:
+ close();
+ }
}
void Dialog::onNotify(LPNMHDR info, LPARAM lParam)
diff --git a/src/dialog.hpp b/src/dialog.hpp
@@ -100,7 +100,7 @@ protected:
return ctrl;
}
- virtual void onInit() = 0;
+ virtual void onInit();
virtual void onShow();
virtual void onHide();
virtual void onTimer();
diff --git a/src/report.cpp b/src/report.cpp
@@ -28,23 +28,53 @@
using namespace std;
static const string SEP(10, '=');
-static const char *NL = "\r\n";
+const char * const ReportDialog::NL = "\r\n";
-Report::Report(Transaction *transaction)
- : Dialog(IDD_REPORT_DIALOG), m_transaction(transaction)
+ReportDialog::ReportDialog()
+ : Dialog(IDD_REPORT_DIALOG)
{
// enable number formatting (ie. "1,234" instead of "1234")
m_stream.imbue(locale(""));
}
-void Report::onInit()
+void ReportDialog::onInit()
+{
+ fillReport();
+
+ const auto_string &str = make_autostring(m_stream.str());
+ SetDlgItemText(handle(), IDC_REPORT, str.c_str());
+}
+
+void ReportDialog::printHeader(const char *title)
+{
+ if(m_stream.tellp())
+ m_stream << NL;
+
+ m_stream << NL << SEP << ' ' << title << ": " << SEP << NL;
+}
+
+void ReportDialog::printChangelog(const string &changelog)
+{
+ istringstream input(changelog);
+ string line;
+
+ while(getline(input, line, '\n'))
+ m_stream << "\x20\x20" << line.substr(line.find_first_not_of('\x20')) << NL;
+}
+
+Report::Report(Transaction *transaction)
+ : ReportDialog(), m_transaction(transaction)
+{
+}
+
+void Report::fillReport()
{
const size_t newPackages = m_transaction->newPackages().size();
const size_t updates = m_transaction->updates().size();
const size_t removals = m_transaction->removals().size();
const size_t errors = m_transaction->errors().size();
- m_stream
+ stream()
<< newPackages << " new packages, "
<< updates << " updates, "
<< removals << " removed files and "
@@ -63,19 +93,6 @@ void Report::onInit()
if(removals)
printRemovals();
-
- const auto_string &str = make_autostring(m_stream.str());
- SetDlgItemText(handle(), IDC_REPORT, str.c_str());
-}
-
-void Report::onCommand(const int id)
-{
- switch(id) {
- case IDOK:
- case IDCANCEL:
- close();
- break;
- }
}
void Report::printNewPackages()
@@ -84,7 +101,7 @@ void Report::printNewPackages()
for(const Transaction::InstallTicket &entry : m_transaction->newPackages()) {
const Version *ver = entry.first;
- m_stream << NL << ver->fullName();
+ stream() << NL << ver->fullName();
}
}
@@ -101,7 +118,7 @@ void Report::printUpdates()
if(ver->code() <= queryRes.entry.version)
break;
- m_stream << NL << ver->fullName() << NL;
+ stream() << NL << ver->fullName() << NL;
if(!ver->changelog().empty())
printChangelog(ver->changelog());
@@ -109,21 +126,12 @@ void Report::printUpdates()
}
}
-void Report::printChangelog(const string &changelog)
-{
- istringstream input(changelog);
- string line;
-
- while(getline(input, line, '\n'))
- m_stream << "\x20\x20" << line.substr(line.find_first_not_of('\x20')) << NL;
-}
-
void Report::printErrors()
{
printHeader("Errors");
for(const Transaction::Error &err : m_transaction->errors())
- m_stream << NL << err.title << ':' << NL << err.message << NL;
+ stream() << NL << err.title << ':' << NL << err.message << NL;
}
void Report::printRemovals()
@@ -131,10 +139,5 @@ void Report::printRemovals()
printHeader("Removed files");
for(const Path &path : m_transaction->removals())
- m_stream << NL << path.join();
-}
-
-void Report::printHeader(const char *title)
-{
- m_stream << NL << SEP << ' ' << title << ": " << SEP << NL;
+ stream() << NL << path.join();
}
diff --git a/src/report.hpp b/src/report.hpp
@@ -23,25 +23,41 @@
#include <sstream>
class Transaction;
+class Version;
-class Report : public Dialog {
+class ReportDialog : public Dialog {
public:
- Report(Transaction *);
+ ReportDialog();
protected:
void onInit() override;
- void onCommand(int) override;
+
+ virtual void fillReport() = 0;
+
+ static const char * const NL;
+ std::ostringstream &stream() { return m_stream; }
+
+ void printHeader(const char *);
+ void printChangelog(const std::string &);
+
+private:
+ std::ostringstream m_stream;
+};
+
+class Report : public ReportDialog {
+public:
+ Report(Transaction *);
+
+protected:
+ void fillReport() override;
private:
void printNewPackages();
void printUpdates();
void printErrors();
void printRemovals();
- void printChangelog(const std::string &);
- void printHeader(const char *);
Transaction *m_transaction;
- std::ostringstream m_stream;
};
#endif