2016-02-17 10:11:00 +03:00
|
|
|
/***************************************************************************
|
|
|
|
* This file is part of the Lime Report project *
|
|
|
|
* Copyright (C) 2015 by Alexander Arin *
|
|
|
|
* arin_a@bk.ru *
|
|
|
|
* *
|
|
|
|
** GNU General Public License Usage **
|
|
|
|
* *
|
|
|
|
* This library is free software: you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
|
|
* *
|
|
|
|
** GNU Lesser General Public License **
|
|
|
|
* *
|
|
|
|
* This library is free software: you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU Lesser General Public License as *
|
|
|
|
* published by the Free Software Foundation, either version 3 of the *
|
|
|
|
* License, or (at your option) any later version. *
|
|
|
|
* You should have received a copy of the GNU Lesser General Public *
|
|
|
|
* License along with this library. *
|
|
|
|
* If not, see <http://www.gnu.org/licenses/>. *
|
|
|
|
* *
|
|
|
|
* This library is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
****************************************************************************/
|
|
|
|
#include "lrtextitemeditor.h"
|
|
|
|
#include "ui_lrtextitemeditor.h"
|
|
|
|
|
|
|
|
#include "lrdatasourcemanager.h"
|
|
|
|
#include "lrscriptenginemanager.h"
|
|
|
|
#include "lrdatadesignintf.h"
|
|
|
|
#include "lrdatasourcemanager.h"
|
2016-02-17 10:28:27 +03:00
|
|
|
|
2016-02-17 10:11:00 +03:00
|
|
|
#include <QMenu>
|
|
|
|
#include <QScrollBar>
|
|
|
|
|
2016-03-04 04:53:34 +03:00
|
|
|
namespace LimeReport{
|
|
|
|
|
2016-02-17 10:11:00 +03:00
|
|
|
TextItemEditor::TextItemEditor(LimeReport::TextItem *item, LimeReport::PageDesignIntf *page, QSettings* settings, QWidget *parent) :
|
|
|
|
QWidget(parent),
|
|
|
|
ui(new Ui::TextItemEditor), m_textItem(item), m_page(page), m_settings(settings), m_ownedSettings(false), m_isReadingSetting(false)
|
|
|
|
{
|
|
|
|
ui->setupUi(this);
|
|
|
|
initUI();
|
|
|
|
m_teContent->setPlainText(item->content());
|
|
|
|
m_teContent->setFocus();
|
|
|
|
setWindowIcon(QIcon(":/items/images/TextItem"));
|
|
|
|
readSetting();
|
|
|
|
}
|
|
|
|
|
|
|
|
TextItemEditor::~TextItemEditor()
|
|
|
|
{
|
|
|
|
#ifdef Q_OS_WIN
|
|
|
|
writeSetting();
|
|
|
|
#endif
|
|
|
|
#ifdef Q_OS_MAC
|
|
|
|
writeSetting();
|
|
|
|
#endif
|
|
|
|
delete ui;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::setSettings(QSettings* value)
|
|
|
|
{
|
|
|
|
if (m_ownedSettings)
|
|
|
|
delete m_settings;
|
|
|
|
m_settings=value;
|
|
|
|
m_ownedSettings=false;
|
|
|
|
readSetting();
|
|
|
|
}
|
|
|
|
|
|
|
|
QSettings*TextItemEditor::settings()
|
|
|
|
{
|
|
|
|
if (m_settings){
|
|
|
|
return m_settings;
|
|
|
|
} else {
|
|
|
|
m_settings = new QSettings("LimeReport",QApplication::applicationName());
|
|
|
|
m_ownedSettings = true;
|
|
|
|
return m_settings;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::resizeEvent(QResizeEvent*)
|
|
|
|
{
|
|
|
|
#ifdef Q_OS_UNIX
|
|
|
|
writeSetting();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::moveEvent(QMoveEvent*)
|
|
|
|
{
|
|
|
|
#ifdef Q_OS_UNIX
|
|
|
|
writeSetting();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::on_pbOk_clicked()
|
|
|
|
{
|
|
|
|
if (m_textItem->content()!=m_teContent->toPlainText()){
|
|
|
|
m_textItem->setContent(m_teContent->toPlainText());
|
|
|
|
}
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::initUI()
|
|
|
|
{
|
|
|
|
QStringList dataWords;
|
|
|
|
m_teContent = ui->textEdit;
|
|
|
|
m_completer = new QCompleter(this);
|
|
|
|
m_teContent->setCompleter(m_completer);
|
|
|
|
|
|
|
|
m_datasourcesMenu = new QMenu(this);
|
|
|
|
|
2016-02-17 10:28:27 +03:00
|
|
|
LimeReport::DataSourceManager* dm = m_page->datasourceManager();
|
|
|
|
LimeReport::ScriptEngineManager& se = LimeReport::ScriptEngineManager::instance();
|
|
|
|
se.setDataManager(dm);
|
|
|
|
|
2016-02-17 10:11:00 +03:00
|
|
|
if (dm){
|
2016-04-13 23:04:56 +03:00
|
|
|
if (dm->isNeedUpdateDatasourceModel())
|
|
|
|
dm->updateDatasourceModel();
|
2016-02-17 10:11:00 +03:00
|
|
|
ui->twData->setModel(dm->datasourcesModel());
|
2016-02-17 10:28:27 +03:00
|
|
|
ui->twScriptEngine->setModel(se.model());
|
2016-02-17 10:11:00 +03:00
|
|
|
|
|
|
|
foreach(QString dsName,dm->dataSourceNames()){
|
|
|
|
foreach(QString field, dm->fieldNames(dsName)){
|
|
|
|
dataWords<<dsName+"."+field;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ui->tabWidget->setVisible(false);
|
|
|
|
}
|
|
|
|
|
2016-11-01 20:42:45 +03:00
|
|
|
foreach (LimeReport::ScriptFunctionDesc functionDesc, se.functionsDescribers()) {
|
2016-02-17 10:11:00 +03:00
|
|
|
dataWords<<functionDesc.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_completer->setModel(new QStringListModel(dataWords,m_completer));
|
|
|
|
ui->gbSettings->setVisible(false);
|
2016-05-26 22:24:29 +03:00
|
|
|
|
|
|
|
if (ui->twScriptEngine->selectionModel()){
|
|
|
|
connect(ui->twScriptEngine->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)),
|
2016-02-17 10:18:19 +03:00
|
|
|
this, SLOT(slotScriptItemsSelectionChanged(QModelIndex,QModelIndex)));
|
2016-05-26 22:24:29 +03:00
|
|
|
}
|
2016-04-21 01:15:15 +03:00
|
|
|
|
|
|
|
BandDesignIntf* band = findParentBand();
|
2016-05-26 22:24:29 +03:00
|
|
|
if (band && ui->twData->model() && !band->datasourceName().isEmpty()){
|
2016-04-21 01:15:15 +03:00
|
|
|
QModelIndexList nodes = ui->twData->model()->match(
|
|
|
|
ui->twData->model()->index(0,0),
|
|
|
|
Qt::DisplayRole,
|
|
|
|
band->datasourceName(),
|
|
|
|
2,
|
|
|
|
Qt::MatchRecursive
|
|
|
|
);
|
|
|
|
if (!nodes.isEmpty()){
|
|
|
|
ui->twData->expand(nodes.at(0).parent());
|
|
|
|
ui->twData->expand(nodes.at(0));
|
|
|
|
}
|
|
|
|
}
|
2016-02-17 10:11:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
QStringListModel *TextItemEditor::getDataSources()
|
|
|
|
{
|
2016-02-17 10:28:27 +03:00
|
|
|
LimeReport::DataSourceManager* dm = m_page->datasourceManager();
|
2016-02-17 10:11:00 +03:00
|
|
|
QStringList dataSources;
|
|
|
|
foreach(QString dsName,dm->dataSourceNames()){
|
|
|
|
dataSources<<dsName;
|
|
|
|
}
|
2016-02-17 10:28:27 +03:00
|
|
|
return new QStringListModel(dataSources, m_completer);
|
2016-02-17 10:11:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
QStringListModel *TextItemEditor::getPrefixes()
|
|
|
|
{
|
|
|
|
QStringList prefixes;
|
|
|
|
prefixes<<"D{"<<"S{";
|
2016-02-17 10:28:27 +03:00
|
|
|
return new QStringListModel(prefixes, m_completer);
|
2016-02-17 10:11:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
QStringListModel *TextItemEditor::getColumns(QString datasource)
|
|
|
|
{
|
|
|
|
QStringList fields;
|
2016-02-17 10:28:27 +03:00
|
|
|
LimeReport::DataSourceManager* dm = m_page->datasourceManager();
|
2016-02-17 10:11:00 +03:00
|
|
|
foreach(QString field, dm->fieldNames(datasource)){
|
|
|
|
fields<<field;
|
|
|
|
}
|
2016-02-17 10:28:27 +03:00
|
|
|
return new QStringListModel(fields, m_completer);
|
2016-02-17 10:11:00 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::on_pbCancel_clicked()
|
|
|
|
{
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::slotFieldSelected()
|
|
|
|
{
|
|
|
|
QAction* action = dynamic_cast<QAction*>(sender());
|
|
|
|
m_teContent->insertPlainText(action->whatsThis());
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::readSetting()
|
|
|
|
{
|
|
|
|
if (settings()==0) return;
|
|
|
|
|
|
|
|
m_isReadingSetting = true;
|
|
|
|
|
|
|
|
settings()->beginGroup("TextItemEditor");
|
|
|
|
QVariant v = settings()->value("Geometry");
|
|
|
|
if (v.isValid()){
|
|
|
|
restoreGeometry(v.toByteArray());
|
|
|
|
}
|
|
|
|
v = settings()->value("State");
|
|
|
|
if (v.isValid()){
|
|
|
|
ui->splitter->restoreState(v.toByteArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant fontName = settings()->value("FontName");
|
|
|
|
if (fontName.isValid()){
|
|
|
|
QVariant fontSize = settings()->value("FontSize");
|
|
|
|
ui->textEdit->setFont(QFont(fontName.toString(),fontSize.toInt()));
|
|
|
|
ui->editorFont->setCurrentFont(ui->textEdit->font());
|
|
|
|
ui->editorFontSize->setValue(fontSize.toInt());
|
|
|
|
}
|
|
|
|
settings()->endGroup();
|
|
|
|
|
|
|
|
m_isReadingSetting = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::writeSetting()
|
|
|
|
{
|
|
|
|
if (settings()!=0){
|
|
|
|
settings()->beginGroup("TextItemEditor");
|
|
|
|
settings()->setValue("Geometry",saveGeometry());
|
|
|
|
settings()->setValue("State",ui->splitter->saveState());
|
|
|
|
settings()->endGroup();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
CompleaterTextEditor::CompleaterTextEditor(QWidget *parent)
|
|
|
|
: QTextEdit(parent),m_compleater(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void CompleaterTextEditor::setCompleter(QCompleter *value)
|
|
|
|
{
|
|
|
|
if (value) disconnect(value,0,this,0);
|
|
|
|
m_compleater = value;
|
|
|
|
if (!m_compleater) return;
|
|
|
|
m_compleater->setWidget(this);
|
|
|
|
m_compleater->setCompletionMode(QCompleter::PopupCompletion);
|
|
|
|
m_compleater->setCaseSensitivity(Qt::CaseInsensitive);
|
|
|
|
connect(m_compleater,SIGNAL(activated(QString)),this,SLOT(insertCompletion(QString)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void CompleaterTextEditor::keyPressEvent(QKeyEvent *e)
|
|
|
|
{
|
|
|
|
if (m_compleater && m_compleater->popup()->isVisible()) {
|
|
|
|
switch (e->key()) {
|
|
|
|
case Qt::Key_Enter:
|
|
|
|
case Qt::Key_Return:
|
|
|
|
case Qt::Key_Escape:
|
|
|
|
case Qt::Key_Tab:
|
|
|
|
case Qt::Key_Backtab:
|
|
|
|
e->ignore();
|
|
|
|
return;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool isShortcut = ((e->modifiers() & Qt::ControlModifier) && e->key() == Qt::Key_E);
|
|
|
|
if (!m_compleater || !isShortcut) QTextEdit::keyPressEvent(e);
|
|
|
|
|
|
|
|
const bool ctrlOrShift = e->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier);
|
|
|
|
if (!m_compleater || (ctrlOrShift && e->text().isEmpty()))
|
|
|
|
return;
|
|
|
|
|
|
|
|
static QString eow("~!@#$%^&*()_+{}|:\"<>?,./;'[]\\-="); // end of word
|
|
|
|
bool hasModifier = (e->modifiers() != Qt::NoModifier) && !ctrlOrShift;
|
|
|
|
|
|
|
|
QString completionPrefix = textUnderCursor();
|
|
|
|
|
|
|
|
if (!isShortcut && (hasModifier || e->text().isEmpty()|| completionPrefix.length() < 3
|
|
|
|
|| eow.contains(e->text().right(1)))) {
|
|
|
|
m_compleater->popup()->hide();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (completionPrefix != m_compleater->completionPrefix()) {
|
|
|
|
m_compleater->setCompletionPrefix(completionPrefix);
|
|
|
|
m_compleater->popup()->setCurrentIndex(m_compleater->completionModel()->index(0, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
QRect cr = cursorRect();
|
|
|
|
cr.setWidth(m_compleater->popup()->sizeHintForColumn(0)
|
|
|
|
+ m_compleater->popup()->verticalScrollBar()->sizeHint().width());
|
|
|
|
m_compleater->complete(cr);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void CompleaterTextEditor::focusInEvent(QFocusEvent *e)
|
|
|
|
{
|
|
|
|
if (m_compleater) m_compleater->setWidget(this);
|
|
|
|
QTextEdit::focusInEvent(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
QString CompleaterTextEditor::textUnderCursor() const
|
|
|
|
{
|
|
|
|
QTextCursor tc = textCursor();
|
|
|
|
tc.select(QTextCursor::WordUnderCursor);
|
|
|
|
return tc.selectedText();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void CompleaterTextEditor::insertCompletion(const QString &completion)
|
|
|
|
{
|
|
|
|
if (m_compleater->widget() != this)
|
|
|
|
return;
|
|
|
|
QTextCursor tc = textCursor();
|
|
|
|
int extra = completion.length() - m_compleater->completionPrefix().length();
|
|
|
|
tc.movePosition(QTextCursor::Left);
|
|
|
|
tc.movePosition(QTextCursor::EndOfWord);
|
|
|
|
tc.insertText(completion.right(extra));
|
|
|
|
setTextCursor(tc);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::on_twData_doubleClicked(const QModelIndex &index)
|
|
|
|
{
|
|
|
|
if (!index.isValid()) return;
|
|
|
|
LimeReport::DataNode* node = static_cast<LimeReport::DataNode*>(index.internalPointer());
|
|
|
|
if (node->type()==LimeReport::DataNode::Field){
|
|
|
|
m_teContent->insertPlainText(QString("$D{%1.%2}").arg(node->parent()->name()).arg(node->name()));
|
|
|
|
}
|
|
|
|
if (node->type()==LimeReport::DataNode::Variable){
|
|
|
|
m_teContent->insertPlainText(QString("$V{%1}").arg(node->name()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::on_twScriptEngine_doubleClicked(const QModelIndex &index)
|
|
|
|
{
|
|
|
|
if (!index.isValid()) return;
|
|
|
|
LimeReport::ScriptEngineNode* node = static_cast<LimeReport::ScriptEngineNode*>(index.internalPointer());
|
|
|
|
if (node->type()==LimeReport::ScriptEngineNode::Function){
|
|
|
|
m_teContent->insertPlainText(node->name()+"()");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::on_splitter_splitterMoved(int , int )
|
|
|
|
{
|
|
|
|
#ifdef unix
|
|
|
|
writeSetting();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::on_editorFont_currentFontChanged(const QFont &f)
|
|
|
|
{
|
|
|
|
if (m_isReadingSetting) return;
|
|
|
|
QFont tmp = f;
|
|
|
|
tmp.setPointSize(ui->editorFontSize->value());
|
|
|
|
ui->textEdit->setFont(tmp);
|
|
|
|
settings()->beginGroup("TextItemEditor");
|
|
|
|
settings()->setValue("FontName",ui->textEdit->font().family());
|
|
|
|
settings()->setValue("FontSize",ui->editorFontSize->value());
|
|
|
|
settings()->endGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::on_editorFontSize_valueChanged(int arg1)
|
|
|
|
{
|
|
|
|
if (m_isReadingSetting) return;
|
|
|
|
ui->textEdit->setFont(QFont(ui->textEdit->font().family(),arg1));
|
|
|
|
settings()->beginGroup("TextItemEditor");
|
|
|
|
settings()->setValue("FontName",ui->textEdit->font().family());
|
|
|
|
settings()->setValue("FontSize",ui->editorFontSize->value());
|
|
|
|
settings()->endGroup();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::on_toolButton_clicked(bool checked)
|
|
|
|
{
|
|
|
|
ui->gbSettings->setVisible(checked);
|
|
|
|
}
|
2016-02-17 10:18:19 +03:00
|
|
|
|
|
|
|
|
|
|
|
void TextItemEditor::on_twScriptEngine_activated(const QModelIndex &index)
|
|
|
|
{
|
|
|
|
LimeReport::ScriptEngineNode* node = static_cast<LimeReport::ScriptEngineNode*>(index.internalPointer());
|
|
|
|
if (node->type()==LimeReport::ScriptEngineNode::Function){
|
|
|
|
ui->lblDescription->setText(node->name());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TextItemEditor::slotScriptItemsSelectionChanged(const QModelIndex &to, const QModelIndex)
|
|
|
|
{
|
|
|
|
LimeReport::ScriptEngineNode* node = static_cast<LimeReport::ScriptEngineNode*>(to.internalPointer());
|
|
|
|
if (node->type()==LimeReport::ScriptEngineNode::Function){
|
|
|
|
ui->lblDescription->setText(node->description());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-21 01:15:15 +03:00
|
|
|
BandDesignIntf *TextItemEditor::findParentBand()
|
|
|
|
{
|
|
|
|
BandDesignIntf* result = 0;
|
|
|
|
BaseDesignIntf* item = m_textItem;
|
|
|
|
while (true){
|
|
|
|
item = dynamic_cast<BaseDesignIntf*>(item->parentItem());
|
|
|
|
if (item){
|
|
|
|
result = dynamic_cast<BandDesignIntf*>(item);
|
|
|
|
if (result) break;
|
|
|
|
} else break;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2016-03-04 04:53:34 +03:00
|
|
|
} // namespace LimeReport
|