Esempio n. 1
0
static void get_new_filter(MCStringRef *p_types, uint4 p_type_count, MCStringRef &r_filters)
{
	MCAutoStringRef t_filters;
	/* UNCHECKED */ MCStringCreateMutable(0, &t_filters);

	for(uint4 t_type_index = 0; t_type_index < p_type_count; ++t_type_index)
	{
		MCAutoStringRefArray t_split;
		/* UNCHECKED */ MCStringsSplit(p_types[t_type_index], '|', t_split.PtrRef(), t_split.CountRef());

		if (t_split.Count() < 1 || 
			(t_split.Count() == 1 && MCStringIsEmpty(t_split[0])))
			continue;

		if (t_type_index != 0)
			/* UNCHECKED */ MCStringAppendChar(*t_filters, '\0');

		/* UNCHECKED */ MCStringAppend(*t_filters, t_split[0]);

		if (t_split.Count() < 2)
			/* UNCHECKED */ MCStringAppendChars(*t_filters, L"\0*.*", 4);
		else
		{
			MCAutoStringRefArray t_extensions;
			/* UNCHECKED */ MCStringsSplit(t_split[1], ',', t_extensions.PtrRef(), t_extensions.CountRef());
			// SN-2014-07-28: [[ Bug 12972 ]] Filters "Tag|" should be understood as "Tag"
			//  and allow all the file types
			if (t_extensions.Count() == 0 || 
					(t_extensions.Count() == 1 && MCStringIsEmpty(t_extensions[0])))
				/* UNCHECKED */ MCStringAppendChars(*t_filters, L"\0*.*", 4);
			else
			{
				for (unsigned int i = 0; i < t_extensions.Count(); ++i)
				{
					if (i != 0)
						/* UNCHECKED*/ MCStringAppendChar(*t_filters, ';');
					else
						/* UNCHECKED*/ MCStringAppendChar(*t_filters, '\0');

					/* UNCHECKED */ MCStringAppendFormat(*t_filters, "*.%@", t_extensions[i]);
				}
			}
		}
	}

	if (MCStringIsEmpty(*t_filters))
		/* UNCHECKED */ MCStringCreateWithNativeChars((char_t*)"All Files\0*.*\0\0", 15, r_filters);
	else
	{
		/* UNCHECKED */ MCStringAppendChar(*t_filters, '\0');
		MCStringCopy(*t_filters, r_filters);
	}
}
void MCScrollbar::SetEndValue(MCExecContext& ctxt, MCStringRef p_value)
{
	// MW-2013-08-27: [[ UnicodifyScrollbar ]] Update to use MCStringRef startstring.
	if (MCStringIsEmpty(p_value))
	{
		reset();
		return;
	}
	
	if (!MCU_stor8(p_value, endvalue))
	{
		ctxt . LegacyThrow(EE_OBJECT_NAN);
		return;
	}
	
	if (startvalue == 0.0 && endvalue == 65535.0)
		reset();
	else
	{
		flags |= F_HAS_VALUES;
		MCValueAssign(endstring, p_value);
	}
	update(thumbpos, MCM_scrollbar_drag);
	Redraw();
}
Esempio n. 3
0
static void getfilter(MCStringRef p_filter, MCStringRef &r_filter)
{
	if (p_filter != nil && !MCStringIsEmpty(p_filter))
	{
		static MCAutoStringRef t_filterstring;

		if (*t_filterstring != nil)
			MCValueRelease(*t_filterstring);

		/* UNCHECKED */ MCStringMutableCopy(p_filter, &t_filterstring);
		
		uindex_t t_offset;

		if (!MCStringFirstIndexOfChar(*t_filterstring, '\n', 0, kMCStringOptionCompareExact, t_offset) &&
				!MCStringFirstIndexOfChar(*t_filterstring, ',', 0, kMCStringOptionCompareExact, t_offset))
		{
			MCStringAppendChar(*t_filterstring, '\0');
			MCStringAppend(*t_filterstring, p_filter);
		}

		/* UNCHECKED */ MCStringAppendChar(*t_filterstring, '\0');
		/* UNCHECKED */ MCStringFindAndReplaceChar(*t_filterstring, '\n', '\0', kMCStringOptionCompareExact);
		/* UNCHECKED */ MCStringFindAndReplaceChar(*t_filterstring, ',', '\0', kMCStringOptionCompareExact);

		MCStringCopy(*t_filterstring, r_filter);
	}
	else
		/* UNCHECKED */ MCStringCreateWithNativeChars((const char_t *)"All Files (*.*)\0*.*\0", 20, r_filter);
}
Esempio n. 4
0
// MW-2008-03-18: [[ Bug 3300 ]] Make sure that if a file has a full path we dont' prepend
//   the selected folder.
// MW-2008-03-18: [[ Bug 6116 ]] Make sure that we don't add an extra slash if there's already
//   one at the end of the folder path.
static void build_path(MCStringRef p_folder, MCStringRef p_file, MCStringRef x_path)
{
	MCAutoStringRef t_path, t_engine_path;
	MCStringCreateMutable(0, &t_path);

	MCS_pathfromnative(p_file, &t_engine_path);

	// Check for absolute paths
	bool t_use_folder;
	if (MCStringIsEmpty(p_folder)
		|| (MCStringGetLength(*t_engine_path) > 1 && MCStringGetCharAtIndex(*t_engine_path, 1) == ':')
		|| (MCStringGetLength(*t_engine_path) > 2 && MCStringGetCharAtIndex(*t_engine_path, 0) == '/' && MCStringGetCharAtIndex(*t_engine_path, 1) == '/'))
	{
		t_use_folder = false;
	}
	else
	{
		t_use_folder = true;
	}

	if (t_use_folder)
	{
		// Add the folder and a separator, if required
		MCStringAppend(*t_path, p_folder);
		if (MCStringGetCharAtIndex(p_folder, MCStringGetLength(p_folder) - 1) != '/')
			MCStringAppendChar(*t_path, '/');
	}

	MCStringAppend(*t_path, *t_engine_path);

	if (*t_path != nil)
		MCStringAppend(x_path, *t_path);
}
void MCButton::SetLabel(MCExecContext& ctxt, MCStringRef p_label)
{
	// Make sure the label is up to date
	if (entry != NULL)
		getentrytext();
	
	// Don't make any changes if it isn't necessary
	if (MCStringIsEqualTo(p_label, label, kMCStringOptionCompareExact))
		return;
	
	MCValueAssign(label, p_label);
    // SN-2014-08-05: [[ Bug 13100 ]] An empty label is not an issue,
    //  we need to rely on the F_LABEL flag
    // AL-2014-09-10: [[ Bug 13401 ]] If label is empty, the flag should reflect the lack of label
    if (MCStringIsEmpty(label))
        flags &= ~F_LABEL;
    else
        flags |= F_LABEL;

	if (entry != NULL)
		entry->settext(0, label, False);
	
	clearmnemonic();
	setupmnemonic();
	Redraw();
}
Esempio n. 6
0
static void MCFontMeasureTextCallback(MCFontRef p_font, MCStringRef p_string, MCRange p_range, font_measure_text_context *ctxt)
{
    if (MCStringIsEmpty(p_string) || p_range.length == 0)
        return;
	
    MCGFont t_font;
	t_font = MCFontStructToMCGFont(p_font->fontstruct);
	
	// MW-2013-12-04: [[ Bug 11535 ]] Pass through the fixed advance.
	t_font . fixed_advance = p_font -> fixed_advance;
	
    ctxt -> m_width += MCGContextMeasurePlatformText(NULL, MCStringGetCharPtr(p_string) + p_range.offset, p_range.length*2, t_font, ctxt -> m_transform);
}
Esempio n. 7
0
bool MCSessionCreateSession(MCSessionIndexRef p_index, MCStringRef p_session_id, MCSession *&r_session)
{
	bool t_success = true;
	
	MCSession *t_session = NULL;

	MCAutoStringRef t_remote_addr_string;
	char *t_remote_addr;
	t_remote_addr = NULL;

	if (MCS_getenv(MCSTR("REMOTE_ADDR"), &t_remote_addr_string))
		MCCStringClone(MCStringGetCString(*t_remote_addr_string), t_remote_addr);
	
	t_success = MCMemoryNew(t_session);
	
	if (t_success)
		t_success = MCCStringClone(t_remote_addr ? t_remote_addr : "", t_session->ip);

	if (t_success)
	{
		if (p_session_id != nil && !MCStringIsEmpty(p_session_id))
		{
			t_session->id = strdup(MCStringGetCString(p_session_id));
			t_success = true;
		}
		else
		{
			MCAutoStringRef t_session_id;
			t_success = MCSessionGenerateID(&t_session_id);
			t_session->id = strdup(MCStringGetCString(*t_session_id));
		}
	}
	
	if (t_success)
		t_success = MCCStringFormat(t_session->filename, "%s_%s", t_remote_addr ? t_remote_addr : "", t_session->id);
	
	if (t_success)
		t_success = MCSessionIndexAddSession(p_index, t_session);
	
	if (t_success)
		r_session = t_session;
	else
	{
		if (t_session != NULL)
			MCSessionCloseSession(t_session, false);
	}
	
	return t_success;
}
Esempio n. 8
0
Boolean MCPlayer::prepare(MCStringRef options)
{
	Boolean ok = False;
    
	if (state & CS_PREPARED || MCStringIsEmpty(filename))
		return True;
	
	if (!opened)
		return False;

	if (ok)
	{
		state |= CS_PREPARED | CS_PAUSED;
        
		nextplayer = MCplayers;
		MCplayers = this;
	}
    
	return ok;
}
void MCButton::GetFormattedWidth(MCExecContext& ctxt, integer_t& r_width)
{
	// MW-2012-02-16: [[ FontRefs ]] As 'formatted' properties require
	//   access to the font, we must be open before we can compute them.
	if (opened)
	{
		// MW-2007-07-05: [[ Bug 2328 ]] - Formatted width of tab buttons incorrect.
		if (getstyleint(flags) == F_MENU && menumode == WM_TOP_LEVEL)
			r_width = (uinteger_t)formattedtabwidth();
		else
		{
			uint2 fwidth;
			
			MCStringRef t_label = getlabeltext();
			if (MCStringIsEmpty(t_label))
				fwidth = 0;
			else 
                fwidth = leftmargin + rightmargin + MCFontMeasureText(m_font, t_label, getstack() -> getdevicetransform());
			
			if (flags & F_SHOW_ICON && icons != NULL)
			{
				reseticon();
				if (icons->curicon != NULL)
				{
					MCRectangle trect = icons->curicon->getrect();
					if (trect.width > fwidth)
						fwidth = trect.width;
				}
			}
			else
				if (getstyleint(flags) == F_CHECK || getstyleint(flags) == F_RADIO)
					fwidth += CHECK_SIZE + leftmargin;
			if (menumode == WM_OPTION)
				fwidth += optionrect.width + (optionrect.width >> 1);
			if (menumode == WM_CASCADE)
				fwidth += rect.height;
			r_width = fwidth;
		}
	}
	else
Esempio n. 10
0
void MCLicenseGetRevLicenseInfo(MCExecContext& ctxt, MCStringRef& r_info)
{
    static const char *s_deploy_targets[] =
    {
        "Windows",
        "Mac OS X",
        "Linux",
        "iOS",
        "Android",
        "Windows Mobile",
        "Linux Mobile",
        "Server",
        "iOS Embedded",
        "Android Embedded",
        "HTML5",
        "FileMaker",
    };
    
    bool t_success;
    
    MCAutoStringRef t_info;
    t_success = MCStringCreateMutable(0, &t_info);
    
    MCStringRef t_license_name;
    t_license_name = MClicenseparameters . license_name;
    if (t_license_name == nil)
        t_license_name = kMCEmptyString;

    MCStringRef t_license_org;
    t_license_org = MClicenseparameters . license_organization;
    if (t_license_org == nil)
        t_license_org = kMCEmptyString;

    MCAutoStringRef t_class;
    if (t_success)
        t_success = MCStringFromLicenseClass(MClicenseparameters . license_class, false, &t_class);
    
    if (t_success)
        t_success = MCStringAppendFormat(*t_info, "%@\n%@\n%@\n%u\n",
                                         t_license_name, t_license_org,
                                         *t_class,
                                         MClicenseparameters . license_multiplicity);
    
    if (MClicenseparameters . deploy_targets != 0)
    {
        bool t_first;
        t_first = true;
        for(uint32_t i = 0; t_success && i < sizeof(s_deploy_targets) / sizeof(s_deploy_targets[0]); i++)
        {
            if ((MClicenseparameters . deploy_targets & (1 << i)) != 0)
            {
                t_success = MCStringAppendFormat(*t_info, t_first ? "%s" : ",%s", s_deploy_targets[i]);
                t_first = false;
            }
        }
    }
    
    // AL-2014-11-04: [[ Bug 13865 ]] Don't add an extra line between deploy targets and addons

    if (t_success && MClicenseparameters . addons != nil)
    {
        MCAutoStringRef t_keys;
        t_success = (MCArrayListKeys(MClicenseparameters . addons, ',', &t_keys) &&
                    MCStringAppendFormat(*t_info, "\n%@", *t_keys));
    }
    
    if (t_success)
        if (MCStringAppendFormat(*t_info, "\n%s", MCStringIsEmpty(MClicenseparameters . license_token) ? "Global" : "Local") &&
                MCStringCopy(*t_info, r_info))
            return;
    
    ctxt . Throw();
}
Esempio n. 11
0
Exec_stat MCF_parsetextatts(Properties which, MCStringRef data,
                            uint4 &flags, MCStringRef &fname, uint2 &height,
                            uint2 &size, uint2 &style)
{
	int2 i1;
	switch (which)
	{
	case P_TEXT_ALIGN:
		flags &= ~F_ALIGNMENT;
		if (MCStringIsEqualToCString(data, MCleftstring, kMCCompareCaseless) || MCStringIsEmpty(data))
			flags |= F_ALIGN_LEFT;
		else
			if (MCStringIsEqualToCString(data, MCcenterstring, kMCCompareCaseless))
				flags |= F_ALIGN_CENTER;
			else
				if (MCStringIsEqualToCString(data, MCrightstring, kMCCompareCaseless))
					flags |= F_ALIGN_RIGHT;
				else
					if (MCStringIsEqualToCString(data, MCjustifystring, kMCCompareCaseless))
						flags |= F_ALIGN_JUSTIFY;
					else
					{
						MCeerror->add(EE_OBJECT_BADALIGN, 0, 0, data);
						return ES_ERROR;
					}
		break;
	case P_TEXT_FONT:
		{// MW-2012-02-17: [[ IntrinsicUnicode ]] Strip any lang tag from the
			//   fontname.
			uindex_t t_offset;
			if (MCStringFirstIndexOfChar(data, ',', 0, kMCCompareExact, t_offset))
				/* UNCHECKED */ MCStringCopySubstring(data, MCRangeMake(t_offset + 1, MCStringGetLength(data) - (t_offset + 1)), fname);
			else
				fname = MCValueRetain(data);
		}
		break;
	case P_TEXT_HEIGHT:
		if (!MCU_stoi2(data, i1))
		{
			MCeerror->add
			(EE_OBJECT_TEXTHEIGHTNAN, 0, 0, data);
			return ES_ERROR;
		}
		height = i1;
		break;
	case P_TEXT_SIZE:
		if (MCStringIsEmpty(data))
			i1 = 0;
		else
			if (!MCU_stoi2(data, i1))
			{
				MCeerror->add
				(EE_OBJECT_TEXTSIZENAN, 0, 0, data);
				return ES_ERROR;
			}
		size = i1;
		break;
	case P_TEXT_STYLE:
		{
			// MW-2012-02-17: [[ SplitTextAttrs ]] If the string is empty, then
			//   return 0 for the style - indicating to unset the property.
            if (MCStringIsEmpty(data))
				style = 0;
			else
            {
                style = FA_DEFAULT_STYLE;
                uindex_t t_start_pos, t_end_pos;
                t_end_pos = 0;
                
                while (t_end_pos < MCStringGetLength(data))
                {
                    t_start_pos = t_end_pos;
                    // skip spaces at the beginning or after a comma (if any)
                    MCU_skip_spaces(data, t_start_pos);
                    
                    uindex_t t_comma;
                    if (!MCStringFirstIndexOfChar(data, ',', t_start_pos, kMCCompareExact, t_comma))
                        t_end_pos = MCStringGetLength(data);
                    else
                        t_end_pos = t_comma;
                    
                    MCAutoStringRef tdata;
                    /* UNCHECKED */ MCStringCopySubstring(data, MCRangeMake(t_start_pos, t_end_pos - t_start_pos), &tdata);
                    t_end_pos++;
                    if (MCF_setweightstring(style, *tdata))
						continue;
					if (MCF_setexpandstring(style, *tdata))
						continue;
					if (MCF_setslantlongstring(style, *tdata))
						continue;
					if (MCStringIsEqualToCString(*tdata, MCplainstring, kMCCompareCaseless))
					{
						style = FA_DEFAULT_STYLE;
						continue;
					}
					if (MCStringIsEqualToCString(*tdata, MCmixedstring, kMCCompareCaseless))
					{
						style = FA_DEFAULT_STYLE;
						continue;
					}
					if (MCStringIsEqualToCString(*tdata, MCboxstring, kMCCompareCaseless))
					{
						style &= ~FA_3D_BOX;
						style |= FA_BOX;
						continue;
                    }
                
					if (MCStringIsEqualToCString(*tdata, MCthreedboxstring, kMCCompareCaseless))
					{
						style &= ~FA_BOX;
						style |= FA_3D_BOX;
						continue;
					}
					if (MCStringIsEqualToCString(*tdata, MCunderlinestring, kMCCompareCaseless))
					{
						style |= FA_UNDERLINE;
						continue;
					}
					if (MCStringIsEqualToCString(*tdata, MCstrikeoutstring, kMCCompareCaseless))
					{
						style |= FA_STRIKEOUT;
						continue;
					}
					if (MCStringIsEqualToCString(*tdata, MCgroupstring, kMCCompareCaseless) || MCStringIsEqualToCString(*tdata, MClinkstring, kMCCompareCaseless))
					{
						style |= FA_LINK;
						continue;
					}
					MCeerror->add(EE_OBJECT_BADSTYLE, 0, 0, data);
					return ES_ERROR;
				}
			}
		}
		break;
	default:
		break;
	}
	return ES_NORMAL;
}
Esempio n. 12
0
void MCPickDoPickDateTime(MCExecContext& ctxt, MCStringRef p_current, MCStringRef p_start, MCStringRef p_end, int32_t *p_step, MCPickButtonType p_buttons, MCRectangle p_button_rect, int p_which)
{
    MCDateTime t_current;
    MCDateTime *t_current_ptr;
    t_current_ptr = nil;
	
	// PM-2015-09-01: [[ Bug 15844 ]] Allow calling mobilePickDate with empty [, current] [, start] [, end] parameters
	// i.e. mobilePickDate "time",,,,10
    if (!MCStringIsEmpty(p_current))
    {
        if (!MCD_convert_to_datetime(ctxt, p_current, CF_UNDEFINED, CF_UNDEFINED, t_current))
            return;
        t_current_ptr = &t_current;
    }
    
    MCDateTime t_start;
    MCDateTime *t_start_ptr;
    t_start_ptr = nil;
    
    if (!MCStringIsEmpty(p_start))
    {
        if (!MCD_convert_to_datetime(ctxt, p_start, CF_UNDEFINED, CF_UNDEFINED, t_start))
            return;
        t_start_ptr = &t_start;
    }
    
    MCDateTime t_end;
    MCDateTime *t_end_ptr;
    t_end_ptr = nil;
    
    if (!MCStringIsEmpty(p_end))
    {
        if (!MCD_convert_to_datetime(ctxt, p_end, CF_UNDEFINED, CF_UNDEFINED, t_end))
            return;
        t_end_ptr = &t_end;
    }
    
    int32_t t_step;
    if (p_step != nil)
        t_step = *p_step;
    else
        t_step = 1;
    
    bool t_cancel_button, t_done_button;
    
    t_cancel_button = false;
    t_done_button = false;
    
    switch (p_buttons)
    {
        case kMCPickButtonCancel:
            t_cancel_button = true;
            break;
        case kMCPickButtonDone:
            t_done_button = true;
            break;
        case kMCPickButtonCancelAndDone:
            t_cancel_button = true;
            t_done_button = true;
            break;
        case kMCPickButtonNone:
        default:
            break;
    }
    
    MCDateTime t_result;
    bool t_cancelled;
    t_cancelled = false;
    
    bool t_success;
    t_success = true;
    MCAutoValueRef t_result_string;
    
    // SN-2014-12-03: [[ Bug 14120 ]] If the picker has been cancelled, we should not try to convert the uninitialised t_result.
    switch (p_which)
    {
    case kMCPickDate:
            t_success = (MCSystemPickDate(t_current_ptr, t_start_ptr, t_end_ptr, t_cancel_button, t_done_button, &t_result, t_cancelled, p_button_rect)
                         && (t_cancelled || MCD_convert_from_datetime(ctxt, t_result, CF_DATE, CF_UNDEFINED, &t_result_string)));
        break;
    case kMCPickTime:
            t_success = (MCSystemPickTime(t_current_ptr, t_start_ptr, t_end_ptr, t_step, t_cancel_button, t_done_button, &t_result, t_cancelled, p_button_rect)
                         && (t_cancelled || MCD_convert_from_datetime(ctxt, t_result, CF_TIME, CF_UNDEFINED, &t_result_string)));
        break;
    case kMCPickDateAndTime:
            t_success = (MCSystemPickDateAndTime(t_current_ptr, t_start_ptr, t_end_ptr, t_step, t_cancel_button, t_done_button, &t_result, t_cancelled, p_button_rect)
                         && (t_cancelled || MCD_convert_from_datetime(ctxt, t_result, CF_DATE, CF_TIME, &t_result_string)));
        break;
    default:
        MCUnreachable();
    }
    
    if (t_success)
    {
        if (t_cancelled)
            ctxt.SetTheResultToStaticCString("cancel");
        else
            ctxt . SetTheResultToValue(*t_result_string);
        return;
    }
    
    ctxt . SetTheResultToEmpty();
}
Esempio n. 13
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;
}
Esempio n. 14
0
static int MCA_do_file_dialog(MCStringRef p_title, MCStringRef p_prompt, MCStringRef p_filter, MCStringRef p_initial, unsigned int p_options, MCStringRef &r_value, MCStringRef &r_result)
{
	int t_result = 0;

	MCAutoStringRef t_initial_file;
	MCAutoStringRef t_initial_folder;
    MCAutoStringRef t_initial_native_folder;

	if (p_initial != nil && !MCStringIsEmpty(p_initial))
	{
		MCAutoStringRef t_fixed_path;
		/* UNCHECKED */ MCU_fix_path(p_initial, &t_fixed_path);

		if (MCS_exists(*t_fixed_path, False))
			t_initial_folder = *t_fixed_path;
		else if ((p_options & MCA_OPTION_SAVE_DIALOG) != 0)
		{
			uindex_t t_last_slash;
			if (!MCStringLastIndexOfChar(*t_fixed_path, '/', UINDEX_MAX, kMCStringOptionCompareExact, t_last_slash))
			{
				if (MCStringGetLength(*t_fixed_path) != 0)
					t_initial_file = *t_fixed_path;
			}
			else
			{
				if (t_last_slash < MCStringGetLength(*t_fixed_path) - 1)
					/* UNCHECKED */ MCStringCopySubstring(*t_fixed_path, MCRangeMake(t_last_slash + 1, MCStringGetLength(*t_fixed_path) - (t_last_slash + 1)), &t_initial_file);

				MCAutoStringRef t_folder_split;
				/* UNCHECKED */ MCStringCopySubstring(*t_fixed_path, MCRangeMake(0, t_last_slash - 1), &t_folder_split);
				if (MCS_exists(*t_folder_split, False))
					t_initial_folder = *t_folder_split;
			}
		}
		else
		{
			uindex_t t_last_slash;

			if (MCStringLastIndexOfChar(*t_fixed_path, '/', UINDEX_MAX, kMCStringOptionCompareExact, t_last_slash))
			{
				MCAutoStringRef t_folder_split;
				/* UNCHECKED */ MCStringCopySubstring(*t_fixed_path, MCRangeMake(0, t_last_slash - 1), &t_folder_split);
				
				if (MCS_exists(*t_folder_split, False))
					t_initial_folder = *t_folder_split;
			}
		}
        
        MCAutoStringRef t_resolved_folder;
        /* UNCHECKED */ MCS_resolvepath(*t_initial_folder != nil ? *t_initial_folder : kMCEmptyString, &t_resolved_folder);
        /* UNCHECKED */ MCS_pathtonative(*t_resolved_folder, &t_initial_native_folder);
	}
    
	if (!MCModeMakeLocalWindows())
	{
		MCAutoStringRefArray t_filters;

		if (p_filter != NULL)
		{
			/* UNCHECKED */ MCStringsSplit(p_filter, '\0', t_filters.PtrRef(), t_filters.CountRef());
		}

		MCRemoteFileDialog(p_title, p_prompt, *t_filters, t_filters.Count(), *t_initial_native_folder, *t_initial_file, (p_options & MCA_OPTION_SAVE_DIALOG) != 0, (p_options & MCA_OPTION_PLURAL) != 0, r_value);

		return 0;
	}

	Window t_window;
	t_window = MCModeGetParentWindow();

	MCAutoStringRef t_value;
	bool t_succeeded;
	int t_filter_index;

	if (MCmajorosversion >= 0x0600)
	{
		static SHCreateItemFromParsingNamePtr  s_shcreateitemfromparsingname = NULL;
		if (s_shcreateitemfromparsingname == NULL)
		{
			static HMODULE s_shell32_module = NULL;
			s_shell32_module = LoadLibraryW(L"shell32.dll");
			s_shcreateitemfromparsingname = (SHCreateItemFromParsingNamePtr)GetProcAddress(s_shell32_module, "SHCreateItemFromParsingName");
		}

		IFileSaveDialog *t_file_save_dialog;
		IFileOpenDialog *t_file_open_dialog;
		IFileDialog *t_file_dialog;

		t_file_dialog = NULL;

		HRESULT t_hresult;

		if ((p_options & MCA_OPTION_SAVE_DIALOG) == 0)
		{
			t_hresult = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, __uuidof(IFileOpenDialog), (LPVOID *)&t_file_open_dialog);
			t_succeeded = SUCCEEDED(t_hresult);

			t_file_dialog = t_file_open_dialog;
		}
		else
		{
			t_hresult = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, __uuidof(IFileSaveDialog), (LPVOID *)&t_file_save_dialog);
			t_succeeded = SUCCEEDED(t_hresult);

			t_file_dialog = t_file_save_dialog;
		}

		if (t_succeeded)
		{
			DWORD t_options;

			t_options = FOS_FORCEFILESYSTEM | FOS_NOCHANGEDIR | FOS_PATHMUSTEXIST;
			if (p_options & MCA_OPTION_PLURAL)
				t_options |= FOS_ALLOWMULTISELECT;
			if (p_options & MCA_OPTION_SAVE_DIALOG)
				t_options |= FOS_OVERWRITEPROMPT;
			if (p_options & MCA_OPTION_FOLDER_DIALOG)
				t_options |= FOS_PICKFOLDERS;
			else
				t_options |= FOS_FILEMUSTEXIST;

			t_hresult = t_file_dialog -> SetOptions(t_options);
			t_succeeded = SUCCEEDED(t_hresult);
		}

		if (t_succeeded && *t_initial_native_folder != NULL)
		{
			IShellItem *t_initial_folder_shellitem;
			t_initial_folder_shellitem = NULL;

			MCAutoStringRefAsWString t_initial_folder_wstr;
			/* UNCHECKED */ t_initial_folder_wstr.Lock(*t_initial_native_folder);

			t_hresult = s_shcreateitemfromparsingname(*t_initial_folder_wstr, NULL, __uuidof(IShellItem), (LPVOID *)&t_initial_folder_shellitem);
			if (SUCCEEDED(t_hresult))
				t_file_dialog -> SetFolder(t_initial_folder_shellitem);
			if (t_initial_folder_shellitem != NULL)
				t_initial_folder_shellitem -> Release();
			t_succeeded = SUCCEEDED(t_hresult);
		}

		if (t_succeeded && *t_initial_file != NULL)
		{
			MCAutoStringRefAsWString t_initial_file_wstr;
			/* UNCHECKED */ t_initial_file_wstr.Lock(*t_initial_file);
			
			t_hresult = t_file_dialog -> SetFileName(*t_initial_file_wstr);
			t_succeeded = SUCCEEDED(t_hresult);
		}

		if (t_succeeded && p_filter != NULL && (p_options & MCA_OPTION_FOLDER_DIALOG) == 0)
		{
			uint4 t_filter_length, t_filter_count;
			measure_filter(p_filter, t_filter_length, t_filter_count);

			MCAutoStringRefAsWString t_filter_wstr;
			/* UNCHECKED */ t_filter_wstr.Lock(p_filter);

			COMDLG_FILTERSPEC *t_filter_spec;

			filter_to_spec(*t_filter_wstr, t_filter_count, t_filter_spec);

			t_hresult = t_file_dialog -> SetFileTypes(t_filter_count, t_filter_spec);
			t_succeeded = SUCCEEDED(t_hresult);

			delete t_filter_spec;
		}

		if (t_succeeded && p_filter != NULL && (p_options & MCA_OPTION_FOLDER_DIALOG) == 0)
		{
			t_hresult = t_file_dialog -> SetFileTypeIndex(1);
			t_succeeded = SUCCEEDED(t_hresult);
		}

		if (t_succeeded)
		{
			MCAutoStringRefAsWString t_prompt_wstr;
			/* UNCHECKED */ t_prompt_wstr.Lock(p_prompt);
			t_hresult = t_file_dialog -> SetTitle(*t_prompt_wstr);
		}

		if (t_succeeded)
		{
			t_hresult = t_file_dialog -> Show(t_window != NULL ? (HWND)t_window -> handle . window : NULL);
			t_succeeded = SUCCEEDED(t_hresult);
		}

		if ((p_options & MCA_OPTION_SAVE_DIALOG) == 0)
		{
			IShellItemArray *t_file_items;
			t_file_items = NULL;
			if (t_succeeded)
			{
				t_hresult = t_file_open_dialog -> GetResults(&t_file_items);
				t_succeeded = SUCCEEDED(t_hresult);
			}

			DWORD t_file_item_count;
			if (t_succeeded)
			{
				t_hresult = t_file_items -> GetCount(&t_file_item_count);
				t_succeeded = SUCCEEDED(t_hresult);
			}

			if (t_succeeded)
			{
				for(uint4 t_index = 0; t_index < t_file_item_count && t_succeeded; ++t_index)
				{
					IShellItem *t_file_item;
					t_file_item = NULL;
					if (t_succeeded)
					{
						t_hresult = t_file_items -> GetItemAt(t_index, &t_file_item);
						t_succeeded = SUCCEEDED(t_hresult);
					}

					if (t_succeeded)
					{
						t_hresult = append_shellitem_path_and_release(t_file_item, t_index == 0, &t_value);
						t_succeeded = SUCCEEDED(t_hresult);
					}
				}
			}

			if (t_file_items != NULL)
				t_file_items -> Release();
		}
		else
		{
			IShellItem *t_file_item;
			t_file_item = NULL;
			if (t_succeeded)
			{
				t_hresult = t_file_dialog -> GetResult(&t_file_item);
				t_succeeded = SUCCEEDED(t_hresult);
			}

			if (t_succeeded)
			{
				t_hresult = append_shellitem_path_and_release(t_file_item, true, &t_value);
				t_succeeded = SUCCEEDED(t_hresult);
			}
		}

		t_filter_index = 0;
		if (t_succeeded && (p_options & MCA_OPTION_FOLDER_DIALOG) == 0)
		{
			UINT t_index;
			t_hresult = t_file_dialog -> GetFileTypeIndex(&t_index);
			t_succeeded = SUCCEEDED(t_hresult);
			if (t_succeeded)
				t_filter_index = (int)t_index;
		}

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

		if (!t_succeeded)
			t_result = t_hresult;
		else
			t_result = 0;
	}
	else
	{
		OPENFILENAMEW t_open_dialog;
		memset(&t_open_dialog, 0, sizeof(OPENFILENAMEW));
		t_open_dialog . lStructSize = sizeof(OPENFILENAMEW);

		MCAutoStringRefAsWString t_initial_folder_wstr;
		MCAutoStringRefAsWString t_prompt_wstr;
		MCAutoStringRefAsWString t_filter_wstr;
		/* UNCHECKED */ t_filter_wstr.Lock(p_filter);
		/* UNCHECKED */ t_initial_folder_wstr.Lock(*t_initial_native_folder);
		/* UNCHECKED */ t_prompt_wstr.Lock(p_prompt);

		MCAutoArray<unichar_t> t_buffer;
		/* UNCHECKED */ t_buffer.New(MAX_PATH);

		if (!MCStringIsEmpty(*t_initial_file))
			/* UNCHECKED */ MCStringGetChars(*t_initial_file, MCRangeMake(0, t_buffer.Size()), t_buffer.Ptr());
		else
			t_buffer[0] = '\0';

		t_open_dialog . lpstrFilter = *t_filter_wstr;
		t_open_dialog . nFilterIndex = 1;
		t_open_dialog . lpstrFile = t_buffer.Ptr();
		t_open_dialog . nMaxFile = t_buffer.Size();
		t_open_dialog . lpstrInitialDir = *t_initial_folder_wstr;
		t_open_dialog . lpstrTitle = *t_prompt_wstr;
		t_open_dialog . Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR |
														OFN_LONGNAMES | OFN_PATHMUSTEXIST | OFN_EXPLORER |
														OFN_ENABLEHOOK | OFN_ENABLESIZING;

		if (p_options & MCA_OPTION_PLURAL)
			t_open_dialog . Flags |= OFN_ALLOWMULTISELECT;

		if (p_options & MCA_OPTION_SAVE_DIALOG)
			t_open_dialog . Flags |= OFN_OVERWRITEPROMPT;

		t_open_dialog . lpstrFilter = *t_filter_wstr;
		t_open_dialog . lpfnHook = open_dialog_hook;
		t_open_dialog . hwndOwner = t_window != NULL ? (HWND)t_window -> handle . window : NULL;

		if (p_options & MCA_OPTION_SAVE_DIALOG)
			t_succeeded = GetSaveFileNameW(&t_open_dialog) == TRUE;
		else
		{
			*t_open_dialog . lpstrFile = '\0';
			t_succeeded = GetOpenFileNameW(&t_open_dialog) == TRUE;
		}

		if (!t_succeeded)
			t_result = CommDlgExtendedError();

		// MW-2005-07-26: Try again without the specified filename if it was invalid
		if (t_result == FNERR_INVALIDFILENAME)
		{
			*t_open_dialog . lpstrFile = '\0';
			if (p_options & MCA_OPTION_SAVE_DIALOG)
				t_succeeded = GetSaveFileNameW(&t_open_dialog) == TRUE;
			else
				t_succeeded = GetOpenFileNameW(&t_open_dialog) == TRUE;

			if (!t_succeeded)
				t_result = CommDlgExtendedError();	
		}

		if (t_result == FNERR_BUFFERTOOSMALL)
			t_succeeded = true;

		if (t_succeeded)
		{
			build_paths(&t_value);
			t_filter_index = t_open_dialog . nFilterIndex;
		}
	}

	if (t_succeeded)
	{
		if (p_options & MCA_OPTION_RETURN_FILTER)
		{
			// The filter string has the following format:
			// "<description0>\0<extensions0>\0<description1>\0...\0<extensionsN>\0"
			// so the n'th filter comes after the 2(n - 1)'th null character
			uindex_t t_index = 2 * (t_filter_index - 1);
			uindex_t t_offset = 0;
			while (t_index--)
			{
				/* UNCHECKED */ MCStringFirstIndexOfChar(p_filter, '\0', t_offset, kMCStringOptionCompareExact, t_offset);
				t_offset++;
			}
			
			uindex_t t_end;
			t_end = UINDEX_MAX;
			/* UNCHECKED */ MCStringFirstIndexOfChar(p_filter, '\0', t_offset, kMCStringOptionCompareExact, t_end);
            
			/* UNCHECKED */ MCStringCopySubstring(p_filter, MCRangeMake(t_offset, t_end-t_offset), r_result);
		}

		t_result = 0;
		r_value = MCValueRetain(*t_value);
	}
	else
		r_result = MCValueRetain(MCNameGetString(MCN_cancel));

	waitonbutton();

	return t_result;
}