00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef _QEDITOR_H_
00017 #define _QEDITOR_H_
00018
00019 #include "qce-config.h"
00020
00026 #include <QHash>
00027 #include <QPointer>
00028 #include <QScrollBar>
00029 #include <QBasicTimer>
00030 #include <QFontMetrics>
00031 #include <QAbstractScrollArea>
00032
00033 #include "qdocument.h"
00034 #include "qdocumentcursor.h"
00035
00036 #ifdef _QMDI_
00037 #include "qmdiclient.h"
00038 #endif
00039
00040 class QMenu;
00041 class QAction;
00042 class QMimeData;
00043 class QTextCodec;
00044 class QActionGroup;
00045
00046 class QReliableFileWatch;
00047
00048 class QDocumentLineHandle;
00049
00050 class QLanguageDefinition;
00051 class QCodeCompletionEngine;
00052
00053 class QCE_EXPORT QEditor : public QAbstractScrollArea
00054 #ifdef _QMDI_
00055 , public qmdiClient
00056 #endif
00057 {
00058 friend class QEditConfig;
00059 friend class QEditorFactory;
00060
00061 Q_OBJECT
00062
00063 public:
00064 enum CodecUpdatePolicy
00065 {
00066 NoUpdate = 0,
00067 UpdateOld = 1,
00068 UpdateDefault = 2,
00069 UpdateCustom = 4,
00070
00071 UpdateAll = 7
00072 };
00073
00074 enum EditFlag
00075 {
00076 None = 0,
00077
00078 Overwrite = 0x001,
00079 CursorOn = 0x002,
00080 ReadOnly = 0x004,
00081 MousePressed = 0x008,
00082 MaybeDrag = 0x010,
00083 Selection = 0x020,
00084
00085 Persistent = 0x040,
00086 Multiline = 0x080,
00087 FoldedCursor = 0x100,
00088
00089 Internal = 0x00000fff,
00090
00091 LineWrap = 0x00001000,
00092
00093 CtrlNavigation = 0x00010000,
00094 CursorJumpPastWrap = 0x00020000,
00095
00096 ReplaceTabs = 0x00100000,
00097 RemoveTrailing = 0x00200000,
00098 PreserveTrailingIndent = 0x00400000,
00099
00100 AutoCloseChars = 0x01000000,
00101 AutoIndent = 0x02000000,
00102
00103 Accessible = 0xfffff000
00104 };
00105
00106 class InputBinding
00107 {
00108 public:
00109 virtual ~InputBinding() {}
00110
00111 virtual QString id() const = 0;
00112 virtual QString name() const = 0;
00113
00114 virtual bool keyPressEvent(QKeyEvent *event, QEditor *editor)
00115 {
00116 Q_UNUSED(event)
00117 Q_UNUSED(editor)
00118 return false;
00119 }
00120
00121 virtual void postKeyPressEvent(QKeyEvent *event, QEditor *editor)
00122 {
00123 Q_UNUSED(event)
00124 Q_UNUSED(editor)
00125 }
00126
00127 virtual bool inputMethodEvent(QInputMethodEvent* event, QEditor *editor)
00128 {
00129 Q_UNUSED(event)
00130 Q_UNUSED(editor)
00131 return false;
00132 }
00133
00134 virtual void postInputMethodEvent(QInputMethodEvent *event, QEditor *editor)
00135 {
00136 Q_UNUSED(event)
00137 Q_UNUSED(editor)
00138 }
00139
00140 virtual bool mouseMoveEvent(QMouseEvent *event, QEditor *editor)
00141 {
00142 Q_UNUSED(event)
00143 Q_UNUSED(editor)
00144 return false;
00145 }
00146
00147 virtual void postMouseMoveEvent(QMouseEvent *event, QEditor *editor)
00148 {
00149 Q_UNUSED(event)
00150 Q_UNUSED(editor)
00151 }
00152
00153 virtual bool mousePressEvent(QMouseEvent *event, QEditor *editor)
00154 {
00155 Q_UNUSED(event)
00156 Q_UNUSED(editor)
00157 return false;
00158 }
00159
00160 virtual void postMousePressEvent(QMouseEvent *event, QEditor *editor)
00161 {
00162 Q_UNUSED(event)
00163 Q_UNUSED(editor)
00164 }
00165
00166 virtual bool mouseReleaseEvent(QMouseEvent *event, QEditor *editor)
00167 {
00168 Q_UNUSED(event)
00169 Q_UNUSED(editor)
00170 return false;
00171 }
00172
00173 virtual void postMouseReleaseEvent(QMouseEvent *event, QEditor *editor)
00174 {
00175 Q_UNUSED(event)
00176 Q_UNUSED(editor)
00177 }
00178
00179 virtual bool mouseDoubleClickEvent(QMouseEvent *event, QEditor *editor)
00180 {
00181 Q_UNUSED(event)
00182 Q_UNUSED(editor)
00183 return false;
00184 }
00185
00186 virtual void postMouseDoubleClickEvent(QMouseEvent *event, QEditor *editor)
00187 {
00188 Q_UNUSED(event)
00189 Q_UNUSED(editor)
00190 }
00191
00192 virtual bool contextMenuEvent(QContextMenuEvent *event, QEditor *editor)
00193 {
00194 Q_UNUSED(event)
00195 Q_UNUSED(editor)
00196
00197 return false;
00198 }
00199 };
00200
00201 Q_DECLARE_FLAGS(State, EditFlag)
00202
00203 struct PlaceHolder
00204 {
00205 class Affector
00206 {
00207 public:
00208 virtual ~Affector() {}
00209 virtual QString affect(const QString& base, int i) = 0;
00210 };
00211
00212 PlaceHolder() : length(0), affector(0) {}
00213 PlaceHolder(const PlaceHolder& ph) : length(ph.length), affector(ph.affector)
00214 {
00215 cursor = ph.cursor;
00216 mirrors << ph.mirrors;
00217 }
00218
00219 int length;
00220 Affector *affector;
00221 QDocumentCursor cursor;
00222 QList<QDocumentCursor> mirrors;
00223 };
00224
00225 QEditor(QWidget *p = 0);
00226 QEditor(bool actions, QWidget *p = 0);
00227 QEditor(const QString& s, QWidget *p = 0);
00228 QEditor(const QString& s, bool actions, QWidget *p = 0);
00229 virtual ~QEditor();
00230
00231 bool flag(EditFlag) const;
00232
00233 bool canUndo() const;
00234 bool canRedo() const;
00235
00236 QString text() const;
00237 QString text(int line) const;
00238
00239 QTextCodec* codec() const;
00240 QDocument* document() const;
00241 InputBinding* inputBinding() const;
00242
00243 bool isCursorVisible() const;
00244 QDocumentCursor cursor() const;
00245
00246 int cursorMirrorCount() const;
00247 QDocumentCursor cursorMirror(int i) const;
00248
00249 QLanguageDefinition* languageDefinition() const;
00250 QCodeCompletionEngine* completionEngine() const;
00251
00252 QAction* action(const QString& s);
00253
00254 virtual QRect cursorRect() const;
00255 virtual QRect selectionRect() const;
00256 virtual QRect lineRect(int line) const;
00257 virtual QRect lineRect(const QDocumentLine& l) const;
00258 virtual QRect cursorRect(const QDocumentCursor& c) const;
00259
00260 #ifndef _QMDI_
00261 QString name() const;
00262 QString fileName() const;
00263
00264 bool isContentModified() const;
00265 #endif
00266
00267 bool isInConflict() const;
00268
00269 int wrapWidth() const;
00270
00271 inline int horizontalOffset() const
00272 { return horizontalScrollBar()->isVisible() ? horizontalScrollBar()->value() : 0; }
00273 inline int verticalOffset() const
00274 { return verticalScrollBar()->isVisible() ? verticalScrollBar()->value() * m_doc->fontMetrics().lineSpacing() : 0; }
00275
00276 inline QPoint mapToContents(const QPoint &point) const
00277 {
00278 return QPoint( point.x() + horizontalOffset(),
00279 point.y() + verticalOffset() );
00280 }
00281
00282 inline QPoint mapFromContents(const QPoint &point) const
00283 {
00284 return QPoint( point.x() - horizontalOffset(),
00285 point.y() - verticalOffset() );
00286 }
00287
00288 static int defaultFlags();
00289 static void setDefaultFlags(int f);
00290
00291 static QTextCodec* defaultCodec();
00292 static void setDefaultCodec(int mib, int update);
00293 static void setDefaultCodec(QTextCodec *c, int update);
00294 static void setDefaultCodec(const char *name, int update);
00295 static void setDefaultCodec(const QByteArray& name, int update);
00296
00297 static QStringList inputBindings();
00298 static QString defaultInputBinding();
00299 static void addInputBinding(InputBinding *b);
00300 static void removeInputBinding(InputBinding *b);
00301 static void setDefaultInputBinding(InputBinding *b);
00302 static void setDefaultInputBinding(const QString& b);
00303
00304 public slots:
00305 void undo();
00306 void redo();
00307
00308 void cut();
00309 void copy();
00310 void paste();
00311
00312 void selectAll();
00313
00314 void find();
00315 void findNext();
00316 void replace();
00317
00318 void gotoLine();
00319
00320 void indentSelection();
00321 void unindentSelection();
00322
00323 void commentSelection();
00324 void uncommentSelection();
00325
00326 void setLineWrapping(bool on);
00327
00328 virtual void save();
00329 void save(const QString& filename);
00330
00331 virtual void print();
00332
00333 virtual void retranslate();
00334
00335 virtual void write(const QString& s);
00336
00337 void addAction(QAction *a, const QString& menu, const QString& toolbar = QString());
00338 void removeAction(QAction *a, const QString& menu, const QString& toolbar = QString());
00339
00340 void load(const QString& file);
00341 void setText(const QString& s);
00342
00343 void setCodec(int mib);
00344 void setCodec(QTextCodec *c);
00345 void setCodec(const char *name);
00346 void setCodec(const QByteArray& name);
00347
00348 void setDocument(QDocument *d);
00349 void setInputBinding(InputBinding *b);
00350
00351 void setCursor(const QDocumentCursor& c);
00352
00353 void setLanguageDefinition(QLanguageDefinition *d);
00354
00355 void setCompletionEngine(QCodeCompletionEngine *e);
00356
00357 void zoom(int n);
00358
00359 void setPanelMargins(int l, int t, int r, int b);
00360 void getPanelMargins(int *l, int *t, int *r, int *b) const;
00361
00362 void setTitle(const QString& title);
00363
00364 void highlight();
00365
00366 void clearPlaceHolders();
00367 void addPlaceHolder(const PlaceHolder& p, bool autoUpdate = true);
00368
00369 int placeHolderCount() const;
00370
00371 void nextPlaceHolder();
00372 void previousPlaceHolder();
00373 void setPlaceHolder(int i);
00374
00375 virtual void setFileName(const QString& f);
00376
00377 signals:
00378 void loaded(QEditor *e, const QString& s);
00379 void saved(QEditor *e, const QString& s);
00380
00381 void contentModified(bool y);
00382 void titleChanged(const QString& title);
00383
00384 void textEdited(QKeyEvent *e);
00385 void cursorPositionChanged();
00386
00387 void copyAvailable(bool y);
00388
00389 void undoAvailable(bool y);
00390 void redoAvailable(bool y);
00391
00392 void markChanged(const QString& f, QDocumentLineHandle *l, int mark, bool on);
00393
00394 public slots:
00395 void checkClipboard();
00396 void reconnectWatcher();
00397 void fileChanged(const QString& f);
00398
00399 void setContentClean(bool y);
00400
00401 void emitCursorPositionChanged();
00402
00403 virtual void setContentModified(bool y);
00404
00405 protected:
00406 virtual bool event(QEvent *e);
00407
00408 virtual void paintEvent(QPaintEvent *e);
00409 virtual void timerEvent(QTimerEvent *e);
00410
00411 virtual void keyPressEvent(QKeyEvent *e);
00412
00413 virtual void inputMethodEvent(QInputMethodEvent* e);
00414
00415 virtual void mouseMoveEvent(QMouseEvent *e);
00416 virtual void mousePressEvent(QMouseEvent *e);
00417 virtual void mouseReleaseEvent(QMouseEvent *e);
00418 virtual void mouseDoubleClickEvent(QMouseEvent *e);
00419
00420 virtual void dragEnterEvent(QDragEnterEvent *e);
00421 virtual void dragLeaveEvent(QDragLeaveEvent *e);
00422 virtual void dragMoveEvent(QDragMoveEvent *e);
00423 virtual void dropEvent(QDropEvent *e);
00424
00425 virtual void changeEvent(QEvent *e);
00426 virtual void showEvent(QShowEvent *);
00427 virtual void wheelEvent(QWheelEvent *e);
00428 virtual void resizeEvent(QResizeEvent *e);
00429 virtual void focusInEvent(QFocusEvent *e);
00430 virtual void focusOutEvent(QFocusEvent *e);
00431
00432 virtual void contextMenuEvent(QContextMenuEvent *e);
00433
00434 virtual void closeEvent(QCloseEvent *e);
00435
00436 virtual bool focusNextPrevChild(bool next);
00437
00438 virtual bool moveKeyEvent(QDocumentCursor& c, QKeyEvent *e, bool *leave);
00439 virtual bool isProcessingKeyEvent(QKeyEvent *e, int *offset = 0);
00440 virtual bool processCursor(QDocumentCursor& c, QKeyEvent *e, bool& b);
00441
00442 virtual void startDrag();
00443 virtual QMimeData* createMimeDataFromSelection() const;
00444 virtual void insertFromMimeData(const QMimeData *d);
00445
00446 virtual void scrollContentsBy(int dx, int dy);
00447
00448
00449 public:
00450 void setFlag(EditFlag f, bool b);
00451
00452 void pageUp(QDocumentCursor::MoveMode moveMode);
00453 void pageDown(QDocumentCursor::MoveMode moveMode);
00454
00455 void selectionChange(bool force = false);
00456
00457 void repaintCursor();
00458 void ensureCursorVisible();
00459 void ensureVisible(int line);
00460 void ensureVisible(const QRect &rect);
00461
00462 void insertText(QDocumentCursor& c, const QString& text);
00463
00464 QDocumentLine lineAtPosition(const QPoint& p) const;
00465 QDocumentCursor cursorForPosition(const QPoint& p) const;
00466
00467 void setClipboardSelection();
00468 void setCursorPosition(const QPoint& p);
00469
00470 void setCursorPosition(int line, int index);
00471 void getCursorPosition(int &line, int &index);
00472
00473 void clearCursorMirrors();
00474 void addCursorMirror(const QDocumentCursor& c);
00475
00476 protected slots:
00477 void documentWidthChanged(int newWidth);
00478 void documentHeightChanged(int newWidth);
00479
00480 void repaintContent(int i, int n);
00481 void updateContent (int i, int n);
00482
00483 void markChanged(QDocumentLineHandle *l, int mark, bool on);
00484
00485 void bindingSelected(QAction *a);
00486
00487 void lineEndingSelected(QAction *a);
00488 void lineEndingChanged(int lineEnding);
00489
00490 protected:
00491 enum SaveState
00492 {
00493 Undefined,
00494 Saving,
00495 Saved,
00496 Conflict
00497 };
00498
00499 void init(bool actions = true);
00500 void updateBindingsMenu();
00501
00502 #ifndef _QMDI_
00503 QString m_name, m_fileName;
00504 #endif
00505
00506 QMenu *pMenu;
00507 QHash<QString, QAction*> m_actions;
00508
00509 QMenu *m_lineEndingsMenu;
00510 QActionGroup *m_lineEndingsActions;
00511
00512 QMenu *m_bindingsMenu;
00513 QAction *aDefaultBinding;
00514 QActionGroup *m_bindingsActions;
00515
00516 char m_saveState;
00517 quint16 m_checksum;
00518
00519 QDocument *m_doc;
00520 QTextCodec *m_codec;
00521 InputBinding *m_binding;
00522
00523 QLanguageDefinition *m_definition;
00524 QPointer<QCodeCompletionEngine> m_completionEngine;
00525
00526 QDocumentCursor m_cursor, m_doubleClick, m_dragAndDrop;
00527
00528 QList<QDocumentCursor> m_mirrors;
00529
00530 int m_curPlaceHolder, m_cphOffset;
00531 QList<PlaceHolder> m_placeHolders;
00532
00533 int m_state;
00534 bool m_selection;
00535 QRect m_crect, m_margins;
00536 QPoint m_clickPoint, m_dragPoint;
00537 QBasicTimer m_blink, m_scroll, m_click, m_drag;
00538
00539 static QReliableFileWatch* watcher();
00540
00541 static int m_defaultFlags;
00542 static QTextCodec *m_defaultCodec;
00543
00544 static QList<QEditor*> m_editors;
00545 static InputBinding *m_defaultBinding;
00546 static QHash<QString, InputBinding*> m_bindings;
00547 };
00548
00549 Q_DECLARE_OPERATORS_FOR_FLAGS(QEditor::State);
00550
00551 #endif