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);