Skip to content

Instantly share code, notes, and snippets.

@taxilian
Created November 15, 2011 22:58
Show Gist options
  • Save taxilian/1368648 to your computer and use it in GitHub Desktop.
Save taxilian/1368648 to your computer and use it in GitHub Desktop.
DialogManager abstraction for FireBreath
#ifndef DialogManager_h__
#define DialogManager_h__
#include <boost/noncopyable.hpp>
#include <boost/function.hpp>
#include "BrowserHost.h"
typedef boost::function<void (const std::string&)> PathCallback;
namespace FB { class PluginWindow; }
class DialogManager
{
public:
static DialogManager* get();
virtual void OpenFolderDialog(const FB::BrowserHostPtr& host, FB::PluginWindow* win, const PathCallback& cb) = 0;
protected:
DialogManager() {}
virtual ~DialogManager() {}
};
#endif // DialogManager_h__
#ifndef DialogManagerMac_h__
#define DialogManagerMac_h__
#include <boost/noncopyable.hpp>
#include <string>
#include "DialogManager.h"
class DialogManagerMac : public DialogManager
{
public:
void OpenFolderDialog(const FB::BrowserHostPtr& host, FB::PluginWindow* win, const PathCallback& cb);
void _showFolderDialog(FB::PluginWindow* win, const PathCallback& cb);
protected:
DialogManagerMac() {};
~DialogManagerMac() {};
friend class DialogManager;
};
#endif // DialogManagerMac_h__
#include <string>
#include <boost/thread.hpp>
#include <AppKit/AppKit.h>
#include <Cocoa/Cocoa.h>
#include "logging.h"
#include "DialogManagerMac.h"
#include "BrowserHost.h"
DialogManager* DialogManager::get()
{
static DialogManagerMac inst;
return &inst;
}
void DialogManagerMac::OpenFolderDialog(const FB::BrowserHostPtr& host, FB::PluginWindow* win, const PathCallback& cb)
{
host->ScheduleOnMainThread(boost::shared_ptr<DialogManagerMac>(), boost::bind(&DialogManagerMac::_showFolderDialog, this, win, cb));
}
void DialogManagerMac::_showFolderDialog(FB::PluginWindow* win, const PathCallback& cb)
{
FBLOG_INFO("DialogManagerMac", "Showing folder dialog");
std::string out;
int result;
NSAutoreleasePool* pool = [NSAutoreleasePool new];
NSOpenPanel *oPanel = [NSOpenPanel openPanel];
[oPanel setAllowsMultipleSelection:NO];
[oPanel setCanChooseFiles:NO];
[oPanel setCanChooseDirectories:YES];
result = [oPanel runModalForDirectory:nil
file:nil types:nil];
if (result == NSOKButton) {
NSArray *filesToOpen = [oPanel filenames];
NSString *aFile = [filesToOpen objectAtIndex:0];
out = [aFile cStringUsingEncoding:[NSString defaultCStringEncoding]];
FBLOG_INFO("DialogManagerMac", "Folder selected: " << out);
}
[pool release];
cb(out);
}
#include "win_common.h"
#include <commdlg.h>
#include <string>
#include <boost/thread.hpp>
#include "utf8_tools.h"
#include "Win/PluginWindowlessWin.h"
#include "Win/PluginWindowWin.h"
#include "DialogManagerWin.h"
#include <shlobj.h>
#include "precompiled_headers.h" // Anything before this is PCH on windows
DialogManager* DialogManager::get()
{
static DialogManagerWin inst;
return &inst;
}
void DialogManagerWin::OpenFolderDialog(const FB::BrowserHostPtr& host, FB::PluginWindow* win, const PathCallback& cb) {
FB::PluginWindowWin* wndWin = dynamic_cast<FB::PluginWindowWin*>(win);
FB::PluginWindowlessWin* wndlessWin = dynamic_cast<FB::PluginWindowlessWin*>(win);
HWND browserWindow = wndWin ? wndWin->getBrowserHWND() : wndlessWin->getHWND();
boost::thread dlgThread(&DialogManagerWin::_showFolderDialog, this, browserWindow, cb);
}
void DialogManagerWin::_showFolderDialog(HWND wnd, const PathCallback& cb) {
BROWSEINFO bi = { 0 };
bi.lpszTitle = _T("Select a folder to import");
bi.hwndOwner = wnd;
LPITEMIDLIST pidl = SHBrowseForFolder ( &bi );
if ( pidl != 0 )
{
std::wstring out;
// get the name of the folder
TCHAR path[MAX_PATH];
if ( SHGetPathFromIDList ( pidl, path ) )
{
out = path;
}
// free memory used
IMalloc * imalloc = 0;
if ( SUCCEEDED( SHGetMalloc ( &imalloc )) )
{
imalloc->Free ( pidl );
imalloc->Release ( );
}
cb(FB::wstring_to_utf8(path));
} else {
cb("");
}
}
void DialogManagerWin::_showFileDialog(HWND wnd, const std::string& path, const std::string& filter, const PathCallback& cb)
{
wchar_t Filestring[256];
std::string out;
std::wstring wFilter(FB::utf8_to_wstring(filter));
std::wstring wPath(FB::utf8_to_wstring(filter));
OPENFILENAME opf;
opf.hwndOwner = wnd;
opf.lpstrFilter = wFilter.c_str();
opf.lpstrCustomFilter = 0;
opf.nMaxCustFilter = 0L;
opf.nFilterIndex = 1L;
opf.lpstrFile = Filestring;
opf.lpstrFile[0] = '\0';
opf.nMaxFile = 256;
opf.lpstrFileTitle = 0;
opf.nMaxFileTitle=50;
opf.lpstrInitialDir = wPath.c_str();
opf.lpstrTitle = L"Choose directory to import";
opf.nFileOffset = 0;
opf.nFileExtension = 0;
opf.lpstrDefExt = L"*.*";
opf.lpfnHook = NULL;
opf.lCustData = 0;
opf.Flags = (OFN_PATHMUSTEXIST | OFN_OVERWRITEPROMPT) & ~OFN_ALLOWMULTISELECT;
opf.lStructSize = sizeof(OPENFILENAME);
if(GetOpenFileName(&opf))
{
out = FB::wstring_to_utf8(std::wstring(opf.lpstrFile));
}
cb(out);
}
#ifndef DialogManagerWin_h__
#define DialogManagerWin_h__
#include <boost/noncopyable.hpp>
#include <string>
#include "DialogManager.h"
class DialogManagerWin : public DialogManager
{
public:
void OpenFolderDialog(const FB::BrowserHostPtr& host, FB::PluginWindow* win, const PathCallback& cb);
protected:
DialogManagerWin() {};
~DialogManagerWin() {};
void _showFileDialog(HWND wnd, const std::string& path, const std::string& filter, const PathCallback& cb);
void _showFolderDialog(HWND wnd, const PathCallback& cb);
friend class DialogManager;
};
#endif // DialogManagerWin_h__
@Faham
Copy link

Faham commented Jul 18, 2012

Hi can you give an example how I should use your code? I'm trying to use it by the following code:

void LocalExecuteAPI::onReturn(const std::string& path) {
}

FB::variant LocalExecuteAPI::selectBracFile(const FB::variant& msg) {
DialogManager* dlg_mgr = DialogManager::get();
boost::shared_ptr loc_exe = m_plugin.lock();
FB::PluginWindow* wh = loc_exe->GetWindow();
dlg_mgr->OpenFolderDialog(m_host, wh, &LocalExecuteAPI::onReturn);
}

but it shows this error:

...src dir\3rdParty\boost\boost/function/function_template.hpp(225): error C2064: term does not evaluate to a function taking 1 arguments
class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment