Warning, file /sdk/lokalize/src/binunitsview.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002   This file is part of Lokalize
0003 
0004   SPDX-FileCopyrightText: 2009-2014 Nick Shaforostoff <shafff@ukr.net>
0005   SPDX-FileCopyrightText: 2018-2019 Simon Depiets <sdepiets@gmail.com>
0006 
0007   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0008 */
0009 
0010 #include "binunitsview.h"
0011 #include "phaseswindow.h" //MyTreeView
0012 #include "catalog.h"
0013 #include "cmd.h"
0014 #include "project.h"
0015 
0016 #include <QContextMenuEvent>
0017 #include <QMenu>
0018 #include <QFileDialog>
0019 
0020 #include <KLocalizedString>
0021 #include <KRun>
0022 #include <KDirWatch>
0023 
0024 //BEGIN BinUnitsModel
0025 BinUnitsModel::BinUnitsModel(Catalog* catalog, QObject* parent)
0026     : QAbstractListModel(parent)
0027     , m_catalog(catalog)
0028 {
0029     connect(catalog, QOverload<>::of(&Catalog::signalFileLoaded), this, &BinUnitsModel::fileLoaded);
0030     connect(catalog, &Catalog::signalEntryModified, this, &BinUnitsModel::entryModified);
0031     connect(KDirWatch::self(), &KDirWatch::dirty, this, &BinUnitsModel::updateFile);
0032 }
0033 
0034 void BinUnitsModel::fileLoaded()
0035 {
0036     beginResetModel();
0037     m_imageCache.clear();
0038     endResetModel();
0039 }
0040 
0041 void BinUnitsModel::entryModified(const DocPosition& pos)
0042 {
0043     if (pos.entry < m_catalog->numberOfEntries())
0044         return;
0045 
0046     QModelIndex item = index(pos.entry - m_catalog->numberOfEntries(), TargetFilePath);
0047     Q_EMIT dataChanged(item, item);
0048 }
0049 
0050 void BinUnitsModel::updateFile(QString path)
0051 {
0052     QString relPath = QDir(Project::instance()->projectDir()).relativeFilePath(path);
0053 
0054     DocPosition pos(m_catalog->numberOfEntries());
0055     int limit = m_catalog->numberOfEntries() + m_catalog->binUnitsCount();
0056     while (pos.entry < limit) {
0057         if (m_catalog->target(pos) == relPath || m_catalog->source(pos) == relPath) {
0058             int row = pos.entry - m_catalog->numberOfEntries();
0059             m_imageCache.remove(relPath);
0060             Q_EMIT dataChanged(index(row, SourceFilePath), index(row, TargetFilePath));
0061             return;
0062         }
0063 
0064         pos.entry++;
0065     }
0066 }
0067 
0068 void BinUnitsModel::setTargetFilePath(int row, const QString& path)
0069 {
0070     DocPosition pos(row + m_catalog->numberOfEntries());
0071     QString old = m_catalog->target(pos);
0072     if (!old.isEmpty()) {
0073         m_catalog->push(new DelTextCmd(m_catalog, pos, old));
0074         m_imageCache.remove(old);
0075     }
0076 
0077     m_catalog->push(new InsTextCmd(m_catalog, pos, QDir(Project::instance()->projectDir()).relativeFilePath(path)));
0078     QModelIndex item = index(row, TargetFilePath);
0079     Q_EMIT dataChanged(item, item);
0080 }
0081 
0082 int BinUnitsModel::rowCount(const QModelIndex& parent) const
0083 {
0084     if (parent.isValid())
0085         return 0;
0086     return m_catalog->binUnitsCount();
0087 }
0088 
0089 QVariant BinUnitsModel::data(const QModelIndex& index, int role) const
0090 {
0091     if (role == Qt::DecorationRole) {
0092         DocPosition pos(index.row() + m_catalog->numberOfEntries());
0093         if (index.column() < Approved) {
0094             QString path = index.column() == SourceFilePath ? m_catalog->source(pos) : m_catalog->target(pos);
0095             if (!m_imageCache.contains(path)) {
0096                 QString absPath = Project::instance()->absolutePath(path);
0097                 KDirWatch::self()->addFile(absPath); //TODO remember watched files to react only on them in dirty() signal handler
0098                 m_imageCache.insert(path, QImage(absPath).scaled(128, 128, Qt::KeepAspectRatio));
0099             }
0100             return m_imageCache.value(path);
0101         }
0102     } else if (role == Qt::TextAlignmentRole)
0103         return int(Qt::AlignLeft | Qt::AlignTop);
0104 
0105     if (role != Qt::DisplayRole)
0106         return QVariant();
0107 
0108     static const char* noyes[] = {I18N_NOOP("no"), I18N_NOOP("yes")};
0109     DocPosition pos(index.row() + m_catalog->numberOfEntries());
0110     switch (index.column()) {
0111     case SourceFilePath:    return m_catalog->source(pos);
0112     case TargetFilePath:    return m_catalog->target(pos);
0113     case Approved:          return noyes[m_catalog->isApproved(pos)];
0114     }
0115     return QVariant();
0116 }
0117 
0118 QVariant BinUnitsModel::headerData(int section, Qt::Orientation, int role) const
0119 {
0120     if (role != Qt::DisplayRole)
0121         return QVariant();
0122 
0123     switch (section) {
0124     case SourceFilePath:    return i18nc("@title:column", "Source");
0125     case TargetFilePath:    return i18nc("@title:column", "Target");
0126     case Approved:          return i18nc("@title:column", "Approved");
0127     }
0128     return QVariant();
0129 }
0130 //END BinUnitsModel
0131 
0132 
0133 BinUnitsView::BinUnitsView(Catalog* catalog, QWidget* parent)
0134     : QDockWidget(i18nc("@title toolview name", "Binary Units"), parent)
0135     , m_catalog(catalog)
0136     , m_model(new BinUnitsModel(catalog, this))
0137     , m_view(new MyTreeView(this))
0138 {
0139     setObjectName(QStringLiteral("binUnits"));
0140     hide();
0141 
0142     setWidget(m_view);
0143     m_view->setModel(m_model);
0144     m_view->setRootIsDecorated(false);
0145     m_view->setAlternatingRowColors(true);
0146     m_view->viewport()->setBackgroundRole(QPalette::Window);
0147     connect(m_view, &MyTreeView::doubleClicked, this, &BinUnitsView::mouseDoubleClicked);
0148 
0149     connect(catalog, QOverload<>::of(&Catalog::signalFileLoaded), this, &BinUnitsView::fileLoaded);
0150 }
0151 
0152 void BinUnitsView::fileLoaded()
0153 {
0154     setVisible(m_catalog->binUnitsCount());
0155 }
0156 
0157 void BinUnitsView::selectUnit(const QString& id)
0158 {
0159     QModelIndex item = m_model->index(m_catalog->unitById(id) - m_catalog->numberOfEntries());
0160     m_view->setCurrentIndex(item);
0161     m_view->scrollTo(item);
0162     show();
0163 }
0164 
0165 void BinUnitsView::contextMenuEvent(QContextMenuEvent *event)
0166 {
0167     QModelIndex item = m_view->currentIndex();
0168     if (!item.isValid())
0169         return;
0170 
0171     QMenu menu;
0172     QAction* setTarget = menu.addAction(i18nc("@action:inmenu", "Set the file"));
0173     QAction* useSource = menu.addAction(i18nc("@action:inmenu", "Use source file"));
0174 
0175 //     menu.addSeparator();
0176 //     QAction* openSource=menu.addAction(i18nc("@action:inmenu","Open source file in external program"));
0177 //     QAction* openTarget=menu.addAction(i18nc("@action:inmenu","Open target file in external program"));
0178 
0179     QAction* result = menu.exec(event->globalPos());
0180     if (!result)
0181         return;
0182 
0183     QString sourceFilePath = item.sibling(item.row(), BinUnitsModel::SourceFilePath).data().toString();
0184     if (result == useSource)
0185         m_model->setTargetFilePath(item.row(), sourceFilePath);
0186     else if (result == setTarget) {
0187         QString targetFilePath = QFileDialog::getOpenFileName(this, QString(), Project::instance()->projectDir());
0188         if (!targetFilePath.isEmpty())
0189             m_model->setTargetFilePath(item.row(), targetFilePath);
0190     }
0191     event->accept();
0192 }
0193 
0194 void BinUnitsView::mouseDoubleClicked(const QModelIndex& item)
0195 {
0196     //FIXME child processes don't notify us about changes ;(
0197     if (item.column() < BinUnitsModel::Approved)
0198         new KRun(QUrl::fromLocalFile(Project::instance()->absolutePath(item.data().toString())), this);
0199 }