commit 76ba324156336015937bf3a27397766c20eac191
parent e70477c00758909ef539c056f9bb1f5eb98420a3
Author: cfillion <cfillion@users.noreply.github.com>
Date: Wed, 6 Sep 2017 01:13:27 -0700
abstract away most of the UTF-8 to UTF-16 conversion for Windows
Diffstat:
41 files changed, 690 insertions(+), 699 deletions(-)
diff --git a/src/about.cpp b/src/about.cpp
@@ -19,7 +19,6 @@
#include "browser.hpp"
#include "config.hpp"
-#include "encoding.hpp"
#include "errors.hpp"
#include "filesystem.hpp"
#include "index.hpp"
@@ -34,10 +33,10 @@
#include "richedit.hpp"
#include "tabbar.hpp"
#include "transaction.hpp"
+#include "win32.hpp"
#include <boost/algorithm/string.hpp>
#include <iomanip>
-#include <sstream>
using namespace std;
@@ -171,15 +170,14 @@ void About::setDelegate(const DelegatePtr &delegate, const bool focus)
void About::setTitle(const string &what)
{
- auto_char title[255];
- auto_snprintf(title, auto_size(title),
- AUTO_STR("About %s"), make_autostring(what).c_str());
- SetWindowText(handle(), title);
+ char title[255];
+ snprintf(title, sizeof(title), "About %s", what.c_str());
+ Win32::setWindowText(handle(), title);
}
void About::setMetadata(const Metadata *metadata, const bool substitution)
{
- string aboutText = metadata->about();
+ string aboutText(metadata->about());
if(substitution) {
boost::replace_all(aboutText, "[[REAPACK_VERSION]]", ReaPack::VERSION);
@@ -187,7 +185,7 @@ void About::setMetadata(const Metadata *metadata, const bool substitution)
}
if(m_desc->setRichText(aboutText))
- m_tabs->addTab({AUTO_STR("About"), {m_desc->handle()}});
+ m_tabs->addTab({"About", {m_desc->handle()}});
const auto &getLinkControl = [](const Metadata::LinkType type) {
switch(type) {
@@ -232,7 +230,7 @@ void About::setMetadata(const Metadata *metadata, const bool substitution)
void About::setAction(const string &label)
{
HWND btn = getControl(IDC_ACTION);
- SetWindowText(btn, make_autostring(label).c_str());
+ Win32::setWindowText(btn, label.c_str());
show(btn);
}
@@ -244,7 +242,7 @@ void About::selectLink(const int ctrl)
m_tabs->setFocus();
if(count == 1) {
- openURL(links.front()->url);
+ Win32::shellExecute(links.front()->url.c_str());
return;
}
@@ -252,13 +250,13 @@ void About::selectLink(const int ctrl)
for(int i = 0; i < count; i++) {
const string &name = boost::replace_all_copy(links[i]->name, "&", "&&");
- menu.addAction(make_autostring(name).c_str(), i | (ctrl << 8));
+ menu.addAction(name.c_str(), i | (ctrl << 8));
}
const int choice = menu.show(getControl(ctrl), handle());
if(choice >> 8 == ctrl)
- openURL(links[choice & 0xff]->url);
+ Win32::shellExecute(links[choice & 0xff]->url.c_str());
}
void About::updateList()
@@ -291,29 +289,29 @@ void AboutIndexDelegate::init(About *dialog)
dialog->setMetadata(m_index->metadata(), m_index->name() == "ReaPack");
dialog->setAction("Install/update " + m_index->name());
- dialog->tabs()->addTab({AUTO_STR("Packages"),
+ dialog->tabs()->addTab({"Packages",
{dialog->menu()->handle(), dialog->list()->handle()}});
- dialog->tabs()->addTab({AUTO_STR("Installed Files"),
+ dialog->tabs()->addTab({"Installed Files",
{dialog->getControl(IDC_REPORT)}});
- dialog->menu()->addColumn({AUTO_STR("Category"), 142});
+ dialog->menu()->addColumn({"Category", 142});
dialog->menu()->reserveRows(m_index->categories().size() + 1);
- dialog->menu()->createRow()->setCell(0, AUTO_STR("<All Packages>"));
+ dialog->menu()->createRow()->setCell(0, "<All Packages>");
for(const Category *cat : m_index->categories())
- dialog->menu()->createRow()->setCell(0, make_autostring(cat->name()));
+ dialog->menu()->createRow()->setCell(0, cat->name());
- dialog->list()->addColumn({AUTO_STR("Package"), 382});
- dialog->list()->addColumn({AUTO_STR("Version"), 80, 0, ListView::VersionType});
- dialog->list()->addColumn({AUTO_STR("Author"), 90});
+ dialog->list()->addColumn({"Package", 382});
+ dialog->list()->addColumn({"Version", 80, 0, ListView::VersionType});
+ dialog->list()->addColumn({"Author", 90});
initInstalledFiles();
}
void AboutIndexDelegate::initInstalledFiles()
{
- HWND report = m_dialog->getControl(IDC_REPORT);
+ const HWND report = m_dialog->getControl(IDC_REPORT);
set<Registry::File> allFiles;
@@ -325,24 +323,21 @@ void AboutIndexDelegate::initInstalledFiles()
}
}
catch(const reapack_error &e) {
- const auto_string &desc = make_autostring(e.what());
- auto_char msg[255];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("The file list is currently unavailable.\x20")
- AUTO_STR("Retry later when all installation task are completed.\r\n")
- AUTO_STR("\r\nError description: %s"),
- desc.c_str());
- SetWindowText(report, msg);
+ char msg[255];
+ snprintf(msg, sizeof(msg),
+ "The file list is currently unavailable.\x20"
+ "Retry later when all installation task are completed.\r\n"
+ "\r\nError description: %s", e.what());
+ Win32::setWindowText(report, msg);
return;
}
if(allFiles.empty()) {
- SetWindowText(report,
- AUTO_STR(
- "This repository does not own any file on your computer at this time.\r\n")
+ Win32::setWindowText(report,
+ "This repository does not own any file on your computer at this time.\r\n"
- AUTO_STR("It is either not yet installed or it does not provide ")
- AUTO_STR("any package compatible with your system."));
+ "It is either not yet installed or it does not provide "
+ "any package compatible with your system.");
}
else {
stringstream stream;
@@ -354,7 +349,7 @@ void AboutIndexDelegate::initInstalledFiles()
stream << "\r\n";
}
- SetWindowText(report, make_autostring(stream.str()).c_str());
+ Win32::setWindowText(report, stream.str().c_str());
}
}
@@ -377,9 +372,9 @@ void AboutIndexDelegate::updateList(const int index)
const Version *lastVer = pkg->lastVersion();
auto row = m_dialog->list()->createRow((void *)pkg);
- row->setCell(c++, make_autostring(pkg->displayName()));
- row->setCell(c++, make_autostring(lastVer->name().toString()), (void *)&lastVer->name());
- row->setCell(c++, make_autostring(lastVer->displayAuthor()));
+ row->setCell(c++, pkg->displayName());
+ row->setCell(c++, lastVer->name().toString(), (void *)&lastVer->name());
+ row->setCell(c++, lastVer->displayAuthor());
}
}
@@ -388,8 +383,8 @@ bool AboutIndexDelegate::fillContextMenu(Menu &menu, const int index) const
if(index < 0)
return false;
- menu.addAction(AUTO_STR("Find in the &browser"), ACTION_FIND_IN_BROWSER);
- menu.addAction(AUTO_STR("About this &package"), ACTION_ABOUT_PKG);
+ menu.addAction("Find in the &browser", ACTION_FIND_IN_BROWSER);
+ menu.addAction("About this &package", ACTION_ABOUT_PKG);
return true;
}
@@ -458,8 +453,8 @@ void AboutIndexDelegate::install()
enum { INSTALL_ALL = 80, UPDATE_ONLY };
Menu menu;
- menu.addAction(AUTO_STR("Install all packages in this repository"), INSTALL_ALL);
- menu.addAction(AUTO_STR("Update installed packages only"), UPDATE_ONLY);
+ menu.addAction("Install all packages in this repository", INSTALL_ALL);
+ menu.addAction("Update installed packages only", UPDATE_ONLY);
const int choice = menu.show(m_dialog->getControl(IDC_ACTION), m_dialog->handle());
@@ -470,9 +465,9 @@ void AboutIndexDelegate::install()
if(!remote) {
// In case the user uninstalled the repository while this dialog was opened
- MessageBox(m_dialog->handle(),
- AUTO_STR("This repository cannot be found in your current configuration."),
- AUTO_STR("ReaPack"), MB_OK);
+ Win32::messageBox(m_dialog->handle(),
+ "This repository cannot be found in your current configuration.",
+ "ReaPack", MB_OK);
return;
}
@@ -480,12 +475,12 @@ void AboutIndexDelegate::install()
if(choice == INSTALL_ALL && boost::logic::indeterminate(remote.autoInstall())
&& !installOpts.autoInstall) {
- const int btn = MessageBox(m_dialog->handle(),
- AUTO_STR("Do you want ReaPack to install new packages from this repository")
- AUTO_STR(" when synchronizing in the future?\r\n\r\nThis setting can also be")
- AUTO_STR(" customized globally or on a per-repository basis in")
- AUTO_STR(" ReaPack > Manage repositories."),
- AUTO_STR("Install all packages in this repository"), MB_YESNOCANCEL);
+ const int btn = Win32::messageBox(m_dialog->handle(),
+ "Do you want ReaPack to install new packages from this repository"
+ " when synchronizing in the future?\r\n\r\nThis setting can also be"
+ " customized globally or on a per-repository basis in"
+ " ReaPack > Manage repositories.",
+ "Install all packages in this repository", MB_YESNOCANCEL);
switch(btn) {
case IDYES:
@@ -523,21 +518,21 @@ void AboutPackageDelegate::init(About *dialog)
dialog->setMetadata(m_package->metadata());
dialog->setAction("About " + m_index->name());
- dialog->tabs()->addTab({AUTO_STR("History"),
+ dialog->tabs()->addTab({"History",
{dialog->menu()->handle(), dialog->getControl(IDC_CHANGELOG)}});
- dialog->tabs()->addTab({AUTO_STR("Contents"),
+ dialog->tabs()->addTab({"Contents",
{dialog->menu()->handle(), dialog->list()->handle()}});
- dialog->menu()->addColumn({AUTO_STR("Version"), 142, 0, ListView::VersionType});
+ dialog->menu()->addColumn({"Version", 142, 0, ListView::VersionType});
- dialog->list()->addColumn({AUTO_STR("File"), 474});
- dialog->list()->addColumn({AUTO_STR("Action List"), 84});
+ dialog->list()->addColumn({"File", 474});
+ dialog->list()->addColumn({"Action List", 84});
dialog->menu()->reserveRows(m_package->versions().size());
for(const Version *ver : m_package->versions()) {
auto row = dialog->menu()->createRow();
- row->setCell(0, make_autostring(ver->name().toString()), (void *)&ver->name());
+ row->setCell(0, ver->name().toString(), (void *)&ver->name());
if(m_current == ver->name())
dialog->menu()->select(row->index());
@@ -563,10 +558,10 @@ void AboutPackageDelegate::updateList(const int index)
const Version *ver = m_package->version(index);
OutputStream stream;
stream << *ver;
- SetWindowText(m_dialog->getControl(IDC_CHANGELOG),
- make_autostring(stream.str()).c_str());
+ Win32::setWindowText(m_dialog->getControl(IDC_CHANGELOG), stream.str().c_str());
m_dialog->list()->reserveRows(ver->sources().size());
+
for(const Source *src : ver->sources()) {
int sections = src->sections();
string actionList;
@@ -593,8 +588,8 @@ void AboutPackageDelegate::updateList(const int index)
int c = 0;
auto row = m_dialog->list()->createRow((void *)src);
- row->setCell(c++, make_autostring(src->targetPath().join()));
- row->setCell(c++, make_autostring(actionList));
+ row->setCell(c++, src->targetPath().join());
+ row->setCell(c++, actionList);
}
}
@@ -605,9 +600,9 @@ bool AboutPackageDelegate::fillContextMenu(Menu &menu, const int index) const
auto src = (const Source *)m_dialog->list()->row(index)->userData;
- menu.addAction(AUTO_STR("Copy source URL"), ACTION_COPY_URL);
+ menu.addAction("Copy source URL", ACTION_COPY_URL);
menu.setEnabled(m_current.size() > 0 && FS::exists(src->targetPath()),
- menu.addAction(AUTO_STR("Locate in explorer/finder"), ACTION_LOCATE));
+ menu.addAction("Locate in explorer/finder", ACTION_LOCATE));
return true;
}
@@ -651,11 +646,10 @@ void AboutPackageDelegate::locate()
if(!FS::exists(path))
return;
- string arg = "/select,\"";
+ string arg("/select,\"");
arg += Path::prefixRoot(path).join();
arg += '"';
- ShellExecute(nullptr, AUTO_STR("open"), AUTO_STR("explorer.exe"),
- make_autostring(arg).c_str(), nullptr, SW_SHOW);
+ Win32::shellExecute("explorer.exe", arg.c_str());
}
}
diff --git a/src/archive.cpp b/src/archive.cpp
@@ -24,6 +24,7 @@
#include "path.hpp"
#include "reapack.hpp"
#include "transaction.hpp"
+#include "win32.hpp"
#include <boost/format.hpp>
#include <fstream>
@@ -34,10 +35,10 @@
#include <zlib/unzip.h>
#include <zlib/ioapi.h>
-using namespace boost;
+using boost::format;
using namespace std;
-static const Path ARCHIVE_TOC = Path("toc");
+static const Path ARCHIVE_TOC("toc");
static const size_t BUFFER_SIZE = 4096;
#ifdef _WIN32
@@ -54,8 +55,10 @@ static void *wide_fopen(voidpf, const void *filename, int mode)
FILE *file = nullptr;
- if(filename && fopen_mode)
- _wfopen_s(&file, static_cast<const wchar_t *>(filename), fopen_mode);
+ if(filename && fopen_mode) {
+ const auto &&wideFilename = Win32::widen(static_cast<const char *>(filename));
+ _wfopen_s(&file, wideFilename.c_str(), fopen_mode);
+ }
return file;
}
@@ -71,7 +74,7 @@ struct ImportArchive {
IndexPtr m_lastIndex;
};
-void Archive::import(const auto_string &path)
+void Archive::import(const string &path)
{
ImportArchive state{make_shared<ArchiveReader>(path),
&g_reapack->config()->remotes};
@@ -105,7 +108,7 @@ void Archive::import(const auto_string &path)
}
}
catch(const reapack_error &e) {
- state.m_tx->receipt()->addError({e.what(), from_autostring(path)});
+ state.m_tx->receipt()->addError({e.what(), path});
}
}
@@ -152,15 +155,15 @@ void ImportArchive::importPackage(const string &data)
const Version *ver = pkg ? pkg->findVersion(versionName) : nullptr;
if(!ver) {
- throw reapack_error(format("%s/%s/%s v%s cannot be found or is"
- " incompatible with your operating system.")
+ throw reapack_error(format(
+ "%s/%s/%s v%s cannot be found or is incompatible with your operating system.")
% m_lastIndex->name() % categoryName % packageName % versionName);
}
m_tx->install(ver, pinned, m_reader);
}
-ArchiveReader::ArchiveReader(const auto_string &path)
+ArchiveReader::ArchiveReader(const string &path)
{
zlib_filefunc64_def filefunc;
fill_fopen64_filefunc(&filefunc);
@@ -168,10 +171,10 @@ ArchiveReader::ArchiveReader(const auto_string &path)
filefunc.zopen64_file = wide_fopen;
#endif
- m_zip = unzOpen2_64(reinterpret_cast<const char *>(path.c_str()), &filefunc);
+ m_zip = unzOpen2_64(path.c_str(), &filefunc);
if(!m_zip)
- throw reapack_error(FS::lastError().c_str());
+ throw reapack_error(FS::lastError());
}
ArchiveReader::~ArchiveReader()
@@ -241,7 +244,7 @@ bool FileExtractor::run()
return true;
}
-size_t Archive::create(const auto_string &path, vector<string> *errors,
+size_t Archive::create(const string &path, vector<string> *errors,
ThreadPool *pool)
{
size_t count = 0;
@@ -296,7 +299,7 @@ size_t Archive::create(const auto_string &path, vector<string> *errors,
return count;
}
-ArchiveWriter::ArchiveWriter(const auto_string &path)
+ArchiveWriter::ArchiveWriter(const string &path)
{
zlib_filefunc64_def filefunc;
fill_fopen64_filefunc(&filefunc);
@@ -304,11 +307,10 @@ ArchiveWriter::ArchiveWriter(const auto_string &path)
filefunc.zopen64_file = wide_fopen;
#endif
- m_zip = zipOpen2_64(reinterpret_cast<const char *>(path.c_str()),
- APPEND_STATUS_CREATE, nullptr, &filefunc);
+ m_zip = zipOpen2_64(path.c_str(), APPEND_STATUS_CREATE, nullptr, &filefunc);
if(!m_zip)
- throw reapack_error(FS::lastError().c_str());
+ throw reapack_error(FS::lastError());
}
ArchiveWriter::~ArchiveWriter()
diff --git a/src/archive.hpp b/src/archive.hpp
@@ -18,7 +18,6 @@
#ifndef REAPACK_ARCHIVE_HPP
#define REAPACK_ARCHIVE_HPP
-#include "encoding.hpp"
#include "path.hpp"
#include "thread.hpp"
@@ -27,14 +26,13 @@ class ThreadPool;
typedef void *zipFile;
namespace Archive {
- void import(const auto_string &path);
- size_t create(const auto_string &path,
- std::vector<std::string> *errors, ThreadPool *pool);
+ void import(const std::string &path);
+ size_t create(const std::string &path, std::vector<std::string> *errors, ThreadPool *pool);
};
class ArchiveReader {
public:
- ArchiveReader(const auto_string &path);
+ ArchiveReader(const std::string &path);
~ArchiveReader();
int extractFile(const Path &);
int extractFile(const Path &, std::ostream &) noexcept;
@@ -47,7 +45,7 @@ typedef std::shared_ptr<ArchiveReader> ArchiveReaderPtr;
class ArchiveWriter {
public:
- ArchiveWriter(const auto_string &path);
+ ArchiveWriter(const std::string &path);
~ArchiveWriter();
int addFile(const Path &fn);
int addFile(const Path &fn, std::istream &) noexcept;
diff --git a/src/browser.cpp b/src/browser.cpp
@@ -20,7 +20,6 @@
#include "about.hpp"
#include "browser_entry.hpp"
#include "config.hpp"
-#include "encoding.hpp"
#include "errors.hpp"
#include "index.hpp"
#include "listview.hpp"
@@ -28,6 +27,7 @@
#include "reapack.hpp"
#include "resource.hpp"
#include "transaction.hpp"
+#include "win32.hpp"
using namespace std;
@@ -50,23 +50,23 @@ void Browser::onInit()
disable(m_actionsBtn);
// don't forget to update order of enum View in header file
- SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("All"));
- SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Queued"));
- SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Installed"));
- SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Out of date"));
- SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Obsolete"));
- SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)AUTO_STR("Uninstalled"));
+ SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)L("All"));
+ SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)L("Queued"));
+ SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)L("Installed"));
+ SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)L("Out of date"));
+ SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)L("Obsolete"));
+ SendMessage(m_view, CB_ADDSTRING, 0, (LPARAM)L("Uninstalled"));
SendMessage(m_view, CB_SETCURSEL, 0, 0);
m_list = createControl<ListView>(IDC_LIST, ListView::Columns{
- {AUTO_STR("Status"), 23, ListView::NoLabelFlag},
- {AUTO_STR("Package"), 345},
- {AUTO_STR("Category"), 105},
- {AUTO_STR("Version"), 55, 0, ListView::VersionType},
- {AUTO_STR("Author"), 95},
- {AUTO_STR("Type"), 70},
- {AUTO_STR("Repository"), 120, ListView::CollapseFlag},
- {AUTO_STR("Last Update"), 105, 0, ListView::TimeType},
+ {"Status", 23, ListView::NoLabelFlag},
+ {"Package", 345},
+ {"Category", 105},
+ {"Version", 55, 0, ListView::VersionType},
+ {"Author", 95},
+ {"Type", 70},
+ {"Repository", 120, ListView::CollapseFlag},
+ {"Last Update", 105, 0, ListView::TimeType},
});
m_list->onActivate([=] { aboutPackage(m_list->itemUnderMouse()); });
@@ -249,8 +249,8 @@ bool Browser::fillContextMenu(Menu &menu, const int index)
if(!menu.empty())
menu.addSeparator();
- menu.addAction(AUTO_STR("&Select all"), IDC_SELECT);
- menu.addAction(AUTO_STR("&Unselect all"), IDC_UNSELECT);
+ menu.addAction("&Select all", IDC_SELECT);
+ menu.addAction("&Unselect all", IDC_UNSELECT);
return true;
}
@@ -260,14 +260,14 @@ void Browser::fillMenu(Menu &menu)
const Entry *entry = getEntry(m_currentIndex);
if(m_list->selectionSize() > 1) {
- menu.addAction(AUTO_STR("&Install/update selection"), ACTION_LATEST_ALL);
- menu.addAction(AUTO_STR("&Reinstall selection"), ACTION_REINSTALL_ALL);
- menu.addAction(AUTO_STR("&Uninstall selection"), ACTION_UNINSTALL_ALL);
- menu.addAction(AUTO_STR("&Clear queued actions"), ACTION_RESET_ALL);
+ menu.addAction("&Install/update selection", ACTION_LATEST_ALL);
+ menu.addAction("&Reinstall selection", ACTION_REINSTALL_ALL);
+ menu.addAction("&Uninstall selection", ACTION_UNINSTALL_ALL);
+ menu.addAction("&Clear queued actions", ACTION_RESET_ALL);
menu.addSeparator();
if(entry) {
- Menu pkgMenu = menu.addMenu(AUTO_STR("Package under cursor"));
+ Menu pkgMenu = menu.addMenu("Package under cursor");
entry->fillMenu(pkgMenu);
}
}
@@ -277,32 +277,32 @@ void Browser::fillMenu(Menu &menu)
void Browser::updateDisplayLabel()
{
- auto_char btnLabel[32];
- auto_snprintf(btnLabel, auto_size(btnLabel), AUTO_STR("%d/%zu package%s..."),
+ char btnLabel[32];
+ snprintf(btnLabel, sizeof(btnLabel), "%d/%zu package%s...",
m_list->rowCount(), m_entries.size(),
- m_entries.size() == 1 ? AUTO_STR("") : AUTO_STR("s"));
+ m_entries.size() == 1 ? "" : "s");
- SetWindowText(m_displayBtn, btnLabel);
+ Win32::setWindowText(m_displayBtn, btnLabel);
}
void Browser::displayButton()
{
- static map<const auto_char *, Package::Type> types = {
- {AUTO_STR("&Scripts"), Package::ScriptType},
- {AUTO_STR("&Effects"), Package::EffectType},
- {AUTO_STR("E&xtensions"), Package::ExtensionType},
- {AUTO_STR("&Themes"), Package::ThemeType},
- {AUTO_STR("&Language Packs"), Package::LangPackType},
- {AUTO_STR("&Web Interfaces"), Package::WebInterfaceType},
- {AUTO_STR("&Project Templates"), Package::ProjectTemplateType},
- {AUTO_STR("&Track Templates"), Package::TrackTemplateType},
- {AUTO_STR("&MIDI Note Names"), Package::MIDINoteNamesType},
- {AUTO_STR("&Other packages"), Package::UnknownType},
+ static map<const char *, Package::Type> types = {
+ {"&Scripts", Package::ScriptType},
+ {"&Effects", Package::EffectType},
+ {"E&xtensions", Package::ExtensionType},
+ {"&Themes", Package::ThemeType},
+ {"&Language Packs", Package::LangPackType},
+ {"&Web Interfaces", Package::WebInterfaceType},
+ {"&Project Templates", Package::ProjectTemplateType},
+ {"&Track Templates", Package::TrackTemplateType},
+ {"&MIDI Note Names", Package::MIDINoteNamesType},
+ {"&Other packages", Package::UnknownType},
};
Menu menu;
- auto index = menu.addAction(AUTO_STR("&All packages"), ACTION_FILTERTYPE);
+ auto index = menu.addAction("&All packages", ACTION_FILTERTYPE);
if(!m_typeFilter)
menu.checkRadio(index);
@@ -316,8 +316,8 @@ void Browser::displayButton()
menu.addSeparator();
- menu.addAction(AUTO_STR("&Refresh repositories"), ACTION_REFRESH);
- menu.addAction(AUTO_STR("&Manage repositories..."), ACTION_MANAGE);
+ menu.addAction("&Refresh repositories", ACTION_REFRESH);
+ menu.addAction("&Manage repositories...", ACTION_MANAGE);
menu.show(m_displayBtn, handle());
}
@@ -360,7 +360,7 @@ void Browser::updateFilter()
{
stopTimer(TIMER_FILTER);
- const string &filter = getText(m_filterHandle);
+ const string &filter = Win32::getWindowText(m_filterHandle);
if(m_filter != filter) {
m_filter = filter;
@@ -404,10 +404,9 @@ void Browser::refresh(const bool stale)
if(!isVisible() || stale) {
show();
- MessageBox(handle(), AUTO_STR("No repository enabled!\r\n")
- AUTO_STR("Enable or import repositories from ")
- AUTO_STR("Extensions > ReaPack > Manage repositories."),
- AUTO_STR("Browse packages"), MB_OK);
+ Win32::messageBox(handle(), "No repository enabled!\r\n"
+ "Enable or import repositories from Extensions > ReaPack > Manage repositories.",
+ "Browse packages", MB_OK);
}
populate({});
@@ -434,7 +433,7 @@ void Browser::refresh(const bool stale)
void Browser::setFilter(const string &newFilter)
{
- SetWindowText(m_filterHandle, make_autostring(newFilter).c_str());
+ Win32::setWindowText(m_filterHandle, newFilter.c_str());
updateFilter(); // don't wait for the timer, update now!
SetFocus(m_filterHandle);
}
@@ -465,14 +464,12 @@ void Browser::populate(const vector<IndexPtr> &indexes)
fillList();
}
catch(const reapack_error &e) {
- const auto_string &desc = make_autostring(e.what());
- auto_char msg[255];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("ReaPack could not read from the local package registry.\r\n")
- AUTO_STR("Retry later once all installation task are completed.\r\n")
- AUTO_STR("\r\nError description: %s"),
- desc.c_str());
- MessageBox(handle(), msg, AUTO_STR("ReaPack"), MB_OK);
+ char msg[255];
+ snprintf(msg, sizeof(msg),
+ "ReaPack could not read from the local package registry.\r\n"
+ "Retry later once all installation task are completed.\r\n"
+ "\r\nError description: %s", e.what());
+ Win32::messageBox(handle(), msg, "ReaPack", MB_OK);
}
if(!isVisible())
@@ -617,12 +614,11 @@ void Browser::installLatestAll()
const bool isEverything = (size_t)m_list->selectionSize() == m_entries.size();
if(isEverything && !installOpts.autoInstall) {
- const int btn = MessageBox(handle(),
- AUTO_STR("Do you want ReaPack to install new packages automatically when")
- AUTO_STR(" synchronizing in the future?\r\n\r\nThis setting can also be")
- AUTO_STR(" customized globally or on a per-repository basis in")
- AUTO_STR(" ReaPack > Manage repositories."),
- AUTO_STR("Install every available packages"), MB_YESNOCANCEL);
+ const int btn = Win32::messageBox(handle(), "Do you want ReaPack to install new packages"
+ " automatically when synchronizing in the future?\r\n\r\nThis setting"
+ " can also be customized globally or on a per-repository basis in"
+ " ReaPack > Manage repositories.",
+ "Install every available packages", MB_YESNOCANCEL);
switch(btn) {
case IDYES:
@@ -753,7 +749,7 @@ void Browser::updateAction(const int index)
updateDisplayLabel();
}
else
- m_list->row(index)->setCell(0, make_autostring(entry->displayState()));
+ m_list->row(index)->setCell(0, entry->displayState());
if(m_actions.empty())
disable(m_applyBtn);
@@ -798,15 +794,13 @@ bool Browser::confirm() const
if(!count)
return true;
- auto_char msg[255];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("Are you sure to uninstall %zu package%s?\r\nThe files and settings will be permanently deleted from this computer."),
- count, count == 1 ? AUTO_STR("") : AUTO_STR("s"));
+ char msg[255];
+ snprintf(msg, sizeof(msg),
+ "Are you sure to uninstall %zu package%s?\r\nThe files and settings will"
+ " be permanently deleted from this computer.",
+ count, count == 1 ? "" : "s");
- const auto_char *title = AUTO_STR("ReaPack Query");
- const int btn = MessageBox(handle(), msg, title, MB_YESNO);
-
- return btn == IDYES;
+ return IDYES == Win32::messageBox(handle(), msg, "ReaPack Query", MB_YESNO);
}
bool Browser::apply()
diff --git a/src/browser_entry.cpp b/src/browser_entry.cpp
@@ -156,34 +156,32 @@ void Browser::Entry::updateRow(const ListView::RowPtr &row) const
int c = 0;
const Time *time = lastUpdate();
- row->setCell(c++, make_autostring(displayState()));
- row->setCell(c++, make_autostring(displayName()));
- row->setCell(c++, make_autostring(categoryName()));
- row->setCell(c++, make_autostring(displayVersion()), (void *)sortVersion());
- row->setCell(c++, make_autostring(displayAuthor()));
- row->setCell(c++, make_autostring(displayType()));
- row->setCell(c++, make_autostring(indexName()));
- row->setCell(c++, time ? make_autostring(time->toString()) : auto_string(), (void *)time);
+ row->setCell(c++, displayState());
+ row->setCell(c++, displayName());
+ row->setCell(c++, categoryName());
+ row->setCell(c++, displayVersion(), (void *)sortVersion());
+ row->setCell(c++, displayAuthor());
+ row->setCell(c++, displayType());
+ row->setCell(c++, indexName());
+ row->setCell(c++, time ? time->toString() : string(), (void *)time);
}
void Browser::Entry::fillMenu(Menu &menu) const
{
if(test(InstalledFlag)) {
if(test(OutOfDateFlag)) {
- auto_char installLabel[32];
- auto_snprintf(installLabel, auto_size(installLabel),
- AUTO_STR("U&pdate to v%s"),
- make_autostring(latest->name().toString()).c_str());
+ char installLabel[32];
+ snprintf(installLabel, sizeof(installLabel),
+ "U&pdate to v%s", latest->name().toString().c_str());
const UINT actionIndex = menu.addAction(installLabel, ACTION_LATEST);
if(target && *target == latest)
menu.check(actionIndex);
}
- auto_char reinstallLabel[32];
- auto_snprintf(reinstallLabel, auto_size(reinstallLabel),
- AUTO_STR("&Reinstall v%s"),
- make_autostring(regEntry.version.toString()).c_str());
+ char reinstallLabel[32];
+ snprintf(reinstallLabel, sizeof(reinstallLabel),
+ "&Reinstall v%s", regEntry.version.toString().c_str());
const UINT actionIndex = menu.addAction(reinstallLabel, ACTION_REINSTALL);
if(!current || test(ObsoleteFlag))
@@ -192,17 +190,16 @@ void Browser::Entry::fillMenu(Menu &menu) const
menu.check(actionIndex);
}
else {
- auto_char installLabel[32];
- auto_snprintf(installLabel, auto_size(installLabel),
- AUTO_STR("&Install v%s"),
- make_autostring(latest->name().toString()).c_str());
+ char installLabel[32];
+ snprintf(installLabel, sizeof(installLabel),
+ "&Install v%s", latest->name().toString().c_str());
const UINT actionIndex = menu.addAction(installLabel, ACTION_LATEST);
if(target && *target == latest)
menu.check(actionIndex);
}
- Menu versionMenu = menu.addMenu(AUTO_STR("Versions"));
+ Menu versionMenu = menu.addMenu("Versions");
const UINT versionMenuIndex = menu.size() - 1;
if(test(ObsoleteFlag))
menu.disable(versionMenuIndex);
@@ -211,8 +208,7 @@ void Browser::Entry::fillMenu(Menu &menu) const
int verIndex = (int)versions.size();
for(const Version *ver : versions | boost::adaptors::reversed) {
const UINT actionIndex = versionMenu.addAction(
- make_autostring(ver->name().toString()).c_str(),
- --verIndex | (ACTION_VERSION << 8));
+ ver->name().toString().c_str(), --verIndex | (ACTION_VERSION << 8));
if(target ? *target == ver : ver == current) {
if(target && ver != latest)
@@ -223,15 +219,13 @@ void Browser::Entry::fillMenu(Menu &menu) const
}
}
- const UINT pinIndex = menu.addAction(
- AUTO_STR("&Pin current version"), ACTION_PIN);
+ const UINT pinIndex = menu.addAction("&Pin current version", ACTION_PIN);
if(!canPin())
menu.disable(pinIndex);
if(pin.value_or(regEntry.pinned))
menu.check(pinIndex);
- const UINT uninstallIndex =
- menu.addAction(AUTO_STR("&Uninstall"), ACTION_UNINSTALL);
+ const UINT uninstallIndex = menu.addAction("&Uninstall", ACTION_UNINSTALL);
if(!test(InstalledFlag) || remote().isProtected())
menu.disable(uninstallIndex);
else if(target && *target == nullptr)
@@ -240,12 +234,10 @@ void Browser::Entry::fillMenu(Menu &menu) const
menu.addSeparator();
menu.setEnabled(!test(ObsoleteFlag),
- menu.addAction(AUTO_STR("About this &package"), ACTION_ABOUT_PKG));
+ menu.addAction("About this &package", ACTION_ABOUT_PKG));
- auto_char aboutLabel[64];
- const auto_string &name = make_autostring(indexName());
- auto_snprintf(aboutLabel, auto_size(aboutLabel),
- AUTO_STR("&About %s"), name.c_str());
+ char aboutLabel[64];
+ snprintf(aboutLabel, sizeof(aboutLabel), "&About %s", indexName().c_str());
menu.addAction(aboutLabel, ACTION_ABOUT_REMOTE);
}
diff --git a/src/config.cpp b/src/config.cpp
@@ -18,6 +18,7 @@
#include "config.hpp"
#include "path.hpp"
+#include "win32.hpp"
#ifdef _WIN32
# include <windows.h>
@@ -27,37 +28,35 @@
using namespace std;
-static const auto_char *GENERAL_GRP = AUTO_STR("general");
-static const auto_char *VERSION_KEY = AUTO_STR("version");
+static const char *GENERAL_GRP = "general";
+static const char *VERSION_KEY = "version";
-static const auto_char *INSTALL_GRP = AUTO_STR("install");
-static const auto_char *AUTOINSTALL_KEY = AUTO_STR("autoinstall");
-static const auto_char *PRERELEASES_KEY = AUTO_STR("prereleases");
-static const auto_char *PROMPTOBSOLETE_KEY = AUTO_STR("promptobsolete");
+static const char *INSTALL_GRP = "install";
+static const char *AUTOINSTALL_KEY = "autoinstall";
+static const char *PRERELEASES_KEY = "prereleases";
+static const char *PROMPTOBSOLETE_KEY = "promptobsolete";
-static const auto_char *ABOUT_GRP = AUTO_STR("about");
-static const auto_char *MANAGER_GRP = AUTO_STR("manager");
+static const char *ABOUT_GRP = "about";
+static const char *MANAGER_GRP = "manager";
-static const auto_char *BROWSER_GRP = AUTO_STR("browser");
-static const auto_char *STATE_KEY = AUTO_STR("state");
+static const char *BROWSER_GRP = "browser";
+static const char *STATE_KEY = "state";
-static const auto_char *NETWORK_GRP = AUTO_STR("network");
-static const auto_char *PROXY_KEY = AUTO_STR("proxy");
-static const auto_char *VERIFYPEER_KEY = AUTO_STR("verifypeer");
-static const auto_char *STALETHRSH_KEY = AUTO_STR("stalethreshold");
+static const char *NETWORK_GRP = "network";
+static const char *PROXY_KEY = "proxy";
+static const char *VERIFYPEER_KEY = "verifypeer";
+static const char *STALETHRSH_KEY = "stalethreshold";
-static const auto_char *SIZE_KEY = AUTO_STR("size");
+static const char *SIZE_KEY = "size";
-static const auto_char *REMOTES_GRP = AUTO_STR("remotes");
-static const auto_char *REMOTE_KEY = AUTO_STR("remote");
+static const char *REMOTES_GRP = "remotes";
+static const char *REMOTE_KEY = "remote";
-static auto_string ArrayKey(const auto_string &key, const unsigned int i)
+inline static string nKey(const char *key, const unsigned int i)
{
- return key + to_autostring(i);
+ return key + to_string(i);
}
-static const int BUFFER_SIZE = 2083;
-
Config::Config()
: m_isFirstRun(false), m_version(0), m_remotesIniSize(0)
{
@@ -133,7 +132,7 @@ void Config::migrate()
void Config::read(const Path &path)
{
- m_path = make_autostring(path.join());
+ m_path = path.join();
install.autoInstall = getBool(INSTALL_GRP, AUTOINSTALL_KEY, install.autoInstall);
install.bleedingEdge = getBool(INSTALL_GRP, PRERELEASES_KEY, install.bleedingEdge);
@@ -178,7 +177,7 @@ void Config::readRemotes()
m_remotesIniSize = getUInt(REMOTES_GRP, SIZE_KEY);
for(unsigned int i = 0; i < m_remotesIniSize; i++) {
- const string data = getString(REMOTES_GRP, ArrayKey(REMOTE_KEY, i));
+ const string data = getString(REMOTES_GRP, nKey(REMOTE_KEY, i).c_str());
remotes.add(Remote::fromString(data));
}
@@ -190,56 +189,47 @@ void Config::writeRemotes()
unsigned int i = 0;
for(auto it = remotes.begin(); it != remotes.end(); it++, i++)
- setString(REMOTES_GRP, ArrayKey(REMOTE_KEY, i), it->toString());
+ setString(REMOTES_GRP, nKey(REMOTE_KEY, i).c_str(), it->toString());
cleanupArray(REMOTES_GRP, REMOTE_KEY, i, m_remotesIniSize);
setUInt(REMOTES_GRP, SIZE_KEY, m_remotesIniSize = i);
}
-string Config::getString(const auto_char *group,
- const auto_string &key, const string &fallback) const
+string Config::getString(const char *group, const char *key, const string &fallback) const
{
- auto_char buffer[BUFFER_SIZE];
- GetPrivateProfileString(group, key.c_str(), make_autostring(fallback).c_str(),
- buffer, sizeof(buffer), m_path.c_str());
-
- return from_autostring(buffer);
+ return Win32::getPrivateProfileString(group, key, fallback.c_str(), m_path.c_str());
}
-void Config::setString(const auto_char *group,
- const auto_string &key, const string &val) const
+void Config::setString(const char *group, const char *key, const string &val) const
{
- WritePrivateProfileString(group, key.c_str(),
- make_autostring(val).c_str(), m_path.c_str());
+ Win32::writePrivateProfileString(group, key, val.c_str(), m_path.c_str());
}
-unsigned int Config::getUInt(const auto_char *group,
- const auto_string &key, const unsigned int fallback) const
+unsigned int Config::getUInt(const char *group,
+ const char *key, const unsigned int fallback) const
{
- return GetPrivateProfileInt(group, key.c_str(), fallback, m_path.c_str());
+ return Win32::getPrivateProfileInt(group, key, fallback, m_path.c_str());
}
-bool Config::getBool(const auto_char *group,
- const auto_string &key, const bool fallback) const
+bool Config::getBool(const char *group, const char *key, const bool fallback) const
{
return getUInt(group, key, fallback) > 0;
}
-void Config::setUInt(const auto_char *group, const auto_string &key,
- const unsigned int val) const
+void Config::setUInt(const char *group, const char *key, const unsigned int val) const
{
setString(group, key, to_string(val));
}
-void Config::deleteKey(const auto_char *group, const auto_string &key) const
+void Config::deleteKey(const char *group, const char *key) const
{
- WritePrivateProfileString(group, key.c_str(), 0, m_path.c_str());
+ Win32::writePrivateProfileString(group, key, nullptr, m_path.c_str());
}
-void Config::cleanupArray(const auto_char *group, const auto_string &key,
+void Config::cleanupArray(const char *group, const char *key,
const unsigned int begin, const unsigned int end) const
{
for(unsigned int i = begin; i < end; i++)
- deleteKey(group, ArrayKey(key, i));
+ deleteKey(group, nKey(key, i).c_str());
}
diff --git a/src/config.hpp b/src/config.hpp
@@ -20,7 +20,6 @@
#include <string>
-#include "encoding.hpp"
#include "remote.hpp"
class Path;
@@ -67,24 +66,19 @@ public:
RemoteList remotes;
private:
- std::string getString(const auto_char *grp,
- const auto_string &key, const std::string &fallback = {}) const;
- void setString(const auto_char *grp,
- const auto_string &key, const std::string &val) const;
+ std::string getString(const char *g, const char *k, const std::string &fallback = {}) const;
+ void setString(const char *g, const char *k, const std::string &v) const;
- bool getBool(const auto_char *grp,
- const auto_string &key, bool fallback = false) const;
- unsigned int getUInt(const auto_char *grp,
- const auto_string &key, unsigned int fallback = 0) const;
- void setUInt(const auto_char *, const auto_string &, unsigned int) const;
+ bool getBool(const char *g, const char *k, bool fallback = false) const;
+ unsigned int getUInt(const char *g, const char *k, unsigned int fallback = 0) const;
+ void setUInt(const char *g, const char *k, unsigned int v) const;
- void deleteKey(const auto_char *, const auto_string &) const;
- void cleanupArray(const auto_char *, const auto_string &,
- unsigned int begin, unsigned int end) const;
+ void deleteKey(const char *g, const char *k) const;
+ void cleanupArray(const char *g, const char *k, unsigned int begin, unsigned int end) const;
void migrate();
- auto_string m_path;
+ std::string m_path;
bool m_isFirstRun;
unsigned int m_version;
diff --git a/src/dialog.cpp b/src/dialog.cpp
@@ -18,7 +18,6 @@
#include "dialog.hpp"
#include "control.hpp"
-#include "encoding.hpp"
#include <algorithm>
#include <boost/range/adaptor/map.hpp>
@@ -331,11 +330,11 @@ void Dialog::stopTimer(int id)
void Dialog::setClipboard(const string &text)
{
- const auto_string &data = make_autostring(text);
- const size_t length = (data.size() + 1) * sizeof(auto_char); // null terminator
+ // calculate the size in bytes including the null terminator
+ const size_t size = (text.size() + 1) * sizeof(char);
- HANDLE mem = GlobalAlloc(GMEM_MOVEABLE, length);
- memcpy(GlobalLock(mem), data.c_str(), length);
+ HANDLE mem = GlobalAlloc(GMEM_MOVEABLE, size);
+ memcpy(GlobalLock(mem), text.c_str(), size);
GlobalUnlock(mem);
OpenClipboard(m_handle);
@@ -354,28 +353,11 @@ void Dialog::setClipboard(const vector<string> &values)
setClipboard(boost::algorithm::join(values, "\n"));
}
-void Dialog::openURL(const string &utf8)
-{
- const auto_string &url = make_autostring(utf8);
- ShellExecute(nullptr, AUTO_STR("open"), url.c_str(), nullptr, nullptr, SW_SHOW);
-}
-
HWND Dialog::getControl(const int idc)
{
return GetDlgItem(m_handle, idc);
}
-string Dialog::getText(HWND handle)
-{
- auto_string buffer(4096, 0);
- GetWindowText(handle, &buffer[0], (int)buffer.size());
-
- // remove extra nulls from the string
- buffer.resize(buffer.find(AUTO_STR('\0')));
-
- return from_autostring(buffer);
-}
-
void Dialog::setAnchor(HWND handle, const int flags)
{
const float left = (float)min(1, flags & AnchorLeft);
diff --git a/src/dialog.hpp b/src/dialog.hpp
@@ -102,9 +102,7 @@ public:
void stopTimer(int id);
void setClipboard(const std::string &);
void setClipboard(const std::vector<std::string> &);
- static void openURL(const std::string &url);
HWND getControl(int idc);
- std::string getText(HWND);
void setAnchor(HWND, int flags);
void setAnchorPos(HWND, const LONG *left = nullptr, const LONG *top = nullptr,
const LONG *right = nullptr, const LONG *bottom = nullptr);
diff --git a/src/download.cpp b/src/download.cpp
@@ -20,11 +20,8 @@
#include "filesystem.hpp"
#include "reapack.hpp"
-#include <boost/format.hpp>
-
#include <reaper_plugin_functions.h>
-using boost::format;
using namespace std;
static const int DOWNLOAD_TIMEOUT = 15;
@@ -68,10 +65,11 @@ DownloadContext::DownloadContext()
{
m_curl = curl_easy_init();
- const auto &userAgent = format("ReaPack/%s REAPER/%s")
- % ReaPack::VERSION % GetAppVersion();
+ char userAgent[64];
+ snprintf(userAgent, sizeof(userAgent), "ReaPack/%s REAPER/%s",
+ ReaPack::VERSION, GetAppVersion());
- curl_easy_setopt(m_curl, CURLOPT_USERAGENT, userAgent.str().c_str());
+ curl_easy_setopt(m_curl, CURLOPT_USERAGENT, userAgent);
curl_easy_setopt(m_curl, CURLOPT_LOW_SPEED_LIMIT, 1);
curl_easy_setopt(m_curl, CURLOPT_LOW_SPEED_TIME, DOWNLOAD_TIMEOUT);
curl_easy_setopt(m_curl, CURLOPT_CONNECTTIMEOUT, DOWNLOAD_TIMEOUT);
@@ -142,8 +140,9 @@ bool Download::run()
closeStream();
if(res != CURLE_OK) {
- const auto &err = format("%s (%d): %s") % curl_easy_strerror(res) % res % errbuf;
- setError({err.str(), m_url});
+ char err[255];
+ snprintf(err, sizeof(err), "%s (%d): %s", curl_easy_strerror(res), res, errbuf);
+ setError({err, m_url});
return false;
}
diff --git a/src/download.hpp b/src/download.hpp
@@ -22,11 +22,10 @@
#include "path.hpp"
#include "thread.hpp"
+#include <curl/curl.h>
#include <fstream>
#include <sstream>
-#include <curl/curl.h>
-
struct DownloadContext {
static void GlobalInit();
static void GlobalCleanup();
diff --git a/src/encoding.cpp b/src/encoding.cpp
@@ -1,45 +0,0 @@
-/* ReaPack: Package manager for REAPER
- * Copyright (C) 2015-2017 Christian Fillion
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "encoding.hpp"
-
-#ifdef _WIN32
-
-auto_string make_autostring(const std::string &input, UINT codepage)
-{
- const int size = MultiByteToWideChar(codepage, 0,
- &input[0], -1, nullptr, 0) - 1;
-
- auto_string output(size, 0);
- MultiByteToWideChar(codepage, 0, &input[0], -1, &output[0], size);
-
- return output;
-}
-
-std::string from_autostring(const auto_string &input)
-{
- const int size = WideCharToMultiByte(CP_UTF8, 0,
- &input[0], -1, nullptr, 0, nullptr, nullptr) - 1;
-
- std::string output(size, 0);
- WideCharToMultiByte(CP_UTF8, 0,
- &input[0], -1, &output[0], size, nullptr, nullptr);
-
- return output;
-}
-
-#endif
diff --git a/src/encoding.hpp b/src/encoding.hpp
@@ -1,58 +0,0 @@
-/* ReaPack: Package manager for REAPER
- * Copyright (C) 2015-2017 Christian Fillion
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef REAPACK_ENCODING_HPP
-#define REAPACK_ENCODING_HPP
-
-// This whole file is a huge hack to support unicode on Windows
-// MultiByteToWideChar is required to make file path like
-// "C:\Users\Test\Downloads\Новая папка" work on Windows...
-
-#include <cstdio>
-#include <string>
-
-#ifdef _WIN32
-
-#include <windows.h>
-
-typedef wchar_t auto_char;
-typedef std::wstring auto_string;
-
-#define AUTO_STR(text) L##text
-#define to_autostring std::to_wstring
-#define auto_snprintf(buf, size, ...) _snwprintf(buf, size - 1, __VA_ARGS__)
-auto_string make_autostring(const std::string &, UINT codepage = CP_UTF8);
-#define make_autocstring(cstr) make_autostring(cstr).c_str() // temporary string!
-std::string from_autostring(const auto_string &);
-
-#else
-
-typedef char auto_char;
-typedef std::string auto_string;
-
-#define AUTO_STR(text) text
-#define to_autostring std::to_string
-#define auto_snprintf snprintf
-#define make_autostring(string) (string)
-#define make_autocstring(cstr) cstr
-#define from_autostring(string) (string)
-
-#endif
-
-#define auto_size(buf) (sizeof(buf) / sizeof(auto_char))
-
-#endif
diff --git a/src/filedialog.cpp b/src/filedialog.cpp
@@ -18,54 +18,58 @@
#include "filedialog.hpp"
#include "path.hpp"
+#include "win32.hpp"
#ifndef _WIN32
# include <swell.h>
#endif
-auto_string FileDialog::getOpenFileName(HWND parent, HINSTANCE instance,
- const auto_char *title, const Path &initialDir,
- const auto_char *filters, const auto_char *defaultExt)
-{
+using namespace std;
+
#ifdef _WIN32
- const auto_string &dirPath = make_autostring(initialDir.join());
- auto_char path[4096] = {};
+static string getFileName(BOOL(__stdcall *func)(LPOPENFILENAME),
+ HWND parent, HINSTANCE instance, const char *title, const Path &initialDir,
+ const Win32::char_type *filters, const Win32::char_type *defaultExt)
+{
+ const auto &&wideTitle = Win32::widen(title);
+ const auto &&wideInitialDir = Win32::widen(initialDir.join());
+
+ wchar_t pathBuffer[4096] = {};
OPENFILENAME of{sizeof(OPENFILENAME), parent, instance};
of.lpstrFilter = filters;
- of.lpstrFile = path;
- of.nMaxFile = auto_size(path);
- of.lpstrInitialDir = dirPath.c_str();
- of.lpstrTitle = title;
- of.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_FILEMUSTEXIST;
+ of.lpstrFile = pathBuffer;
+ of.nMaxFile = lengthof(pathBuffer);
+ of.lpstrInitialDir = wideInitialDir.c_str();
+ of.lpstrTitle = wideTitle.c_str();
+ of.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_OVERWRITEPROMPT;
of.lpstrDefExt = defaultExt;
- return GetOpenFileName(&of) ? path : auto_string();
+ return func(&of) ? Win32::narrow(pathBuffer) : string();
+}
+#endif
+
+string FileDialog::getOpenFileName(HWND parent, HINSTANCE instance,
+ const char *title, const Path &initialDir,
+ const Win32::char_type *filters, const Win32::char_type *defaultExt)
+{
+#ifdef _WIN32
+ return getFileName(&GetOpenFileName, parent, instance,
+ title, initialDir, filters, defaultExt);
#else
- char *path = BrowseForFiles(title, initialDir.join().c_str(),
+ const char *path = BrowseForFiles(title, initialDir.join().c_str(),
nullptr, false, filters);
- return path ? path : auto_string();
+ return path ? path : string();
#endif
}
-auto_string FileDialog::getSaveFileName(HWND parent, HINSTANCE instance,
- const auto_char *title, const Path &initialDir,
- const auto_char *filters, const auto_char *defaultExt)
+string FileDialog::getSaveFileName(HWND parent, HINSTANCE instance,
+ const char *title, const Path &initialDir,
+ const Win32::char_type *filters, const Win32::char_type *defaultExt)
{
#ifdef _WIN32
- const auto_string &dirPath = make_autostring(initialDir.join());
- auto_char path[4096] = {};
-
- OPENFILENAME of{sizeof(OPENFILENAME), parent, instance};
- of.lpstrFilter = filters;
- of.lpstrFile = path;
- of.nMaxFile = auto_size(path);
- of.lpstrInitialDir = dirPath.c_str();
- of.lpstrTitle = title;
- of.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_OVERWRITEPROMPT;
- of.lpstrDefExt = defaultExt;
-
- return GetSaveFileName(&of) ? path : auto_string();
+ return getFileName(&GetSaveFileName, parent, instance,
+ title, initialDir, filters, defaultExt);
#else
char path[4096] = {};
diff --git a/src/filedialog.hpp b/src/filedialog.hpp
@@ -18,21 +18,15 @@
#ifndef REAPACK_FILEBROWSE_HPP
#define REAPACK_FILEBROWSE_HPP
-#include "encoding.hpp"
-
-#ifdef _WIN32
-# include <windows.h>
-#else
-# include <swell-types.h>
-#endif
+#include "win32.hpp"
class Path;
namespace FileDialog {
- auto_string getOpenFileName(HWND, HINSTANCE, const auto_char *title,
- const Path &directory, const auto_char *filters, const auto_char *defext);
- auto_string getSaveFileName(HWND, HINSTANCE, const auto_char *title,
- const Path &directory, const auto_char *filters, const auto_char *defext);
+ std::string getOpenFileName(HWND, HINSTANCE, const char *title,
+ const Path &directory, const Win32::char_type *filters, const Win32::char_type *defext);
+ std::string getSaveFileName(HWND, HINSTANCE, const char *title,
+ const Path &directory, const Win32::char_type *filters, const Win32::char_type *defext);
};
#endif
diff --git a/src/filesystem.cpp b/src/filesystem.cpp
@@ -17,8 +17,8 @@
#include "filesystem.hpp"
-#include "encoding.hpp"
#include "path.hpp"
+#include "win32.hpp"
#include <cerrno>
#include <cstdio>
@@ -36,36 +36,34 @@ using namespace std;
static bool stat(const Path &path, struct stat *out)
{
- const Path &fullPath = Path::prefixRoot(path);
+ const auto &&fullPath = Win32::widen(Path::prefixRoot(path).join());
#ifdef _WIN32
- if(_wstat(make_autostring(fullPath.join()).c_str(), out))
- return false;
+ constexpr auto func = &_wstat;
#else
- if(::stat(fullPath.join().c_str(), out))
- return false;
+ constexpr int(*func)(const char *, struct stat *) = &::stat;
#endif
- return true;
+ return !func(fullPath.c_str(), out);
}
FILE *FS::open(const Path &path)
{
- const Path &fullPath = Path::prefixRoot(path);
+ const auto &&fullPath = Win32::widen(Path::prefixRoot(path).join());
#ifdef _WIN32
FILE *file = nullptr;
- _wfopen_s(&file, make_autostring(fullPath.join()).c_str(), L"rb");
+ _wfopen_s(&file, fullPath.c_str(), L"rb");
return file;
#else
- return fopen(fullPath.join().c_str(), "rb");
+ return fopen(fullPath.c_str(), "rb");
#endif
}
bool FS::open(ifstream &stream, const Path &path)
{
- const Path &fullPath = Path::prefixRoot(path);
- stream.open(make_autostring(fullPath.join()), ios_base::binary);
+ const auto &&fullPath = Win32::widen(Path::prefixRoot(path).join());
+ stream.open(fullPath, ios_base::binary);
return stream.good();
}
@@ -74,8 +72,8 @@ bool FS::open(ofstream &stream, const Path &path)
if(!mkdir(path.dirname()))
return false;
- const Path &fullPath = Path::prefixRoot(path);
- stream.open(make_autostring(fullPath.join()), ios_base::binary);
+ const auto &&fullPath = Win32::widen(Path::prefixRoot(path).join());
+ stream.open(fullPath, ios_base::binary);
return stream.good();
}
@@ -102,21 +100,21 @@ bool FS::rename(const TempPath &path)
bool FS::rename(const Path &from, const Path &to)
{
- const string &fullFrom = Path::prefixRoot(from).join();
- const string &fullTo = Path::prefixRoot(to).join();
+ const auto &&fullFrom = Win32::widen(Path::prefixRoot(from).join());
+ const auto &&fullTo = Win32::widen(Path::prefixRoot(to).join());
#ifdef _WIN32
- return !_wrename(make_autostring(fullFrom).c_str(),
- make_autostring(fullTo).c_str());
+ const auto func = &_wrename;
#else
- return !::rename(fullFrom.c_str(), fullTo.c_str());
+ const auto func = &::rename;
#endif
+
+ return !func(fullFrom.c_str(), fullTo.c_str());
}
bool FS::remove(const Path &path)
{
- const auto_string &fullPath =
- make_autostring(Path::prefixRoot(path).join());
+ const auto &&fullPath = Win32::widen(Path::prefixRoot(path).join());
#ifdef _WIN32
if(GetFileAttributes(fullPath.c_str()) == INVALID_FILE_ATTRIBUTES
@@ -191,7 +189,7 @@ bool FS::mkdir(const Path &path)
for(const string &dir : path) {
fullPath.append(dir);
- const auto_string &joined = make_autostring(fullPath.join());
+ const auto &&joined = Win32::widen(fullPath.join());
#ifdef _WIN32
if(!CreateDirectory(joined.c_str(), nullptr) && GetLastError() != ERROR_ALREADY_EXISTS)
@@ -205,7 +203,7 @@ bool FS::mkdir(const Path &path)
return true;
}
-string FS::lastError()
+const char *FS::lastError()
{
return strerror(errno);
}
diff --git a/src/filesystem.hpp b/src/filesystem.hpp
@@ -36,7 +36,7 @@ namespace FS {
bool exists(const Path &, bool dir = false);
bool mkdir(const Path &);
- std::string lastError();
+ const char *lastError();
};
#endif
diff --git a/src/import.cpp b/src/import.cpp
@@ -26,13 +26,14 @@
#include "remote.hpp"
#include "resource.hpp"
#include "transaction.hpp"
+#include "win32.hpp"
#include <boost/algorithm/string/trim.hpp>
using namespace std;
-static const auto_char *TITLE = AUTO_STR("ReaPack: Import repositories");
-static const string DISCOVER_URL = "https://reapack.com/repos";
+static const char *TITLE = "ReaPack: Import repositories";
+static const char *DISCOVER_URL = "https://reapack.com/repos";
Import::Import()
: Dialog(IDD_IMPORT_DIALOG), m_pool(nullptr), m_state(OK)
@@ -43,7 +44,7 @@ void Import::onInit()
{
Dialog::onInit();
- SetWindowText(handle(), TITLE);
+ Win32::setWindowText(handle(), TITLE);
m_url = getControl(IDC_URL);
m_progress = getControl(IDC_PROGRESS);
@@ -61,7 +62,7 @@ void Import::onCommand(const int id, int)
fetch();
break;
case IDC_DISCOVER:
- openURL(DISCOVER_URL);
+ Win32::shellExecute(DISCOVER_URL);
break;
case IDCANCEL:
if(m_pool) {
@@ -120,7 +121,7 @@ void Import::fetch()
const auto &opts = g_reapack->config()->network;
size_t index = 0;
- stringstream stream(getText(m_url));
+ stringstream stream(Win32::getWindowText(m_url));
string url;
while(getline(stream, url)) {
boost::algorithm::trim(url);
@@ -139,11 +140,10 @@ void Import::fetch()
m_pool->abort();
break;
case ThreadTask::Failure: {
- auto_char msg[1024];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("Download failed: %s\r\nn%s"),
- make_autostring(dl->error().message).c_str(), make_autostring(url).c_str());
- MessageBox(handle(), msg, TITLE, MB_OK);
+ char msg[1024];
+ snprintf(msg, sizeof(msg), "Download failed: %s\r\n%s",
+ dl->error().message.c_str(), url.c_str());
+ Win32::messageBox(handle(), msg, TITLE, MB_OK);
m_pool->abort();
break;
}
@@ -163,7 +163,7 @@ void Import::fetch()
bool Import::read(MemoryDownload *dl, const size_t idx)
{
- auto_char msg[1024];
+ char msg[1024];
try {
IndexPtr index = Index::load({}, dl->contents().c_str());
@@ -172,19 +172,19 @@ bool Import::read(MemoryDownload *dl, const size_t idx)
if(exists && remote.url() != dl->url()) {
if(remote.isProtected()) {
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("The repository %s is protected and cannot be overwritten."),
- make_autostring(index->name()).c_str());
- MessageBox(handle(), msg, TITLE, MB_OK);
+ snprintf(msg, sizeof(msg),
+ "The repository %s is protected and cannot be overwritten.",
+ index->name().c_str());
+ Win32::messageBox(handle(), msg, TITLE, MB_OK);
return false;
}
else {
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("%s is already configured with a different URL.\r\n")
- AUTO_STR("Do you want to overwrite it?"),
- make_autostring(index->name()).c_str());
+ snprintf(msg, sizeof(msg),
+ "%s is already configured with a different URL.\r\n"
+ "Do you want to overwrite it?",
+ index->name().c_str());
- const auto answer = MessageBox(handle(), msg, TITLE, MB_YESNO);
+ const auto answer = Win32::messageBox(handle(), msg, TITLE, MB_YESNO);
if(answer != IDYES)
return true;
@@ -200,11 +200,9 @@ bool Import::read(MemoryDownload *dl, const size_t idx)
return true;
}
catch(const reapack_error &e) {
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("The received file is invalid: %s\r\n%s"),
- make_autostring(string(e.what())).c_str(),
- make_autostring(dl->url()).c_str());
- MessageBox(handle(), msg, TITLE, MB_OK);
+ snprintf(msg, sizeof(msg), "The received file is invalid: %s\r\n%s",
+ e.what(), dl->url().c_str());
+ Win32::messageBox(handle(), msg, TITLE, MB_OK);
return false;
}
}
diff --git a/src/index.cpp b/src/index.cpp
@@ -17,7 +17,6 @@
#include "index.hpp"
-#include "encoding.hpp"
#include "errors.hpp"
#include "filesystem.hpp"
#include "path.hpp"
@@ -42,7 +41,7 @@ IndexPtr Index::load(const string &name, const char *data)
FILE *file = FS::open(pathFor(name));
if(!file)
- throw reapack_error(FS::lastError().c_str());
+ throw reapack_error(FS::lastError());
doc.LoadFile(file);
fclose(file);
diff --git a/src/listview.cpp b/src/listview.cpp
@@ -20,6 +20,7 @@
#include "menu.hpp"
#include "time.hpp"
#include "version.hpp"
+#include "win32.hpp"
#include <boost/algorithm/string.hpp>
@@ -57,9 +58,10 @@ int ListView::addColumn(const Column &col)
item.mask |= LVCF_WIDTH;
item.cx = col.test(CollapseFlag) ? 0 : adjustWidth(col.width);
+ const auto &&label = Win32::widen(col.label);
if(!col.test(NoLabelFlag)) {
item.mask |= LVCF_TEXT;
- item.pszText = const_cast<auto_char *>(col.label.c_str());
+ item.pszText = const_cast<Win32::char_type *>(label.c_str());
}
const int index = columnCount();
@@ -91,8 +93,9 @@ auto ListView::createRow(void *data) -> RowPtr
void ListView::updateCell(int row, int cell)
{
const int viewRowIndex = translate(row);
+ const auto &&text = Win32::widen(m_rows[row]->cell(cell).value);
ListView_SetItemText(handle(), viewRowIndex, cell,
- const_cast<auto_char *>(m_rows[row]->cell(cell).value.c_str()));
+ const_cast<Win32::char_type *>(text.c_str()));
}
void ListView::removeRow(const int userIndex)
@@ -444,7 +447,7 @@ void ListView::headerMenu(const int x, const int y)
}
menu.addSeparator();
- menu.addAction(AUTO_STR("Reset columns"), ACTION_RESTORE);
+ menu.addAction("Reset columns", ACTION_RESTORE);
const int id = menu.show(x, y, handle());
@@ -542,10 +545,10 @@ int ListView::Column::compare(const ListView::Cell &cl, const ListView::Cell &cr
switch(dataType) {
case UserType: { // arbitrary data or no data: sort by visible text
- auto_string l = cl.value;
+ string l = cl.value;
boost::algorithm::to_lower(l);
- auto_string r = cr.value;
+ string r = cr.value;
boost::algorithm::to_lower(r);
return l.compare(r);
@@ -567,7 +570,7 @@ ListView::Row::Row(const size_t size, void *data, ListView *list)
{
}
-void ListView::Row::setCell(const int i, const auto_string &val, void *data)
+void ListView::Row::setCell(const int i, const string &val, void *data)
{
Cell &cell = m_cells[i];
cell.value = val;
diff --git a/src/listview.hpp b/src/listview.hpp
@@ -25,7 +25,6 @@
#include <functional>
#include <vector>
-#include "encoding.hpp"
#include "serializer.hpp"
class Menu;
@@ -49,7 +48,7 @@ public:
Cell() : userData(nullptr) {}
Cell(const Cell &) = delete;
- auto_string value;
+ std::string value;
void *userData;
};
@@ -64,7 +63,7 @@ public:
int index() const { return m_userIndex; }
const Cell &cell(const int i) const { return m_cells[i]; }
- void setCell(const int i, const auto_string &, void *data = nullptr);
+ void setCell(const int i, const std::string &, void *data = nullptr);
protected:
friend ListView;
@@ -79,7 +78,7 @@ public:
typedef std::shared_ptr<Row> RowPtr;
struct Column {
- auto_string label;
+ std::string label;
int width;
int flags;
ColumnDataType dataType;
diff --git a/src/main.cpp b/src/main.cpp
@@ -19,6 +19,7 @@
#include "errors.hpp"
#include "menu.hpp"
#include "reapack.hpp"
+#include "win32.hpp"
#define REAPERAPI_IMPLEMENT
#include <reaper_plugin_functions.h>
@@ -50,14 +51,14 @@ static bool loadAPI(void *(*getFunc)(const char *))
*func.ptr = getFunc(func.name);
if(func.required && *func.ptr == nullptr) {
- auto_char msg[1024];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("ReaPack v%s is incompatible with this version of REAPER.\r\n\r\n")
- AUTO_STR("(Unable to import the following API function: %s)"),
- make_autocstring(ReaPack::VERSION), make_autocstring(func.name));
+ char msg[1024];
+ snprintf(msg, sizeof(msg),
+ "ReaPack v%s is incompatible with this version of REAPER.\r\n\r\n"
+ "(Unable to import the following API function: %s)",
+ ReaPack::VERSION, func.name);
- MessageBox(Splash_GetWnd ? Splash_GetWnd() : nullptr,
- msg, AUTO_STR("ReaPack: Fatal Error"), MB_OK);
+ Win32::messageBox(Splash_GetWnd ? Splash_GetWnd() : nullptr,
+ msg, "ReaPack: Fatal Error", MB_OK);
return false;
}
@@ -76,25 +77,25 @@ static void menuHook(const char *name, HMENU handle, int f)
if(strcmp(name, "Main extensions") || f != 0)
return;
- Menu menu = Menu(handle).addMenu(AUTO_STR("ReaPack"));
+ Menu menu = Menu(handle).addMenu("ReaPack");
- menu.addAction(AUTO_STR("&Synchronize packages"),
+ menu.addAction("&Synchronize packages",
NamedCommandLookup("_REAPACK_SYNC"));
- menu.addAction(AUTO_STR("&Browse packages..."),
+ menu.addAction("&Browse packages...",
NamedCommandLookup("_REAPACK_BROWSE"));
- menu.addAction(AUTO_STR("&Import repositories..."),
+ menu.addAction("&Import repositories...",
NamedCommandLookup("_REAPACK_IMPORT"));
- menu.addAction(AUTO_STR("&Manage repositories..."),
+ menu.addAction("&Manage repositories...",
NamedCommandLookup("_REAPACK_MANAGE"));
menu.addSeparator();
- auto_char aboutLabel[32];
- auto_snprintf(aboutLabel, auto_size(aboutLabel),
- AUTO_STR("&About ReaPack v%s"), make_autocstring(ReaPack::VERSION));
+ char aboutLabel[32];
+ snprintf(aboutLabel, sizeof(aboutLabel),
+ "&About ReaPack v%s", ReaPack::VERSION);
menu.addAction(aboutLabel, NamedCommandLookup("_REAPACK_ABOUT"));
}
@@ -106,9 +107,9 @@ static bool checkLocation(REAPER_PLUGIN_HINSTANCE module)
expected.append(REAPACK_FILE);
#ifdef _WIN32
- auto_char self[MAX_PATH] = {};
- GetModuleFileName(module, self, auto_size(self));
- Path current(from_autostring(self).c_str());
+ Win32::char_type self[MAX_PATH] = {};
+ GetModuleFileName(module, self, lengthof(self));
+ Path current(Win32::narrow(self));
#else
Dl_info info{};
dladdr((const void *)checkLocation, &info);
@@ -119,16 +120,16 @@ static bool checkLocation(REAPER_PLUGIN_HINSTANCE module)
if(current == expected)
return true;
- auto_char msg[4096];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("ReaPack was not loaded from the standard extension path")
- AUTO_STR(" or its filename was altered.\n")
- AUTO_STR("Move or rename it to the expected location and retry.\n\n")
- AUTO_STR("Current:\xa0%s\n\nExpected:\xa0%s"),
- self, make_autostring(expected.join()).c_str());
+ char msg[4096];
+ snprintf(msg, sizeof(msg),
+ "ReaPack was not loaded from the standard extension path"
+ " or its filename was altered.\n"
+ "Move or rename it to the expected location and retry.\n\n"
+ "Current: %s\n\nExpected: %s",
+ current.join().c_str(), expected.join().c_str());
- MessageBox(Splash_GetWnd(), msg,
- AUTO_STR("ReaPack: Installation path mismatch"), MB_OK);
+ Win32::messageBox(Splash_GetWnd(), msg,
+ "ReaPack: Installation path mismatch", MB_OK);
return false;
}
diff --git a/src/manager.cpp b/src/manager.cpp
@@ -20,7 +20,6 @@
#include "about.hpp"
#include "archive.hpp"
#include "config.hpp"
-#include "encoding.hpp"
#include "errors.hpp"
#include "filedialog.hpp"
#include "import.hpp"
@@ -31,12 +30,13 @@
#include "remote.hpp"
#include "resource.hpp"
#include "transaction.hpp"
+#include "win32.hpp"
#include <boost/algorithm/string/join.hpp>
-static const auto_char *ARCHIVE_FILTER =
- AUTO_STR("ReaPack Offline Archive (*.ReaPackArchive)\0*.ReaPackArchive\0");
-static const auto_char *ARCHIVE_EXT = AUTO_STR("ReaPackArchive");
+static const Win32::char_type *ARCHIVE_FILTER =
+ L("ReaPack Offline Archive (*.ReaPackArchive)\0*.ReaPackArchive\0");
+static const Win32::char_type *ARCHIVE_EXT = L("ReaPackArchive");
using namespace std;
@@ -67,9 +67,9 @@ void Manager::onInit()
disable(m_apply);
m_list = createControl<ListView>(IDC_LIST, ListView::Columns{
- {AUTO_STR("Name"), 115},
- {AUTO_STR("Index URL"), 415},
- {AUTO_STR("State"), 60},
+ {"Name", 115},
+ {"Index URL", 415},
+ {"State", 60},
});
m_list->onActivate(bind(&Manager::aboutRepo, this, true));
@@ -212,39 +212,38 @@ bool Manager::fillContextMenu(Menu &menu, const int index) const
const Remote &remote = getRemote(index);
if(!remote) {
- menu.addAction(AUTO_STR("&Select all"), ACTION_SELECT);
- menu.addAction(AUTO_STR("&Unselect all"), ACTION_UNSELECT);
+ menu.addAction("&Select all", ACTION_SELECT);
+ menu.addAction("&Unselect all", ACTION_UNSELECT);
return true;
}
const UINT enableAction =
- menu.addAction(AUTO_STR("&Enable"), ACTION_ENABLE);
+ menu.addAction("&Enable", ACTION_ENABLE);
const UINT disableAction =
- menu.addAction(AUTO_STR("&Disable"), ACTION_DISABLE);
+ menu.addAction("&Disable", ACTION_DISABLE);
menu.addSeparator();
- menu.addAction(AUTO_STR("&Refresh"), ACTION_REFRESH);
+ menu.addAction("&Refresh", ACTION_REFRESH);
- Menu autoInstallMenu = menu.addMenu(AUTO_STR("&Install new packages"));
+ Menu autoInstallMenu = menu.addMenu("&Install new packages");
const UINT autoInstallGlobal = autoInstallMenu.addAction(
- AUTO_STR("Use &global setting"), ACTION_AUTOINSTALL_GLOBAL);
+ "Use &global setting", ACTION_AUTOINSTALL_GLOBAL);
const UINT autoInstallOff = autoInstallMenu.addAction(
- AUTO_STR("Manually"), ACTION_AUTOINSTALL_OFF);
+ "Manually", ACTION_AUTOINSTALL_OFF);
const UINT autoInstallOn = autoInstallMenu.addAction(
- AUTO_STR("When synchronizing"), ACTION_AUTOINSTALL_ON);
+ "When synchronizing", ACTION_AUTOINSTALL_ON);
- menu.addAction(AUTO_STR("&Copy URL"), ACTION_COPYURL);
+ menu.addAction("&Copy URL", ACTION_COPYURL);
const UINT uninstallAction =
- menu.addAction(AUTO_STR("&Uninstall"), ACTION_UNINSTALL);
+ menu.addAction("&Uninstall", ACTION_UNINSTALL);
menu.addSeparator();
- auto_char aboutLabel[64];
- const auto_string &name = make_autostring(remote.name());
- auto_snprintf(aboutLabel, auto_size(aboutLabel),
- AUTO_STR("&About %s"), name.c_str());
+ char aboutLabel[64];
+ snprintf(aboutLabel, sizeof(aboutLabel),
+ "&About %s", remote.name().c_str());
menu.addAction(aboutLabel, index | (ACTION_ABOUT << 8));
bool allEnabled = true;
@@ -319,7 +318,7 @@ void Manager::refresh()
const vector<int> selection = m_list->selection();
vector<string> selected(selection.size());
for(size_t i = 0; i < selection.size(); i++)
- selected[i] = from_autostring(m_list->row(selection[i])->cell(0).value); // TODO: use data ptr to Remote
+ selected[i] = m_list->row(selection[i])->cell(0).value; // TODO: use data ptr to Remote
const auto &remotes = g_reapack->config()->remotes;
@@ -332,8 +331,8 @@ void Manager::refresh()
int c = 0;
auto row = m_list->createRow();
- row->setCell(c++, make_autostring(remote.name()));
- row->setCell(c++, make_autostring(remote.url()));
+ row->setCell(c++, remote.name());
+ row->setCell(c++, remote.url());
updateEnabledCell(row->index(), remote);
if(find(selected.begin(), selected.end(), remote.name()) != selected.end())
@@ -345,8 +344,7 @@ void Manager::refresh()
void Manager::updateEnabledCell(int index, const Remote &remote)
{
- m_list->row(index)->setCell(2, isRemoteEnabled(remote) ?
- AUTO_STR("Enabled") : AUTO_STR("Disabled"));
+ m_list->row(index)->setCell(2, isRemoteEnabled(remote) ? "Enabled" : "Disabled");
}
void Manager::setMods(const ModsCallback &cb, const bool updateRow)
@@ -498,10 +496,10 @@ void Manager::aboutRepo(const bool focus)
void Manager::importExport()
{
Menu menu;
- menu.addAction(AUTO_STR("Import &repositories..."), ACTION_IMPORT_REPO);
+ menu.addAction("Import &repositories...", ACTION_IMPORT_REPO);
menu.addSeparator();
- menu.addAction(AUTO_STR("Import offline archive..."), ACTION_IMPORT_ARCHIVE);
- menu.addAction(AUTO_STR("&Export offline archive..."), ACTION_EXPORT_ARCHIVE);
+ menu.addAction("Import offline archive...", ACTION_IMPORT_ARCHIVE);
+ menu.addAction("&Export offline archive...", ACTION_EXPORT_ARCHIVE);
menu.show(getControl(IDC_IMPORT), handle());
}
@@ -520,9 +518,9 @@ bool Manager::importRepo()
void Manager::importArchive()
{
- const auto_char *title = AUTO_STR("Import offline archive");
+ const char *title = "Import offline archive";
- const auto_string &path = FileDialog::getOpenFileName(handle(), instance(),
+ const string &path = FileDialog::getOpenFileName(handle(), instance(),
title, Path::prefixRoot(Path::DATA), ARCHIVE_FILTER, ARCHIVE_EXT);
if(path.empty())
@@ -532,23 +530,18 @@ void Manager::importArchive()
Archive::import(path);
}
catch(const reapack_error &e) {
- const auto_string &desc = make_autostring(e.what());
-
- auto_char msg[512];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("An error occured while reading %s.\r\n\r\n%s."),
- path.c_str(), desc.c_str()
- );
-
- MessageBox(handle(), msg, title, MB_OK);
+ char msg[512];
+ snprintf(msg, sizeof(msg), "An error occured while reading %s.\r\n\r\n%s.",
+ path.c_str(), e.what());
+ Win32::messageBox(handle(), msg, title, MB_OK);
}
}
void Manager::exportArchive()
{
- const auto_char *title = AUTO_STR("Export offline archive");
+ const char *title = "Export offline archive";
- const auto_string &path = FileDialog::getSaveFileName(handle(), instance(),
+ const string &path = FileDialog::getSaveFileName(handle(), instance(),
title, Path::prefixRoot(Path::DATA), ARCHIVE_FILTER, ARCHIVE_EXT);
if(path.empty())
@@ -564,22 +557,22 @@ void Manager::exportArchive()
const auto finish = [=] {
Dialog::Destroy(progress);
- auto_char error[1024];
+ char error[1024];
if(errors.empty())
error[0] = 0;
else {
- auto_snprintf(error, auto_size(error),
- AUTO_STR("\r\n\r\n%zu file%s could not be archived. ")
- AUTO_STR("Synchronize packages to repair any missing file.\r\n\r\n%s"),
- errors.size(), errors.size() == 1 ? AUTO_STR("") : AUTO_STR("s"),
- make_autostring(boost::algorithm::join(errors, "\r\n")).c_str());
+ snprintf(error, sizeof(error),
+ "\r\n\r\n%zu file%s could not be archived. "
+ "Synchronize packages to repair any missing file.\r\n\r\n%s",
+ errors.size(), errors.size() == 1 ? "" : "s",
+ boost::algorithm::join(errors, "\r\n").c_str());
}
- auto_char msg[2048];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("Done! %zu package%s were exported in the archive.%s"),
- count, count == 1 ? AUTO_STR("") : AUTO_STR("s"), error);
- MessageBox(handle(), msg, title, MB_OK);
+ char msg[2048];
+ snprintf(msg, sizeof(msg),
+ "Done! %zu package%s were exported in the archive.%s",
+ count, count == 1 ? "" : "s", error);
+ Win32::messageBox(handle(), msg, title, MB_OK);
delete pool;
};
@@ -593,24 +586,19 @@ void Manager::exportArchive()
Dialog::Destroy(progress);
delete pool;
- const auto_string &desc = make_autostring(e.what());
-
- auto_char msg[512];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("An error occured while writing into %s.\r\n\r\n%s."),
- path.c_str(), desc.c_str()
+ char msg[512];
+ snprintf(msg, sizeof(msg),
+ "An error occured while writing into %s.\r\n\r\n%s.",
+ path.c_str(), e.what()
);
- MessageBox(handle(), msg, title, MB_OK);
+ Win32::messageBox(handle(), msg, title, MB_OK);
}
}
void Manager::launchBrowser()
{
- const auto promptApply = [&] {
- const auto_char *title = AUTO_STR("ReaPack Query");
- const auto_char *msg = AUTO_STR("Apply unsaved changes?");
- const int btn = MessageBox(handle(), msg, title, MB_YESNO);
- return btn == IDYES;
+ const auto promptApply = [this] {
+ return IDYES == Win32::messageBox(handle(), "Apply unsaved changes?", "ReaPack Query", MB_YESNO);
};
if(m_changes && promptApply())
@@ -624,25 +612,25 @@ void Manager::options()
Menu menu;
UINT index = menu.addAction(
- AUTO_STR("&Install new packages when synchronizing"), ACTION_AUTOINSTALL);
+ "&Install new packages when synchronizing", ACTION_AUTOINSTALL);
if(m_autoInstall.value_or(g_reapack->config()->install.autoInstall))
menu.check(index);
index = menu.addAction(
- AUTO_STR("Enable &pre-releases globally (bleeding edge)"), ACTION_BLEEDINGEDGE);
+ "Enable &pre-releases globally (bleeding edge)", ACTION_BLEEDINGEDGE);
if(m_bleedingEdge.value_or(g_reapack->config()->install.bleedingEdge))
menu.check(index);
index = menu.addAction(
- AUTO_STR("Prompt to uninstall obsolete packages"), ACTION_PROMPTOBSOLETE);
+ "Prompt to uninstall obsolete packages", ACTION_PROMPTOBSOLETE);
if(m_promptObsolete.value_or(g_reapack->config()->install.promptObsolete))
menu.check(index);
- menu.addAction(AUTO_STR("&Network settings..."), ACTION_NETCONFIG);
+ menu.addAction("&Network settings...", ACTION_NETCONFIG);
menu.addSeparator();
- menu.addAction(AUTO_STR("&Restore default settings"), ACTION_RESETCONFIG);
+ menu.addAction("&Restore default settings", ACTION_RESETCONFIG);
menu.show(getControl(IDC_OPTIONS), handle());
}
@@ -660,16 +648,12 @@ bool Manager::confirm() const
const size_t uninstallSize = m_uninstall.size();
- auto_char msg[255];
- auto_snprintf(msg, auto_size(msg), AUTO_STR("Uninstall %zu %s?\n")
- AUTO_STR("Every file they contain will be removed from your computer."),
- uninstallSize,
- uninstallSize == 1 ? AUTO_STR("repository") : AUTO_STR("repositories"));
-
- const auto_char *title = AUTO_STR("ReaPack Query");
- const int btn = MessageBox(handle(), msg, title, MB_YESNO);
+ char msg[255];
+ snprintf(msg, sizeof(msg), "Uninstall %zu %s?\n"
+ "Every file they contain will be removed from your computer.",
+ uninstallSize, uninstallSize == 1 ? "repository" : "repositories");
- return btn == IDYES;
+ return IDYES == Win32::messageBox(handle(), msg, "ReaPack Query", MB_YESNO);
}
bool Manager::apply()
@@ -757,7 +741,7 @@ Remote Manager::getRemote(const int index) const
if(index < 0 || index > m_list->rowCount() - 1)
return {};
- const string &remoteName = from_autostring(m_list->row(index)->cell(0).value);
+ const string &remoteName = m_list->row(index)->cell(0).value;
return g_reapack->config()->remotes.get(remoteName);
}
@@ -771,7 +755,7 @@ void NetworkConfig::onInit()
Dialog::onInit();
m_proxy = getControl(IDC_PROXY);
- SetWindowText(m_proxy, make_autostring(m_opts->proxy).c_str());
+ Win32::setWindowText(m_proxy, m_opts->proxy.c_str());
m_verifyPeer = getControl(IDC_VERIFYPEER);
setChecked(m_opts->verifyPeer, m_verifyPeer);
@@ -794,7 +778,7 @@ void NetworkConfig::onCommand(const int id, int)
void NetworkConfig::apply()
{
- m_opts->proxy = getText(m_proxy);
+ m_opts->proxy = Win32::getWindowText(m_proxy);
m_opts->verifyPeer = isChecked(m_verifyPeer);
m_opts->staleThreshold = isChecked(m_staleThreshold)
? NetworkOpts::OneWeekThreshold : NetworkOpts::NoThreshold;
diff --git a/src/menu.cpp b/src/menu.cpp
@@ -17,10 +17,18 @@
#include "menu.hpp"
+#include "win32.hpp"
+
#ifndef MIIM_FTYPE // for SWELL
-#define MIIM_FTYPE MIIM_TYPE
+# define MIIM_FTYPE MIIM_TYPE
+#endif
+
+#ifndef _WIN32
+# include <swell.h>
#endif
+using namespace std;
+
Menu::Menu(HMENU handle)
: m_handle(handle), m_ownership(!handle)
{
@@ -39,14 +47,15 @@ Menu::~Menu()
DestroyMenu(m_handle);
}
-UINT Menu::addAction(const auto_char *label, const int commandId)
+UINT Menu::addAction(const string &label, const int commandId)
{
MENUITEMINFO mii{};
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask |= MIIM_TYPE;
mii.fType = MFT_STRING;
- mii.dwTypeData = const_cast<auto_char *>(label);
+ const auto &&wideLabel = Win32::widen(label);
+ mii.dwTypeData = const_cast<Win32::char_type *>(wideLabel.c_str());
mii.fMask |= MIIM_ID;
mii.wID = commandId;
@@ -67,14 +76,15 @@ void Menu::addSeparator()
append(mii);
}
-Menu Menu::addMenu(const auto_char *label)
+Menu Menu::addMenu(const string &label)
{
MENUITEMINFO mii{};
mii.cbSize = sizeof(MENUITEMINFO);
mii.fMask |= MIIM_TYPE;
mii.fType = MFT_STRING;
- mii.dwTypeData = const_cast<auto_char *>(label);
+ const auto &&wideLabel = Win32::widen(label);
+ mii.dwTypeData = const_cast<Win32::char_type *>(wideLabel.c_str());
mii.fMask |= MIIM_SUBMENU;
mii.hSubMenu = CreatePopupMenu();
diff --git a/src/menu.hpp b/src/menu.hpp
@@ -18,14 +18,14 @@
#ifndef REAPACK_MENU_HPP
#define REAPACK_MENU_HPP
+#include <string>
+
#ifdef _WIN32
-#include <windows.h>
+# include <windows.h>
#else
-#include <swell/swell.h>
+# include <swell-types.h>
#endif
-#include "encoding.hpp"
-
class Menu {
public:
Menu(HMENU handle = nullptr);
@@ -34,9 +34,9 @@ public:
UINT size() { return m_size; }
bool empty() const { return m_size == 0; }
- UINT addAction(const auto_char *label, int commandId);
+ UINT addAction(const std::string &label, int commandId);
void addSeparator();
- Menu addMenu(const auto_char *label);
+ Menu addMenu(const std::string &label);
int show(int x, int y, HWND parent) const;
int show(HWND control, HWND parent) const;
diff --git a/src/obsquery.cpp b/src/obsquery.cpp
@@ -17,7 +17,6 @@
#include "obsquery.hpp"
-#include "encoding.hpp"
#include "listview.hpp"
#include "menu.hpp"
#include "package.hpp"
@@ -42,13 +41,13 @@ void ObsoleteQuery::onInit()
m_okBtn = getControl(IDOK);
m_list = createControl<ListView>(IDC_LIST, ListView::Columns{
- {AUTO_STR("Package"), 550}
+ {"Package", 550}
});
m_list->onSelect([=] { setEnabled(m_list->hasSelection(), m_okBtn); });
m_list->onContextMenu([=] (Menu &menu, int) {
- menu.addAction(AUTO_STR("Select &all"), ACTION_SELECT_ALL);
- menu.addAction(AUTO_STR("&Unselect all"), ACTION_UNSELECT_ALL);
+ menu.addAction("Select &all", ACTION_SELECT_ALL);
+ menu.addAction("&Unselect all", ACTION_UNSELECT_ALL);
return true;
});
@@ -58,7 +57,7 @@ void ObsoleteQuery::onInit()
ostringstream stream;
stream << entry.remote << '/' << entry.category << '/'
<< Package::displayName(entry.package, entry.description);
- m_list->createRow()->setCell(0, make_autostring(stream.str()));
+ m_list->createRow()->setCell(0, stream.str());
}
m_list->autoSizeHeader();
diff --git a/src/progress.cpp b/src/progress.cpp
@@ -19,6 +19,7 @@
#include "thread.hpp"
#include "resource.hpp"
+#include "win32.hpp"
using namespace std;
@@ -35,9 +36,9 @@ void Progress::onInit()
Dialog::onInit();
m_label = getControl(IDC_LABEL);
- m_progress = GetDlgItem(handle(), IDC_PROGRESS);
+ m_progress = getControl(IDC_PROGRESS);
- SetWindowText(m_label, AUTO_STR("Initializing..."));
+ Win32::setWindowText(m_label, "Initializing...");
}
void Progress::onCommand(const int id, int)
@@ -68,7 +69,7 @@ void Progress::addTask(ThreadTask *task)
startTimer(100);
task->onStart([=] {
- m_current = make_autostring(task->summary());
+ m_current = task->summary();
updateProgress();
});
@@ -80,22 +81,22 @@ void Progress::addTask(ThreadTask *task)
void Progress::updateProgress()
{
- auto_char position[32];
- auto_snprintf(position, auto_size(position), AUTO_STR("%d of %d"),
+ char position[32];
+ snprintf(position, sizeof(position), "%d of %d",
min(m_done + 1, m_total), m_total);
- auto_char label[1024];
- auto_snprintf(label, auto_size(label), m_current.c_str(), position);
+ char label[1024];
+ snprintf(label, sizeof(label), m_current.c_str(), position);
- SetWindowText(m_label, label);
+ Win32::setWindowText(m_label, label);
const double pos = (double)(min(m_done+1, m_total)) / max(2, m_total);
const int percent = (int)(pos * 100);
- auto_char title[255];
- auto_snprintf(title, auto_size(title),
- AUTO_STR("ReaPack: Operation in progress (%d%%)"), percent);
+ char title[255];
+ snprintf(title, sizeof(title),
+ "ReaPack: Operation in progress (%d%%)", percent);
SendMessage(m_progress, PBM_SETPOS, percent, 0);
- SetWindowText(handle(), title);
+ Win32::setWindowText(handle(), title);
}
diff --git a/src/progress.hpp b/src/progress.hpp
@@ -20,7 +20,6 @@
#include "dialog.hpp"
-#include "encoding.hpp"
class ThreadPool;
class ThreadTask;
@@ -39,7 +38,7 @@ private:
void updateProgress();
ThreadPool *m_pool;
- auto_string m_current;
+ std::string m_current;
HWND m_label;
HWND m_progress;
diff --git a/src/reapack.cpp b/src/reapack.cpp
@@ -31,6 +31,7 @@
#include "report.hpp"
#include "richedit.hpp"
#include "transaction.hpp"
+#include "win32.hpp"
#include <reaper_plugin_functions.h>
@@ -48,7 +49,7 @@ ReaPack *ReaPack::s_instance = nullptr;
static void CleanupTempFiles()
{
const Path &path = Path::prefixRoot(Path::DATA + "*.tmp");
- const auto_string &pattern = make_autostring(path.join());
+ const wstring &pattern = Win32::widen(path.join());
WIN32_FIND_DATA fd = {};
HANDLE handle = FindFirstFile(pattern.c_str(), &fd);
@@ -57,7 +58,7 @@ static void CleanupTempFiles()
return;
do {
- auto_string file = pattern;
+ wstring file = pattern;
file.replace(file.size() - 5, 5, fd.cFileName); // 5 == strlen("*.tmp")
DeleteFile(file.c_str());
} while(FindNextFile(handle, &fd));
@@ -66,13 +67,13 @@ static void CleanupTempFiles()
}
#endif
-std::string ReaPack::resourcePath()
+Path ReaPack::resourcePath()
{
#ifdef _WIN32
// convert from the current system codepage to UTF-8
- return from_autostring(make_autostring(GetResourcePath(), CP_ACP));
+ return Win32::narrow(Win32::widen(GetResourcePath(), CP_ACP));
#else
- return GetResourcePath();
+ return {GetResourcePath()};
#endif
}
@@ -336,15 +337,13 @@ Transaction *ReaPack::setupTransaction()
m_tx = new Transaction;
}
catch(const reapack_error &e) {
- const auto_string &desc = make_autostring(e.what());
-
- auto_char msg[512];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("The following error occurred while creating a transaction:\n\n%s"),
- desc.c_str()
+ char msg[512];
+ snprintf(msg, sizeof(msg),
+ "The following error occurred while creating a transaction:\n\n%s",
+ e.what()
);
- MessageBox(m_mainWindow, msg, AUTO_STR("ReaPack"), MB_OK);
+ Win32::messageBox(m_mainWindow, msg, "ReaPack", MB_OK);
return nullptr;
}
@@ -420,16 +419,14 @@ void ReaPack::createDirectories()
if(FS::mkdir(path))
return;
- const auto_string &desc = make_autostring(FS::lastError());
-
- auto_char msg[255];
- auto_snprintf(msg, auto_size(msg),
- AUTO_STR("ReaPack could not create %s! ")
- AUTO_STR("Please investigate or report this issue.\n\n")
- AUTO_STR("Error description: %s"),
- make_autostring(Path::prefixRoot(path).join()).c_str(), desc.c_str());
+ char msg[255];
+ snprintf(msg, sizeof(msg),
+ "ReaPack could not create %s! "
+ "Please investigate or report this issue.\n\n"
+ "Error description: %s",
+ Path::prefixRoot(path).join().c_str(), FS::lastError());
- MessageBox(Splash_GetWnd(), msg, AUTO_STR("ReaPack"), MB_OK);
+ Win32::messageBox(Splash_GetWnd(), msg, "ReaPack", MB_OK);
}
void ReaPack::registerSelf()
diff --git a/src/reapack.hpp b/src/reapack.hpp
@@ -47,7 +47,7 @@ public:
static const char *BUILDTIME;
static ReaPack *instance() { return s_instance; }
- static std::string resourcePath();
+ static Path resourcePath();
gaccel_register_t syncAction;
gaccel_register_t browseAction;
diff --git a/src/report.cpp b/src/report.cpp
@@ -17,11 +17,11 @@
#include "report.hpp"
-#include "encoding.hpp"
#include "package.hpp"
#include "resource.hpp"
#include "source.hpp"
#include "transaction.hpp"
+#include "win32.hpp"
#include <boost/range/adaptor/reversed.hpp>
@@ -92,12 +92,11 @@ void Report::fillReport()
printRemovals();
if(installs + updates + removals == 0) {
- SetDlgItemText(handle(), IDC_LABEL,
- AUTO_STR("Oops! The following error(s) occured:"));
+ Win32::setWindowText(getControl(IDC_LABEL),
+ "Oops! The following error(s) occured:");
}
- const auto_string &str = make_autostring(m_stream.str());
- SetDlgItemText(handle(), IDC_REPORT, str.c_str());
+ Win32::setWindowText(getControl(IDC_REPORT), m_stream.str().c_str());
}
void Report::printInstalls()
diff --git a/src/richedit-win32.cpp b/src/richedit-win32.cpp
@@ -22,8 +22,6 @@
// Starting here and onward is the Win32 implementation of RichEdit
// The OS X implementation can be found in richedit.mm
-#include "encoding.hpp"
-
#include <memory>
#include <richedit.h>
#include <sstream>
@@ -34,19 +32,19 @@ static void HandleLink(ENLINK *info, HWND handle)
{
const CHARRANGE &range = info->chrg;
- auto_char *url = new auto_char[(range.cpMax - range.cpMin) + 1]();
- unique_ptr<auto_char[]> ptr(url);
+ wchar_t *url = new wchar_t[(range.cpMax - range.cpMin) + 1]();
+ unique_ptr<wchar_t[]> ptr(url);
TEXTRANGE tr{range, url};
SendMessage(handle, EM_GETTEXTRANGE, 0, (LPARAM)&tr);
if(info->msg == WM_LBUTTONUP)
- ShellExecute(nullptr, AUTO_STR("open"), url, nullptr, nullptr, SW_SHOW);
+ ShellExecute(nullptr, L"open", url, nullptr, nullptr, SW_SHOW);
}
void RichEdit::Init()
{
- LoadLibrary(AUTO_STR("Msftedit.dll"));
+ LoadLibrary(L"Msftedit.dll");
}
RichEdit::RichEdit(HWND handle)
diff --git a/src/tabbar.cpp b/src/tabbar.cpp
@@ -18,6 +18,7 @@
#include "tabbar.hpp"
#include "dialog.hpp"
+#include "win32.hpp"
#ifdef _WIN32
# include <commctrl.h>
@@ -38,7 +39,8 @@ int TabBar::addTab(const Tab &tab)
TCITEM item{};
item.mask |= TCIF_TEXT;
- item.pszText = const_cast<auto_char *>(tab.text.c_str());
+ const auto &&wideText = Win32::widen(tab.text);
+ item.pszText = const_cast<Win32::char_type *>(wideText.c_str());
TabCtrl_InsertItem(handle(), index, &item);
diff --git a/src/tabbar.hpp b/src/tabbar.hpp
@@ -22,14 +22,13 @@
#include <vector>
-#include "encoding.hpp"
class Dialog;
class TabBar : public Control {
public:
typedef std::vector<HWND> Page;
- struct Tab { auto_string text; Page page; };
+ struct Tab { const char *text; Page page; };
typedef std::vector<Tab> Tabs;
TabBar(HWND handle, Dialog *parent, const Tabs &tabs = {});
diff --git a/src/task.cpp b/src/task.cpp
@@ -107,7 +107,7 @@ void InstallTask::commit()
for(const TempPath &paths : m_newFiles) {
if(!FS::rename(paths)) {
- tx()->receipt()->addError({"Cannot rename to target: " + FS::lastError(),
+ tx()->receipt()->addError({string("Cannot rename to target: ") + FS::lastError(),
paths.target().join()});
// it's a bit late to rollback here as some files might already have been
diff --git a/src/thread.cpp b/src/thread.cpp
@@ -78,7 +78,7 @@ void ThreadTask::exec()
WorkerThread::WorkerThread() : m_exit(false)
{
- m_wake = CreateEvent(nullptr, true, false, AUTO_STR("WakeEvent"));
+ m_wake = CreateEvent(nullptr, true, false, nullptr);
m_thread = CreateThread(nullptr, 0, run, (void *)this, 0, nullptr);
}
diff --git a/src/transaction.cpp b/src/transaction.cpp
@@ -169,7 +169,7 @@ IndexPtr Transaction::loadIndex(const Remote &remote)
}
catch(const reapack_error &e) {
m_receipt.addError({
- "Couldn't load repository: " + string(e.what()), remote.name()});
+ string("Couldn't load repository: ") + e.what(), remote.name()});
return nullptr;
}
}
diff --git a/src/win32.cpp b/src/win32.cpp
@@ -0,0 +1,99 @@
+/* ReaPack: Package manager for REAPER
+ * Copyright (C) 2015-2017 Christian Fillion
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "win32.hpp"
+
+#ifdef _WIN32
+# define widen_cstr(cstr) widen(cstr).c_str()
+#else
+# include <swell/swell.h>
+# define widen_cstr(cstr) cstr
+#endif
+
+using namespace std;
+
+#ifdef _WIN32
+wstring Win32::widen(const char *input, const UINT codepage)
+{
+ const int size = MultiByteToWideChar(codepage, 0, input, -1, nullptr, 0) - 1;
+
+ wstring output(size, 0);
+ MultiByteToWideChar(codepage, 0, input, -1, &output[0], size);
+
+ return output;
+}
+
+string Win32::narrow(const wchar_t *input)
+{
+ const int size = WideCharToMultiByte(CP_UTF8, 0,
+ input, -1, nullptr, 0, nullptr, nullptr) - 1;
+
+ string output(size, 0);
+ WideCharToMultiByte(CP_UTF8, 0, input, -1, &output[0], size, nullptr, nullptr);
+
+ return output;
+}
+#endif
+
+int Win32::messageBox(const HWND handle, const char *text,
+ const char *title, const unsigned int buttons)
+{
+ return MessageBox(handle, widen_cstr(text), widen_cstr(title), buttons);
+}
+
+string Win32::getWindowText(const HWND handle)
+{
+ char_type buffer[4096];
+ GetWindowText(handle, buffer, (int)lengthof(buffer));
+
+ return narrow(buffer);
+}
+
+void Win32::setWindowText(const HWND handle, const char *text)
+{
+ SetWindowText(handle, widen_cstr(text));
+}
+
+void Win32::shellExecute(const char *what, const char *arg)
+{
+ ShellExecute(nullptr, L("open"), widen_cstr(what), widen_cstr(arg), nullptr, SW_SHOW);
+}
+
+bool Win32::writePrivateProfileString(const char *group, const char *key,
+ const char *value, const char *path)
+{
+ // value can be null for deleting a key
+ return WritePrivateProfileString(widen_cstr(group), widen_cstr(key),
+ value ? widen_cstr(value) : nullptr, widen_cstr(path));
+}
+
+string Win32::getPrivateProfileString(const char *group, const char *key,
+ const char *fallback, const char *path)
+{
+ char_type buffer[4096];
+ GetPrivateProfileString(widen_cstr(group), widen_cstr(key),
+ widen_cstr(fallback), buffer, lengthof(buffer), widen_cstr(path));
+
+ return narrow(buffer);
+}
+
+unsigned int Win32::getPrivateProfileInt(const char *group, const char *key,
+ const unsigned int fallback, const char *path)
+{
+ return GetPrivateProfileInt(widen_cstr(group), widen_cstr(key),
+ fallback, widen_cstr(path));
+}
diff --git a/src/win32.hpp b/src/win32.hpp
@@ -0,0 +1,64 @@
+/* ReaPack: Package manager for REAPER
+ * Copyright (C) 2015-2017 Christian Fillion
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REAPACK_WIN32_HPP
+#define REAPACK_WIN32_HPP
+
+// Utility wrappers around the Windows Wide API
+
+#include <string>
+
+#ifdef _WIN32
+# define L(str) L##str
+# include <windows.h>
+#else
+# define L(str) str
+# include <swell-types.h>
+#endif
+
+#define lengthof(t) (sizeof(t) / sizeof(*t))
+
+namespace Win32 {
+#ifdef _WIN32
+ typedef wchar_t char_type;
+
+ std::wstring widen(const char *, UINT codepage = CP_UTF8);
+ inline std::wstring widen(const std::string &str) { return widen(str.c_str(), CP_UTF8); }
+
+ std::string narrow(const wchar_t *);
+ inline std::string narrow(const std::wstring &str) { return narrow(str.c_str()); }
+#else
+ typedef char char_type;
+
+ inline std::string widen(const char *s, UINT = 0) { return s; }
+ inline std::string widen(const std::string &s) { return s; }
+
+ inline std::string narrow(const char *s) { return s; }
+ inline std::string narrow(const std::string &s) { return s; }
+#endif
+
+ int messageBox(HWND, const char *text, const char *title, unsigned int buttons);
+ void setWindowText(HWND handle, const char *text);
+ std::string getWindowText(HWND handle);
+ void shellExecute(const char *what, const char *arg = nullptr);
+
+ bool writePrivateProfileString(const char *g, const char *k, const char *v, const char *p);
+ std::string getPrivateProfileString(const char *g, const char *k, const char *v, const char *p);
+ unsigned int getPrivateProfileInt(const char *g, const char *k, unsigned int f, const char *p);
+};
+
+#endif
diff --git a/test/encoding.cpp b/test/encoding.cpp
@@ -1,32 +0,0 @@
-#include <catch.hpp>
-
-#include <encoding.hpp>
-
-using namespace std;
-
-static const char *M = "[encoding]";
-
-TEST_CASE("to_autostring", M) {
- REQUIRE(to_autostring(42) == AUTO_STR("42"));
-}
-
-TEST_CASE("string to wstring to string", M) {
- SECTION("ascii") {
- const auto_string &wstr = make_autostring("hello world");
- const string &str = from_autostring(wstr);
-
- REQUIRE(str == "hello world");
- }
-
- SECTION("cyrillic") {
- const auto_string &wstr = make_autostring("Новая папка");
- const string &str = from_autostring(wstr);
-
- REQUIRE(str == "Новая папка");
- }
-}
-
-TEST_CASE("auto_size", M) {
- auto_char test[42] = {};
- REQUIRE(auto_size(test) == 42);
-}
diff --git a/test/win32.cpp b/test/win32.cpp
@@ -0,0 +1,37 @@
+#include "helper.hpp"
+
+#include <win32.hpp>
+
+using namespace std;
+
+static const char *M = "[win32]";
+
+TEST_CASE("widen string", M) {
+ SECTION("ascii") {
+ const auto &wide = Win32::widen("hello world");
+ REQUIRE(wide == L("hello world"));
+ REQUIRE(wide.size() == 11);
+ }
+
+ SECTION("cyrillic") {
+ const auto &wide = Win32::widen("世界");
+ REQUIRE(wide == L("\u4e16\u754c"));
+#ifdef _WIN32
+ REQUIRE(wide.size() == 2);
+#else
+ REQUIRE(wide.size() == 6);
+#endif
+ }
+}
+
+TEST_CASE("narrow string", M) {
+ SECTION("ascii") {
+ const auto &narrow = Win32::narrow(L("hello world"));
+ REQUIRE(narrow == "hello world");
+ }
+
+ SECTION("cyrillic") {
+ const auto &narrow = Win32::narrow(L("\u4e16\u754c"));
+ REQUIRE(narrow == "世界");
+ }
+}