[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: =?utf-8?q?=5Bkdevplatform=5D_/=3A_Introduce_and_integrate_VcsFil?=
From: Andrey Batyiev <batyiev () gmail ! com>
Date: 2011-05-01 20:56:14
Message-ID: 20110501205614.01BEBA60A4 () git ! kde ! org
[Download RAW message or body]
Git commit 85bfe7888d9e3fd4f015e106ef15fa04063be739 by Andrey Batyiev.
Committed on 01/05/2011 at 22:55.
Pushed by abatyiev into branch 'master'.
Introduce and integrate VcsFileChangesModel.
REVIEW: 101145
M +1 -1 plugins/patchreview/CMakeLists.txt
M +67 -184 plugins/patchreview/patchreview.cpp
M +3 -0 plugins/patchreview/patchreview.h
M +1 -6 plugins/patchreview/patchreview.ui
M +3 -0 vcs/CMakeLists.txt
A +11 -0 vcs/models/tests/CMakeLists.txt [License: UNKNOWN] *
A +125 -0 vcs/models/tests/modelstest.cpp [License: GPL (v2/3)]
A +35 -0 vcs/models/tests/modelstest.h [License: GPL (v2/3)]
A +184 -0 vcs/models/vcsfilechangesmodel.cpp [License: LGPL (v2+)]
A +127 -0 vcs/models/vcsfilechangesmodel.h [License: LGPL (v2+)]
M +7 -77 vcs/widgets/vcscommitdialog.cpp
M +5 -23 vcs/widgets/vcscommitdialog.ui
The files marked with a * at the end have a non valid license. Please read: \
http://techbase.kde.org/Policies/Licensing_Policy and use the headers which are \
listed at that page.
http://commits.kde.org/kdevplatform/85bfe7888d9e3fd4f015e106ef15fa04063be739
diff --git a/plugins/patchreview/CMakeLists.txt b/plugins/patchreview/CMakeLists.txt
index 222e28f..ddd01b7 100644
--- a/plugins/patchreview/CMakeLists.txt
+++ b/plugins/patchreview/CMakeLists.txt
@@ -33,7 +33,7 @@ kde4_add_ui_files(patchreview_PART_SRCS ${patchreview_UI} )
kde4_add_plugin(kdevpatchreview ${patchreview_PART_SRCS})
-target_link_libraries(kdevpatchreview ${KDE4_KDEUI_LIBS} ${KDE4_KTEXTEDITOR_LIBS} \
${KDE4_KPARTS_LIBS} kdevplatforminterfaces kdevplatformutil kdevplatformlanguage \
${KDE4_KDE3SUPPORT_LIBS} sublime) +target_link_libraries(kdevpatchreview \
${KDE4_KDEUI_LIBS} ${KDE4_KTEXTEDITOR_LIBS} ${KDE4_KPARTS_LIBS} \
kdevplatforminterfaces kdevplatformutil kdevplatformlanguage \
${KDEVPLATFORM_VCS_LIBRARIES} ${KDE4_KDE3SUPPORT_LIBS} sublime)
install(TARGETS kdevpatchreview DESTINATION ${PLUGIN_INSTALL_DIR})
diff --git a/plugins/patchreview/patchreview.cpp \
b/plugins/patchreview/patchreview.cpp index 2811869..e80cdb1 100644
--- a/plugins/patchreview/patchreview.cpp
+++ b/plugins/patchreview/patchreview.cpp
@@ -74,6 +74,8 @@ std::string*/
#include <interfaces/ipatchexporter.h>
#include "standardpatchexport.h"
#include <language/highlighting/colorcache.h>
+#include <vcs/models/vcsfilechangesmodel.h>
+#include <shell/core.h>
using namespace KDevelop;
@@ -84,6 +86,43 @@ namespace {
Q_DECLARE_METATYPE( const Diff2::DiffModel* )
+
+class PatchFilesModel : public VcsFileChangesModel
+{
+public:
+ PatchFilesModel(QObject *parent, bool allowSelection = false) : \
VcsFileChangesModel(parent, allowSelection) { }; + enum ItemRoles { HunksNumberRole \
= VcsStatusInfoRole+1 }; +
+public slots:
+ void updateState(const KDevelop::VcsStatusInfo &status, unsigned hunksNum) {
+ int row = VcsFileChangesModel::updateState(invisibleRootItem(), status);
+ if (row == -1)
+ return;
+
+ QStandardItem *item = invisibleRootItem()->child(row, 0);
+ setFileInfo(item, hunksNum);
+ item->setData(QVariant(hunksNum), HunksNumberRole);
+ }
+
+ void updateState(const KDevelop::VcsStatusInfo &status) {
+ int row = VcsFileChangesModel::updateState(invisibleRootItem(), status);
+ if (row == -1)
+ return;
+
+ QStandardItem *item = invisibleRootItem()->child(row, 0);
+ setFileInfo(invisibleRootItem()->child(row, 0), \
item->data(HunksNumberRole).toUInt()); + }
+
+private:
+ void setFileInfo(QStandardItem *item, unsigned int hunksNum) {
+ QString newText = i18ncp("%1: number of changed hunks, %2: file name",
+ "%2 (1 hunk)", "%2 (%1 hunks)", hunksNum, \
item->text()); + item->setText(newText);
+ }
+};
+
+
+
PatchReviewToolView::PatchReviewToolView( QWidget* parent, PatchReviewPlugin* plugin \
) : QWidget( parent ), m_reversed( false ), m_plugin( plugin )
{
@@ -203,7 +242,7 @@ void PatchReviewToolView::fillEditFromPatch() {
void PatchReviewToolView::patchSelectionChanged(int selection)
{
- m_editPatch.filesList->clear();
+ m_fileModel->removeRows(0, m_fileModel->rowCount());
if(selection >= 0 && selection < m_plugin->knownPatches().size()) {
m_plugin->setPatch(m_plugin->knownPatches()[selection]);
}
@@ -239,6 +278,8 @@ void PatchReviewToolView::showEditDialog() {
m_editPatch.setupUi( this );
+ m_fileModel = new PatchFilesModel(this, true);
+ m_editPatch.filesList->setModel(m_fileModel);
m_editPatch.filesList->header()->hide();
m_editPatch.filesList->setRootIsDecorated(false);
@@ -439,58 +480,19 @@ void PatchReviewPlugin::highlightPatch() {
void PatchReviewToolView::finishReview()
{
- QList<KUrl> selectedUrls;
- for(int a = 0; a< m_editPatch.filesList->topLevelItemCount(); ++a) {
- QTreeWidgetItem* item = m_editPatch.filesList->topLevelItem(a);
- if(item && item->checkState(0) == Qt::Checked) {
- QVariant v = item->data(0, Qt::UserRole);
-
- if( v.canConvert<KUrl>() ) {
- selectedUrls << v.value<KUrl>();
- }else if ( v.canConvert<const Diff2::DiffModel*>() ) {
- const Diff2::DiffModel* model = v.value<const Diff2::DiffModel*>();
-
- KUrl file = m_plugin->urlForFileModel( model );
-
- selectedUrls << file;
- }
- }
- }
+ QList<KUrl> selectedUrls = m_fileModel->checkedUrls();
kDebug() << "finishing review with" << selectedUrls;
m_plugin->finishReview(selectedUrls);
}
void PatchReviewToolView::fileDoubleClicked( const QModelIndex& i ) {
- try {
- if ( !m_plugin->modelList() )
- throw "no model";
-
- QVariant v = i.data( Qt::UserRole );
-
- if( v.canConvert<KUrl>() ) {
- KUrl u = v.value<KUrl>();
- ICore::self()->documentController()->openDocument( u, \
KTextEditor::Cursor() );
- return;
- }
-
- if ( !v.canConvert<const Diff2::DiffModel*>() )
- throw "cannot convert";
- const Diff2::DiffModel* model = v.value<const Diff2::DiffModel*>();
- if ( !model )
- throw "bad model-value";
+ KUrl file = m_fileModel->statusInfo( i ).url();
- KUrl file = m_plugin->urlForFileModel( model );
+ kDebug() << "opening" << file.toLocalFile();
- kDebug() << "opening" << file.toLocalFile();
+ ICore::self()->documentController()->openDocument( file, KTextEditor::Cursor() \
);
- ICore::self()->documentController()->openDocument( file, \
KTextEditor::Cursor() );
-
- m_plugin->seekHunk( true, file );
- } catch ( const QString & str ) {
- kDebug() << "fileDoubleClicked():" << str;
- } catch ( const char * str ) {
- kDebug() << "fileDoubleClicked():" << str;
- }
+ m_plugin->seekHunk( true, file );
}
KUrl PatchReviewPlugin::urlForFileModel(const Diff2::DiffModel* model)
@@ -503,60 +505,15 @@ KUrl PatchReviewPlugin::urlForFileModel(const Diff2::DiffModel* \
model) return file;
}
-static QString stateToString(KDevelop::VcsStatusInfo::State state)
-{
- switch(state)
- {
- case KDevelop::VcsStatusInfo::ItemAdded:
- return i18nc("VCS file status", "Added");
- case KDevelop::VcsStatusInfo::ItemDeleted:
- return i18nc("VCS file status", "Deleted");
- case KDevelop::VcsStatusInfo::ItemHasConflicts:
- return i18nc("VCS file status", "Has Conflicts");
- case KDevelop::VcsStatusInfo::ItemModified:
- return i18nc("VCS file status", "Modified");
- case KDevelop::VcsStatusInfo::ItemUpToDate:
- return i18nc("VCS file status", "Up To Date");
- case KDevelop::VcsStatusInfo::ItemUnknown:
- case KDevelop::VcsStatusInfo::ItemUserState:
- return i18nc("VCS file status", "Unknown");
- }
- return i18nc("Unknown VCS file status, probably a backend error", "?");
-}
-
-static KIcon stateToIcon(KDevelop::VcsStatusInfo::State state)
-{
- switch(state)
- {
- case KDevelop::VcsStatusInfo::ItemAdded:
- return KIcon("vcs-added");
- case KDevelop::VcsStatusInfo::ItemDeleted:
- return KIcon("vcs-removed");
- case KDevelop::VcsStatusInfo::ItemHasConflicts:
- return KIcon("vcs-conflicting");
- case KDevelop::VcsStatusInfo::ItemModified:
- return KIcon("vcs-locally-modified");
- case KDevelop::VcsStatusInfo::ItemUpToDate:
- return KIcon("vcs-normal");
- case KDevelop::VcsStatusInfo::ItemUnknown:
- case KDevelop::VcsStatusInfo::ItemUserState:
- return KIcon("unknown");
- }
- return KIcon("dialog-error");
-}
-
void PatchReviewToolView::kompareModelChanged()
{
- m_editPatch.filesList->clear();
- m_editPatch.filesList->setColumnCount(1);
+ m_fileModel->removeRows(0, m_fileModel->rowCount());
if (!m_plugin->modelList())
return;
QMap<KUrl, KDevelop::VcsStatusInfo::State> additionalUrls = \
m_plugin->patch()->additionalSelectableFiles();
- QSet<KUrl> haveUrls;
-
const Diff2::DiffModelList* models = m_plugin->modelList()->models();
if( models )
{
@@ -568,88 +525,25 @@ void PatchReviewToolView::kompareModelChanged()
cnt = diffs->count();
KUrl file = m_plugin->urlForFileModel(*it);
- haveUrls.insert(file);
-
if(!QFileInfo(file.toLocalFile()).isReadable())
continue;
-
- QTreeWidgetItem* item = new QTreeWidgetItem(m_editPatch.filesList);
-
- m_editPatch.filesList->insertTopLevelItem(0, item);
-
- const QString filenameArgument = \
ICore::self()->projectController()->prettyFileName(file, \
KDevelop::IProjectController::FormatPlain);
-
- QString text;
- QIcon icon;
- if(additionalUrls.contains(file)) {
- text = i18ncp("%1: number of changed hunks, %2: file name, %3: vcs \
file state",
- "%2 (1 hunk, %3)", "%2 (%1 hunks, %3)", cnt, filenameArgument, \
stateToString(additionalUrls[file]));
- icon = stateToIcon(additionalUrls[file]);
- } else {
- text = i18ncp("%1: number of changed hunks, %2: file name",
- "%2 (1 hunk)", "%2 (%1 hunks)", cnt, filenameArgument);
- }
- item->setData( 0, Qt::DisplayRole, text );
- item->setIcon( 0, icon );
- item->setData( 0, Qt::UserRole, qVariantFromValue<const \
Diff2::DiffModel*>(*it));
- item->setCheckState( 0, Qt::Checked );
- }
- }
-
- // Maps the _really_ useful items (with VCS state) to index 0,
- // the items that have at least a project found to 1,
- // and the probably really useless items without project found to 2.
- // The project-manager filters useless stuff like backups out so they get index \
2.
- QMap<int, QList< QPair<KUrl, KDevelop::VcsStatusInfo::State> > > newItems;
-
- for(QMap<KUrl, KDevelop::VcsStatusInfo::State>::const_iterator it = \
additionalUrls.constBegin(); it != additionalUrls.constEnd(); ++it)
- {
- KUrl url = it.key();
-
- if(!haveUrls.contains(url))
- {
- haveUrls.insert(url);
-
- if(*it != KDevelop::VcsStatusInfo::ItemUnknown)
- {
- newItems[0] << qMakePair(url, *it);
- }else{
- if(((bool)ICore::self()->projectController()->findProjectForUrl(url)))
- {
- newItems[1] << qMakePair(url, *it);
- }else{
- newItems[2] << qMakePair(url, *it);
- }
- }
+ VcsStatusInfo status;
+ status.setUrl(file);
+ status.setState(VcsStatusInfo::ItemModified);
+
+ m_fileModel->updateState(status, cnt);
}
}
-
- for(int a = 0; a < 3; ++a)
- {
- for(QList< QPair< KUrl, KDevelop::VcsStatusInfo::State > >::iterator itemIt = \
newItems[a].begin(); itemIt != newItems[a].end(); ++itemIt)
- {
- KUrl url = itemIt->first;
- KDevelop::VcsStatusInfo::State state = itemIt->second;
-
- QTreeWidgetItem* item = new QTreeWidgetItem(m_editPatch.filesList);
-
- QString text = ICore::self()->projectController()->prettyFileName(url, \
KDevelop::IProjectController::FormatPlain);
- text += " (" + stateToString(state) + ")";
-
- item->setData( 0, Qt::DisplayRole, text );
- QVariant v;
- v.setValue<KUrl>( url );
- item->setData( 0, Qt::UserRole, v );
- item->setIcon( 0, stateToIcon(state) );
- item->setCheckState( 0, Qt::Unchecked );
-
- if(a == 0)
- item->setCheckState( 0, Qt::Checked );
-
- m_editPatch.filesList->addTopLevelItem(item);
- }
+
+ for(QMap<KUrl, KDevelop::VcsStatusInfo::State>::const_iterator it = \
additionalUrls.constBegin(); it != additionalUrls.constEnd(); it++) { + \
VcsStatusInfo status; + status.setUrl(it.key());
+ status.setState(it.value());
+ m_fileModel->updateState(status);
}
+
+ m_editPatch.filesList->resizeColumnToContents(0);
}
@@ -658,23 +552,12 @@ void PatchReviewToolView::documentActivated(IDocument* doc)
QModelIndexList i = m_editPatch.filesList->selectionModel() ->selectedIndexes();
if ( !m_plugin->modelList() )
return ;
- for(int a = 0; a < m_editPatch.filesList->topLevelItemCount(); ++a) {
-
- QTreeWidgetItem* item = m_editPatch.filesList->topLevelItem(a);
-
- QVariant v = item->data( 0, Qt::UserRole );
- if ( v.canConvert<const Diff2::DiffModel*>() ) {
- const Diff2::DiffModel * model = v.value<const Diff2::DiffModel*>();
-
- KUrl file = m_plugin->urlForFileModel(model);
-
- if(file == doc->url()) {
- m_editPatch.filesList->setCurrentItem(item);
- return;
- }
- }
+ QStandardItem *fileItem = m_fileModel->fileItemForUrl(doc->url());
+ if (fileItem) {
+ m_editPatch.filesList->setCurrentIndex(fileItem->index());
+ } else {
+ m_editPatch.filesList->setCurrentIndex(QModelIndex());
}
- m_editPatch.filesList->setCurrentIndex(QModelIndex());
}
void PatchHighlighter::aboutToDeleteMovingInterfaceContent(KTextEditor::Document* )
diff --git a/plugins/patchreview/patchreview.h b/plugins/patchreview/patchreview.h
index eb0bc38..8e86063 100644
--- a/plugins/patchreview/patchreview.h
+++ b/plugins/patchreview/patchreview.h
@@ -50,6 +50,7 @@ class Info;
}
namespace KDevelop {
class IDocument;
+class VcsFileChangesModel;
}
///Delete itself when the document(or textDocument), or Diff-Model is deleted.
@@ -144,6 +145,8 @@ private:
PatchReviewPlugin* m_plugin;
QPointer<QWidget> m_customWidget;
+
+ class PatchFilesModel* m_fileModel;
public slots:
void documentActivated(KDevelop::IDocument*);
void patchSelectionChanged(int);
diff --git a/plugins/patchreview/patchreview.ui b/plugins/patchreview/patchreview.ui
index 8fe9cd1..9d52dac 100644
--- a/plugins/patchreview/patchreview.ui
+++ b/plugins/patchreview/patchreview.ui
@@ -285,15 +285,10 @@
<number>0</number>
</property>
<item row="0" column="0" rowspan="2">
- <widget class="QTreeWidget" name="filesList">
+ <widget class="QTreeView" name="filesList">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
- <column>
- <property name="text">
- <string notr="true">1</string>
- </property>
- </column>
</widget>
</item>
</layout>
diff --git a/vcs/CMakeLists.txt b/vcs/CMakeLists.txt
index f3cd726..5fedee8 100644
--- a/vcs/CMakeLists.txt
+++ b/vcs/CMakeLists.txt
@@ -1,4 +1,5 @@
add_subdirectory(dvcs/tests)
+add_subdirectory(models/tests)
add_subdirectory(tests)
add_definitions(-DKDE_DEFAULT_DEBUG_AREA=9509)
@@ -32,6 +33,7 @@ set(kdevplatformvcs_LIB_SRCS
widgets/standardvcslocationwidget.cpp
models/vcsannotationmodel.cpp
models/vcseventmodel.cpp
+ models/vcsfilechangesmodel.cpp
models/vcsitemeventmodel.cpp
dvcs/dvcsjob.cpp
dvcs/dvcsplugin.cpp
@@ -91,6 +93,7 @@ install(FILES
install(FILES
models/vcsannotationmodel.h
models/vcseventmodel.h
+ models/vcsfilechangesmodel.h
models/vcsitemeventmodel.h
DESTINATION ${INCLUDE_INSTALL_DIR}/kdevplatform/vcs/models COMPONENT Devel
)
diff --git a/vcs/models/tests/CMakeLists.txt b/vcs/models/tests/CMakeLists.txt
new file mode 100644
index 0000000..e6b6942
--- /dev/null
+++ b/vcs/models/tests/CMakeLists.txt
@@ -0,0 +1,11 @@
+set(EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
+set(modelsTest_SRCS modelstest.cpp)
+kde4_add_unit_test(modelsTest ${modelsTest_SRCS})
+target_link_libraries(modelsTest
+ ${QT_QTTEST_LIBRARY}
+ ${QT_QTGUI_LIBRARY}
+ ${KDE4_KDECORE_LIBS}
+ ${KDEVPLATFORM_TESTS_LIBRARIES}
+ kdevplatformutil
+ kdevplatformvcs
+ )
diff --git a/vcs/models/tests/modelstest.cpp b/vcs/models/tests/modelstest.cpp
new file mode 100644
index 0000000..0af6ffd
--- /dev/null
+++ b/vcs/models/tests/modelstest.cpp
@@ -0,0 +1,125 @@
+/***************************************************************************
+ * Copyright 2011 Andrey Batyiev <batyiev@gmail.com> *
+ * *
+ * 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) version 3 or any later version *
+ * accepted by the membership of KDE e.V. (or its successor approved *
+ * by the membership of KDE e.V.), which shall act as a proxy *
+ * defined in Section 14 of version 3 of the license. *
+ * *
+ * 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, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include "modelstest.h"
+
+#include <QtTest/QtTest>
+#include <qtest_kde.h>
+
+#include <vcs/models/vcsfilechangesmodel.h>
+#include <tests/autotestshell.h>
+#include <tests/testcore.h>
+
+using namespace KDevelop;
+
+void ModelsTest::testInit()
+{
+ AutoTestShell::init();
+ Core::initialize();
+}
+
+
+void ModelsTest::testVcsFileChangesModel()
+{
+ VcsFileChangesModel *model = new VcsFileChangesModel(this);
+
+ // Newly created model should be empty
+ QVERIFY(model->rowCount() == 0);
+
+ // Pull some files into
+ QString filenames[] = {"foo", "bar", "pew", "trash"};
+ VcsStatusInfo::State states[] = {VcsStatusInfo::ItemAdded, \
VcsStatusInfo::ItemModified, VcsStatusInfo::ItemDeleted, \
VcsStatusInfo::ItemUpToDate}; + VcsStatusInfo status;
+
+ for(int i = 0; i < 3; i++) {
+ status.setUrl(KUrl(filenames[i]));
+ status.setState(states[i]);
+ model->updateState(status);
+ QVERIFY(model->rowCount() == (i+1));
+ }
+
+ // Pulling up-to-date file doesn't change anything
+ {
+ status.setUrl(KUrl(filenames[3]));
+ status.setState(states[3]);
+ model->updateState(status);
+ QVERIFY(model->rowCount() == 3);
+ }
+
+ // Check that all OK
+ for(int i = 0; i < 3; i++) {
+ QStandardItem* item = model->fileItemForUrl(filenames[i]);
+ QVERIFY(item);
+ VcsStatusInfo info = VcsFileChangesModel::statusInfo(item);
+ QVERIFY(info.url().toLocalFile() == filenames[i]);
+ QVERIFY(info.state() == states[i]);
+ }
+
+ // Pull it all again = nothing changed
+ for(int i = 0; i < 3; i++) {
+ status.setUrl(KUrl(filenames[i]));
+ status.setState(states[i]);
+ model->updateState(status);
+ QVERIFY(model->rowCount() == 3);
+ }
+
+ // Check that all OK
+ for(int i = 0; i < 3; i++) {
+ QStandardItem* item = model->fileItemForUrl(filenames[i]);
+ QVERIFY(item);
+ VcsStatusInfo info = VcsFileChangesModel::statusInfo(item);
+ QVERIFY(info.url().toLocalFile() == filenames[i]);
+ QVERIFY(info.state() == states[i]);
+ }
+
+ // Remove one file
+ {
+ states[1] = VcsStatusInfo::ItemUpToDate;
+ status.setUrl(KUrl(filenames[1]));
+ status.setState(states[1]);
+ model->updateState(status);
+ QVERIFY(model->rowCount() == 2);
+ }
+
+ // Check them all
+ for(int i = 0; i < 3; i++) {
+ if(states[i] != VcsStatusInfo::ItemUpToDate && states[i] != \
VcsStatusInfo::ItemUnknown) { + QStandardItem* item = \
model->fileItemForUrl(filenames[i]); + QVERIFY(item);
+ VcsStatusInfo info = VcsFileChangesModel::statusInfo(item);
+ QVERIFY(info.url().toLocalFile() == filenames[i]);
+ QVERIFY(info.state() == states[i]);
+ }
+ }
+
+ // Delete them all
+ model->removeRows(0, model->rowCount());
+ QVERIFY(model->rowCount() == 0);
+
+ // Pull it all again
+ for(int i = 0; i < 3; i++) {
+ status.setUrl(KUrl(filenames[i]));
+ status.setState(states[i]);
+ model->updateState(status);
+ }
+ QVERIFY(model->rowCount() == 2);
+}
+
+QTEST_KDEMAIN(ModelsTest, GUI);
diff --git a/vcs/models/tests/modelstest.h b/vcs/models/tests/modelstest.h
new file mode 100644
index 0000000..81587d6
--- /dev/null
+++ b/vcs/models/tests/modelstest.h
@@ -0,0 +1,35 @@
+/***************************************************************************
+ * Copyright 2011 Andrey Batyiev <batyiev@gmail.com> *
+ * *
+ * 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) version 3 or any later version *
+ * accepted by the membership of KDE e.V. (or its successor approved *
+ * by the membership of KDE e.V.), which shall act as a proxy *
+ * defined in Section 14 of version 3 of the license. *
+ * *
+ * 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, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#ifndef MODELSTEST_H
+#define MODELSTEST_H
+
+#include <QObject>
+
+
+class ModelsTest : public QObject
+{
+ Q_OBJECT
+private slots:
+ void testInit();
+ void testVcsFileChangesModel();
+};
+
+#endif // MODELSTEST_H
diff --git a/vcs/models/vcsfilechangesmodel.cpp b/vcs/models/vcsfilechangesmodel.cpp
new file mode 100644
index 0000000..ff87e8b
--- /dev/null
+++ b/vcs/models/vcsfilechangesmodel.cpp
@@ -0,0 +1,184 @@
+/* This file is part of KDevelop
+ Copyright 2010 Aleix Pol <aleixpol@kde.org>
+
+ Splitted into separate class
+ Copyright 2011 Andrey Batyiev <batyiev@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <KLocale>
+#include <KIcon>
+#include <KMimeType>
+#include <KDebug>
+
+#include <interfaces/icore.h>
+#include <interfaces/iprojectcontroller.h>
+
+#include <vcs/vcsstatusinfo.h>
+
+#include "vcsfilechangesmodel.h"
+
+namespace KDevelop
+{
+
+static QString stateToString(KDevelop::VcsStatusInfo::State state)
+{
+ switch(state)
+ {
+ case KDevelop::VcsStatusInfo::ItemAdded:
+ return i18nc("file was added to versioncontrolsystem", "Added");
+ case KDevelop::VcsStatusInfo::ItemDeleted:
+ return i18nc("file was deleted from versioncontrolsystem", "Deleted");
+ case KDevelop::VcsStatusInfo::ItemHasConflicts:
+ return i18nc("file is confilicting (versioncontrolsystem)", "Has \
Conflicts"); + case KDevelop::VcsStatusInfo::ItemModified:
+ return i18nc("version controlled file was modified", "Modified");
+ case KDevelop::VcsStatusInfo::ItemUpToDate:
+ return i18nc("file is up to date in versioncontrolsystem", "Up To \
Date"); + case KDevelop::VcsStatusInfo::ItemUnknown:
+ case KDevelop::VcsStatusInfo::ItemUserState:
+ return i18nc("file is not known to versioncontrolsystem", "Unknown");
+ }
+ return i18nc("Unknown VCS file status, probably a backend error", "?");
+}
+
+static KIcon stateToIcon(KDevelop::VcsStatusInfo::State state)
+{
+ switch(state)
+ {
+ case KDevelop::VcsStatusInfo::ItemAdded:
+ return KIcon("vcs-added");
+ case KDevelop::VcsStatusInfo::ItemDeleted:
+ return KIcon("vcs-removed");
+ case KDevelop::VcsStatusInfo::ItemHasConflicts:
+ return KIcon("vcs-conflicting");
+ case KDevelop::VcsStatusInfo::ItemModified:
+ return KIcon("vcs-locally-modified");
+ case KDevelop::VcsStatusInfo::ItemUpToDate:
+ return KIcon("vcs-normal");
+ case KDevelop::VcsStatusInfo::ItemUnknown:
+ case KDevelop::VcsStatusInfo::ItemUserState:
+ return KIcon("unknown");
+ }
+ return KIcon("dialog-error");
+}
+
+class VcsFileChangesModelPrivate
+{
+public:
+ bool allowSelection;
+};
+
+VcsFileChangesModel::VcsFileChangesModel(QObject *parent, bool allowSelection)
+ : QStandardItemModel(parent), d(new VcsFileChangesModelPrivate)
+{
+ setColumnCount(2);
+ setHeaderData(0, Qt::Horizontal, i18n("Filename"));
+ setHeaderData(1, Qt::Horizontal, i18n("Status"));
+ d->allowSelection = allowSelection;
+}
+
+int VcsFileChangesModel::updateState(QStandardItem *parent, const \
KDevelop::VcsStatusInfo &status) +{
+ QStandardItem* it1=0;
+ QStandardItem* itStatus;
+
+ it1=fileItemForUrl(parent, status.url());
+
+ if(status.state()==VcsStatusInfo::ItemUnknown || \
status.state()==VcsStatusInfo::ItemUpToDate) { + if(it1)
+ parent->removeRow(it1->row());
+ return -1;
+ } else {
+ if(!it1) {
+ QString path = \
ICore::self()->projectController()->prettyFileName(status.url(), \
KDevelop::IProjectController::FormatPlain); + KIcon \
icon(KMimeType::findByUrl(status.url(), 0, false, true)->iconName(status.url())); + \
it1 = new QStandardItem(icon, path); + itStatus = new QStandardItem;
+
+ if(d->allowSelection) {
+ it1->setCheckable(true);
+ it1->setCheckState(status.state() == VcsStatusInfo::ItemUnknown ? \
Qt::Unchecked : Qt::Checked); + }
+
+ parent->appendRow(QList<QStandardItem*>() << it1 << itStatus);
+ } else {
+ QStandardItem *parent = it1->parent();
+ if(parent == 0)
+ parent = invisibleRootItem();
+ itStatus = parent->child(it1->row(), 1);
+ }
+
+ QString text = stateToString(status.state());
+ if(itStatus->text()!=text) {
+ itStatus->setText(text);
+ itStatus->setIcon(stateToIcon(status.state()));
+ }
+ it1->setData(qVariantFromValue<VcsStatusInfo>(status), VcsStatusInfoRole);
+ return it1->row();
+ }
+}
+
+QStandardItem* VcsFileChangesModel::fileItemForUrl(QStandardItem* parent, const \
QUrl& url) +{
+ for(int i=0; i<parent->rowCount(); i++) {
+ QStandardItem* curr=parent->child(i);
+
+ if(curr->data(VcsStatusInfoRole).value<VcsStatusInfo>().url()==url) {
+ return curr;
+ }
+ }
+
+ return 0;
+}
+
+QList<VcsStatusInfo> VcsFileChangesModel::checkedStatuses(QStandardItem *parent) \
const +{
+ QList<VcsStatusInfo> ret;
+
+ if(!d->allowSelection)
+ return ret;
+
+ for(int i = 0; i < parent->rowCount(); i++) {
+ QStandardItem* item = parent->child(i);
+ if(item->checkState() == Qt::Checked) {
+ ret << statusInfo(item);
+ }
+ }
+
+ return ret;
+}
+
+QList<KUrl> VcsFileChangesModel::checkedUrls(QStandardItem *parent) const
+{
+ QList<KUrl> ret;
+
+ if(!d->allowSelection)
+ return ret;
+
+ for(int i = 0; i < parent->rowCount(); i++) {
+ QStandardItem* item = parent->child(i);
+ if(item->checkState() == Qt::Checked) {
+ ret << statusInfo(item).url();
+ }
+ }
+
+ return ret;
+}
+
+
+}
diff --git a/vcs/models/vcsfilechangesmodel.h b/vcs/models/vcsfilechangesmodel.h
new file mode 100644
index 0000000..af02e80
--- /dev/null
+++ b/vcs/models/vcsfilechangesmodel.h
@@ -0,0 +1,127 @@
+/* This file is part of KDevelop
+ Copyright 2010 Aleix Pol <aleixpol@kde.org>
+
+ Splitted into separate class
+ Copyright 2011 Andrey Batyiev <batyiev@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef FILECHANGESMODEL_H
+#define FILECHANGESMODEL_H
+
+#include <QStandardItemModel>
+
+#include <vcs/vcsstatusinfo.h>
+
+#include "../vcsexport.h"
+
+class KUrl;
+
+namespace KDevelop
+{
+class VcsStatusInfo;
+
+/**
+ * This class holds and represents information about changes in files.
+ * Also it is possible to provide tree like models by inheriting this class, see \
protected members. + * All stuff should be pulled in by @p updateState.
+ */
+
+class KDEVPLATFORMVCS_EXPORT VcsFileChangesModel : public QStandardItemModel
+{
+ Q_OBJECT
+public:
+ /**
+ * Constructor for class.
+ * @param allowSelection if true, model will show checkboxes on items.
+ */
+ VcsFileChangesModel(QObject *parent, bool allowSelection = false);
+ enum ItemRoles { VcsStatusInfoRole = Qt::UserRole+1 };
+
+ /**
+ * Returns item for particular url.
+ */
+ QStandardItem* fileItemForUrl(const QUrl &url) {
+ return fileItemForUrl(invisibleRootItem(), url);
+ }
+
+ /**
+ * Returns list of currently checked statuses.
+ */
+ QList<VcsStatusInfo> checkedStatuses() const {
+ return checkedStatuses(invisibleRootItem());
+ }
+
+ /**
+ * Returns list of currently checked urls.
+ */
+ QList<KUrl> checkedUrls() const {
+ return checkedUrls(invisibleRootItem());
+ }
+
+
+ /**
+ * Simple helper to get VcsStatusInfo.
+ */
+ static VcsStatusInfo statusInfo(const QModelIndex &i) {
+ return i.data(VcsStatusInfoRole).value<VcsStatusInfo>();
+ }
+
+ /**
+ * Simple helper to get VcsStatusInfo.
+ */
+ static VcsStatusInfo statusInfo(const QStandardItem *item) {
+ return item->data(VcsStatusInfoRole).value<VcsStatusInfo>();
+ }
+
+public slots:
+ /**
+ * Used to post update of status of some file. Any status except UpToDate
+ * and Unknown will update (or add) item representation.
+ */
+ void updateState(const KDevelop::VcsStatusInfo &status) {
+ updateState(invisibleRootItem(), status);
+ }
+
+protected:
+ /**
+ * Post update of status of some file.
+ * @return changed row or -1 if row is deleted
+ */
+ int updateState(QStandardItem *parent, const KDevelop::VcsStatusInfo &status);
+
+ /**
+ * Returns item for particular url.
+ */
+ static QStandardItem* fileItemForUrl(QStandardItem *parent, const QUrl &url);
+
+ /**
+ * Returns list of currently checked statuses.
+ */
+ QList<VcsStatusInfo> checkedStatuses(QStandardItem *parent) const;
+
+ /**
+ * Returns list of currently checked urls.
+ */
+ QList<KUrl> checkedUrls(QStandardItem *parent) const;
+
+private:
+ class VcsFileChangesModelPrivate *const d;
+};
+}
+
+#endif // FILECHANGESMODEL_H
diff --git a/vcs/widgets/vcscommitdialog.cpp b/vcs/widgets/vcscommitdialog.cpp
index fca9e94..607d5aa 100644
--- a/vcs/widgets/vcscommitdialog.cpp
+++ b/vcs/widgets/vcscommitdialog.cpp
@@ -35,6 +35,7 @@
#include "../interfaces/idistributedversioncontrol.h"
#include "../interfaces/icentralizedversioncontrol.h"
#include "../vcsstatusinfo.h"
+#include "../models/vcsfilechangesmodel.h"
#include "ui_vcscommitdialog.h"
#include <KComponentData>
@@ -46,47 +47,13 @@ namespace KDevelop
class VcsCommitDialogPrivate
{
public:
-
- VcsCommitDialogPrivate(VcsCommitDialog* dialog)
- : dlg(dialog)
- {}
-
- void insertRow( const QString& state, const KUrl& url,
- const KStatefulBrush &foregroundColor = \
KStatefulBrush(KColorScheme::View, KColorScheme::NormalText),
- Qt::CheckState checkstate = Qt::Checked)
- {
- QStringList strings;
- strings << "" << state << \
ICore::self()->projectController()->prettyFileName(url, \
KDevelop::IProjectController::FormatPlain);
- QTreeWidgetItem *item = new QTreeWidgetItem( ui.files, strings );
- item->setData(0, Qt::UserRole, url);
- item->setForeground(2, foregroundColor.brush(dlg));
- item->setCheckState(0, checkstate);
- }
-
- QList< KUrl > selection() {
- if(!m_selection.isEmpty())
- return m_selection;
-
- QList< KUrl > ret;
-
- QTreeWidgetItemIterator it( ui.files, QTreeWidgetItemIterator::Checked );
- for( ; *it; ++it ){
- QVariant v = (*it)->data(0, Qt::UserRole);
- Q_ASSERT(v.canConvert<KUrl>());
- ret << v.value<KUrl>();
- }
-
- return ret;
- }
-
- VcsCommitDialog* dlg;
Ui::VcsCommitDialog ui;
- QList< KUrl > m_selection;
IPatchSource* m_patchSource;
+ VcsFileChangesModel* m_model;
};
VcsCommitDialog::VcsCommitDialog( IPatchSource *patchSource, QWidget *parent )
- : KDialog( parent ), d(new VcsCommitDialogPrivate(this))
+ : KDialog( parent ), d(new VcsCommitDialogPrivate())
{
d->ui.setupUi( mainWidget() );
QWidget *customWidget = patchSource->customWidget();
@@ -97,9 +64,9 @@ VcsCommitDialog::VcsCommitDialog( IPatchSource *patchSource, \
QWidget *parent )
setButtons( KDialog::Ok | KDialog::Cancel );
- d->ui.files->resizeColumnToContents(0);
- d->ui.files->resizeColumnToContents(1);
d->m_patchSource = patchSource;
+ d->m_model = new VcsFileChangesModel( this, true );
+ d->ui.files->setModel( d->m_model );
connect(this, SIGNAL( okClicked() ), SLOT( ok() ) );
connect(this, SIGNAL( cancelClicked() ), SLOT( cancel() ) );
}
@@ -116,47 +83,10 @@ void VcsCommitDialog::setRecursive( bool recursive )
void VcsCommitDialog::setCommitCandidates( const QVariant& statuses )
{
- KStatefulBrush deletedRed(KColorScheme::View, KColorScheme::NegativeText);
- KStatefulBrush newGreen(KColorScheme::View, KColorScheme::ActiveText);
-
foreach( const QVariant &var, statuses.toList() )
{
VcsStatusInfo info = qVariantValue<KDevelop::VcsStatusInfo>( var );
-
- QString state;
- KStatefulBrush brush(KColorScheme::View, KColorScheme::NormalText);
- Qt::CheckState checked = Qt::Checked;
-
- switch( info.state() )
- {
- case VcsStatusInfo::ItemAdded:
- state = i18nc("file was added to versioncontrolsystem", "Added");
- brush = newGreen;
- break;
- case VcsStatusInfo::ItemDeleted:
- state = i18nc("file was deleted from versioncontrolsystem", \
"Deleted");
- brush = deletedRed;
- break;
- case VcsStatusInfo::ItemModified:
- state = i18nc("version controlled file was modified", "Modified");
- break;
- case VcsStatusInfo::ItemUnknown:
- state = i18nc("file is not known to versioncontrolsystem", \
"Unknown");
- brush = newGreen;
- checked = Qt::Unchecked;
- break;
- default:
- break;
- }
-
- if(!state.isEmpty())
- {
- d->insertRow(state, info.url(), brush, checked);
- }
- }
- if( d->ui.files->topLevelItemCount() == 0 )
- {
- reject();
+ d->m_model->updateState( info );
}
}
@@ -167,7 +97,7 @@ bool VcsCommitDialog::recursive() const
void VcsCommitDialog::ok()
{
- if( d->m_patchSource->finishReview(d->selection()) )
+ if( d->m_patchSource->finishReview( d->m_model->checkedUrls() ) )
{
deleteLater();
}
diff --git a/vcs/widgets/vcscommitdialog.ui b/vcs/widgets/vcscommitdialog.ui
index 5f09c95..f32f8a2 100644
--- a/vcs/widgets/vcscommitdialog.ui
+++ b/vcs/widgets/vcscommitdialog.ui
@@ -38,31 +38,13 @@
</widget>
</item>
<item row="2" column="0" colspan="2">
- <widget class="QTreeWidget" name="files">
- <property name="windowTitle">
- <string>Select Files to commit</string>
+ <widget class="QTreeView" name="files">
+ <property name="editTriggers">
+ <set>QAbstractItemView::NoEditTriggers</set>
</property>
- <property name="indentation">
- <number>0</number>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
</property>
- <property name="allColumnsShowFocus">
- <bool>true</bool>
- </property>
- <column>
- <property name="text">
- <string/>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Status</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Files to commit</string>
- </property>
- </column>
</widget>
</item>
</layout>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic