<commit_before>/*
    This file is part of Akregator.

    Copyright (C) 2004 <NAME> <<EMAIL>>
                  2005 <NAME> <frank.osterfeld at kdemail.net>
    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; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "articlelistview.h"

#include "actionmanager.h"
#include "akregatorconfig.h"
#include "articlemodel.h"
#include "kernel.h"
#include "types.h"

#include <KIcon>
#include <KLocale>

#include <QApplication>
#include <QContextMenuEvent>
#include <QHeaderView>
#include <QKeyEvent>
#include <QList>
#include <QMenu>
#include <QPaintEvent>
#include <QPalette>

Akregator::SortColorizeProxyModel::SortColorizeProxyModel( QObject* parent ) : QSortFilterProxyModel( parent )
{
    m_keepFlagIcon = KIcon("flag");
}

int Akregator::SortColorizeProxyModel::columnCount( const QModelIndex& index ) const
{
    return 3;
}

QVariant Akregator::SortColorizeProxyModel::headerData( int section, Qt::Orientation, int role ) const
{
    if ( role != Qt::DisplayRole )
        return QVariant();

    switch (section)
    {
        case ItemTitleColumn:
            return i18n("Article");
        case FeedTitleColumn:
            return i18n("Feed");
        case DateColumn:
            return i18n("Date");
    }

    return QVariant();
}

QVariant Akregator::SortColorizeProxyModel::data( const QModelIndex& idx, int role ) const
{
    if ( !idx.isValid() || !sourceModel() )
        return QVariant();

    switch ( role )
    {
        case Qt::ForegroundRole:
        {
            switch ( static_cast<Akregator::ArticleStatus>( QSortFilterProxyModel::data( idx, Akregator::ArticleModel::StatusRole ).toInt() ) )
            {
                case Akregator::Unread:
                {
                    return Settings::useCustomColors() ?
                        Settings::colorUnreadArticles() : Qt::blue;
                }
                case Akregator::New:
                {
                    return Settings::useCustomColors() ?
                        Settings::colorNewArticles() : Qt::red;
                }
                case Akregator::Read:
                {
                    return QApplication::palette().color( QPalette::WindowText );
                }
            }
        }
        break;
        case Qt::DecorationRole:
        {
            if ( idx.column() == ItemTitleColumn )
            {
                const QModelIndex sourceIdx = mapToSource( idx );
                return sourceIdx.data( Akregator::ArticleModel::IsImportantRole ).toBool() ? m_keepFlagIcon : QVariant();
            }
        }
        break;
    }
    return QSortFilterProxyModel::data( idx, role );
}

namespace {

    static bool isRead( const QModelIndex& idx )
    {
        if ( !idx.isValid() )
            return false;
    
        return static_cast<Akregator::ArticleStatus>( idx.data( Akregator::ArticleModel::StatusRole ).toInt() ) == Akregator::Read;
    }
}

void Akregator::ArticleListView::setArticleModel( Akregator::ArticleModel* model )
{
    QAbstractProxyModel* proxy = new Akregator::SortColorizeProxyModel( model );
    proxy->setSourceModel( model );
    setModel( proxy );
    header()->setResizeMode( ItemTitleColumn, QHeaderView::Stretch );
    header()->setStretchLastSection( false );
    header()->setResizeMode( DateColumn, QHeaderView::ResizeToContents );
}

QItemSelectionModel* Akregator::ArticleListView::articleSelectionModel() const
{
    return selectionModel();
}

const QAbstractItemView* Akregator::ArticleListView::itemView() const
{
    return this;
}

QAbstractItemView* Akregator::ArticleListView::itemView()
{
    return this;
}

void Akregator::ArticleListView::setGroupMode()
{
    if ( m_columnMode == GroupMode )
        return;
    setColumnHidden( ArticleListView::FeedTitleColumn, false );
    m_columnMode = GroupMode;
}

void Akregator::ArticleListView::setFeedMode()
{
    if ( m_columnMode == FeedMode )
        return;
    setColumnHidden( ArticleListView::FeedTitleColumn, true );
    m_columnMode = FeedMode;
}

Akregator::ArticleListView::~ArticleListView()
{
    Settings::setTitleWidth( columnWidth(ItemTitleColumn) );
    Settings::setFeedWidth( columnWidth(FeedTitleColumn) );
    Settings::setSortColumn( header()->sortIndicatorSection() );
    Settings::setSortAscending( header()->sortIndicatorOrder() );
    Settings::self()->writeConfig();
}

void Akregator::ArticleListView::setIsAggregation( bool aggregation )
{
    if ( aggregation == m_isAggregation )
        return;
    m_isAggregation = aggregation;
    if ( aggregation )
        setGroupMode();
    else
        setFeedMode();
}

Akregator::ArticleListView::ArticleListView( QWidget* parent ) : QTreeView(parent), m_columnMode( Akregator::ArticleListView::Unspecified ), m_isAggregation( false )
{
    setSortingEnabled( true );
    setAlternatingRowColors( true );
    setSelectionMode( QAbstractItemView::ExtendedSelection );
    setUniformRowHeights( true );

    setMinimumSize( 250, 150 );
    setWhatsThis( i18n("<h2>Article list</h2>"
        "Here you can browse articles from the currently selected feed. "
        "You can also manage articles, as marking them as persistent (\"Keep Article\") or delete them, using the right mouse button menu."
        "To view the web page of the article, you can open the article internally in a tab or in an external browser window."));

    //connect(this, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()));
    
    //connect(this, SIGNAL(mouseButtonPressed(int, Q3ListViewItem *, const QPoint &, int)), this, SLOT(slotMouseButtonPressed(int, Q3ListViewItem *, const QPoint &, int)));
<commit_msg>Remove the branch decorations next to items in the article list view.<commit_after>/*
    This file is part of Akregator.

    Copyright (C) 2004 <NAME> <<EMAIL>>
                  2005 <NAME> <frank.osterfeld at kdemail.net>
    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; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "articlelistview.h"

#include "actionmanager.h"
#include "akregatorconfig.h"
#include "articlemodel.h"
#include "kernel.h"
#include "types.h"

#include <KIcon>
#include <KLocale>

#include <QApplication>
#include <QContextMenuEvent>
#include <QHeaderView>
#include <QKeyEvent>
#include <QList>
#include <QMenu>
#include <QPaintEvent>
#include <QPalette>

Akregator::SortColorizeProxyModel::SortColorizeProxyModel( QObject* parent ) : QSortFilterProxyModel( parent )
{
    m_keepFlagIcon = KIcon("flag");
}

int Akregator::SortColorizeProxyModel::columnCount( const QModelIndex& index ) const
{
    return 3;
}

QVariant Akregator::SortColorizeProxyModel::headerData( int section, Qt::Orientation, int role ) const
{
    if ( role != Qt::DisplayRole )
        return QVariant();

    switch (section)
    {
        case ItemTitleColumn:
            return i18n("Article");
        case FeedTitleColumn:
            return i18n("Feed");
        case DateColumn:
            return i18n("Date");
    }

    return QVariant();
}

QVariant Akregator::SortColorizeProxyModel::data( const QModelIndex& idx, int role ) const
{
    if ( !idx.isValid() || !sourceModel() )
        return QVariant();

    switch ( role )
    {
        case Qt::ForegroundRole:
        {
            switch ( static_cast<Akregator::ArticleStatus>( QSortFilterProxyModel::data( idx, Akregator::ArticleModel::StatusRole ).toInt() ) )
            {
                case Akregator::Unread:
                {
                    return Settings::useCustomColors() ?
                        Settings::colorUnreadArticles() : Qt::blue;
                }
                case Akregator::New:
                {
                    return Settings::useCustomColors() ?
                        Settings::colorNewArticles() : Qt::red;
                }
                case Akregator::Read:
                {
                    return QApplication::palette().color( QPalette::WindowText );
                }
            }
        }
        break;
        case Qt::DecorationRole:
        {
            if ( idx.column() == ItemTitleColumn )
            {
                const QModelIndex sourceIdx = mapToSource( idx );
                return sourceIdx.data( Akregator::ArticleModel::IsImportantRole ).toBool() ? m_keepFlagIcon : QVariant();
            }
        }
        break;
    }
    return QSortFilterProxyModel::data( idx, role );
}

namespace {

    static bool isRead( const QModelIndex& idx )
    {
        if ( !idx.isValid() )
            return false;
    
        return static_cast<Akregator::ArticleStatus>( idx.data( Akregator::ArticleModel::StatusRole ).toInt() ) == Akregator::Read;
    }
}

void Akregator::ArticleListView::setArticleModel( Akregator::ArticleModel* model )
{
    QAbstractProxyModel* proxy = new Akregator::SortColorizeProxyModel( model );
    proxy->setSourceModel( model );
    setModel( proxy );
    header()->setResizeMode( ItemTitleColumn, QHeaderView::Stretch );
    header()->setStretchLastSection( false );
    header()->setResizeMode( DateColumn, QHeaderView::ResizeToContents );
}

QItemSelectionModel* Akregator::ArticleListView::articleSelectionModel() const
{
    return selectionModel();
}

const QAbstractItemView* Akregator::ArticleListView::itemView() const
{
    return this;
}

QAbstractItemView* Akregator::ArticleListView::itemView()
{
    return this;
}

void Akregator::ArticleListView::setGroupMode()
{
    if ( m_columnMode == GroupMode )
        return;
    setColumnHidden( ArticleListView::FeedTitleColumn, false );
    m_columnMode = GroupMode;
}

void Akregator::ArticleListView::setFeedMode()
{
    if ( m_columnMode == FeedMode )
        return;
    setColumnHidden( ArticleListView::FeedTitleColumn, true );
    m_columnMode = FeedMode;
}

Akregator::ArticleListView::~ArticleListView()
{
    Settings::setTitleWidth( columnWidth(ItemTitleColumn) );
    Settings::setFeedWidth( columnWidth(FeedTitleColumn) );
    Settings::setSortColumn( header()->sortIndicatorSection() );
    Settings::setSortAscending( header()->sortIndicatorOrder() );
    Settings::self()->writeConfig();
}

void Akregator::ArticleListView::setIsAggregation( bool aggregation )
{
    if ( aggregation == m_isAggregation )
        return;
    m_isAggregation = aggregation;
    if ( aggregation )
        setGroupMode();
    else
        setFeedMode();
}

Akregator::ArticleListView::ArticleListView( QWidget* parent ) : QTreeView(parent), m_columnMode( Akregator::ArticleListView::Unspecified ), m_isAggregation( false )
{
    setSortingEnabled( true );
    setAlternatingRowColors( true );
    setSelectionMode( QAbstractItemView::ExtendedSelection );
    setUniformRowHeights( true );
    setRootIsDecorated( false );

    setMinimumSize( 250, 150 );
    setWhatsThis( i18n("<h2>Article list</h2>"
        "Here you can browse articles from the currently selected feed. "
        "You can also manage articles, as marking them as persistent (\"Keep Article\") or delete them, using the right mouse button menu."
        "To view the web page of the article, you can open the article internally in a tab or in an external browser window."));

    //connect(this, SIGNAL(selectionChanged()), this, SLOT(slotSelectionChanged()));
    
    //connect(this, SIGNAL(mouseButtonPressed(int, Q3ListViewItem *, const QPoint &, int)), this, SLOT(slotMouseButtonPressed(int, Q3ListViewItem *, const QPoint &, int)));

{'fraction_non_alphanumeric': 0.1031400412560165, 'fraction_numerical': 0.005959202383680954, 'mean_word_length': 3.1687898089171975, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3496900', 'n_tokens_mistral': 3784, 'n_tokens_neox': 3572, 'n_words': 997}