00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "grepdlg.h"
00013
00014 #include <qlayout.h>
00015 #include <qpushbutton.h>
00016 #include <qregexp.h>
00017 #include <qhbox.h>
00018 #include <qwhatsthis.h>
00019 #include <qtooltip.h>
00020 #include <qstringlist.h>
00021 #include <kfiledialog.h>
00022 #include <kbuttonbox.h>
00023 #include <kpushbutton.h>
00024 #include <kapplication.h>
00025 #include <kiconloader.h>
00026 #include <klocale.h>
00027 #include <kconfig.h>
00028 #include <kmessagebox.h>
00029 #include <kdebug.h>
00030 #include <kdeversion.h>
00031 #include <qlabel.h>
00032 #include <kcombobox.h>
00033 #include <kurlcompletion.h>
00034 #include <kurlrequester.h>
00035 #include <kstdguiitem.h>
00036 #include <kparts/part.h>
00037 #include <kdevpartcontroller.h>
00038
00039 #include "grepviewpart.h"
00040
00041
00042 const char *template_desc[] = {
00043 "verbatim",
00044 "assignment",
00045 "->MEMBER(",
00046 "class::MEMBER(",
00047 "OBJECT->member(",
00048 "[OBJECT method",
00049 0
00050 };
00051
00052 const char *template_str[] = {
00053 "%s",
00054 "\\<%s\\>[\\t ]*=[^=]",
00055 "\\->[\\t ]*\\<%s\\>[\\t ]*\\(",
00056 "[a-z0-9_$]\\+[\\t ]*::[\\t ]*\\<%s\\>[\\t ]*\\(",
00057 "\\<%s\\>[\\t ]*\\->[\\t ]*[a-z0-9_$]\\+[\\t ]*\\(",
00058 "\\[[\\t ]*\\<%s\\>[\\t ]*[a-zA-Z0-9_$:]",
00059 0
00060 };
00061
00062 const char *filepatterns[] = {
00063 "*.h,*.hxx,*.hpp,*.hh,*.h++,*.H,*.tlh,*.cpp,*.cc,*.C,*.c++,*.cxx,*.inl,*.idl,*.c,*.m,*.mm,*.M",
00064 "*.cpp,*.cc,*.C,*.c++,*.cxx,*.inl,*.c,*.m,*.mm,*.M",
00065 "*.h,*.hxx,*.hpp,*.hh,*.h++,*.H,*.tlh,*.idl",
00066 "*.java",
00067 "*",
00068 0
00069 };
00070
00071
00072 GrepDialog::GrepDialog( GrepViewPart * part, QWidget *parent, const char *name )
00073 : QDialog(parent, name, false), m_part( part )
00074 {
00075 setCaption(i18n("Find in Files"));
00076
00077 config = GrepViewFactory::instance()->config();
00078 config->setGroup("GrepDialog");
00079
00080 QGridLayout *layout = new QGridLayout(this, 6, 2, 10, 4);
00081 layout->addRowSpacing(4, 10);
00082 layout->setRowStretch(4, 0);
00083 layout->setColStretch(0, 0);
00084 layout->setColStretch(1, 20);
00085
00086 QLabel *pattern_label = new QLabel(i18n("&Pattern:"), this);
00087 layout->addWidget(pattern_label, 0, 0, AlignRight | AlignVCenter);
00088
00089 pattern_combo = new QComboBox(true, this);
00090 pattern_label->setBuddy(pattern_combo);
00091 pattern_combo->setFocus();
00092 pattern_combo->insertStringList(config->readListEntry("LastSearchItems"));
00093 pattern_combo->setInsertionPolicy(QComboBox::NoInsertion);
00094 layout->addWidget(pattern_combo, 0, 1);
00095
00096 QLabel *template_label = new QLabel(i18n("&Template:"), this);
00097 layout->addWidget(template_label, 1, 0, AlignRight | AlignVCenter);
00098
00099 QBoxLayout *template_layout = new QHBoxLayout(4);
00100 layout->addLayout(template_layout, 1, 1);
00101
00102 template_edit = new QLineEdit(this);
00103 template_label->setBuddy(template_edit);
00104 template_edit->setText(template_str[0]);
00105 template_layout->addWidget(template_edit, 1);
00106
00107 QComboBox *template_combo = new QComboBox(false, this);
00108 template_combo->insertStrList(template_desc);
00109 template_layout->addWidget(template_combo, 0);
00110
00111 QLabel *files_label = new QLabel(i18n("&Files:"), this);
00112 layout->addWidget(files_label, 2, 0, AlignRight | AlignVCenter);
00113
00114 files_combo = new QComboBox(true, this);
00115 files_label->setBuddy(files_combo->focusProxy());
00116 files_combo->insertStrList(filepatterns);
00117 layout->addWidget(files_combo, 2, 1);
00118
00119 QLabel *dir_label = new QLabel(i18n("&Directory:"), this);
00120 layout->addWidget(dir_label, 3, 0, AlignRight | AlignVCenter);
00121
00122 QBoxLayout *dir_layout = new QHBoxLayout(4);
00123 layout->addLayout(dir_layout, 3, 1);
00124
00125 dir_combo = new KComboBox( true, this );
00126 dir_combo->insertStringList(config->readPathListEntry("LastSearchPaths"));
00127 dir_combo->setInsertionPolicy(QComboBox::NoInsertion);
00128 dir_combo->setEditText(QDir::homeDirPath());
00129
00130 url_requester = new KURLRequester( dir_combo, this );
00131 url_requester->completionObject()->setMode(KURLCompletion::DirCompletion);
00132 url_requester->setMode( KFile::Directory | KFile::ExistingOnly | KFile::LocalOnly );
00133
00134 dir_label->setBuddy( url_requester );
00135 dir_combo->setMinimumWidth(dir_combo->fontMetrics().maxWidth()*25);
00136 dir_layout->addWidget( url_requester, 10 );
00137
00138 synch_button = new QPushButton(".", this );
00139 QToolTip::add( synch_button, i18n("Set directory to that of the current file") );
00140 dir_layout->addWidget( synch_button );
00141
00142 QBoxLayout *dir_checks_layout = new QHBoxLayout(4);
00143 layout->addLayout(dir_checks_layout, 4, 1);
00144
00145 recursive_box = new QCheckBox(i18n("&Recursive"), this);
00146 recursive_box->setChecked(true);
00147 dir_checks_layout->addSpacing(10);
00148 dir_checks_layout->addWidget(recursive_box);
00149
00150 ignore_scm_box = new QCheckBox(i18n("S&kip VCS dirs"), this);
00151 ignore_scm_box->setChecked(true);
00152 dir_checks_layout->addSpacing(10);
00153 dir_checks_layout->addWidget(ignore_scm_box);
00154
00155 case_sens_box = new QCheckBox(i18n("Case &sensitive"), this);
00156 case_sens_box->setChecked(true);
00157 dir_checks_layout->addSpacing(10);
00158 dir_checks_layout->addWidget(case_sens_box);
00159
00160 QBoxLayout *button_layout = new QHBoxLayout(4);
00161 layout->addLayout(button_layout, 5, 1);
00162 search_button = new QPushButton(i18n("&Search"), this);
00163 search_button->setDefault(true);
00164 KPushButton *done_button = new KPushButton(KStdGuiItem::cancel(), this);
00165 button_layout->addStretch();
00166 button_layout->addWidget(search_button);
00167 button_layout->addWidget(done_button);
00168
00169 resize(sizeHint());
00170
00171 QWhatsThis::add(pattern_combo,
00172 i18n("<qt>Enter the regular expression you want to search for here.<p>"
00173 "Possible meta characters are:"
00174 "<ul>"
00175 "<li><b>.</b> - Matches any character"
00176 "<li><b>^</b> - Matches the beginning of a line"
00177 "<li><b>$</b> - Matches the end of a line"
00178 "<li><b>\\<</b> - Matches the beginning of a word"
00179 "<li><b>\\></b> - Matches the end of a word"
00180 "</ul>"
00181 "The following repetition operators exist:"
00182 "<ul>"
00183 "<li><b>?</b> - The preceding item is matched at most once"
00184 "<li><b>*</b> - The preceding item is matched zero or more times"
00185 "<li><b>+</b> - The preceding item is matched one or more times"
00186 "<li><b>{<i>n</i>}</b> - The preceding item is matched exactly <i>n</i> times"
00187 "<li><b>{<i>n</i>,}</b> - The preceding item is matched <i>n</i> or more times"
00188 "<li><b>{,<i>n</i>}</b> - The preceding item is matched at most <i>n</i> times"
00189 "<li><b>{<i>n</i>,<i>m</i>}</b> - The preceding item is matched at least <i>n</i>, "
00190 "but at most <i>m</i> times."
00191 "</ul>"
00192 "Furthermore, backreferences to bracketed subexpressions are "
00193 "available via the notation \\<i>n</i>.</qt>"
00194 ));
00195 QWhatsThis::add(files_combo,
00196 i18n("Enter the file name pattern of the files to search here. "
00197 "You may give several patterns separated by commas"));
00198 QWhatsThis::add(template_edit,
00199 i18n("You can choose a template for the pattern from the combo box "
00200 "and edit it here. The string %s in the template is replaced "
00201 "by the pattern input field, resulting in the regular expression "
00202 "to search for."));
00203
00204 connect( template_combo, SIGNAL(activated(int)),
00205 SLOT(templateActivated(int)) );
00206 connect( search_button, SIGNAL(clicked()),
00207 SLOT(slotSearchClicked()) );
00208 connect( done_button, SIGNAL(clicked()),
00209 SLOT(hide()) );
00210 connect( pattern_combo->lineEdit(), SIGNAL( textChanged ( const QString & ) ),
00211 SLOT( slotPatternChanged( const QString & ) ) );
00212 connect( synch_button, SIGNAL(clicked()), this, SLOT(slotSynchDirectory()) );
00213 slotPatternChanged( pattern_combo->currentText() );
00214 }
00215
00216
00217 static QStringList qCombo2StringList( QComboBox* combo )
00218 {
00219 QStringList list;
00220 if (!combo)
00221 return list;
00222 for (int i = 0; i < combo->count(); ++i ) {
00223 list << combo->text(i);
00224 }
00225 return list;
00226 }
00227
00228 GrepDialog::~GrepDialog()
00229 {
00230 config->setGroup("GrepDialog");
00231
00232 config->writeEntry("LastSearchItems", qCombo2StringList(pattern_combo));
00233 config->writePathEntry("LastSearchPaths", qCombo2StringList(dir_combo));
00234 }
00235
00236 void GrepDialog::slotPatternChanged( const QString & _text )
00237 {
00238 search_button->setEnabled( !_text.isEmpty() );
00239 }
00240
00241 void GrepDialog::templateActivated(int index)
00242 {
00243 template_edit->setText(template_str[index]);
00244 }
00245
00246
00247 static bool qComboContains( const QString& s, QComboBox* combo )
00248 {
00249 if (!combo)
00250 return false;
00251 for (int i = 0; i < combo->count(); ++i ) {
00252 if (combo->text(i) == s) {
00253 return true;
00254 }
00255 }
00256 return false;
00257 }
00258
00259 void GrepDialog::slotSearchClicked()
00260 {
00261 if (pattern_combo->currentText().isEmpty()) {
00262 KMessageBox::sorry(this, i18n("Please enter a search pattern"));
00263 pattern_combo->setFocus();
00264 return;
00265 }
00266
00267 if (!qComboContains(pattern_combo->currentText(), pattern_combo)) {
00268 pattern_combo->insertItem(pattern_combo->currentText(), 0);
00269 }
00270 if (pattern_combo->count() > 15) {
00271 pattern_combo->removeItem(15);
00272 }
00273 if (!qComboContains(dir_combo->currentText(), dir_combo)) {
00274 dir_combo->insertItem(dir_combo->currentText(), 0);
00275 }
00276 if (dir_combo->count() > 15) {
00277 dir_combo->removeItem(15);
00278 }
00279
00280 emit searchClicked();
00281 hide();
00282 }
00283
00284 void GrepDialog::show()
00285 {
00286
00287
00288 if (isVisible())
00289 QDialog::hide();
00290 QDialog::show();
00291 pattern_combo->setFocus();
00292 }
00293
00294 void GrepDialog::slotSynchDirectory( )
00295 {
00296 KParts::ReadOnlyPart * part = dynamic_cast<KParts::ReadOnlyPart*>( m_part->partController()->activePart() );
00297 if ( part )
00298 {
00299 KURL url = part->url();
00300 if ( url.isLocalFile() )
00301 {
00302 dir_combo->setEditText( url.upURL().path( +1 ) );
00303
00304 }
00305 }
00306 }
00307
00308 #include "grepdlg.moc"