Theme Editor: Added an edit menu with a find/replace function (copied from an LGPL...
authorbieber <bieber@a1c6a512-1295-4272-9138-f99709370657>
Sat, 26 Jun 2010 07:59:23 +0000 (26 07:59 +0000)
committerbieber <bieber@a1c6a512-1295-4272-9138-f99709370657>
Sat, 26 Jun 2010 07:59:23 +0000 (26 07:59 +0000)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27137 a1c6a512-1295-4272-9138-f99709370657

12 files changed:
utils/themeeditor/findreplace/findreplacedialog.cpp [new file with mode: 0644]
utils/themeeditor/findreplace/findreplacedialog.h [new file with mode: 0644]
utils/themeeditor/findreplace/findreplacedialog.ui [new file with mode: 0644]
utils/themeeditor/findreplace/findreplaceform.cpp [new file with mode: 0644]
utils/themeeditor/findreplace/findreplaceform.h [new file with mode: 0644]
utils/themeeditor/findreplace/findreplaceform.ui [new file with mode: 0644]
utils/themeeditor/gui/editorwindow.cpp
utils/themeeditor/gui/editorwindow.h
utils/themeeditor/gui/editorwindow.ui
utils/themeeditor/gui/skindocument.cpp
utils/themeeditor/gui/skindocument.h
utils/themeeditor/themeeditor.pro

diff --git a/utils/themeeditor/findreplace/findreplacedialog.cpp b/utils/themeeditor/findreplace/findreplacedialog.cpp
new file mode 100644 (file)
index 0000000..547ad23
--- /dev/null
@@ -0,0 +1,64 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * This file has been copied from Lorenzo Bettini, with minor modifications
+ * made available under the LGPL version 3, as the original file was licensed
+ *
+ ****************************************************************************
+ *
+ * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>
+ * See COPYING file that comes with this distribution
+ */
+
+#include "findreplacedialog.h"
+#include "ui_findreplacedialog.h"
+
+FindReplaceDialog::FindReplaceDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::FindReplaceDialog)
+{
+    ui->setupUi(this);
+}
+
+FindReplaceDialog::~FindReplaceDialog()
+{
+    delete ui;
+}
+
+void FindReplaceDialog::changeEvent(QEvent *e)
+{
+    QDialog::changeEvent(e);
+    switch (e->type()) {
+    case QEvent::LanguageChange:
+        ui->retranslateUi(this);
+        break;
+    default:
+        break;
+    }
+}
+
+void FindReplaceDialog::setTextEdit(QPlainTextEdit *textEdit) {
+    ui->findReplaceForm->setTextEdit(textEdit);
+}
+
+void FindReplaceDialog::writeSettings(QSettings &settings, const QString &prefix) {
+    ui->findReplaceForm->writeSettings(settings, prefix);
+}
+
+void FindReplaceDialog::readSettings(QSettings &settings, const QString &prefix) {
+    ui->findReplaceForm->readSettings(settings, prefix);
+}
+
+void FindReplaceDialog::findNext() {
+    ui->findReplaceForm->findNext();
+}
+
+void FindReplaceDialog::findPrev() {
+    ui->findReplaceForm->findPrev();
+}
diff --git a/utils/themeeditor/findreplace/findreplacedialog.h b/utils/themeeditor/findreplace/findreplacedialog.h
new file mode 100644 (file)
index 0000000..c3f2539
--- /dev/null
@@ -0,0 +1,80 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * This file has been copied from Lorenzo Bettini, with minor modifications
+ * made available under the LGPL version 3, as the original file was licensed
+ *
+ ****************************************************************************
+ *
+ * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>
+ * See COPYING file that comes with this distribution
+ */
+
+#ifndef FINDREPLACEDIALOG_H
+#define FINDREPLACEDIALOG_H
+
+#include <QDialog>
+#include <QPlainTextEdit>
+
+namespace Ui {
+    class FindReplaceDialog;
+}
+
+class QTextEdit;
+class QSettings;
+
+/**
+  * A find/replace dialog.
+  *
+  * It relies on a FindReplaceForm object (see that class for the functionalities provided).
+  */
+class FindReplaceDialog : public QDialog {
+    Q_OBJECT
+public:
+    FindReplaceDialog(QWidget *parent = 0);
+    virtual ~FindReplaceDialog();
+
+    /**
+      * Associates the text editor where to perform the search
+      * @param textEdit
+      */
+    void setTextEdit(QPlainTextEdit *textEdit);
+
+    /**
+      * Writes the state of the form to the passed settings.
+      * @param settings
+      * @param prefix the prefix to insert in the settings
+      */
+    virtual void writeSettings(QSettings &settings, const QString &prefix = "FindReplaceDialog");
+
+    /**
+      * Reads the state of the form from the passed settings.
+      * @param settings
+      * @param prefix the prefix to look for in the settings
+      */
+    virtual void readSettings(QSettings &settings, const QString &prefix = "FindReplaceDialog");
+
+public slots:
+    /**
+     * Finds the next occurrence
+     */
+    void findNext();
+
+    /**
+     * Finds the previous occurrence
+     */
+    void findPrev();
+
+protected:
+    void changeEvent(QEvent *e);
+
+    Ui::FindReplaceDialog *ui;
+};
+
+#endif // FINDREPLACEDIALOG_H
diff --git a/utils/themeeditor/findreplace/findreplacedialog.ui b/utils/themeeditor/findreplace/findreplacedialog.ui
new file mode 100644 (file)
index 0000000..74984b3
--- /dev/null
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ui version="4.0">\r
+ <class>FindReplaceDialog</class>\r
+ <widget class="QDialog" name="FindReplaceDialog">\r
+  <property name="geometry">\r
+   <rect>\r
+    <x>0</x>\r
+    <y>0</y>\r
+    <width>342</width>\r
+    <height>140</height>\r
+   </rect>\r
+  </property>\r
+  <property name="windowTitle">\r
+   <string>Find/Replace</string>\r
+  </property>\r
+  <layout class="QGridLayout" name="gridLayout">\r
+   <item row="0" column="0">\r
+    <widget class="FindReplaceForm" name="findReplaceForm" native="true"/>\r
+   </item>\r
+  </layout>\r
+ </widget>\r
+ <customwidgets>\r
+  <customwidget>\r
+   <class>FindReplaceForm</class>\r
+   <extends>QWidget</extends>\r
+   <header location="global">findreplaceform.h</header>\r
+   <container>1</container>\r
+  </customwidget>\r
+ </customwidgets>\r
+ <resources/>\r
+ <connections/>\r
+</ui>\r
diff --git a/utils/themeeditor/findreplace/findreplaceform.cpp b/utils/themeeditor/findreplace/findreplaceform.cpp
new file mode 100644 (file)
index 0000000..cd2700f
--- /dev/null
@@ -0,0 +1,222 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * This file has been copied from Lorenzo Bettini, with minor modifications
+ * made available under the LGPL version 3, as the original file was licensed
+ *
+ ****************************************************************************
+ *
+ * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>
+ * See COPYING file that comes with this distribution
+ */
+
+#include <QtGui>
+#include <QTextEdit>
+#include <QRegExp>
+#include <QSettings>
+
+#include "findreplaceform.h"
+#include "ui_findreplaceform.h"
+
+#define TEXT_TO_FIND "textToFind"
+#define TEXT_TO_REPLACE "textToReplace"
+#define DOWN_RADIO "downRadio"
+#define UP_RADIO "upRadio"
+#define CASE_CHECK "caseCheck"
+#define WHOLE_CHECK "wholeCheck"
+#define REGEXP_CHECK "regexpCheck"
+
+FindReplaceForm::FindReplaceForm(QWidget *parent) :
+    QWidget(parent),
+    ui(new Ui::FindReplaceForm), textEdit(0)
+{
+    ui->setupUi(this);
+
+    ui->errorLabel->setText("");
+
+    connect(ui->textToFind, SIGNAL(textChanged(QString)), this, SLOT(textToFindChanged()));
+    connect(ui->textToFind, SIGNAL(textChanged(QString)), this, SLOT(validateRegExp(QString)));
+
+    connect(ui->regexCheckBox, SIGNAL(toggled(bool)), this, SLOT(regexpSelected(bool)));
+
+    connect(ui->findButton, SIGNAL(clicked()), this, SLOT(find()));
+    connect(ui->closeButton, SIGNAL(clicked()), parent, SLOT(close()));
+
+    connect(ui->replaceButton, SIGNAL(clicked()), this, SLOT(replace()));
+    connect(ui->replaceAllButton, SIGNAL(clicked()), this, SLOT(replaceAll()));
+}
+
+FindReplaceForm::~FindReplaceForm()
+{
+    delete ui;
+}
+
+void FindReplaceForm::hideReplaceWidgets() {
+    ui->replaceLabel->setVisible(false);
+    ui->textToReplace->setVisible(false);
+    ui->replaceButton->setVisible(false);
+    ui->replaceAllButton->setVisible(false);
+}
+
+void FindReplaceForm::setTextEdit(QPlainTextEdit *textEdit_) {
+    textEdit = textEdit_;
+    connect(textEdit, SIGNAL(copyAvailable(bool)), ui->replaceButton, SLOT(setEnabled(bool)));
+    connect(textEdit, SIGNAL(copyAvailable(bool)), ui->replaceAllButton, SLOT(setEnabled(bool)));
+}
+
+void FindReplaceForm::changeEvent(QEvent *e)
+{
+    QWidget::changeEvent(e);
+    switch (e->type()) {
+    case QEvent::LanguageChange:
+        ui->retranslateUi(this);
+        break;
+    default:
+        break;
+    }
+}
+
+void FindReplaceForm::textToFindChanged() {
+    ui->findButton->setEnabled(ui->textToFind->text().size() > 0);
+}
+
+void FindReplaceForm::regexpSelected(bool sel) {
+    if (sel)
+        validateRegExp(ui->textToFind->text());
+    else
+        validateRegExp("");
+}
+
+void FindReplaceForm::validateRegExp(const QString &text) {
+    if (!ui->regexCheckBox->isChecked() || text.size() == 0) {
+        ui->errorLabel->setText("");
+        return; // nothing to validate
+    }
+
+    QRegExp reg(text,
+                (ui->caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive));
+
+    if (reg.isValid()) {
+        showError("");
+    } else {
+        showError(reg.errorString());
+    }
+}
+
+void FindReplaceForm::showError(const QString &error) {
+    if (error == "") {
+        ui->errorLabel->setText("");
+    } else {
+        ui->errorLabel->setText("<span style=\" font-weight:600; color:#ff0000;\">" +
+                                error +
+                                "</span>");
+    }
+}
+
+void FindReplaceForm::showMessage(const QString &message) {
+    if (message == "") {
+        ui->errorLabel->setText("");
+    } else {
+        ui->errorLabel->setText("<span style=\" font-weight:600; color:green;\">" +
+                                message +
+                                "</span>");
+    }
+}
+
+void FindReplaceForm::find() {
+    find(ui->downRadioButton->isChecked());
+}
+
+void FindReplaceForm::find(bool next) {
+    if (!textEdit)
+        return; // TODO: show some warning?
+
+    // backward search
+    bool back = !next;
+
+    const QString &toSearch = ui->textToFind->text();
+
+    bool result = false;
+
+    QTextDocument::FindFlags flags;
+
+    if (back)
+        flags |= QTextDocument::FindBackward;
+    if (ui->caseCheckBox->isChecked())
+        flags |= QTextDocument::FindCaseSensitively;
+    if (ui->wholeCheckBox->isChecked())
+        flags |= QTextDocument::FindWholeWords;
+
+    if (ui->regexCheckBox->isChecked()) {
+        QRegExp reg(toSearch,
+                    (ui->caseCheckBox->isChecked() ? Qt::CaseSensitive : Qt::CaseInsensitive));
+
+        qDebug() << "searching for regexp: " << reg.pattern();
+
+        textCursor = textEdit->document()->find(reg, textCursor, flags);
+        textEdit->setTextCursor(textCursor);
+        result = (!textCursor.isNull());
+    } else {
+        qDebug() << "searching for: " << toSearch;
+
+        result = textEdit->find(toSearch, flags);
+    }
+
+    if (result) {
+        showError("");
+    } else {
+        showError(tr("no match found"));
+        // move to the beginning of the document for the next find
+        textCursor.setPosition(0);
+        textEdit->setTextCursor(textCursor);
+    }
+}
+
+void FindReplaceForm::replace() {
+    if (!textEdit->textCursor().hasSelection()) {
+        find();
+    } else {
+        textEdit->textCursor().insertText(ui->textToReplace->text());
+        find();
+    }
+}
+
+void FindReplaceForm::replaceAll() {
+    int i=0;
+    while (textEdit->textCursor().hasSelection()){
+        textEdit->textCursor().insertText(ui->textToReplace->text());
+        find();
+        i++;
+    }
+    showMessage(tr("Replaced %1 occurrence(s)").arg(i));
+}
+
+void FindReplaceForm::writeSettings(QSettings &settings, const QString &prefix) {
+    settings.beginGroup(prefix);
+    settings.setValue(TEXT_TO_FIND, ui->textToFind->text());
+    settings.setValue(TEXT_TO_REPLACE, ui->textToReplace->text());
+    settings.setValue(DOWN_RADIO, ui->downRadioButton->isChecked());
+    settings.setValue(UP_RADIO, ui->upRadioButton->isChecked());
+    settings.setValue(CASE_CHECK, ui->caseCheckBox->isChecked());
+    settings.setValue(WHOLE_CHECK, ui->wholeCheckBox->isChecked());
+    settings.setValue(REGEXP_CHECK, ui->regexCheckBox->isChecked());
+    settings.endGroup();
+}
+
+void FindReplaceForm::readSettings(QSettings &settings, const QString &prefix) {
+    settings.beginGroup(prefix);
+    ui->textToFind->setText(settings.value(TEXT_TO_FIND, "").toString());
+    ui->textToReplace->setText(settings.value(TEXT_TO_REPLACE, "").toString());
+    ui->downRadioButton->setChecked(settings.value(DOWN_RADIO, true).toBool());
+    ui->upRadioButton->setChecked(settings.value(UP_RADIO, false).toBool());
+    ui->caseCheckBox->setChecked(settings.value(CASE_CHECK, false).toBool());
+    ui->wholeCheckBox->setChecked(settings.value(WHOLE_CHECK, false).toBool());
+    ui->regexCheckBox->setChecked(settings.value(REGEXP_CHECK, false).toBool());
+    settings.endGroup();
+}
diff --git a/utils/themeeditor/findreplace/findreplaceform.h b/utils/themeeditor/findreplace/findreplaceform.h
new file mode 100644 (file)
index 0000000..f18052b
--- /dev/null
@@ -0,0 +1,153 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id$
+ *
+ * This file has been copied from Lorenzo Bettini, with minor modifications
+ * made available under the LGPL version 3, as the original file was licensed
+ *
+ ****************************************************************************
+ *
+ * Copyright (C) 2009  Lorenzo Bettini <http://www.lorenzobettini.it>
+ * See COPYING file that comes with this distribution
+ */
+
+#ifndef FINDREPLACEFORM_H
+#define FINDREPLACEFORM_H
+
+#include <QWidget>
+#include <QTextCursor>
+#include <QPlainTextEdit>
+
+namespace Ui {
+    class FindReplaceForm;
+}
+
+class QTextEdit;
+class QSettings;
+
+/**
+  * The form for the find/replace dialog.  The form presents the typical
+  * widgets you find in standard find/replace dialogs, and it acts on a QTextEdit.
+  *
+  * \image html Screenshot-FindReplace.png
+  *
+  * You need to set the QTextEdit explicitly, using the method setTextEdit(QTextEdit *textEdit).
+  *
+  * For instance
+  * \code
+  * m_findReplaceDialog = new FindReplaceDialog(this);
+  * m_findReplaceDialog->setModal(false);
+  * m_findReplaceDialog->setTextEdit(ui->textEdit);
+  * \endcode
+  *
+  * The find functionalities is available even if the find dialog is not shown: if something
+  * to search for was already specified, the application can call the methods findNext() and
+  * findPrev() (e.g., by connecting them to menu items).
+  *
+  * In case a regular expression is used as the search term, the form also checks whether the
+  * expression is a valid regular expression (You may want to take a look at the syntax of regular expressions:
+  * http://doc.trolltech.com/qregexp.html).
+  *
+  * The form provides also functionalities to save and restore its state using a QSettings object (i.e.,
+  * the last word searched for, the options of the form, etc.) via the methods writeSettings()
+  * and readSettings().
+  *
+  * You can take a look at the \ref examples page.
+  */
+class FindReplaceForm : public QWidget {
+    Q_OBJECT
+public:
+    FindReplaceForm(QWidget *parent = 0);
+    virtual ~FindReplaceForm();
+
+    /**
+      * Associates the text editor where to perform the search
+      * @param textEdit_
+      */
+    void setTextEdit(QPlainTextEdit *textEdit_);
+
+    /// hides replace widgets from the form
+    void hideReplaceWidgets();
+
+    /**
+      * Writes the state of the form to the passed settings.
+      * @param settings
+      * @param prefix the prefix to insert in the settings
+      */
+    virtual void writeSettings(QSettings &settings, const QString &prefix = "FindReplaceDialog");
+
+    /**
+      * Reads the state of the form from the passed settings.
+      * @param settings
+      * @param prefix the prefix to look for in the settings
+      */
+    virtual void readSettings(QSettings &settings, const QString &prefix = "FindReplaceDialog");
+
+public slots:
+    /**
+     * performs the find task
+     * @param down whether to find the next or the previous
+     * occurrence
+     */
+    void find(bool down);
+
+    /**
+     * Finds the next occurrence
+     */
+    void find();
+
+    /**
+     * Finds the next occurrence
+     */
+    void findNext() { find(true); }
+
+    /**
+     * Finds the previous occurrence
+     */
+    void findPrev() { find(false); }
+
+    /**
+      * Replaces the found occurrences and goes to the next occurrence
+      */
+    void replace();
+
+    /**
+      * Replaces all the found occurrences
+      */
+    void replaceAll();
+
+protected:
+    void changeEvent(QEvent *e);
+
+    /// shows an error in the dialog
+    void showError(const QString &error);
+
+    /// shows a message in the dialog
+    void showMessage(const QString &message);
+
+protected slots:
+    /// when the text edit contents changed
+    void textToFindChanged();
+
+    /// checks whether the passed text is a valid regexp
+    void validateRegExp(const QString &text);
+
+    /// the regexp checkbox was selected
+    void regexpSelected(bool sel);
+
+protected:
+    Ui::FindReplaceForm *ui;
+
+    /// for searching into the text
+    QTextCursor textCursor;
+
+    /// the text editor (possibly) associated with this form
+    QPlainTextEdit *textEdit;
+};
+
+#endif // FINDREPLACEFORM_H
diff --git a/utils/themeeditor/findreplace/findreplaceform.ui b/utils/themeeditor/findreplace/findreplaceform.ui
new file mode 100644 (file)
index 0000000..acc055c
--- /dev/null
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ui version="4.0">\r
+ <class>FindReplaceForm</class>\r
+ <widget class="QWidget" name="FindReplaceForm">\r
+  <property name="geometry">\r
+   <rect>\r
+    <x>0</x>\r
+    <y>0</y>\r
+    <width>483</width>\r
+    <height>288</height>\r
+   </rect>\r
+  </property>\r
+  <property name="windowTitle">\r
+   <string>Form</string>\r
+  </property>\r
+  <layout class="QGridLayout" name="gridLayout">\r
+   <item row="0" column="0">\r
+    <layout class="QVBoxLayout" name="verticalLayout_5">\r
+     <item>\r
+      <layout class="QVBoxLayout" name="verticalLayout_2">\r
+       <item>\r
+        <layout class="QGridLayout" name="gridLayout_3">\r
+         <item row="0" column="0">\r
+          <widget class="QLabel" name="label">\r
+           <property name="text">\r
+            <string>&amp;Find:</string>\r
+           </property>\r
+           <property name="buddy">\r
+            <cstring>textToFind</cstring>\r
+           </property>\r
+          </widget>\r
+         </item>\r
+         <item row="0" column="1">\r
+          <widget class="QLineEdit" name="textToFind"/>\r
+         </item>\r
+         <item row="1" column="0">\r
+          <widget class="QLabel" name="replaceLabel">\r
+           <property name="text">\r
+            <string>R&amp;eplace with:</string>\r
+           </property>\r
+           <property name="buddy">\r
+            <cstring>textToReplace</cstring>\r
+           </property>\r
+          </widget>\r
+         </item>\r
+         <item row="1" column="1">\r
+          <widget class="QLineEdit" name="textToReplace"/>\r
+         </item>\r
+        </layout>\r
+       </item>\r
+      </layout>\r
+     </item>\r
+     <item>\r
+      <widget class="QLabel" name="errorLabel">\r
+       <property name="text">\r
+        <string>errorLabel</string>\r
+       </property>\r
+      </widget>\r
+     </item>\r
+     <item>\r
+      <layout class="QHBoxLayout" name="horizontalLayout">\r
+       <item>\r
+        <widget class="QGroupBox" name="groupBox">\r
+         <property name="title">\r
+          <string>D&amp;irection</string>\r
+         </property>\r
+         <layout class="QVBoxLayout" name="verticalLayout_3">\r
+          <item>\r
+           <widget class="QRadioButton" name="downRadioButton">\r
+            <property name="text">\r
+             <string>&amp;Down</string>\r
+            </property>\r
+            <property name="checked">\r
+             <bool>true</bool>\r
+            </property>\r
+           </widget>\r
+          </item>\r
+          <item>\r
+           <widget class="QRadioButton" name="upRadioButton">\r
+            <property name="text">\r
+             <string>&amp;Up</string>\r
+            </property>\r
+           </widget>\r
+          </item>\r
+         </layout>\r
+        </widget>\r
+       </item>\r
+       <item>\r
+        <widget class="QGroupBox" name="groupBox_2">\r
+         <property name="title">\r
+          <string>&amp;Options</string>\r
+         </property>\r
+         <layout class="QVBoxLayout" name="verticalLayout_4">\r
+          <item>\r
+           <widget class="QCheckBox" name="caseCheckBox">\r
+            <property name="text">\r
+             <string>&amp;Case sensitive</string>\r
+            </property>\r
+           </widget>\r
+          </item>\r
+          <item>\r
+           <widget class="QCheckBox" name="wholeCheckBox">\r
+            <property name="text">\r
+             <string>&amp;Whole words only</string>\r
+            </property>\r
+           </widget>\r
+          </item>\r
+          <item>\r
+           <widget class="QCheckBox" name="regexCheckBox">\r
+            <property name="toolTip">\r
+             <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;\r
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;\r
+p, li { white-space: pre-wrap; }\r
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;\r
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;whether the text to search should be interpreted as a regular expression.&lt;/p&gt;\r
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;/p&gt;\r
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;You may want to take a look at the syntax of regular expressions:&lt;/p&gt;\r
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://doc.trolltech.com/qregexp.html&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;http://doc.trolltech.com/qregexp.html&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>\r
+            </property>\r
+            <property name="text">\r
+             <string>R&amp;egular Expression</string>\r
+            </property>\r
+           </widget>\r
+          </item>\r
+         </layout>\r
+        </widget>\r
+       </item>\r
+      </layout>\r
+     </item>\r
+    </layout>\r
+   </item>\r
+   <item row="0" column="1">\r
+    <layout class="QVBoxLayout" name="verticalLayout">\r
+     <property name="leftMargin">\r
+      <number>10</number>\r
+     </property>\r
+     <item>\r
+      <widget class="QPushButton" name="findButton">\r
+       <property name="enabled">\r
+        <bool>false</bool>\r
+       </property>\r
+       <property name="text">\r
+        <string>&amp;Find</string>\r
+       </property>\r
+      </widget>\r
+     </item>\r
+     <item>\r
+      <widget class="QPushButton" name="closeButton">\r
+       <property name="text">\r
+        <string>&amp;Close</string>\r
+       </property>\r
+      </widget>\r
+     </item>\r
+     <item>\r
+      <widget class="QPushButton" name="replaceButton">\r
+       <property name="enabled">\r
+        <bool>false</bool>\r
+       </property>\r
+       <property name="text">\r
+        <string>&amp;Replace</string>\r
+       </property>\r
+      </widget>\r
+     </item>\r
+     <item>\r
+      <widget class="QPushButton" name="replaceAllButton">\r
+       <property name="enabled">\r
+        <bool>false</bool>\r
+       </property>\r
+       <property name="text">\r
+        <string>Replace &amp;All</string>\r
+       </property>\r
+      </widget>\r
+     </item>\r
+     <item>\r
+      <spacer name="verticalSpacer">\r
+       <property name="orientation">\r
+        <enum>Qt::Vertical</enum>\r
+       </property>\r
+       <property name="sizeHint" stdset="0">\r
+        <size>\r
+         <width>20</width>\r
+         <height>40</height>\r
+        </size>\r
+       </property>\r
+      </spacer>\r
+     </item>\r
+    </layout>\r
+   </item>\r
+  </layout>\r
+ </widget>\r
+ <tabstops>\r
+  <tabstop>textToFind</tabstop>\r
+  <tabstop>textToReplace</tabstop>\r
+  <tabstop>downRadioButton</tabstop>\r
+  <tabstop>upRadioButton</tabstop>\r
+  <tabstop>caseCheckBox</tabstop>\r
+  <tabstop>wholeCheckBox</tabstop>\r
+  <tabstop>regexCheckBox</tabstop>\r
+  <tabstop>findButton</tabstop>\r
+  <tabstop>closeButton</tabstop>\r
+ </tabstops>\r
+ <resources/>\r
+ <connections/>\r
+</ui>\r
index b778a1f..ea6c91f 100644 (file)
@@ -200,6 +200,20 @@ void EditorWindow::setupMenus()
 
     QObject::connect(ui->actionOpen_Project, SIGNAL(triggered()),
                      this, SLOT(openProject()));
+
+    /* Connecting the edit menu */
+    QObject::connect(ui->actionUndo, SIGNAL(triggered()),
+                     this, SLOT(undo()));
+    QObject::connect(ui->actionRedo, SIGNAL(triggered()),
+                     this, SLOT(redo()));
+    QObject::connect(ui->actionCut, SIGNAL(triggered()),
+                     this, SLOT(cut()));
+    QObject::connect(ui->actionCopy, SIGNAL(triggered()),
+                     this, SLOT(copy()));
+    QObject::connect(ui->actionPaste, SIGNAL(triggered()),
+                     this, SLOT(paste()));
+    QObject::connect(ui->actionFind_Replace, SIGNAL(triggered()),
+                     this, SLOT(findReplace()));
 }
 
 void EditorWindow::addTab(TabContent *doc)
@@ -237,6 +251,12 @@ void EditorWindow::shiftTab(int index)
         ui->actionClose_Document->setEnabled(false);
         ui->actionToolbarSave->setEnabled(false);
         ui->fromTree->setEnabled(false);
+        ui->actionUndo->setEnabled(false);
+        ui->actionRedo->setEnabled(false);
+        ui->actionCut->setEnabled(false);
+        ui->actionCopy->setEnabled(false);
+        ui->actionPaste->setEnabled(false);
+        ui->actionFind_Replace->setEnabled(false);
         viewer->setScene(0);
     }
     else if(widget->type() == TabContent::Config)
@@ -245,6 +265,12 @@ void EditorWindow::shiftTab(int index)
         ui->actionSave_Document_As->setEnabled(true);
         ui->actionClose_Document->setEnabled(true);
         ui->actionToolbarSave->setEnabled(true);
+        ui->actionUndo->setEnabled(false);
+        ui->actionRedo->setEnabled(false);
+        ui->actionCut->setEnabled(false);
+        ui->actionCopy->setEnabled(false);
+        ui->actionPaste->setEnabled(false);
+        ui->actionFind_Replace->setEnabled(false);
         viewer->setScene(0);
     }
     else if(widget->type() == TabContent::Skin)
@@ -260,12 +286,26 @@ void EditorWindow::shiftTab(int index)
         ui->actionToolbarSave->setEnabled(true);
         ui->fromTree->setEnabled(true);
 
+        ui->actionUndo->setEnabled(true);
+        ui->actionRedo->setEnabled(true);
+        ui->actionCut->setEnabled(true);
+        ui->actionCopy->setEnabled(true);
+        ui->actionPaste->setEnabled(true);
+        ui->actionFind_Replace->setEnabled(true);
+
         sizeColumns();
 
         /* Syncing the preview */
         viewer->setScene(doc->scene());
 
     }
+
+    /* Hiding all the find/replace dialogs */
+    for(int i = 0; i < ui->editorTabs->count(); i++)
+        if(dynamic_cast<TabContent*>(ui->editorTabs->widget(i))->type() ==
+           TabContent::Skin)
+            dynamic_cast<SkinDocument*>(ui->editorTabs->widget(i))->hideFind();
+
 }
 
 bool EditorWindow::closeTab(int index)
@@ -469,6 +509,56 @@ void EditorWindow::lineChanged(int line)
 
 }
 
+void EditorWindow::undo()
+{
+    TabContent* doc = dynamic_cast<TabContent*>
+                      (ui->editorTabs->currentWidget());
+    if(doc->type() == TabContent::Skin)
+        dynamic_cast<SkinDocument*>(doc)->getEditor()->undo();
+}
+
+void EditorWindow::redo()
+{
+    TabContent* doc = dynamic_cast<TabContent*>
+                      (ui->editorTabs->currentWidget());
+    if(doc->type() == TabContent::Skin)
+        dynamic_cast<SkinDocument*>(doc)->getEditor()->redo();
+
+}
+
+void EditorWindow::cut()
+{
+    TabContent* doc = dynamic_cast<TabContent*>
+                      (ui->editorTabs->currentWidget());
+    if(doc->type() == TabContent::Skin)
+        dynamic_cast<SkinDocument*>(doc)->getEditor()->cut();
+}
+
+void EditorWindow::copy()
+{
+    TabContent* doc = dynamic_cast<TabContent*>
+                      (ui->editorTabs->currentWidget());
+    if(doc->type() == TabContent::Skin)
+        dynamic_cast<SkinDocument*>(doc)->getEditor()->copy();
+}
+
+void EditorWindow::paste()
+{
+    TabContent* doc = dynamic_cast<TabContent*>
+                      (ui->editorTabs->currentWidget());
+    if(doc->type() == TabContent::Skin)
+        dynamic_cast<SkinDocument*>(doc)->getEditor()->paste();
+}
+
+void EditorWindow::findReplace()
+{
+    TabContent* doc = dynamic_cast<TabContent*>
+                      (ui->editorTabs->currentWidget());
+    if(doc->type() == TabContent::Skin)
+        dynamic_cast<SkinDocument*>(doc)->showFind();
+}
+
+
 void EditorWindow::expandLine(ParseTreeModel* model, QModelIndex parent,
                               int line)
 {
index ab75cc5..6f30249 100644 (file)
@@ -73,6 +73,12 @@ private slots:
     void tabTitleChanged(QString title);
     void updateCurrent(); /* Generates code in the current tab */
     void lineChanged(int line); /* Used for auto-expand */
+    void undo();
+    void redo();
+    void cut();
+    void copy();
+    void paste();
+    void findReplace();
 
 private:
     /* Setup functions */
index 2f84d38..707e246 100644 (file)
     <addaction name="separator"/>
     <addaction name="actionDevice_Configuration"/>
    </widget>
+   <widget class="QMenu" name="menuEdit">
+    <property name="title">
+     <string>&amp;Edit</string>
+    </property>
+    <addaction name="actionUndo"/>
+    <addaction name="actionRedo"/>
+    <addaction name="separator"/>
+    <addaction name="actionCut"/>
+    <addaction name="actionCopy"/>
+    <addaction name="actionPaste"/>
+    <addaction name="separator"/>
+    <addaction name="actionFind_Replace"/>
+   </widget>
    <addaction name="menuFile"/>
+   <addaction name="menuEdit"/>
    <addaction name="menuView"/>
   </widget>
   <widget class="QStatusBar" name="statusbar"/>
     <string>Ctrl+D</string>
    </property>
   </action>
+  <action name="actionUndo">
+   <property name="text">
+    <string>&amp;Undo</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+Z</string>
+   </property>
+  </action>
+  <action name="actionRedo">
+   <property name="text">
+    <string>&amp;Redo</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+Shift+Z</string>
+   </property>
+  </action>
+  <action name="actionCut">
+   <property name="text">
+    <string>C&amp;ut</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+X</string>
+   </property>
+  </action>
+  <action name="actionCopy">
+   <property name="text">
+    <string>&amp;Copy</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+C</string>
+   </property>
+  </action>
+  <action name="actionPaste">
+   <property name="text">
+    <string>&amp;Paste</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+V</string>
+   </property>
+  </action>
+  <action name="actionFind_Replace">
+   <property name="text">
+    <string>&amp;Find/Replace</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+F</string>
+   </property>
+  </action>
  </widget>
  <tabstops>
   <tabstop>projectTree</tabstop>
index 6863ff5..f8206e1 100644 (file)
@@ -151,6 +151,12 @@ void SkinDocument::setupUI()
     QObject::connect(device, SIGNAL(settingsChanged()),
                      this, SLOT(deviceChanged()));
 
+    /* Attaching the find/replace dialog */
+    findReplace = new FindReplaceDialog(this);
+    findReplace->setModal(false);
+    findReplace->setTextEdit(editor);
+    findReplace->hide();
+
     settingsChanged();
 }
 
index c6b3687..1713023 100644 (file)
@@ -27,6 +27,8 @@
 #include <QHBoxLayout>
 #include <QGraphicsScene>
 
+#include "findreplacedialog.h"
+
 #include "skinhighlighter.h"
 #include "parsetreemodel.h"
 #include "preferencesdialog.h"
@@ -61,6 +63,7 @@ public:
     QString file() const{ return fileName; }
     QString title() const{ return titleText; }
     QString getStatus(){ return parseStatus; }
+    CodeEditor* getEditor(){ return editor; }
     void genCode(){ editor->document()->setPlainText(model->genCode()); }
     void setProject(ProjectModel* project){ this->project = project; }
 
@@ -73,6 +76,9 @@ public:
 
     QGraphicsScene* scene(){ return model->render(project, device, &fileName); }
 
+    void showFind(){ findReplace->show(); }
+    void hideFind(){ findReplace->hide(); }
+
 signals:
 
 public slots:
@@ -104,6 +110,8 @@ private:
 
     ProjectModel* project;
     DeviceState* device;
+
+    FindReplaceDialog* findReplace;
 };
 
 #endif // SKINDOCUMENT_H
index 50cafe0..329500e 100644 (file)
@@ -11,6 +11,7 @@ RBBASE_DIR = $$replace(RBBASE_DIR,/utils/themeeditor,)
 INCLUDEPATH += gui
 INCLUDEPATH += models
 INCLUDEPATH += graphics
+INCLUDEPATH += findreplace
 
 # Stuff for the parse lib
 libskin_parser.commands = @$(MAKE) \
@@ -40,7 +41,9 @@ HEADERS += models/parsetreemodel.h \
     graphics/rbrenderinfo.h \
     graphics/rbimage.h \
     graphics/rbfont.h \
-    gui/devicestate.h
+    gui/devicestate.h \
+    findreplace/findreplaceform.h \
+    findreplace/findreplacedialog.h
 SOURCES += main.cpp \
     models/parsetreemodel.cpp \
     models/parsetreenode.cpp \
@@ -57,7 +60,9 @@ SOURCES += main.cpp \
     graphics/rbrenderinfo.cpp \
     graphics/rbimage.cpp \
     graphics/rbfont.cpp \
-    gui/devicestate.cpp
+    gui/devicestate.cpp \
+    findreplace/findreplaceform.cpp \
+    findreplace/findreplacedialog.cpp
 OTHER_FILES += README \
     resources/windowicon.png \
     resources/appicon.xcf \
@@ -69,5 +74,7 @@ OTHER_FILES += README \
 FORMS += gui/editorwindow.ui \
     gui/preferencesdialog.ui \
     gui/configdocument.ui \
-    gui/skinviewer.ui
+    gui/skinviewer.ui \
+    findreplace/findreplaceform.ui \
+    findreplace/findreplacedialog.ui
 RESOURCES += resources.qrc