Add support for Unicode file names on Windows

- Fixed issue #46: open .png files with Unicode chars
- Fixed issue #150: ability to uncompress program in folders w/Unicode chars
- Added base::utf8_iterator
- Added base::FileHandle
- Added base::get_app_path()
- Modified ui::KeyMessage::ascii() -> unicodeChar()
- Removed JI_NOTEXT flag
- Added app::XmlDocumentRef class and app::open_xml() function
- Added support for Unicode text exchange with Win32 clipboard
This commit is contained in:
David Capello 2013-10-14 19:58:11 -03:00
parent 092ae7b2d6
commit 5b252c30f5
121 changed files with 1020 additions and 617 deletions

View File

@ -220,6 +220,9 @@ if(WIN32)
# Windows XP is the minimum supported platform.
add_definitions(-D_WIN32_WINNT=0x0501 -DWINVER=0x0501)
# We need Unicode support
add_definitions(-DUNICODE -D_UNICODE)
endif(WIN32)
# -- Mac OS X --

View File

@ -69,7 +69,7 @@ AL_FUNC(void, save_window_pos, (void));
/* main window */
#define WND_TITLE_SIZE 128
AL_ARRAY(char, wnd_title);
AL_ARRAY(wchar_t, wnd_title);
AL_VAR(int, wnd_x);
AL_VAR(int, wnd_y);
AL_VAR(int, wnd_width);

View File

@ -1961,7 +1961,7 @@ PACKFILE *pack_fopen_chunk(PACKFILE *f, int pack)
do {
size = new_size;
tmp_dir = _AL_REALLOC(tmp_dir, size);
new_size = GetTempPath(size, tmp_dir);
new_size = GetTempPathA(size, tmp_dir);
} while ( (size < new_size) && (new_size > 0) );
/* Check if we retrieved the path OK */

View File

@ -0,0 +1,30 @@
// Copyright (C) 2013 by David Capello
#ifndef ALLEGRO_WIN_UTF8_H
#define ALLEGRO_WIN_UTF8_H
static char* convert_widechar_to_utf8(const wchar_t* wstr)
{
char* u8str;
int wlen = wcslen(wstr);
int u8len = WideCharToMultiByte(CP_UTF8, 0, wstr, wlen, NULL, 0, NULL, NULL);
u8len++;
u8str = _AL_MALLOC(u8len);
u8str[u8len-1] = 0;
WideCharToMultiByte(CP_UTF8, 0, wstr, wlen, u8str, u8len, NULL, NULL);
return u8str;
}
static wchar_t* convert_utf8_to_widechar(const char* u8str)
{
wchar_t* wstr;
int u8len = strlen(u8str);
int wlen = MultiByteToWideChar(CP_UTF8, 0, u8str, u8len, NULL, 0);
wlen++;
wstr = _AL_MALLOC(wlen * sizeof(wchar_t));
wstr[wlen-1] = 0;
MultiByteToWideChar(CP_UTF8, 0, u8str, u8len, wstr, wlen);
return wstr;
}
#endif

View File

@ -105,7 +105,7 @@ int get_dx_ver(void)
}
/* First check for DX 8 and 9 */
dsetup_hinst = LoadLibrary( "DSETUP.DLL" );
dsetup_hinst = LoadLibrary( L"DSETUP.DLL" );
if ( dsetup_hinst ) {
DSetupCreate = (DSETUPCREATE)GetProcAddress(dsetup_hinst, "DirectXSetupGetVersion");
if ( DSetupCreate ) {
@ -171,10 +171,10 @@ int get_dx_ver(void)
dx_version = 0x200;
/* we are not supposed to be able to tell which SP we are on, so check for DInput */
dinput_hinst = LoadLibrary("DINPUT.DLL");
dinput_hinst = LoadLibrary(L"DINPUT.DLL");
if (!dinput_hinst) {
/* no DInput... must be DX2 on NT 4 pre-SP3 */
OutputDebugString("Couldn't LoadLibrary DInput\r\n");
OutputDebugString(L"Couldn't LoadLibrary DInput\r\n");
return dx_version;
}
@ -200,7 +200,7 @@ int get_dx_ver(void)
/* now we know we are in Windows 9x (or maybe 3.1), so anything's possible;
* first see if DDRAW.DLL even exists.
*/
ddraw_hinst = LoadLibrary("DDRAW.DLL");
ddraw_hinst = LoadLibrary(L"DDRAW.DLL");
if (!ddraw_hinst) {
dx_version = 0;
goto End;
@ -236,7 +236,7 @@ int get_dx_ver(void)
dx_version = 0x200;
/* see if we can create the DirectInput object */
dinput_hinst = LoadLibrary("DINPUT.DLL");
dinput_hinst = LoadLibrary(L"DINPUT.DLL");
if (!dinput_hinst) {
/* no DInput... must be DX2 */
goto End;

View File

@ -25,6 +25,7 @@
#include "allegro.h"
#include "allegro/internal/aintern.h"
#include "allegro/platform/aintwin.h"
#include "utf8.h"
#ifndef ALLEGRO_WINDOWS
#error something is wrong with the makefile
@ -235,10 +236,10 @@ static void sys_directx_exit(void)
*/
static void sys_directx_get_executable_name(char *output, int size)
{
char *temp = _AL_MALLOC_ATOMIC(size);
wchar_t* temp = _AL_MALLOC_ATOMIC(size);
if (GetModuleFileName(allegro_inst, temp, size))
do_uconvert(temp, U_ASCII, output, U_CURRENT, size);
do_uconvert((char*)temp, U_UNICODE, output, U_CURRENT, size);
else
usetc(output, 0);
@ -254,7 +255,7 @@ static void sys_directx_set_window_title(AL_CONST char *name)
{
HWND allegro_wnd = win_get_window();
do_uconvert(name, U_CURRENT, wnd_title, U_ASCII, WND_TITLE_SIZE);
do_uconvert(name, U_CURRENT, (char*)wnd_title, U_UNICODE, WND_TITLE_SIZE);
SetWindowText(allegro_wnd, wnd_title);
}
@ -320,8 +321,8 @@ static void sys_directx_message(AL_CONST char *msg)
msg += uwidth(msg);
MessageBoxW(allegro_wnd,
(unsigned short *)uconvert(msg, U_CURRENT, tmp1, U_UNICODE, ALLEGRO_MESSAGE_SIZE),
(unsigned short *)uconvert(wnd_title, U_ASCII, tmp2, U_UNICODE, sizeof(tmp2)),
(wchar_t*)uconvert(msg, U_CURRENT, tmp1, U_UNICODE, ALLEGRO_MESSAGE_SIZE),
(wchar_t*)uconvert((char*)wnd_title, U_CURRENT, tmp2, U_UNICODE, sizeof(tmp2)),
MB_OK);
_AL_FREE(tmp1);
@ -334,7 +335,7 @@ static void sys_directx_message(AL_CONST char *msg)
*/
static void sys_directx_assert(AL_CONST char *msg)
{
OutputDebugString(msg); /* thread safe */
OutputDebugStringA(msg); /* thread safe */
DebugBreak();
}
@ -447,7 +448,7 @@ static void sys_directx_yield_timeslice(void)
*/
static int sys_directx_trace_handler(AL_CONST char *msg)
{
OutputDebugString(msg); /* thread safe */
OutputDebugStringA(msg); /* thread safe */
return 0;
}
@ -458,25 +459,26 @@ static int sys_directx_trace_handler(AL_CONST char *msg)
* which makes it look as if the application can still have a normal
* main() function.
*/
int _WinMain(void *_main, void *hInst, void *hPrev, char *Cmd, int nShow)
int _WinMain(void* _main, void* hInst, void* hPrev, char* Cmd, int nShow)
{
int (*mainfunc) (int argc, char *argv[]) = (int (*)(int, char *[]))_main;
char *argbuf;
char *cmdline;
char **argv;
int (*mainfunc)(int argc, char *argv[]) = (int (*)(int, char *[]))_main;
wchar_t* argbuf;
wchar_t* cmdline;
wchar_t* arg_w;
char** argv;
int argc;
int argc_max;
int i, q;
int i, j, q;
/* can't use parameter because it doesn't include the executable name */
cmdline = GetCommandLine();
i = strlen(cmdline) + 1;
i = sizeof(wchar_t) * (wcslen(cmdline) + 1);
argbuf = _AL_MALLOC(i);
memcpy(argbuf, cmdline, i);
argc = 0;
argc_max = 64;
argv = _AL_MALLOC(sizeof(char *) * argc_max);
argv = _AL_MALLOC(sizeof(char*) * argc_max);
if (!argv) {
_AL_FREE(argbuf);
return 1;
@ -486,11 +488,11 @@ int _WinMain(void *_main, void *hInst, void *hPrev, char *Cmd, int nShow)
/* parse commandline into argc/argv format */
while (argbuf[i]) {
while ((argbuf[i]) && (uisspace(argbuf[i])))
while ((argbuf[i]) && (iswspace(argbuf[i])))
i++;
if (argbuf[i]) {
if ((argbuf[i] == '\'') || (argbuf[i] == '"')) {
if ((argbuf[i] == L'\'') || (argbuf[i] == L'"')) {
q = argbuf[i++];
if (!argbuf[i])
break;
@ -498,7 +500,8 @@ int _WinMain(void *_main, void *hInst, void *hPrev, char *Cmd, int nShow)
else
q = 0;
argv[argc++] = &argbuf[i];
arg_w = argbuf+i;
++argc;
if (argc >= argc_max) {
argc_max += 64;
@ -509,23 +512,28 @@ int _WinMain(void *_main, void *hInst, void *hPrev, char *Cmd, int nShow)
}
}
while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (!uisspace(argbuf[i]))))
while ((argbuf[i]) && ((q) ? (argbuf[i] != q) : (!iswspace(argbuf[i]))))
i++;
if (argbuf[i]) {
argbuf[i] = 0;
i++;
}
argv[argc-1] = convert_widechar_to_utf8(arg_w);
}
}
argv[argc] = NULL;
_AL_FREE(argbuf);
/* call the application entry point */
i = mainfunc(argc, argv);
for (j=0; j<argc; ++j)
_AL_FREE(argv[j]);
_AL_FREE(argv);
_AL_FREE(argbuf);
return i;
}
@ -539,9 +547,9 @@ char *win_err_str(long err)
{
static char msg[256];
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&msg, 0, NULL);
FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&msg[0], 0, NULL);
return msg;
}
@ -561,5 +569,5 @@ void thread_safe_trace(char *msg,...)
vsprintf(buf, msg, ap);
va_end(ap);
OutputDebugString(buf); /* thread safe */
OutputDebugStringA(buf); /* thread safe */
}

View File

@ -53,21 +53,20 @@ void _win_thread_init(void)
if (first_call) {
first_call = 0;
ole32 = GetModuleHandle("OLE32.DLL");
ole32 = GetModuleHandleA("OLE32.DLL");
if (ole32 != NULL) {
_CoInitializeEx = (_CoInitializeEx_ptr) GetProcAddress(
ole32, "CoInitializeEx");
_CoInitializeEx = (_CoInitializeEx_ptr)GetProcAddress(ole32, "CoInitializeEx");
}
else {
MessageBox(allegro_wnd,
"OLE32.DLL can't be loaded.", "Warning", MB_ICONWARNING + MB_OK);
MessageBoxA(allegro_wnd,
"OLE32.DLL can't be loaded.", "Warning", MB_ICONWARNING + MB_OK);
}
if (_CoInitializeEx == NULL) {
MessageBox(allegro_wnd,
"Microsoft Distributed COM is not installed on this system. If you have problems "
"with this application, please install the DCOM update. You can find it on the "
"Microsoft homepage.", "DCOM not found", MB_ICONWARNING + MB_OK);
MessageBoxA(allegro_wnd,
"Microsoft Distributed COM is not installed on this system. If you have problems "
"with this application, please install the DCOM update. You can find it on the "
"Microsoft homepage.", "DCOM not found", MB_ICONWARNING + MB_OK);
}
}

View File

@ -40,7 +40,7 @@
/* general */
static HWND allegro_wnd = NULL;
char wnd_title[WND_TITLE_SIZE]; /* ASCII string */
wchar_t wnd_title[WND_TITLE_SIZE]; /* Unicode string title */
int wnd_x = 0;
int wnd_y = 0;
int wnd_width = 0;
@ -66,7 +66,7 @@ static BOOL sizing = FALSE;
void (*user_resize_proc)(RESIZE_DISPLAY_EVENT *ev) = NULL;
/* window thread internals */
#define ALLEGRO_WND_CLASS "ASEWindowClass"
#define ALLEGRO_WND_CLASS L"AsepriteWindowClass"
static HANDLE wnd_thread = NULL;
static int old_style = 0;
@ -432,7 +432,7 @@ static HWND create_directx_window(void)
wnd_class.cbClsExtra = 0;
wnd_class.cbWndExtra = 0;
wnd_class.hInstance = allegro_inst;
wnd_class.hIcon = LoadIcon(allegro_inst, "allegro_icon");
wnd_class.hIcon = LoadIcon(allegro_inst, L"allegro_icon");
if (!wnd_class.hIcon)
wnd_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wnd_class.hCursor = LoadCursor(NULL, IDC_ARROW);
@ -450,7 +450,7 @@ static HWND create_directx_window(void)
if (ugetat(fname, -1) == '.')
usetat(fname, -1, 0);
do_uconvert(get_filename(fname), U_CURRENT, wnd_title, U_ASCII, WND_TITLE_SIZE);
do_uconvert(get_filename(fname), U_CURRENT, (char*)wnd_title, U_UNICODE, WND_TITLE_SIZE);
first = 0;
}
@ -515,8 +515,8 @@ int init_directx_window(void)
DWORD threadId;
/* setup globals */
msg_call_proc = RegisterWindowMessage("Allegro call proc");
msg_suicide = RegisterWindowMessage("Allegro window suicide");
msg_call_proc = RegisterWindowMessage(L"Allegro call proc");
msg_suicide = RegisterWindowMessage(L"Allegro window suicide");
/* create window thread */
events[0] = CreateEvent(NULL, FALSE, FALSE, NULL); /* acknowledges that thread is up */
@ -601,7 +601,7 @@ int adjust_window(int w, int h)
}
else {
/* try to get the height of the window's title bar */
user32_handle = GetModuleHandle("user32");
user32_handle = GetModuleHandle(L"user32");
if (user32_handle) {
get_title_bar_info
= (func)GetProcAddress(user32_handle, "GetTitleBarInfo");

View File

@ -230,4 +230,5 @@ add_library(app-library
util/thmbnail.cpp
webserver.cpp
widget_loader.cpp
xml_document.cpp
xml_exception.cpp)

View File

@ -70,8 +70,8 @@ AppMenus::AppMenus()
void AppMenus::reload()
{
TiXmlDocument& doc(GuiXml::instance()->doc());
TiXmlHandle handle(&doc);
XmlDocumentRef doc(GuiXml::instance()->doc());
TiXmlHandle handle(doc);
const char* path = GuiXml::instance()->filename();
/**************************************************/
@ -304,7 +304,7 @@ Widget* AppMenus::convertXmlelemToMenuitem(TiXmlElement* elem)
{
// is it a <separator>?
if (strcmp(elem->Value(), "separator") == 0)
return new Separator(NULL, JI_HORIZONTAL);
return new Separator("", JI_HORIZONTAL);
const char* command_name = elem->Attribute("command");
Command* command =
@ -361,7 +361,7 @@ Widget* AppMenus::createInvalidVersionMenuitem()
subMenu->addChild(new AppMenuItem(PACKAGE " is using a customized gui.xml (maybe from your HOME directory).", NULL, NULL));
subMenu->addChild(new AppMenuItem("You should update your customized gui.xml file to the new version to get", NULL, NULL));
subMenu->addChild(new AppMenuItem("the latest commands available.", NULL, NULL));
subMenu->addChild(new Separator(NULL, JI_HORIZONTAL));
subMenu->addChild(new Separator("", JI_HORIZONTAL));
subMenu->addChild(new AppMenuItem("You can bypass this validation adding the correct version", NULL, NULL));
subMenu->addChild(new AppMenuItem("number in <gui version=\"" VERSION "\"> element.", NULL, NULL));
menuitem->setSubmenu(subMenu);

View File

@ -53,7 +53,7 @@ void AboutCommand::onExecute(Context* context)
Label* title = new Label(PACKAGE " v" VERSION);
Label* subtitle = new Label("Animated sprite editor && pixel art tool");
Separator* authors_separator1 = new Separator("Authors:", JI_HORIZONTAL | JI_TOP);
Separator* authors_separator2 = new Separator(NULL, JI_HORIZONTAL);
Separator* authors_separator2 = new Separator("", JI_HORIZONTAL);
Label* author1 = new LinkLabel("http://dacap.com.ar/", "David Capello");
Label* author1_desc = new Label("| Programming");
Label* author2 = new LinkLabel("http://ilkke.blogspot.com/", "Ilija Melentijevic");

View File

@ -40,8 +40,6 @@
#include "raster/mask.h"
#include "ui/ui.h"
#include <allegro.h>
namespace app {
using namespace gfx;

View File

@ -53,7 +53,7 @@ public:
for (Documents::const_iterator
it = context->getDocuments().begin(),
end = context->getDocuments().end(); it != end; ++it) {
m_docs.addItem((*it)->getFilename());
m_docs.addItem((*it)->getFilename().c_str());
}
m_docs.addItem("---------");
}

View File

@ -28,10 +28,10 @@
#include "app/load_widget.h"
#include "app/modules/editors.h"
#include "app/ui_context.h"
#include "base/path.h"
#include "raster/sprite.h"
#include "ui/ui.h"
#include <allegro.h>
#include <cstdio>
namespace app {
@ -65,7 +65,6 @@ void DuplicateSpriteCommand::onExecute(Context* context)
Widget* src_name, *dst_name, *flatten;
const ContextReader reader(context);
const Document* document = reader.document();
char buf[1024];
/* load the window widget */
base::UniquePtr<Window> window(app::load_widget<Window>("duplicate_sprite.xml", "duplicate_sprite"));
@ -74,10 +73,9 @@ void DuplicateSpriteCommand::onExecute(Context* context)
dst_name = window->findChild("dst_name");
flatten = window->findChild("flatten");
src_name->setText(get_filename(document->getFilename()));
std::sprintf(buf, "%s Copy", document->getFilename());
dst_name->setText(buf);
base::string fn = document->getFilename();
src_name->setText(base::get_file_name(fn));
dst_name->setText(base::get_file_title(fn) + " Copy." + base::get_file_extension(fn));
if (get_config_bool("DuplicateSprite", "Flatten", false))
flatten->setSelected(true);
@ -95,7 +93,7 @@ void DuplicateSpriteCommand::onExecute(Context* context)
else
docCopy = document->duplicate(DuplicateExactCopy);
docCopy->setFilename(dst_name->getText());
docCopy->setFilename(dst_name->getText().c_str());
context->addDocument(docCopy);
}

View File

@ -119,7 +119,7 @@ void FramePropertiesCommand::onExecute(Context* context)
window->openWindowInForeground();
if (window->getKiller() == ok) {
int num = strtol(frlen->getText(), NULL, 10);
int num = frlen->getTextInt();
if (m_target == ALL_FRAMES) {
if (Alert::show("Warning"

View File

@ -158,7 +158,7 @@ protected:
if (window->getKiller() != ok)
return editor->getFrame();
m_frame = strtol(frame->getText(), NULL, 10);
m_frame = frame->getTextInt();
}
return MID(FrameNumber(0), FrameNumber(m_frame-1), editor->getSprite()->getLastFrame());

View File

@ -25,8 +25,7 @@
#include "app/launcher.h"
#include "app/resource_finder.h"
#include "base/compiler_specific.h"
#include <allegro.h>
#include "base/fs.h"
namespace app {
@ -80,7 +79,7 @@ void LaunchCommand::onExecute(Context* context)
rf.findInDocsDir(m_path.c_str());
while (const char* path = rf.next()) {
if (!exists(path))
if (!base::file_exists(path))
continue;
launcher::open_file(path);

View File

@ -39,8 +39,7 @@
#include "raster/sprite.h"
#include "ui/ui.h"
#include <allegro.h>
#include <stdio.h>
#include <cstdio>
static const int kMonitoringPeriod = 100;
@ -62,7 +61,7 @@ private:
class OpenFileJob : public Job, public IFileOpProgress
{
public:
OpenFileJob(FileOp* fop, const char* filename)
OpenFileJob(FileOp* fop)
: Job("Loading file")
, m_fop(fop)
{
@ -132,7 +131,7 @@ void OpenFileCommand::onExecute(Context* context)
unrecent = true;
}
else {
OpenFileJob task(fop, get_filename(m_filename.c_str()));
OpenFileJob task(fop);
task.showProgressWindow();
// Post-load processing, it is called from the GUI because may require user intervention.

View File

@ -36,8 +36,6 @@
#include "raster/image.h"
#include "ui/ui.h"
#include <allegro.h>
namespace app {
using namespace ui;

View File

@ -48,6 +48,8 @@
#include "app/undoers/set_palette_colors.h"
#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/fs.h"
#include "base/path.h"
#include "gfx/hsv.h"
#include "gfx/rgb.h"
#include "gfx/size.h"
@ -59,9 +61,8 @@
#include "ui/graphics.h"
#include "ui/ui.h"
#include <allegro.h>
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include <vector>
namespace app {
@ -599,9 +600,9 @@ void PaletteEntryEditor::onSavePaletteClick(Event& ev)
again:
filename = app::show_file_selector("Save Palette", "", "png,pcx,bmp,tga,col,gpl");
if (!filename.empty()) {
if (exists(filename.c_str())) {
if (base::file_exists(filename)) {
ret = Alert::show("Warning<<File exists, overwrite it?<<%s||&Yes||&No||&Cancel",
get_filename(filename.c_str()));
base::get_file_name(filename).c_str());
if (ret == 2)
goto again;

View File

@ -72,7 +72,7 @@ void RefreshCommand::onExecute(Context* context)
#if defined ALLEGRO_WINDOWS && defined DEBUGMODE
{
PROCESS_MEMORY_COUNTERS pmc;
if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
if (::GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
StatusBar::instance()
->showTip(1000,
"Current memory: %.16g KB (%lu)\n"

View File

@ -31,20 +31,20 @@
#include "app/recent_files.h"
#include "app/ui/status_bar.h"
#include "base/bind.h"
#include "base/fs.h"
#include "base/path.h"
#include "base/thread.h"
#include "base/unique_ptr.h"
#include "raster/sprite.h"
#include "ui/ui.h"
#include <allegro.h>
static const int kMonitoringPeriod = 100;
namespace app {
class SaveFileJob : public Job, public IFileOpProgress {
public:
SaveFileJob(FileOp* fop, const char* filename)
SaveFileJob(FileOp* fop)
: Job("Saving file")
, m_fop(fop)
{
@ -81,7 +81,7 @@ static void save_document_in_background(Document* document, bool mark_as_saved)
if (!fop)
return;
SaveFileJob job(fop, get_filename(document->getFilename()));
SaveFileJob job(fop);
job.showProgressWindow();
if (fop->has_error()) {
@ -89,13 +89,13 @@ static void save_document_in_background(Document* document, bool mark_as_saved)
console.printf(fop->error.c_str());
}
else {
App::instance()->getRecentFiles()->addRecentFile(document->getFilename());
App::instance()->getRecentFiles()->addRecentFile(document->getFilename().c_str());
if (mark_as_saved)
document->markAsSaved();
StatusBar::instance()
->setStatusText(2000, "File %s, saved.",
get_filename(document->getFilename()));
base::get_file_name(document->getFilename()));
}
}
@ -119,23 +119,22 @@ static void save_as_dialog(const ContextReader& reader, const char* dlg_title, b
filename = newfilename;
/* does the file exist? */
if (exists(filename.c_str())) {
/* ask if the user wants overwrite the file? */
if (base::file_exists(filename.c_str())) {
// Ask if the user wants overwrite the existent file?
ret = ui::Alert::show("Warning<<File exists, overwrite it?<<%s||&Yes||&No||&Cancel",
get_filename(filename.c_str()));
base::get_file_name(filename).c_str());
}
else
break;
/* "yes": we must continue with the operation... */
// "yes": we must continue with the operation...
if (ret == 1)
break;
/* "cancel" or <esc> per example: we back doing nothing */
// "cancel" or <esc> per example: we back doing nothing
else if (ret != 2)
return;
/* "no": we must back to select other file-name */
// "no": we must back to select other file-name
}
{

View File

@ -117,7 +117,7 @@ private:
UI_FOREACH_WIDGET(m_stockListBox->getChildren(), it) {
Widget* child = *it;
if (strcmp(child->getText(), oldSelected) == 0) {
if (child->getText() == oldSelected) {
select_this = child;
break;
}
@ -135,7 +135,7 @@ private:
void onMatrixChange()
{
ListItem* selected = m_stockListBox->getSelectedChild();
SharedPtr<ConvolutionMatrix> matrix = m_stock.getByName(selected->getText());
SharedPtr<ConvolutionMatrix> matrix = m_stock.getByName(selected->getText().c_str());
Target newTarget = matrix->getDefaultTarget();
m_filter.setMatrix(matrix);

View File

@ -24,10 +24,10 @@
#include "app/commands/filters/convolution_matrix_stock.h"
#include "base/unique_ptr.h"
#include "filters/convolution_matrix.h"
#include "app/resource_finder.h"
#include "app/util/filetoks.h"
#include "base/file_handle.h"
#include "filters/convolution_matrix.h"
namespace app {
@ -50,13 +50,6 @@ SharedPtr<ConvolutionMatrix> ConvolutionMatrixStock::getByName(const char* name)
return SharedPtr<ConvolutionMatrix>(0);
}
namespace {
class FileDestroyer {
public:
static void destroy(FILE* ptr) { fclose(ptr); }
};
}
void ConvolutionMatrixStock::reloadStock()
{
#define READ_TOK() { \
@ -75,7 +68,6 @@ void ConvolutionMatrixStock::reloadStock()
char *s, buf[256], leavings[4096];
int i, c, x, y, w, h, div, bias;
SharedPtr<ConvolutionMatrix> matrix;
base::UniquePtr<FILE, int(*)(FILE*)> f;
std::string name;
cleanStock();
@ -86,7 +78,7 @@ void ConvolutionMatrixStock::reloadStock()
while (const char* path = rf.next()) {
// Open matrices stock file
f.reset(fopen(path, "r"), fclose);
base::FileHandle f = base::open_file(path, "r");
if (!f)
continue;

View File

@ -22,9 +22,6 @@
#include "app/commands/filters/filter_target_buttons.h"
#include <allegro.h>
#include <string.h>
#include "app/modules/gfx.h"
#include "app/modules/gui.h"
#include "app/ui/skin/skin_parts.h"
@ -35,6 +32,8 @@
#include "ui/theme.h"
#include "ui/widget.h"
#include <cstring>
namespace app {
using namespace filters;
@ -100,7 +99,7 @@ FilterTargetButtons::FilterTargetButtons(int imgtype, bool withChannels)
}
// Create the button to select "image" target
images = new Button(NULL);
images = new Button("");
setup_bevels(images,
withChannels ? 0: 2,
withChannels ? 0: 2, 2, 2);

View File

@ -20,7 +20,6 @@
#include "config.h"
#endif
#include <allegro.h>
#include <stdarg.h>
#include <stdio.h>
@ -58,7 +57,7 @@ Console::Console()
Window* window = new Window(false, "Errors Console");
Grid* grid = new Grid(1, false);
View* view = new View();
TextBox* textbox = new TextBox(NULL, JI_WORDWRAP);
TextBox* textbox = new TextBox("", JI_WORDWRAP);
Button* button = new Button("&Cancel");
if (!grid || !textbox || !button)
@ -109,19 +108,16 @@ Console::~Console()
}
}
void Console::printf(const char *format, ...)
void Console::printf(const char* format, ...)
{
char buf[1024]; // TODO warning buffer overflow
char buf[4096]; // TODO warning buffer overflow
va_list ap;
va_start(ap, format);
uvsprintf(buf, format, ap);
vsprintf(buf, format, ap);
va_end(ap);
if (wid_console) {
const char* text;
char* final;
// Open the window
if (!wid_console->isVisible()) {
wid_console->openWindow();
@ -140,19 +136,14 @@ void Console::printf(const char *format, ...)
wid_console->invalidate();
}
text = wid_textbox->getText();
if (!text)
final = base_strdup(buf);
else {
final = (char*)base_malloc(ustrlen(text) + ustrlen(buf) + 1);
const std::string& text = wid_textbox->getText();
ustrcpy(final, empty_string);
ustrcat(final, text);
ustrcat(final, buf);
}
base::string final;
if (!text.empty())
final += text;
final += buf;
wid_textbox->setText(final);
base_free(final);
wid_textbox->setText(final.c_str());
}
else {
fputs(buf, stdout);

View File

@ -221,7 +221,7 @@ void switch_between_animation_and_sprite_editor(Context* context)
// Create the window & the animation-editor
{
base::UniquePtr<Window> window(new Window(true, NULL));
base::UniquePtr<Window> window(new Window(true, ""));
AnimationEditor anieditor(context);
window->addChild(&anieditor);

View File

@ -189,12 +189,7 @@ void Document::notifyCelCopied(Layer* fromLayer, FrameNumber fromFrame, Layer* t
notifyObservers<DocumentEvent&>(&DocumentObserver::onCelCopied, ev);
}
const char* Document::getFilename() const
{
return m_filename.c_str();
}
void Document::setFilename(const char* filename)
void Document::setFilename(const base::string& filename)
{
m_filename = filename;
}

View File

@ -19,17 +19,16 @@
#ifndef APP_DOCUMENT_H_INCLUDED
#define APP_DOCUMENT_H_INCLUDED
#include "base/disable_copying.h"
#include "base/shared_ptr.h"
#include "base/unique_ptr.h"
#include "app/document_id.h"
#include "gfx/transformation.h"
#include "base/disable_copying.h"
#include "base/observable.h"
#include "base/shared_ptr.h"
#include "base/string.h"
#include "base/unique_ptr.h"
#include "gfx/transformation.h"
#include "raster/frame_number.h"
#include "raster/pixel_format.h"
#include <string>
namespace base {
class mutex;
}
@ -110,8 +109,8 @@ namespace app {
//////////////////////////////////////////////////////////////////////
// File related properties
const char* getFilename() const;
void setFilename(const char* filename);
const base::string& getFilename() const { return m_filename; }
void setFilename(const base::string& filename);
bool isModified() const;
bool isAssociatedToFile() const;
@ -201,7 +200,7 @@ namespace app {
base::UniquePtr<DocumentUndo> m_undo;
// Document's file name (from where it was loaded, where it is saved).
std::string m_filename;
base::string m_filename;
// True if this sprite is associated to a file in the file-system.
bool m_associated_to_file;

View File

@ -139,7 +139,7 @@ static LRESULT CALLBACK ase_wnd_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM
if (length > 0) {
TCHAR* lpstr = new TCHAR[length+1];
DragQueryFile(hdrop, index, lpstr, length+1);
dropped_files->push_back(lpstr);
dropped_files->push_back(base::to_utf8(lpstr));
delete[] lpstr;
}
}

View File

@ -23,10 +23,10 @@
#include "app/document.h"
#include "app/file/file.h"
#include "app/file/file_format.h"
#include "app/file/file_handle.h"
#include "app/file/format_options.h"
#include "base/cfile.h"
#include "base/exception.h"
#include "base/file_handle.h"
#include "raster/raster.h"
#include "zlib.h"
@ -137,9 +137,7 @@ FileFormat* CreateAseFormat()
bool AseFormat::onLoad(FileOp *fop)
{
FileHandle f(fop->filename.c_str(), "rb");
if (!f)
return false;
FileHandle f(open_file_with_exception(fop->filename, "rb"));
ASE_Header header;
if (!ase_file_read_header(f, &header)) {
@ -291,7 +289,7 @@ bool AseFormat::onSave(FileOp *fop)
ASE_Header header;
ASE_FrameHeader frame_header;
FileHandle f(fop->filename.c_str(), "wb");
FileHandle f(open_file_with_exception(fop->filename, "wb"));
/* prepare the header */
ase_file_prepare_header(f, &header, sprite);

View File

@ -24,9 +24,9 @@
#include "app/file/file.h"
#include "app/file/file_format.h"
#include "app/file/file_handle.h"
#include "app/file/format_options.h"
#include "base/cfile.h"
#include "base/file_handle.h"
#include "raster/raster.h"
#include <allegro/color.h>
@ -611,9 +611,7 @@ bool BmpFormat::onLoad(FileOp *fop)
PixelFormat pixelFormat;
int format;
FileHandle f(fop->filename.c_str(), "rb");
if (!f)
return false;
FileHandle f(open_file_with_exception(fop->filename, "rb"));
if (read_bmfileheader(f, &fileheader) != 0)
return false;
@ -739,11 +737,7 @@ bool BmpFormat::onSave(FileOp *fop)
bfSize = 54 + biSizeImage; /* header + image data */
}
FileHandle f(fop->filename.c_str(), "wb");
if (!f) {
fop_error(fop, "Error creating file.\n");
return false;
}
FileHandle f(open_file_with_exception(fop->filename, "wb"));
/* file_header */
fputw(0x4D42, f); /* bfType ("BM") */

View File

@ -20,26 +20,29 @@
#include "config.h"
#endif
#include "app/file/file.h"
#include "app/app.h"
#include "app/ui/status_bar.h"
#include "base/mutex.h"
#include "base/scoped_lock.h"
#include "base/shared_ptr.h"
#include "base/string.h"
#include "app/console.h"
#include "app/document.h"
#include "app/file/file.h"
#include "app/file/file_format.h"
#include "app/file/file_formats_manager.h"
#include "app/file/format_options.h"
#include "app/modules/gui.h"
#include "app/modules/palettes.h"
#include "app/ui/status_bar.h"
#include "base/fs.h"
#include "base/mutex.h"
#include "base/path.h"
#include "base/scoped_lock.h"
#include "base/shared_ptr.h"
#include "base/string.h"
#include "raster/quantization.h"
#include "raster/raster.h"
#include "ui/alert.h"
#include <allegro.h>
#include <string.h>
#include <cstring>
namespace app {
@ -143,13 +146,13 @@ FileOp* fop_to_load_document(const char* filename, int flags)
if (!fop)
return NULL;
/* get the extension of the filename (in lower case) */
std::string extension = base::string_to_lower(get_extension(filename));
// Get the extension of the filename (in lower case)
base::string extension = base::string_to_lower(base::get_file_extension(filename));
PRINTF("Loading file \"%s\" (%s)\n", filename, extension.c_str());
/* does file exist? */
if (!file_exists(filename, FA_ALL, NULL)) {
// Does file exist?
if (!base::file_exists(filename)) {
fop_error(fop, "File not found: \"%s\"\n", filename);
goto done;
}
@ -230,7 +233,6 @@ done:;
FileOp* fop_to_save_document(Document* document)
{
char extension[32], buf[2048];
FileOp *fop;
bool fatal;
@ -238,25 +240,24 @@ FileOp* fop_to_save_document(Document* document)
if (!fop)
return NULL;
/* document to save */
// Document to save
fop->document = document;
/* get the extension of the filename (in lower case) */
ustrcpy(extension, get_extension(fop->document->getFilename()));
ustrlwr(extension);
// Get the extension of the filename (in lower case)
base::string extension = base::string_to_lower(base::get_file_extension(fop->document->getFilename()));
PRINTF("Saving document \"%s\" (%s)\n", fop->document->getFilename(), extension);
PRINTF("Saving document \"%s\" (%s)\n", fop->document->getFilename(), extension.c_str());
/* get the format through the extension of the filename */
fop->format = get_fileformat(extension);
fop->format = get_fileformat(extension.c_str());
if (!fop->format ||
!fop->format->support(FILE_SUPPORT_SAVE)) {
fop_error(fop, "ASEPRITE can't save \"%s\" files\n", extension);
return fop;
}
/* warnings */
ustrcpy(buf, empty_string);
// Warnings
base::string warnings;
fatal = false;
/* check image type support */
@ -264,29 +265,32 @@ FileOp* fop_to_save_document(Document* document)
case IMAGE_RGB:
if (!(fop->format->support(FILE_SUPPORT_RGB))) {
usprintf(buf+ustrlen(buf), "<<- %s", "RGB format");
warnings += "<<- RGB format";
fatal = true;
}
if (!(fop->format->support(FILE_SUPPORT_RGBA)) &&
fop->document->getSprite()->needAlpha()) {
usprintf(buf+ustrlen(buf), "<<- %s", "Alpha channel");
warnings += "<<- Alpha channel";
}
break;
case IMAGE_GRAYSCALE:
if (!(fop->format->support(FILE_SUPPORT_GRAY))) {
usprintf(buf+ustrlen(buf), "<<- Grayscale format");
warnings += "<<- Grayscale format";
fatal = true;
}
if (!(fop->format->support(FILE_SUPPORT_GRAYA)) &&
fop->document->getSprite()->needAlpha()) {
usprintf(buf+ustrlen(buf), "<<- Alpha channel");
warnings += "<<- Alpha channel";
}
break;
case IMAGE_INDEXED:
if (!(fop->format->support(FILE_SUPPORT_INDEXED))) {
usprintf(buf+ustrlen(buf), "<<- Indexed format");
warnings += "<<- Indexed format";
fatal = true;
}
break;
@ -296,14 +300,14 @@ FileOp* fop_to_save_document(Document* document)
if (fop->document->getSprite()->getTotalFrames() > 1) {
if (!fop->format->support(FILE_SUPPORT_FRAMES) &&
!fop->format->support(FILE_SUPPORT_SEQUENCES)) {
usprintf(buf+ustrlen(buf), "<<- Frames");
warnings += "<<- Frames";
}
}
// layers support
if (fop->document->getSprite()->getFolder()->getLayersCount() > 1) {
if (!(fop->format->support(FILE_SUPPORT_LAYERS))) {
usprintf(buf+ustrlen(buf), "<<- Layers");
warnings += "<<- Layers";
}
}
@ -311,25 +315,25 @@ FileOp* fop_to_save_document(Document* document)
if (fop->document->getSprite()->getPalettes().size() > 1) {
if (!fop->format->support(FILE_SUPPORT_PALETTES) &&
!fop->format->support(FILE_SUPPORT_SEQUENCES)) {
usprintf(buf+ustrlen(buf), "<<- Palette changes between frames");
warnings += "<<- Palette changes between frames";
}
}
/* show the confirmation alert */
if (ugetc(buf)) {
/* interative */
// Show the confirmation alert
if (!warnings.empty()) {
// Interative
if (App::instance()->isGui()) {
int ret;
if (fatal)
ret = ui::Alert::show("Error<<File format \"%s\" doesn't support:%s"
"||&Close",
fop->format->name(), buf);
fop->format->name(), warnings.c_str());
else
ret = ui::Alert::show("Warning<<File format \"%s\" doesn't support:%s"
"<<Do you want continue?"
"||&Yes||&No",
fop->format->name(), buf);
fop->format->name(), warnings.c_str());
/* operation can't be done (by fatal error) or the user cancel
the operation */
@ -338,9 +342,9 @@ FileOp* fop_to_save_document(Document* document)
return NULL;
}
}
/* no interactive & fatal error? */
// No interactive & fatal error?
else if (fatal) {
fop_error(fop, buf);
fop_error(fop, warnings.c_str());
return fop;
}
}
@ -355,10 +359,10 @@ FileOp* fop_to_save_document(Document* document)
}
// To save more frames
else {
char buf[256], left[256], right[256];
char left[256], right[256];
int width, start_from;
start_from = split_filename(fop->document->getFilename(), left, right, &width);
start_from = split_filename(fop->document->getFilename().c_str(), left, right, &width);
if (start_from < 0) {
start_from = 0;
width =
@ -368,8 +372,9 @@ FileOp* fop_to_save_document(Document* document)
}
for (FrameNumber frame(0); frame<fop->document->getSprite()->getTotalFrames(); ++frame) {
/* get the name for this frame */
usprintf(buf, "%s%0*d%s", left, width, start_from+frame, right);
// Get the name for this frame
char buf[4096];
sprintf(buf, "%s%0*d%s", left, width, start_from+frame, right);
fop->seq.filename_list.push_back(buf);
}
}

View File

@ -23,10 +23,10 @@
#include "app/document.h"
#include "app/file/file.h"
#include "app/file/file_format.h"
#include "app/file/file_handle.h"
#include "app/file/fli/fli.h"
#include "app/file/format_options.h"
#include "app/modules/palettes.h"
#include "base/file_handle.h"
#include "raster/raster.h"
#include <allegro/color.h>
@ -34,6 +34,8 @@
namespace app {
using namespace base;
static int get_time_precision(Sprite *sprite);
class FliFormat : public FileFormat {
@ -79,7 +81,7 @@ bool FliFormat::onLoad(FileOp* fop)
int index = 0;
// Open the file to read in binary mode
FileHandle f(fop->filename.c_str(), "rb");
FileHandle f(open_file_with_exception(fop->filename, "rb"));
fli_read_header(f, &fli_header);
fseek(f, 128, SEEK_SET);
@ -94,9 +96,9 @@ bool FliFormat::onLoad(FileOp* fop)
h = fli_header.height;
// Create the bitmaps
base::UniquePtr<Image> bmp(Image::create(IMAGE_INDEXED, w, h));
base::UniquePtr<Image> old(Image::create(IMAGE_INDEXED, w, h));
base::UniquePtr<Palette> pal(new Palette(FrameNumber(0), 256));
UniquePtr<Image> bmp(Image::create(IMAGE_INDEXED, w, h));
UniquePtr<Image> old(Image::create(IMAGE_INDEXED, w, h));
UniquePtr<Palette> pal(new Palette(FrameNumber(0), 256));
// Create the image
Sprite* sprite = new Sprite(IMAGE_INDEXED, w, h, 256);
@ -207,13 +209,13 @@ bool FliFormat::onSave(FileOp* fop)
fli_header.oframe1 = fli_header.oframe2 = 0;
/* open the file to write in binary mode */
FileHandle f(fop->filename.c_str(), "wb");
FileHandle f(open_file_with_exception(fop->filename, "wb"));
fseek(f, 128, SEEK_SET);
// Create the bitmaps
base::UniquePtr<Image> bmp(Image::create(IMAGE_INDEXED, sprite->getWidth(), sprite->getHeight()));
base::UniquePtr<Image> old(Image::create(IMAGE_INDEXED, sprite->getWidth(), sprite->getHeight()));
UniquePtr<Image> bmp(Image::create(IMAGE_INDEXED, sprite->getWidth(), sprite->getHeight()));
UniquePtr<Image> old(Image::create(IMAGE_INDEXED, sprite->getWidth(), sprite->getHeight()));
// Write frame by frame
for (FrameNumber frpos(0);

View File

@ -25,9 +25,9 @@
#include "app/document.h"
#include "app/file/file.h"
#include "app/file/file_format.h"
#include "app/file/file_handle.h"
#include "app/file/format_options.h"
#include "base/cfile.h"
#include "base/file_handle.h"
#include "raster/raster.h"
#include <allegro/color.h>
@ -90,7 +90,7 @@ struct BITMAPINFOHEADER {
bool IcoFormat::onLoad(FileOp* fop)
{
FileHandle f(fop->filename.c_str(), "rb");
FileHandle f(open_file_with_exception(fop->filename, "rb"));
// Read the icon header
ICONDIR header;
@ -242,7 +242,7 @@ bool IcoFormat::onSave(FileOp* fop)
int c, x, y, b, m, v;
FrameNumber n, num = sprite->getTotalFrames();
FileHandle f(fop->filename.c_str(), "wb");
FileHandle f(open_file_with_exception(fop->filename, "wb"));
offset = 6 + num*16; // ICONDIR + ICONDIRENTRYs

View File

@ -24,12 +24,12 @@
#include "app/console.h"
#include "app/file/file.h"
#include "app/file/file_format.h"
#include "app/file/file_handle.h"
#include "app/file/format_options.h"
#include "app/find_widget.h"
#include "app/ini_file.h"
#include "app/load_widget.h"
#include "base/compiler_specific.h"
#include "base/file_handle.h"
#include "base/memory.h"
#include "raster/raster.h"
#include "ui/ui.h"
@ -42,6 +42,8 @@
namespace app {
using namespace base;
class JpegFormat : public FileFormat {
// Data for JPEG files
class JpegOptions : public FormatOptions {
@ -110,9 +112,7 @@ bool JpegFormat::onLoad(FileOp* fop)
JDIMENSION buffer_height;
int c;
FileHandle file(fop->filename.c_str(), "rb");
if (!file)
return false;
FileHandle file(open_file_with_exception(fop->filename, "rb"));
// Initialize the JPEG decompression object with error handling.
jerr.fop = fop;
@ -247,11 +247,7 @@ bool JpegFormat::onSave(FileOp* fop)
int c;
// Open the file for write in it.
FileHandle file(fop->filename.c_str(), "wb");
if (!file) {
fop_error(fop, "Error creating file.\n");
return false;
}
FileHandle file(open_file_with_exception(fop->filename, "wb"));
// Allocate and initialize JPEG compression object.
jerr.fop = fop;
@ -367,7 +363,7 @@ SharedPtr<FormatOptions> JpegFormat::onGetFormatOptions(FileOp* fop)
return jpeg_options;
// Load the window to ask to the user the JPEG options he wants.
base::UniquePtr<ui::Window> window(app::load_widget<ui::Window>("jpeg_options.xml", "jpeg_options"));
UniquePtr<ui::Window> window(app::load_widget<ui::Window>("jpeg_options.xml", "jpeg_options"));
ui::Slider* slider_quality = app::find_widget<ui::Slider>(window, "quality");
ui::Widget* ok = app::find_widget<ui::Widget>(window, "ok");
@ -385,7 +381,7 @@ SharedPtr<FormatOptions> JpegFormat::onGetFormatOptions(FileOp* fop)
return jpeg_options;
}
catch (base::Exception& e) {
catch (std::exception& e) {
Console::showException(e);
return SharedPtr<JpegOptions>(0);
}

View File

@ -24,9 +24,9 @@
#include "app/file/file.h"
#include "app/file/file_format.h"
#include "app/file/file_handle.h"
#include "app/file/format_options.h"
#include "base/cfile.h"
#include "base/file_handle.h"
#include "raster/raster.h"
#include <allegro/color.h>
@ -66,7 +66,7 @@ bool PcxFormat::onLoad(FileOp* fop)
int x, y;
char ch = 0;
FileHandle f(fop->filename.c_str(), "rb");
FileHandle f(open_file_with_exception(fop->filename, "rb"));
fgetc(f); /* skip manufacturer ID */
fgetc(f); /* skip version flag */
@ -193,7 +193,7 @@ bool PcxFormat::onSave(FileOp* fop)
char runchar;
char ch = 0;
FileHandle f(fop->filename.c_str(), "wb");
FileHandle f(open_file_with_exception(fop->filename, "wb"));
if (image->getPixelFormat() == IMAGE_RGB) {
depth = 24;

View File

@ -24,9 +24,9 @@
#include "app/document.h"
#include "app/file/file.h"
#include "app/file/file_format.h"
#include "app/file/file_handle.h"
#include "app/file/format_options.h"
#include "app/ini_file.h"
#include "base/file_handle.h"
#include "raster/raster.h"
#include <stdio.h>
@ -36,6 +36,8 @@
namespace app {
using namespace base;
class PngFormat : public FileFormat {
const char* onGetName() const { return "png"; }
const char* onGetExtensions() const { return "png"; }
@ -78,7 +80,7 @@ bool PngFormat::onLoad(FileOp* fop)
png_bytep row_pointer;
PixelFormat pixelFormat;
FileHandle fp(fop->filename.c_str(), "rb");
FileHandle fp(open_file_with_exception(fop->filename, "rb"));
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,
@ -337,7 +339,7 @@ bool PngFormat::onSave(FileOp* fop)
int pass, number_passes;
/* open the file */
FileHandle fp(fop->filename.c_str(), "wb");
FileHandle fp(open_file_with_exception(fop->filename, "wb"));
/* Create and initialize the png_struct with the desired error handler
* functions. If you want to use the default stderr and longjump method,

View File

@ -25,9 +25,9 @@
#include "app/file/file.h"
#include "app/file/file_format.h"
#include "app/file/file_handle.h"
#include "app/file/format_options.h"
#include "base/cfile.h"
#include "base/file_handle.h"
#include "raster/raster.h"
#include <allegro/color.h>
@ -210,7 +210,7 @@ bool TgaFormat::onLoad(FileOp* fop)
unsigned int c, i, x, y, yc;
int compressed;
FileHandle f(fop->filename.c_str(), "rb");
FileHandle f(open_file_with_exception(fop->filename, "rb"));
id_length = fgetc(f);
palette_type = fgetc(f);
@ -405,7 +405,7 @@ bool TgaFormat::onSave(FileOp* fop)
int depth = (image->getPixelFormat() == IMAGE_RGB) ? 32 : 8;
bool need_pal = (image->getPixelFormat() == IMAGE_INDEXED)? true: false;
FileHandle f(fop->filename.c_str(), "wb");
FileHandle f(open_file_with_exception(fop->filename, "wb"));
fputc(0, f); /* id length (no id saved) */
fputc((need_pal) ? 1 : 0, f); /* palette type */

View File

@ -25,6 +25,11 @@
#include "config.h"
#endif
#include "app/file_system.h"
#include "base/path.h"
#include "base/string.h"
#include <algorithm>
#include <cstdio>
#include <map>
@ -58,9 +63,6 @@
#include <shlwapi.h>
#endif
#include "app/file_system.h"
#include "base/path.h"
//////////////////////////////////////////////////////////////////////
#ifdef USE_PIDLS
@ -320,7 +322,6 @@ IFileItem* FileSystemModule::getFileItemFromPath(const base::string& path)
#ifdef USE_PIDLS
{
ULONG cbEaten;
WCHAR wStr[MAX_PATH];
LPITEMIDLIST fullpidl = NULL;
SFGAOF attrib = SFGAO_FOLDER;
@ -330,12 +331,10 @@ IFileItem* FileSystemModule::getFileItemFromPath(const base::string& path)
return fileitem;
}
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
path.c_str(), path.size()+1, wStr, MAX_PATH);
if (shl_idesktop->ParseDisplayName(NULL, NULL,
wStr, &cbEaten,
&fullpidl,
&attrib) != S_OK) {
if (shl_idesktop->ParseDisplayName
(NULL, NULL,
const_cast<LPWSTR>(base::from_utf8(path).c_str()),
&cbEaten, &fullpidl, &attrib) != S_OK) {
//PRINTF("FS: > (null)\n");
return NULL;
}
@ -708,7 +707,7 @@ int FileItem::compare(const FileItem& that) const
static void update_by_pidl(FileItem* fileitem)
{
STRRET strret;
TCHAR pszName[MAX_PATH];
WCHAR pszName[MAX_PATH];
IShellFolder *pFolder = NULL;
if (fileitem == rootitem)
@ -729,13 +728,13 @@ static void update_by_pidl(FileItem* fileitem)
SHGDN_NORMAL | SHGDN_FORPARSING,
&strret) == S_OK) {
StrRetToBuf(&strret, fileitem->pidl, pszName, MAX_PATH);
fileitem->filename = pszName;
fileitem->filename = base::to_utf8(pszName);
}
else if (shl_idesktop->GetDisplayNameOf(fileitem->fullpidl,
SHGDN_NORMAL | SHGDN_FORPARSING,
&strret) == S_OK) {
StrRetToBuf(&strret, fileitem->fullpidl, pszName, MAX_PATH);
fileitem->filename = pszName;
fileitem->filename = base::to_utf8(pszName);
}
else
fileitem->filename = "ERR";
@ -749,14 +748,14 @@ static void update_by_pidl(FileItem* fileitem)
SHGDN_INFOLDER,
&strret) == S_OK) {
StrRetToBuf(&strret, fileitem->pidl, pszName, MAX_PATH);
fileitem->displayname = pszName;
fileitem->displayname = base::to_utf8(pszName);
}
else if (fileitem->isFolder() &&
shl_idesktop->GetDisplayNameOf(fileitem->fullpidl,
SHGDN_INFOLDER,
&strret) == S_OK) {
StrRetToBuf(&strret, fileitem->fullpidl, pszName, MAX_PATH);
fileitem->displayname = pszName;
fileitem->displayname = base::to_utf8(pszName);
}
else {
fileitem->displayname = base::get_file_name(fileitem->filename);
@ -884,12 +883,10 @@ static base::string get_key_for_pidl(LPITEMIDLIST pidl)
return key;
#else
STRRET strret;
TCHAR pszName[MAX_PATH];
char key[4096];
WCHAR pszName[MAX_PATH];
WCHAR key[4096] = { 0 };
int len;
ustrcpy(key, empty_string);
// Go pidl by pidl from the fullpidl to the root (desktop)
//PRINTF("FS: ***\n");
pidl = clone_pidl(pidl);
@ -901,20 +898,20 @@ static base::string get_key_for_pidl(LPITEMIDLIST pidl)
//PRINTF("FS: + %s\n", pszName);
len = ustrlen(pszName);
len = wcslen(pszName);
if (len > 0) {
if (*key) {
if (pszName[len-1] != '\\') {
memmove(key+len+1, key, ustrlen(key)+1);
key[len] = '\\';
if (pszName[len-1] != L'\\') {
memmove(key+len+1, key, sizeof(WCHAR)*(wcslen(key)+1));
key[len] = L'\\';
}
else
memmove(key+len, key, ustrlen(key)+1);
memmove(key+len, key, sizeof(WCHAR)*(wcslen(key)+1));
}
else
key[len] = 0;
memcpy(key, pszName, len);
memcpy(key, pszName, sizeof(WCHAR)*len);
}
}
remove_last_pidl(pidl);
@ -922,7 +919,7 @@ static base::string get_key_for_pidl(LPITEMIDLIST pidl)
free_pidl(pidl);
//PRINTF("FS: =%s\n***\n", key);
return key;
return base::to_utf8(key);
#endif
}

View File

@ -23,6 +23,7 @@
#include "app/gui_xml.h"
#include "app/resource_finder.h"
#include "app/xml_document.h"
#include "app/xml_exception.h"
#include "base/fs.h"
@ -54,9 +55,9 @@ GuiXml::GuiXml()
PRINTF(" - \"%s\" found\n", path);
// Try to load the XML file
if (!m_doc.LoadFile(path))
throw XmlException(&m_doc);
// Load the XML file. As we've already checked "path" existence,
// in a case of exception we should show the error and stop.
m_doc = app::open_xml(path);
// Done, we load the file successfully.
return;
@ -65,14 +66,9 @@ GuiXml::GuiXml()
throw base::Exception("gui.xml was not found");
}
TiXmlDocument& GuiXml::doc()
base::string GuiXml::version()
{
return m_doc;
}
std::string GuiXml::version()
{
TiXmlHandle handle(&m_doc);
TiXmlHandle handle(m_doc);
TiXmlElement* xmlKey = handle.FirstChild("gui").ToElement();
if (xmlKey && xmlKey->Attribute("version")) {

View File

@ -19,8 +19,8 @@
#ifndef APP_GUI_XML_INCLUDED
#define APP_GUI_XML_INCLUDED
#include <string>
#include "tinyxml.h"
#include "app/xml_document.h"
#include "base/string.h"
namespace app {
@ -33,19 +33,21 @@ namespace app {
static GuiXml* instance();
// Returns the tinyxml document instance.
TiXmlDocument& doc();
XmlDocumentRef doc() {
return m_doc;
}
// Returns the name of the gui.xml file.
const char* filename() {
return m_doc.Value();
return m_doc->Value();
}
std::string version();
base::string version();
private:
GuiXml();
TiXmlDocument m_doc;
XmlDocumentRef m_doc;
};
} // namespace app

View File

@ -23,6 +23,7 @@
#include "app/ini_file.h"
#include "app/resource_finder.h"
#include "base/fs.h"
#include "ui/rect.h"
#include <allegro/config.h>
@ -33,19 +34,19 @@ namespace app {
using namespace gfx;
static char config_filename[512];
static std::string config_filename;
ConfigModule::ConfigModule()
{
ResourceFinder rf;
rf.findConfigurationFile();
config_filename[0] = 0;
config_filename.clear();
// Search the configuration file from first to last path
while (const char* path = rf.next()) {
if (exists(path)) {
ustrcpy(config_filename, path);
if (base::file_exists(path)) {
config_filename = path;
break;
}
}
@ -53,9 +54,9 @@ ConfigModule::ConfigModule()
// If the file wasn't found, we will create configuration file
// in the first path
if (config_filename[0] == 0 && rf.first())
ustrcpy(config_filename, rf.first());
config_filename = rf.first();
override_config_file(config_filename);
override_config_file(config_filename.c_str());
}
ConfigModule::~ConfigModule()

View File

@ -47,7 +47,7 @@ namespace app {
#ifdef NEED_LOG // log file info
static std::string log_filename;
static FILE *log_fileptr = NULL;
static FILE* log_fileptr = NULL;
#endif
static LoggerModule* logger_instance = NULL;

View File

@ -653,7 +653,7 @@ bool Shortcut::is_pressed(Message* msg)
if (accel) {
return accel->check(msg->keyModifiers(),
static_cast<KeyMessage*>(msg)->scancode(),
static_cast<KeyMessage*>(msg)->ascii());
static_cast<KeyMessage*>(msg)->unicodeChar());
}
return false;
}

View File

@ -24,6 +24,8 @@
#include <cstdio>
#include "app/resource_finder.h"
#include "base/fs.h"
#include "base/path.h"
namespace app {
@ -48,24 +50,19 @@ const char* ResourceFinder::next()
return m_paths[m_current++].c_str();
}
void ResourceFinder::addPath(std::string path)
void ResourceFinder::addPath(const std::string& path)
{
m_paths.push_back(path);
}
void ResourceFinder::findInBinDir(const char* filename)
{
char buf[1024], path[1024];
get_executable_name(path, sizeof(path));
replace_filename(buf, path, filename, sizeof(buf));
addPath(buf);
addPath(base::join_path(base::get_file_path(base::get_app_path()), filename));
}
void ResourceFinder::findInDataDir(const char* filename)
{
char buf[1024];
char buf[4096];
#if defined ALLEGRO_UNIX || defined ALLEGRO_MACOSX
@ -104,7 +101,7 @@ void ResourceFinder::findInDataDir(const char* filename)
void ResourceFinder::findInDocsDir(const char* filename)
{
char buf[1024];
char buf[4096];
#if defined ALLEGRO_UNIX || defined ALLEGRO_MACOSX
@ -140,8 +137,8 @@ void ResourceFinder::findInHomeDir(const char* filename)
{
#if defined ALLEGRO_UNIX || defined ALLEGRO_MACOSX
char *env = getenv("HOME");
char buf[1024];
char* env = getenv("HOME");
char buf[4096];
if ((env) && (*env)) {
// $HOME/filename

View File

@ -31,7 +31,7 @@ namespace app {
const char* first();
const char* next();
void addPath(std::string path);
void addPath(const std::string& path);
void findInBinDir(const char* filename);
void findInDataDir(const char* filename);

View File

@ -156,8 +156,8 @@ void ToolBox::loadTools()
{
PRINTF("Loading ASEPRITE tools\n");
TiXmlDocument& doc(GuiXml::instance()->doc());
TiXmlHandle handle(&doc);
XmlDocumentRef doc(GuiXml::instance()->doc());
TiXmlHandle handle(doc);
// For each group
TiXmlElement* xmlGroup = handle.FirstChild("gui").FirstChild("tools").FirstChild("group").ToElement();

View File

@ -43,7 +43,7 @@ class ButtonSet::Item : public RadioButton
{
public:
Item(int index, int radioGroup, int b1, int b2, int b3, int b4)
: RadioButton(NULL, radioGroup, kButtonWidget)
: RadioButton("", radioGroup, kButtonWidget)
, m_index(index)
{
setRadioGroup(radioGroup);

View File

@ -217,7 +217,7 @@ void ColorButton::onPaint(PaintEvent& ev) // TODO use "ev.getGraphics()"
if (color.isValid())
textcolor = color_utils::blackandwhite_neg(ui::rgba(color.getRed(), color.getGreen(), color.getBlue()));
jdraw_text(ji_screen, getFont(), getText(), text.x1, text.y1,
jdraw_text(ji_screen, getFont(), getText().c_str(), text.x1, text.y1,
textcolor, ColorNone, false, jguiscale());
}

View File

@ -139,7 +139,7 @@ private:
Rect rc = getBounds();
rc.y += rc.h;
rc.w *= 3;
m_popupWindow = new PopupWindow(NULL, false);
m_popupWindow = new PopupWindow("", false);
m_popupWindow->setAutoRemap(false);
m_popupWindow->setBounds(rc);

View File

@ -293,7 +293,7 @@ bool FileList::onProcessMessage(Message* msg)
if (hasFocus()) {
KeyMessage* keyMsg = static_cast<KeyMessage*>(msg);
KeyScancode scancode = keyMsg->scancode();
int ascii = keyMsg->ascii();
int unicodeChar = keyMsg->unicodeChar();
int select = getSelectedIndex();
View* view = View::getView(this);
int bottom = m_list.size();
@ -358,15 +358,15 @@ bool FileList::onProcessMessage(Message* msg)
goUp();
return true;
default:
if (ascii == ' ' ||
(utolower(ascii) >= 'a' &&
utolower(ascii) <= 'z') ||
(utolower(ascii) >= '0' &&
utolower(ascii) <= '9')) {
if (unicodeChar == ' ' ||
(utolower(unicodeChar) >= 'a' &&
utolower(unicodeChar) <= 'z') ||
(utolower(unicodeChar) >= '0' &&
utolower(unicodeChar) <= '9')) {
if (ji_clock - m_isearchClock > ISEARCH_KEYPRESS_INTERVAL_MSECS)
m_isearch.clear();
m_isearch.push_back(ascii);
m_isearch.push_back(unicodeChar);
int i, chrs = m_isearch.size();
FileItemList::iterator

View File

@ -115,7 +115,7 @@ public:
protected:
virtual bool onProcessMessage(Message* msg) OVERRIDE {
if (msg->type() == kKeyUpMessage &&
static_cast<KeyMessage*>(msg)->ascii() >= 32) {
static_cast<KeyMessage*>(msg)->unicodeChar() >= 32) {
// Check if all keys are released
for (int c=0; c<KEY_MAX; ++c) {
if (key[c])
@ -568,14 +568,11 @@ void FileSelector::addInNavigationHistory(IFileItem* folder)
void FileSelector::selectFileTypeFromFileName()
{
const char *filename = m_fileName->getText();
char *p = get_extension(filename);
char buf[MAX_PATH];
base::string ext = base::get_file_extension(m_fileName->getText());
if (p && *p != 0) {
ustrcpy(buf, get_extension(filename));
ustrlwr(buf);
m_fileType->setSelectedItemIndex(m_fileType->findItemIndex(buf));
if (!ext.empty()) {
ext = base::string_to_lower(ext);
m_fileType->setSelectedItemIndex(m_fileType->findItemIndex(ext.c_str()));
}
}

View File

@ -48,7 +48,7 @@ namespace app {
using namespace ui;
MainWindow::MainWindow()
: Window(true, NULL)
: Window(true, "")
, m_lastSplitterPos(0.0)
, m_advancedMode(false)
{
@ -206,7 +206,8 @@ void MainWindow::mouseOverTab(Tabs* tabs, TabView* tabView)
if (tabView) {
DocumentView* docView = static_cast<DocumentView*>(tabView);
Document* document = docView->getDocument();
m_statusBar->setStatusText(250, "%s", static_cast<const char*>(document->getFilename()));
m_statusBar->setStatusText(250, "%s",
document->getFilename().c_str());
}
else {
m_statusBar->clearText();

View File

@ -38,7 +38,7 @@ namespace app {
using namespace app::skin;
using namespace ui;
PopupWindowPin::PopupWindowPin(const char* text, bool close_on_buttonpressed)
PopupWindowPin::PopupWindowPin(const base::string& text, bool close_on_buttonpressed)
: PopupWindow(text, close_on_buttonpressed)
, m_pin("")
{

View File

@ -26,7 +26,7 @@ namespace app {
class PopupWindowPin : public ui::PopupWindow {
public:
PopupWindowPin(const char* text, bool close_on_buttonpressed);
PopupWindowPin(const base::string& text, bool close_on_buttonpressed);
protected:
virtual bool onProcessMessage(ui::Message* msg) OVERRIDE;

View File

@ -29,8 +29,10 @@
#include "app/ui/skin/skin_property.h"
#include "app/ui/skin/skin_slider_property.h"
#include "app/ui/skin/skin_theme.h"
#include "app/xml_document.h"
#include "app/xml_exception.h"
#include "base/bind.h"
#include "base/fs.h"
#include "base/shared_ptr.h"
#include "gfx/border.h"
#include "gfx/point.h"
@ -377,7 +379,7 @@ void SkinTheme::reload_skin()
rf.findInDataDir(sheet_filename.c_str());
while (const char* path = rf.next()) {
if (exists(path)) {
if (base::file_exists(path)) {
int old_color_conv = _color_conv;
set_color_conversion(COLORCONV_NONE);
@ -421,14 +423,11 @@ void SkinTheme::onRegenerate()
rf.findInDataDir(xml_filename.c_str());
while (const char* path = rf.next()) {
if (!exists(path))
if (!base::file_exists(path))
continue;
TiXmlDocument doc;
if (!doc.LoadFile(path))
throw XmlException(&doc);
TiXmlHandle handle(&doc);
XmlDocumentRef doc = open_xml(path);
TiXmlHandle handle(doc);
// Load colors
{
@ -1134,7 +1133,7 @@ void SkinTheme::paintListItem(ui::PaintEvent& ev)
if (widget->hasText()) {
// Text
jdraw_text(ji_screen, widget->getFont(), widget->getText(), x, y,
jdraw_text(ji_screen, widget->getFont(), widget->getText().c_str(), x, y,
fg, bg, true, jguiscale());
// Background
@ -1495,7 +1494,7 @@ void SkinTheme::paintComboBoxEntry(ui::PaintEvent& ev)
Entry* widget = static_cast<Entry*>(ev.getSource());
bool password = widget->isPassword();
int scroll, caret, state, selbeg, selend;
const char *text = widget->getText();
const char *text = widget->getText().c_str();
int c, ch, x, y, w;
int x1, y1, x2, y2;
int caret_x;
@ -1816,7 +1815,7 @@ void SkinTheme::drawTextStringDeprecated(const char *t, ui::Color fg_color, ui::
int x, y, w, h;
if (!t) {
t = widget->getText();
t = widget->getText().c_str();
w = jwidget_get_text_length(widget);
h = jwidget_get_text_height(widget);
}
@ -1887,7 +1886,7 @@ void SkinTheme::drawTextString(Graphics* g, const char *t, ui::Color fg_color, u
g->setFont(widget->getFont());
if (!t)
t = widget->getText();
t = widget->getText().c_str();
textrc.setSize(g->measureString(t));

View File

@ -127,9 +127,9 @@ public:
scancode == kKeyEnterPad) {
Command* cmd = CommandsModule::instance()->getCommandByName(CommandId::GotoFrame);
Params params;
int frame = strtol(this->getText(), NULL, 10);
int frame = getTextInt();
if (frame > 0) {
params.set("frame", this->getText());
params.set("frame", getText().c_str());
UIContext::instance()->executeCommand(cmd, &params);
}
// Select the text again
@ -162,7 +162,7 @@ StatusBar::StatusBar()
#define ICON_NEW(name, icon, action) \
{ \
BUTTON_NEW((name), NULL, (action)); \
BUTTON_NEW((name), "", (action)); \
set_gfxicon_to_button((name), icon, icon##_SELECTED, icon##_DISABLED, JI_CENTER | JI_MIDDLE); \
}
@ -547,13 +547,13 @@ bool StatusBar::onProcessMessage(Message* msg)
}
// Status bar text
if (this->getTextSize() > 0) {
textout_ex(doublebuffer, this->getFont(), this->getText(),
if (getTextSize() > 0) {
textout_ex(doublebuffer, getFont(), getText().c_str(),
x,
rc.y + rc.h/2 - text_height(this->getFont())/2,
rc.y + rc.h/2 - text_height(getFont())/2,
to_system(text_color), -1);
x += ji_font_text_len(this->getFont(), this->getText()) + 4*jguiscale();
x += ji_font_text_len(getFont(), getText().c_str()) + 4*jguiscale();
}
// Draw progress bar

View File

@ -398,7 +398,7 @@ void ToolBar::openPopupWindow(int group_index, ToolGroup* tool_group)
// In case this tool contains more than just one tool, show the popup window
m_open_on_hot = true;
m_popupWindow = new PopupWindow(NULL, false);
m_popupWindow = new PopupWindow("", false);
m_popupWindow->Close.connect(Bind<void, ToolBar, ToolBar>(&ToolBar::onClosePopup, this));
ToolStrip* toolstrip = new ToolStrip(tool_group, this);

View File

@ -24,11 +24,13 @@
#include "app/app.h"
#include "app/modules/gui.h"
#include "app/xml_document.h"
#include "app/resource_finder.h"
#include "app/ui/color_button.h"
#include "app/widget_not_found.h"
#include "app/xml_exception.h"
#include "base/bind.h"
#include "base/fs.h"
#include "base/memory.h"
#include "ui/ui.h"
@ -76,12 +78,12 @@ Widget* WidgetLoader::loadWidget(const char* fileName, const char* widgetId)
rf.addPath(fileName);
buf = "app/ui/";
buf = "widgets/";
buf += fileName;
rf.findInDataDir(buf.c_str());
while (const char* path = rf.next()) {
if (exists(path)) {
if (base::file_exists(path)) {
buf = path;
found = true;
break;
@ -91,24 +93,23 @@ Widget* WidgetLoader::loadWidget(const char* fileName, const char* widgetId)
if (!found)
throw WidgetNotFound(widgetId);
widget = loadWidgetFromXmlFile(buf.c_str(), widgetId);
widget = loadWidgetFromXmlFile(buf, widgetId);
if (!widget)
throw WidgetNotFound(widgetId);
return widget;
}
Widget* WidgetLoader::loadWidgetFromXmlFile(const char* xmlFilename, const char* widgetId)
Widget* WidgetLoader::loadWidgetFromXmlFile(const base::string& xmlFilename,
const base::string& widgetId)
{
Widget* widget = NULL;
m_tooltipManager = NULL;
TiXmlDocument doc;
if (!doc.LoadFile(xmlFilename))
throw XmlException(&doc);
XmlDocumentRef doc(open_xml(xmlFilename));
TiXmlHandle handle(doc);
// Search the requested widget.
TiXmlHandle handle(&doc);
TiXmlElement* xmlElement = handle
.FirstChild("gui")
.FirstChildElement().ToElement();
@ -116,7 +117,7 @@ Widget* WidgetLoader::loadWidgetFromXmlFile(const char* xmlFilename, const char*
while (xmlElement) {
const char* nodename = xmlElement->Attribute("id");
if (nodename && ustrcmp(nodename, widgetId) == 0) {
if (nodename && nodename == widgetId) {
widget = convertXmlElementToWidget(xmlElement, NULL);
break;
}
@ -129,7 +130,7 @@ Widget* WidgetLoader::loadWidgetFromXmlFile(const char* xmlFilename, const char*
Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget* root)
{
const char *elem_name = elem->Value();
const std::string elem_name = elem->Value();
Widget* widget = NULL;
Widget* child;
@ -142,7 +143,7 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
widget = it->second->createWidgetFromXml(elem);
}
// Boxes
else if (ustrcmp(elem_name, "box") == 0) {
else if (elem_name == "box") {
bool horizontal = bool_attr_is_true(elem, "horizontal");
bool vertical = bool_attr_is_true(elem, "vertical");
bool homogeneous = bool_attr_is_true(elem, "homogeneous");
@ -151,25 +152,25 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
vertical ? JI_VERTICAL: 0) |
(homogeneous ? JI_HOMOGENEOUS: 0));
}
else if (ustrcmp(elem_name, "vbox") == 0) {
else if (elem_name == "vbox") {
bool homogeneous = bool_attr_is_true(elem, "homogeneous");
widget = new VBox();
if (homogeneous)
widget->setAlign(widget->getAlign() | JI_HOMOGENEOUS);
}
else if (ustrcmp(elem_name, "hbox") == 0) {
else if (elem_name == "hbox") {
bool homogeneous = bool_attr_is_true(elem, "homogeneous");
widget = new HBox();
if (homogeneous)
widget->setAlign(widget->getAlign() | JI_HOMOGENEOUS);
}
else if (ustrcmp(elem_name, "boxfiller") == 0) {
else if (elem_name == "boxfiller") {
widget = new BoxFiller();
}
// Button
else if (ustrcmp(elem_name, "button") == 0) {
else if (elem_name == "button") {
const char *text = elem->Attribute("text");
widget = new Button(text ? TRANSLATE_ATTR(text): NULL);
@ -210,7 +211,7 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
}
}
// Check
else if (ustrcmp(elem_name, "check") == 0) {
else if (elem_name == "check") {
const char *text = elem->Attribute("text");
const char *looklike = elem->Attribute("looklike");
@ -236,11 +237,11 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
}
}
/* combobox */
else if (ustrcmp(elem_name, "combobox") == 0) {
else if (elem_name == "combobox") {
widget = new ComboBox();
}
/* entry */
else if (ustrcmp(elem_name, "entry") == 0) {
else if (elem_name == "entry") {
const char* maxsize = elem->Attribute("maxsize");
const char* text = elem->Attribute("text");
const char* suffix = elem->Attribute("suffix");
@ -261,7 +262,7 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
throw std::runtime_error("<entry> element found without 'maxsize' attribute");
}
/* grid */
else if (ustrcmp(elem_name, "grid") == 0) {
else if (elem_name == "grid") {
const char *columns = elem->Attribute("columns");
bool same_width_columns = bool_attr_is_true(elem, "same_width_columns");
@ -271,7 +272,7 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
}
}
/* label */
else if (ustrcmp(elem_name, "label") == 0) {
else if (elem_name == "label") {
const char *text = elem->Attribute("text");
widget = new Label(text ? TRANSLATE_ATTR(text): NULL);
@ -288,17 +289,17 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
}
}
/* listbox */
else if (ustrcmp(elem_name, "listbox") == 0) {
else if (elem_name == "listbox") {
widget = new ListBox();
}
/* listitem */
else if (ustrcmp(elem_name, "listitem") == 0) {
else if (elem_name == "listitem") {
const char *text = elem->Attribute("text");
widget = new ListItem(text ? TRANSLATE_ATTR(text): NULL);
}
/* splitter */
else if (ustrcmp(elem_name, "splitter") == 0) {
else if (elem_name == "splitter") {
bool horizontal = bool_attr_is_true(elem, "horizontal");
bool vertical = bool_attr_is_true(elem, "vertical");
const char* by = elem->Attribute("by");
@ -317,7 +318,7 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
widget = splitter;
}
/* radio */
else if (ustrcmp(elem_name, "radio") == 0) {
else if (elem_name == "radio") {
const char* text = elem->Attribute("text");
const char* group = elem->Attribute("group");
const char *looklike = elem->Attribute("looklike");
@ -345,7 +346,7 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
}
}
/* separator */
else if (ustrcmp(elem_name, "separator") == 0) {
else if (elem_name == "separator") {
const char *text = elem->Attribute("text");
bool center = bool_attr_is_true(elem, "center");
bool right = bool_attr_is_true(elem, "right");
@ -354,7 +355,7 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
bool horizontal = bool_attr_is_true(elem, "horizontal");
bool vertical = bool_attr_is_true(elem, "vertical");
widget = new Separator(text ? TRANSLATE_ATTR(text): NULL,
widget = new Separator(text ? TRANSLATE_ATTR(text): "",
(horizontal ? JI_HORIZONTAL: 0) |
(vertical ? JI_VERTICAL: 0) |
(center ? JI_CENTER:
@ -363,7 +364,7 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
(bottom ? JI_BOTTOM: JI_TOP)));
}
/* slider */
else if (ustrcmp(elem_name, "slider") == 0) {
else if (elem_name == "slider") {
const char *min = elem->Attribute("min");
const char *max = elem->Attribute("max");
int min_value = min != NULL ? ustrtol(min, NULL, 10): 0;
@ -372,30 +373,30 @@ Widget* WidgetLoader::convertXmlElementToWidget(const TiXmlElement* elem, Widget
widget = new Slider(min_value, max_value, min_value);
}
/* textbox */
else if (ustrcmp(elem_name, "textbox") == 0) {
else if (elem_name == "textbox") {
bool wordwrap = bool_attr_is_true(elem, "wordwrap");
widget = new TextBox(elem->GetText(), wordwrap ? JI_WORDWRAP: 0);
}
/* view */
else if (ustrcmp(elem_name, "view") == 0) {
else if (elem_name == "view") {
widget = new View();
}
/* window */
else if (ustrcmp(elem_name, "window") == 0) {
else if (elem_name == "window") {
const char *text = elem->Attribute("text");
if (text) {
bool desktop = bool_attr_is_true(elem, "desktop");
if (desktop)
widget = new Window(true, NULL);
widget = new Window(true, "");
else
widget = new Window(false, TRANSLATE_ATTR(text));
}
}
/* colorpicker */
else if (ustrcmp(elem_name, "colorpicker") == 0) {
else if (elem_name == "colorpicker") {
widget = new ColorButton(Color::fromMask(), app_get_current_pixel_format());
}

View File

@ -20,9 +20,9 @@
#define APP_WIDGET_LOADER_H_INCLUDED
#include "app/widget_type_mismatch.h"
#include "base/string.h"
#include <map>
#include <string>
class TiXmlElement;
@ -69,10 +69,11 @@ namespace app {
}
private:
ui::Widget* loadWidgetFromXmlFile(const char* xmlFilename, const char* widgetId);
ui::Widget* loadWidgetFromXmlFile(const base::string& xmlFilename,
const base::string& widgetId);
ui::Widget* convertXmlElementToWidget(const TiXmlElement* elem, ui::Widget* root);
typedef std::map<std::string, IWidgetTypeCreator*> TypeCreatorsMap;
typedef std::map<base::string, IWidgetTypeCreator*> TypeCreatorsMap;
TypeCreatorsMap m_typeCreators;
ui::TooltipManager* m_tooltipManager;

View File

@ -26,9 +26,9 @@ namespace app {
class WidgetNotFound : public std::runtime_error {
public:
WidgetNotFound(const char* widgetId)
: std::runtime_error(std::string("A data file is corrupted.\nPlease reinstall the program\n\n"
"Details: Widget not found: ") + widgetId) { }
WidgetNotFound(const std::string& widgetId)
: std::runtime_error("A data file is corrupted.\nPlease reinstall the program\n\n"
"Details: Widget not found: " + widgetId) { }
};
} // namespace app

View File

@ -26,8 +26,8 @@ namespace app {
class WidgetTypeMismatch : public std::runtime_error {
public:
WidgetTypeMismatch(const char* widgetId)
: std::runtime_error(std::string("Widget ") + widgetId +
WidgetTypeMismatch(const std::string& widgetId)
: std::runtime_error("Widget " + widgetId +
" of the expected type.\nPlease reinstall the program.\n\n") { }
};

49
src/app/xml_document.cpp Normal file
View File

@ -0,0 +1,49 @@
/* Aseprite
* Copyright (C) 2001-2013 David Capello
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "app/xml_document.h"
#include "app/xml_exception.h"
#include "base/file_handle.h"
#include "tinyxml.h"
namespace app {
using namespace base;
XmlDocumentRef open_xml(const string& filename)
{
FileHandle file(open_file(filename, "rb"));
if (!file)
throw Exception("Error loading file: " + filename);
// Try to load the XML file
XmlDocumentRef doc(new TiXmlDocument());
doc->SetValue(filename.c_str());
if (!doc->LoadFile(file))
throw XmlException(doc);
return doc;
}
} // namespace app

View File

@ -16,29 +16,21 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef APP_FILE_HANDLE_FORMAT_H_INCLUDED
#define APP_FILE_HANDLE_FORMAT_H_INCLUDED
#ifndef APP_XML_DOCUMENT_H_INCLUDED
#define APP_XML_DOCUMENT_H_INCLUDED
#include "base/exception.h"
#include "base/unique_ptr.h"
#include "base/shared_ptr.h"
#include "base/string.h"
#include <cstdio>
#include <string>
#include "tinyxml.h"
class FileHandle
{
public:
FileHandle(const char* fileName, const char* mode)
: m_handle(std::fopen(fileName, mode), std::fclose)
{
if (!m_handle)
throw base::Exception(std::string("Cannot open ") + fileName);
}
namespace app {
operator std::FILE*() { return m_handle; }
typedef SharedPtr<TiXmlDocument> XmlDocumentRef;
private:
base::UniquePtr<std::FILE, int(*)(std::FILE*)> m_handle;
};
XmlDocumentRef open_xml(const base::string& filename);
} // namespace app
#endif

View File

@ -28,7 +28,7 @@
namespace app {
XmlException::XmlException(TiXmlDocument* doc) throw()
XmlException::XmlException(const TiXmlDocument* doc) throw()
{
try {
char buf[4096]; // TODO Overflow

View File

@ -27,7 +27,7 @@ namespace app {
class XmlException : public base::Exception {
public:
XmlException(TiXmlDocument* doc) throw();
XmlException(const TiXmlDocument* doc) throw();
};
} // namespace app

View File

@ -21,6 +21,7 @@ add_library(base-lib
convert_to.cpp
errno_string.cpp
exception.cpp
file_handle.cpp
fs.cpp
launcher.cpp
mem_utils.cpp

48
src/base/file_handle.cpp Normal file
View File

@ -0,0 +1,48 @@
// Aseprite Base Library
// Copyright (c) 2001-2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "base/file_handle.h"
#include "base/string.h"
#include <stdexcept>
#ifdef WIN32
#include <windows.h>
#endif
using namespace std;
namespace base {
FILE* open_file_raw(const string& filename, const string& mode)
{
#ifdef WIN32
return _wfopen(from_utf8(filename).c_str(),
from_utf8(mode).c_str());
#else
return fopen(filename.c_str(), mode);
#endif
}
FileHandle open_file(const string& filename, const string& mode)
{
return FileHandle(open_file_raw(filename, mode), fclose);
}
FileHandle open_file_with_exception(const string& filename, const string& mode)
{
FileHandle f(open_file_raw(filename, mode), fclose);
if (!f)
throw runtime_error("Cannot open " + filename);
return f;
}
}

25
src/base/file_handle.h Normal file
View File

@ -0,0 +1,25 @@
// Aseprite Base Library
// Copyright (c) 2001-2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#ifndef BASE_OPEN_FILE_H_INCLUDED
#define BASE_OPEN_FILE_H_INCLUDED
#include "base/shared_ptr.h"
#include "base/string.h"
#include <cstdio>
namespace base {
typedef SharedPtr<FILE> FileHandle;
FILE* open_file_raw(const string& filename, const string& mode);
FileHandle open_file(const string& filename, const string& mode);
FileHandle open_file_with_exception(const string& filename, const string& mode);
}
#endif

View File

@ -17,6 +17,7 @@ namespace base {
void make_directory(const string& path);
void remove_directory(const string& path);
string get_app_path();
string get_temp_path();
}

View File

@ -42,6 +42,11 @@ void remove_directory(const string& path)
}
}
string get_app_path()
{
return getexecname();
}
string get_temp_path()
{
char* tmpdir = getenv("TMPDIR");

View File

@ -7,11 +7,13 @@
#include <windows.h>
#include <stdexcept>
#include "base/string.h"
namespace base {
bool file_exists(const string& path)
{
DWORD attr = ::GetFileAttributes(path.c_str());
DWORD attr = ::GetFileAttributes(from_utf8(path).c_str());
// GetFileAttributes returns INVALID_FILE_ATTRIBUTES in case of
// fail.
@ -21,7 +23,7 @@ bool file_exists(const string& path)
bool directory_exists(const string& path)
{
DWORD attr = ::GetFileAttributes(path.c_str());
DWORD attr = ::GetFileAttributes(from_utf8(path).c_str());
return ((attr != INVALID_FILE_ATTRIBUTES) &&
((attr & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY));
@ -29,7 +31,7 @@ bool directory_exists(const string& path)
void make_directory(const string& path)
{
BOOL result = ::CreateDirectory(path.c_str(), NULL);
BOOL result = ::CreateDirectory(from_utf8(path).c_str(), NULL);
if (result == 0) {
// TODO add GetLastError() value into the exception
throw std::runtime_error("Error creating directory");
@ -38,18 +40,27 @@ void make_directory(const string& path)
void remove_directory(const string& path)
{
BOOL result = ::RemoveDirectory(path.c_str());
BOOL result = ::RemoveDirectory(from_utf8(path).c_str());
if (result == 0) {
// TODO add GetLastError() value into the exception
throw std::runtime_error("Error removing directory");
}
}
string get_app_path()
{
TCHAR buffer[MAX_PATH+1];
if (::GetModuleFileName(NULL, buffer, sizeof(buffer)/sizeof(TCHAR)))
return to_utf8(buffer);
else
return "";
}
string get_temp_path()
{
TCHAR buffer[MAX_PATH+1];
DWORD result = GetTempPath(sizeof(buffer)/sizeof(TCHAR), buffer);
return string(buffer);
return to_utf8(buffer);
}
}

View File

@ -10,6 +10,7 @@
#include "base/launcher.h"
#include "base/exception.h"
#include "base/string.h"
#ifdef WIN32
#include <windows.h>
@ -17,7 +18,7 @@
#define SEE_MASK_DEFAULT 0x00000000
#endif
static int win32_shell_execute(const char* verb, const char* file, const char* params)
static int win32_shell_execute(const wchar_t* verb, const wchar_t* file, const wchar_t* params)
{
SHELLEXECUTEINFO sh;
ZeroMemory((LPVOID)&sh, sizeof(sh));
@ -70,7 +71,8 @@ bool open_file(const std::string& file)
#ifdef WIN32
ret = win32_shell_execute("open", file.c_str(), NULL);
ret = win32_shell_execute(L"open",
base::from_utf8(file).c_str(), NULL);
#elif __APPLE__
@ -88,7 +90,10 @@ bool open_file(const std::string& file)
bool open_folder(const std::string& file)
{
#ifdef WIN32
int ret = win32_shell_execute(NULL, "explorer", ("/e,/select,\"" + file + "\"").c_str());
int ret = win32_shell_execute(NULL,
L"explorer",
(L"/e,/select,\"" + base::from_utf8(file) + L"\"").c_str());
return (ret == 0);
#else
return false;

View File

@ -12,13 +12,15 @@
#include <dbghelp.h>
#endif
static std::string memoryDumpFile;
#include "base/string.h"
static std::wstring memoryDumpFile;
class base::MemoryDump::MemoryDumpImpl
{
public:
MemoryDumpImpl() {
memoryDumpFile = "memory.dmp";
memoryDumpFile = L"memory.dmp";
::SetUnhandledExceptionFilter(MemoryDumpImpl::unhandledException);
}
@ -27,7 +29,7 @@ public:
}
void setFileName(const std::string& fileName) {
memoryDumpFile = fileName;
memoryDumpFile = base::from_utf8(fileName);
}
static LONG WINAPI unhandledException(_EXCEPTION_POINTERS* exceptionPointers) {

View File

@ -60,7 +60,8 @@ public:
~SharedPtrRefCounterImpl()
{
m_deleter(m_ptr);
if (m_ptr)
m_deleter(m_ptr);
}
private:
@ -89,7 +90,8 @@ public:
m_refCount = new SharedPtrRefCounterImpl<T, DefaultSharedPtrDeleter<T> >(ptr, DefaultSharedPtrDeleter<T>());
}
catch (...) {
DefaultSharedPtrDeleter<T>()(ptr);
if (ptr)
DefaultSharedPtrDeleter<T>()(ptr);
throw;
}
m_ptr = ptr;
@ -104,7 +106,8 @@ public:
m_refCount = new SharedPtrRefCounterImpl<T, Deleter>(ptr, deleter);
}
catch (...) {
deleter(ptr);
if (ptr)
deleter(ptr);
throw;
}
m_ptr = ptr;
@ -146,7 +149,8 @@ public:
m_refCount = new SharedPtrRefCounterImpl<T, DefaultSharedPtrDeleter<T> >(ptr, DefaultSharedPtrDeleter<T>());
}
catch (...) {
DefaultSharedPtrDeleter<T>()(ptr);
if (ptr)
DefaultSharedPtrDeleter<T>()(ptr);
throw;
}
m_ptr = ptr;
@ -168,7 +172,8 @@ public:
m_refCount = new SharedPtrRefCounterImpl<T, Deleter>(ptr, deleter);
}
catch (...) {
deleter(ptr);
if (ptr)
deleter(ptr);
throw;
}
m_ptr = ptr;

View File

@ -9,8 +9,13 @@
#endif
#include "base/string.h"
#include <vector>
#include <cctype>
#ifdef WIN32
#include <windows.h>
#endif
namespace base {
string string_to_lower(const string& original)
@ -33,4 +38,59 @@ string string_to_upper(const string& original)
return result;
}
#ifdef WIN32
string to_utf8(const std::wstring& src)
{
int required_size =
::WideCharToMultiByte(CP_UTF8, 0,
src.c_str(), src.size(),
NULL, 0, NULL, NULL);
if (required_size == 0)
return string();
std::vector<char> buf(++required_size);
::WideCharToMultiByte(CP_UTF8, 0,
src.c_str(), src.size(),
&buf[0], required_size,
NULL, NULL);
return base::string(&buf[0]);
}
std::wstring from_utf8(const string& src)
{
int required_size =
MultiByteToWideChar(CP_UTF8, 0,
src.c_str(), src.size(),
NULL, 0);
if (required_size == 0)
return std::wstring();
std::vector<wchar_t> buf(++required_size);
::MultiByteToWideChar(CP_UTF8, 0,
src.c_str(), src.size(),
&buf[0], required_size);
return std::wstring(&buf[0]);
}
#endif // WIN32
int utf8_length(const string& utf8string)
{
utf8_const_iterator it(utf8string.begin());
utf8_const_iterator end(utf8string.end());
int c = 0;
while (it != end)
++it, ++c;
return c;
}
} // namespace base

View File

@ -8,6 +8,7 @@
#define BASE_STRING_H_INCLUDED
#include <string>
#include <iterator>
namespace base {
@ -16,6 +17,123 @@ namespace base {
string string_to_lower(const string& original);
string string_to_upper(const string& original);
string to_utf8(const std::wstring& widestring);
std::wstring from_utf8(const string& utf8string);
int utf8_length(const string& utf8string);
template<typename SubIterator>
class utf8_iteratorT : public std::iterator<std::forward_iterator_tag,
string::value_type,
string::difference_type,
typename SubIterator::pointer,
typename SubIterator::reference> {
public:
explicit utf8_iteratorT(const SubIterator& it)
: m_internal(it) {
}
utf8_iteratorT& operator++() {
int c = *m_internal;
++m_internal;
if (c & 0x80) {
int n = 1;
while (c & (0x80>>n))
n++;
c &= (1<<(8-n))-1;
while (--n > 0) {
int t = *m_internal;
++m_internal;
if ((!(t & 0x80)) || (t & 0x40)) {
--m_internal;
return *this;
}
c = (c<<6) | (t & 0x3F);
}
}
return *this;
}
utf8_iteratorT& operator+=(int i) {
while (i--)
operator++();
return *this;
}
utf8_iteratorT operator+(int i) {
utf8_iteratorT it(*this);
it += i;
return it;
}
const int operator*() const {
SubIterator it = m_internal;
int c = *it;
++it;
if (c & 0x80) {
int n = 1;
while (c & (0x80>>n))
n++;
c &= (1<<(8-n))-1;
while (--n > 0) {
int t = *it;
++it;
if ((!(t & 0x80)) || (t & 0x40))
return '^';
c = (c<<6) | (t & 0x3F);
}
}
return c;
}
bool operator==(const utf8_iteratorT& it) const {
return m_internal == it.m_internal;
}
bool operator!=(const utf8_iteratorT& it) const {
return m_internal != it.m_internal;
}
pointer operator->() {
return m_internal.operator->();
}
private:
SubIterator m_internal;
};
class utf8_iterator : public utf8_iteratorT<string::iterator> {
public:
utf8_iterator(const utf8_iteratorT<string::iterator>& it)
: utf8_iteratorT<string::iterator>(it) {
}
explicit utf8_iterator(const string::iterator& it)
: utf8_iteratorT<string::iterator>(it) {
}
};
class utf8_const_iterator : public utf8_iteratorT<string::const_iterator> {
public:
utf8_const_iterator(const utf8_iteratorT<string::const_iterator>& it)
: utf8_iteratorT<string::const_iterator>(it) {
}
explicit utf8_const_iterator(const string::const_iterator& it)
: utf8_iteratorT<string::const_iterator>(it) {
}
};
}
#endif

View File

@ -0,0 +1,59 @@
// Aseprite Base Library
// Copyright (c) 2001-2013 David Capello
//
// This source file is distributed under MIT license,
// please read LICENSE.txt for more information.
#include <gtest/gtest.h>
#include "base/string.h"
#include <algorithm>
using namespace base;
bool all(int) { return true; }
TEST(String, Utf8Iterator)
{
string a = "Hello";
int value = std::count_if(utf8_iterator(a.begin()),
utf8_iterator(a.end()), all);
ASSERT_EQ(5, value);
ASSERT_EQ('H', *(utf8_iterator(a.begin())));
ASSERT_EQ('e', *(utf8_iterator(a.begin())+1));
ASSERT_EQ('l', *(utf8_iterator(a.begin())+2));
ASSERT_EQ('l', *(utf8_iterator(a.begin())+3));
ASSERT_EQ('o', *(utf8_iterator(a.begin())+4));
string b = "Copyright \xC2\xA9";
value = std::count_if(utf8_iterator(b.begin()),
utf8_iterator(b.end()), all);
ASSERT_EQ(11, value);
ASSERT_EQ('C', *(utf8_iterator(b.begin())));
ASSERT_EQ('o', *(utf8_iterator(b.begin())+1));
ASSERT_EQ(0xA9, *(utf8_iterator(b.begin())+10));
ASSERT_TRUE((utf8_iterator(b.begin())+11) == utf8_iterator(b.end()));
string c = "\xf0\x90\x8d\x86\xe6\x97\xa5\xd1\x88";
value = std::count_if(utf8_iterator(c.begin()),
utf8_iterator(c.end()), all);
ASSERT_EQ(3, value);
ASSERT_EQ(0x10346, *(utf8_iterator(c.begin())));
ASSERT_EQ(0x65E5, *(utf8_iterator(c.begin())+1));
ASSERT_EQ(0x448, *(utf8_iterator(c.begin())+2));
ASSERT_TRUE((utf8_iterator(c.begin())+3) == utf8_iterator(c.end()));
string d = "\xf0\xa4\xad\xa2";
value = std::count_if(utf8_iterator(d.begin()),
utf8_iterator(d.end()), all);
ASSERT_EQ(1, value);
ASSERT_EQ(0x24B62, *(utf8_iterator(d.begin())));
ASSERT_TRUE((utf8_iterator(d.begin())+1) == utf8_iterator(d.end()));
}
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -84,7 +84,7 @@ int app_main(int argc, char* argv[])
std::srand(static_cast<unsigned int>(std::time(NULL)));
#ifdef WIN32
CoInitialize(NULL);
::CoInitialize(NULL);
#endif
try {
@ -105,6 +105,9 @@ int app_main(int argc, char* argv[])
}
catch (std::exception& e) {
std::cerr << e.what() << '\n';
#ifdef WIN32
::MessageBoxA(NULL, e.what(), PACKAGE, MB_OK | MB_ICONERROR);
#endif
return 1;
}
}

View File

@ -11,6 +11,7 @@
#include "she.h"
#include <allegro.h>
#include <allegro/internal/aintern.h>
#ifdef ALLEGRO_WINDOWS
#include <winalleg.h>
#endif
@ -272,7 +273,8 @@ class Alleg4System : public System {
public:
Alleg4System() {
allegro_init();
set_uformat(U_ASCII);
set_uformat(U_UTF8);
_al_detect_filename_encoding();
install_timer();
// Register PNG as a supported bitmap type

View File

@ -21,13 +21,13 @@
namespace ui {
void Accelerator::addKey(KeyModifiers modifiers, KeyScancode scancode, int ascii)
void Accelerator::addKey(KeyModifiers modifiers, KeyScancode scancode, int unicodeChar)
{
KeyCombo key;
key.modifiers = modifiers;
key.scancode = scancode;
key.ascii = ascii;
key.unicodeChar = unicodeChar;
m_combos.push_back(key);
}
@ -36,7 +36,7 @@ static void process_one_word(Accelerator* accel, char* word)
{
KeyModifiers modifiers = kKeyNoneModifier;
KeyScancode scancode = kKeyNil;
int ascii = 0;
int unicodeChar = 0;
char* tok;
// Special case: plus sign
@ -65,10 +65,10 @@ static void process_one_word(Accelerator* accel, char* word)
else if (tok[1] == 0) {
if (((*tok >= 'a') && (*tok <= 'z')) ||
((*tok >= 'A') && (*tok <= 'Z'))) {
ascii = tolower(*tok);
unicodeChar = tolower(*tok);
}
else {
ascii = *tok;
unicodeChar = *tok;
}
if (((*tok >= 'a') && (*tok <= 'z')) ||
@ -171,7 +171,7 @@ static void process_one_word(Accelerator* accel, char* word)
}
}
accel->addKey(modifiers, scancode, ascii);
accel->addKey(modifiers, scancode, unicodeChar);
}
void Accelerator::addKeysFromString(const char* string)
@ -323,8 +323,8 @@ std::string Accelerator::KeyCombo::toString()
ustrcat(buf, "Shift+");
// Key
if (this->ascii)
usprintf(buf+ustrlen(buf), "%c", toupper(this->ascii));
if (this->unicodeChar)
usprintf(buf+ustrlen(buf), "%c", toupper(this->unicodeChar));
else if (this->scancode)
ustrcat(buf, table[this->scancode]);
else
@ -339,7 +339,7 @@ std::string Accelerator::toString()
return m_combos.front().toString();
}
bool Accelerator::check(KeyModifiers modifiers, KeyScancode scancode, int ascii)
bool Accelerator::check(KeyModifiers modifiers, KeyScancode scancode, int unicodeChar)
{
#ifdef REPORT_KEYS
char buf[256];
@ -359,10 +359,10 @@ bool Accelerator::check(KeyModifiers modifiers, KeyScancode scancode, int ascii)
(scancode >= kKeySpace && scancode <= kKeyDown) ||
(scancode >= kKeyEnterPad && scancode <= kKeyNoconvert) ||
(scancode == kKeyKanji)) {
ascii = 0;
unicodeChar = 0;
}
// For Ctrl+number
/* scancode ascii
/* scancode unicodeChar
Ctrl+0 27 0
Ctrl+1 28 2
Ctrl+2 29 0
@ -375,22 +375,22 @@ bool Accelerator::check(KeyModifiers modifiers, KeyScancode scancode, int ascii)
Ctrl+9 36 2
*/
else if ((scancode >= kKey0 && scancode <= kKey9) &&
(ascii < 32 || ascii == 127)) {
ascii = '0' + scancode - kKey0;
(unicodeChar < 32 || unicodeChar == 127)) {
unicodeChar = '0' + scancode - kKey0;
scancode = kKeyNil;
}
// For Ctrl+letter
else if (ascii >= 1 && ascii <= 'z'-'a'+1) {
ascii = 'a'+ascii-1;
else if (unicodeChar >= 1 && unicodeChar <= 'z'-'a'+1) {
unicodeChar = 'a'+unicodeChar-1;
scancode = kKeyNil;
}
// For any other legal ASCII code
else if (ascii >= ' ') {
ascii = tolower(ascii);
// For any other legal Unicode code
else if (unicodeChar >= ' ') {
unicodeChar = tolower(unicodeChar);
/* without shift (because characters like '*' can be trigger with
"Shift+8", so we don't want "Shift+*") */
if (!(ascii >= 'a' && ascii <= 'z'))
if (!(unicodeChar >= 'a' && unicodeChar <= 'z'))
modifiers = (KeyModifiers)((int)modifiers & ((int)~kKeyShiftModifier));
scancode = kKeyNil;
@ -400,7 +400,7 @@ bool Accelerator::check(KeyModifiers modifiers, KeyScancode scancode, int ascii)
#ifdef REPORT_KEYS
{
base::UniquePtr<Accelerator> a2(new Accelerator);
a2->addKey(modifiers, scancode, ascii);
a2->addKey(modifiers, scancode, unicodeChar);
buf2 = a2->getString();
}
#endif
@ -409,13 +409,13 @@ bool Accelerator::check(KeyModifiers modifiers, KeyScancode scancode, int ascii)
it != end; ++it) {
#ifdef REPORT_KEYS
printf("%3d==%3d %3d==%3d %s==%s ",
it->scancode, scancode, it->ascii, ascii,
it->scancode, scancode, it->unicodeChar, unicodeChar,
it->getString().c_str(), buf2.c_str();
#endif
if ((it->modifiers == modifiers) &&
((it->scancode != kKeyNil && it->scancode == scancode) ||
(it->ascii && it->ascii == ascii))) {
(it->unicodeChar && it->unicodeChar == unicodeChar))) {
#ifdef REPORT_KEYS
printf("true\n");

View File

@ -17,7 +17,7 @@ namespace ui {
class Accelerator
{
public:
void addKey(KeyModifiers modifiers, KeyScancode scancode, int ascii);
void addKey(KeyModifiers modifiers, KeyScancode scancode, int unicodeChar);
// Adds keys from strings like "<Ctrl+Q> <ESC>"
void addKeysFromString(const char* string);
@ -25,14 +25,14 @@ namespace ui {
bool isEmpty() const { return m_combos.empty(); }
std::string toString();
bool check(KeyModifiers modifiers, KeyScancode scancode, int ascii);
bool check(KeyModifiers modifiers, KeyScancode scancode, int unicodeChar);
bool checkFromAllegroKeyArray();
private:
struct KeyCombo {
KeyModifiers modifiers;
KeyScancode scancode;
int ascii;
int unicodeChar;
std::string toString();
};

View File

@ -139,7 +139,7 @@ void Alert::processString(char* buf, std::vector<Widget*>& labels, std::vector<W
labels.push_back(label);
}
else if (separator) {
labels.push_back(new Separator(NULL, JI_HORIZONTAL));
labels.push_back(new Separator("", JI_HORIZONTAL));
}
else if (button) {
char buttonId[256];

View File

@ -57,8 +57,7 @@ namespace ui {
#define JI_EXPANSIVE 0x0100 // Is expansive (want more space).
#define JI_DECORATIVE 0x0200 // To decorate windows.
#define JI_INITIALIZED 0x0400 // The widget was already initialized by a theme.
#define JI_NOTEXT 0x0800 // The widget does not have text.
#define JI_DIRTY 0x1000 // The widget (or one child) is dirty (update_region != empty).
#define JI_DIRTY 0x0800 // The widget (or one child) is dirty (update_region != empty).
typedef unsigned int JID;

View File

@ -25,7 +25,7 @@
namespace ui {
ButtonBase::ButtonBase(const char* text,
ButtonBase::ButtonBase(const base::string& text,
WidgetType type,
WidgetType behaviorType,
WidgetType drawType)
@ -309,7 +309,7 @@ void ButtonBase::generateButtonSelectSignal()
// Button class
// ======================================================================
Button::Button(const char *text)
Button::Button(const base::string& text)
: ButtonBase(text, kButtonWidget, kButtonWidget, kButtonWidget)
{
setAlign(JI_CENTER | JI_MIDDLE);
@ -319,7 +319,7 @@ Button::Button(const char *text)
// CheckBox class
// ======================================================================
CheckBox::CheckBox(const char *text, WidgetType drawType)
CheckBox::CheckBox(const base::string& text, WidgetType drawType)
: ButtonBase(text, kCheckWidget, kCheckWidget, drawType)
{
setAlign(JI_LEFT | JI_MIDDLE);
@ -329,7 +329,7 @@ CheckBox::CheckBox(const char *text, WidgetType drawType)
// RadioButton class
// ======================================================================
RadioButton::RadioButton(const char *text, int radioGroup, WidgetType drawType)
RadioButton::RadioButton(const base::string& text, int radioGroup, WidgetType drawType)
: ButtonBase(text, kRadioWidget, kRadioWidget, drawType)
{
setAlign(JI_LEFT | JI_MIDDLE);

View File

@ -36,7 +36,7 @@ namespace ui {
class ButtonBase : public Widget
{
public:
ButtonBase(const char* text,
ButtonBase(const base::string& text,
WidgetType type,
WidgetType behaviorType,
WidgetType drawType);
@ -80,21 +80,21 @@ namespace ui {
class Button : public ButtonBase
{
public:
Button(const char* text);
Button(const base::string& text);
};
// Check boxes
class CheckBox : public ButtonBase
{
public:
CheckBox(const char* text, WidgetType drawType = kCheckWidget);
CheckBox(const base::string& text, WidgetType drawType = kCheckWidget);
};
// Radio buttons
class RadioButton : public ButtonBase
{
public:
RadioButton(const char* text, int radioGroup, WidgetType drawType = kRadioWidget);
RadioButton(const base::string& text, int radioGroup, WidgetType drawType = kRadioWidget);
int getRadioGroup() const;
void setRadioGroup(int radioGroup);

View File

@ -10,8 +10,9 @@
#include "ui/clipboard.h"
#include "base/string.h"
#include <algorithm>
#include <string>
#ifdef WIN32
#include <allegro.h>
@ -20,7 +21,7 @@
#pragma warning(disable:4996) // To void MSVC warning about std::copy() with unsafe arguments
static std::string clipboard_text;
static base::string clipboard_text;
static void lowlevel_set_clipboard_text(const char *text)
{
@ -30,13 +31,13 @@ static void lowlevel_set_clipboard_text(const char *text)
const char* ui::clipboard::get_text()
{
#ifdef WIN32
if (IsClipboardFormatAvailable(CF_TEXT)) {
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
if (OpenClipboard(win_get_window())) {
HGLOBAL hglobal = GetClipboardData(CF_TEXT);
HGLOBAL hglobal = GetClipboardData(CF_UNICODETEXT);
if (hglobal != NULL) {
LPSTR lpstr = static_cast<LPSTR>(GlobalLock(hglobal));
LPWSTR lpstr = static_cast<LPWSTR>(GlobalLock(hglobal));
if (lpstr != NULL) {
lowlevel_set_clipboard_text(lpstr);
lowlevel_set_clipboard_text(base::to_utf8(lpstr).c_str());
GlobalUnlock(hglobal);
}
}
@ -53,21 +54,22 @@ void ui::clipboard::set_text(const char *text)
lowlevel_set_clipboard_text(text);
#ifdef WIN32
if (IsClipboardFormatAvailable(CF_TEXT)) {
if (IsClipboardFormatAvailable(CF_UNICODETEXT)) {
if (OpenClipboard(win_get_window())) {
EmptyClipboard();
if (!clipboard_text.empty()) {
int len = clipboard_text.size();
std::wstring wstr = base::from_utf8(clipboard_text);
int len = wstr.size();
HGLOBAL hglobal = GlobalAlloc(GMEM_MOVEABLE |
GMEM_ZEROINIT, sizeof(char)*(len+1));
GMEM_ZEROINIT, sizeof(WCHAR)*(len+1));
LPSTR lpstr = static_cast<LPSTR>(GlobalLock(hglobal));
std::copy(clipboard_text.begin(), clipboard_text.end(), lpstr);
LPWSTR lpstr = static_cast<LPWSTR>(GlobalLock(hglobal));
std::copy(wstr.begin(), wstr.end(), lpstr);
GlobalUnlock(hglobal);
SetClipboardData(CF_TEXT, hglobal);
SetClipboardData(CF_UNICODETEXT, hglobal);
}
CloseClipboard();
}

View File

@ -163,7 +163,7 @@ int ComboBox::addItem(ListItem* item)
return m_items.size()-1;
}
int ComboBox::addItem(const char* text)
int ComboBox::addItem(const base::string& text)
{
return addItem(new ListItem(text));
}
@ -178,7 +178,7 @@ void ComboBox::insertItem(int itemIndex, ListItem* item)
setSelectedItemIndex(0);
}
void ComboBox::insertItem(int itemIndex, const char* text)
void ComboBox::insertItem(int itemIndex, const base::string& text)
{
insertItem(itemIndex, new ListItem(text));
}
@ -228,17 +228,20 @@ ListItem* ComboBox::getItem(int itemIndex)
return NULL;
}
const char* ComboBox::getItemText(int itemIndex) const
const base::string& ComboBox::getItemText(int itemIndex) const
{
if (itemIndex >= 0 && (size_t)itemIndex < m_items.size()) {
ListItem* item = m_items[itemIndex];
return item->getText();
}
else
return "";
else {
// Returns the text of the combo-box (it should be empty).
ASSERT(getText().empty());
return getText();
}
}
void ComboBox::setItemText(int itemIndex, const char* text)
void ComboBox::setItemText(int itemIndex, const base::string& text)
{
ASSERT(itemIndex >= 0 && (size_t)itemIndex < m_items.size());
@ -246,7 +249,7 @@ void ComboBox::setItemText(int itemIndex, const char* text)
item->setText(text);
}
int ComboBox::findItemIndex(const char* text)
int ComboBox::findItemIndex(const base::string& text)
{
int itemIndex = 0;
@ -254,8 +257,8 @@ int ComboBox::findItemIndex(const char* text)
for (it = m_items.begin(); it != end; ++it) {
ListItem* item = *it;
if ((m_casesensitive && ustrcmp(item->getText(), text) == 0) ||
(!m_casesensitive && ustricmp(item->getText(), text) == 0)) {
if ((m_casesensitive && item->getText() == text) ||
(!m_casesensitive && item->getText() == text)) {
return itemIndex;
}
@ -358,7 +361,7 @@ void ComboBox::onPreferredSize(PreferredSizeEvent& ev)
for (it = m_items.begin(); it != end; ++it) {
int item_w =
2*jguiscale()+
text_length(this->getFont(), (*it)->getText())+
text_length(getFont(), (*it)->getText().c_str())+
10*jguiscale();
reqSize.w = MAX(reqSize.w, item_w);
@ -471,7 +474,7 @@ void ComboBox::onButtonClick(Event& ev)
void ComboBox::openListBox()
{
if (!m_window) {
m_window = new Window(false, NULL);
m_window = new Window(false, "");
View* view = new View();
m_listbox = new ComboBoxListBox(this);
m_window->setOnTop(true);

View File

@ -46,9 +46,9 @@ namespace ui {
bool isCaseSensitive();
int addItem(ListItem* item);
int addItem(const char* text);
int addItem(const base::string& text);
void insertItem(int itemIndex, ListItem* item);
void insertItem(int itemIndex, const char* text);
void insertItem(int itemIndex, const base::string& text);
// Removes the given item (you must delete it).
void removeItem(ListItem* item);
@ -61,9 +61,9 @@ namespace ui {
int getItemCount() const;
ListItem* getItem(int itemIndex);
const char* getItemText(int itemIndex) const;
void setItemText(int itemIndex, const char* text);
int findItemIndex(const char* text);
const base::string& getItemText(int itemIndex) const;
void setItemText(int itemIndex, const base::string& text);
int findItemIndex(const base::string& text);
ListItem* getSelectedItem() const;
void setSelectedItem(ListItem* item);

View File

@ -12,7 +12,7 @@
namespace ui {
CustomLabel::CustomLabel(const char *text)
CustomLabel::CustomLabel(const base::string& text)
: Label(text)
{
}

View File

@ -15,7 +15,7 @@ namespace ui {
class CustomLabel : public Label
{
public:
CustomLabel(const char *text);
CustomLabel(const base::string& text);
protected:
bool onProcessMessage(Message* msg) OVERRIDE;

View File

@ -10,6 +10,7 @@
#include "ui/entry.h"
#include "base/string.h"
#include "ui/clipboard.h"
#include "ui/font.h"
#include "ui/manager.h"
@ -22,8 +23,8 @@
#include <allegro.h>
#include <allegro/internal/aintern.h>
#include <stdarg.h>
#include <stdio.h>
#include <cstdarg>
#include <cstdio>
#define CHARACTER_LENGTH(f, c) ((f)->vtable->char_length((f), (c)))
@ -44,7 +45,7 @@ Entry::Entry(size_t maxsize, const char *format, ...)
}
// empty string
else {
ustrcpy(buf, empty_string);
buf[0] = 0;
}
m_maxsize = maxsize;
@ -103,22 +104,24 @@ void Entry::hideCaret()
void Entry::setCaretPos(int pos)
{
const char *text = this->getText();
base::utf8_const_iterator utf8_begin = base::utf8_const_iterator(getText().begin());
int textlen = base::utf8_length(getText());
int x, c;
m_caret = pos;
/* backward scroll */
// Backward scroll
if (m_caret < m_scroll)
m_scroll = m_caret;
/* forward scroll */
// Forward scroll
m_scroll--;
do {
x = this->rc->x1 + this->border_width.l;
for (c=++m_scroll; ; c++) {
x += CHARACTER_LENGTH(this->getFont(),
(c < ustrlen(text))? ugetat(text, c): ' ');
int ch = (c < textlen ? *(utf8_begin+c) : ' ');
x += CHARACTER_LENGTH(getFont(), ch);
if (x >= this->rc->x2-this->border_width.r)
break;
@ -133,7 +136,7 @@ void Entry::setCaretPos(int pos)
void Entry::selectText(int from, int to)
{
int end = ustrlen(this->getText());
int end = base::utf8_length(getText());
m_select = from;
setCaretPos(from); // to move scroll
@ -212,48 +215,48 @@ bool Entry::onProcessMessage(Message* msg)
switch (scancode) {
case KEY_LEFT:
case kKeyLeft:
if (msg->ctrlPressed())
cmd = EntryCmd::BackwardWord;
else
cmd = EntryCmd::BackwardChar;
break;
case KEY_RIGHT:
case kKeyRight:
if (msg->ctrlPressed())
cmd = EntryCmd::ForwardWord;
else
cmd = EntryCmd::ForwardChar;
break;
case KEY_HOME:
case kKeyHome:
cmd = EntryCmd::BeginningOfLine;
break;
case KEY_END:
case kKeyEnd:
cmd = EntryCmd::EndOfLine;
break;
case KEY_DEL:
case kKeyDel:
if (msg->shiftPressed())
cmd = EntryCmd::Cut;
else
cmd = EntryCmd::DeleteForward;
break;
case KEY_INSERT:
case kKeyInsert:
if (msg->shiftPressed())
cmd = EntryCmd::Paste;
else if (msg->ctrlPressed())
cmd = EntryCmd::Copy;
break;
case KEY_BACKSPACE:
case kKeyBackspace:
cmd = EntryCmd::DeleteBackward;
break;
default:
if (keymsg->ascii() >= 32) {
if (keymsg->unicodeChar() >= 32) {
// Ctrl and Alt must be unpressed to insert a character
// in the text-field.
if ((msg->keyModifiers() & (kKeyCtrlModifier | kKeyAltModifier)) == 0) {
@ -276,7 +279,7 @@ bool Entry::onProcessMessage(Message* msg)
if (cmd == EntryCmd::NoOp)
break;
executeCmd(cmd, keymsg->ascii(),
executeCmd(cmd, keymsg->unicodeChar(),
(msg->shiftPressed()) ? true: false);
return true;
}
@ -288,7 +291,9 @@ bool Entry::onProcessMessage(Message* msg)
case kMouseMoveMessage:
if (hasCapture()) {
gfx::Point mousePos = static_cast<MouseMessage*>(msg)->position();
const char *text = this->getText();
base::utf8_const_iterator utf8_begin = base::utf8_const_iterator(getText().begin());
base::utf8_const_iterator utf8_end = base::utf8_const_iterator(getText().end());
int textlen = base::utf8_length(getText());
int c, x;
bool move = true;
@ -305,18 +310,17 @@ bool Entry::onProcessMessage(Message* msg)
}
// Forward scroll
else if (mousePos.x >= this->rc->x2) {
if (m_scroll < ustrlen(text)) {
if (m_scroll < textlen) {
m_scroll++;
x = this->rc->x1 + this->border_width.l;
for (c=m_scroll; ; c++) {
x += CHARACTER_LENGTH(this->getFont(),
(c < ustrlen(text))? ugetat(text, c): ' ');
for (c=m_scroll; utf8_begin != utf8_end; ++c) {
int ch = (c < textlen ? *(utf8_begin+c) : ' ');
x += CHARACTER_LENGTH(getFont(), ch);
if (x > this->rc->x2-this->border_width.r) {
c--;
break;
}
else if (!ugetat (text, c))
break;
}
m_caret = c;
move = false;
@ -414,6 +418,8 @@ void Entry::onEntryChange()
int Entry::getCaretFromMouse(MouseMessage* mousemsg)
{
base::utf8_const_iterator utf8_begin = base::utf8_const_iterator(getText().begin());
base::utf8_const_iterator utf8_end = base::utf8_const_iterator(getText().end());
int c, x, w, mx, caret = m_caret;
mx = mousemsg->position().x;
@ -422,8 +428,10 @@ int Entry::getCaretFromMouse(MouseMessage* mousemsg)
this->rc->x2-this->border_width.r-1);
x = this->rc->x1 + this->border_width.l;
for (c=m_scroll; ugetat(this->getText(), c); c++) {
w = CHARACTER_LENGTH(this->getFont(), ugetat(this->getText(), c));
base::utf8_const_iterator utf8_it = utf8_begin + m_scroll;
for (c=m_scroll; utf8_it != utf8_end; ++c, ++utf8_it) {
w = CHARACTER_LENGTH(getFont(), *utf8_it);
if (x+w >= this->rc->x2-this->border_width.r)
break;
if ((mx >= x) && (mx < x+w)) {
@ -433,17 +441,19 @@ int Entry::getCaretFromMouse(MouseMessage* mousemsg)
x += w;
}
if (!ugetat(this->getText(), c))
if (utf8_it == utf8_end) {
if ((mx >= x) &&
(mx <= this->rc->x2-this->border_width.r-1))
(mx <= this->rc->x2-this->border_width.r-1)) {
caret = c;
}
}
return caret;
}
void Entry::executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed)
void Entry::executeCmd(EntryCmd::Type cmd, int unicodeChar, bool shift_pressed)
{
std::string text = getText();
std::wstring text = base::from_utf8(getText());
int c, selbeg, selend;
getEntryThemeInfo(NULL, NULL, NULL, &selbeg, &selend);
@ -464,7 +474,7 @@ void Entry::executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed)
// put the character
if (text.size() < m_maxsize) {
ASSERT((size_t)m_caret <= text.size());
text.insert(m_caret++, 1, ascii);
text.insert(m_caret++, 1, unicodeChar);
}
m_select = -1;
@ -540,8 +550,8 @@ void Entry::executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed)
if (selbeg >= 0) {
// *cut* text!
if (cmd == EntryCmd::Cut) {
base::string buf = text.substr(selbeg, selend - selbeg + 1);
clipboard::set_text(buf.c_str());
std::wstring selected = text.substr(selbeg, selend - selbeg + 1);
clipboard::set_text(base::to_utf8(selected).c_str());
}
// remove text
@ -559,9 +569,11 @@ void Entry::executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed)
break;
case EntryCmd::Paste: {
const char *clipboard;
const char* clipboard_str;
if ((clipboard_str = clipboard::get_text())) {
base::string clipboard(clipboard_str);
if ((clipboard = clipboard::get_text())) {
// delete the entire selection
if (selbeg >= 0) {
text.erase(selbeg, selend-selbeg+1);
@ -571,11 +583,13 @@ void Entry::executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed)
}
// paste text
for (c=0; c<ustrlen(clipboard); c++)
for (c=0; c<base::utf8_length(clipboard); c++) {
if (text.size() < m_maxsize)
text.insert(m_caret+c, 1, ugetat(clipboard, c));
text.insert(m_caret+c, 1,
*(base::utf8_const_iterator(clipboard.begin())+c));
else
break;
}
setCaretPos(m_caret+c);
}
@ -584,8 +598,8 @@ void Entry::executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed)
case EntryCmd::Copy:
if (selbeg >= 0) {
base::string buf = text.substr(selbeg, selend - selbeg + 1);
clipboard::set_text(buf.c_str());
std::wstring selected = text.substr(selbeg, selend - selbeg + 1);
clipboard::set_text(base::to_utf8(selected).c_str());
}
break;
@ -606,8 +620,9 @@ void Entry::executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed)
break;
}
if (text != this->getText()) {
this->setText(text.c_str());
base::string newText = base::to_utf8(text);
if (newText != getText()) {
setText(newText.c_str());
onEntryChange();
}
@ -621,18 +636,20 @@ void Entry::executeCmd(EntryCmd::Type cmd, int ascii, bool shift_pressed)
void Entry::forwardWord()
{
base::utf8_const_iterator utf8_begin = base::utf8_const_iterator(getText().begin());
int textlen = base::utf8_length(getText());
int ch;
for (; m_caret<ustrlen(this->getText()); m_caret++) {
ch = ugetat(this->getText(), m_caret);
if (IS_WORD_CHAR (ch))
for (; m_caret < textlen; m_caret++) {
ch = *(utf8_begin + m_caret);
if (IS_WORD_CHAR(ch))
break;
}
for (; m_caret<ustrlen(this->getText()); m_caret++) {
ch = ugetat(this->getText(), m_caret);
for (; m_caret < textlen; m_caret++) {
ch = *(utf8_begin + m_caret);
if (!IS_WORD_CHAR(ch)) {
m_caret++;
++m_caret;
break;
}
}
@ -640,18 +657,19 @@ void Entry::forwardWord()
void Entry::backwardWord()
{
base::utf8_const_iterator utf8_begin = base::utf8_const_iterator(getText().begin());
int ch;
for (m_caret--; m_caret >= 0; m_caret--) {
ch = ugetat(this->getText(), m_caret);
for (--m_caret; m_caret >= 0; --m_caret) {
ch = *(utf8_begin + m_caret);
if (IS_WORD_CHAR(ch))
break;
}
for (; m_caret >= 0; m_caret--) {
ch = ugetat(this->getText(), m_caret);
for (; m_caret >= 0; --m_caret) {
ch = *(utf8_begin + m_caret);
if (!IS_WORD_CHAR(ch)) {
m_caret++;
++m_caret;
break;
}
}

View File

@ -105,7 +105,7 @@ void IntEntry::openPopup()
if (rc.x+rc.w > JI_SCREEN_W)
rc.x = rc.x - rc.w + getBounds().w;
m_popupWindow = new PopupWindow(NULL, false);
m_popupWindow = new PopupWindow("", false);
m_popupWindow->setAutoRemap(false);
m_popupWindow->setBounds(rc);
m_popupWindow->setBgColor(rgba(0, 0, 0, 0));

View File

@ -12,7 +12,7 @@
#include <allegro.h>
int ui::scancode_to_ascii(KeyScancode scancode)
int ui::scancode_to_unicode(KeyScancode scancode)
{
return ::scancode_to_ascii(scancode);
}

View File

@ -151,7 +151,7 @@ namespace ui {
kKeyScancodes = 127
};
int scancode_to_ascii(KeyScancode scancode);
int scancode_to_unicode(KeyScancode scancode);
} // namespace ui

View File

@ -15,7 +15,7 @@
namespace ui {
Label::Label(const char *text)
Label::Label(const base::string& text)
: Widget(kLabelWidget)
{
setAlign(JI_LEFT | JI_MIDDLE);
@ -37,7 +37,7 @@ void Label::onPreferredSize(PreferredSizeEvent& ev)
{
gfx::Size sz(0, 0);
if (this->hasText()) {
if (hasText()) {
sz.w = jwidget_get_text_length(this);
sz.h = jwidget_get_text_height(this);
}

View File

@ -16,7 +16,7 @@ namespace ui {
class Label : public Widget
{
public:
Label(const char *text);
Label(const base::string& text);
Color getTextColor() const;
void setTextColor(Color color);

View File

@ -18,19 +18,19 @@
namespace ui {
LinkLabel::LinkLabel(const char* urlOrText)
LinkLabel::LinkLabel(const base::string& urlOrText)
: CustomLabel(urlOrText)
, m_url(urlOrText)
{
}
LinkLabel::LinkLabel(const char* url, const char* text)
LinkLabel::LinkLabel(const base::string& url, const base::string& text)
: CustomLabel(text)
, m_url(url)
{
}
void LinkLabel::setUrl(const char* url)
void LinkLabel::setUrl(const base::string& url)
{
m_url = url;
}

View File

@ -18,11 +18,11 @@ namespace ui {
class LinkLabel : public CustomLabel
{
public:
LinkLabel(const char* urlOrText);
LinkLabel(const char* url, const char* text);
LinkLabel(const base::string& urlOrText);
LinkLabel(const base::string& url, const base::string& text);
const char* getUrl() const { return m_url.c_str(); }
void setUrl(const char* url);
const base::string& getUrl() const { return m_url; }
void setUrl(const base::string& url);
Signal0<void> Click;
@ -30,7 +30,7 @@ namespace ui {
bool onProcessMessage(Message* msg) OVERRIDE;
void onPaint(PaintEvent& ev) OVERRIDE;
std::string m_url;
base::string m_url;
};
} // namespace ui

Some files were not shown because too many files have changed in this diff Show More