Undo

Undo

Postby hag » Tue Jan 12, 2010 11:34 pm

I'm thinking on creating an undo in the program. I read the thread on the subject.
Has anyone created an undo and could share the code.

Users get frustrated if the enter data and then want to go back and change to the original and can't remember what the original was.
Especially guys like me...OLD. :)
Thank you
Harvey
hag
 
Posts: 598
Joined: Tue Apr 15, 2008 4:51 pm
Location: LOs Angeles, California

Re: Undo

Postby James Bott » Wed Jan 13, 2010 7:56 pm

Harvey,

Harvey,

I have not done this but I think it is a good idea.

Here is an idea for a single level undo. It requires that you are using a buffer to edit a record's data. Just before you save the buffer to the record, append a new record, save the data from the existing record to the new record, then delete the new record. Finally, save the users changes to the original record.

Now if the user wants to undo the changes, you can seek for a deleted record with the same ID, if found then restore the data from the deleted record to the original record. You might also want to add an "undo" flag field to the file so you can enable/disable the Undo button based on this flag.

Of course, the downside of this technique is that you will be creating a lot of deleted records which will slow down performance. Theoretically you could end up with one deleted record for every good record in the file.

Another idea is instead of using deleted records, you put the old data into another "undo" file with the same file structure. This will require an additional file for each existing file.

If you are using database objects all this code could be built into a database subclass then it would work automatically with every data file.

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Undo

Postby hag » Wed Jan 13, 2010 9:24 pm

James:
Copy the original file to a new file may be better. When they exit the diaolog it can erase the new file and recopy the existing file in its place.
So the activity only occurs when the undo button is pressed....interesting. Grab the data from the new file place into the get of the original...

any thoughts
Thank you
Harvey
hag
 
Posts: 598
Joined: Tue Apr 15, 2008 4:51 pm
Location: LOs Angeles, California

Re: Undo

Postby James Bott » Wed Jan 13, 2010 10:11 pm

Harvey,

Copy the original file to a new file may be better. When they exit the dialog it can erase the new file and recopy the existing file in its place.

So the activity only occurs when the undo button is pressed....interesting. Grab the data from the new file place into the get of the original...

OK, it sounds like you are not using an editing buffer but rather you are editing the fields of the record directly. If so, then when a user edits a field, then exits it, the data is automatically written to the disk. In this case the only way you could have a Cancel button on the dialog is to already have stored the original data before presenting the dialog.

The better way is to copy all the fields into a buffer array and then use this buffer to edit in the dialog. Then the Cancel button just closes the dialog with no further action. The OK button would save the buffer to the disk.

I would not call either of the above an "undo" but rather just a cancel. If the user made changes then decided to not save them, they just press the Cancel button. They can then reload the original data by opening the dialog again.

Conversly, the Undo I was describing in my previous message would enable a user to undo the last changes made to a record at any time until another edit and save was made to that record--this could be a minute, day, week, month later.

Forgive me if you already know this, but this an important point regarding user interface design. All modal dialogs should have two terminating buttons, OK and Cancel. OK saves and closes the dialog, and Cancel just closes the dialog. This is why you really must use a buffer to edit data.

Perhaps this answers your original question--maybe you just didn't have a Cancel?

You can't really put an Undo button on an edit dialog, because it would unclear as to what it does. If you opened the dialog then immediately pressed Undo, you would get the previous data (before the last edit and save). But if you edited the data, then pressed Undo, you would still get the previous data, not the current data in the record before the edit. Very confusing.

Perhaps you can clarify whether you wanted a Cancel or an Undo?

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Undo

Postby hag » Thu Jan 14, 2010 12:24 am

James thanks for the info. Do you have any code on the how to code the buffer array...never did that before...
Cancel is the idea not the undo.
Thanks again for your helo
Thank you
Harvey
hag
 
Posts: 598
Joined: Tue Apr 15, 2008 4:51 pm
Location: LOs Angeles, California

Re: Undo

Postby StefanHaupt » Thu Jan 14, 2010 8:50 am

Harvey,

you can use a database object like TDatabase or similar (James is selling a good class), that has buffering technique or you define local variables to buffer the input data.

Load all data from the dbf in an array and let the user edit the elements of this array. If the user clicks ok, save all data in the dbf, if the user clicks cancel, nothing happened to the original data. Thats it.

If you want a real undo function, you have to implement a database transaction system with transaction rollback. But this is very complex and difficult to implement. Here you get more informations about this system.
http://en.wikipedia.org/wiki/Database_transaction
kind regards
Stefan
StefanHaupt
 
Posts: 824
Joined: Thu Oct 13, 2005 7:39 am
Location: Germany

Re: Undo

Postby James Bott » Thu Jan 14, 2010 6:03 pm

Harvey,

Many programmers wrote a function for each database to put the data into variables and to save the data from the variables into the record.

cName:= field->name

redefine get var cName

A better and generic way is to use Scatter() and Gather() functions. Scatter puts data from all the fields of a record into an array and Gather puts all the data from the array into the record. The same Scatter and Gather routines can be used with any data file. However, a disadvantage of this method is that you have to use an array reference which is hard to understand later. E.G.:

aBuffer:= scatter()

redefine get var aBuffer[3]

A much better approach is to use a database object. Database objects are also generic and can be used with any database. Database objects also have the unique ability to use the fieldnames as variables which actually refer to the buffer location. So you can do:

redefine get var oCustomer:name

This is actually referring to oCustomer:aBuffer[3] but it is so much easier to work with as a programmer. The term aBuffer[3] is very cryptic while oCustomer:name is very clear.

Also, a database class has built in functions to save the data.

oCustomer:save()

By sub classing a database class you can build in any needed functions specific to that database, such as editing, etc. So then you can do:

oCustomer:= TCustomer():new() // initialize the object
oCustomer:seek("1234") // lookup customer 1234
oCustomer;edit() // edit (with save or cancel)

There are way too many advantages of objects to list here. I suggest that you go to my web site:

http://www.gointellitech.com/program.htm

And read the articles on OOP programming. These will give you more information, although they only cover the tip of the iceberg of the power of OOP databases.

Regards,
James
User avatar
James Bott
 
Posts: 4840
Joined: Fri Nov 18, 2005 4:52 pm
Location: San Diego, California, USA

Re: Undo

Postby hag » Thu Jan 14, 2010 6:20 pm

James thans very much for the info. will check it all out. And do some learning.
Thank you
Harvey
hag
 
Posts: 598
Joined: Tue Apr 15, 2008 4:51 pm
Location: LOs Angeles, California


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 82 guests