FreeCAD

Форк
0
/
TextDocumentEditorView.cpp 
299 строк · 9.3 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2017 Markus Hovorka <m.hovorka@live.de>                 *
3
 *                                                                         *
4
 *   This file is part of the FreeCAD CAx development system.              *
5
 *                                                                         *
6
 *   This library is free software; you can redistribute it and/or         *
7
 *   modify it under the terms of the GNU Library General Public           *
8
 *   License as published by the Free Software Foundation; either          *
9
 *   version 2 of the License, or (at your option) any later version.      *
10
 *                                                                         *
11
 *   This library  is distributed in the hope that it will be useful,      *
12
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
13
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
14
 *   GNU Library General Public License for more details.                  *
15
 *                                                                         *
16
 *   You should have received a copy of the GNU Library General Public     *
17
 *   License along with this library; see the file COPYING.LIB. If not,    *
18
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
19
 *   Suite 330, Boston, MA  02111-1307, USA                                *
20
 *                                                                         *
21
 ***************************************************************************/
22

23
#include "PreCompiled.h"
24
#ifndef _PreComp_
25
# include <QApplication>
26
# include <QClipboard>
27
# include <QMessageBox>
28
# include <QPushButton>
29
# include <QString>
30
#endif
31

32
#include "TextDocumentEditorView.h"
33
#include "Application.h"
34
#include "Document.h"
35
#include "MainWindow.h"
36

37

38
using namespace Gui;
39

40
TYPESYSTEM_SOURCE_ABSTRACT(Gui::TextDocumentEditorView, Gui::MDIView)
41

42
TextDocumentEditorView::TextDocumentEditorView(
43
        App::TextDocument* txtDoc, QPlainTextEdit* e,
44
        QWidget* parent)
45
    : MDIView(
46
            Application::Instance->getDocument(txtDoc->getDocument()),
47
            parent),
48
    editor {e}, textDocument {txtDoc}
49
{
50
    setupEditor();
51
    setupConnection();
52
    setCentralWidget(editor);
53

54
    // update editor actions on request
55
    Gui::MainWindow* mw = Gui::getMainWindow();
56
    connect(editor, &QPlainTextEdit::undoAvailable, mw, &MainWindow::updateEditorActions);
57
    connect(editor, &QPlainTextEdit::redoAvailable, mw, &MainWindow::updateEditorActions);
58
    connect(editor, &QPlainTextEdit::copyAvailable, mw, &MainWindow::updateEditorActions);
59
}
60

61
TextDocumentEditorView::~TextDocumentEditorView()
62
{
63
    textConnection.disconnect();
64
    labelConnection.disconnect();
65
}
66

67
void TextDocumentEditorView::showEvent(QShowEvent* event)
68
{
69
    Gui::MainWindow* mw = Gui::getMainWindow();
70
    mw->updateEditorActions();
71
    MDIView::showEvent(event);
72
}
73

74
void TextDocumentEditorView::hideEvent(QHideEvent* event)
75
{
76
    MDIView::hideEvent(event);
77
}
78

79
void TextDocumentEditorView::closeEvent(QCloseEvent* event)
80
{
81
    MDIView::closeEvent(event);
82
    if (event->isAccepted()) {
83
        aboutToClose = true;
84
        Gui::MainWindow* mw = Gui::getMainWindow();
85
        mw->updateEditorActions();
86
    }
87
}
88

89
bool TextDocumentEditorView::event(QEvent *event)
90
{
91
    if (event->type() == QEvent::Show && sourceModified) {
92
        refresh();
93
        sourceModified = false;
94
    }
95
    return MDIView::event(event);
96
}
97

98
void TextDocumentEditorView::setupEditor()
99
{
100
    connect(getEditor()->document(), &QTextDocument::modificationChanged,
101
            this, &TextDocumentEditorView::setWindowModified);
102
    setWindowTitle(QString::fromUtf8(textDocument->Label.getValue())
103
            + QString::fromLatin1("[*]"));
104
    getEditor()->setPlainText(
105
            QString::fromUtf8(textDocument->Text.getValue()));
106
}
107

108
void TextDocumentEditorView::setupConnection()
109
{
110
    //NOLINTBEGIN
111
    textConnection = textDocument->connectText(
112
            std::bind(&TextDocumentEditorView::sourceChanged, this));
113
    labelConnection = textDocument->connectLabel(
114
            std::bind(&TextDocumentEditorView::labelChanged, this));
115
    //NOLINTEND
116
}
117

118
void TextDocumentEditorView::sourceChanged()
119
{
120
    if (getMainWindow()->activeWindow() == this) {
121
        refresh();
122
        sourceModified = false;
123
    } else {
124
        sourceModified = true;
125
    }
126
}
127

128
void TextDocumentEditorView::labelChanged()
129
{
130
    setWindowTitle(QString::fromUtf8(textDocument->Label.getValue())
131
            + QString::fromLatin1("[*]"));
132
}
133

134
void TextDocumentEditorView::refresh()
135
{
136
    QString text = QString::fromUtf8(
137
            textDocument->Text.getValue());
138
    if (isEditorModified()) {
139
        QMessageBox msgBox {this};
140
        msgBox.setWindowTitle(tr("Text updated"));
141
        msgBox.setIcon(QMessageBox::Question);
142
        msgBox.setText(tr(
143
                    "The text of the underlying object has changed. "
144
                    "Discard changes and reload the text from the object?"));
145
        msgBox.addButton(
146
                tr("Yes, reload."), QMessageBox::YesRole);
147
        QPushButton* noBtt = msgBox.addButton(QMessageBox::No);
148
        msgBox.exec();
149
        if (msgBox.clickedButton() == noBtt)
150
            return;
151
    }
152
    getEditor()->setPlainText(text);
153
}
154

155
bool TextDocumentEditorView::onMsg(const char* msg, const char**)
156
{
157
    // don't allow any actions if the editor is being closed
158
    if (aboutToClose)
159
        return false;
160

161
    if (strcmp(msg,"Save") == 0) {
162
        saveToObject();
163
        return getGuiDocument()->save();
164
    }
165
    if (strcmp(msg,"Cut") == 0) {
166
        getEditor()->cut();
167
        return true;
168
    }
169
    if (strcmp(msg,"Copy") == 0) {
170
        getEditor()->copy();
171
        return true;
172
    }
173
    if (strcmp(msg,"Paste") == 0) {
174
        getEditor()->paste();
175
        return true;
176
    }
177
    if (strcmp(msg,"Undo") == 0) {
178
        getEditor()->undo();
179
        return true;
180
    }
181
    if (strcmp(msg,"Redo") == 0) {
182
        getEditor()->redo();
183
        return true;
184
    }
185
    return false;
186
}
187

188
bool TextDocumentEditorView::isEditorModified() const
189
{
190
    return getEditor()->document()->isModified();
191
}
192

193
bool TextDocumentEditorView::onHasMsg(const char* msg) const
194
{
195
    // don't allow any actions if the editor is being closed
196
    if (aboutToClose)
197
        return false;
198

199
    if (strcmp(msg,"Save") == 0) {
200
        return true;
201
    }
202
    if (strcmp(msg,"Cut") == 0) {
203
        return (!getEditor()->isReadOnly() &&
204
                getEditor()->textCursor().hasSelection());
205
    }
206
    if (strcmp(msg,"Copy") == 0) {
207
        return (getEditor()->textCursor().hasSelection());
208
    }
209
    if (strcmp(msg,"Paste") == 0) {
210
        if (getEditor()->isReadOnly())
211
            return false;
212
        QClipboard *cb = QApplication::clipboard();
213
        QString text = cb->text();
214
        return !text.isEmpty();
215
    }
216
    if (strcmp(msg,"Undo") == 0) {
217
        return (getEditor()->document()->isUndoAvailable());
218
    }
219
    if (strcmp(msg,"Redo") == 0) {
220
        return (getEditor()->document()->isRedoAvailable());
221
    }
222
    return false;
223
}
224

225
bool TextDocumentEditorView::canClose()
226
{
227
    if (getEditor()->document()->isModified()) {
228
        this->setFocus();
229

230
        QMessageBox box(this);
231
        box.setIcon(QMessageBox::Question);
232
        box.setWindowTitle(tr("Unsaved document"));
233
        box.setText(tr("Do you want to save your changes before closing?"));
234
        box.setInformativeText(tr("If you don't save, your changes will be lost."));
235
        box.setStandardButtons(QMessageBox::Discard | QMessageBox::Cancel | QMessageBox::Save);
236
        box.setDefaultButton(QMessageBox::Save);
237
        box.setEscapeButton(QMessageBox::Cancel);
238

239
        // add shortcuts
240
        QAbstractButton* saveBtn = box.button(QMessageBox::Save);
241
        if (saveBtn->shortcut().isEmpty()) {
242
            QString text = saveBtn->text();
243
            text.prepend(QLatin1Char('&'));
244
            saveBtn->setShortcut(QKeySequence::mnemonic(text));
245
        }
246

247
        QAbstractButton* discardBtn = box.button(QMessageBox::Discard);
248
        if (discardBtn->shortcut().isEmpty()) {
249
            QString text = discardBtn->text();
250
            text.prepend(QLatin1Char('&'));
251
            discardBtn->setShortcut(QKeySequence::mnemonic(text));
252
        }
253

254
        box.adjustSize();
255
        switch (box.exec())
256
        {
257
        case QMessageBox::Save:
258
            saveToObject();
259
            if (getGuiDocument()->isLastView())
260
                return getGuiDocument()->save();
261
            return true;
262
        case QMessageBox::Discard:
263
            return true;
264
        case QMessageBox::Cancel:
265
        default:
266
            return false;
267
        }
268
    }
269
    else {
270
        // this view belongs to the document so we have to ask the user
271
        // how to continue if this is the last view
272
        return MDIView::canClose();
273
    }
274
}
275

276
void TextDocumentEditorView::saveToObject()
277
{
278
    boost::signals2::shared_connection_block textBlock {textConnection};
279
    textDocument->Text.setValue(
280
            getEditor()->document()->toPlainText().toUtf8());
281
    textDocument->purgeTouched();
282
    getEditor()->document()->setModified(false);
283
}
284

285
QStringList TextDocumentEditorView::undoActions() const
286
{
287
    QStringList undo;
288
    undo << tr("Edit text");
289
    return undo;
290
}
291

292
QStringList TextDocumentEditorView::redoActions() const
293
{
294
    QStringList redo;
295
    redo << tr("Edit text");
296
    return redo;
297
}
298

299
#include "moc_TextDocumentEditorView.cpp"
300

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.