#ifndef WIDGETS_H #define WIDGETS_H class HelpContentsKeySequence : public QKeySequence { public: // HelpContents = Ctrl+? in mac os X, is not working http://www.qtcentre.org/threads/57829-Shortcut-QKeySequence-HelpContents-and-Modal-Dialog HelpContentsKeySequence() : QKeySequence(QString("F1")) {} }; class LineEditHelper : public QLineEdit { Q_OBJECT public: LineEditHelper(QWidget * parent = 0); signals: void doubleClicked(); protected: void mouseDoubleClickEvent(QMouseEvent *event); }; class EnumEdit : public QComboBox { Q_OBJECT public: EnumEdit(QWidget * parent, const QStringList &items); signals: void dropDown(); private slots: void editDoubleClicked(); protected: virtual void keyPressEvent(QKeyEvent *event); virtual void showPopup(); }; class BoolEdit : public EnumEdit { Q_OBJECT public: BoolEdit(QWidget * parent = 0); void setChecked(bool value) { setCurrentIndex(value ? 1 : 0); } bool checked() const { return currentIndex() == 1; } signals: void toggled(bool value); private slots: void slotCurrentIndexChanged(int value); }; class StringListEdit : public QPlainTextEdit { Q_OBJECT public: StringListEdit(QWidget * parent = 0); private slots: void slotTextChanged(); signals: void textChanged(const QString &string); }; class LineEdit : public QLineEdit { public: LineEdit(QWidget *parent = NULL) : QLineEdit(parent) { #ifdef __APPLE__ setAttribute(Qt::WA_MacShowFocusRect, false); #endif } }; class ButtonLineEdit : public LineEdit { Q_OBJECT public: ButtonLineEdit(QWidget *parent = 0); protected: void resizeEvent(QResizeEvent *); void mouseDoubleClickEvent(QMouseEvent *e); QToolButton *button() const { return button_; } protected slots: virtual void buttonClicked() { } private: QToolButton *button_; }; class SearchLineEdit : public ButtonLineEdit { Q_OBJECT public: SearchLineEdit(QWidget *parent = 0); protected: void mouseDoubleClickEvent(QMouseEvent *e); protected slots: virtual void buttonClicked(); private slots: void updateButton(const QString &text); }; class FileDialog { public: static QString getOpenFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); static QString getSaveFileName(QWidget *parent = 0, const QString &caption = QString(), const QString &dir = QString(), const QString &filter = QString(), QString *selectedFilter = 0, QFileDialog::Options options = 0); static QString defaultPath() { return defaultPath_; } private: static QString defaultPath_; }; class FileNameEdit : public ButtonLineEdit { Q_OBJECT public: FileNameEdit(QWidget *parent = 0); void setFilter(const QString &filter) { filter_ = filter; } void setRelativePath(const QString &relativePath) { relativePath_ = relativePath; } void setSaveMode(bool value) { saveMode_ = value; } signals: void fileOpened(const QString &value); protected slots: virtual void buttonClicked(); private: virtual bool event(QEvent *e); QString filter_; QString relativePath_; bool saveMode_; }; class WatermarkEdit : public ButtonLineEdit { Q_OBJECT public: WatermarkEdit(QWidget *parent = 0); protected slots: virtual void buttonClicked(); }; class ScriptEdit : public Scintilla::ScintillaEditBase { Q_OBJECT public: ScriptEdit(QWidget *parent = 0); void setText(const QString &text); QString text() const; bool canUndo() const; bool canRedo() const; bool canPaste() const; bool hasSelection() const; void del(); QPoint currentPos() const; bool getOverType() const; void setOverType(bool value) const; void maintainIndentation(int ch); void hilightView(); signals: void updateUI(); public slots: void undo(); void redo(); void copy(); void cut(); void paste(); }; class TabWidget : public QTabWidget { Q_OBJECT public: explicit TabWidget(QWidget *parent = 0) : QTabWidget(parent) { #ifdef __APPLE__ setAttribute(Qt::WA_LayoutUsesWidgetRect, false); #endif } QTabBar* tabBar() const { return QTabWidget::tabBar(); } signals: void resized(); protected: virtual void resizeEvent(QResizeEvent *e) { QTabWidget::resizeEvent(e); emit resized(); } }; #define MONOSPACE_FONT_FAMILY "Courier New" class BinEditor : public QAbstractScrollArea { Q_OBJECT public: BinEditor(QWidget *parent = 0); ~BinEditor(); void setData(const QByteArray &data); QByteArray data() const { return data_; } QString value() const; void setValue(const QString &value); enum MoveMode { MoveAnchor, KeepAnchor }; void setCursorPosition(int pos, MoveMode moveMode = MoveAnchor); void setOverwriteMode(bool value); bool overwriteMode() { return overwriteMode_; } int maxLength() const { return maxLength_; } void setMaxLength(int value) { maxLength_ = value; } void setMaskAllowed(bool value) { maskAllowed_ = value; } bool isEmpty() const { return data_.isEmpty(); } bool isUndoAvailable() const; bool isRedoAvailable() const; bool hasSelectedText() const; public slots: void selectAll(); void copy(); void cut(); bool deleteSelection(); void paste(); void undo(); void redo(); signals: void dataChanged(); protected: struct CheckPoint { CheckPoint(int cp = 0, int ap = 0, const QString &t = "") : cursorPosition(cp), anchorPosition(ap), text(t) {} int cursorPosition, anchorPosition; QString text; }; CheckPoint CurrentCheckPoint() const { return CheckPoint(cursorPosition_, anchorPosition_, value()); } class CheckPointMaker { public: CheckPointMaker(BinEditor *obj) : obj_(obj), original_cp_(obj->CurrentCheckPoint()) {} ~CheckPointMaker() { if (obj_->value() != original_cp_.text) obj_->makeUndoCheckpoint(original_cp_); } private: BinEditor *obj_; CheckPoint original_cp_; }; friend class CheckPointMaker; void makeUndoCheckpoint(const CheckPoint &cp); void restoreUndoCheckpoint(const CheckPoint &cp); void paintEvent(QPaintEvent *e); void resizeEvent(QResizeEvent *); void mousePressEvent(QMouseEvent *e); void mouseMoveEvent(QMouseEvent *e); void focusInEvent(QFocusEvent *); void focusOutEvent(QFocusEvent *); void timerEvent(QTimerEvent *); void keyPressEvent(QKeyEvent *e); bool event(QEvent *e); void contextMenuEvent(QContextMenuEvent *); private: void init(); int posAt(const QPoint &pos) const; void updateLines(); void updateLines(int fromPosition, int toPosition); void setBlinkingCursorEnabled(bool enable); void ensureCursorVisible(); QRect cursorRect() const; void insert(int index, char c); void insert(int index, const QString &str); void replace(int index, char c, char mask = 0); void remove(int index, int len = 1); bool inTextArea(const QPoint &pos) const; void changed(); bool deleteSelectionInternal(); QMenu *createStandardContextMenu(); int bytesPerLine_; int numVisibleLines_; int lineHeight_; int charWidth_; int numLines_; QByteArray data_; QByteArray mask_; int margin_; int addressWidth_; int columnWidth_; int textWidth_; int cursorPosition_; int anchorPosition_; bool cursorVisible_; QBasicTimer cursorBlinkTimer_; bool overwriteMode_; bool hexCursor_; int maxLength_; bool maskAllowed_; QStack m_undoStack, m_redoStack; }; namespace Qt { namespace Vmp { enum ItemDataRole { StaticTextRole = Qt::UserRole + 1, StaticColorRole }; }; } class TreeViewItemDelegate : public QStyledItemDelegate { public: TreeViewItemDelegate(QObject *parent = NULL); void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const; void setEditorData(QWidget *editor, const QModelIndex &index) const; }; template class TTemplateView : public T { public: TTemplateView(QWidget *parent = NULL); void copy(); private: void getIndexTexts(const QModelIndex &idx, QString *selected_text_as_html, QString *selected_text); }; template TTemplateView::TTemplateView(QWidget *parent) : T(parent) { #ifdef __APPLE__ T::setAttribute(Qt::WA_MacShowFocusRect, false); #endif T::setItemDelegate(new TreeViewItemDelegate(this)); } template void TTemplateView::getIndexTexts(const QModelIndex &idx, QString *selected_text_as_html, QString *selected_text) { QString text = idx.data().toString(); QString staticText = idx.data(Qt::Vmp::StaticTextRole).toString().replace('\x1', QChar(0x2190)).replace('\x2', QChar(0x2191)).replace('\x3', QChar(0x2192)).replace('\x4', QChar(0x2193)); /* if (text[0] < 5) { // branch symbols opt.text = QChar(0x2190 + text[0].unicode() - 1); */ QColor foreColorOrBlack(Qt::black); if (staticText.length() > 0) { auto mdl = T::model(); assert(mdl); if (!mdl) return; QVariant foreColor = mdl->data(idx, Qt::Vmp::StaticColorRole); if (foreColor.canConvert()) { foreColorOrBlack = qvariant_cast(foreColor); } if (foreColorOrBlack != QColor(Qt::black)) { selected_text_as_html->append(QString("%1 %5").arg(text.toHtmlEscaped()).arg( foreColorOrBlack.red()).arg(foreColorOrBlack.green()).arg(foreColorOrBlack.blue()).arg( staticText.toHtmlEscaped())); } else { selected_text_as_html->append(QString("%1 %2").arg(text.toHtmlEscaped()).arg(staticText.toHtmlEscaped())); } text += QString(" %1").arg(staticText); } else { selected_text_as_html->append(text.toHtmlEscaped()); } selected_text->append(text); } template void TTemplateView::copy() { QModelIndexList indexes = T::selectionModel()->selectedIndexes(); if (indexes.size() < 1) return; std::sort(indexes.begin(), indexes.end()); QString selected_text_as_html; QString selected_text; selected_text_as_html.prepend(""); QModelIndex previous; for (int i = 0; i < indexes.size(); i++) { QModelIndex current = indexes[i]; if (current.row() != previous.row()) { if (previous.isValid()) { selected_text_as_html.append(""); selected_text.append(QLatin1Char('\n')); } selected_text_as_html.append(""); } else { selected_text.append(QLatin1Char('\t')); } selected_text_as_html.append(""); previous = current; } if (previous.isValid()) selected_text_as_html.append(""); selected_text_as_html.append("
"); getIndexTexts(current, &selected_text_as_html, &selected_text); selected_text_as_html.append("
"); QMimeData * md = new QMimeData; md->setHtml(selected_text_as_html); md->setText(selected_text); QApplication::clipboard()->setMimeData(md); } typedef TTemplateView TreeView; typedef TTemplateView TableView; class LogTreeView : public TreeView { public: LogTreeView(QWidget *parent = NULL) : TreeView(parent) {} private: /*virtual*/ QStyleOptionViewItem viewOptions() const; }; class PushButton : public QPushButton { public: PushButton(QWidget *parent = NULL) : QPushButton(parent) { #ifdef __APPLE__ setAttribute(Qt::WA_LayoutUsesWidgetRect, true); #endif } PushButton(const QString &text, QWidget *parent = NULL) : QPushButton(text, parent) { #ifdef __APPLE__ setAttribute(Qt::WA_LayoutUsesWidgetRect, true); #endif } }; class FindWidget : public QFrame { Q_OBJECT public: FindWidget(QWidget *parent = 0); ~FindWidget(); void show(); void showAndClear(const QString &term); QString text() const; bool caseSensitive() const; void setPalette(bool found); void setTextWrappedVisible(bool visible); signals: void findNext(); void findPrevious(); void escapePressed(); void find(const QString &text, bool forward, bool incremental); private slots: void updateButtons(); void textChanged(const QString &text); private: bool eventFilter(QObject *object, QEvent *e); private: QLineEdit *editFind; QCheckBox *checkCase; QLabel *labelWrapped; QToolButton *toolNext; QToolButton *toolClose; QToolButton *toolPrevious; }; class ElidedAction : public QAction { private: QString fullText_; public: ElidedAction(const QString &text, QObject *parent) : QAction(text, parent) {} ElidedAction(QObject *parent) : QAction(parent) {} void setFullText(const QString &text); const QString &getFullText() { return fullText_; } }; class ToolButtonElided : public QToolButton { private: QString fullText_; public: explicit ToolButtonElided(QWidget *parent = NULL) : QToolButton(parent) {} void resizeEvent(QResizeEvent *event); void setText(const QString &text); void elideText(const QSize &widgetSize); }; class Label : public QLabel { Q_OBJECT public: Label(QWidget * parent = 0); signals: void doubleClicked(); protected: void mouseDoubleClickEvent(QMouseEvent *event); }; class DisasmView : public TableView { Q_OBJECT public: DisasmView(QWidget * parent = 0); protected: void scrollContentsBy(int dx, int dy) override; }; #endif