[Aptitude-devel] 002-qt-stubs-review round 2 part 1
Piotr Galiszewski
piotr at galiszewski.pl
Mon Jul 19 20:50:20 UTC 2010
2010/7/19 Daniel Burrows <dburrows at debian.org>:
> First round of reviews on this. I didn't have time to go through the
> whole thing, but I think tabs_manager.cc is probably the most tricky
> part.
>
>> + /** \brief Slot invoked when a tab_widget is destroyed
>> + *
>> + * This slot removes all references of destroyed tab_widget from manager data
>> + */
>> + void tab_widget_destroyed();
>
> Would you mind adding periods at the end of these sentences? Also
> "of destroyed -> to the destroyed".
>
OK.
>> + void tabs_manager::tabs_manager_impl::update_packages_tabs_closability(tab_widget *tabs)
>> + {
>> + const boost::unordered_set<packages_tab *> &packages_tabs = active_packages_tabs[tabs];
>> +
>> + if(packages_tabs.size() == 1)
>> + tabs->set_tab_closable((*packages_tabs.begin()), false);
>> + else if(packages_tabs.size() == 2)
>> + {
>> + for(boost::unordered_set<packages_tab *>::const_iterator it =
>> + packages_tabs.begin(); it != packages_tabs.end(); ++it)
>> + tabs->set_tab_closable(*it, false);
>> + }
>> + }
>
> Should this be setting closable to "true" in the second case?
>
Yes
>> + void tabs_manager::tabs_manager_impl::activate_tab(tab *tab_to_activate)
>> + {
>> + main_window *window = qobject_cast<main_window *>(tab_to_activate->window());
>
> A general comment on this cast and the ones later on: would you mind
> if I wrote a post-patch that refactored this code so that the casts
> weren't necessary? I can do it without exposing the main_widget type
> to the various tabs or allowing them to invoke methods on it, which I
> think is what you're trying to avoid.
>
> I don't think this is a big enough deal to hold up the patch for it,
> or for you to divert your attention from new code.
>
Yes of course. I have not seen simpler way to do this, and this
qobject_cast should work (and they do not require RTTI ). I am willing
to learn better way to do it
>> + if(window->isMinimized())
>> + window->showNormal(); // unminimize
>> + window->raise();
>> + window->activateWindow();
>
> Normally the window should be unminimized (since the user is
> interacting with it) -- if we show a tab because of some background
> process, I think it would be better to display a notification instead
> of popping the window to the foreground. Also, if the user's window
> manager is configured to not raise on click, we're overriding their
> preferences here.
>
> In summary: is there a good reason to bring ourselves into the
> foreground whenever a tab is displayed? It seems impolite to me.
>
I have made an assumption, that tabs are only opened on user request.
Background processes shouldn't open new tabs. If they want to inform
user about something, they would use status_widget (now
active_background_jobs model) and add to widget "Show Details" button,
which will open new tab
I thought that if user decides to show some tabs, he want to use them
immediately. Of course I could be wrong and this code could be easy
fixed ;)
>> + if(changes_preview == NULL)
>> + {
>> + tab_widget *widget = window->get_tab_widget();
>> +
>> + connect_tab_widget_signals(widget);
>> +
>> + changes_preview = new changes_preview_tab();
>> + widget->addTab(changes_preview, _("Preview"));
>> + return;
>> + }
>
> I wonder if you could factor this into a private method to save some
> typing in the couple of places that follow this pattern. Does this go
> too far?
>
> /** \brief If the given pointer variable is not NULL, displays the
> * corresponding tab.
> *
> * Otherwise, instantiates a new instance of its type using the
> * default constructor and displays that instance with the given
> * title, storing the new instance in the given variable.
> */
> void create_or_display<TabType>(TabType &output, tab_widget *tabs, const char *name)
> {
> if(output == NULL)
> {
> connect_tab_widget_signals(tabs);
>
> output = new TabType;
> tabs->addTab(output, name);
> }
>
> activate_tab(output);
> }
>
OK.
>> + void tabs_manager::tabs_manager_impl::open_package_info_tab(QWidget *tab_context)
>> + {
>> + main_window *window = qobject_cast<main_window *>(tab_context->window());
>> + if(window == NULL)
>> + return;
>> + }
>
> Presumably this is being implemented in another patch?
>
Yes. It is implemented in 290af4033b7
>> + void tabs_manager::tabs_manager_impl::tab_deletion_requested(tab *tab_to_delete, bool force)
>> + {
>> + // when for example performing changes tab is closed, we do not destroy it but only hide
>> + if(tab_to_delete->get_policy() == tab::closing_policy_hide)
>> + {
>> + if(force)
>
> This logic is a little hairy.
>
> I almost would prefer a different signal/slot pair in this case, or
> maybe connecting to the destroyed signal on the tab itself when we
> attach it (in create_or_display<>).
>
OK. I said that this code is tricky ;) I thought about his and decided
that it would be better to avoid series of objects cast in order to
decide which variable should be cleared. Should I create new method
for each tab_type (it is possible that there will be more types in the
future)
>> + else
>> + tab_to_delete->hide();
>
> I wonder if it would be better to split this into two methods:
> request_destroy(), which decides whether to destroy or hide a tab, and
> tab_destroyed(), which removes backlinks to the tab when it's
> destroyed.
>
> Also, shouldn't the policy be checked in the !force case? And isn't
> it irrelevant in the force case (since the tab will be deleted
> anyway)? Or am I missing a subtlety of the logic?
>
> Seems to me that the logic should be:
>
> if(force || tab->get_policy() == closing_policy_destroy)
> {
> destroy_tab(); // Maybe only if not forced?
> tab_destroyed(tab); // Should be invoked by the destroyed signal?
> }
> else
> tab->hide();
>
Yes. It is more readable. Logic looks correct. I will change that.
Thanks for the review!
> Daniel
>
> _______________________________________________
> Aptitude-devel mailing list
> Aptitude-devel at lists.alioth.debian.org
> http://lists.alioth.debian.org/mailman/listinfo/aptitude-devel
>
--
Regards
Piotr Galiszewski
More information about the Aptitude-devel
mailing list