QCodeEdit  2.2
lib/qeditor.h
Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
00004 **
00005 ** This file is part of the Edyuk project <http://edyuk.org>
00006 ** 
00007 ** This file may be used under the terms of the GNU General Public License
00008 ** version 3 as published by the Free Software Foundation and appearing in the
00009 ** file GPL.txt included in the packaging of this file.
00010 **
00011 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00012 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
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 QEditorInputBindingInterface;
00054 
00055 class QCE_EXPORT QEditor : public QAbstractScrollArea
00056 #ifdef _QMDI_
00057 , public qmdiClient
00058 #endif
00059 {
00060     friend class QEditConfig;
00061     friend class QEditorFactory;
00062     
00063     Q_OBJECT
00064     
00065     public:
00066         enum CodecUpdatePolicy
00067         {
00068             NoUpdate        = 0,
00069             UpdateOld       = 1,
00070             UpdateDefault   = 2,
00071             UpdateCustom    = 4,
00072             
00073             UpdateAll       = 7
00074         };
00075         
00076         enum EditFlag
00077         {
00078             None            = 0,
00079             
00080             Overwrite       = 0x001,
00081             CursorOn        = 0x002,
00082             ReadOnly        = 0x004,
00083             MousePressed    = 0x008,
00084             MaybeDrag       = 0x010,
00085             Selection       = 0x020,
00086             EnsureVisible   = 0x040,
00087             
00088             FoldedCursor    = 0x100,
00089             
00090             Internal                = 0x00000fff,
00091             
00092             LineWrap                = 0x00001000,
00093             
00094             CtrlNavigation          = 0x00010000,
00095             CursorJumpPastWrap      = 0x00020000,
00096             
00097             ReplaceTabs             = 0x00100000,
00098             RemoveTrailing          = 0x00200000,
00099             PreserveTrailingIndent  = 0x00400000,
00100             AdjustIndent            = 0x00800000,
00101             
00102             AutoCloseChars          = 0x01000000,
00103             AutoIndent              = 0x02000000,
00104             
00105             Accessible              = 0xfffff000
00106         };
00107         
00108         Q_DECLARE_FLAGS(State, EditFlag)
00109         
00110         struct PlaceHolder
00111         {
00112             class Affector
00113             {
00114                 public:
00115                     virtual ~Affector() {}
00116                     virtual void affect(const QStringList& base, int ph, const QKeyEvent *e, int mirror, QString& after) const = 0;
00117             };
00118             
00119             PlaceHolder() : length(0), autoRemove(false), affector(0) {}
00120             PlaceHolder(const PlaceHolder& ph) : length(ph.length), autoRemove(ph.autoRemove), affector(ph.affector)
00121             {
00122                 cursor = ph.cursor;
00123                 mirrors << ph.mirrors;
00124             }
00125             
00126             int length;
00127             bool autoRemove;
00128             Affector *affector;
00129             QDocumentCursor cursor;
00130             QList<QDocumentCursor> mirrors;
00131         };
00132         
00133         QEditor(QWidget *p = 0);
00134         QEditor(bool actions, QWidget *p = 0);
00135         QEditor(const QString& s, QWidget *p = 0);
00136         QEditor(const QString& s, bool actions, QWidget *p = 0);
00137         virtual ~QEditor();
00138         
00139         bool flag(EditFlag) const;
00140         
00141         bool canUndo() const;
00142         bool canRedo() const;
00143         
00144         QString text() const;
00145         QString text(int line) const;
00146         
00147         QTextCodec* codec() const;
00148         QDocument* document() const;
00149         
00150         QList<QEditorInputBindingInterface*> inputBindings() const;
00151         
00152         bool isCursorVisible() const;
00153         QDocumentCursor cursor() const;
00154         
00155         int cursorMirrorCount() const;
00156         QDocumentCursor cursorMirror(int i) const;
00157         
00158         QLanguageDefinition* languageDefinition() const;
00159         QCodeCompletionEngine* completionEngine() const;
00160         
00161         QAction* action(const QString& s);
00162         
00163         virtual QRect cursorRect() const;
00164         virtual QRect selectionRect() const;
00165         virtual QRect lineRect(int line) const;
00166         virtual QRect lineRect(const QDocumentLine& l) const;
00167         virtual QRect cursorRect(const QDocumentCursor& c) const;
00168         
00169         #ifndef _QMDI_
00170         QString name() const;
00171         QString fileName() const;
00172         
00173         bool isContentModified() const;
00174         #endif
00175         
00176         bool isInConflict() const;
00177         
00178         int wrapWidth() const;
00179         
00180         inline int horizontalOffset() const
00181         { return horizontalScrollBar()->isVisible() ? horizontalScrollBar()->value() : 0; }
00182         inline int verticalOffset() const
00183         { return verticalScrollBar()->isVisible() ? verticalScrollBar()->value() * m_doc->fontMetrics().lineSpacing() : 0; }
00184         
00185         inline QPoint mapToContents(const QPoint &point) const
00186         {
00187             return QPoint(  point.x() + horizontalOffset(),
00188                             point.y() + verticalOffset() );
00189         }
00190         
00191         inline QPoint mapFromContents(const QPoint &point) const
00192         {
00193             return QPoint(  point.x() - horizontalOffset(),
00194                             point.y() - verticalOffset() );
00195         }
00196         
00197         virtual bool protectedCursor(const QDocumentCursor& c) const;
00198         
00199         static int defaultFlags();
00200         static void setDefaultFlags(int f);
00201         
00202         static QTextCodec* defaultCodec();
00203         static void setDefaultCodec(int mib, int update);
00204         static void setDefaultCodec(QTextCodec *c, int update);
00205         static void setDefaultCodec(const char *name, int update);
00206         static void setDefaultCodec(const QByteArray& name, int update);
00207         
00208         static QEditorInputBindingInterface* registeredInputBinding(const QString& n);
00209         static QString defaultInputBindingId();
00210         static QStringList registeredInputBindingIds();
00211         static void registerInputBinding(QEditorInputBindingInterface *b);
00212         static void unregisterInputBinding(QEditorInputBindingInterface *b);
00213         static void setDefaultInputBinding(QEditorInputBindingInterface *b);
00214         static void setDefaultInputBinding(const QString& b);
00215         
00216         static inline const QList<QEditor*>& editors() { return m_editors; }
00217         
00218     public slots:
00219         void undo();
00220         void redo();
00221         
00222         void cut();
00223         void copy();
00224         void paste();
00225         
00226         void selectAll();
00227         
00228         void find();
00229         void findNext();
00230         void replace();
00231         
00232         void gotoLine();
00233         
00234         void indentSelection();
00235         void unindentSelection();
00236         
00237         void commentSelection();
00238         void uncommentSelection();
00239         
00240         void setLineWrapping(bool on);
00241         
00242         virtual void save();
00243         void save(const QString& filename);
00244         
00245         virtual void print();
00246         
00247         virtual void retranslate();
00248         
00249         virtual void write(const QString& s);
00250         
00251         void addAction(QAction *a, const QString& menu, const QString& toolbar = QString());
00252         void removeAction(QAction *a, const QString& menu, const QString& toolbar = QString());
00253         
00254         void load(const QString& file);
00255         void setText(const QString& s);
00256         
00257         void setCodec(int mib);
00258         void setCodec(QTextCodec *c);
00259         void setCodec(const char *name);
00260         void setCodec(const QByteArray& name);
00261         
00262         void setDocument(QDocument *d);
00263         
00264         void addInputBinding(QEditorInputBindingInterface *b);
00265         void removeInputBinding(QEditorInputBindingInterface *b);
00266         void setInputBinding(QEditorInputBindingInterface *b);
00267         
00268         void setCursor(const QDocumentCursor& c);
00269         
00270         void setLanguageDefinition(QLanguageDefinition *d);
00271         
00272         void setCompletionEngine(QCodeCompletionEngine *e);
00273         
00274         void zoom(int n);
00275         
00276         void setPanelMargins(int l, int t, int r, int b);
00277         void getPanelMargins(int *l, int *t, int *r, int *b) const;
00278         
00279         void setTitle(const QString& title);
00280         
00281         void highlight();
00282         
00283         void clearPlaceHolders();
00284         void removePlaceHolder(int i);
00285         void addPlaceHolder(const PlaceHolder& p, bool autoUpdate = true);
00286         
00287         int placeHolderCount() const;
00288         int currentPlaceHolder() const;
00289         
00290         void nextPlaceHolder();
00291         void previousPlaceHolder();
00292         void setPlaceHolder(int i);
00293         
00294         virtual void setFileName(const QString& f);
00295         
00296     signals:
00297         void loaded(QEditor *e, const QString& s);
00298         void saved(QEditor *e, const QString& s);
00299         
00300         void contentModified(bool y);
00301         void titleChanged(const QString& title);
00302         
00303         void textEdited(QKeyEvent *e);
00304         void cursorPositionChanged();
00305         
00306         void copyAvailable(bool y);
00307         
00308         void undoAvailable(bool y);
00309         void redoAvailable(bool y);
00310         
00311         void markChanged(const QString& f, QDocumentLineHandle *l, int mark, bool on);
00312         
00313     public slots:
00314         void checkClipboard();
00315         void reconnectWatcher();
00316         void fileChanged(const QString& f);
00317         
00318         void setContentClean(bool y);
00319         
00320         void emitCursorPositionChanged();
00321         
00322         virtual void setContentModified(bool y);
00323         
00324     protected:
00325         virtual bool event(QEvent *e);
00326         
00327         virtual void paintEvent(QPaintEvent *e);
00328         virtual void timerEvent(QTimerEvent *e);
00329         
00330         virtual void keyPressEvent(QKeyEvent *e);
00331         
00332         virtual void inputMethodEvent(QInputMethodEvent* e);
00333         
00334         virtual void mouseMoveEvent(QMouseEvent *e);
00335         virtual void mousePressEvent(QMouseEvent *e);
00336         virtual void mouseReleaseEvent(QMouseEvent *e);
00337         virtual void mouseDoubleClickEvent(QMouseEvent *e);
00338         
00339         virtual void dragEnterEvent(QDragEnterEvent *e);
00340         virtual void dragLeaveEvent(QDragLeaveEvent *e);
00341         virtual void dragMoveEvent(QDragMoveEvent *e);
00342         virtual void dropEvent(QDropEvent *e);
00343         
00344         virtual void changeEvent(QEvent *e);
00345         virtual void showEvent(QShowEvent *);
00346         virtual void wheelEvent(QWheelEvent *e);
00347         virtual void resizeEvent(QResizeEvent *e);
00348         virtual void focusInEvent(QFocusEvent *e);
00349         virtual void focusOutEvent(QFocusEvent *e);
00350         
00351         virtual void contextMenuEvent(QContextMenuEvent *e);
00352         
00353         virtual void closeEvent(QCloseEvent *e);
00354         
00355         virtual bool focusNextPrevChild(bool next);
00356         
00357         virtual bool moveKeyEvent(QDocumentCursor& c, QKeyEvent *e, bool *leave);
00358         virtual bool isProcessingKeyEvent(QKeyEvent *e, int *offset = 0);
00359         virtual bool processCursor(QDocumentCursor& c, QKeyEvent *e, bool& b);
00360         
00361         virtual void startDrag();
00362         virtual QMimeData* createMimeDataFromSelection() const;
00363         virtual void insertFromMimeData(const QMimeData *d);
00364         
00365         virtual void scrollContentsBy(int dx, int dy);
00366         
00367         // got to make it public for bindings
00368     public:
00369         void setFlag(EditFlag f, bool b);
00370         
00371         void pageUp(QDocumentCursor::MoveMode moveMode);
00372         void pageDown(QDocumentCursor::MoveMode moveMode);
00373         
00374         void selectionChange(bool force = false);
00375         
00376         void repaintCursor();
00377         void ensureCursorVisible();
00378         void ensureVisible(int line);
00379         void ensureVisible(const QRect &rect);
00380         
00381         void preInsert(QDocumentCursor& c, const QString& text);
00382         void insertText(QDocumentCursor& c, const QString& text);
00383         
00384         QDocumentLine lineAtPosition(const QPoint& p) const;
00385         QDocumentCursor cursorForPosition(const QPoint& p) const;
00386         
00387         void setClipboardSelection();
00388         void setCursorPosition(const QPoint& p);
00389         
00390         void setCursorPosition(int line, int index);
00391         void getCursorPosition(int &line, int &index);
00392         
00393         void clearCursorMirrors();
00394         void addCursorMirror(const QDocumentCursor& c);
00395         
00396     protected slots:
00397         void documentWidthChanged(int newWidth);
00398         void documentHeightChanged(int newWidth);
00399         
00400         void repaintContent(int i, int n);
00401         void updateContent (int i, int n);
00402         
00403         void markChanged(QDocumentLineHandle *l, int mark, bool on);
00404         
00405         void bindingSelected(QAction *a);
00406         
00407         void lineEndingSelected(QAction *a);
00408         void lineEndingChanged(int lineEnding);
00409         
00410     protected:
00411         enum SaveState
00412         {
00413             Undefined,
00414             Saving,
00415             Saved,
00416             Conflict
00417         };
00418         
00419         void init(bool actions = true);
00420         void updateBindingsMenu();
00421         
00422         #ifndef _QMDI_
00423         QString m_name, m_fileName;
00424         #endif
00425         
00426         QMenu *pMenu;
00427         QHash<QString, QAction*> m_actions;
00428         
00429         QMenu *m_lineEndingsMenu;
00430         QActionGroup *m_lineEndingsActions;
00431         
00432         QMenu *m_bindingsMenu;
00433         QAction *aDefaultBinding;
00434         QActionGroup *m_bindingsActions;
00435         
00436         char m_saveState;
00437         quint16 m_checksum;
00438         
00439         QDocument *m_doc;
00440         QTextCodec *m_codec;
00441         QList<QEditorInputBindingInterface*> m_bindings;
00442         
00443         QLanguageDefinition *m_definition;
00444         QPointer<QCodeCompletionEngine> m_completionEngine;
00445         
00446         QDocumentCursor m_cursor, m_doubleClick, m_dragAndDrop;
00447         
00448         QList<QDocumentCursor> m_mirrors;
00449         
00450         int m_curPlaceHolder, m_cphOffset;
00451         QList<PlaceHolder> m_placeHolders;
00452         
00453         int m_state;
00454         bool m_selection;
00455         QRect m_crect, m_margins;
00456         QPoint m_clickPoint, m_dragPoint;
00457         QBasicTimer m_blink, m_scroll, m_click, m_drag;
00458         
00459         static QReliableFileWatch* watcher();
00460         
00461         static int m_defaultFlags;
00462         static QTextCodec *m_defaultCodec;
00463         
00464         static QList<QEditor*> m_editors;
00465         static QEditorInputBindingInterface *m_defaultBinding;
00466         static QHash<QString, QEditorInputBindingInterface*> m_registeredBindings;
00467 };
00468 
00469 Q_DECLARE_OPERATORS_FOR_FLAGS(QEditor::State);
00470 
00471 #endif