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

PR: Add a tab switcher dialog to the Editor #4302

Merged
merged 11 commits into from
Apr 20, 2017

Conversation

rlaverde
Copy link
Member

@rlaverde rlaverde commented Mar 28, 2017

Fixes #43


TODO:

  • Fix error when closing a file (stack history isn't updated)

tabs_mru

@rlaverde rlaverde added this to the v3.2 milestone Mar 28, 2017
@rlaverde rlaverde self-assigned this Mar 28, 2017
@rlaverde rlaverde requested review from ccordoba12 and goanpeca March 28, 2017 00:46

self.id_list = []
self.load_data()
size = CONF.get('main', 'completion/size')
Copy link
Member Author

Choose a reason for hiding this comment

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

I reused completion widget size widget, is that ok? should I add a setting? or leave a fixed size

Copy link
Member

@ccordoba12 ccordoba12 Mar 28, 2017

Choose a reason for hiding this comment

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

What if you use the same size and positioning of the file switcher?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think It's better in the center of the editor (I take inspiration from Kate), at the center you will have to move less the eyes than if it's at the top.

Or maybe something like 1/4(editor height) from top?

Copy link
Member

Choose a reason for hiding this comment

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

I think it's better to have both widgets (the file switcher and this one) placed at the same location to avoid breaking expectations from users (i.e. where to expect each dialog in the screen). Since the file switcher came first, this one has to follow it.

Copy link
Member

Choose a reason for hiding this comment

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

Besides, that's what VSCode also does, i.e. place both widgets at the same location.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, on the top is better for consistency. But we can evaluate the UX of all those dialogs in a separate issue

Handle "most recent used" tab behavior,
When ctrl is released and tab_switcher is visible, tab will be changed.
"""
if (event.key() == Qt.Key_Control and self.tabs_switcher is not None
Copy link
Member Author

Choose a reason for hiding this comment

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

This will break if It's set a shortcut without "Ctrl" (Although I think that will be a really rare use case)

should I add a validation when configuring the shortcut?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, please add the validation to prevent this possibility.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll add an option for also considering Alt, I think the shortcuts validation could be addressed in other Issue in a more general and reusable way

Copy link
Member

Choose a reason for hiding this comment

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

Agreed!

@@ -274,6 +274,70 @@ def breakpoints_changed(self):
self.save_breakpoints.emit(self.filename, repr(breakpoints))


class TabSwitcherWidget(QListWidget):
"""Show tabs in mru order and change between them."""
Copy link
Member

Choose a reason for hiding this comment

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

one space here


self.id_list = []
self.load_data()
size = CONF.get('main', 'completion/size')
Copy link
Member

Choose a reason for hiding this comment

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

Yes, on the top is better for consistency. But we can evaluate the UX of all those dialogs in a separate issue

for index in self.stack_history[::-1]:
text = self.tabs.tabText(self.id_list.index(index))
item = QListWidgetItem(ima.icon('FileIcon'), text)
self.addItem(item)
Copy link
Member

Choose a reason for hiding this comment

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

As discussed @rlaverde lets move all the stack history logic into a separate class (StackHistory)

# stack history is in inverse order
id_ = self.stack_history[-(self.currentRow()+1)]

index = self.id_list.index(id_)
Copy link
Member

Choose a reason for hiding this comment

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

Lets remove this logic and put inside the StackHistory widget

@ccordoba12
Copy link
Member

@rlaverde, please make my suggested changes so I can merge this one.

@rlaverde
Copy link
Member Author

@rlaverde, please make my suggested changes so I can merge this one.

I already moved it to the top, and the shortcuts validation should be address in a more general way in another PR

spectacle z15337

@@ -274,6 +275,111 @@ def breakpoints_changed(self):
self.save_breakpoints.emit(self.filename, repr(breakpoints))


class StackHistory(MutableSequence):
"""Handles editor stack history"""
Copy link
Member

Choose a reason for hiding this comment

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

period at the end :-), remeber docstrings are sentences

if _id not in self.id_list:
self.history.remove(_id)

def __len__(self): return len(self.history)
Copy link
Member

Choose a reason for hiding this comment

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

split in 2 lines

def __getitem__(self, i):
return self.id_list.index(self.history[i])

def __delitem__(self, i): del self.history[i]
Copy link
Member

Choose a reason for hiding this comment

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

same here

return str(list(self))

def insert(self, i, v):
_id = id(self.editor.tabs.widget(v))
Copy link
Member

Choose a reason for hiding this comment

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

docstring :-p ?

_id = id(self.editor.tabs.widget(v))
self.history.insert(i, _id)

def remove(self, index):
Copy link
Member

Choose a reason for hiding this comment

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

docstring?

row = (self.currentRow() + steps) % self.count()
self.setCurrentRow(row)

def set_dialog_position(self):
Copy link
Member

Choose a reason for hiding this comment

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

Is there a way we can generalize this method, so that it can be used by the fileswitcher and this one, and any other pop up dialog we use?

Maybe have a base PopUpDialog class that handles this based on the parent?

Copy link
Member Author

@rlaverde rlaverde Apr 17, 2017

Choose a reason for hiding this comment

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

hmm yes, maybe reusing some of the Modes logic introduced with editor panels

class PopUpDialog(QWidget):
    ...
    def set_dialog_position(self, top, left):

top and left will be numbers from 0 to 1 than indicate the position i.e.:

(0.5, 0.5) will be the center
(0, 0.5) will be the top-center

Copy link
Member

Choose a reason for hiding this comment

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

Yeah something like that would be vey useful... probably out of the scope of this PR, but you could do it afterwards? please create an issue for it :-)

@ccordoba12
Copy link
Member

@rlaverde, please merge with 3.x to fix the error in CircleCI.

@@ -274,6 +275,119 @@ def breakpoints_changed(self):
self.save_breakpoints.emit(self.filename, repr(breakpoints))


class StackHistory(MutableSequence):
Copy link
Member

Choose a reason for hiding this comment

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

Please move this to spyder/utils/editor.py

Copy link
Member

Choose a reason for hiding this comment

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

Sorry, don't worry about it. We simply need to split this file in multiple files because it's huge!!

But let's do that in master (I'll do it).

Copy link
Member

Choose a reason for hiding this comment

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

I mean, I'll do it after we release 3.2

@ccordoba12
Copy link
Member

I found an annoying behavior: some files get an ampersand in their name:

seleccion_002

@rlaverde, please fix that and then I'll merge ;-)

@rlaverde
Copy link
Member Author

@ccordoba12 I'm not able to reproduce that behavior, any hint of what is causing it?

@ccordoba12
Copy link
Member

It happens in some versions of Qt5, I think. Don't worry, it was a simple fix and I made it myself ;-)

@ccordoba12 ccordoba12 changed the title PR: Mru editor tabs PR: Add a tab switcher dialog to the Editor Apr 20, 2017
@ccordoba12 ccordoba12 merged commit 4acf3b5 into spyder-ide:3.x Apr 20, 2017
ccordoba12 added a commit that referenced this pull request Apr 20, 2017
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.

3 participants