diff --git a/gpt4all-chat/CHANGELOG.md b/gpt4all-chat/CHANGELOG.md
index 335177f3..44c7aa80 100644
--- a/gpt4all-chat/CHANGELOG.md
+++ b/gpt4all-chat/CHANGELOG.md
@@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
## [Unreleased]
### Added
+- Add ability to attach text, markdown, and rst files to chat ([#3135](https://github.com/nomic-ai/gpt4all/pull/3135))
- Add feature to minimize to system tray (by [@bgallois](https://github.com/bgallois) in ([#3109](https://github.com/nomic-ai/gpt4all/pull/3109))
### Changed
diff --git a/gpt4all-chat/CMakeLists.txt b/gpt4all-chat/CMakeLists.txt
index dcf77a83..06dd3237 100644
--- a/gpt4all-chat/CMakeLists.txt
+++ b/gpt4all-chat/CMakeLists.txt
@@ -218,6 +218,7 @@ qt_add_qml_module(chat
qml/MyDialog.qml
qml/MyDirectoryField.qml
qml/MyFileDialog.qml
+ qml/MyFileIcon.qml
qml/MyFolderDialog.qml
qml/MyFancyLink.qml
qml/MyMenu.qml
@@ -252,6 +253,7 @@ qt_add_qml_module(chat
icons/eject.svg
icons/email.svg
icons/file-doc.svg
+ icons/file-docx.svg
icons/file-md.svg
icons/file-pdf.svg
icons/file-txt.svg
diff --git a/gpt4all-chat/icons/file-docx.svg b/gpt4all-chat/icons/file-docx.svg
new file mode 100644
index 00000000..c26b4ea0
--- /dev/null
+++ b/gpt4all-chat/icons/file-docx.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/gpt4all-chat/qml/ChatView.qml b/gpt4all-chat/qml/ChatView.qml
index cf6b60cc..1239496c 100644
--- a/gpt4all-chat/qml/ChatView.qml
+++ b/gpt4all-chat/qml/ChatView.qml
@@ -915,30 +915,12 @@ Rectangle {
anchors.fill: parent
anchors.margins: 5
- Item {
- id: attachmentFileIcon
- width: 40
- height: 40
- Image {
- id: fileIcon
- anchors.fill: parent
- visible: false
- sourceSize.width: 40
- sourceSize.height: 40
- mipmap: true
- source: {
- return "qrc:/gpt4all/icons/file-xls.svg"
- }
- }
- ColorOverlay {
- anchors.fill: fileIcon
- source: fileIcon
- color: theme.textColor
- }
+ MyFileIcon {
+ iconSize: 40
+ fileName: modelData.file
}
Text {
- id: attachmentFileText
width: 295
height: 40
text: modelData.file
@@ -1343,32 +1325,11 @@ Rectangle {
id: title
spacing: 5
Layout.maximumWidth: 180
- Item {
- Layout.preferredWidth: 24
- Layout.preferredHeight: 24
- Image {
- id: fileIcon
- anchors.fill: parent
- visible: false
- sourceSize.width: 24
- sourceSize.height: 24
- mipmap: true
- source: {
- if (modelData.file.toLowerCase().endsWith(".txt"))
- return "qrc:/gpt4all/icons/file-txt.svg"
- else if (modelData.file.toLowerCase().endsWith(".pdf"))
- return "qrc:/gpt4all/icons/file-pdf.svg"
- else if (modelData.file.toLowerCase().endsWith(".md"))
- return "qrc:/gpt4all/icons/file-md.svg"
- else
- return "qrc:/gpt4all/icons/file.svg"
- }
- }
- ColorOverlay {
- anchors.fill: fileIcon
- source: fileIcon
- color: theme.textColor
- }
+ MyFileIcon {
+ iconSize: 24
+ fileName: modelData.file
+ Layout.preferredWidth: iconSize
+ Layout.preferredHeight: iconSize
}
Text {
Layout.maximumWidth: 156
@@ -1949,30 +1910,12 @@ Rectangle {
anchors.fill: parent
anchors.margins: 5
- Item {
- id: attachmentFileIcon2
- width: 40
- height: 40
- Image {
- id: fileIcon2
- anchors.fill: parent
- visible: false
- sourceSize.width: 40
- sourceSize.height: 40
- mipmap: true
- source: {
- return "qrc:/gpt4all/icons/file-xls.svg"
- }
- }
- ColorOverlay {
- anchors.fill: fileIcon2
- source: fileIcon2
- color: theme.textColor
- }
+ MyFileIcon {
+ iconSize: 40
+ fileName: model.file
}
Text {
- id: attachmentFileText2
width: 265
height: 40
text: model.file
@@ -2188,7 +2131,7 @@ Rectangle {
MyFileDialog {
id: fileDialog
- nameFilters: ["Excel files (*.xlsx)"]
+ nameFilters: ["All Supported Files (*.txt *.md *.rst *.xlsx)", "Text Files (*.txt *.md *.rst)", "Excel Worksheets (*.xlsx)"]
}
MyMenu {
diff --git a/gpt4all-chat/qml/MyFileIcon.qml b/gpt4all-chat/qml/MyFileIcon.qml
new file mode 100644
index 00000000..036baa5b
--- /dev/null
+++ b/gpt4all-chat/qml/MyFileIcon.qml
@@ -0,0 +1,41 @@
+import QtCore
+import QtQuick
+import QtQuick.Controls
+import QtQuick.Controls.Basic
+import Qt5Compat.GraphicalEffects
+
+Item {
+ id: fileIcon
+ property real iconSize: 24
+ property string fileName: ""
+ implicitWidth: iconSize
+ implicitHeight: iconSize
+
+ Image {
+ id: fileImage
+ anchors.fill: parent
+ visible: false
+ sourceSize.width: iconSize
+ sourceSize.height: iconSize
+ mipmap: true
+ source: {
+ if (fileIcon.fileName.toLowerCase().endsWith(".txt"))
+ return "qrc:/gpt4all/icons/file-txt.svg"
+ else if (fileIcon.fileName.toLowerCase().endsWith(".pdf"))
+ return "qrc:/gpt4all/icons/file-pdf.svg"
+ else if (fileIcon.fileName.toLowerCase().endsWith(".md"))
+ return "qrc:/gpt4all/icons/file-md.svg"
+ else if (fileIcon.fileName.toLowerCase().endsWith(".xlsx"))
+ return "qrc:/gpt4all/icons/file-xls.svg"
+ else if (fileIcon.fileName.toLowerCase().endsWith(".docx"))
+ return "qrc:/gpt4all/icons/file-docx.svg"
+ else
+ return "qrc:/gpt4all/icons/file.svg"
+ }
+ }
+ ColorOverlay {
+ anchors.fill: fileImage
+ source: fileImage
+ color: theme.textColor
+ }
+}
diff --git a/gpt4all-chat/src/chat.cpp b/gpt4all-chat/src/chat.cpp
index 6b9c8898..bb5d3a1d 100644
--- a/gpt4all-chat/src/chat.cpp
+++ b/gpt4all-chat/src/chat.cpp
@@ -132,7 +132,13 @@ void Chat::newPromptResponsePair(const QString &prompt, const QList &attac
Q_ASSERT(url.isLocalFile());
const QString localFilePath = url.toLocalFile();
const QFileInfo info(localFilePath);
- Q_ASSERT(info.suffix() == "xlsx"); // We only support excel right now
+
+ Q_ASSERT(
+ info.suffix().toLower() == "xlsx" ||
+ info.suffix().toLower() == "txt" ||
+ info.suffix().toLower() == "md" ||
+ info.suffix().toLower() == "rst"
+ );
PromptAttachment attached;
attached.url = url;
diff --git a/gpt4all-chat/src/chatmodel.h b/gpt4all-chat/src/chatmodel.h
index 43b96246..32539fa6 100644
--- a/gpt4all-chat/src/chatmodel.h
+++ b/gpt4all-chat/src/chatmodel.h
@@ -40,6 +40,11 @@ public:
QString processedContent() const
{
+ const QString localFilePath = url.toLocalFile();
+ const QFileInfo info(localFilePath);
+ if (info.suffix().toLower() != "xlsx")
+ return u"## Attached: %1\n\n%2"_s.arg(file(), content);
+
QBuffer buffer;
buffer.setData(content);
buffer.open(QIODevice::ReadOnly);