$search
00001 /* 00002 Aseba - an event-based framework for distributed robot control 00003 Copyright (C) 2007--2012: 00004 Stephane Magnenat <stephane at magnenat dot net> 00005 (http://stephane.magnenat.net) 00006 and other contributors, see authors.txt for details 00007 00008 This program is free software: you can redistribute it and/or modify 00009 it under the terms of the GNU Lesser General Public License as published 00010 by the Free Software Foundation, version 3 of the License. 00011 00012 This program is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU Lesser General Public License for more details. 00016 00017 You should have received a copy of the GNU Lesser General Public License 00018 along with this program. If not, see <http://www.gnu.org/licenses/>. 00019 */ 00020 00021 #include "FindDialog.h" 00022 00023 #include <cassert> 00024 00025 #include <QLabel> 00026 #include <QLineEdit> 00027 #include <QPushButton> 00028 #include <QCheckBox> 00029 #include <QTextEdit> 00030 #include <QTextDocument> 00031 #include <QGridLayout> 00032 #include <QButtonGroup> 00033 #include <QGroupBox> 00034 00035 #include <FindDialog.moc> 00036 00037 namespace Aseba 00038 { 00039 FindDialog::FindDialog(QWidget *parent, QTextEdit* editor): 00040 QDialog(parent), 00041 editor(editor) 00042 { 00043 setWindowTitle(tr("Aseba Studio - Search and Replace")); 00044 00045 QLabel* label = new QLabel(tr("&Search for:")); 00046 findLineEdit = new QLineEdit; 00047 label->setBuddy(findLineEdit); 00048 QHBoxLayout *entryLayout = new QHBoxLayout; 00049 entryLayout->addWidget(label); 00050 entryLayout->addWidget(findLineEdit); 00051 00052 caseCheckBox = new QCheckBox(tr("&Case sensitive")); 00053 wholeWordsCheckBox = new QCheckBox(tr("&Whole words")); 00054 regularExpressionsCheckBox = new QCheckBox(tr("Re&gular expressions")); 00055 QHBoxLayout *optionsLayout = new QHBoxLayout; 00056 optionsLayout->addWidget(caseCheckBox); 00057 optionsLayout->addWidget(wholeWordsCheckBox); 00058 optionsLayout->addWidget(regularExpressionsCheckBox); 00059 00060 findNextButton = new QPushButton(tr("&Find Next")); 00061 findNextButton->setDefault(true); 00062 findPreviousButton = new QPushButton(tr("Find &Previous")); 00063 findFromTopButton = new QPushButton(tr("Find from &Top")); 00064 QHBoxLayout *buttonsLayout = new QHBoxLayout; 00065 buttonsLayout->addWidget(findNextButton); 00066 buttonsLayout->addWidget(findPreviousButton); 00067 buttonsLayout->addWidget(findFromTopButton); 00068 00069 warningText = new QLabel; 00070 warningText->setStyleSheet("color: darkred; font-weight: bold"); 00071 00072 replaceGroupBox = new QGroupBox(tr("&Replace")); 00073 replaceGroupBox->setCheckable(true); 00074 replaceGroupBox->setChecked(false); 00075 label = new QLabel(tr("w&ith:")); 00076 QHBoxLayout *entryLayout2 = new QHBoxLayout; 00077 replaceLineEdit = new QLineEdit; 00078 label->setBuddy(replaceLineEdit); 00079 entryLayout2->addWidget(label); 00080 entryLayout2->addWidget(replaceLineEdit); 00081 replaceFindNextButton = new QPushButton(tr("Replace and\nFind &Next")); 00082 replaceFindPreviousButton = new QPushButton(tr("Replace and\nFind Previo&us")); 00083 replaceAllButton = new QPushButton(tr("Replace &All\nOccurrences")); 00084 QHBoxLayout *buttonsLayout2 = new QHBoxLayout; 00085 buttonsLayout2->addWidget(replaceFindNextButton); 00086 buttonsLayout2->addWidget(replaceFindPreviousButton); 00087 buttonsLayout2->addWidget(replaceAllButton); 00088 QVBoxLayout *replaceLayout = new QVBoxLayout; 00089 replaceLayout->addLayout(entryLayout2); 00090 replaceLayout->addLayout(buttonsLayout2); 00091 replaceGroupBox->setLayout(replaceLayout); 00092 00093 QVBoxLayout* layout = new QVBoxLayout; 00094 layout->addLayout(entryLayout); 00095 layout->addLayout(optionsLayout); 00096 layout->addLayout(buttonsLayout); 00097 layout->addWidget(warningText); 00098 layout->addWidget(replaceGroupBox); 00099 00100 setLayout(layout); 00101 00102 connect(findNextButton, SIGNAL(clicked()), SLOT(findNext())); 00103 connect(findPreviousButton, SIGNAL(clicked()), SLOT(findPrevious())); 00104 connect(findFromTopButton, SIGNAL(clicked()), SLOT(findFromTop())); 00105 connect(replaceFindNextButton, SIGNAL(clicked()), SLOT(replaceFindNext())); 00106 connect(replaceFindPreviousButton, SIGNAL(clicked()), SLOT(replaceFindPrevious())); 00107 connect(replaceAllButton, SIGNAL(clicked()), SLOT(replaceAll())); 00108 } 00109 00110 void FindDialog::setFindText(const QString& text) 00111 { 00112 findLineEdit->setText(text); 00113 } 00114 00115 void FindDialog::findNext() 00116 { 00117 find(editor->textCursor(), QTextDocument::FindFlag(0)); 00118 } 00119 00120 void FindDialog::findPrevious() 00121 { 00122 find(editor->textCursor(), QTextDocument::FindBackward); 00123 } 00124 00125 void FindDialog::findFromTop() 00126 { 00127 find(QTextCursor(editor->document()), QTextDocument::FindFlag(0)); 00128 } 00129 00130 void FindDialog::replaceFindNext() 00131 { 00132 replace(); 00133 find(editor->textCursor(), QTextDocument::FindFlag(0)); 00134 } 00135 00136 void FindDialog::replaceFindPrevious() 00137 { 00138 replace(); 00139 find(editor->textCursor(), QTextDocument::FindBackward); 00140 } 00141 00142 void FindDialog::replaceAll() 00143 { 00144 QTextCursor c(editor->document()); 00145 while (find(c, QTextDocument::FindFlag(0))) 00146 { 00147 replace(); 00148 c = editor->textCursor(); 00149 } 00150 } 00151 00152 bool FindDialog::find(const QTextCursor cc, const QTextDocument::FindFlag dir) 00153 { 00154 assert(editor); 00155 00156 //if (cc.hasSelection()) 00157 00158 QTextDocument::FindFlags flags(dir); 00159 QTextCursor nc; 00160 00161 // search text 00162 if (wholeWordsCheckBox->isChecked()) 00163 flags |= QTextDocument::FindWholeWords; 00164 if (regularExpressionsCheckBox->isChecked()) 00165 { 00166 Qt::CaseSensitivity cs; 00167 if (caseCheckBox->isChecked()) 00168 cs = Qt::CaseSensitive; 00169 else 00170 cs = Qt::CaseInsensitive; 00171 nc = editor->document()->find(QRegExp(findLineEdit->text(), cs), cc ,flags); 00172 } 00173 else 00174 { 00175 if (caseCheckBox->isChecked()) 00176 flags |= QTextDocument::FindCaseSensitively; 00177 nc = editor->document()->find(findLineEdit->text(), cc ,flags); 00178 } 00179 00180 // do something with found text 00181 if (nc.isNull()) 00182 { 00183 nc = QTextCursor(editor->document()); 00184 if (dir == QTextDocument::FindBackward) 00185 nc.movePosition(QTextCursor::End); 00186 warningText->setText(tr("End of document reached!")); 00187 editor->setTextCursor(nc); 00188 return false; 00189 } 00190 else 00191 { 00192 warningText->setText(""); 00193 editor->setTextCursor(nc); 00194 return true; 00195 } 00196 } 00197 00198 void FindDialog::replace() 00199 { 00200 QTextCursor cc(editor->textCursor()); 00201 if (cc.isNull() || !cc.hasSelection()) 00202 return; 00203 if (replaceGroupBox->isChecked()) 00204 { 00205 const int p = std::min(cc.anchor(), cc.position()); 00206 const int l = replaceLineEdit->text().length(); 00207 cc.insertText(replaceLineEdit->text()); 00208 cc.setPosition(p); 00209 cc.setPosition(p+l, QTextCursor::KeepAnchor); 00210 editor->setTextCursor(cc); 00211 } 00212 } 00213 }