summaryrefslogtreecommitdiff
path: root/kodereviewer
diff options
context:
space:
mode:
Diffstat (limited to 'kodereviewer')
-rw-r--r--kodereviewer/models/file.py75
-rw-r--r--kodereviewer/qml/FilesDrawer.qml70
-rw-r--r--kodereviewer/qml/KRContextDrawer.qml36
-rw-r--r--kodereviewer/qml/Main.qml27
-rw-r--r--kodereviewer/qml/PullRequestDescription.qml225
-rw-r--r--kodereviewer/qml/PullRequestFilesDrawer.qml57
-rw-r--r--kodereviewer/qml/PullRequestPage.qml74
7 files changed, 364 insertions, 200 deletions
diff --git a/kodereviewer/models/file.py b/kodereviewer/models/file.py
index 4f0d139..43fcbe4 100644
--- a/kodereviewer/models/file.py
+++ b/kodereviewer/models/file.py
@@ -22,8 +22,11 @@ logger = logging.getLogger(__name__)
@dataclass
class FileItem:
- filename: str
+ path: str
+ icon: str
+ name: str
parent: Self | None
+ patch: str | None = None
children: list[Self] = field(default_factory=list)
def append(self, child: Self):
@@ -48,8 +51,11 @@ class FileItem:
"""Only the filename."""
return 1
+ def is_file(self) -> bool:
+ return self.patch is not None
+
def __str__(self) -> str:
- return f'{self.filename} | {id(self.parent)} | {[x.filename for x in self.children]}'
+ return f'{self.name} | {id(self.parent)} | {[x.name for x in self.children]}'
@QmlElement
@@ -60,18 +66,23 @@ class TreeFileModel(QAbstractItemModel):
root_node: FileItem
_pull_request: Optional[PullRequest]
+ class Roles(IntEnum):
+ Filename = Qt.ItemDataRole.UserRole + 1
+ Path = auto()
+ IconName = auto()
+ Patch = auto()
+ IsFile = auto()
+
def __init__(self):
super().__init__()
- self.root_node = FileItem('./', None)
+ self.root_node = FileItem('./', '', './', parent=None)
self._pull_request = None
- def load_files(self, filenames: list[str]):
- logger.info(f'Loading {filenames}')
- self.filenames = filenames
+ def load_files(self, files: list[ChangedFile]):
self.dir_mapping: dict[str, FileItem] = {}
- root_node = FileItem('./', None)
- for file in self.filenames:
- p = Path(file)
+ root_node = FileItem('./', '', './', parent=None)
+ for file in files:
+ p = Path(file.filename)
directories = p.parts[:-1]
fname = p.name
current_path = Path('')
@@ -79,15 +90,13 @@ class TreeFileModel(QAbstractItemModel):
for dir in directories:
current_path = current_path / dir
if str(current_path) not in self.dir_mapping:
- logger.info(f'Creating {current_path}')
self.dir_mapping[str(current_path)] = FileItem(
- str(current_path), parent
+ path=str(current_path), name=current_path.name, icon='inode-directory-symbolic', parent=parent
)
- logger.info(f'Appending to {parent}')
parent.append(self.dir_mapping[str(current_path)])
parent = self.dir_mapping[str(current_path)]
- file_item = FileItem(fname, parent)
+ file_item = FileItem(path=str(p), name=fname, icon='document-open-symbolic', patch=file.patch, parent=parent)
parent.append(file_item)
self.root_node = root_node
logger.info(self.root_node)
@@ -116,20 +125,19 @@ class TreeFileModel(QAbstractItemModel):
def _reset_model(self) -> None:
logger.info('reseting model')
self.beginResetModel()
- filenames = [f.filename for f in self._pull_request.files]
- self.load_files(filenames)
+ self.load_files(self._pull_request.files)
self.endResetModel()
def index(self, row: int, column: int,
- index: QModelIndex = QModelIndex()) -> QModelIndex:
+ parent: QModelIndex = QModelIndex()) -> QModelIndex:
"""Returns the index of the item in the model specified by the given row, column and parent index."""
- if not self.hasIndex(row, column, index):
+ if not self.hasIndex(row, column, parent):
return QModelIndex()
item: FileItem
- if not index.isValid():
+ if not parent.isValid():
item = self.root_node
else:
- item = index.internalPointer()
+ item = parent.internalPointer()
if item.child(row):
return self.createIndex(row, column, item.child(row))
@@ -166,25 +174,32 @@ class TreeFileModel(QAbstractItemModel):
def columnCount(self, parent: QModelIndex = QModelIndex()) -> int:
return 1
- FilenameRole = Qt.ItemDataRole.UserRole + 1
-
def data(self, index: QModelIndex, role: int) -> Any:
if not index.isValid():
return ''
- filename = index.internalPointer().filename
- name = Path(filename).name
- logger.info(index)
- logger.info(f'Role: {role} | {self.FilenameRole}')
+ item: FileItem = index.internalPointer()
+
if role == Qt.ItemDataRole.DisplayRole:
- return name
- if role == self.FilenameRole:
- logger.info(name)
- return name
+ return item.name
+ if role == self.Roles.Filename:
+ return item.name
+ if role == self.Roles.Path:
+ return item.path
+ if role == self.Roles.IconName:
+ return item.icon
+ if role == self.Roles.Patch:
+ return item.patch
+ if role == self.Roles.IsFile:
+ return item.is_file()
return None
def roleNames(self) -> dict[int, QByteArray]:
return {
- self.FilenameRole: QByteArray(b'filename'),
+ self.Roles.Filename: QByteArray(b'filename'),
+ self.Roles.IconName: QByteArray(b'iconName'),
+ self.Roles.Path: QByteArray(b'path'),
+ self.Roles.Patch: QByteArray(b'patch'),
+ self.Roles.IsFile: QByteArray(b'isFile'),
}
diff --git a/kodereviewer/qml/FilesDrawer.qml b/kodereviewer/qml/FilesDrawer.qml
new file mode 100644
index 0000000..3f98290
--- /dev/null
+++ b/kodereviewer/qml/FilesDrawer.qml
@@ -0,0 +1,70 @@
+import QtQuick
+import QtQuick.Controls as QQC2
+import QtQuick.Layouts
+import org.kde.kirigami as Kirigami
+import org.kde.kirigamiaddons.delegates as Delegates
+import org.kde.kitemmodels
+
+import org.deprecated.kodereviewer 1.0
+
+
+Kirigami.ContextDrawer {
+ id: contextDrawer
+ modal: false
+ handleVisible: false
+ property alias model: descendantsModel.model
+ width: Kirigami.Units.gridUnit * 20
+
+ signal fileSelected(string filename, string text)
+
+ contentItem: ColumnLayout {
+ id: mainLayout
+ implicitWidth: Kirigami.Units.gridUnit * 20
+ QQC2.ToolBar {
+ id: toolbar
+ Layout.fillWidth: true
+
+ Layout.preferredHeight: pageStack.globalToolBar.preferredHeight
+
+ contentItem: RowLayout {
+ Kirigami.Heading {
+ Layout.fillWidth: true
+ text: "Files"
+ }
+ }
+ }
+
+ QQC2.ScrollView {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ ListView {
+ anchors.fill: parent
+ clip: true
+ id: menu
+ model: KDescendantsProxyModel {
+ id: descendantsModel
+ }
+
+ delegate: Delegates.RoundedTreeDelegate {
+ padding: 4
+ required property string filename
+ required property string iconName
+ required property string path
+ required property string patch
+ required property bool isFile
+ text: filename
+ icon.name: iconName
+
+ highlighted: menu.currentItem ? menu.currentItem.path == path : false
+ onClicked: {
+ menu.currentIndex = index
+ if (isFile) {
+ contextDrawer.fileSelected(filename, patch)
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/kodereviewer/qml/KRContextDrawer.qml b/kodereviewer/qml/KRContextDrawer.qml
deleted file mode 100644
index c3923fa..0000000
--- a/kodereviewer/qml/KRContextDrawer.qml
+++ /dev/null
@@ -1,36 +0,0 @@
-import QtQuick
-import QtQuick.Controls as QQC2
-import org.kde.kirigami as Kirigami
-import org.kde.kirigamiaddons.delegates as Delegates
-import org.kde.kitemmodels
-
-import org.deprecated.kodereviewer 1.0
-
-
-Kirigami.ContextDrawer {
- id: contextDrawer
- // modal: false
- handleVisible: false
- property alias model: descendantsModel.model
- contentItem: QQC2.ScrollView {
- implicitWidth: Kirigami.Units.gridUnit * 20
- ListView {
- anchors.fill: parent
- clip: true
- id: menu
- model: KDescendantsProxyModel {
- id: descendantsModel
- }
-
- delegate: Delegates.RoundedTreeDelegate {
- required property string filename
- text: filename
-
- highlighted: menu.currentItem ? menu.currentItem.filename == filename : false
- onClicked: {
- menu.currentIndex = index
- }
- }
- }
- }
-}
diff --git a/kodereviewer/qml/Main.qml b/kodereviewer/qml/Main.qml
index 56248d7..1c5e951 100644
--- a/kodereviewer/qml/Main.qml
+++ b/kodereviewer/qml/Main.qml
@@ -46,6 +46,29 @@ Kirigami.ApplicationWindow {
}
}
+
+
+ Loader {
+ id: treeFileModelLoader
+ active: !!pullRequest
+ property var pullRequest: undefined
+
+ sourceComponent: TreeFileModel {
+ pullRequest: treeFileModelLoader.pullRequest
+ }
+ }
+
+ contextDrawer: FilesDrawer {
+ id: contextDrawer
+ enabled: treeFileModelLoader.active
+ model: treeFileModelLoader.item
+
+ onEnabledChanged: {
+ print("Enabled? " + enabled)
+ }
+ }
+
+
Loader {
id: projectListPageLoader
active: false
@@ -55,7 +78,9 @@ Kirigami.ApplicationWindow {
project: root.project
onPullRequestSelected: number => {
- pullRequestPageLoader.item.pullRequest = project.pullRequest(number)
+ const pullRequest = project.pullRequest(number)
+ pullRequestPageLoader.item.pullRequest = pullRequest
+ treeFileModelLoader.pullRequest = pullRequest
}
}
}
diff --git a/kodereviewer/qml/PullRequestDescription.qml b/kodereviewer/qml/PullRequestDescription.qml
index de5a679..075b210 100644
--- a/kodereviewer/qml/PullRequestDescription.qml
+++ b/kodereviewer/qml/PullRequestDescription.qml
@@ -1,137 +1,158 @@
-pragma ComponentBehavior: Bound
-import QtQuick
import QtCore
+//pragma ComponentBehavior: Bound
+import QtQuick
import QtQuick.Controls as QQC2
import QtQuick.Layouts
-
+import org.deprecated.kodereviewer 1.0
import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard
-import org.deprecated.kodereviewer 1.0
-
-ScrollView {
+Kirigami.FormLayout {
id: root
- property var pullRequest: undefined
- anchors.fill: parent
+ property var pullRequest
+ implicitWidth: parent.width
- Kirigami.FormLayout {
- anchors.fill: parent
- implicitWidth: parent.width
+ Kirigami.Heading {
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignHCenter
+ leftPadding: Kirigami.Units.largeSpacing
+ rightPadding: Kirigami.Units.largeSpacing
+ level: 1
+ text: root.pullRequest ? root.pullRequest.title : ""
+ wrapMode: Text.WordWrap
+ }
- Kirigami.Heading {
- Layout.fillWidth: true
- Layout.alignment: Qt.AlignHCenter
- leftPadding: Kirigami.Units.largeSpacing
- rightPadding: Kirigami.Units.largeSpacing
- level: 1
- text: root.pullRequest ? root.pullRequest.title : ""
- wrapMode: Text.WordWrap
- }
+ Kirigami.Separator {
+ Kirigami.FormData.isSection: true
+ }
- Kirigami.Separator {
- Kirigami.FormData.isSection: true
- }
+ RowLayout {
+ Layout.fillWidth: true
- RowLayout {
+ ColumnLayout {
Layout.fillWidth: true
- ColumnLayout {
- Layout.fillWidth: true
- RowLayout {
- QQC2.Label {
- text: "Author"
- elide: Text.ElideRight
- }
- QQC2.Label {
- text: root.pullRequest ? root.pullRequest.username : ""
- elide: Text.ElideLeft
- }
+
+ RowLayout {
+ QQC2.Label {
+ text: "Author"
+ elide: Text.ElideRight
}
- RowLayout {
- QQC2.Label {
- text: "State: "
- elide: Text.ElideRight
- }
- QQC2.Label {
- text: root.pullRequest ? root.pullRequest.state : ""
- elide: Text.ElideLeft
- }
+
+ QQC2.Label {
+ text: root.pullRequest ? root.pullRequest.username : ""
+ elide: Text.ElideLeft
}
- RowLayout {
- QQC2.Label {
- text: "Draft?: "
- elide: Text.ElideRight
- }
- QQC2.Label {
- text: root.pullRequest ? root.pullRequest.draft ? i18n("Yes") : i18n("No") : ""
- elide: Text.ElideLeft
- }
+
+ }
+
+ RowLayout {
+ QQC2.Label {
+ text: "State: "
+ elide: Text.ElideRight
}
- RowLayout {
- QQC2.Label {
- text: "Last commit: "
- elide: Text.ElideRight
- }
- QQC2.Label {
- text: root.pullRequest ? root.pullRequest.last_commit : ""
- elide: Text.ElideLeft
- }
+ QQC2.Label {
+ text: root.pullRequest ? root.pullRequest.state : ""
+ elide: Text.ElideLeft
}
+
}
- ColumnLayout {
- Layout.fillWidth: false
- Layout.fillHeight: true
- Repeater {
- model: 0
- delegate: QQC2.Label {
- text: "#Faa"
- }
+ RowLayout {
+ QQC2.Label {
+ text: "Draft?: "
+ elide: Text.ElideRight
}
+
+ QQC2.Label {
+ text: root.pullRequest ? root.pullRequest.draft ? i18n("Yes") : i18n("No") : ""
+ elide: Text.ElideLeft
+ }
+
}
- }
- Loader {
- id: labelModelLoader
- active: !!root.pullRequest
- sourceComponent: LabelModel {
- pullRequest: root.pullRequest
+ RowLayout {
+ QQC2.Label {
+ text: "Last commit: "
+ elide: Text.ElideRight
+ }
+
+ QQC2.Label {
+ text: root.pullRequest ? root.pullRequest.last_commit : ""
+ elide: Text.ElideLeft
+ }
+
}
+
}
- RowLayout {
+ ColumnLayout {
+ Layout.fillWidth: false
+ Layout.fillHeight: true
+
Repeater {
- model: labelModelLoader.item
- delegate: Rectangle {
- required property string name
- required property string labelColor
- required property string textColor
- color: labelColor
- width: thelabel.implicitWidth
- height: thelabel.implicitHeight
- radius: 5
- QQC2.Label {
- id: thelabel
- padding: Kirigami.Units.smallSpacing
- text: name
- color: textColor
- }
+ model: 0
+
+ delegate: QQC2.Label {
+ text: "#Faa"
}
+
}
+
}
- Kirigami.Separator {
- Kirigami.FormData.isSection: true
- Kirigami.FormData.label: "Description"
+ }
+
+ Loader {
+ id: labelModelLoader
+
+ active: !!root.pullRequest
+
+ sourceComponent: LabelModel {
+ pullRequest: root.pullRequest
}
- MarkdownLabel {
- Layout.fillWidth: true
- Layout.fillHeight: false
- leftPadding: Kirigami.Units.largeSpacing
- rightPadding: Kirigami.Units.largeSpacing
- text: root.pullRequest ?
- (root.pullRequest.body != "" ? root.pullRequest.body : "*No description provided.*") : ""
+ }
+
+ RowLayout {
+ Repeater {
+ model: labelModelLoader.item
+
+ delegate: Rectangle {
+ required property string name
+ required property string labelColor
+ required property string textColor
+
+ color: labelColor
+ width: thelabel.implicitWidth
+ height: thelabel.implicitHeight
+ radius: 5
+
+ QQC2.Label {
+ id: thelabel
+
+ padding: Kirigami.Units.smallSpacing
+ text: name
+ color: textColor
+ }
+
+ }
+
}
+
+ }
+
+ Kirigami.Separator {
+ Kirigami.FormData.isSection: true
+ Kirigami.FormData.label: "Description"
}
+
+ MarkdownLabel {
+ Layout.fillWidth: true
+ Layout.fillHeight: false
+ leftPadding: Kirigami.Units.largeSpacing
+ rightPadding: Kirigami.Units.largeSpacing
+ text: root.pullRequest ? (root.pullRequest.body != "" ? root.pullRequest.body : "*No description provided.*") : ""
+ }
+
}
diff --git a/kodereviewer/qml/PullRequestFilesDrawer.qml b/kodereviewer/qml/PullRequestFilesDrawer.qml
new file mode 100644
index 0000000..e54fc7b
--- /dev/null
+++ b/kodereviewer/qml/PullRequestFilesDrawer.qml
@@ -0,0 +1,57 @@
+import QtQuick
+import QtQuick.Controls as QQC2
+import QtQuick.Layouts
+
+import org.kde.kirigami as Kirigami
+
+import org.kde.kirigamiaddons.delegates as Delegates
+import org.deprecated.kodereviewer 1.0
+
+Kirigami.OverlayDrawer {
+ id: root
+
+ required property FileModel fileModel
+
+ width: actualWidth
+
+ readonly property int minWidth: Kirigami.Units.gridUnit * 15
+ readonly property int maxWidth: Kirigami.Units.gridUnit * 25
+ readonly property int defaultWidth: Kirigami.Units.gridUnit * 20
+ property int actualWidth: {
+ return Kirigami.Units.gridUnit * 20;
+ }
+
+ onOpened: forceActiveFocus()
+
+ edge: Qt.application.layoutDirection == Qt.RightToLeft ? Qt.LeftEdge : Qt.RightEdge
+
+ topPadding: 0
+ bottomPadding: 0
+ leftPadding: 0
+ rightPadding: 0
+
+ Kirigami.Theme.colorSet: Kirigami.Theme.View
+
+ contentItem: Loader {
+ id: loader
+ active: root.drawerOpen
+
+ sourceComponent: QQC2.ScrollView {
+ ListView {
+ id: listView
+ model: root.fileModel
+ delegate: Delegates.RoundedItemDelegate {
+ required property string filename
+ required property string patch
+ highlighted: ListView.isCurrentItem
+ text: filename
+
+ onClicked: {
+ textArea.text = patch
+ textArea.file = filename
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/kodereviewer/qml/PullRequestPage.qml b/kodereviewer/qml/PullRequestPage.qml
index 860bfcb..cdcc1ec 100644
--- a/kodereviewer/qml/PullRequestPage.qml
+++ b/kodereviewer/qml/PullRequestPage.qml
@@ -34,7 +34,11 @@ Kirigami.ScrollablePage {
icon.name: "file-catalog-symbolic"
enabled: !!root.pullRequest
onTriggered: {
- contextDrawer.open()
+ if(contextDrawer.opened) {
+ contextDrawer.close()
+ } else {
+ contextDrawer.open()
+ }
}
}
]
@@ -72,21 +76,6 @@ Kirigami.ScrollablePage {
}
}
- Loader {
- id: treeFileModelLoader
- active: !!root.pullRequest
- sourceComponent: TreeFileModel {
- pullRequest: root.pullRequest
- }
- }
-
- KRContextDrawer {
- id: contextDrawer
- enabled: !!root.pullRequest
- modal: true
- model: treeFileModelLoader.item
- }
-
Kirigami.PlaceholderMessage {
visible: !root.pullRequest
anchors.centerIn: parent
@@ -94,25 +83,48 @@ Kirigami.ScrollablePage {
text: "Select a pull request"
}
- PullRequestDescription {
- visible: !!root.pullRequest && root.currentView == "info"
- pullRequest: root.pullRequest
+ ColumnLayout {
+ id: mainLayout
anchors.fill: parent
- }
+ PullRequestDescription {
+ visible: !!root.pullRequest && root.currentView == "info"
+ pullRequest: root.pullRequest
- Kirigami.CardsListView {
- visible: !!root.pullRequest && root.currentView == "comments"
- anchors.fill: parent
- // Layout.fillWidth: true
- // Layout.fillHeight: true
- model: commentModelLoader.item
- delegate: CommentDelegate {}
- footerPositioning: ListView.OverlayFooter
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ //anchors.fill: parent
+ }
+
+ Kirigami.CardsListView {
+ visible: !!root.pullRequest && root.currentView == "comments"
+ //anchors.fill: parent
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ model: commentModelLoader.item
+ delegate: CommentDelegate {}
+ footerPositioning: ListView.OverlayFooter
+ }
+
+ Editor {
+ visible: !!root.pullRequest && root.currentView == "files"
+
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ id: editor
+ text: ""
+ file: ""
+ //fileModel: fileModelLoader.item
+ }
}
- FilesView {
- visible: !!root.pullRequest && root.currentView == "files"
- fileModel: fileModelLoader.item
+ Connections {
+ target: contextDrawer
+ function onFileSelected(filename, text) {
+ print("ASDF")
+ editor.filename = filename + '.diff'
+ editor.text = text
+ }
}
footer: Kirigami.NavigationTabBar {