File indexing completed on 2024-05-12 16:40:53
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at> 0003 Copyright (C) 2004-2005 Jarosław Staniek <staniek@kde.org> 0004 Copyright (C) 2005 Cedric Pasteur <cedric.pasteur@free.fr> 0005 0006 This program is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This program is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this program; see the file COPYING. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 * Boston, MA 02110-1301, USA. 0020 */ 0021 0022 #include "kexieditor.h" 0023 0024 #include <KexiMainWindowIface.h> 0025 #include <kexiutils/utils.h> 0026 0027 #include <QList> 0028 #include <QMenu> 0029 #include <QVBoxLayout> 0030 0031 //uncomment this to enable KTextEdit-based editor 0032 //#define KTEXTEDIT_BASED_TEXT_EDITOR 0033 0034 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0035 # include <KTextEdit> 0036 #else 0037 # include <KTextEditor/Document> 0038 # include <KTextEditor/Editor> 0039 # include <KTextEditor/View> 0040 # include <KTextEditor/ConfigInterface> 0041 #endif 0042 0043 /** Used for the shared action framework to redirect shared actions like 0044 copy and paste to the editor. */ 0045 class KexiEditorSharedActionConnector : public KexiSharedActionConnector 0046 { 0047 public: 0048 KexiEditorSharedActionConnector(KexiActionProxy* proxy, QObject* obj) 0049 : KexiSharedActionConnector(proxy, obj) { 0050 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0051 plugSharedAction("edit_cut", SLOT(cut())); 0052 plugSharedAction("edit_copy", SLOT(copy())); 0053 plugSharedAction("edit_paste", SLOT(paste())); 0054 plugSharedAction("edit_clear", SLOT(clear())); 0055 plugSharedAction("edit_undo", SLOT(undo())); 0056 plugSharedAction("edit_redo", SLOT(redo())); 0057 plugSharedAction("edit_select_all", SLOT(selectAll())); 0058 #else 0059 QList<QByteArray> actions; 0060 actions << "edit_cut" << "edit_copy" << "edit_paste" << "edit_clear" 0061 << "edit_undo" << "edit_redo" << "edit_select_all"; 0062 //! @todo KEXI3 plugSharedActionsToExternalGUI(actions, dynamic_cast<KXMLGUIClient*>(obj)); 0063 #endif 0064 } 0065 }; 0066 0067 //! @internal 0068 class Q_DECL_HIDDEN KexiEditor::Private 0069 { 0070 public: 0071 Private() {} 0072 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0073 KTextEdit *view; 0074 #else 0075 KTextEditor::Document *doc; 0076 KTextEditor::View *view; 0077 #endif 0078 }; 0079 0080 KexiEditor::KexiEditor(QWidget *parent) 0081 : KexiView(parent) 0082 , d(new Private()) 0083 { 0084 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0085 d->view = new KTextEdit("", QString(), this); 0086 //adjust font 0087 connect(d->view, SIGNAL(textChanged()), this, SIGNAL(textChanged())); 0088 QFont f("Courier"); 0089 f.setStyleStrategy(QFont::PreferAntialias); 0090 f.setPointSize(d->view->font().pointSize()); 0091 d->view->setFont(f); 0092 d->view->setCheckSpellingEnabled(false); 0093 #else 0094 QWidget *fr = new QWidget(this); 0095 QVBoxLayout *layout = new QVBoxLayout(fr); 0096 layout->setContentsMargins(0, 0, 0, 0); 0097 0098 KTextEditor::Editor *editor = KTextEditor::Editor::instance(); 0099 if (!editor) 0100 return; 0101 //! @todo error handling! 0102 0103 d->doc = editor->createDocument(fr); 0104 if (!d->doc) 0105 return; 0106 d->view = d->doc->createView(fr); 0107 // suppresing default saving mechanism of KTextEditor 0108 d->view->action("file_save")->setEnabled(false); 0109 // set word wrap by default 0110 KTextEditor::ConfigInterface *configIface 0111 = qobject_cast<KTextEditor::ConfigInterface*>(d->view); 0112 configIface->setConfigValue("dynamic-word-wrap", true); 0113 0114 //! @todo KEXI3 Q3PopupMenu *pop = qobject_cast<Q3PopupMenu*>( mainWin->factory()->container("edit", mainWin) ); 0115 //! @todo KEXI3 d->view->setContextMenu(pop); 0116 d->view->setContextMenu(d->view->defaultContextMenu()); 0117 0118 connect(d->doc, SIGNAL(textChanged(KTextEditor::Document*)), 0119 this, SLOT(slotTextChanged(KTextEditor::Document*))); 0120 #endif 0121 KexiEditorSharedActionConnector c(this, d->view); 0122 d->view->installEventFilter(this); 0123 0124 layout->addWidget(d->view); 0125 setViewWidget(fr, false/*!focus*/); 0126 setFocusProxy(d->view); 0127 } 0128 0129 KexiEditor::~KexiEditor() 0130 { 0131 delete d; 0132 } 0133 0134 void KexiEditor::updateActions(bool activated) 0135 { 0136 KexiView::updateActions(activated); 0137 } 0138 0139 bool KexiEditor::isAdvancedEditor() 0140 { 0141 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0142 return false; 0143 #else 0144 return true; 0145 #endif 0146 } 0147 0148 QString KexiEditor::text() 0149 { 0150 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0151 return d->view->text(); 0152 #else 0153 if (!d->doc) 0154 return QString(); 0155 return d->doc->text(); 0156 #endif 0157 } 0158 0159 void KexiEditor::setText(const QString &text) 0160 { 0161 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0162 const bool was_dirty = m_parentView ? m_parentView->idDirty() : idDirty(); 0163 d->view->setText(text); 0164 setDirty(was_dirty); 0165 #else 0166 if (!d->doc) 0167 return; 0168 const bool was_dirty = isDirty(); 0169 d->doc->setText(text); 0170 setDirty(was_dirty); 0171 #endif 0172 } 0173 0174 void KexiEditor::setHighlightMode(const QString& highlightmodename) 0175 { 0176 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0177 #else 0178 if (!d->doc) 0179 return; 0180 QString n = highlightmodename; 0181 if (n == "javascript" || n == "qtscript") 0182 n = "JavaScript"; 0183 else if (n.size() > 0) 0184 n = n[0].toLower() + n.mid(1); 0185 if (!d->doc->setMode(n)) 0186 d->doc->setMode(QString()); // don't highlight 0187 if (!d->doc->setHighlightingMode(n)) 0188 d->doc->setHighlightingMode(QString()); //hl->setHlMode(0); // 0=None, don't highlight anything. 0189 0190 //! @todo Code from 3540345ea16477d05e84, these signals no longer exist 0191 // QMetaObject::invokeMethod(d->view, "modeChanged", Q_ARG(KTextEditor::Document*, d->doc)); 0192 // QMetaObject::invokeMethod(d->view, "highlightingModeChanged", Q_ARG(KTextEditor::Document*, d->doc)); 0193 #endif 0194 } 0195 0196 void KexiEditor::slotConfigureEditor() 0197 { 0198 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0199 //! @todo show configuration... 0200 #else 0201 if (!d->doc) 0202 return; 0203 KTextEditor::Editor *editor = KTextEditor::Editor::instance(); 0204 if (!editor) 0205 return; 0206 editor->configDialog(this); 0207 //! @todo use d->doc->editor()->writeConfig() or KTextEditor::ConfigInterface to save changes 0208 #endif 0209 } 0210 0211 void KexiEditor::jump(int character) 0212 { 0213 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0214 const int numRows = d->view->paragraphs(); 0215 int row = 0, col = 0; 0216 for (int ch = 0; row < numRows; row++) { 0217 const int rowLen = d->view->paragraphLength(row) + 1; 0218 if ((ch + rowLen) > character) { 0219 col = character - ch; 0220 break; 0221 } 0222 ch += rowLen; 0223 } 0224 d->view->setCursorPosition(row, col); 0225 #else 0226 if (!d->doc) 0227 return; 0228 const int numRows = d->doc->lines(); 0229 int row = 0, col = 0; 0230 for (int ch = 0; row < numRows; row++) { 0231 const int rowLen = d->doc->lineLength(row) + 1; 0232 if ((ch + rowLen) > character) { 0233 col = character - ch; 0234 break; 0235 } 0236 ch += rowLen; 0237 } 0238 d->view->setCursorPosition(KTextEditor::Cursor(row, col)); 0239 #endif 0240 } 0241 0242 void KexiEditor::setCursorPosition(int line, int col) 0243 { 0244 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0245 d->view->setCursorPosition(line, col); 0246 #else 0247 d->view->setCursorPosition(KTextEditor::Cursor(line, col)); 0248 #endif 0249 } 0250 0251 void KexiEditor::clearUndoRedo() 0252 { 0253 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0254 //! @todo how to remove undo/redo from a KTextEdit? 0255 #else 0256 //! @todo KEXI3 KexiEditor::clearUndoRedo() 0257 #endif 0258 } 0259 0260 void KexiEditor::slotTextChanged(KTextEditor::Document *) 0261 { 0262 emit textChanged(); 0263 } 0264 0265 QMenu* KexiEditor::defaultContextMenu() 0266 { 0267 #ifdef KTEXTEDIT_BASED_TEXT_EDITOR 0268 return d->view->createStandardContextMenu(); 0269 #else 0270 QMenu* menu = d->view->defaultContextMenu(); 0271 menu->addSeparator(); 0272 menu->addAction(d->view->action("edit_find")); 0273 menu->addAction(d->view->action("edit_find_next")); 0274 menu->addAction(d->view->action("edit_find_prev")); 0275 menu->addAction(d->view->action("edit_replace")); 0276 menu->addAction(d->view->action("go_goto_line")); 0277 return menu; 0278 #endif 0279 } 0280