mirror of
https://github.com/azure-rtos/guix.git
synced 2025-02-04 07:13:17 +08:00
1067 lines
34 KiB
C++
1067 lines
34 KiB
C++
|
|
#include "studiox_includes.h"
|
|
#include "undo_manager.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#endif
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
undo_manager::undo_manager()
|
|
{
|
|
current = NULL;
|
|
|
|
tail = undo_list;
|
|
tail += MAX_UNDO_ENTRIES - 1;
|
|
entries = 0;
|
|
|
|
is_add_entry_locked = FALSE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
undo_manager::~undo_manager()
|
|
{
|
|
Reset();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void undo_manager::AddEntry(int type, folder_info *folder, int display_index)
|
|
{
|
|
if (!folder || IsAddEntryLocked())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (current)
|
|
{
|
|
current++;
|
|
if (current > tail)
|
|
{
|
|
current = undo_list;
|
|
}
|
|
if (entries < MAX_UNDO_ENTRIES)
|
|
{
|
|
entries++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
current = undo_list;
|
|
entries = 1;
|
|
}
|
|
|
|
ClearUndoRecord(current);
|
|
current->type = type;
|
|
|
|
undo_widget new_entry;
|
|
|
|
switch (type)
|
|
{
|
|
case UNDO_TYPE_DELETE_FOLDER:
|
|
case UNDO_TYPE_INSERT_TOP_LEVEL_WIDGETS:
|
|
new_entry.folder = new folder_info(*folder);
|
|
break;
|
|
|
|
case UNDO_TYPE_INSERT_FOLDER:
|
|
new_entry.folder_name = folder->folder_name;
|
|
break;
|
|
}
|
|
|
|
new_entry.res_index = display_index;
|
|
current->widget_list.Add(new_entry);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void undo_manager::AddEntry(int type, widget_info *info, int res_index, BOOL fold)
|
|
{
|
|
if (!info || !info->widget || IsAddEntryLocked())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (current)
|
|
{
|
|
// in a few cases we don't need to make another entry
|
|
// repeast position/size changes can be folded into one
|
|
// repeated name changes are folded into one
|
|
// repeated style changes are foled into one
|
|
switch(type)
|
|
{
|
|
case UNDO_TYPE_SIZE:
|
|
case UNDO_TYPE_POSITION:
|
|
|
|
if (current->type == type && fold)
|
|
{
|
|
if (current->widget_list[0].project_info == info)
|
|
{
|
|
// no need to make a new entry
|
|
return;
|
|
}
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_STYLE:
|
|
case UNDO_TYPE_NAMES:
|
|
case UNDO_TYPE_USER_DATA:
|
|
if (current->type == type &&
|
|
current->widget_list[0].project_info == info)
|
|
{
|
|
// same widget getting name or style change, don't save new record
|
|
return;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
current++;
|
|
if (current > tail)
|
|
{
|
|
current = undo_list;
|
|
}
|
|
if (entries < MAX_UNDO_ENTRIES)
|
|
{
|
|
entries++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
current = undo_list;
|
|
entries = 1;
|
|
}
|
|
|
|
ClearUndoRecord(current);
|
|
current->type = type;
|
|
|
|
undo_widget new_entry;
|
|
|
|
if (type == UNDO_TYPE_DELETE_WIDGET)
|
|
{
|
|
// copy the entire info tree, including children
|
|
new_entry.copy_info = new widget_info(*info);
|
|
new_entry.copy_info->widget = NULL;
|
|
|
|
// When a widget is deleted, the corresponding widget_info is also deleted.
|
|
// So if we un-delete the widget, we need to fixup any undo_manager entries
|
|
// that are pointing at the old widget_info structures:
|
|
UpdateUndoRecordInfoPointers(new_entry.copy_info, info);
|
|
}
|
|
else
|
|
{
|
|
// copy just this one record
|
|
new_entry.copy_info = new widget_info(info->basetype);
|
|
*new_entry.copy_info = *info;
|
|
new_entry.copy_info->widget = NULL;
|
|
}
|
|
|
|
if (info)
|
|
{
|
|
// save pointer to original widget_info
|
|
new_entry.project_info = info;
|
|
}
|
|
else
|
|
{
|
|
ErrorMsg("Internal Error: Invalid project information.");
|
|
}
|
|
|
|
studiox_project *project = GetOpenProject();
|
|
|
|
widget_info *parent_info = project->FindParentInfo(info);
|
|
if (parent_info)
|
|
{
|
|
new_entry.parent_info = parent_info;
|
|
}
|
|
else
|
|
{
|
|
new_entry.parent_info = NULL;
|
|
|
|
if (project)
|
|
{
|
|
folder_info *folder = project->FindParentFolderInfo(info);
|
|
|
|
if (folder)
|
|
{
|
|
//new_entry.folder = folder;
|
|
new_entry.folder_name = folder->folder_name;
|
|
}
|
|
}
|
|
}
|
|
new_entry.res_index = res_index;
|
|
current->widget_list.Add(new_entry);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void undo_manager::AddEntry(int type, CArray<WIDGET_SELECT_ENTRY> &widget_list, BOOL fold)
|
|
{
|
|
int widget_count;
|
|
int widget_index;
|
|
BOOL same_set = TRUE;
|
|
|
|
if (IsAddEntryLocked())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (current)
|
|
{
|
|
// see if we just need to update most recent undo entry
|
|
|
|
if (current->type == type && fold &&
|
|
(type == UNDO_TYPE_POSITION || type == UNDO_TYPE_SIZE))
|
|
{
|
|
widget_count = current->widget_list.GetSize();
|
|
if (widget_count != widget_list.GetCount())
|
|
{
|
|
same_set = FALSE;
|
|
}
|
|
else
|
|
{
|
|
for (widget_index = 0; widget_index < widget_count; widget_index++)
|
|
{
|
|
if (current->widget_list[widget_index].project_info !=
|
|
widget_list[widget_index].info)
|
|
{
|
|
same_set = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (same_set)
|
|
{
|
|
// same set of widgets being positioned, so no need to make new copy
|
|
// of the widget info
|
|
return;
|
|
}
|
|
}
|
|
|
|
current++;
|
|
if (current > tail)
|
|
{
|
|
current = undo_list;
|
|
}
|
|
if (entries < MAX_UNDO_ENTRIES)
|
|
{
|
|
entries++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
current = undo_list;
|
|
entries = 1;
|
|
}
|
|
|
|
ClearUndoRecord(current);
|
|
current->type = type;
|
|
|
|
widget_count = widget_list.GetCount();
|
|
current->widget_list.SetSize(widget_count);
|
|
|
|
for (widget_index = 0; widget_index < widget_count; widget_index++)
|
|
{
|
|
widget_info *info = widget_list[widget_index].info;
|
|
|
|
current->widget_list[widget_index].project_info = info;
|
|
current->widget_list[widget_index].copy_info = new widget_info(info->basetype);
|
|
*current->widget_list[widget_index].copy_info = *info;
|
|
current->widget_list[widget_index].copy_info->widget = NULL;
|
|
current->widget_list[widget_index].parent_info = GetOpenProject()->FindParentInfo(info);
|
|
current->widget_list[widget_index].res_index = 0;
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Count how many nodes are in a widget_info tree.
|
|
This is done as part of UpdateUndoEntryInfoPointers()
|
|
*/
|
|
|
|
int undo_manager::CountInfoNodes(widget_info *start, int count)
|
|
{
|
|
while(start)
|
|
{
|
|
count++;
|
|
if (start->GetChildWidgetInfo())
|
|
{
|
|
count += CountInfoNodes(start->GetChildWidgetInfo(), count);
|
|
}
|
|
start = start->GetNextWidgetInfo();
|
|
}
|
|
return count;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Write an array of old_info and new_info pointers.
|
|
This is done as part of UpdateUndoEntryInfoPointers()
|
|
*/
|
|
widget_info **undo_manager::BuildInfoNodeArray(widget_info **write, widget_info *new_tree, widget_info *old_tree)
|
|
{
|
|
while(new_tree)
|
|
{
|
|
*write++ = old_tree;
|
|
*write++ = new_tree;
|
|
|
|
if (new_tree->GetChildWidgetInfo())
|
|
{
|
|
write = BuildInfoNodeArray(write, new_tree->GetChildWidgetInfo(), old_tree->GetChildWidgetInfo());
|
|
}
|
|
new_tree = new_tree->GetNextWidgetInfo();
|
|
old_tree = old_tree->GetNextWidgetInfo();
|
|
}
|
|
return write;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* Called by UpdateUndoEntryInfoPointers.
|
|
For each undo entry, go through the list of project_info pointers. If any
|
|
of them are in the node_list array, replace them with the new pointers.
|
|
*/
|
|
void undo_manager::SearchAndReplaceInfoPointers(undo_record *search, widget_info **node_list, int node_list_size)
|
|
{
|
|
int widget_index;
|
|
int list_index;
|
|
|
|
int rows = search->widget_list.GetCount();
|
|
widget_info *old_pointer;
|
|
|
|
for (widget_index = 0; widget_index < rows; widget_index++)
|
|
{
|
|
old_pointer = search->widget_list[widget_index].project_info;
|
|
|
|
for (list_index = 0; list_index < node_list_size * 2; list_index += 2)
|
|
{
|
|
if (node_list[list_index] == old_pointer)
|
|
{
|
|
search->widget_list[widget_index].project_info = node_list[list_index + 1];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
/* If we Delete a widget, then undo the Delete, it's possible that the undo
|
|
list will hold records pointing at the old widget_info structure tree. So if
|
|
we un-delete a widget (tree), we need to update the undo list records to
|
|
convert the old project_info pointers to the new project_info pointers.
|
|
*/
|
|
void undo_manager::UpdateUndoRecordInfoPointers(widget_info *new_info, widget_info *old_info)
|
|
{
|
|
undo_record *search = current;
|
|
int rows = entries;
|
|
|
|
int nodes = CountInfoNodes(new_info, 0);
|
|
widget_info **info_list = new widget_info*[nodes * 2];
|
|
BuildInfoNodeArray(info_list, new_info, old_info);
|
|
|
|
while(rows--)
|
|
{
|
|
SearchAndReplaceInfoPointers(search, info_list, nodes);
|
|
search--;
|
|
if (search < undo_list)
|
|
{
|
|
search = tail;
|
|
}
|
|
}
|
|
delete [] info_list;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void undo_manager::Undo()
|
|
{
|
|
int widget_list_size;
|
|
int widget_list_index;
|
|
int resource_index;
|
|
int display;
|
|
widget_service_provider *provider;
|
|
widget_info *current_info;
|
|
widget_info *parent_info;
|
|
GX_WIDGET *target;
|
|
|
|
studiox_project *pProject = GetOpenProject();
|
|
|
|
if (entries <= 0 || pProject == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LockAddEntry();
|
|
|
|
undo_record *entry = current;
|
|
current--;
|
|
if (current < undo_list)
|
|
{
|
|
current = tail;
|
|
}
|
|
entries--;
|
|
|
|
if (!entries)
|
|
{
|
|
current = NULL;
|
|
}
|
|
|
|
widget_list_size = entry->widget_list.GetSize();
|
|
|
|
if (widget_list_size)
|
|
{
|
|
if (entry->type == UNDO_TYPE_DELETE_WIDGET)
|
|
{
|
|
parent_info = entry->widget_list[0].parent_info;
|
|
}
|
|
else
|
|
{
|
|
parent_info = entry->widget_list[0].project_info;
|
|
}
|
|
}
|
|
|
|
if (parent_info)
|
|
{
|
|
GetTargetScreen()->MakeTopWindowVisible(parent_info);
|
|
}
|
|
|
|
switch(entry->type)
|
|
{
|
|
case UNDO_TYPE_POSITION:
|
|
case UNDO_TYPE_SIZE:
|
|
for (widget_list_index = 0; widget_list_index < widget_list_size; widget_list_index++)
|
|
{
|
|
widget_factory::MoveWidget(entry->widget_list[widget_list_index].project_info,
|
|
entry->widget_list[widget_list_index].copy_info->size);
|
|
|
|
current_info = entry->widget_list[widget_list_index].project_info;
|
|
if (current_info)
|
|
{
|
|
GetTargetScreen()->WidgetWasMoved(current_info);
|
|
}
|
|
}
|
|
GetPropsWin()->WidgetWasMoved();
|
|
break;
|
|
|
|
case UNDO_TYPE_STYLE:
|
|
current_info = entry->widget_list[0].project_info;
|
|
target = current_info->widget;
|
|
|
|
if (current_info)
|
|
{
|
|
current_info->style = entry->widget_list[0].copy_info->style;
|
|
if (target)
|
|
{
|
|
gx_widget_style_set(target, current_info->style);
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_TEMPLATE:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
current_info->is_template = entry->widget_list[0].copy_info->is_template;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_SLIDER_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
target = current_info->widget;
|
|
|
|
if (current_info)
|
|
{
|
|
current_info->ewi = entry->widget_list[0].copy_info->ewi;
|
|
current_info->misc_value = entry->widget_list[0].copy_info->misc_value;
|
|
|
|
if (target)
|
|
{
|
|
GX_SLIDER *slider = (GX_SLIDER *) target;
|
|
if (current_info->basetype == GX_TYPE_SLIDER)
|
|
{
|
|
slider->gx_slider_tick_count = current_info->misc_value;
|
|
}
|
|
gx_slider_info_set(slider, ¤t_info->ewi.slider);
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_PROGRESS_BAR_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
current_info->ewi = entry->widget_list[0].copy_info->ewi;
|
|
properties_win::AssignProgressBarInfo(current_info);
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_LIST_ROWS:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
switch(current_info->basetype)
|
|
{
|
|
case GX_TYPE_VERTICAL_LIST:
|
|
case GX_TYPE_HORIZONTAL_LIST:
|
|
current_info->ewi.vlist.total_rows = entry->widget_list[0].copy_info->ewi.vlist.total_rows;
|
|
break;
|
|
|
|
case GX_TYPE_DROP_LIST:
|
|
current_info->ewi.drop_list.total_rows = entry->widget_list[0].copy_info->ewi.drop_list.total_rows;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_OPEN_HEIGHT:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
current_info->ewi.drop_list.open_height = entry->widget_list[0].copy_info->ewi.drop_list.open_height;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_DYNAMIC_TEXT_BUFFER:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
current_info->ewi.text_info.dynamic_buffer = entry->widget_list[0].copy_info->ewi.text_info.dynamic_buffer;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_TEXT_VIEW_WHITESPACE:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
current_info->ewi.text_info.whitespace = entry->widget_list[0].copy_info->ewi.text_info.whitespace;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_TEXT_VIEW_LINE_SPACE:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
current_info->ewi.text_info.line_space = entry->widget_list[0].copy_info->ewi.text_info.line_space;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_TEXT_BUFFER_SIZE:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
current_info->ewi.text_info.buffer_size = entry->widget_list[0].copy_info->ewi.text_info.buffer_size;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_SCROLL_APPEARANCE:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
GX_SCROLLBAR_APPEARANCE appearance = entry->widget_list[0].copy_info->ewi.scroll;
|
|
widget_factory::ReplaceScrollbar(current_info, &appearance);
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_SCROLL_STYLE:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
GX_SCROLLBAR_APPEARANCE appearance = current_info->ewi.scroll;
|
|
current_info->style = entry->widget_list[0].copy_info->style;
|
|
widget_factory::ReplaceScrollbar(current_info, &appearance);
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_INSERT_WIDGET:
|
|
if (widget_list_size > 1)
|
|
{
|
|
GetTargetScreen()->DeSelect();
|
|
}
|
|
|
|
for (widget_list_index = 0; widget_list_index < widget_list_size; widget_list_index++)
|
|
{
|
|
current_info = entry->widget_list[widget_list_index].project_info;
|
|
if (current_info)
|
|
{
|
|
GetProjectView()->DeleteWidget(current_info);
|
|
}
|
|
else
|
|
{
|
|
ErrorMsg("Internal Error: Invalid Undo information.");
|
|
}
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_DELETE_WIDGET:
|
|
{
|
|
// re-insert the deleted widget
|
|
// copy the widget info structures
|
|
parent_info = entry->widget_list[0].parent_info;
|
|
|
|
// select the parent widget so that we don't get
|
|
// an out-of-sync verification error:
|
|
GetTargetScreen()->SelectWidget(parent_info, TRUE, FALSE);
|
|
|
|
widget_info *pTemp = entry->widget_list[0].copy_info;
|
|
entry->widget_list[0].copy_info = NULL;
|
|
|
|
widget_info *search_start;
|
|
BOOL is_top_level_widget;
|
|
|
|
if (parent_info == NULL)
|
|
{
|
|
search_start = NULL;
|
|
is_top_level_widget = TRUE;
|
|
}
|
|
else
|
|
{
|
|
search_start = GetProjectView()->FindTopLevelWidget(parent_info);
|
|
if (!search_start)
|
|
{
|
|
break;
|
|
}
|
|
search_start = search_start->GetChildWidgetInfo();
|
|
is_top_level_widget = FALSE;
|
|
}
|
|
|
|
widget_factory::CreateUniqueAppNames(pTemp, pTemp, search_start, is_top_level_widget); // handy name passed to create
|
|
|
|
// now make the widget visible:
|
|
if (parent_info)
|
|
{
|
|
pProject->AddWidgetToParent(parent_info, pTemp);
|
|
}
|
|
else
|
|
{
|
|
//selected parent folder in case paste wrong place.
|
|
GetProjectView()->FolderSelected(entry->widget_list[0].res_index, entry->widget_list[0].folder_name);
|
|
|
|
folder_info *parent_folder = pProject->FindFolderInfo(entry->widget_list[0].res_index, entry->widget_list[0].folder_name);
|
|
pProject->AddWidgetToFolder(parent_folder, pTemp);
|
|
}
|
|
|
|
if (!pTemp->id_name.IsEmpty())
|
|
{
|
|
display = pProject->GetDisplayIndex(pTemp);
|
|
pProject->AddToIdDictionary(display, ID_TYPE_WIDGET, pTemp->id_name);
|
|
}
|
|
GetProjectView()->CheckParentRefresh(parent_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_DELETE_FOLDER:
|
|
{
|
|
folder_info *folder = entry->widget_list[0].folder;
|
|
entry->widget_list[0].folder = NULL;
|
|
|
|
project_view *pview = GetProjectView();
|
|
|
|
if (pview)
|
|
{
|
|
pview->SelectDisplay(entry->widget_list[0].res_index);
|
|
pProject->AddFolderToDisplay(entry->widget_list[0].res_index, folder);
|
|
//widget_factory::GenerateWidgets(NULL, folder->GetFirstChildWidget());
|
|
pview->SelectDisplay(entry->widget_list[0].res_index);
|
|
|
|
if (folder->GetFirstChildWidget())
|
|
{
|
|
pview->WidgetSelected(folder->GetFirstChildWidget());
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_INSERT_FOLDER:
|
|
{
|
|
project_view *pview = GetProjectView();
|
|
if (pview)
|
|
{
|
|
undo_widget *test = &(entry->widget_list[0]);
|
|
folder_info *folder = pProject->FindFolderInfo(entry->widget_list[0].res_index, entry->widget_list[0].folder_name);
|
|
|
|
if (folder)
|
|
{
|
|
pview->DeleteFolder(folder);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_INSERT_TOP_LEVEL_WIDGETS:
|
|
{
|
|
project_view *pview = GetProjectView();
|
|
|
|
if (pview)
|
|
{
|
|
folder_info *folder = entry->widget_list[0].folder;
|
|
CArray<widget_info *> widget_list;
|
|
folder_info *parent_folder = pProject->FindFolderInfo(entry->widget_list[0].res_index, folder->folder_name);
|
|
widget_info *info = folder->GetFirstChildWidget();
|
|
|
|
pview->FolderSelected(parent_folder);
|
|
|
|
while (info)
|
|
{
|
|
widget_list.Add(info);
|
|
info = info->GetNextWidgetInfo();
|
|
}
|
|
|
|
for (int count = widget_list.GetCount() - 1; count >= 0; count--)
|
|
{
|
|
info = widget_list.GetAt(count);
|
|
info = pProject->FindWidgetInfo(parent_folder, info->app_name, FALSE);
|
|
pview->DeleteWidget(info);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_COLOR:
|
|
current_info = entry->widget_list[0].project_info;
|
|
resource_index = entry->widget_list[0].res_index;
|
|
provider = widget_factory::GetServiceProvider(current_info->basetype);
|
|
|
|
if (provider && current_info)
|
|
{
|
|
provider->AssignColor(current_info,
|
|
resource_index,
|
|
entry->widget_list[0].copy_info->color_id[resource_index]);
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
break;
|
|
|
|
case UNDO_TYPE_FONT:
|
|
current_info = entry->widget_list[0].project_info;
|
|
resource_index = entry->widget_list[0].res_index;
|
|
provider = widget_factory::GetServiceProvider(current_info->basetype);
|
|
|
|
if (provider && current_info)
|
|
{
|
|
provider->AssignFont(current_info,
|
|
resource_index, entry->widget_list[0].copy_info->font_id[resource_index]);
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
break;
|
|
|
|
case UNDO_TYPE_PIXELMAP:
|
|
current_info = entry->widget_list[0].project_info;
|
|
resource_index = entry->widget_list[0].res_index;
|
|
provider = widget_factory::GetServiceProvider(current_info->basetype);
|
|
|
|
if (provider && current_info)
|
|
{
|
|
provider->AssignPixelmap(current_info,
|
|
resource_index,
|
|
entry->widget_list[0].copy_info->pixelmap_id[resource_index]);
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
break;
|
|
|
|
case UNDO_TYPE_STRING:
|
|
current_info = entry->widget_list[0].project_info;
|
|
resource_index = entry->widget_list[0].res_index;
|
|
display = GetProjectView()->GetActiveDisplay();
|
|
|
|
provider = widget_factory::GetServiceProvider(current_info->basetype);
|
|
|
|
if (display >= 0 && current_info && provider)
|
|
{
|
|
provider->AssignText(current_info, 0,
|
|
entry->widget_list[0].copy_info->string_id[resource_index]);
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_NAMES:
|
|
current_info = entry->widget_list[0].project_info;
|
|
|
|
if (current_info)
|
|
{
|
|
current_info->app_name = entry->widget_list[0].copy_info->app_name;
|
|
current_info->callback_func = entry->widget_list[0].copy_info->callback_func;
|
|
|
|
if (current_info->id_name != entry->widget_list[0].copy_info->id_name)
|
|
{
|
|
display = pProject->GetDisplayIndex(current_info);
|
|
|
|
if (!current_info->id_name.IsEmpty() &&
|
|
pProject->mDisplays[display].screenflow)
|
|
{
|
|
pProject->mDisplays[display].screenflow->UpdateIdName(current_info, current_info->id_name, entry->widget_list[0].copy_info->id_name);
|
|
}
|
|
current_info->id_name = entry->widget_list[0].copy_info->id_name;
|
|
}
|
|
current_info->event_func = entry->widget_list[0].copy_info->event_func;
|
|
current_info->draw_func = entry->widget_list[0].copy_info->draw_func;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_USER_DATA:
|
|
current_info = entry->widget_list[0].project_info;
|
|
|
|
if (current_info)
|
|
{
|
|
current_info->user_data = entry->widget_list[0].copy_info->user_data;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_FOCUS:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
current_info->accepts_focus = entry->widget_list[0].copy_info->accepts_focus;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_CIRCULAR_GAUGE_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
current_info->ewi.gauge.info = entry->widget_list[0].copy_info->ewi.gauge.info;
|
|
current_info->ewi.gauge.start_angle = entry->widget_list[0].copy_info->ewi.gauge.start_angle;
|
|
|
|
if (current_info->widget)
|
|
{
|
|
GX_CIRCULAR_GAUGE *gauge = (GX_CIRCULAR_GAUGE *) current_info->widget;
|
|
gauge->gx_circular_gauge_info = current_info->ewi.gauge.info;
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_CHART_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
|
|
if (current_info)
|
|
{
|
|
current_info->ewi.line_chart_info = entry->widget_list[0].copy_info->ewi.line_chart_info;
|
|
|
|
if (current_info->widget)
|
|
{
|
|
GX_LINE_CHART *chart = (GX_LINE_CHART *) current_info->widget;
|
|
chart->gx_line_chart_info = current_info->ewi.line_chart_info;
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_NUMERIC_PROMPT_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
provider = widget_factory::GetServiceProvider(current_info->basetype);
|
|
|
|
((prompt_service_provider *)provider)->AssignNumericValue(current_info,
|
|
entry->widget_list[0].copy_info->ewi.numeric_prompt_value);
|
|
|
|
current_info->ewi.numeric_prompt_value = entry->widget_list[0].copy_info->ewi.numeric_prompt_value;
|
|
current_info->format_func = entry->widget_list[0].copy_info->format_func;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_SCROLL_WHEEL_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
|
|
if (current_info)
|
|
{
|
|
scroll_wheel_service_provider *provider = (scroll_wheel_service_provider *)widget_factory::GetServiceProvider(current_info->basetype);
|
|
if (provider)
|
|
{
|
|
provider->AssignScrollWheelInfo(current_info, &entry->widget_list[0].copy_info->ewi.scroll_wheel);
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_TEXT_SCROLL_WHEEL_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
|
|
if (current_info)
|
|
{
|
|
int normal_font = entry->widget_list[0].copy_info->font_id[NORMAL_FONT_INDEX];
|
|
int selected_font = entry->widget_list[0].copy_info->font_id[SELECTED_FONT_INDEX];
|
|
current_info->font_id[NORMAL_FONT_INDEX] = normal_font;
|
|
current_info->font_id[SELECTED_FONT_INDEX] = selected_font;
|
|
|
|
text_scroll_wheel_service_provider *provider = (text_scroll_wheel_service_provider *)widget_factory::GetServiceProvider(current_info->basetype);
|
|
|
|
if (provider)
|
|
{
|
|
provider->AssignFont(current_info, NORMAL_FONT_INDEX, normal_font);
|
|
provider->AssignFont(current_info, SELECTED_FONT_INDEX, selected_font);
|
|
}
|
|
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_STRING_SCROLL_WHEEL_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
string_scroll_wheel_service_provider *provider = (string_scroll_wheel_service_provider *)widget_factory::GetServiceProvider(current_info->basetype);
|
|
|
|
if (provider)
|
|
{
|
|
widget_info *entry_info = entry->widget_list[0].copy_info;
|
|
current_info->callback_func = entry_info->callback_func;
|
|
|
|
CArray<GX_RESOURCE_ID> list_array;
|
|
provider->InitStringIdListArray(entry_info->ewi.string_scroll_wheel.string_id_list, entry_info->ewi.string_scroll_wheel.base.total_rows, list_array);
|
|
if (current_info->ewi.string_scroll_wheel.string_id_list)
|
|
{
|
|
delete current_info->ewi.string_scroll_wheel.string_id_list;
|
|
current_info->ewi.string_scroll_wheel.string_id_list = NULL;
|
|
}
|
|
provider->CreateStringIdList(current_info, list_array);
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_NUMRIC_SCROLL_WHEEL_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
|
|
if (current_info)
|
|
{
|
|
numeric_scroll_wheel_info *wheel_info = &entry->widget_list[0].copy_info->ewi.numeric_scroll_wheel;
|
|
current_info->ewi.numeric_scroll_wheel = *wheel_info;
|
|
|
|
numeric_scroll_wheel_service_provider *provider = (numeric_scroll_wheel_service_provider *)widget_factory::GetServiceProvider(current_info->basetype);
|
|
target = current_info->widget;
|
|
|
|
if (provider)
|
|
{
|
|
provider->AssignScrollWheelInfo(current_info, &wheel_info->base);
|
|
provider->AssignValueRange(current_info, wheel_info->start_val, wheel_info->end_val);
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_MENU_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
|
|
if (current_info)
|
|
{
|
|
widget_info *copy = entry->widget_list[0].copy_info;
|
|
target = current_info->widget;
|
|
provider = widget_factory::GetServiceProvider(current_info->basetype);
|
|
|
|
((menu_service_provider *)provider)->AssignTextOffset(current_info,
|
|
copy->ewi.menu.text_x_offset, copy->ewi.menu.text_y_offset);
|
|
((menu_service_provider *)provider)->AssignStyle(current_info, copy->style);
|
|
current_info->ewi.menu.insert_as_menu_item = copy->ewi.menu.insert_as_menu_item;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_TREE_VIEW_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
target = current_info->widget;
|
|
|
|
if (current_info)
|
|
{
|
|
current_info->ewi.tree_view_indentation = entry->widget_list[0].copy_info->ewi.tree_view_indentation;
|
|
if (target)
|
|
{
|
|
gx_tree_view_indentation_set((GX_TREE_VIEW *)target, current_info->ewi.tree_view_indentation);
|
|
}
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_VISIBLE_AT_STARTUP:
|
|
current_info = entry->widget_list[0].project_info;
|
|
if (current_info)
|
|
{
|
|
current_info->visible_at_startup = entry->widget_list[0].copy_info->visible_at_startup;
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
case UNDO_TYPE_RADIAL_SLIDER_INFO:
|
|
current_info = entry->widget_list[0].project_info;
|
|
|
|
if (current_info)
|
|
{
|
|
provider = widget_factory::GetServiceProvider(current_info->basetype);
|
|
((radial_slider_service_provider *)provider)->SetRadialSliderInfo(current_info, &entry->widget_list[0].copy_info->ewi.radial_slider);
|
|
GetPropsWin()->WidgetWasModified(current_info);
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
ClearUndoRecord(entry);
|
|
FreeAddEntry();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void undo_manager::ClearUndoRecord(undo_record *record)
|
|
{
|
|
// delete the copied widget_info structures associate with this undo record:
|
|
int widget_list_size = record->widget_list.GetSize();
|
|
int widget_list_index;
|
|
|
|
for (widget_list_index = 0; widget_list_index < widget_list_size; widget_list_index++)
|
|
{
|
|
switch (record->type)
|
|
{
|
|
case UNDO_TYPE_INSERT_FOLDER:
|
|
case UNDO_TYPE_INSERT_TOP_LEVEL_WIDGETS:
|
|
case UNDO_TYPE_DELETE_FOLDER:
|
|
if (record->widget_list[widget_list_index].folder)
|
|
{
|
|
delete record->widget_list[widget_list_index].folder;
|
|
record->widget_list[widget_list_index].folder = NULL;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if (record->widget_list[widget_list_index].copy_info)
|
|
{
|
|
delete record->widget_list[widget_list_index].copy_info;
|
|
record->widget_list[widget_list_index].copy_info = NULL;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// now empty out the undo record widget list array
|
|
record->widget_list.RemoveAll();
|
|
record->type = 0;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
void undo_manager::Reset()
|
|
{
|
|
while(entries)
|
|
{
|
|
undo_record *entry = current;
|
|
current--;
|
|
if (current < undo_list)
|
|
{
|
|
current = tail;
|
|
}
|
|
ClearUndoRecord(entry);
|
|
entries--;
|
|
}
|
|
current = NULL;
|
|
}
|
|
|