CString CBaseCloudStorage::FormatDisplayName(const CString& sFilePath)
{
	CString sDisplay;
	sDisplay.Format(_T("%s: %s"), GetMenuText(), FileMisc::GetFileNameFromPath(sFilePath));
	
	return sDisplay;
}
// GetMenuCount()
// Return number of menu items that are defined.
int CMenuSubscribeDlg::GetMenuCount() {
	int iCount = 0;

    // A menu item is defined if menu text is entered.
	for( int i = 0; i < 3; i++ ) {
		if( GetMenuText(i).length() > 0 ) iCount++;
	}

	return iCount;
}
bool CBaseCloudStorage::RetrieveTasklist(ITS_TASKLISTINFO* pFInfo, ITaskList* /*pDestTaskFile*/, IPreferences* /*pPrefs*/, LPCTSTR /*szKey*/, bool bSilent)
{
	CString sUserFolder;
	
	if (IsInstalled(sUserFolder))
	{
		CString sSrcPath = pFInfo->szTasklistID;
		CString sDestPath = pFInfo->szLocalFileName;
		
		if (bSilent && sSrcPath.IsEmpty())
			return false;
		
		if (sSrcPath.IsEmpty())
		{
			CFileOpenDialog	dialog(GetMenuText(), 
									_T("tdl"), 
									NULL, 
									EOFN_DEFAULTOPEN, 
									_T("Tasklists (*.tdl)|*.tdl"));

			dialog.m_ofn.lpstrInitialDir = sUserFolder;
			
			if (dialog.DoModal() != IDOK)
				return false;
			
			// else
			sSrcPath = dialog.GetPathName();

			if (sDestPath.IsEmpty())
				sDestPath = sSrcPath;
		}
		
		if (FileMisc::IsSameFile(sSrcPath, sDestPath) || ::CopyFile(sSrcPath, sDestPath, FALSE))
		{
			// return information to caller
			UpdateTaskListInfo(pFInfo, sDestPath);
			return true;
		}
	}
	
	return false;
}
char* Screen_Base::ExportMenuLayout()
{
    cJSON* menuitemarray = cJSON_CreateArray();

    for( int i=0; i<MAX_MENUITEMS; i++ )
    {
        MenuItem* pMenuItem = m_pMenuItems[i];

        if( pMenuItem )
        {
            cJSON* menuitem = cJSON_CreateObject();
            cJSON_AddItemToArray( menuitemarray, menuitem );

            cJSON_AddStringToObject( menuitem, "Name", pMenuItem->m_Name );

            cJSON_AddNumberToObject( menuitem, "X", pMenuItem->m_Transform.m41 );
            cJSON_AddNumberToObject( menuitem, "Y", pMenuItem->m_Transform.m42 );

            cJSON_AddNumberToObject( menuitem, "Scale", pMenuItem->m_Scale.x );

            cJSON_AddNumberToObject( menuitem, "SX", pMenuItem->m_Size.x );
            cJSON_AddNumberToObject( menuitem, "SY", pMenuItem->m_Size.y );

            cJSON_AddNumberToObject( menuitem, "OffX", pMenuItem->m_PositionOffset.x );
            cJSON_AddNumberToObject( menuitem, "OffY", pMenuItem->m_PositionOffset.y );

            switch( pMenuItem->m_MenuItemType )
            {
            case MIT_Sprite:
                {
                    MenuSprite* pMenuSprite = GetMenuSprite( i );

                    cJSON_AddNumberToObject( menuitem, "W", pMenuItem->m_Transform.m11 );
                    cJSON_AddNumberToObject( menuitem, "H", pMenuItem->m_Transform.m22 );

                    cJSON_AddNumberToObject( menuitem, "BGShadowX", pMenuSprite->m_DropShadowOffsetBG_X );
                    cJSON_AddNumberToObject( menuitem, "BGShadowY", pMenuSprite->m_DropShadowOffsetBG_Y );
                }
                break;

            case MIT_Text: // MenuText_SaveLoad
                {
                    MenuText* pMenuText = GetMenuText( i );

                    cJSON_AddNumberToObject( menuitem, "FontHeight", pMenuText->m_FontHeight );

                    cJSON_AddNumberToObject( menuitem, "TextShadowX", pMenuText->m_DropShadowOffsetX );
                    cJSON_AddNumberToObject( menuitem, "TextShadowY", pMenuText->m_DropShadowOffsetY );

                    cJSON_AddNumberToObject( menuitem, "Justify", pMenuText->m_Justification );
                }
                break;

            case MIT_Button:
                {
                    MenuButton* pMenuButton = GetMenuButton( i );

                    cJSON_AddNumberToObject( menuitem, "W", pMenuItem->m_Transform.m11 );
                    cJSON_AddNumberToObject( menuitem, "H", pMenuItem->m_Transform.m22 );

                    cJSON_AddNumberToObject( menuitem, "IW", pMenuButton->m_InputWidth );
                    cJSON_AddNumberToObject( menuitem, "IH", pMenuButton->m_InputHeight );

                    cJSON_AddNumberToObject( menuitem, "FontHeight", pMenuButton->m_FontHeight );

                    cJSON_AddNumberToObject( menuitem, "BGShadowX", pMenuButton->m_DropShadowOffsetBG_X );
                    cJSON_AddNumberToObject( menuitem, "BGShadowY", pMenuButton->m_DropShadowOffsetBG_Y );

                    cJSON_AddNumberToObject( menuitem, "TextShadowX", pMenuButton->m_DropShadowOffsetText_X );
                    cJSON_AddNumberToObject( menuitem, "TextShadowY", pMenuButton->m_DropShadowOffsetText_Y );
                }
                break;

            case MIT_Base:
            case MIT_InputBox:
            case MIT_ScrollingText:
            case MIT_ScrollBox:
            case MIT_CheckBox:
            case MIT_NumMenuItemTypes:
                break;
            }
        }
    }

    char* savestring = cJSON_PrintUnformatted( menuitemarray );
    cJSON_Delete( menuitemarray );

    char* RidiculousReallocatedStringSoICanUseMyNewDeleteOverridesWithoutChangingThecJSONCodeToUseThemForAllItsSmallAllocations;
    int len = (int)strlen( savestring );
    RidiculousReallocatedStringSoICanUseMyNewDeleteOverridesWithoutChangingThecJSONCodeToUseThemForAllItsSmallAllocations = MyNew char[len+1];
    strcpy_s( RidiculousReallocatedStringSoICanUseMyNewDeleteOverridesWithoutChangingThecJSONCodeToUseThemForAllItsSmallAllocations, len+1, savestring );
    free( savestring );

    return RidiculousReallocatedStringSoICanUseMyNewDeleteOverridesWithoutChangingThecJSONCodeToUseThemForAllItsSmallAllocations;
}
void Screen_Base::ImportMenuLayout(const char* layout)
{
    if( layout == 0 )
        return;

    cJSON* menuitemarray = cJSON_Parse( layout );
    assert( menuitemarray );

    if( menuitemarray )
    {
        int numitems = cJSON_GetArraySize( menuitemarray );
        assert( numitems <= MAX_MENUITEMS );

        for( int i=0; i<numitems; i++ )
        {
            cJSON* menuitem = cJSON_GetArrayItem( menuitemarray, i );

            cJSON* objname = cJSON_GetObjectItem( menuitem, "Name" );

            int itemindex = -1;
            for( itemindex = 0; itemindex < MAX_MENUITEMS; itemindex++ )
            {
                if( strcmp( objname->valuestring, m_pMenuItems[itemindex]->m_Name ) == 0 )
                    break;
            }

            if( itemindex < MAX_MENUITEMS )
            {
                float x = 0;
                float y = 0;
                float w = 0;
                float h = 0;
                float iw = -1;
                float ih = -1;

                MenuItem* pMenuItem = m_pMenuItems[itemindex];

                cJSONExt_GetFloat( menuitem, "X", &x );
                cJSONExt_GetFloat( menuitem, "Y", &y );

                cJSONExt_GetFloat( menuitem, "Scale", &pMenuItem->m_Scale.x );
                cJSONExt_GetFloat( menuitem, "Scale", &pMenuItem->m_Scale.y );
                cJSONExt_GetFloat( menuitem, "Scale", &pMenuItem->m_Scale.z );

                cJSONExt_GetFloat( menuitem, "SX", &pMenuItem->m_Size.x );
                cJSONExt_GetFloat( menuitem, "SY", &pMenuItem->m_Size.y );

                cJSONExt_GetFloat( menuitem, "W", &w );
                cJSONExt_GetFloat( menuitem, "H", &h );

                cJSONExt_GetFloat( menuitem, "IW", &iw );
                cJSONExt_GetFloat( menuitem, "IH", &ih );

                cJSONExt_GetFloat( menuitem, "OffX", &pMenuItem->m_PositionOffset.x );
                cJSONExt_GetFloat( menuitem, "OffY", &pMenuItem->m_PositionOffset.y );

                pMenuItem->SetPositionAndSize( x, y, w, h, iw, ih );

                switch( pMenuItem->m_MenuItemType )
                {
                case MIT_Sprite:
                    {
                        MenuSprite* pMenuSprite = GetMenuSprite( itemindex );

                        cJSONExt_GetFloat( menuitem, "BGShadowX", &pMenuSprite->m_DropShadowOffsetBG_X );
                        cJSONExt_GetFloat( menuitem, "BGShadowY", &pMenuSprite->m_DropShadowOffsetBG_Y );
                    }
                    break;

                case MIT_Text: // MenuText_SaveLoad
                    {
                        MenuText* pMenuText = GetMenuText( itemindex );

                        cJSONExt_GetFloat( menuitem, "FontHeight", &pMenuText->m_FontHeight );
                        cJSONExt_GetFloat( menuitem, "TextShadowX", &pMenuText->m_DropShadowOffsetX );
                        cJSONExt_GetFloat( menuitem, "TextShadowY", &pMenuText->m_DropShadowOffsetY );

                        cJSONExt_GetUnsignedChar( menuitem, "Justify", &pMenuText->m_Justification );
                    }
                    break;

                case MIT_Button:
                    {
                        MenuButton* pMenuButton = GetMenuButton( itemindex );

                        cJSONExt_GetFloat( menuitem, "FontHeight", &pMenuButton->m_FontHeight );
                        cJSONExt_GetFloat( menuitem, "BGShadowX", &pMenuButton->m_DropShadowOffsetBG_X );
                        cJSONExt_GetFloat( menuitem, "BGShadowY", &pMenuButton->m_DropShadowOffsetBG_Y );
                        cJSONExt_GetFloat( menuitem, "TextShadowX", &pMenuButton->m_DropShadowOffsetText_X );
                        cJSONExt_GetFloat( menuitem, "TextShadowY", &pMenuButton->m_DropShadowOffsetText_Y );
                    }
                    break;

                case MIT_Base:
                case MIT_InputBox:
                case MIT_ScrollingText:
                case MIT_ScrollBox:
                case MIT_CheckBox:
                case MIT_NumMenuItemTypes:
                    break;
                }
            }
        }

        cJSON_Delete( menuitemarray );
    }
}
// BuildAddRequest()
// Builds XML and checks for errors for DoAddRequest().
// Returns request XML if it could be created.
//
string CMenuSubscribeDlg::BuildAddRequest() {
	// Begin request.
	DOMXMLBuilder xmlBuilder;
	xmlBuilder.CreateSubscriptionXMLHeader();

	// Check initial xmlBuilder access for COM and other initialization errors.
	if( xmlBuilder.GetHasError() ) {
		DisplayXMLError( xmlBuilder );
		return "";
	}

	// Add UI Extension tags.
	xmlBuilder.AddAggregate( UIEXTSUBADDRQ_TAG );
	xmlBuilder.AddAggregate( UIEXTSUBADD_TAG );

	// Add subscriber id.
	xmlBuilder.AddElement( SUBSCRIBERID_TAG, SUBSCRIBER_ID );
	
	// Add callback info.
	xmlBuilder.AddAggregate( COMCALLBACKINFO_TAG );
	xmlBuilder.AddElement( APPNAME_TAG, HANDLER_APP_NAME );
	xmlBuilder.AddElement( CLSID_TAG, HANDLER_CLSID );
	xmlBuilder.AddEndAggregate( COMCALLBACKINFO_TAG );

	// Begin menu definition section.
	xmlBuilder.AddAggregate( MENUEXTSUB_TAG );
	string strAddToMenu = GetItemText( IDC_ADD_TO );
	xmlBuilder.AddElement( ADDTOMENU_TAG, strAddToMenu );

	// If more than one menu defined, create submenu of items.
	int iCount = GetMenuCount();
	if( iCount > 1 ) {
		xmlBuilder.AddAggregate( SUBMENU_TAG );
	}

	// Create XML for each defined menu item.
	for( int iMenu = 0; iMenu < 3; iMenu++ ) {
		// Menu text.
		string strMenuText = GetMenuText( iMenu );

		// If menu text defined, add menu item.
		if( strMenuText.length() > 0 ) {
			// Begin this menu item definition.
			xmlBuilder.AddAggregate( MENUITEM_TAG );
			xmlBuilder.AddElement( MENUTEXT_TAG, strMenuText );

			// Menu tag (menu_1,menu_2,etc.) This gets echoed back in
			// event XML when menu item is clicked by user.
			string strEventTag = "menu_";
			char lpszID[2];
			lpszID[0] = (char)('1'+iMenu);
			lpszID[1] = 0;
			strEventTag.append( lpszID );
			xmlBuilder.AddElement( EVENTTAG_TAG, strEventTag );

			// Display conditions.
			string strVisibleCondition = GetVisibleCondition( iMenu );
			string strEnabledCondition = GetEnabledCondition( iMenu );
			if( strVisibleCondition.length() > 0 || strEnabledCondition.length() > 0 ) {
				xmlBuilder.AddAggregate( DISPLAYCONDITION_TAG );
				// Visible condition.
				if( strVisibleCondition.length() > 0 ) {
					BOOL bVisibleIf = GetVisibleIf( iMenu );
					if( bVisibleIf ) {
						xmlBuilder.AddElement( VISIBLEIF_TAG, strVisibleCondition );
					}
					else {
						xmlBuilder.AddElement( VISIBLEIFNOT_TAG, strVisibleCondition );
					}
				}
				// Enabled condition.
				if( strEnabledCondition.length() > 0 ) {
					BOOL bEnabledIf = GetEnabledIf( iMenu );
					if( bEnabledIf ) {
						xmlBuilder.AddElement( ENABLEDIF_TAG, strEnabledCondition );
					}
					else {
						xmlBuilder.AddElement( ENABLEDIFNOT_TAG, strEnabledCondition );
					}
				}
				xmlBuilder.AddEndAggregate( DISPLAYCONDITION_TAG );
			}

			// End menu item aggregate.
			xmlBuilder.AddEndAggregate( MENUITEM_TAG );
		}
	}

	// If more than one menu defined, end submenu aggregate.
	if( iCount > 1 ) {
		xmlBuilder.AddEndAggregate( SUBMENU_TAG );
	}

	// Finish request.
	xmlBuilder.AddEndAggregate( MENUEXTSUB_TAG );

	xmlBuilder.AddEndAggregate( UIEXTSUBADD_TAG );
	xmlBuilder.AddEndAggregate( UIEXTSUBADDRQ_TAG );
	xmlBuilder.CreateSubscriptionXMLTrailer();

	// If any errors occurred, display error message.
	if( xmlBuilder.GetHasError() ) {
		DisplayXMLError( xmlBuilder );
		return "";
	}

	// If no errors, return request formatted with tabs and line breaks.
	return xmlBuilder.GetXML();
}