mirror of
https://github.com/Murmele/Gittyup.git
synced 2024-11-03 21:24:30 +03:00
Remove DiffWidget and FileList
This commit is contained in:
parent
6def9eb3fd
commit
25242600ab
@ -65,16 +65,6 @@ theme['commits'] = {
|
||||
highlighted_bright_text = { active = '#A6CBF0', inactive = '#9090A5' }
|
||||
}
|
||||
|
||||
-- file list colors
|
||||
-- { default, active, inactive, disabled }
|
||||
theme['files'] = {
|
||||
text = '#E1E5F2',
|
||||
background = '#36373E',
|
||||
alternate = '#2D2E34', -- an alternate background color for list rows
|
||||
highlight = { active = '#2A82DA', inactive = '#1B5B9B' },
|
||||
highlighted_text = { active = '#E1E5F2', inactive = '#E1E5F2' },
|
||||
}
|
||||
|
||||
-- status badge colors
|
||||
-- { normal, selected, conflicted, head, notification }
|
||||
theme['badge'] = {
|
||||
|
@ -65,16 +65,6 @@ theme['commits'] = {
|
||||
highlighted_bright_text = { active = '#FFFFFF', inactive = '#FFFFFF' }
|
||||
}
|
||||
|
||||
-- file list colors
|
||||
-- { default, active, inactive, disabled }
|
||||
theme['files'] = {
|
||||
text = '#232627',
|
||||
background = '#FCFCFC',
|
||||
alternate = '#EFF0F1', -- an alternate background color for list rows
|
||||
highlight = { active = '#3DAEE9', inactive = '#C2E0F5' },
|
||||
highlighted_text = { active = '#FCFCFC', inactive = '#232627' },
|
||||
}
|
||||
|
||||
-- status badge colors
|
||||
-- { normal, selected, conflicted, head, notification }
|
||||
theme['badge'] = {
|
||||
|
@ -168,13 +168,6 @@ QString CustomTheme::styleSheet() const
|
||||
" color: palette(bright-text)"
|
||||
"}"
|
||||
|
||||
"FileList {"
|
||||
" border-top: 1px solid palette(dark)"
|
||||
"}"
|
||||
"FileList QToolButton {"
|
||||
" background: none"
|
||||
"}"
|
||||
|
||||
"FindWidget {"
|
||||
" background: palette(highlight)"
|
||||
"}"
|
||||
@ -441,20 +434,6 @@ QColor CustomTheme::diff(Diff color)
|
||||
}
|
||||
}
|
||||
|
||||
QPalette CustomTheme::fileList()
|
||||
{
|
||||
QVariantMap fileList = mMap.value("files").toMap();
|
||||
|
||||
QPalette palette;
|
||||
setPaletteColors(palette, QPalette::Text, fileList.value("text"));
|
||||
setPaletteColors(palette, QPalette::Base, fileList.value("background"));
|
||||
setPaletteColors(palette, QPalette::AlternateBase, fileList.value("alternate"));
|
||||
setPaletteColors(palette, QPalette::Highlight, fileList.value("highlight"));
|
||||
setPaletteColors(palette, QPalette::HighlightedText,
|
||||
fileList.value("highlighted_text"));
|
||||
return palette;
|
||||
}
|
||||
|
||||
QColor CustomTheme::heatMap(HeatMap color)
|
||||
{
|
||||
QVariantMap heatmap = mMap.value("blame").toMap();
|
||||
|
@ -32,7 +32,6 @@ public:
|
||||
QPalette commitList() override;
|
||||
QColor commitEditor(CommitEditor color) override;
|
||||
QColor diff(Diff color) override;
|
||||
QPalette fileList() override;
|
||||
QColor heatMap(HeatMap color) override;
|
||||
QColor remoteComment(Comment color) override;
|
||||
QColor star() override;
|
||||
|
@ -242,11 +242,6 @@ QColor Theme::diff(Diff color)
|
||||
}
|
||||
}
|
||||
|
||||
QPalette Theme::fileList()
|
||||
{
|
||||
return QPalette();
|
||||
}
|
||||
|
||||
QColor Theme::heatMap(HeatMap color)
|
||||
{
|
||||
if (mDark) {
|
||||
|
@ -88,7 +88,6 @@ public:
|
||||
virtual QPalette commitList();
|
||||
virtual QColor commitEditor(CommitEditor color);
|
||||
virtual QColor diff(Diff color);
|
||||
virtual QPalette fileList();
|
||||
virtual QColor heatMap(HeatMap color);
|
||||
virtual QColor remoteComment(Comment color);
|
||||
virtual QColor star();
|
||||
|
@ -19,12 +19,10 @@ add_library(ui
|
||||
DiffView/Images.cpp
|
||||
DiffView/Comment.cpp
|
||||
DiffView/EditButton.cpp
|
||||
DiffWidget.cpp
|
||||
DoubleTreeWidget.cpp
|
||||
EditorWindow.cpp
|
||||
ExpandButton.cpp
|
||||
FileContextMenu.cpp
|
||||
FileList.cpp
|
||||
FindWidget.cpp
|
||||
Footer.cpp
|
||||
History.cpp
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "DetailView.h"
|
||||
#include "Badge.h"
|
||||
#include "ContextMenuButton.h"
|
||||
#include "DiffWidget.h"
|
||||
#include "MenuBar.h"
|
||||
#include "ContextMenuButton.h"
|
||||
#include "TreeWidget.h"
|
||||
@ -1196,7 +1195,6 @@ DetailView::DetailView(const git::Repository &repo, QWidget *parent)
|
||||
mContent = new QStackedWidget(this);
|
||||
layout->addWidget(mContent, 1);
|
||||
|
||||
//mContent->addWidget(new DiffWidget(repo, this));
|
||||
mContent->addWidget(new DoubleTreeWidget(repo, this));
|
||||
mContent->addWidget(new TreeWidget(repo, this));
|
||||
}
|
||||
|
2333
src/ui/DiffView.cpp
2333
src/ui/DiffView.cpp
File diff suppressed because it is too large
Load Diff
@ -1,183 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2016, Scientific Toolworks, Inc.
|
||||
//
|
||||
// This software is licensed under the MIT License. The LICENSE.md file
|
||||
// describes the conditions under which this software may be distributed.
|
||||
//
|
||||
// Author: Jason Haslam
|
||||
//
|
||||
|
||||
#include "DiffWidget.h"
|
||||
#include "DiffView/DiffView.h"
|
||||
#include "FileList.h"
|
||||
#include "FindWidget.h"
|
||||
#include "RepoView.h"
|
||||
#include "conf/Settings.h"
|
||||
#include "git/Commit.h"
|
||||
#include "git/Diff.h"
|
||||
#include "git/Index.h"
|
||||
#include <QScrollBar>
|
||||
#include <QShortcut>
|
||||
#include <QSplitter>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
namespace {
|
||||
|
||||
const QItemSelectionModel::SelectionFlags kSelectionFlags =
|
||||
QItemSelectionModel::Current;
|
||||
|
||||
} // anon. namespace
|
||||
|
||||
DiffWidget::DiffWidget(const git::Repository &repo, QWidget *parent)
|
||||
: ContentWidget(parent)
|
||||
{
|
||||
mFiles = new FileList(repo, this);
|
||||
mFiles->hide(); // Start hidden.
|
||||
|
||||
mDiffView = new DiffView(repo, this);
|
||||
|
||||
mFind = new FindWidget(mDiffView, this);
|
||||
mFind->hide(); // Start hidden.
|
||||
|
||||
QWidget *view = new QWidget(this);
|
||||
QVBoxLayout *viewLayout = new QVBoxLayout(view);
|
||||
viewLayout->setContentsMargins(0,0,0,0);
|
||||
viewLayout->setSpacing(0);
|
||||
viewLayout->addWidget(mFind);
|
||||
viewLayout->addWidget(mDiffView);
|
||||
|
||||
mSplitter = new QSplitter(Qt::Vertical, this);
|
||||
mSplitter->setChildrenCollapsible(false);
|
||||
mSplitter->setHandleWidth(0);
|
||||
mSplitter->addWidget(mFiles);
|
||||
mSplitter->addWidget(view);
|
||||
mSplitter->setStretchFactor(1, 1);
|
||||
connect(mSplitter, &QSplitter::splitterMoved, [this] {
|
||||
FileList::setFileRows(mFiles->height() / mFiles->sizeHintForRow(0));
|
||||
});
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
layout->setContentsMargins(0,0,0,0);
|
||||
layout->addWidget(mSplitter);
|
||||
|
||||
// Filter on selection change.
|
||||
QItemSelectionModel *selection = mFiles->selectionModel();
|
||||
connect(selection, &QItemSelectionModel::selectionChanged, [this] {
|
||||
QStringList paths;
|
||||
QModelIndexList indexes = mFiles->selectionModel()->selectedIndexes();
|
||||
foreach (const QModelIndex &index, indexes)
|
||||
paths.append(index.data().toString());
|
||||
mDiffView->updateFiles();
|
||||
});
|
||||
|
||||
connect(mDiffView->verticalScrollBar(), &QScrollBar::valueChanged,
|
||||
this, &DiffWidget::setCurrentFile);
|
||||
|
||||
connect(mFiles, &FileList::sortRequested, [this] {
|
||||
setDiff(mDiff);
|
||||
});
|
||||
}
|
||||
|
||||
QString DiffWidget::selectedFile() const
|
||||
{
|
||||
QModelIndexList indexes = mFiles->selectionModel()->selectedIndexes();
|
||||
return indexes.isEmpty() ? QString() :
|
||||
indexes.first().data(Qt::DisplayRole).toString();
|
||||
}
|
||||
|
||||
void DiffWidget::setDiff(
|
||||
const git::Diff &diff,
|
||||
const QString &file,
|
||||
const QString &pathspec)
|
||||
{
|
||||
mDiff = diff;
|
||||
|
||||
// Cancel find.
|
||||
mFind->hide();
|
||||
|
||||
// Populate views.
|
||||
if (mDiff.isValid()) {
|
||||
Qt::SortOrder order = Qt::DescendingOrder;
|
||||
git::Diff::SortRole role = git::Diff::StatusRole;
|
||||
if (!mDiff.isConflicted()) {
|
||||
Settings *settings = Settings::instance();
|
||||
role = static_cast<git::Diff::SortRole>(settings->value("sort/role").toInt());
|
||||
order = static_cast<Qt::SortOrder>(settings->value("sort/order").toInt());
|
||||
}
|
||||
|
||||
mDiff.sort(role, order);
|
||||
}
|
||||
|
||||
mDiffView->setDiff(diff);
|
||||
mFiles->setDiff(diff, pathspec);
|
||||
|
||||
// Reset find.
|
||||
mFind->reset();
|
||||
|
||||
// Adjust splitter.
|
||||
mSplitter->setSizes({mFiles->sizeHint().height(), -1});
|
||||
|
||||
// Scroll to file.
|
||||
selectFile(file);
|
||||
}
|
||||
|
||||
void DiffWidget::find()
|
||||
{
|
||||
mFind->showAndSetFocus();
|
||||
}
|
||||
|
||||
void DiffWidget::findNext()
|
||||
{
|
||||
mFind->find();
|
||||
}
|
||||
|
||||
void DiffWidget::findPrevious()
|
||||
{
|
||||
mFind->find(FindWidget::Backward);
|
||||
}
|
||||
|
||||
void DiffWidget::selectFile(const QString &file)
|
||||
{
|
||||
if (file.isEmpty())
|
||||
return;
|
||||
|
||||
QAbstractItemModel *model = mFiles->model();
|
||||
QModelIndex start = model->index(0, 0);
|
||||
QModelIndexList indexes = model->match(start, Qt::DisplayRole, file);
|
||||
|
||||
// The file might not be found if it was renamed.
|
||||
// FIXME: Look up the old name from the blame?
|
||||
if (!indexes.isEmpty()) {
|
||||
QModelIndex index = indexes.first();
|
||||
if (mDiffView->scrollToFile(index.row()))
|
||||
mFiles->selectionModel()->select(index, kSelectionFlags);
|
||||
}
|
||||
}
|
||||
|
||||
void DiffWidget::setCurrentFile(int value)
|
||||
{
|
||||
// FIXME: This is bogus.
|
||||
if (!mDiffView->widget())
|
||||
return;
|
||||
|
||||
QAbstractItemModel *model = mFiles->model();
|
||||
int rows = model->rowCount();
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
if (!mDiffView->file(i)->isVisible())
|
||||
continue;
|
||||
|
||||
// Get the position of the next widget.
|
||||
int pos = mDiffView->widget()->height();
|
||||
if (i < rows - 1)
|
||||
pos = mDiffView->file(i + 1)->y();
|
||||
|
||||
// Stop at the first index where the scroll
|
||||
// value is less than the next widget.
|
||||
if (value < pos) {
|
||||
QModelIndex index = model->index(i, 0);
|
||||
mFiles->selectionModel()->select(index, kSelectionFlags);
|
||||
mFiles->scrollTo(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2016, Scientific Toolworks, Inc.
|
||||
//
|
||||
// This software is licensed under the MIT License. The LICENSE.md file
|
||||
// describes the conditions under which this software may be distributed.
|
||||
//
|
||||
// Author: Jason Haslam
|
||||
//
|
||||
|
||||
#ifndef DIFFWIDGET_H
|
||||
#define DIFFWIDGET_H
|
||||
|
||||
#include "DetailView.h"
|
||||
#include "git/Index.h"
|
||||
|
||||
|
||||
class DiffView;
|
||||
class FileList;
|
||||
class FindWidget;
|
||||
class QSplitter;
|
||||
|
||||
namespace git {
|
||||
class Diff;
|
||||
class Repository;
|
||||
}
|
||||
|
||||
class DiffWidget : public ContentWidget
|
||||
{
|
||||
public:
|
||||
DiffWidget(const git::Repository &repo, QWidget *parent = nullptr);
|
||||
|
||||
QString selectedFile() const override;
|
||||
|
||||
void setDiff(
|
||||
const git::Diff &diff,
|
||||
const QString &file = QString(),
|
||||
const QString &pathspec = QString()) override;
|
||||
|
||||
void find() override;
|
||||
void findNext() override;
|
||||
void findPrevious() override;
|
||||
|
||||
private:
|
||||
void selectFile(const QString &name);
|
||||
void setCurrentFile(int value);
|
||||
|
||||
DiffView *mDiffView;
|
||||
FileList *mFiles;
|
||||
FindWidget *mFind;
|
||||
QSplitter *mSplitter;
|
||||
|
||||
git::Diff mDiff;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,477 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2016, Scientific Toolworks, Inc.
|
||||
//
|
||||
// This software is licensed under the MIT License. The LICENSE.md file
|
||||
// describes the conditions under which this software may be distributed.
|
||||
//
|
||||
// Author: Jason Haslam
|
||||
//
|
||||
|
||||
#include "FileList.h"
|
||||
#include "Badge.h"
|
||||
#include "ContextMenuButton.h"
|
||||
#include "FileContextMenu.h"
|
||||
#include "RepoView.h"
|
||||
#include "app/Application.h"
|
||||
#include "conf/Settings.h"
|
||||
#include "git/Diff.h"
|
||||
#include "git/Patch.h"
|
||||
#include "git/Repository.h"
|
||||
#include "tools/ExternalTool.h"
|
||||
#include <QAbstractListModel>
|
||||
#include <QApplication>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QSettings>
|
||||
#include <QStyledItemDelegate>
|
||||
#include <QWindow>
|
||||
|
||||
namespace {
|
||||
|
||||
const QString kFileRowsKey = "file/rows";
|
||||
|
||||
class FileModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FileModel(const git::Repository &repo, QObject *parent = nullptr)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
connect(repo.notifier(), &git::RepositoryNotifier::indexChanged,
|
||||
this, &FileModel::updateCheckState);
|
||||
}
|
||||
|
||||
void setDiff(const git::Diff &diff)
|
||||
{
|
||||
beginResetModel();
|
||||
mDiff = diff;
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override
|
||||
{
|
||||
return mDiff.isValid() ? mDiff.count() : 0;
|
||||
}
|
||||
|
||||
QVariant data(
|
||||
const QModelIndex &index,
|
||||
int role = Qt::DisplayRole) const override
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::DisplayRole:
|
||||
return mDiff.name(index.row());
|
||||
|
||||
case Qt::DecorationRole:
|
||||
return git::Diff::statusChar(mDiff.status(index.row()));
|
||||
|
||||
case Qt::CheckStateRole: {
|
||||
if (!mDiff.isStatusDiff())
|
||||
return QVariant();
|
||||
|
||||
QString name = mDiff.name(index.row());
|
||||
switch (mDiff.index().isStaged(name)) {
|
||||
case git::Index::Disabled:
|
||||
case git::Index::Unstaged:
|
||||
case git::Index::Conflicted:
|
||||
return Qt::Unchecked;
|
||||
|
||||
case git::Index::PartiallyStaged:
|
||||
return Qt::PartiallyChecked;
|
||||
|
||||
case git::Index::Staged:
|
||||
return Qt::Checked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
Qt::ItemFlags flags(const QModelIndex &index) const override
|
||||
{
|
||||
return QAbstractListModel::flags(index) | Qt::ItemIsUserCheckable;
|
||||
}
|
||||
|
||||
bool setData(
|
||||
const QModelIndex &index,
|
||||
const QVariant &value,
|
||||
int role = Qt::EditRole) override
|
||||
{
|
||||
switch (role) {
|
||||
case Qt::CheckStateRole: {
|
||||
QString name = mDiff.name(index.row());
|
||||
if (mDiff.index().isStaged(name) == git::Index::Conflicted &&
|
||||
mDiff.patch(index.row()).count() > 0)
|
||||
return false;
|
||||
|
||||
mDiff.index().setStaged({name}, value.toBool(), mYieldFocus);
|
||||
emit dataChanged(index, index, {role});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void setYieldFocus(bool enabled)
|
||||
{
|
||||
mYieldFocus = enabled;
|
||||
}
|
||||
|
||||
private:
|
||||
void updateCheckState(const QStringList &paths)
|
||||
{
|
||||
foreach (const QString &path, paths) {
|
||||
QModelIndexList indexes = match(index(0, 0), Qt::DisplayRole, path);
|
||||
if (!indexes.isEmpty()) {
|
||||
QModelIndex index = indexes.first();
|
||||
emit dataChanged(index, index, {Qt::CheckStateRole});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
git::Diff mDiff;
|
||||
|
||||
bool mYieldFocus = true;
|
||||
};
|
||||
|
||||
class FileDelegate : public QStyledItemDelegate
|
||||
{
|
||||
public:
|
||||
FileDelegate(QObject *parent = nullptr)
|
||||
: QStyledItemDelegate(parent)
|
||||
{}
|
||||
|
||||
void paint(
|
||||
QPainter *painter,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override
|
||||
{
|
||||
QStyleOptionViewItem opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
|
||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
style->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
|
||||
|
||||
QString text = index.data(Qt::DecorationRole).toChar();
|
||||
QStyle::SubElement se = QStyle::SE_ItemViewItemDecoration;
|
||||
QRect rect = style->subElementRect(se, &opt, opt.widget);
|
||||
Badge::paint(painter, {text}, rect, &opt);
|
||||
}
|
||||
|
||||
QSize sizeHint(
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const override
|
||||
{
|
||||
// Increase spacing.
|
||||
QSize size = QStyledItemDelegate::sizeHint(option, index);
|
||||
size.setHeight(Badge::size(option.font).height() + 4);
|
||||
return size;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Get the rectangle occupied by the item's checkboy.
|
||||
* Used in the UI tests
|
||||
*/
|
||||
QRect checkRect(
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const
|
||||
{
|
||||
QStyleOptionViewItem opt = option;
|
||||
initStyleOption(&opt, index);
|
||||
|
||||
if (!(opt.features & QStyleOptionViewItem::HasCheckIndicator))
|
||||
return QRect();
|
||||
|
||||
QStyle::SubElement se = QStyle::SE_ItemViewItemCheckIndicator;
|
||||
QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
|
||||
return style->subElementRect(se, &opt, opt.widget);
|
||||
}
|
||||
|
||||
protected:
|
||||
void initStyleOption(
|
||||
QStyleOptionViewItem *option,
|
||||
const QModelIndex &index) const override
|
||||
{
|
||||
QStyledItemDelegate::initStyleOption(option, index);
|
||||
option->decorationSize = Badge::size(option->font);
|
||||
}
|
||||
|
||||
bool editorEvent(
|
||||
QEvent *event,
|
||||
QAbstractItemModel *model,
|
||||
const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) override
|
||||
{
|
||||
FileModel *fm = static_cast<FileModel *>(model);
|
||||
fm->setYieldFocus(event->type() != QEvent::KeyPress);
|
||||
bool result = QStyledItemDelegate::editorEvent(event, model, option, index);
|
||||
fm->setYieldFocus(true);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
} // anon. namespace
|
||||
|
||||
FileList::FileList(const git::Repository &repo, QWidget *parent)
|
||||
: QListView(parent)
|
||||
{
|
||||
Theme *theme = Application::theme();
|
||||
setPalette(theme->fileList());
|
||||
|
||||
setAlternatingRowColors(true);
|
||||
setFrameShape(QFrame::NoFrame);
|
||||
setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
setModel(new FileModel(repo, this));
|
||||
setItemDelegate(new FileDelegate(this));
|
||||
|
||||
mButton = new ContextMenuButton(this);
|
||||
QMenu *menu = new QMenu(this);
|
||||
mButton->setMenu(menu);
|
||||
|
||||
mSortMenu = menu->addMenu(tr("Sort By"));
|
||||
mSelectMenu = menu->addMenu(tr("Select"));
|
||||
|
||||
mSortName = mSortMenu->addAction(tr("Name"), [this] {
|
||||
Settings *settings = Settings::instance();
|
||||
Qt::SortOrder order = Qt::AscendingOrder;
|
||||
if (settings->value("sort/role").toInt() == git::Diff::NameRole &&
|
||||
settings->value("sort/order").toInt() == Qt::AscendingOrder)
|
||||
order = Qt::DescendingOrder;
|
||||
settings->setValue("sort/order", order);
|
||||
settings->setValue("sort/role", git::Diff::NameRole);
|
||||
emit sortRequested();
|
||||
});
|
||||
|
||||
mSortStatus = mSortMenu->addAction(tr("Status"), [this] {
|
||||
Settings *settings = Settings::instance();
|
||||
Qt::SortOrder order = Qt::AscendingOrder;
|
||||
if (settings->value("sort/role").toInt() == git::Diff::StatusRole &&
|
||||
settings->value("sort/order").toInt() == Qt::AscendingOrder)
|
||||
order = Qt::DescendingOrder;
|
||||
settings->setValue("sort/order", order);
|
||||
settings->setValue("sort/role", git::Diff::StatusRole);
|
||||
emit sortRequested();
|
||||
});
|
||||
|
||||
menu->addSeparator();
|
||||
|
||||
mIgnoreWs = menu->addAction(tr("Ignore Whitespace (-w)"));
|
||||
mIgnoreWs->setCheckable(true);
|
||||
connect(mIgnoreWs, &QAction::triggered, [](bool checked) {
|
||||
Settings::instance()->setWhitespaceIgnored(checked);
|
||||
});
|
||||
|
||||
connect(this, &FileList::doubleClicked, [this](const QModelIndex &index) {
|
||||
if (!index.isValid())
|
||||
return;
|
||||
|
||||
QString file = index.data().toString();
|
||||
RepoView *view = RepoView::parentView(this);
|
||||
|
||||
// Launch external tool.
|
||||
git::Diff diff = view->diff();
|
||||
git::Repository repo = view->repo();
|
||||
if (ExternalTool *tool = ExternalTool::create(file, diff, repo, this)) {
|
||||
// Diff and merge tool both detach from parent after start.
|
||||
if (tool->isValid() && tool->start())
|
||||
return;
|
||||
|
||||
delete tool;
|
||||
}
|
||||
|
||||
// Open editor.
|
||||
view->edit(file);
|
||||
});
|
||||
}
|
||||
|
||||
void FileList::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QListView::resizeEvent(event);
|
||||
mButton->move(viewport()->width() - mButton->width() - 2, y() + 2);
|
||||
}
|
||||
|
||||
void FileList::setDiff(const git::Diff &diff, const QString &pathspec)
|
||||
{
|
||||
mDiff = diff;
|
||||
|
||||
FileModel *model = static_cast<FileModel *>(this->model());
|
||||
model->setDiff(diff);
|
||||
|
||||
int rows = model->rowCount();
|
||||
setVisible(rows > 0);
|
||||
if (rows > 0) {
|
||||
int rowHeight = sizeHintForRow(0);
|
||||
setMinimumHeight(rowHeight + 1);
|
||||
setMaximumHeight(rowHeight * rows + 1);
|
||||
}
|
||||
|
||||
updateMenu(diff);
|
||||
|
||||
if (pathspec.isEmpty())
|
||||
return;
|
||||
|
||||
QItemSelection selection;
|
||||
for (int i = 0; i < rows; ++i) {
|
||||
QModelIndex index = model->index(i, 0);
|
||||
if (index.data().toString().startsWith(pathspec))
|
||||
selection.select(index, index);
|
||||
}
|
||||
|
||||
selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
|
||||
QSize FileList::sizeHint() const
|
||||
{
|
||||
QSettings settings;
|
||||
QSize size = QListView::sizeHint();
|
||||
int rows = qMin(model()->rowCount(), settings.value(kFileRowsKey, 5).toInt());
|
||||
return (rows > 0) ? QSize(size.width(), sizeHintForRow(0) * rows + 1) : size;
|
||||
}
|
||||
|
||||
QRect FileList::checkRect(const QModelIndex &index)
|
||||
{
|
||||
QStyleOptionViewItem options = viewOptions();
|
||||
options.rect = visualRect(index);
|
||||
|
||||
FileDelegate *delegate = static_cast<FileDelegate *>(itemDelegate());
|
||||
return delegate->checkRect(options, index);
|
||||
}
|
||||
|
||||
void FileList::setFileRows(int rows)
|
||||
{
|
||||
QSettings settings;
|
||||
settings.setValue(kFileRowsKey, rows);
|
||||
}
|
||||
|
||||
void FileList::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QPoint pos = event->pos();
|
||||
QModelIndex index = indexAt(pos);
|
||||
if (checkRect(index).contains(pos))
|
||||
return;
|
||||
|
||||
QListView::mouseMoveEvent(event);
|
||||
}
|
||||
|
||||
void FileList::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
if (event->button() == Qt::LeftButton && selectionModel()->isSelected(index))
|
||||
mPressedIndex = index;
|
||||
|
||||
QListView::mousePressEvent(event);
|
||||
}
|
||||
|
||||
void FileList::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
// Make sure the check state isn't changing.
|
||||
QModelIndex index = indexAt(event->pos());
|
||||
QVariant checked = index.data(Qt::CheckStateRole);
|
||||
|
||||
QListView::mouseReleaseEvent(event);
|
||||
|
||||
if (event->button() == Qt::LeftButton &&
|
||||
index.data(Qt::CheckStateRole) == checked && index == mPressedIndex) {
|
||||
if (event->modifiers() & Qt::ControlModifier) {
|
||||
selectionModel()->select(index, QItemSelectionModel::Deselect);
|
||||
} else {
|
||||
clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
mPressedIndex = QModelIndex();
|
||||
}
|
||||
|
||||
void FileList::contextMenuEvent(QContextMenuEvent *event)
|
||||
{
|
||||
QStringList files;
|
||||
foreach (const QModelIndex &index, selectionModel()->selectedIndexes())
|
||||
files.append(index.data(Qt::DisplayRole).toString());
|
||||
|
||||
RepoView *view = RepoView::parentView(this);
|
||||
FileContextMenu menu(view, files, mDiff.index());
|
||||
menu.exec(event->globalPos());
|
||||
}
|
||||
|
||||
void FileList::updateMenu(const git::Diff &diff)
|
||||
{
|
||||
if (!diff.isValid())
|
||||
return;
|
||||
|
||||
// sort
|
||||
Settings *settings = Settings::instance();
|
||||
int role = settings->value("sort/role").toInt();
|
||||
int order = settings->value("sort/order").toInt();
|
||||
|
||||
qreal dpr = window()->windowHandle()->devicePixelRatio();
|
||||
QPixmap pixmap(16 * dpr, 16 * dpr);
|
||||
pixmap.setDevicePixelRatio(dpr);
|
||||
pixmap.fill(Qt::transparent);
|
||||
|
||||
QIcon spacer;
|
||||
spacer.addPixmap(pixmap);
|
||||
|
||||
qreal x = pixmap.width() / (2 * dpr);
|
||||
qreal y = pixmap.height() / (2 * dpr);
|
||||
qreal f = (order == Qt::AscendingOrder) ? 1 : -1;
|
||||
|
||||
QPainterPath path;
|
||||
path.moveTo(x - (3 * f), y - (1.5 * f));
|
||||
path.lineTo(x, y + (1.5 * f));
|
||||
path.lineTo(x + (3 * f), y - (1.5 * f));
|
||||
|
||||
QPainter painter(&pixmap);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
painter.setPen(QPen(palette().color(QPalette::Text), 1.5));
|
||||
painter.drawPath(path);
|
||||
|
||||
QIcon icon;
|
||||
icon.addPixmap(pixmap);
|
||||
|
||||
mSortName->setIcon(role == git::Diff::NameRole ? icon : spacer);
|
||||
mSortStatus->setIcon(role == git::Diff::StatusRole ? icon : spacer);
|
||||
|
||||
// select
|
||||
mSelectMenu->clear();
|
||||
QSet<git_delta_t> kinds;
|
||||
for (int i = 0; i < diff.count(); ++i)
|
||||
kinds.insert(diff.status(i));
|
||||
foreach (git_delta_t kind, kinds) {
|
||||
QString name;
|
||||
switch (kind) {
|
||||
case GIT_DELTA_ADDED: name = tr("Added"); break;
|
||||
case GIT_DELTA_DELETED: name = tr("Deleted"); break;
|
||||
case GIT_DELTA_MODIFIED: name = tr("Modified"); break;
|
||||
case GIT_DELTA_RENAMED: name = tr("Renamed"); break;
|
||||
case GIT_DELTA_COPIED: name = tr("Copied"); break;
|
||||
case GIT_DELTA_IGNORED: name = tr("Ignored"); break;
|
||||
case GIT_DELTA_UNTRACKED: name = tr("Untracked"); break;
|
||||
case GIT_DELTA_UNREADABLE: name = tr("Unreadable"); break;
|
||||
case GIT_DELTA_CONFLICTED: name = tr("Conflicted"); break;
|
||||
case GIT_DELTA_UNMODIFIED: name = tr("Unmodified"); break;
|
||||
case GIT_DELTA_TYPECHANGE: name = tr("Type Change"); break;
|
||||
}
|
||||
|
||||
mSelectMenu->addAction(name, [this, kind] {
|
||||
QItemSelection selection;
|
||||
QString status(git::Diff::statusChar(kind));
|
||||
for (int i = 0; i < model()->rowCount(); ++i) {
|
||||
QModelIndex index = model()->index(i, 0);
|
||||
if (index.data(Qt::DecorationRole).toChar() == status)
|
||||
selection.select(index, index);
|
||||
}
|
||||
|
||||
selectionModel()->select(selection, QItemSelectionModel::ClearAndSelect);
|
||||
});
|
||||
}
|
||||
|
||||
// ignore whitespace
|
||||
mIgnoreWs->setChecked(settings->isWhitespaceIgnored());
|
||||
}
|
||||
|
||||
#include "FileList.moc"
|
@ -1,69 +0,0 @@
|
||||
//
|
||||
// Copyright (c) 2016, Scientific Toolworks, Inc.
|
||||
//
|
||||
// This software is licensed under the MIT License. The LICENSE.md file
|
||||
// describes the conditions under which this software may be distributed.
|
||||
//
|
||||
// Author: Jason Haslam
|
||||
//
|
||||
|
||||
#ifndef FILELIST_H
|
||||
#define FILELIST_H
|
||||
|
||||
#include "git/Diff.h"
|
||||
#include <QListView>
|
||||
|
||||
class QToolButton;
|
||||
|
||||
namespace git {
|
||||
class Repository;
|
||||
}
|
||||
|
||||
/*!
|
||||
* List view which shows the modified files
|
||||
* \brief The FileList class
|
||||
*/
|
||||
class FileList : public QListView
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FileList(const git::Repository &repo, QWidget *parent = nullptr);
|
||||
|
||||
void setDiff(const git::Diff &diff, const QString &pathspec = QString());
|
||||
|
||||
QSize sizeHint() const override;
|
||||
|
||||
/*!
|
||||
* Get the rectangle occupied by the item's checkboy.
|
||||
* Used in the UI tests
|
||||
*/
|
||||
QRect checkRect(const QModelIndex &index);
|
||||
|
||||
static void setFileRows(int rows);
|
||||
|
||||
signals:
|
||||
void sortRequested();
|
||||
|
||||
protected:
|
||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||
void mouseMoveEvent(QMouseEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void mouseReleaseEvent(QMouseEvent *event) override;
|
||||
void resizeEvent(QResizeEvent *) override;
|
||||
|
||||
private:
|
||||
void updateMenu(const git::Diff &diff);
|
||||
|
||||
QAction *mSortName;
|
||||
QAction *mSortStatus;
|
||||
QMenu *mSelectMenu;
|
||||
QMenu *mSortMenu;
|
||||
QAction *mIgnoreWs;
|
||||
QModelIndex mPressedIndex;
|
||||
QToolButton *mButton;
|
||||
|
||||
git::Diff mDiff;
|
||||
};
|
||||
|
||||
#endif
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "Test.h"
|
||||
#include "ui/DoubleTreeWidget.h"
|
||||
#include "ui/FileList.h"
|
||||
#include "ui/MainWindow.h"
|
||||
#include "ui/RepoView.h"
|
||||
#include "ui/TreeView.h"
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "ui/DetailView.h"
|
||||
#include "ui/DiffView/DiffView.h"
|
||||
#include "ui/DoubleTreeWidget.h"
|
||||
#include "ui/FileList.h"
|
||||
#include "ui/Footer.h"
|
||||
#include "ui/MainWindow.h"
|
||||
#include "ui/RepoView.h"
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "ui/CommitList.h"
|
||||
#include "ui/DetailView.h"
|
||||
#include "ui/DoubleTreeWidget.h"
|
||||
#include "ui/FileList.h"
|
||||
#include "ui/MainWindow.h"
|
||||
#include "ui/RepoView.h"
|
||||
#include "ui/TreeView.h"
|
||||
|
@ -8,7 +8,6 @@
|
||||
//
|
||||
|
||||
#include "Test.h"
|
||||
#include "ui/FileList.h"
|
||||
#include "ui/MainWindow.h"
|
||||
#include "ui/DetailView.h"
|
||||
#include "ui/DiffView/DiffView.h"
|
||||
|
Loading…
Reference in New Issue
Block a user