Exemple #1
0
static void build_paths(MCStringRef &r_path)
{
	MCAutoStringRef t_path;
	/* UNCHECKED */ MCStringCreateMutable(0, &t_path);
	MCAutoStringRef t_std_path;
	MCAutoStringRef t_native_path;
	/* UNCHECKED */ MCStringCreateWithChars(s_chosen_folder.Ptr(), s_chosen_folder.Size()-1, &t_native_path);
	/* UNCHECKED */ MCS_pathfromnative(*t_native_path, &t_std_path);

	if (MCStringGetCharAtIndex(*t_std_path, 0) == '"')
	{
		// Does this ever actually receive a quoted path?
		/*Meta::itemised_string t_items(sg_chosen_files, ' ', true);
		for(unsigned int t_index = 0; t_index < t_items . count(); ++t_index)
		{
			if (t_index != 0)
				/* UNCHECKED * / MCStringAppendChar(*t_path, '\n');

			build_path(*t_std_path, t_items[t_index], *t_path);
		}*/
		MCAutoStringRef t_item;
		/* UNCHECKED */ MCStringCreateWithChars(s_chosen_files.Ptr(), s_chosen_files.Size()-1, &t_item);
		build_path(*t_std_path, *t_item, *t_path);
	}
	else
	{
		MCAutoStringRef t_files;
		/* UNCHECKED */ MCStringCreateWithChars(s_chosen_files.Ptr(), s_chosen_files.Size()-1, &t_files);
		build_path(*t_std_path, *t_files, *t_path);
	}

	s_chosen_files.Delete();
	s_chosen_folder.Delete();

	MCStringCopy(*t_path, r_path);
}
Exemple #2
0
static MCStringRef windows_query_locale(uint4 t_index)
{
	// Allocate a buffer for the locale information
	int t_buf_size;
	t_buf_size = GetLocaleInfoW(LOCALE_USER_DEFAULT, t_index, NULL, 0);
	wchar_t* t_buffer = new wchar_t[t_buf_size];
	
	// Get the locale information and create a StringRef from it
	if (GetLocaleInfoW(LOCALE_USER_DEFAULT, t_index, t_buffer, t_buf_size) == 0)
		return MCValueRetain(kMCEmptyString);
	MCStringRef t_string;
	MCStringCreateWithChars(t_buffer, MCU_max(0, t_buf_size - 1), t_string);
	delete[] t_buffer;
	
	return t_string;
}
Exemple #3
0
static HRESULT append_shellitem_path_and_release(IShellItem *p_item, bool p_first, MCStringRef &x_string)
{
	HRESULT t_hresult;
	t_hresult = S_OK;

	bool t_succeeded;
	t_succeeded = true;

	WCHAR *t_filename;
	t_filename = NULL;
	if (t_succeeded)
	{
		t_hresult = p_item -> GetDisplayName(SIGDN_FILESYSPATH, &t_filename);
		t_succeeded = SUCCEEDED(t_hresult);
	}
	
	if (t_succeeded)
	{
		if (x_string == nil)
			MCStringCreateMutable(0, x_string);
		else if (!MCStringIsMutable(x_string))
		{
			MCStringRef t_clone;
			MCStringMutableCopy(x_string, t_clone);
			MCValueAssign(x_string, t_clone);
		}

		MCAutoStringRef t_rev_filename;
		MCAutoStringRef t_native_filename;
		
		/* UNCHECKED */ MCStringCreateWithChars(t_filename, lstrlenW(t_filename), &t_native_filename);
		/* UNCHECKED */ MCS_pathfromnative(*t_native_filename, &t_rev_filename);
		/* UNCHECKED */ MCStringAppendFormat(x_string, p_first ? "%@" : "\n%@", *t_rev_filename);
	}

	if (t_filename != NULL)
		CoTaskMemFree(t_filename);

	if (p_item != NULL)
		p_item -> Release();

	return t_hresult;
}
Exemple #4
0
// MW-2014-06-25: [[ Bug 12370 ]] Map an input keyCode and mapped codepoint to
//   engine keysym and char. The engine expects keyCode to be the mapped key
//   if an ascii character and the raw keycode if not.
static void map_key_to_engine(MCPlatformKeyCode p_key_code, codepoint_t p_mapped_codepoint, codepoint_t p_unmapped_codepoint, MCPlatformKeyCode& r_key_code, MCStringRef &r_native_char)
{
    if (p_mapped_codepoint <= 0xffff)
	{
        uint16_t t_unicode_char;
        char_t t_native_char;

        // MW-2014-08-05: [[ Bug 13042 ]] This was a mis-merge from an updated fix to bug 12747
        //   (the code previously was using unmapped codepoint).
        t_unicode_char = p_mapped_codepoint & 0xffff;
		
		if (MCUnicodeMapToNative(&t_unicode_char, 1, t_native_char))
		{
            /* UNCHECKED */ MCStringCreateWithNativeChars(&t_native_char, 1, r_native_char);
            
            // MW-2014-06-25: [[ Bug 12370 ]] The engine expects keyCode to be the mapped key whenever
            //   the mapped key is ASCII. If the mapped key is not ASCII then the keyCode reflects
            //   the raw (US English) keycode.
            // SN-2014-12-08: [[ Bug 14067 ]] Avoid to use the native char instead of the key code
            // the numeric keypad keys.
            if (isascii(t_native_char) && (p_key_code < kMCPlatformKeyCodeKeypadSpace || p_key_code > kMCPlatformKeyCodeKeypadEqual))
                r_key_code = t_native_char;
            else
                r_key_code = p_key_code;
            
            return;
        }
        // SN-2014-12-05: [[ Bug 14162 ]] We can have unicode chars being typed.
        // We keep the given keycode (the codepoint) as the key code in these conditions.
        else
        {
            /* UNCHECKED */ MCStringCreateWithChars(&t_unicode_char, 1, r_native_char);
            r_key_code = p_key_code;
            
            return;
        }
    }
    
    r_native_char = MCValueRetain(kMCEmptyString);
    r_key_code = p_key_code;
}
Exemple #5
0
// MW-2005-05-15: Updated for new answer command restructuring
int MCA_folder(MCStringRef p_title, MCStringRef p_prompt, MCStringRef p_initial, unsigned int p_options, MCStringRef &r_value, MCStringRef &r_result)
{
	if (MCmajorosversion >= 0x0600 && MCModeMakeLocalWindows())
		return MCA_file(p_title, p_prompt, nil, p_initial, p_options | MCA_OPTION_FOLDER_DIALOG, r_value, r_result);

// MW-2005-05-27: We'll use a static (I know bad me) to store the version
//   of the shell dll.
	static int s_shell_version = -1;
	static MCStringRef s_last_folder = MCValueRetain(kMCEmptyString);

	MCAutoStringRef t_native_filename;

	if (p_initial != NULL)
	{
		MCAutoStringRef t_std_path;

		/* UNCHECKED */ MCS_pathfromnative(p_initial, &t_std_path);
		t_native_filename = *t_std_path;
	}
	else
		t_native_filename = MCValueRetain(s_last_folder);

	if (!MCModeMakeLocalWindows())
    {
		MCAutoStringRef t_answer_path;
		MCRemoteFolderDialog(p_title, p_prompt, *t_native_filename, &t_answer_path);
        if (*t_answer_path != nil)
		{
			MCAutoStringRef t_std_path;

			/* UNCHECKED */ MCS_pathfromnative(*t_answer_path, &t_std_path);
			MCValueAssign(s_last_folder, *t_std_path);
		}
		r_value = MCValueRetain(*t_answer_path);
		return 0;
	}

	if (s_shell_version == -1)
		s_shell_version = get_dll_version(L"shell32.dll");

	bool sheet = (p_options & MCA_OPTION_SHEET) != 0;

	BROWSEINFOW bi;
	memset(&bi, 0, sizeof(BROWSEINFOW));

	Window pw;
	pw = MCModeGetParentWindow();

	if (pw != DNULL)
		bi.hwndOwner = (HWND)pw->handle.window;

	MCAutoStringRefAsWString t_prompt_wstr;
	MCAutoStringRefAsWString t_native_filename_wstr;
	/* UNCHECKED */ t_prompt_wstr.Lock(p_prompt);

	bi.pidlRoot = NULL;
	bi.lpszTitle = *t_prompt_wstr;
	bi.ulFlags = BIF_RETURNONLYFSDIRS;
	if (s_shell_version >= 500)
		bi.ulFlags |= BIF_NEWDIALOGSTYLE;
	if (*t_native_filename != nil && !MCStringIsEmpty(*t_native_filename))
	{
		t_native_filename_wstr.Lock(*t_native_filename);
		
		bi . lpfn = BrowseCallbackProc;
		bi . lParam = (LPARAM)*t_native_filename_wstr;
	}
	else
	{
		bi.lpfn = NULL;
		bi.lParam = NULL;
	}
	LPITEMIDLIST lpiil;
	LPMALLOC lpm;
	SHGetMalloc(&lpm);

	DWORD t_error;
	lpiil = SHBrowseForFolderW(&bi);
	if (lpiil == NULL)
	{
		t_error = GetLastError();
	}
	
	MCAutoArray<unichar_t> t_buffer;
	/* UNCHECKED */ t_buffer.New(MAX_PATH);

	if (lpiil != NULL && SHGetPathFromIDListW(lpiil, t_buffer.Ptr()))
	{
		if (s_last_folder != NULL)
			MCValueRelease(s_last_folder);

		size_t t_length;
		/* UNCHECKED */ StringCchLength(t_buffer.Ptr(), t_buffer.Size(), &t_length);
		/* UNCHECKED */ MCStringCreateWithChars(t_buffer.Ptr(), t_length, s_last_folder);

		MCAutoStringRef t_std_path;
		/* UNCHECKED */ MCS_pathfromnative(s_last_folder, &t_std_path);

		r_value = MCValueRetain(*t_std_path);
	}
	else
		r_result = MCSTR(MCcancelstring);

	//  SMR 1880 clear shift and button state
	waitonbutton();

	lpm->Free(lpiil);
	lpm->Release();

	return 0;
}
Exemple #6
0
void MCPlatformHandleTextInputInsertText(MCPlatformWindowRef p_window, unichar_t *p_chars, uindex_t p_char_count, MCRange p_replace_range, MCRange p_selection_range, bool p_mark)
{
	if (!MCactivefield)
		return;
	
    // SN-2014-12-04: [[ Bug 14152 ]] Locking the screen here doesn't allow the screen to refresh after
    //  text input, inside an MCWait loop
//	MCRedrawLockScreen();
	
	int32_t t_r_si, t_r_ei;
	t_r_si = 0;
	t_r_ei = INT32_MAX;
	MCactivefield -> resolvechars(0, t_r_si, t_r_ei, p_replace_range . offset, p_replace_range . length);
	
    // SN-2014-09-15: [[ Bug 13423 ]] t_was_compositing now used further in the function
    bool t_was_compositing;
    t_was_compositing = false;
	if (!p_mark)
	{
        // MW-2014-08-05: [[ Bug 13098 ]] If we have been compositing, then don't synthesise a
        //   keyDown / keyUp.
		int4 si, ei;
		if (MCactivefield -> getcompositionrange(si, ei))
		{
			if (si < t_r_si)
				t_r_si -= MCMin(t_r_si - si, ei - si);
			if (si < t_r_ei)
				t_r_ei -= MCMin(t_r_ei - si, ei - si);
			
			MCactivefield -> stopcomposition(True, False);
            
            t_was_compositing = true;
		}
        else
            t_was_compositing = false;
		
		// If the char count is 1 and the replacement range matches the current selection,
		// the char is native and the requested selection is after the char, then synthesis a
		// keydown/up pair.        
        // MW-2014-06-25: [[ Bug 12370 ]] If the char is ascii then map appropriately so we get
        //   the keycodes the engine expects.
		char_t t_char;

		if (!t_was_compositing &&
            p_char_count == 1 &&
			MCUnicodeMapToNative(p_chars, 1, t_char) &&
			p_selection_range . offset == p_replace_range . offset + 1 &&
			p_selection_range . length == 0)
		{
			int32_t t_s_si, t_s_ei;
			MCactivefield -> selectedmark(False, t_s_si, t_s_ei, False);
			if (t_s_si == t_r_si &&
				t_s_ei == t_r_ei)
			{

                // SN-2014-09-15: [[ Bug 13423 ]] Send the messages for all the characters typed
                while (s_pending_key_down != nil)
                {
                    // MW-2014-04-15: [[ Bug 12086 ]] Pass the keycode from the last event that was
                    //   passed to the IME.
                    MCAutoStringRef t_mapped_char;
                    MCPlatformKeyCode t_mapped_key_code;

                    map_key_to_engine(s_pending_key_down -> key_code, s_pending_key_down -> mapped_codepoint, s_pending_key_down -> unmapped_codepoint, t_mapped_key_code, &t_mapped_char);
                    
                    // SN-2014-11-03: [[ Bug 13832 ]] Enqueue the event, instead of firing it now (we are still in the NSApplication's keyDown).
                    // PM-2015-05-15: [[ Bug 15372]] call MCKeyMessageAppend before wkdown to prevent a crash if 'wait with messages' is used (since s_pending_key_down might become nil after wkdown
                    MCKeyMessageAppend(s_pending_key_up, s_pending_key_down -> key_code, s_pending_key_down -> mapped_codepoint, s_pending_key_down -> unmapped_codepoint);
                    
                    MCdispatcher -> wkdown(p_window, *t_mapped_char, t_mapped_key_code);
                    
                    MCKeyMessageNext(s_pending_key_down);
                
                }
				return;
			}
		}
	}
	else
	{
		if (p_char_count == 0)
			MCactivefield -> stopcomposition(True, False);
		else
		{
			int4 si, ei;
			if (MCactivefield -> getcompositionrange(si, ei))
			{
				if (si < t_r_si)
					t_r_si -= MCMin(t_r_si - si, ei - si);
				if (si < t_r_ei)
					t_r_ei -= MCMin(t_r_ei - si, ei - si);
				
				MCactivefield -> stopcomposition(True, False);
			}
		}
	}
	
    // SN-2014-09-14: [[ Bug 13423 ]] MCPlatformHandleRawKeyDown gets the US mac layout key, without any modifier included.
    // We need to update the elements:
    // if the key pressed leads to an actual char:
    //    this wrong key is replaced by this new 'combined' char
    // if the key pressed fails to generate a char:
    //    this wrong key is replaced by the dead-key char
    // SN-2015-04-10: [[ Bug 14205 ]] When using the dictation, there is no
    //  pending key down, but the composition was still on though.
    // SN-2015-06-23: [[ Bug 3537 ]] We should not cast p_char as a uint1 if it
    //  is not a native char.
    uint1 t_char[2];
    bool t_is_native_char;
    t_is_native_char = MCUnicodeMapToNative(p_chars, 1, t_char[0]);
    t_char[1] = 0;
    
    if (t_was_compositing && s_pending_key_down && t_is_native_char)
    {
        s_pending_key_down -> key_code = (uint1)*t_char;
        s_pending_key_down -> mapped_codepoint = (uint1)*t_char;
        s_pending_key_down -> unmapped_codepoint = (uint1)*t_char;
        
        // SN-2015-05-18: [[ Bug 15385 ]] Enqueue the first char in the sequence
        //  here - that will be the same as keyDown.
        // SN-2015-06-23: [[ Bug 3537 ]] In this only case, we don't want this
        //  nativised char to be mapped again in MCPlatformHandleKeyUp.
        MCKeyMessageAppend(s_pending_key_up, (uint1)*t_char, (uint1)*t_char, (uint1)*t_char, false);
    }
    
	// Set the text.	
	MCactivefield -> seltext(t_r_si, t_r_ei, False);
	
	if (p_mark)
		MCactivefield -> startcomposition();
    
    // SN-2014-09-15: [[ Bug 13423 ]] If the character typed is not Unicode and follows a dead key character, then we send
    // [Raw]KeyDown/Up and remove the first character from the sequence of keys typed.
    // If the character successfully combined with the dead char before it in a native char, we don't use finsert
    // Otherwise, we have the dead char in p_chars, we need to remove the one stored first in the sequence
    MCAutoStringRef t_string;
    
    // SN-2015-01-20: [[ Bug 14406 ]] If we have a series of pending keys, we have two possibilities:
    //   - typing IME characters: the characters are native, so we use the finsertnew
    //   - typing dead characters: the character, if we arrive here, is > 127
    // SN-2015-04-13: [[ Bug 14205 ]] Ensure that s_pending_key_down is not nil
    if (*p_chars > 127 && s_pending_key_down && s_pending_key_down -> next
            && t_is_native_char)
    {
        MCStringCreateWithNativeChars((const char_t *)t_char, 1, &t_string);
        MCdispatcher -> wkdown(p_window, *t_string, *t_char);
        
        MCKeyMessageNext(s_pending_key_down);
    }
    else
    {
        MCStringCreateWithChars(p_chars, p_char_count, &t_string);
        
        // SN-2014-12-05: [[ Bug 14162 ]] In case the character is a Unicode alphanumeric char,
        // then that's not a combining char - and it deserves its (raw)Key(Down|Up) messages
        uint32_t t_codepoint;
        t_codepoint = MCStringGetCodepointAtIndex(*t_string, 0);
        
        // SN-2015-05-18: [[ Bug 3537 ]] Use p_mark to determine whether we are
        //  in an IME state
        // SN-2015-05-05: [[ Bug 15305 ]] Check that s_pending_key_down is not
        //  nil before trying to use it, and use IME only if p_mark says so.
        if (s_pending_key_down && !p_mark)
        {
            MCAutoStringRef t_mapped_char;
            MCPlatformKeyCode t_mapped_key_code;

            map_key_to_engine(s_pending_key_down -> key_code, s_pending_key_down -> mapped_codepoint, s_pending_key_down -> unmapped_codepoint, t_mapped_key_code, &t_mapped_char);

            MCdispatcher -> wkdown(p_window, *t_string, *p_chars);

            // SN-2015-05-18: [[ Bug 3537 ]] If we were compositing, then we want
            //  to send the same message for keyUp and keyDown - which might be
            //  seeveral character-long
            if (t_was_compositing)
                MCdispatcher -> wkup(p_window, *t_string, *p_chars);
            else
                MCKeyMessageAppend(s_pending_key_up, *p_chars, s_pending_key_down -> mapped_codepoint, s_pending_key_down -> unmapped_codepoint);
            
            MCKeyMessageNext(s_pending_key_down);
        }
        else
            MCactivefield -> finsertnew(FT_IMEINSERT, *t_string, True);
    }
	
	// And update the selection range.
	int32_t t_s_si, t_s_ei;
	t_s_si = 0;
	t_s_ei = INT32_MAX;
	MCactivefield -> resolvechars(0, t_s_si, t_s_ei, p_selection_range . offset, p_selection_range . length);
	MCactivefield -> setcompositioncursoroffset(t_s_si - t_r_si);
	MCactivefield -> seltext(t_s_si, t_s_ei, True);
	
    // SN-2014-12-04: [[ Bug 14152 ]] Locking the screen here doesn't allow the screen to refresh after
    //  text input, inside an MCWait loop
//	MCRedrawUnlockScreen();
}