linuxdcpp-team team mailing list archive
-
linuxdcpp-team team
-
Mailing list archive
-
Message #06206
[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3093: allow plugins to add commands
------------------------------------------------------------
revno: 3093
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Mon 2012-10-29 19:19:03 +0100
message:
allow plugins to add commands
modified:
changelog.txt
dcpp/PluginApiImpl.cpp
dcpp/PluginApiImpl.h
dcpp/PluginDefs.h
dwt/include/dwt/Widget.h
dwt/src/Widget.cpp
dwt/src/widgets/Menu.cpp
plugins/Dev/Dialog.cpp
plugins/Dev/Dialog.h
plugins/Dev/Plugin.cpp
plugins/Dev/Plugin.h
win32/MainWindow.cpp
win32/MainWindow.h
win32/PluginApiImpl.cpp
--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk
Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'changelog.txt'
--- changelog.txt 2012-10-27 14:30:14 +0000
+++ changelog.txt 2012-10-29 18:19:03 +0000
@@ -3,6 +3,7 @@
* Add "chunked" transfer encoding as per the HTTP/1.1 spec (crise)
* [L#1072041] Fix DPI conversion problems (poy
* Remove the "Windows UPnP" port mapper in favor of MiniUPnP (poy)
+* Add a UI interface to the plugin API (poy)
-- 0.802 2012-10-20 --
* Perf improvements using lock-free queues, requires P6 CPUs (poy)
=== modified file 'dcpp/PluginApiImpl.cpp'
--- dcpp/PluginApiImpl.cpp 2012-10-27 16:10:35 +0000
+++ dcpp/PluginApiImpl.cpp 2012-10-29 18:19:03 +0000
@@ -169,6 +169,9 @@
DCUI PluginApiImpl::dcUI = {
DCINTF_DCPP_UI_VER,
+ &PluginApiImpl::addCommand,
+ &PluginApiImpl::removeCommand,
+
&PluginApiImpl::playSound
};
=== modified file 'dcpp/PluginApiImpl.h'
--- dcpp/PluginApiImpl.h 2012-10-27 16:10:35 +0000
+++ dcpp/PluginApiImpl.h 2012-10-29 18:19:03 +0000
@@ -94,6 +94,9 @@
static void DCAPI addTag(TagDataPtr hTags, size_t start, size_t end, const char* id, const char* attributes);
// Functions for DCUI - the host has to define these
+ static void DCAPI addCommand(const char* name, void (*command)());
+ static void DCAPI removeCommand(const char* name);
+
static void DCAPI playSound(const char* path);
// Functions for DCQueue
=== modified file 'dcpp/PluginDefs.h'
--- dcpp/PluginDefs.h 2012-10-27 16:10:35 +0000
+++ dcpp/PluginDefs.h 2012-10-29 18:19:03 +0000
@@ -420,6 +420,9 @@
/* User interface API version */
uint32_t apiVersion;
+ void (DCAPI *add_command) (const char* name, void (*command)());
+ void (DCAPI *remove_command) (const char* name);
+
void (DCAPI *play_sound) (const char* path);
} DCUI, *DCUIPtr;
=== modified file 'dwt/include/dwt/Widget.h'
--- dwt/include/dwt/Widget.h 2012-07-07 15:36:18 +0000
+++ dwt/include/dwt/Widget.h 2012-10-29 18:19:03 +0000
@@ -111,7 +111,6 @@
typedef std::function<bool(const MSG& msg, LRESULT& ret)> CallbackType;
typedef std::list<CallbackType> CallbackList;
typedef CallbackList::iterator CallbackIter;
- typedef std::unordered_map<Message, CallbackList> CallbackCollectionType;
/// Adds a new callback - multiple callbacks for the same message will be called in the order they were added
CallbackIter addCallback(const Message& msg, const CallbackType& callback);
@@ -122,11 +121,12 @@
/// Clear a callback registered to msg
void clearCallback(const Message& msg, const CallbackIter& i);
+ /// Clear all callbacks registered to msg
+ void clearCallbacks(const Message& msg);
+
/** Run a function bound to this widget asynchronously */
void callAsync(const Application::Callback& f);
- CallbackCollectionType &getCallbacks();
-
/// Returns true if handled, else false
virtual bool handleMessage(const MSG &msg, LRESULT &retVal);
@@ -241,7 +241,7 @@
static GlobalAtom propAtom;
// Contains the list of signals we're (this window) processing
- CallbackCollectionType handlers;
+ std::unordered_map<Message, CallbackList> handlers;
HWND hwnd;
@@ -278,10 +278,6 @@
return (::GetWindowLong(handle(), GWL_EXSTYLE) & style) == style;
}
-inline Widget::CallbackCollectionType& Widget::getCallbacks() {
- return handlers;
-}
-
inline HWND Widget::getParentHandle() {
return getParent() ? getParent()->handle() : NULL;
}
=== modified file 'dwt/src/Widget.cpp'
--- dwt/src/Widget.cpp 2012-07-07 15:36:18 +0000
+++ dwt/src/Widget.cpp 2012-10-29 18:19:03 +0000
@@ -124,6 +124,13 @@
void Widget::clearCallback(const Message& msg, const CallbackIter& i) {
CallbackList& callbacks = handlers[msg];
callbacks.erase(i);
+ if(callbacks.empty()) {
+ handlers.erase(msg);
+ }
+}
+
+void Widget::clearCallbacks(const Message& msg) {
+ handlers.erase(msg);
}
/// Make sure that handle is still valid before calling f
=== modified file 'dwt/src/widgets/Menu.cpp'
--- dwt/src/widgets/Menu.cpp 2012-06-18 16:32:14 +0000
+++ dwt/src/widgets/Menu.cpp 2012-10-29 18:19:03 +0000
@@ -755,17 +755,21 @@
}
}
- // remove from the child list if this was a sub-menu.
if(child) {
+ // remove this sub-menu from the child list.
itsChildren.erase(std::remove_if(itsChildren.begin(), itsChildren.end(),
[child](std::unique_ptr<Menu>& sub) { return sub->handle() == child; }), itsChildren.end());
+
+ } else if(!getRootMenu()->popup) {
+ // in the menu bar: remove the callback.
+ getParent()->clearCallbacks(Message(WM_MENUCOMMAND, index * 31 + reinterpret_cast<LPARAM>(handle())));
}
}
void Menu::removeAllItems() {
- //must be backwards, since bigger indexes change on remove
- for(int i = size() - 1; i >= 0; i--) {
- removeItem( i );
+ // must be backwards, since higher indexes change when removing lower ones
+ for(int i = size() - 1, end = itsTitle.empty() ? 0 : 1; i >= end; --i) {
+ removeItem(i);
}
}
=== modified file 'plugins/Dev/Dialog.cpp'
--- plugins/Dev/Dialog.cpp 2012-08-02 17:49:34 +0000
+++ plugins/Dev/Dialog.cpp 2012-10-29 18:19:03 +0000
@@ -18,6 +18,7 @@
#include "stdafx.h"
#include "Dialog.h"
+#include "Plugin.h"
#include "resource.h"
#include "Util.h"
@@ -44,16 +45,14 @@
}
Dialog::~Dialog() {
- if(hwnd) {
- DestroyWindow(hwnd);
- }
+ close();
dlg = nullptr;
}
-void Dialog::create(HWND parent) {
+void Dialog::create() {
if(hwnd) {
- MessageBox(parent, Util::toT("The dev plugin hasn't been properly shut down; you better restart " + Util::appName).c_str(),
+ MessageBox(0, Util::toT("The dev plugin hasn't been properly shut down; you better restart " + Util::appName).c_str(),
_T("Error creating the dev plugin's dialog"), MB_OK);
return;
}
@@ -63,7 +62,7 @@
if(!hwnd) {
TCHAR buf[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, 0, GetLastError(), 0, buf, 256, 0);
- MessageBox(parent, buf, _T("Error creating the dev plugin's dialog"), MB_OK);
+ MessageBox(0, buf, _T("Error creating the dev plugin's dialog"), MB_OK);
}
}
@@ -73,6 +72,13 @@
messages.push_back(move(msg));
}
+void Dialog::close() {
+ if(hwnd) {
+ DestroyWindow(hwnd);
+ hwnd = nullptr;
+ }
+}
+
INT_PTR CALLBACK Dialog::DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM) {
switch(uMsg) {
case WM_INITDIALOG:
@@ -92,7 +98,7 @@
}
case WM_CLOSE:
{
- delete dlg;
+ Plugin::dlgClosed();
break;
}
case WM_DESTROY:
=== modified file 'plugins/Dev/Dialog.h'
--- plugins/Dev/Dialog.h 2012-07-26 17:35:04 +0000
+++ plugins/Dev/Dialog.h 2012-10-29 18:19:03 +0000
@@ -40,8 +40,9 @@
Dialog();
~Dialog();
- void create(HWND parent);
+ void create();
void write(bool hubOrUser, bool sending, string ip, string peer, string message);
+ void close();
static HINSTANCE instance;
=== modified file 'plugins/Dev/Plugin.cpp'
--- plugins/Dev/Plugin.cpp 2012-08-02 17:49:34 +0000
+++ plugins/Dev/Plugin.cpp 2012-10-29 18:19:03 +0000
@@ -22,13 +22,17 @@
Plugin* Plugin::instance = nullptr;
+const char* switchText = "Dev plugin: enable/disable";
+
Plugin::Plugin() {
}
Plugin::~Plugin() {
- for(auto& i: events)
- hooks->release_hook(i.second);
- events.clear();
+ clearHooks();
+
+ if(ui) {
+ ui->remove_command(switchText);
+ }
}
Bool DCAPI Plugin::main(PluginState state, DCCorePtr core, dcptr_t) {
@@ -37,15 +41,16 @@
case ON_LOAD:
{
Bool res = True;
- newInstance();
- getInstance()->onLoad(core, (state == ON_INSTALL), res);
+ instance = new Plugin();
+ instance->onLoad(core, (state == ON_INSTALL), res);
return res;
}
case ON_UNINSTALL:
case ON_UNLOAD:
{
- deleteInstance();
+ delete instance;
+ instance = nullptr;
return True;
}
@@ -56,6 +61,37 @@
}
}
+void Plugin::dlgClosed() {
+ instance->close();
+}
+
+void Plugin::addHooks() {
+ events[HOOK_NETWORK_HUB_IN] = hooks->bind_hook(HOOK_NETWORK_HUB_IN, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
+ return instance->onHubDataIn(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData)); }, nullptr);
+ events[HOOK_NETWORK_HUB_OUT] = hooks->bind_hook(HOOK_NETWORK_HUB_OUT, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
+ return instance->onHubDataOut(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData)); }, nullptr);
+ events[HOOK_NETWORK_CONN_IN] = hooks->bind_hook(HOOK_NETWORK_CONN_IN, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
+ return instance->onConnectionDataIn(reinterpret_cast<ConnectionDataPtr>(pObject), reinterpret_cast<char*>(pData)); }, nullptr);
+ events[HOOK_NETWORK_CONN_OUT] = hooks->bind_hook(HOOK_NETWORK_CONN_OUT, [](dcptr_t pObject, dcptr_t pData, dcptr_t, Bool*) {
+ return instance->onConnectionDataOut(reinterpret_cast<ConnectionDataPtr>(pObject), reinterpret_cast<char*>(pData)); }, nullptr);
+}
+
+void Plugin::clearHooks() {
+ for(auto& i: events)
+ hooks->release_hook(i.second);
+ events.clear();
+}
+
+void Plugin::start() {
+ dialog.create();
+ addHooks();
+}
+
+void Plugin::close() {
+ clearHooks();
+ dialog.close();
+}
+
void Plugin::onLoad(DCCorePtr core, bool install, Bool& loadRes) {
dcpp = core;
hooks = reinterpret_cast<DCHooksPtr>(core->query_interface(DCINTF_HOOKS, DCINTF_HOOKS_VER));
@@ -63,38 +99,31 @@
auto utils = reinterpret_cast<DCUtilsPtr>(core->query_interface(DCINTF_DCPP_UTILS, DCINTF_DCPP_UTILS_VER));
auto config = reinterpret_cast<DCConfigPtr>(core->query_interface(DCINTF_CONFIG, DCINTF_CONFIG_VER));
auto logger = reinterpret_cast<DCLogPtr>(core->query_interface(DCINTF_LOGGING, DCINTF_LOGGING_VER));
+ ui = reinterpret_cast<DCUIPtr>(core->query_interface(DCINTF_DCPP_UI, DCINTF_DCPP_UI_VER));
- if(!utils || !config || !logger) {
+ if(!utils || !config || !logger || !ui) {
loadRes = False;
return;
}
Util::initialize(core->host_name(), utils, config, logger);
- /*if(install) {
- // Default settings
-
- Util::logMessage("Dev plugin installed, please restart " + Util::appName + " to begin using the plugin.");
- return;
- }*/
-
- events[HOOK_HUB_OFFLINE] = hooks->bind_hook(HOOK_HUB_OFFLINE, &hubOfflineEvent, NULL);
- events[HOOK_HUB_ONLINE] = hooks->bind_hook(HOOK_HUB_ONLINE, &hubOnlineEvent, NULL);
-
- events[HOOK_NETWORK_HUB_IN] = hooks->bind_hook(HOOK_NETWORK_HUB_IN, &netHubInEvent, NULL);
- events[HOOK_NETWORK_HUB_OUT] = hooks->bind_hook(HOOK_NETWORK_HUB_OUT, &netHubOutEvent, NULL);
- events[HOOK_NETWORK_CONN_IN] = hooks->bind_hook(HOOK_NETWORK_CONN_IN, &netConnInEvent, NULL);
- events[HOOK_NETWORK_CONN_OUT] = hooks->bind_hook(HOOK_NETWORK_CONN_OUT, &netConnOutEvent, NULL);
-
- events[HOOK_UI_CREATED] = hooks->bind_hook(HOOK_UI_CREATED, &uiCreatedEvent, NULL);
-}
-
-Bool Plugin::onHubDisconnected(HubDataPtr hHub) {
- return False;
-}
-
-Bool Plugin::onHubConnected(HubDataPtr hHub) {
- return False;
+ if(install) {
+ /// @todo config enabled/disabled
+
+ Util::logMessage("The dev plugin has been installed; check the \"" + string(switchText) + "\" command.");
+ }
+
+ start();
+ ui->add_command(switchText, [] { instance->onSwitched(); });
+}
+
+void Plugin::onSwitched() {
+ if(events.empty()) {
+ start();
+ } else {
+ close();
+ }
}
Bool Plugin::onHubDataIn(HubDataPtr hHub, const char* message) {
@@ -102,7 +131,7 @@
return False;
}
-Bool Plugin::onHubDataOut(HubDataPtr hHub, const char* message, Bool* bBreak) {
+Bool Plugin::onHubDataOut(HubDataPtr hHub, const char* message) {
dialog.write(true, true, hHub->ip, "Hub " + string(hHub->url), message);
return False;
}
@@ -116,8 +145,3 @@
dialog.write(false, true, hConn->ip, "User" /** @todo get user's nick */, message);
return False;
}
-
-Bool Plugin::onUiCreated(HWND hwnd) {
- dialog.create(hwnd);
- return False;
-}
=== modified file 'plugins/Dev/Plugin.h'
--- plugins/Dev/Plugin.h 2012-07-19 22:00:20 +0000
+++ plugins/Dev/Plugin.h 2012-10-29 18:19:03 +0000
@@ -19,8 +19,6 @@
#ifndef PLUGINS_DEV_PLUGIN_H
#define PLUGINS_DEV_PLUGIN_H
-#include <Singleton.h>
-
#include <map>
#include "Dialog.h"
@@ -28,42 +26,40 @@
using std::map;
using std::string;
-class Plugin : public dcpp::Singleton<Plugin>
+class Plugin
{
public:
static Bool DCAPI main(PluginState state, DCCorePtr core, dcptr_t);
+ static void dlgClosed();
+
private:
- friend class dcpp::Singleton<Plugin>;
-
Plugin();
~Plugin();
+ void addHooks();
+ void clearHooks();
+
+ void start();
+ void close();
+
void onLoad(DCCorePtr core, bool install, Bool& loadRes);
- Bool onHubDisconnected(HubDataPtr hHub);
- Bool onHubConnected(HubDataPtr hHub);
+ void onSwitched();
Bool onHubDataIn(HubDataPtr hHub, const char* message);
- Bool onHubDataOut(HubDataPtr hHub, const char* message, Bool* bBreak);
+ Bool onHubDataOut(HubDataPtr hHub, const char* message);
Bool onConnectionDataIn(ConnectionDataPtr hConn, const char* message);
Bool onConnectionDataOut(ConnectionDataPtr hConn, const char* message);
- Bool onUiCreated(HWND hwnd);
-
- // Event wrappers
- static Bool DCAPI hubOfflineEvent(dcptr_t pObject, dcptr_t /*pData*/, dcptr_t, Bool* /*bBreak*/) { return getInstance()->onHubDisconnected(reinterpret_cast<HubDataPtr>(pObject)); }
- static Bool DCAPI hubOnlineEvent(dcptr_t pObject, dcptr_t /*pData*/, dcptr_t, Bool* /*bBreak*/) { return getInstance()->onHubConnected(reinterpret_cast<HubDataPtr>(pObject)); }
- static Bool DCAPI netHubInEvent(dcptr_t pObject, dcptr_t pData, dcptr_t, Bool* /*bBreak*/) { return getInstance()->onHubDataIn(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData)); }
- static Bool DCAPI netHubOutEvent(dcptr_t pObject, dcptr_t pData, dcptr_t, Bool* bBreak) { return getInstance()->onHubDataOut(reinterpret_cast<HubDataPtr>(pObject), reinterpret_cast<char*>(pData), bBreak); }
- static Bool DCAPI netConnInEvent(dcptr_t pObject, dcptr_t pData, dcptr_t, Bool* /*bBreak*/) { return getInstance()->onConnectionDataIn(reinterpret_cast<ConnectionDataPtr>(pObject), reinterpret_cast<char*>(pData)); }
- static Bool DCAPI netConnOutEvent(dcptr_t pObject, dcptr_t pData, dcptr_t, Bool* /*bBreak*/) { return getInstance()->onConnectionDataOut(reinterpret_cast<ConnectionDataPtr>(pObject), reinterpret_cast<char*>(pData)); }
- static Bool DCAPI uiCreatedEvent(dcptr_t pObject, dcptr_t /*pData*/, dcptr_t, Bool* /*bBreak*/) { return getInstance()->onUiCreated(reinterpret_cast<HWND>(pObject)); }
map<string, subsHandle> events;
DCCorePtr dcpp;
DCHooksPtr hooks;
+ DCUIPtr ui;
Dialog dialog;
+ /** @todo switch to dcpp::Singleton when <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=51494>
+ is fixed */
static Plugin* instance;
};
=== modified file 'win32/MainWindow.cpp'
--- win32/MainWindow.cpp 2012-10-20 16:10:39 +0000
+++ win32/MainWindow.cpp 2012-10-29 18:19:03 +0000
@@ -90,6 +90,8 @@
using dwt::Spinner;
using dwt::ToolBar;
+map<tstring, function<void ()>, noCaseStringLess> MainWindow::pluginCommands;
+
static dwt::IconPtr mainIcon(WinUtil::createIcon(IDI_DCPP, 32));
static dwt::IconPtr mainSmallIcon(WinUtil::createIcon(IDI_DCPP, 16));
@@ -308,6 +310,10 @@
file->appendItem(T_("GeoIP database update"), [this] { updateGeo(); });
file->appendSeparator();
+ pluginMenu = file->appendPopup(T_("Plugins"));
+ refreshPluginMenu();
+ file->appendSeparator();
+
file->appendItem(T_("E&xit\tAlt+F4"), [this] { close(true); }, WinUtil::menuIcon(IDI_EXIT));
}
@@ -641,7 +647,40 @@
return false;
}
-void MainWindow::notify(const tstring& title, const tstring& message, const std::function<void ()>& callback, const dwt::IconPtr& balloonIcon) {
+void MainWindow::addPluginCommand(const tstring& text, function<void ()> command) {
+ pluginCommands.emplace(text, command);
+
+ if(WinUtil::mainWindow && !WinUtil::mainWindow->closing()) {
+ WinUtil::mainWindow->pluginMenu->removeAllItems();
+ WinUtil::mainWindow->refreshPluginMenu();
+ }
+}
+
+void MainWindow::removePluginCommand(const tstring& text) {
+ auto i = pluginCommands.find(text);
+ if(i == pluginCommands.end()) return;
+ auto index = std::distance(pluginCommands.begin(), i);
+ pluginCommands.erase(i);
+
+ if(WinUtil::mainWindow && !WinUtil::mainWindow->closing()) {
+ WinUtil::mainWindow->pluginMenu->removeItem(index + 1 /* account for the menu title */);
+ if(pluginCommands.empty()) {
+ WinUtil::mainWindow->refreshPluginMenu();
+ }
+ }
+}
+
+void MainWindow::refreshPluginMenu() {
+ if(pluginCommands.empty()) {
+ pluginMenu->appendItem(T_("(No plugin command found)"), nullptr, nullptr, false);
+ } else {
+ for(auto& i: pluginCommands) {
+ pluginMenu->appendItem(i.first, i.second);
+ }
+ }
+}
+
+void MainWindow::notify(const tstring& title, const tstring& message, function<void ()> callback, const dwt::IconPtr& balloonIcon) {
notifier->addMessage(str(TF_("DC++ - %1%") % title), message, [this, callback] { handleRestore(); if(callback) callback(); }, balloonIcon);
}
@@ -981,9 +1020,10 @@
// This should end immediately, as it only should be the stopper that sends another WM_CLOSE
WaitForSingleObject(stopperThread, 60*1000);
CloseHandle(stopperThread);
- stopperThread = NULL;
::PostQuitMessage(0);
dcdebug("Quit message posted\n");
+
+ WinUtil::mainWindow = nullptr;
return true;
}
=== modified file 'win32/MainWindow.h'
--- win32/MainWindow.h 2012-10-20 16:10:39 +0000
+++ win32/MainWindow.h 2012-10-29 18:19:03 +0000
@@ -30,6 +30,7 @@
#include "forward.h"
#include "AspectStatus.h"
+using std::function;
using std::unique_ptr;
class MainWindow :
@@ -64,8 +65,11 @@
void handleSettings();
+ static void addPluginCommand(const tstring& text, function<void ()> command);
+ static void removePluginCommand(const tstring& text);
+
/** show a balloon popup. refer to the dwt::Notification::addMessage doc for info about parameters. */
- void notify(const tstring& title, const tstring& message, const std::function<void ()>& callback = nullptr, const dwt::IconPtr& balloonIcon = nullptr);
+ void notify(const tstring& title, const tstring& message, function<void ()> callback = nullptr, const dwt::IconPtr& balloonIcon = nullptr);
void setStaticWindowState(const string& id, bool open);
void TrayPM();
@@ -118,6 +122,7 @@
RebarPtr rebar;
SplitterContainerPtr paned;
MenuPtr mainMenu;
+ Menu* pluginMenu;
Menu* viewMenu;
TransferView* transfers;
ToolBarPtr toolbar;
@@ -128,6 +133,10 @@
bool tray_pm;
+ /* sorted list of plugin commands. static because they may be added before the window has
+ actually been created. */
+ static map<tstring, function<void ()>, noCaseStringLess> pluginCommands;
+
unique_ptr<HttpDownload> conns[CONN_LAST];
HANDLE stopperThread;
@@ -197,6 +206,7 @@
void layout();
void updateStatus();
void updateAwayStatus();
+ void refreshPluginMenu();
void showPortsError(const string& port);
void setSaveTimer();
void saveSettings();
=== modified file 'win32/PluginApiImpl.cpp'
--- win32/PluginApiImpl.cpp 2012-10-27 16:10:35 +0000
+++ win32/PluginApiImpl.cpp 2012-10-29 18:19:03 +0000
@@ -24,11 +24,20 @@
#include <dcpp/Text.h>
+#include "MainWindow.h"
#include "WinUtil.h"
namespace dcpp {
// Functions for DCUI
+void PluginApiImpl::addCommand(const char* name, void (*command)()) {
+ MainWindow::addPluginCommand(Text::toT(name), command);
+}
+
+void PluginApiImpl::removeCommand(const char* name) {
+ MainWindow::removePluginCommand(Text::toT(name));
+}
+
void PluginApiImpl::playSound(const char* path) {
WinUtil::playSound(Text::toT(path));
}