Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Save As Popup #327

Closed

Conversation

iamutkarshtiwari
Copy link
Contributor

@iamutkarshtiwari iamutkarshtiwari commented Jul 4, 2016

'Save As' popup added which appears on activity close. It allows user to provide instance name to the user. - https://www.youtube.com/watch?v=xcvBH7zzFBo
desktop-animation

@icarito
Copy link
Contributor

icarito commented Jul 8, 2016

Allright I just tested this feature.
My comments:

  • Text entry is way too small.
  • Text entry does not offer current object title for changing
  • There should be a way to cancel the alert.
  • It should not be possible to enter an empty name.
  • Save as/Discard button is ambiguous (and it takes a lot of time to act for some reason).
  • "Same name" warning is ambiguous. The same name object is the object itself.
  • Overwrite action should happen if user insists with stop button.

Some serious thought needs to go into this interaction, as it is a very important one.

We must take into consideration that Sugar already saves the object if the user changed activities or views before, even if it was the first instance (of object creation).

Perhaps the alert could work this way: It could have default actions for each question. Pressing Stop button again will simply take default actions (I instinctively tried this, i.e. telling the system I really want to stop, don't ask me questions).

Take this as an idea:

  • Confirm saving as: [Object title] - _save_, cancel
    • If a user changes the object title, the buttons could switch to _rename_, save copy, cancel
    • In addition, a menu button could be added for the following secondary actions: discard, save to...*

@samdroid-apps
Copy link
Contributor

I agree with @icarito about the issues with the current implementation.

Here are a few of my takes on it:

  • What does the disregard button do? Is it suppose to delete the entry? Isn't that what was discussed on the mailing list? When I tested, the disregard button just did nothing and closed the activity :(
  • Disregard is such a fancy word. Could we use more direct words like "save" and "delete" rather than "confirm" and "disregard"?
  • Can it be a popwindow? Then we get the full width of the screen, and you can put the full journal details view there - making it easy to add a description. Using the full details view (rather than making a new view) is nice from a consistency perspective - it is a view that users are familiar with.
  • Can the options be "save" and "delete". Save will save the journal object, with whatever the title and metadata the user has set.

@iamutkarshtiwari
Copy link
Contributor Author

@icarito @samdroid-apps I have fixed some of the issues. Please test the newest commit.

@samdroid-apps When the user selects the discard option, the activity data (for eg. text in case of Write activity) doesn't get saved on close. Only the object entry appears in datastore for statistical purpose but not the activity data.

@samdroid-apps
Copy link
Contributor

@samdroid-apps When the user selects the discard option, the activity data (for eg. text in case of Write activity) doesn't get saved on close. Only the object entry appears in datastore for statistical purpose but not the activity data.

I thought that one of the main reasons to add this change was the delete journal clutter by letting the user delete entries more quickly.

What is the use case of saving the metadata but not the entry data?

@iamutkarshtiwari
Copy link
Contributor Author

iamutkarshtiwari commented Jul 10, 2016

@samdroid-apps Mr. Anderson asked me to build it that way.

@icarito
Copy link
Contributor

icarito commented Jul 10, 2016

"When the user selects the discard option, the activity data (for eg. text in case of Write activity) doesn't get saved on close."

But it's already saved before close! You mean it gets deleted?

@iamutkarshtiwari
Copy link
Contributor Author

iamutkarshtiwari commented Jul 10, 2016

icarito Yes. When the activity is open, a duplicate copy is created. If the user selects to 'discard' the data, the duplicate copy is deleted without saving the data. And if the user selects to save the data, the duplicate copy is retained by the new name provided by the user in the text entry and the data is saved to that dupicate instance without overwriting the original instance.

@icarito
Copy link
Contributor

icarito commented Jul 10, 2016

Here's comments by Tony on private thread:
"Consider:

You open Paint and create a red X and save it as x. Then you open x and change the image to a blue O. You want to save it as O, so you change the name.
Now try to open X. It is gone.

Suppose you open Paint to show someone how to select a brush and give it a color. You scribble something. When asked for a name, you click on 'quit' because there is not need to save this image.

The alert should be simple:

Please give your project a title. [Untitled] Save Quit

The default title is 'Untitled' not 'Write.activity'. If the user clicks save with the title unchanged, it is ignored. If the user clicks on Quit, the activity quits (with no save of the Document - but the metadata is saved). if the user resumes an activity the alert shows:

Change the title to save as a new document [X] Save Quit

The user changes the title [X] to [Y]. Then Save saves Y to the Journal and X is still in the Journal as well. If the user doesn't change and clicks Save, the X object is deleted and the new X version is saved. if the user clicks on Quit - the document is not saved, the original X document is in the Journal
and the activity quits."

I can't find Tony's github user to mantion him.

My comment is:

Clicking Stop, and then "Quit" does not tell me as a user that my work will be deleted (this is what you seem to be suggesting).

"Change the title to save as a new document": seems long to me. Also it's not always a document (e.g. Browse session).

if the user clicks on Quit - the document is not saved, the original X document is in the Journal
and the activity quits." - but the document may already have been saved (on view change, for instance).

@icarito
Copy link
Contributor

icarito commented Jul 10, 2016

"If the user selects to 'discard' the data, the duplicate copy is deleted without saving the data. "

This is the part that I don't understand, Sugar will save the data on every view change. So you mean it will delete the duplicate (that may have been previously already saved).

@icarito
Copy link
Contributor

icarito commented Jul 10, 2016

I tried the new version and it works much better. I'm not convinced by the text in the alert. You seem to imply two objects can't have the same name, but they can. Objects are identified by a unique hash id in the journal.

Save as / Quit is a strange button label.

One of Sugar's design principles is simplicity.


return True
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After your patch I can't close ImageViewer or Chat. This is likely why.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason 'ImageViewer' and 'Chat' didn't close is because these two activities override the 'can_close()' funtion of 'activitly.py' which is responsible to display my alert.

I have figured out a solution and commit a new tweak for the same.

@icarito
Copy link
Contributor

icarito commented Jul 10, 2016

Currently my main concern from a UI pov is that choosing "Stop" and then "Quit" will result in the user discarding his work. This is not intuitive to me.

@icarito
Copy link
Contributor

icarito commented Jul 10, 2016

"Mr. Anderson asked me to build it that way." - That's a bad reason, you should believe in what you do! There are better ways to collect metadata than to clutter the journal. This has been a bad use of it.

@iamutkarshtiwari
Copy link
Contributor Author

iamutkarshtiwari commented Jul 10, 2016

@icarito I agree. But the 'SaveAs' feature was proposed by Mr. Anderson and I'll have to abide by the requirements he specifies.

@tony37
Copy link

tony37 commented Jul 10, 2016

This thread would be a lot more useful if you took the time to understand Sugar as well as this PR.

"Mr. Anderson asked me to build it that way." - That's a bad reason, you should believe in what you do! There are better ways to collect metadata than to clutter the journal. This has been a bad use of it.

This is crazy. I am mentoring this feature. Granted Utkarsh can proceed as he feels best but we don't need to involve him in these quibbles.

Any Journal object consists of two elements: a metadata file and an (optional) data file. The data file normally conforms to a meta_type and is from the point of view of the user, a document.

The metadata needs to be saved in every case. The document only if the user chooses. Note: that any user is free to delete any Journal object at any time without getting permission from anyone.

@tony37
Copy link

tony37 commented Jul 10, 2016

Currently my main concern from a UI pov is that choosing "Stop" and then "Quit" will result in the user discarding his work. This is not intuitive to me.

This is why you should discuss the issue. The alert offers two options: save and quit. The alert appears because the user has clicked on 'stop' to request terminating the activity.

The current activity.py does indeed save the document without action by the user (we used to have 'keep' which gave the user the option to save and then continue. This was removed.

However, the implementation is flawed. The jobject used by activity.py in case of resume is the original jobject_id. This means, unknown to the user, he is making irretrievable changes to his document. Hence,
the scenario quoted by Utkarsh.

Utkarsh makes a copy of the original jobject and this is what is changed. This enables the save option after a name change, to keep both the original document and the new instance as a user should expect.

@tony37
Copy link

tony37 commented Jul 10, 2016

When choosing to overwrite do you delete the previous copy or do you always keep a copy?

If you take the trouble to read the description of the feature, you will know that if the user resumes an activity with a title and chooses not to change the title, then the modified document is saved and the original is deleted. This is exactly what happens now. If the user changes the name, then the new document is saved under its new name and the unmodified original is also in the Journal.

@tony37
Copy link

tony37 commented Jul 10, 2016

If you have cosmetic changes make them on another PR. It makes it hard to see what you changed

Who decides what changes are important and which are 'cosmetic'. This is the PR.

@tony37
Copy link

tony37 commented Jul 10, 2016

The reason 'ImageViewer' and 'Chat' didn't close is because these two activities override the 'can_close()' funtion of 'activitly.py' which is responsible to display my alert.

I have figured out a solution and commit a new tweak for the same.

Utkarsh: 'can_close' is a function which can be supplied by the activity. In that case, the copy in activity.py is not called. What you need to do is post the alert after can_close. This way from the user's view, the alert will be seen before close. When the user responds to the alert, the activity can close.

@tony37
Copy link

tony37 commented Jul 10, 2016

I tried the new version and it works much better. I'm not convinced by the text in the alert. You seem to imply two objects can't have the same name, but they can. Objects are identified by a unique hash id in the journal.

From the user perspective, documents should have a unique name. Granted in standard software, different files may have the same name in different directories. We only have the Journal.

Save as / Quit is a strange button label.

The button options should be 'save' and 'quit'. The text on the button may differ from the start new case when the title is 'Untitled' or 'Write.activity' - perhaps: Please give a name to your project. In the resume case, the text should refer to the option to save (no change) or save as (change). Perhaps, Change the name of your project to save a new document.

One of Sugar's design principles is simplicity.

@iamutkarshtiwari
Copy link
Contributor Author

iamutkarshtiwari commented Jul 10, 2016

@icarito @tony37 The 'Chat' and 'ImageViewer' deadlock on close issue is resolved in the latest commit. Please test it and share your suggestions

@tony37 We all together can workout this feature's design and functionality :) After all, our contributions are going to benefit our Sugar community.

@icarito
Copy link
Contributor

icarito commented Jul 15, 2016

As promised here's a screenshot of Sugar 0.92's "save as" dialog:
captura de pantalla de 2016-07-14 21-33-17

As per our meeting today I think Martin Dengler's proposal to land the user in the Journal after quitting with focus on Object Title would be a good solution.

@icarito
Copy link
Contributor

icarito commented Jul 15, 2016

Correction screenshot is from Sugar 0.90.2

@tony37
Copy link

tony37 commented Jul 15, 2016

As you might expect, I totally disagree.

First, by that time the damage has been done. Either the 'save as'
option has been taken with a new object created or the 'resumed'
document has been overwritten - as at present.

This feature has two objectives:

 1 - require Journal items to have a name supplied by user
 2 - enable the user to choose whether to save the object as a new 

one or to simply save the modified document.

This proposal addresses neither objective.

You are not going to change your point of view so the only solution I
can see is to provide a gsetting option so that users and deployments
can decide on how they want this to work.

Re: the screenshot. Help me - as I remember this dialog was modal and
required an entry in the description area - leaving the title as 'Write
activity' was ok.
This was to implement Walter's desire that the description serve as the
message does in git.

Tony

On 07/15/2016 04:36 AM, Sebastian Silva wrote:

As promised here's a screenshot of Sugar 0.92's "save as" dialog:
captura de pantalla de 2016-07-14 21-33-17
https://cloud.githubusercontent.com/assets/199755/16861909/cc262c7c-4a0a-11e6-8ebd-88c4a5157595.png

As per our meeting today I think Martin Dengler's proposal to land the
user in the Journal after quitting with focus on Object Title would be
a good solution.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#327 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAULkhTztLdY3u833M4V3dte_sV3q3RMks5qVvISgaJpZM4JEg63.

@tony37
Copy link

tony37 commented Jul 15, 2016 via email

@samdroid-apps
Copy link
Contributor

This feature has two objectives:

1 - require Journal items to have a name supplied by user
2 - enable the user to choose whether to save the object as a new

one or to simply save the modified document.

This proposal addresses neither objective.

I think that user testing is invaluable there. But I think that @icarito very clearly addresses item number 1 - the proposal literally puts the user in front of a screen dedicated to managing activity metadata.

For addressing proposal 2, did you want to make sugarlabs/sugar#699 false by default? I would support making that false by default, now that I understand the rational.

But seriously, if you do some user testing and write up some scenarios for the users, I can also find some other people and carry out the same tests too! More testing the better!

@tony37
Copy link

tony37 commented Jul 16, 2016

Sam

I don't understand you. #327 satisfies both objectives.

"The proposal literally puts the user in front of a screen dedicated to
managing activity metadata." Clearly, this must be something completely
different from $327 or #699. Perhaps you could describe this proposal in
more detail. Does it have a PR? Could you be referring to Sebastian's
suggestion to switch the user to the Journal view on close?

#699 is a completely different feature. Yes, it should not change Sugar
unless the user or deployment chooses. While I many deployments have
asked for this capability, it is not consistent with Walter's decision
to provide resume from the home view as the default behavior for Sugar.

I have no idea how to test the first item you describe - it has nothing
to do with either #327 or #699. I have had 'resume' implemented at least
5 schools with nearly 500 XOs operating Sugar. I am not sure what more
user experience is needed. Remember, this behavior was the way Sugar
worked through its intial releases and may, for all we know, be the way
it still works on the majority of operational XOs.

User tests on #327 seem unnecessary, We all use it everyday on Linux,
Windows, or Mac. My most common use is on nano where when I close a
buffer, I must give it a name. If it has a name, I am given the
opportunity to change it. Virtually all document-handling applications
that I am aware of work this way.

Tony

On 07/15/2016 11:54 PM, Sam wrote:

This feature has two objectives:

|1 - require Journal items to have a name supplied by user 2 -
enable the user to choose whether to save the object as a new |

one or to simply save the modified document.

This proposal addresses neither objective.

I think that user testing is invaluable there. But I think that
@icarito https://github.com/icarito very clearly addresses item
number 1 - the proposal literally puts the user in front of a screen
dedicated to managing activity metadata.

For addressing proposal 2, did you want to make sugarlabs/sugar#699
sugarlabs/sugar#699 false by default? I
would support making that false by default, now that I understand the
rational.

But seriously, if you do some user testing and write up some scenarios
for the users, I can also find some other people and carry out the
same tests too! More testing the better!


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#327 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAULkogxGP2httu5vM9EFwM_XFC_9KgPks5qWAGagaJpZM4JEg63.

@iamutkarshtiwari
Copy link
Contributor Author

@quozl I'll update sugarlabs/sugar-toolkit#4 accordingly after this PR is completed

@quozl
Copy link
Contributor

quozl commented May 2, 2017

putting the call to get_focus inside a GObject.idle_add call.

No, that's wrong, and may create a race condition. It may work most of the time, but sometimes it will fail, if the graphics device is momentarily delayed, and especially on multicore systems where the GTK+ program may move to idle processing before another core has finished graphics device update. It is better to connect to the realize or map signal, and that's what the documentation says to do.

  • Also, your 91d2f74 is ambiguous; the idle function is called repeatedly until it returns False, and grab_focus is not specified to return False. That it does seem to is somewhat accidental.

@quozl
Copy link
Contributor

quozl commented May 2, 2017

Also in 97c7836 when save-as is enabled,

  • there is no busy cursor during close; this is a regression, which you can fix by making the cursor busy again when the alert button 'Save' is pressed,
  • the _closing signal is emitted early, which causes a save_title in widgets.py to run, but is that necessary?
  • the activity can_close is called only once, yet the learner can continue to interact with the activity (which I've just tested again) and may invalidate can_close; this is a regression on the meaning of can_close, which you can fix by either making the alert modal (which would be unfortunate), or calling can_close again sometime later.

For your testing, among the activities that implement can_close are Browse, Chat, Develop, FractionBounce, GetBooks, ImageViewer, Jukebox, Maze, Physics, Read, and TurtleBlocks.

I'm having trouble following the new logic path in close; it seem convoluted to call _alert_confirmation only for that method to find out that the title has been changed, then set a flag _pre_naming which is tested again later in close.

@tony37
Copy link

tony37 commented May 2, 2017 via email

@iamutkarshtiwari
Copy link
Contributor Author

iamutkarshtiwari commented May 2, 2017

Also in 97c7836 when save-as is enabled,

there is no busy cursor during close; this is a regression, which you can fix by making the cursor busy again when the alert button 'Save' is pressed,

Fixed

the _closing signal is emitted early, which causes a save_title in widgets.py to run, but is that necessary?

_closing signal is now emitted only when the user takes an actions (Save/Don't save) from alert

the activity can_close is called only once, yet the learner can continue to interact with the activity (which I've just tested again) and may invalidate can_close; this is a regression on the meaning of can_close, which you can fix by either making the alert modal (which would be unfortunate), or calling can_close again sometime later.

After checking I found out that the 'can_close()' is called everytime 'close()' functions executes i.e. everytime 'Stop' button is pressed.

For your testing, among the activities that implement can_close are Browse, Chat, Develop, FractionBounce, GetBooks, ImageViewer, Jukebox, Maze, Physics, Read, and TurtleBlocks.

I'm having trouble following the new logic path in close; it seem convoluted to call _alert_confirmation only for that method to find out that the title has been changed, then set a flag _pre_naming which is tested again later in close.

_alert_confirmation code moved inside 'close()' to remove ambiguity

1) Busy cursor after Save enabled
2) _alert_confirmation removed
3) Entry focus grab on 'realize' added
@quozl
Copy link
Contributor

quozl commented May 3, 2017

@iamutkarshtiwari, thanks. I've tested all day and found many problems. It was easier to fix the problems and rework the code than go into detail explaining what I've fixed. I've pushed two branches:

Please consider;

  • do a code review of the overall difference from master at cddaf79,
  • fetch, checkout and test either of my branches,
  • if you agree with them, or they aren't too far from what you want, cherry-pick into your branch my four patches on top of yours, 751c178, 011ccff, 36b7f45 and 2cb0b33,
  • look at the FIXME markers I've added; in particular the Write activity doesn't seem to work with the focus grab, and there are some minor private member accesses in activity/alerts.py.

My own TODO list;

  • test with an activity shared across three or more computers,
  • test with an activity that calls copy(), such as Pippy export,
  • test with activities that call close() explicitly, such as Browse, ImageViewer, Pippy, and Terminal,
  • test with a forced keep error,
  • look deeper into the Write activity focus grab failure,
  • see if it is possible to avoid self._is_resumed.

quozl added 4 commits May 3, 2017 20:10
- Gtk.EventBox is not needed,

- show_all is used, so show is not needed,

- documented some accesses to private members of an instance,
- move Gio.Settings access to sugar3.profile.get_save_as,

- remove several instance members; flags, and the alert,

- remove key-press-event and use accelerators instead,

- use reference counted busy cursor implementation from home view,

- register stop buttons and make them insensitive during stop alert,

- reword the stop alert, add cancel button.
@quozl
Copy link
Contributor

quozl commented May 4, 2017

Thanks for taking my changes, you've encouraged me to look further at the problems.

I've pushed 11 patches to my branch, please review and cherry-pick them;

Progress was;

  • use datastore.copy() so that the clone will have all the statistical metadata of the original object, otherwise metadata was being lost,
  • add context sensitive tooltips and button labels, because the meaning of the buttons changes slightly depending on the context,
  • fix several problems when used with shared activities, like resuming a shared activity didn't make it shared again, and every participant underwent the stop alert even if the name had been changed,
  • fixed the minor private member accesses in alerts.py by moving code into alert.py; alerts now support a Gtk.Entry,

Also tested with shared activities; in particular Maze and Chat.

quozl and others added 12 commits May 10, 2017 19:11
- add tooltips to the buttons, for mouse-over explanations in context,

- change the button labels and tooltip according to the context;
  resumed or new activity, unchanged or changed name.
- handle.object_id was being tested twice, so move conditional code into
  the first test.

- tested with local activities only.
- it is the original title and does not always refer to the clone.
- joining a shared instance will change the title from the default,
  which would force every participant to undergo the stop alert,

- so set the title again after it has finished changing.
- an Alert may now have a Gtk.Entry between the title and the buttons.
- but in this case, use the current jobject title
- move the copy to after the nested event loop so that metadata updates
  resulting from the start of sharing are not lost,

- use datastore.copy to copy all metadata rather than initialise a new
  journal object, thus simplifying code and preserving statistics,

- rename _jobject_clone to _jobject_old as it isn't really the clone,
  but rather the old object before it was cloned.

Tested with shared activities; Maze and Chat.
@quozl
Copy link
Contributor

quozl commented May 16, 2017

@iamutkarshtiwari, thanks for taking my changes; have you reproduced the problem with focus on the Write activity with these patches applied? Any ideas on what causes it? I've not seen any other activity affected. I'm inclined to let it pass.

@quozl
Copy link
Contributor

quozl commented Jun 1, 2017

Rebased and merged as 926a262, 83697d2, 286387b, b1d1129, 6bcd664, 3a574ae, and ba6993d.

@quozl quozl closed this Jun 1, 2017
@tony37
Copy link

tony37 commented Jun 1, 2017 via email

@iamutkarshtiwari
Copy link
Contributor Author

@tony37 @quozl Thank you for your support and guidance. I am happy that it got merged! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants