File indexing completed on 2024-05-05 11:56:08

0001 /*
0002     SPDX-License-Identifier: GPL-2.0-or-later
0003     SPDX-FileCopyrightText: 2020 Sirgienko Nikita <warquark@gmail.com>
0004 */
0005 
0006 #include "filebrowserpanelplugin.h"
0007 
0008 #include <QFileSystemModel>
0009 #include <QTreeView>
0010 #include <QHeaderView>
0011 #include <QModelIndex>
0012 #include <QStandardItem>
0013 #include <QDesktopServices>
0014 #include <QUrl>
0015 #include <QDebug>
0016 #include <QWidget>
0017 #include <QVBoxLayout>
0018 #include <QPushButton>
0019 #include <QAction>
0020 #include <QLineEdit>
0021 #include <QComboBox>
0022 
0023 #include <KLocalizedString>
0024 #include <KParts/ReadOnlyPart>
0025 #include <KPluginFactory>
0026 
0027 FileBrowserPanelPlugin::FileBrowserPanelPlugin(QObject* parent, const QList<QVariant>& args): Cantor::PanelPlugin(parent),
0028     m_mainWidget(nullptr), m_treeview(nullptr), m_pathEdit(nullptr), m_filterCombobox(nullptr)
0029 {
0030     Q_UNUSED(args);
0031 
0032     auto* part = dynamic_cast<KParts::ReadOnlyPart*>(parent->parent());
0033     QString baseRootDir;
0034     if (part && !part->url().isEmpty())
0035         baseRootDir = QFileInfo(part->url().toLocalFile()).absoluteDir().absolutePath();
0036     else
0037         baseRootDir = QDir::currentPath();
0038     m_rootDirsHistory.push_back(baseRootDir);
0039 }
0040 
0041 FileBrowserPanelPlugin::~FileBrowserPanelPlugin()
0042 {
0043     if (m_mainWidget)
0044     {
0045         m_mainWidget->deleteLater();
0046         m_treeview = nullptr;
0047         m_pathEdit = nullptr;
0048         m_filterCombobox = nullptr;
0049         m_model->deleteLater();
0050     }
0051 }
0052 
0053 QWidget* FileBrowserPanelPlugin::widget()
0054 {
0055     if (!m_mainWidget)
0056     {
0057         m_model = new QFileSystemModel();
0058         m_model->setRootPath(m_rootDirsHistory.last());
0059         constructMainWidget();
0060     }
0061 
0062     return m_mainWidget;
0063 }
0064 
0065 void FileBrowserPanelPlugin::connectToShell(QObject* cantorShell)
0066 {
0067     connect(this, SIGNAL(requestOpenWorksheet(QUrl)), cantorShell, SLOT(load(QUrl)));
0068 }
0069 
0070 bool FileBrowserPanelPlugin::showOnStartup()
0071 {
0072     return false;
0073 }
0074 
0075 void FileBrowserPanelPlugin::handleDoubleClicked(const QModelIndex& index)
0076 {
0077     QVariant data = m_model->data(index, QFileSystemModel::FilePathRole);
0078     if (data.isValid() && data.type() == QVariant::String)
0079     {
0080         const QString& filename = data.value<QString>();
0081         if (m_model->isDir(index))
0082         {
0083             moveFileBrowserRoot(filename);
0084         }
0085         else
0086         {
0087             const QUrl& url = QUrl::fromLocalFile(filename);
0088             if (filename.endsWith(QLatin1String(".cws")) || filename.endsWith(QLatin1String(".ipynb")))
0089                 emit requestOpenWorksheet(url);
0090             else
0091                 QDesktopServices::openUrl(url);
0092         }
0093     }
0094 }
0095 
0096 void FileBrowserPanelPlugin::constructMainWidget()
0097 {
0098     m_mainWidget = new QWidget();
0099 
0100     m_treeview = new QTreeView(m_mainWidget);
0101     m_treeview->setModel(m_model);
0102     m_treeview->setRootIndex(m_model->index(m_rootDirsHistory.last()));
0103     m_treeview->setExpandsOnDoubleClick(false);
0104     connect(m_treeview, &QTreeView::doubleClicked, this, &FileBrowserPanelPlugin::handleDoubleClicked);
0105 
0106     // First column is name with the dir tree
0107     // Show only the first column
0108     for (int i = 1; i < m_model->columnCount(); i++)
0109         m_treeview->setColumnHidden(i, true);
0110     m_treeview->header()->hide();
0111     m_treeview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
0112 
0113     QWidget* buttonContainer = new QWidget(m_mainWidget);
0114 
0115     QPushButton* dirUpButton = new QPushButton(QIcon::fromTheme(QLatin1String("go-up")), QString(), buttonContainer);
0116     dirUpButton->setMinimumSize(40, 40);
0117     connect(dirUpButton, &QPushButton::clicked, this, &FileBrowserPanelPlugin::dirUpButtonHandle);
0118 
0119     QPushButton* homeButton = new QPushButton(QIcon::fromTheme(QLatin1String("go-home")), QString(), buttonContainer);
0120     homeButton->setMinimumSize(40, 40);
0121     connect(homeButton, &QPushButton::clicked, this, &FileBrowserPanelPlugin::homeButtonHandle);
0122 
0123     QPushButton* dirPreviousButton = new QPushButton(QIcon::fromTheme(QLatin1String("go-previous")), QString(), buttonContainer);
0124     dirPreviousButton->setMinimumSize(40, 40);
0125     connect(dirPreviousButton, &QPushButton::clicked, this, &FileBrowserPanelPlugin::dirPreviousButtonHandle);
0126 
0127     QPushButton* dirNextButton = new QPushButton(QIcon::fromTheme(QLatin1String("go-next")), QString(), buttonContainer);
0128     dirNextButton->setMinimumSize(40, 40);
0129     connect(dirNextButton, &QPushButton::clicked, this, &FileBrowserPanelPlugin::dirNextButtonHandle);
0130 
0131     m_pathEdit = new QLineEdit(m_rootDirsHistory.last(), buttonContainer);
0132     connect(m_pathEdit, &QLineEdit::returnPressed, this, &FileBrowserPanelPlugin::setNewRootPath);
0133     m_pathEdit->setMinimumHeight(40);
0134     m_pathEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
0135 
0136     m_filterCombobox = new QComboBox(buttonContainer);
0137     m_filterCombobox->addItem(i18n("Cantor files"), QLatin1String("*.cws")); //Default value
0138     m_filterCombobox->addItem(i18n("Jupyter files"), QLatin1String("*.ipynb"));
0139     m_filterCombobox->addItem(i18n("All supported files"), QLatin1String("*.cws *.ipynb"));
0140     m_filterCombobox->addItem(i18n("All files"), QLatin1String("*"));
0141     connect(m_filterCombobox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, &FileBrowserPanelPlugin::handleFilterChanging);
0142     m_model->setNameFilters({QLatin1String("*.cws")});
0143     m_model->setNameFilterDisables(false);
0144 
0145     QHBoxLayout* horizontalLayout = new QHBoxLayout();
0146     horizontalLayout->setDirection(QBoxLayout::LeftToRight);
0147     horizontalLayout->addWidget(dirPreviousButton);
0148     horizontalLayout->addWidget(dirUpButton);
0149     horizontalLayout->addWidget(homeButton);
0150     horizontalLayout->addWidget(dirNextButton);
0151     horizontalLayout->addWidget(m_pathEdit);
0152     horizontalLayout->addWidget(m_filterCombobox);
0153     horizontalLayout->setMargin(0);
0154 
0155     buttonContainer->setLayout(horizontalLayout);
0156     buttonContainer->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
0157 
0158     QVBoxLayout* layout = new QVBoxLayout();
0159     layout->addWidget(buttonContainer);
0160     layout->addWidget(m_treeview);
0161 
0162     m_mainWidget->setLayout(layout);
0163 }
0164 
0165 void FileBrowserPanelPlugin::moveFileBrowserRoot(const QString& path)
0166 {
0167     for (int i = 0; i < historyBackCount; i++)
0168         m_rootDirsHistory.pop_back();
0169     historyBackCount = 0;
0170 
0171     m_rootDirsHistory.push_back(path);
0172     setRootPath(path);
0173 }
0174 
0175 void FileBrowserPanelPlugin::setRootPath(const QString& path)
0176 {
0177     m_model->setRootPath(path);
0178     m_treeview->setRootIndex(m_model->index(path));
0179     m_pathEdit->setText(path);
0180 }
0181 
0182 void FileBrowserPanelPlugin::dirUpButtonHandle()
0183 {
0184     QDir dir(m_model->rootPath());
0185     if (dir.cdUp())
0186         moveFileBrowserRoot(dir.absolutePath());
0187 }
0188 
0189 void FileBrowserPanelPlugin::homeButtonHandle()
0190 {
0191     moveFileBrowserRoot(QDir::homePath());
0192 }
0193 
0194 void FileBrowserPanelPlugin::dirNextButtonHandle()
0195 {
0196     if (historyBackCount <= 0)
0197         return;
0198     historyBackCount -= 1;
0199 
0200     const QString& newPath = m_rootDirsHistory[m_rootDirsHistory.size() - 1 - historyBackCount];
0201 
0202     setRootPath(newPath);
0203 }
0204 
0205 void FileBrowserPanelPlugin::dirPreviousButtonHandle()
0206 {
0207     if (historyBackCount >= m_rootDirsHistory.size() - 1)
0208         return;
0209     historyBackCount += 1;
0210 
0211     const QString& newPath = m_rootDirsHistory[m_rootDirsHistory.size() - 1 - historyBackCount];
0212     setRootPath(newPath);
0213 }
0214 
0215 void FileBrowserPanelPlugin::setNewRootPath()
0216 {
0217     QString path = m_pathEdit->text();
0218     QFileInfo info(path);
0219     if (info.isDir())
0220         moveFileBrowserRoot(path);
0221 }
0222 
0223 void FileBrowserPanelPlugin::handleFilterChanging(int index)
0224 {
0225     if (m_model)
0226         m_model->setNameFilters(m_filterCombobox->itemData(index).toString().split(QLatin1Char(' ')));
0227 }
0228 
0229 K_PLUGIN_FACTORY_WITH_JSON(filebrowserpanelplugin, "filebrowserpanelplugin.json", registerPlugin<FileBrowserPanelPlugin>();)
0230 #include "filebrowserpanelplugin.moc"