findscreen.cpp

Go to the documentation of this file.
00001 #include "main.h"
00002 #include "findscreen.h"
00003 #include "findtablewidget.h"
00004 #include "knowtreemodel.h"
00005 
00006 #include <QLineEdit>
00007 #include <QPushButton>
00008 #include <QComboBox>
00009 #include <QToolButton>
00010 #include <QHBoxLayout>
00011 #include <QSplitter>
00012 #include <QWidget>
00013 
00014 #include <QtGui/qboxlayout.h>
00015 #include <QtGui/qtextdocument.h>
00016 #include <QtGui/qlineedit.h>
00017 
00018 extern appconfig mytetraconfig;
00019 
00020 
00021 findscreen::findscreen(QWidget *parent) : QWidget(parent)
00022 {
00023  setup_toolsline();
00024  assembly_toolsline();
00025 
00026  setup_wherefindline();
00027  assembly_wherefindline();
00028 
00029  setup_ui();
00030  assembly();
00031  
00032  setup_signals();
00033 }
00034 
00035 
00036 findscreen::~findscreen(void)
00037 {
00038 
00039 }
00040 
00041 void findscreen::setup_toolsline(void)
00042 {
00043  findtext=new QLineEdit();
00044   
00045  findstart=new QPushButton(tr("Find"));
00046  findstart->setDefault(true);
00047  findstart->setEnabled(false);
00048  
00049  wordregard=new QComboBox();
00050  wordregard->addItem(tr("Any word"));
00051  wordregard->addItem(tr("All words"));
00052  wordregard->setCurrentIndex(mytetraconfig.get_findscreen_wordregard());
00053  
00054  howextract=new QComboBox();
00055  howextract->addItem(tr("Separate word"));
00056  howextract->addItem(tr("Substring"));
00057  howextract->setCurrentIndex(mytetraconfig.get_findscreen_howextract());
00058 
00059  closebutton=new QToolButton(this);
00060  closebutton->setVisible(true);
00061  int w=closebutton->geometry().width();
00062  int h=closebutton->geometry().height();
00063  int x=imin(w,h)/2;
00064  closebutton->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, QSizePolicy::ToolButton));
00065  closebutton->setIcon(this->style()->standardIcon(QStyle::SP_TitleBarCloseButton));
00066  closebutton->setMinimumSize(x,x);
00067  closebutton->setMaximumSize(x,x);
00068  closebutton->resize(x,x);
00069 
00070 }
00071 
00072 
00073 // Строка формирование поискового запроса с кнопочкой закрытия
00074 void findscreen::assembly_toolsline(void)
00075 {
00076  // Горизонтальный набор инструментов запроса
00077  // с распоркой чтобы область кнопки была справа
00078  toolsline=new QHBoxLayout();
00079  toolsline->addWidget(findtext);
00080  toolsline->addWidget(findstart);
00081  toolsline->addWidget(wordregard);
00082  toolsline->addWidget(howextract);
00083  toolsline->addStretch();
00084  
00085  // Вертикальная область с кнопкой закрытия и распоркой 
00086  // чтобы кнопка была вверху
00087  placeupclosebutton=new QVBoxLayout();
00088  placeupclosebutton->setContentsMargins(0,0,0,0);
00089  placeupclosebutton->addWidget(closebutton);
00090  placeupclosebutton->addStretch();
00091  toolsline->addLayout(placeupclosebutton);
00092  
00093  toolsline->setContentsMargins(3,2,2,0); // Устанавливаются границы
00094 }
00095 
00096 
00097 void findscreen::setup_wherefindline(void)
00098 {
00099  wherefindlabel=new QLabel(tr("Find in: "));
00100 
00101  find_in_name=new QCheckBox(tr("Title"));
00102  find_in_name->setChecked(mytetraconfig.get_findscreen_find_in_field("name"));
00103 
00104  find_in_author=new QCheckBox(tr("Author(s)"));
00105  find_in_author->setChecked(mytetraconfig.get_findscreen_find_in_field("author"));
00106 
00107  find_in_url=new QCheckBox(tr("Url"));
00108  find_in_url->setChecked(mytetraconfig.get_findscreen_find_in_field("url"));
00109 
00110  find_in_tags=new QCheckBox(tr("Tags"));
00111  find_in_tags->setChecked(mytetraconfig.get_findscreen_find_in_field("tags"));
00112 
00113  find_in_text=new QCheckBox(tr("Text"));
00114  find_in_text->setChecked(mytetraconfig.get_findscreen_find_in_field("text"));
00115 }
00116 
00117 
00118 void findscreen::assembly_wherefindline(void)
00119 {
00120  wherefindline=new QHBoxLayout();
00121  
00122  wherefindline->addWidget(wherefindlabel);
00123  wherefindline->addWidget(find_in_name);
00124  wherefindline->addWidget(find_in_author);
00125  wherefindline->addWidget(find_in_url);
00126  wherefindline->addWidget(find_in_tags);
00127  wherefindline->addWidget(find_in_text);
00128  
00129  wherefindline->addStretch();
00130  
00131  wherefindline->setContentsMargins(3,0,0,0); // Устанавливаются границы
00132 }
00133 
00134 
00135 void findscreen::setup_signals(void)
00136 {
00137  // При каждом изменении текста в строке запроса
00138  connect(findtext,SIGNAL(textChanged(const QString&)),
00139          this,SLOT(enable_find_button(const QString&)));
00140 
00141  // При нажатии Enter в строке запроса
00142  connect(findtext,SIGNAL(returnPressed()),
00143          this,SLOT(find_clicked()));
00144  
00145  // При нажатии кнопки Find
00146  connect(findstart,SIGNAL(clicked()),
00147          this,SLOT(find_clicked()));
00148  
00149  // При нажатии кнопки закрытия
00150  connect(closebutton,SIGNAL(clicked()),
00151          this,SLOT(widget_hide()));
00152  
00153  // Сигналы для запоминания состояния интерфейса
00154  connect(wordregard,SIGNAL(currentIndexChanged(int)),
00155          this,SLOT(changed_wordregard(int)));
00156 
00157  connect(howextract,SIGNAL(currentIndexChanged(int)),
00158          this,SLOT(changed_howextract(int)));
00159 
00160  connect(find_in_name,SIGNAL(stateChanged(int)),
00161          this,SLOT(changed_find_in_name(int)));
00162 
00163  connect(find_in_author,SIGNAL(stateChanged(int)),
00164          this,SLOT(changed_find_in_author(int)));
00165 
00166  connect(find_in_url,SIGNAL(stateChanged(int)),
00167          this,SLOT(changed_find_in_url(int)));
00168 
00169  connect(find_in_tags,SIGNAL(stateChanged(int)),
00170          this,SLOT(changed_find_in_tags(int)));
00171 
00172  connect(find_in_text,SIGNAL(stateChanged(int)),
00173          this,SLOT(changed_find_in_text(int)));
00174 }
00175 
00176 
00177 void findscreen::setup_ui(void)
00178 {
00179  findtable=new findtablewidget();
00180 
00181 }
00182 
00183 
00184 void findscreen::assembly(void)
00185 {
00186  centrallayout=new QVBoxLayout();
00187  centrallayout->addLayout(toolsline);
00188  centrallayout->addLayout(wherefindline);
00189  centrallayout->addWidget(findtable);
00190  centrallayout->setContentsMargins(0,0,0,0); // Границы убираются
00191  centrallayout->setSizeConstraint(QLayout::SetNoConstraint);
00192  
00193  this->setLayout(centrallayout);
00194 }
00195 
00196 
00197 void findscreen::enable_find_button(const QString &text)
00198 {
00199  findstart->setEnabled(!text.isEmpty());
00200 }
00201 
00202 
00203 void findscreen::find_clicked(void)
00204 {
00205  // Поля, где нужно искать (Заголовок, текст, теги...)
00206  search_area["name"]  =find_in_name->isChecked();
00207  search_area["author"]=find_in_author->isChecked();
00208  search_area["url"]   =find_in_url->isChecked();
00209  search_area["tags"]  =find_in_tags->isChecked();
00210  search_area["text"]  =find_in_text->isChecked();
00211  
00212  // Проверяется, установлено ли хоть одно поле для поиска
00213  int findenableflag=0;
00214  foreach (bool value, search_area)
00215   if(value==true)findenableflag=1;
00216 
00217  // Если не отмечены поля для поиска
00218  if(findenableflag==0)
00219   {
00220    QMessageBox messageBox(this);
00221    messageBox.setWindowTitle(tr("Can not start find process"));
00222    messageBox.setText(tr("Please checked one or more find field"));
00223    QAbstractButton *okButton =messageBox.addButton(tr("Ok"),QMessageBox::AcceptRole);
00224    messageBox.exec();
00225    return; 
00226   }
00227 
00228  // Выясняется список слов, которые нужно искать
00229  search_word_list=text_decompose(findtext->text());
00230 
00231  if(search_word_list.size()==0)
00232   {
00233    QMessageBox messageBox(this);
00234    messageBox.setWindowTitle(tr("Can not start find process"));
00235    messageBox.setText(tr("Too small query, try write at least one word."));
00236    QAbstractButton *okButton =messageBox.addButton(tr("Ok"),QMessageBox::AcceptRole);
00237    messageBox.exec();
00238    return; 
00239   }
00240 
00241  find_start();
00242 }
00243 
00244 
00245 QStringList findscreen::text_decompose(QString text)
00246 {
00247  text.replace('"',' ');
00248  text.replace("'"," ");
00249  text.replace('.',' ');
00250  text.replace(',',' ');
00251  text.replace(';',' ');
00252  text.replace(':',' ');
00253  text.replace('-',' ');
00254  text.replace('?',' ');
00255  text.replace('!',' ');
00256  
00257  QStringList list = text.split(QRegExp("\\W+"), QString::SkipEmptyParts);
00258  
00259  return list;
00260 }
00261 
00262 
00263 void findscreen::find_start(void)
00264 {
00265  // Очищается таблица результата поиска
00266  findtable->clear_all();
00267  
00268  // Выясняется ссылка на модель дерева данных
00269  knowtreemodel *search_model=static_cast<knowtreemodel*>(find_object<QTreeView>("knowtree")->model());
00270  
00271  //Вызывается рекурсивный поиск в дереве, начиная с корневого элемента
00272  find_recurse(search_model->rootItem);
00273  
00274  // После вставки всех данных подгоняется ширина колонок
00275  findtable->update_columns_width();
00276 }
00277 
00278 
00279 void findscreen::find_recurse(TreeItem *curritem)
00280 {
00281 
00282  // Если в ветке присутсвует таблица конечных записей
00283  if(curritem->recordtable_getrowcount() > 0)
00284   {
00285    // Обработка таблицы конечных записей
00286   
00287    // Выясняется ссылка на таблицу конечных записей
00288    recordtabledata *search_recordtable=curritem->recordtable_gettabledata();
00289 
00290    // Перебираются записи таблицы
00291    for(int i=0;i<search_recordtable->size();i++)
00292     {
00293      // Результаты поиска в полях
00294      QMap<QString, bool> iteration_search_result; 
00295 
00296      iteration_search_result["name"]  =false;
00297      iteration_search_result["author"]=false;
00298      iteration_search_result["url"]   =false;
00299      iteration_search_result["tags"]  =false;
00300      iteration_search_result["text"]  =false;
00301 
00302      // Текст в котором будет проводиться поиск
00303      QString inspect_text;
00304 
00305      // Цикл поиска в отмеченных пользователем полях
00306      QMapIterator<QString, bool> j(iteration_search_result);
00307      while(j.hasNext()) 
00308       {
00309        j.next();
00310        QString key=j.key();
00311 
00312        // Если в данном поле нужно проводить поиск
00313        if(search_area[key]==true)
00314         {
00315          if(key!="text")
00316           {
00317            // Поиск в обычном поле
00318            inspect_text=search_recordtable->get_field(key,i);
00319            iteration_search_result[key]=find_in_text_process(inspect_text);
00320           }
00321          else
00322           {
00323            // Поиск в тексте записи 
00324            inspect_text=search_recordtable->get_text(i);
00325            QTextDocument textdoc;
00326            textdoc.setHtml(inspect_text);
00327            iteration_search_result[key]=find_in_text_process(textdoc.toPlainText());
00328           }
00329         } 
00330       } // Закрылся цикл поиска в полях 
00331      
00332     
00333      // Проверяется, есть ли поле, в котором поиск был успешен
00334      int findflag=0;
00335      foreach (bool value, iteration_search_result)
00336       if(value==true)findflag=1;
00337      
00338      // Если запись найдена
00339      if(findflag==1)
00340       {
00341        qDebug() << "Find succesfull in " << search_recordtable->get_field("name",i);
00342     
00343        // В таблицу результатов поиска добавляются данные
00344        // Имя записи
00345        // Имя ветки
00346        // Теги
00347        // Путь к ветке
00348        // Номер записи в таблице конечных записей
00349        findtable->add_row(search_recordtable->get_field("name",i),
00350                           curritem->data("name").toString(),
00351                           search_recordtable->get_field("tags",i),
00352                           curritem->get_path(),
00353                           i);
00354       }
00355      
00356     } // Закрылся цикл перебора записей в таблице конечных записей
00357   } // Закрылось условие что в ветке есть таблица конечных записей
00358  
00359 
00360  // Рекурсивная обработка каждой подчиненной ветки
00361  for(int i=0;i<curritem->childCount();i++) find_recurse(curritem->child(i));
00362 
00363 }
00364 
00365 
00366 // Поиск в переданном тексте
00367 // Учитываются состояния переключателей wordregard и howextract
00368 bool findscreen::find_in_text_process(const QString& text)
00369 {
00370  int findwordcount=0;
00371  int findflag=0;
00372  
00373  // Перебираются искомые слова
00374  for(int i=0; i< search_word_list.size(); ++i) 
00375   {
00376    findflag=0;
00377 
00378    // Если надо найти совпадение целого слова
00379    if(howextract->currentIndex()==0)
00380     {
00381      // Текст разбивается на слова с очисткой от лишних знаков 
00382      // и проверяется, есть ли в полученном списке текущее слово
00383      if(text_decompose(text).contains(search_word_list.at(i), Qt::CaseInsensitive))
00384       findflag=1;
00385     }
00386    else
00387     { 
00388      // Если надо найти слово как подстроку
00389      if(text.contains(search_word_list.at(i), Qt::CaseInsensitive))
00390       findflag=1;
00391     }
00392    
00393    // Если слово было найдено, количество найденных слов увеличивается
00394    if(findflag==1)findwordcount++;
00395    
00396    // Если ищется хотя бы одно совпадение
00397    if(findflag==1 && wordregard->currentIndex()==0)
00398     return true; // То при первом же совпадении цикл прекращается
00399   }    
00400 
00401  // Искалось хотя бы одно совпадение, но не было найдено
00402  if(wordregard->currentIndex()==0) return false;
00403  else
00404   {
00405    // Иначе требовалось найти все слова в запросе
00406    if( findwordcount==search_word_list.size() )
00407     return true;
00408    else 
00409     return false;
00410   }  
00411  
00412 }
00413 
00414 
00415 void findscreen::changed_wordregard(int pos)
00416 {
00417  mytetraconfig.set_findscreen_wordregard(pos);
00418 }
00419 
00420 
00421 void findscreen::changed_howextract(int pos)
00422 {
00423  mytetraconfig.set_findscreen_howextract(pos);
00424 }
00425 
00426 
00427 void findscreen::changed_find_in_name(int state)
00428 {
00429  changed_find_in_field("name",state);
00430 }
00431 
00432 
00433 void findscreen::changed_find_in_author(int state)
00434 {
00435  changed_find_in_field("author",state);
00436 }
00437 
00438 
00439 void findscreen::changed_find_in_url(int state)
00440 {
00441  changed_find_in_field("url",state);
00442 }
00443 
00444 
00445 void findscreen::changed_find_in_tags(int state)
00446 {
00447  changed_find_in_field("tags",state);
00448 }
00449 
00450 
00451 void findscreen::changed_find_in_text(int state)
00452 {
00453  changed_find_in_field("text",state);
00454 }
00455 
00456 
00457 void findscreen::changed_find_in_field(QString fieldname, int state)
00458 {
00459  bool i;
00460  if(state==Qt::Checked) i=true;
00461  else i=false;
00462   
00463  mytetraconfig.set_findscreen_find_in_field(fieldname,i);
00464 }
00465  
00466 
00467 void findscreen::widget_show(void)
00468 {
00469  mytetraconfig.set_findscreen_show(true);
00470  this->show();
00471 }
00472 
00473 
00474 void findscreen::widget_hide(void)
00475 {
00476  // Запоминается размер сплиттера перед скрытием виджета
00477  QSplitter *findsplitter_rel=find_object<QSplitter>("findsplitter");
00478  mytetraconfig.set_findsplitter_size_list(findsplitter_rel->sizes());
00479  
00480  // Виджет скрывается
00481  mytetraconfig.set_findscreen_show(false);
00482  this->close();
00483 }

Generated on Mon Feb 2 00:25:34 2009 for mytetra by  doxygen 1.5.1