[Aptitude-devel] Review of 298143
Daniel Burrows
dburrows at debian.org
Tue Aug 3 18:29:29 UTC 2010
> + package_filters_model::package_filters_model(QObject *parent)
Pass the package_filters_manager here and save it in a member, so
other implementations can be substituted. (you can provide a
convenience constructor that uses get_instance() as usual)
> + : QAbstractListModel(parent)
> + {
> + package_filters_manager::get_instance()->connect_filter_about_to_be_added(
> + sigc::mem_fun(*this, &package_filters_model::filter_about_to_be_added));
Wrapping doesn't match the usual style here. You can save yourself
a lot of horizontal space by saving a pointer to the manager (but see
my note above):
package_filters_manager * const manager = package_filters_manager::get_instance();
Also, you can create slots on separate lines from the connect() calls...
sigc::slot<void, package_filter_definition_ptr> added_slot =
sigc::mem_fun(*this, &package_filters_model::filter_added);
manager->connect_filter_added(added_slot);
...although TBH, I would probably just write some long lines instead.
> + QVariant package_filters_model::headerData(int section, Qt::Orientation orientation, int role) const
> + {
> + if (role != Qt::DisplayRole)
> + return QVariant();
> +
> + if (orientation == Qt::Horizontal)
> + return QString("Column %1").arg(section);
Should this output something like "Filter" instead?
> + /** \brief Class responsible for propagating package filers information
"propagating package filter information to package filter views".
> + * to package filters views
> + */
> + class package_filters_model : public QAbstractListModel
> + {
> + Q_OBJECT
> +
> + /** \brief Method called just before filter is added to manager.
> + *
> + * This method starts adding of the given filter to view
"just before a filter is added to the manager", "adding the given
filter to the view". Also, pass by const reference.
> + */
> + void filter_about_to_be_added(package_filter_definition_ptr filter);
> +
> + /** \brief Method called just after filter is added to manager.
> + *
> + * This method ends adding of the given filter to view
Ditto
> + */
> + void filter_added(package_filter_definition_ptr filter);
> +
> + /** \brief Method called just before filter is removed to manager.
> + *
> + * This method starts removing of the given filter from view
Ditto
> + */
> + void filter_about_to_be_removed(package_filter_definition_ptr filter);
> +
> + /** \brief Method called just before filter is removed to manager.
> + *
> + * This method ends removing of the given filter from view
> + */
> + void filter_removed(package_filter_definition_ptr filter);
Ditto.
> + public:
> + /** \brief Create a new package_filters_model. */
> + explicit package_filters_model(QObject *parent = 0);
As noted above, this should take a manager pointer.
> + virtual ~package_filters_model();
> +
> + /** \brief Retrieve a number of columns for the children of the given parent. */
> + virtual int columnCount(const QModelIndex &parent) const;
"the number of columns"
> +
> + /** \brief Retrieve a number of rows under the given parent. */
> + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
"the number of rows"
> +
> + /** \brief Returns a data stored under the given role for the item
> + * referred to by the index.
> + */
> + virtual QVariant data(const QModelIndex &index, int role) const;
"Returns an attribute of the given index, selected by its role."
> +
> + /** \brief Retrieve a data for the given role and section in the header
> + * with the specified orientation.
> + */
> + virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
"Returns an attribute of the column header."
> + /** \brief Retrieve a pointer to a filer under the given index. */
"a filer under the given index" -> "the filter at the given index".
> + package_filter_definition_ptr filter_at_index(const QModelIndex &index) const;
> +
> + /** \brief Retrieve a index in view for a the given filter. */
> + int filter_index(package_filter_definition_ptr filter) const ;
"Retrieve the index of the given filter", also pass by const
reference.
> +++ b/src/qt/models/packages_proxy_model.cc
> @@ -0,0 +1,135 @@
> +/** \file package_proxy_model.cc */
\file doesn't match the file name (saw this in other files in this
patch too, not noting all of them).
> + bool packages_proxy_model::lessThan(const QModelIndex &left, const QModelIndex &right) const
> + {
> + if(!source_packages_model)
> + return QSortFilterProxyModel::lessThan(left, right);
> +
> + switch(left.column())
>
> + {
> + case 1:
Lots of hardcoding and magic numbers. Please at least put an enum
in here.
> + case 2:
> + {
> + QString left_string = left.data(package_installed_version_role).toString();
> + QString right_string = right.data(package_installed_version_role).toString();
> +
> + return left_string > right_string;
When comparing version numbers, you should use CmpVersion. e.g.,
return _system->GetVS()->CmpVersion(left_string, right_string) < 0;
> + }
> + case 3:
> + {
> + QString left_string = left.data(package_candidate_version_role).toString();
> + QString right_string = right.data(package_candidate_version_role).toString();
> +
> + return left_string > right_string;
Ditto.
> + bool packages_proxy_model::filterAcceptsRow(int source_row, const QModelIndex &source_arent) const
> + {
> + package_ptr pkg = sourceModel()->index(source_row, 0).data(package_role).value<package_ptr>();
> + Q_FOREACH(package_filter_definition_ptr filter, filters)
Is Q_FOREACH just a fancy way of saying
for(QList<package_filter_definition_ptr>::const_iterator it = filters.begin();
it != filters.end(); ++it)
{
const package_filter_definition_ptr filter = *it;
// ...
}
?
> + void packages_proxy_model::add_filter(package_filter_definition_ptr filter)
Why do we take a definition and not a filter here?
> + {
> + filters.append(filter);
Maybe this should be a set, so we can dedupe?
> + void packages_proxy_model::remove_filter(package_filter_definition_ptr filter)
> + {
> + filters.removeAll(filter);
> + invalidateFilter();
> +// filter->connect_filter_changed(sigc::mem_fun(*this, &packages_model::handle_cache_reloaded));
Is that stale code I see?
> + void packages_proxy_model::invalidate()
> + {
> + QSortFilterProxyModel::invalidate();
> + }
What's the purpose of this method? All it does is defer to the
superclass.
> + /** \brief Class responsible for sorting and filtering data passed between package_model
> + * and package view widget
> + *
> + * This class contains list of active filters. During package checking, matches method
> + * is called on all registered filters. When at least one filter matches tested package
> + * the package is accepted.
I think I would prefer to just have a single filter and manage the
policy of OR, AND, XOR ( :) ), etc elsewhere, probably in whatever is
handling selections (i.e., create an "OR filter" that accumulates some
sub-filters). Unless there's a benefit to managing the list here
(e.g., performance / design)?
> + /** \brief Create new packages_proxy_model*/
"a new", also "model*/" -> "model. */"
> + explicit packages_proxy_model(QObject *parent = 0);
> +
> + virtual ~packages_proxy_model();
> +
> + /** \brief Sets the given sourceModel to be processed by this proxy model. */
Maybe "Set the source model that will be filtered by this proxy."?
Also, needs wrapping.
> + virtual void setSourceModel(QAbstractItemModel *source_model);
> +
> + /** \brief Adds the given filter to list of used filters and invalidates filtering. */
"to the list of active filters", "invalidates the filtering", wrap.
> + void add_filter(package_filter_definition_ptr filter);
> +
> + /** \brief Removes the given filter from list of used filters and invalidates filtering. */
"from the list of active filters", "invalidates the filtering", wrap.
> + void remove_filter(package_filter_definition_ptr filter);
> +
> + /** \brief Method called when one of the active filters has changed.
> + *
> + * This method also invalidates actual filtering
"invalidates the filtering".
> + */
> + void invalidate();
> + };
> + }
> + }
> +}
> + class package_filters_manager::package_filters_manager_impl : public package_filters_manager
> + {
> + bool loaded;
> +
> + std::vector<package_filter_definition_ptr> filters;
> +
> + //for future:
> + void ensure_loaded();
> + void load();
> + void store();
> +
> + public:
> + explicit package_filters_manager_impl();
> + virtual ~package_filters_manager_impl();
> +
> + package_filter_definition_ptr by_index(unsigned int index);
> + unsigned int count();
> + const std::vector<package_filter_definition_ptr> get_filters();
> + unsigned int index_of(package_filter_definition_ptr filter);
> +
> + void add_filter(package_filter_definition_ptr filter);
> + void remove_filter(package_filter_definition_ptr filter);
> +
> + sigc::signal1<void, package_filter_definition_ptr> filter_about_to_be_added;
> + sigc::signal1<void, package_filter_definition_ptr> filter_added;
> + sigc::signal1<void, package_filter_definition_ptr> filter_about_to_be_removed;
> + sigc::signal1<void, package_filter_definition_ptr> filter_removed;
> +
> + sigc::connection connect_filter_about_to_be_added(const sigc::slot<void, package_filter_definition_ptr> &slot);
> + sigc::connection connect_filter_added(const sigc::slot<void, package_filter_definition_ptr> &slot);
> + sigc::connection connect_filter_about_to_be_removed(const sigc::slot<void, package_filter_definition_ptr> &slot);
> + sigc::connection connect_filter_removed(const sigc::slot<void, package_filter_definition_ptr> &slot);
> + };
> +
> + package_filters_manager::package_filters_manager_impl::package_filters_manager_impl()
> + : loaded(false)
> + {
> + }
> +
> + package_filters_manager::package_filters_manager::package_filters_manager_impl::~package_filters_manager_impl()
> + {
> + }
> +
> + void package_filters_manager::package_filters_manager_impl::ensure_loaded()
> + {
> + if(!loaded)
> + {
> + //TODO: loaded should be after load()
> + loaded = true;
> + load();
> + }
> + }
> +
> + void package_filters_manager::package_filters_manager_impl::load()
> + {
> + }
> +
> + void package_filters_manager::package_filters_manager_impl::store()
> + {
> +
> + }
> +
> + package_filter_definition_ptr package_filters_manager::package_filters_manager_impl::by_index(unsigned int index)
> + {
> + ensure_loaded();
> +
> + if(index >= count())
> + return package_filter_definition_ptr();
> +
> + return filters.at(index);
> + }
> +
> + unsigned int package_filters_manager::package_filters_manager_impl::count()
> + {
> + ensure_loaded();
> + return filters.size();
> + }
> +
> + unsigned int package_filters_manager::package_filters_manager_impl::index_of(package_filter_definition_ptr filter)
> + {
> + ensure_loaded();
> + for(unsigned int i=0;i<filters.size();++i)
> + if(filters[i] == filter)
> + return i;
> +
> + return -1;
> + }
> +
> + const std::vector<package_filter_definition_ptr> package_filters_manager::package_filters_manager_impl::get_filters()
> + {
> + ensure_loaded();
> + return filters;
> + }
> +
> + void package_filters_manager::package_filters_manager_impl::add_filter(package_filter_definition_ptr filter)
> + {
> + ensure_loaded();
> +
> + if(find(filters.begin(), filters.end(), filter) == filters.end())
> + return;
> +
> + filter_about_to_be_added(filter);
> + filters.push_back(filter);
> + filter_added(filter);
> + }
> +
> + void package_filters_manager::package_filters_manager_impl::remove_filter(package_filter_definition_ptr filter)
> + {
> + ensure_loaded();
> +
> + int i;
> + if((i = find(filters.begin(), filters.end(), filter) == filters.end()))
> + return;
> +
> + filter_about_to_be_removed(filter);
> + filters.erase(filters.begin() + i);
> + filter_removed(filter);
> + }
> +
> + sigc::connection
> + package_filters_manager::package_filters_manager_impl::connect_filter_about_to_be_added(const sigc::slot<void, package_filter_definition_p> tr> &slot)
> + {
> + return filter_about_to_be_added.connect(slot);
> + }
> +
> + sigc::connection
> + package_filters_manager::package_filters_manager_impl::connect_filter_added(const sigc::slot<void, package_filter_definition_ptr> &slot)
> + {
> + return filter_added.connect(slot);
> + }
> +
> + sigc::connection
> + package_filters_manager::package_filters_manager_impl::connect_filter_about_to_be_removed(const sigc::slot<void, package_filter_definition> _ptr> &slot)
> + {
> + return filter_about_to_be_removed.connect(slot);
> + }
> +
> + sigc::connection
> + package_filters_manager::package_filters_manager_impl::connect_filter_removed(const sigc::slot<void, package_filter_definition_ptr> &slot)
> + {
> + return filter_removed.connect(slot);
> + }
> +
> + package_filters_manager *package_filters_manager::get_instance()
> + {
> + static package_filters_manager_impl instance;
> +
> + return &instance;
> + }
> +
> + package_filters_manager::package_filters_manager()
> + {
> + }
> +
> + package_filters_manager::~package_filters_manager()
> + {
> + }
> + }
> + }
> +}
> diff --git a/src/qt/package_filters_manager.h b/src/qt/package_filters_manager.h
> new file mode 100644
> index 0000000..c109799
> --- /dev/null
> +++ b/src/qt/package_filters_manager.h
> @@ -0,0 +1,112 @@
> +/** \file filter_manager.h */ // -*-c++-*-
> +//
> +// Copyright (C) 2010 Piotr Galiszewski
> +//
> +// This program is free software; you can redistribute it and/or
> +// modify it under the terms of the GNU General Public License as
> +// published by the Free Software Foundation; either version 2 of the
> +// License, or (at your option) any later version.
> +//
> +// This program is distributed in the hope that it will be useful, but
> +// WITHOUT ANY WARRANTY; without even the implied warranty of
> +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> +// General Public License for more details.
> +//
> +// You should have received a copy of the GNU General Public License
> +// along with this program; see the file COPYING. If not, write to
> +// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> +// Boston, MA 02111-1307, USA.
> +
> +#ifndef APTITUDE_QT_PACKAGE_FILTERS_MANAGER_H
> +#define APTITUDE_QT_PACKAGE_FILTERS_MANAGER_H
> +
> +// System includes
> +#include <boost/shared_ptr.hpp>
> +
> +#include <sigc++/connection.h>
> +#include <sigc++/slot.h>
> +
> +#include <vector>
> +
> +namespace aptitude
> +{
> + namespace gui
> + {
> + namespace qt
> + {
> + class package_filter_definition;
> + typedef boost::shared_ptr<package_filter_definition> package_filter_definition_ptr;
> +
Thanks for breaking the generic stuff out into a separate class.
> + /** \brief Manage all defined filters in application.
Manages the defined filters.
> + *
> + * package_filters_manager provides methods to adding and removing each
> + * of the package filters that the could be used in filter view.
package_filters_manager maintains the set of package filters that
can be used in filtered views.
Or did you mean:
package_filters_manager maintains the set of package filters that
can be picked from filter lists.
> + * Every registered filter is displayed in each package filter view of the program
Every registered filter is displayed in each list of available
filters.
> + * Registered filters will be stored in configuration file and lazy loaded before
> + * first use of filters.
All registered filters will be stored in the configuration file
and lazily loaded before the first time that the list of filters
is required.
> + /** \brief Retrieve filter at the given index.
Retrieve the filter at the given index.
> + * If the index is out of range empty pointer is returned
Usually I say "invalid pointer" instead of "empty pointer".
If the index is out of range, an invalid pointer is returned.
> + */
> + virtual package_filter_definition_ptr by_index(unsigned int index) = 0;
> +
> + /** \brief Retrieve registered filters count. */
Retrieve the number of registered filters. It would be more
consistent with normal C++ usage to call this "size".
> + virtual unsigned int count() = 0;
> +
> + /** \brief Retrieve all registered filters. */
> + virtual const std::vector<package_filter_definition_ptr> get_filters() = 0;
Maybe instead export begin() and end()? If not, return by const
reference.
> + /** \brief Retrieve the index of the given filter or -1 if not found. */
"or -1 if it is not present".
> + virtual unsigned int index_of(package_filter_definition_ptr filter) = 0;
> +
> + /** \brief Adds new filter to the filters list.
> + *
> + * If filter is already added this method does nothing. On other situation
"Adds a new filter"
"On other situation" -> "Otherwise,"
> + * filter_about_to_be_added and filter_added signals are emitted
"the filter_about_to_be_added"
"are emitted."
> + */
> + virtual void add_filter(package_filter_definition_ptr filter) = 0;
Pass by const reference.
> + /** \brief Removes filter from the filters list.
"Removes a filter"
> + * If filter is not in list this method does nothing. On other situation
"If the filter"
"On other situation" -> "Otherwise,"
> + * filter_about_to_be_removed and filter_removed signals are emitted
"the filter_about_to_be_removed"
"are emitted."
> + */
> + virtual void remove_filter(package_filter_definition_ptr filter) = 0;
Pass by const reference.
> + /** \brief Connect to a signal emited just before filter is added to manager. */
emitted.
"just before a filter is added to the manager."
> + virtual sigc::connection connect_filter_about_to_be_added(const sigc::slot<void, package_filter_definition_ptr> &slot) = 0;
> +
> + /** \brief Connect to a signal emited just after filter is added to manager. */
Ditto.
> + virtual sigc::connection connect_filter_added(const sigc::slot<void, package_filter_definition_ptr> &slot) = 0;
> +
> + /** \brief Connect to a signal emited just before filter is removed from manager. */
Ditto.
> + virtual sigc::connection connect_filter_about_to_be_removed(const sigc::slot<void, package_filter_definition_ptr> &slot) = 0;
> +
> + /** \brief Connect to a signal emited just after filter is removed from manager. */
Ditto.
> + virtual sigc::connection connect_filter_removed(const sigc::slot<void, package_filter_definition_ptr> &slot) = 0;
> + };
> + }
> + }
> +}
> +
> +#endif // APTITUDE_QT_PACKAGE_FILTERS_MANAGER_H
> + enum search_by
> + {
> + /** \brief searched_text is searched only in package name. */
> + search_by_name = 0,
> + /** \brief searched_text is searched in package name and package descriptions. */
> + search_by_name_and_description = 1,
> + /** \brief searched_text is searched in package maintainer name */
> + search_by_maintainer = 2,
> + /** \brief searched_text is searched only in all available package versions */
> + search_by_version = 3
> + };
Doesn't this basically reimplement a small section of the match
patterns? Please don't do that. I'm not going to comment further on
this class unless you can convince me it should exist. :-)
Daniel
More information about the Aptitude-devel
mailing list