/***************************************************************************** tdefilereplaceview.cpp - description ------------------- begin : sam oct 16 15:28:00 CEST 1999 copyright : (C) 1999 by Fran�is Dupoux (C) 2004 Emiliano Gulmini *****************************************************************************/ /***************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * *****************************************************************************/ // TQt #include #include #include #include // KDE #include #include #include #include #include #include #include #include #include //#include #include #include #include // local #include "tdefilereplaceview.h" #include "tdefilereplacelib.h" #include "kaddstringdlg.h" #include "whatthis.h" using namespace whatthisNameSpace; TDEFileReplaceView::TDEFileReplaceView(RCOptions* info, TQWidget *parent,const char *name) : TDEFileReplaceViewWdg(parent,name) { m_option = info; initGUI(); // result listview: connect events connect(m_lvResults, TQT_SIGNAL(mouseButtonClicked(int, TQListViewItem *, const TQPoint &, int)), this, TQT_SLOT(slotResultMouseButtonClicked(int, TQListViewItem *, const TQPoint &))); connect(m_lvResults, TQT_SIGNAL(returnPressed(TQListViewItem *)), this, TQT_SLOT(slotResultReturnPressed(TQListViewItem *))); connect(m_lvResults, TQT_SIGNAL(executed(TQListViewItem *)), this, TQT_SLOT(slotResultReturnPressed(TQListViewItem *))); connect(m_lvResults_2, TQT_SIGNAL(mouseButtonClicked(int, TQListViewItem *, const TQPoint &, int)), this, TQT_SLOT(slotResultMouseButtonClicked(int, TQListViewItem *, const TQPoint &))); connect(m_lvResults_2, TQT_SIGNAL(returnPressed(TQListViewItem *)), this, TQT_SLOT(slotResultReturnPressed(TQListViewItem *))); connect(m_lvResults_2, TQT_SIGNAL(executed(TQListViewItem *)), this, TQT_SLOT(slotResultReturnPressed(TQListViewItem *))); // connect header events connect(m_lvResults->header(), TQT_SIGNAL(clicked(int)), this,TQT_SLOT(slotResultHeaderClicked(int))); connect(m_lvResults_2->header(), TQT_SIGNAL(clicked(int)), this,TQT_SLOT(slotResultHeaderClicked(int))); // string listview: connect events connect(m_lvStrings, TQT_SIGNAL(doubleClicked(TQListViewItem *)), this, TQT_SLOT(slotStringsAdd())); connect(m_lvStrings_2, TQT_SIGNAL(doubleClicked(TQListViewItem *)), this, TQT_SLOT(slotStringsAdd())); whatsThis(); } TQString TDEFileReplaceView::getItemPath(const TQListViewItem *lvi) { if (!lvi) { return TQString::null; } return TQString(lvi->text(1)+"/"+lvi->text(0)); } TQListViewItem* TDEFileReplaceView::getCurrItemTopLevelParent() { TQListViewItem *lvi = m_rv->currentItem(); while (lvi && lvi->parent()) { lvi = lvi->parent(); } return lvi; } void TDEFileReplaceView::showSemaphore(TQString s) { if(s == "green") { m_ledGo->setState(KLed::On); m_ledWait->setState(KLed::Off); m_ledStop->setState(KLed::Off); } else if(s == "yellow") { m_ledGo->setState(KLed::Off); m_ledWait->setState(KLed::On); m_ledStop->setState(KLed::Off); } else if(s == "red") { m_ledGo->setState(KLed::Off); m_ledWait->setState(KLed::Off); m_ledStop->setState(KLed::On); } } void TDEFileReplaceView::displayScannedFiles(int foldersNumber, int filesNumber) { m_lcdFoldersNumber->display(TQString::number(foldersNumber,10)); m_lcdFilesNumber->display(TQString::number(filesNumber,10)); } void TDEFileReplaceView::stringsInvert(bool invertAll) { if (m_option->m_searchingOnlyMode) { return; } TDEListView *sv = getStringsView(); TQListViewItem *lviCurItem; if (invertAll) { lviCurItem = sv->firstChild(); } else { lviCurItem = sv->currentItem(); } if (!lviCurItem) { return; } do { TQString searchText = lviCurItem->text(0), replaceText = lviCurItem->text(1); // Cannot invert the string when search string is empty if (replaceText.isEmpty()) { KMessageBox::error(0, i18n("Cannot invert string %1, because the search string would be empty.") .arg(searchText)); } else { lviCurItem->setText(0, replaceText); lviCurItem->setText(1, searchText); } lviCurItem = lviCurItem->nextSibling(); } while (invertAll && lviCurItem); updateStringMap(); emit updateGUI(); } void TDEFileReplaceView::changeViews() { changeViews(m_option->m_searchingOnlyMode); } void TDEFileReplaceView::changeViews(bool searchingOnlyMode) { if (searchingOnlyMode) { m_stackResults->raiseWidget(m_lvResults_2); m_stackStrings->raiseWidget(m_lvStrings_2); m_rv = m_lvResults_2; m_sv = m_lvStrings_2; m_lvResults->clear(); m_lvStrings->clear(); } else { m_stackResults->raiseWidget(m_lvResults); m_stackStrings->raiseWidget(m_lvStrings); m_rv = m_lvResults; m_sv = m_lvStrings; m_lvResults_2->clear(); m_lvStrings_2->clear(); } } TDEListView* TDEFileReplaceView::getResultsView() { if (m_option->m_searchingOnlyMode) m_rv = m_lvResults_2; else m_rv = m_lvResults; return m_rv; } TDEListView* TDEFileReplaceView::getStringsView() { if (m_option->m_searchingOnlyMode) m_sv = m_lvStrings_2; else m_sv = m_lvStrings; return m_sv; } //PUBLIC SLOTS void TDEFileReplaceView::slotResultMouseButtonClicked(int button, TQListViewItem *lvi, const TQPoint &pos) { if (lvi == 0) // No item selected return; if (button == Qt::RightButton) { // Right mouse button: open popup menub m_menuResult->popup(pos); } } void TDEFileReplaceView::slotResultReturnPressed (TQListViewItem *lvi) { if (lvi == 0) // No item selected return; // Left mouse button: open item in default view slotResultOpen(); } void TDEFileReplaceView::slotResultProperties() { TQString currItemPath = getItemPath(getCurrItemTopLevelParent()); if (!currItemPath.isEmpty()) { KURL url(currItemPath); (void) new KPropertiesDialog(url); } } void TDEFileReplaceView::slotResultOpen() { TQString currItemPath = getItemPath(getCurrItemTopLevelParent()); if (!currItemPath.isEmpty()) { (void) new KRun(KURL(currItemPath), 0, true, true); } } void TDEFileReplaceView::slotResultOpenWith() { TQString currItemPath = getItemPath(getCurrItemTopLevelParent()); if (!currItemPath.isEmpty()) { KURL::List kurls; kurls.append(KURL(currItemPath)); KRun::displayOpenWithDialog(kurls); } } void TDEFileReplaceView::slotResultDirOpen() { TQString currItemPath = getItemPath(getCurrItemTopLevelParent()); if (!currItemPath.isEmpty()) { TQFileInfo fi; fi.setFile(currItemPath); (void) new KRun (KURL::fromPathOrURL(fi.dirPath()), 0, true, true); } } void TDEFileReplaceView::slotResultEdit() { TQListViewItem *lvi = m_rv->firstChild(); while (lvi) { DCOPClient *client = kapp->dcopClient(); DCOPRef quanta(client->appId(),"WindowManagerIf"); TQString path = TQString(lvi->text(1)+"/"+lvi->text(0)); TQListViewItem *lviChild = lvi; while(lviChild) { if(lviChild->isSelected()) { coord c; if(lviChild == lvi) { c.line = 0; c.column = 0; } else { c= extractWordCoordinates(lviChild); } bool success = quanta.send("openFile", path, c.line, c.column); if(!success) { TQString message = i18n("File %1 cannot be opened. Might be a DCOP problem.").arg(path); KMessageBox::error(parentWidget(), message); } } if (lviChild == lvi) lviChild = lviChild->firstChild(); else lviChild = lviChild->nextSibling(); } lvi = lvi->nextSibling(); } } void TDEFileReplaceView::slotResultRemoveEntry() { TQListViewItem *currItem = getCurrItemTopLevelParent(); if (currItem) { delete currItem; } emit updateGUI(); } void TDEFileReplaceView::slotResultDelete() { TQListViewItem *currItem = getCurrItemTopLevelParent(); TQString currItemPath = getItemPath(currItem); if (currItem) { TQFile fi; int answer = KMessageBox::warningContinueCancel(this, i18n("Do you really want to delete %1?").arg(currItemPath), TQString(),KStdGuiItem::del()); if(answer == KMessageBox::Continue) { fi.setName(currItemPath); fi.remove(); delete currItem; } } emit updateGUI(); } void TDEFileReplaceView::slotResultTreeExpand() { TQListViewItem *lviRoot = getResultsView()->firstChild(); if(lviRoot) expand(lviRoot, true); } void TDEFileReplaceView::slotResultTreeReduce() { TQListViewItem *lviRoot = getResultsView()->firstChild(); if(lviRoot) expand(lviRoot, false); } void TDEFileReplaceView::slotResultLoad() { // Selects the file to load from TQString menu = "*.tfr_results|" + i18n("TDEFileReplace Results") + " (*.tfr_results)\n*|" + i18n("All Files") + " (*)"; TQString fileName = KFileDialog::getOpenFileName(TQString(), menu, this, i18n("Load Results From File")); if (fileName.isEmpty()) { return; } // Creates a xml document and browses it TQDomDocument doc("results"); TQFile file(fileName); if (!file.open(IO_ReadOnly)) { KMessageBox::error(this, i18n("Cannot open the file %1 and load the results list.").arg(fileName)); return; } if (!doc.setContent(&file)) { file.close(); KMessageBox::information(this, i18n("File %1 seems not to be valid.").arg(fileName), i18n("Warning")); return; } else { file.close(); } TQDomElement docElem = doc.documentElement(); TQDomNode tln = docElem.firstChild(); // top level node TQString searchAttribute = tln.toElement().attribute("search"); if (searchAttribute.isNull() || searchAttribute.isEmpty()) { int answer = KMessageBox::warningYesNo(this, i18n("Missing search type. Is this a search-and-replace list of results?").arg(fileName),i18n("Warning"),i18n("Yes"),i18n("No")); if (answer == KMessageBox::Yes) { m_option->m_searchingOnlyMode = false; } else { m_option->m_searchingOnlyMode = true; } } else { m_option->m_searchingOnlyMode = (searchAttribute == "true"); } changeViews(); // Clears view TDEListView *rv = getResultsView(); rv->clear(); // Reads the result list KeyValueMap docMap; tln = tln.nextSibling(); if (!tln.isNull()) { tln = tln.firstChild(); } while (!tln.isNull()) { TQDomElement fileEle = tln.toElement(); if (!fileEle.isNull()) { TDEListViewItem *fileItem = new TDEListViewItem(rv); fileItem->setText(0, fileEle.attribute("name", "!ERROR!")); fileItem->setText(1, fileEle.attribute("folder")); if (m_option->m_searchingOnlyMode) { fileItem->setText(2, fileEle.attribute("size")); fileItem->setText(3, fileEle.attribute("matches")); fileItem->setText(4, fileEle.attribute("user")); fileItem->setText(5, fileEle.attribute("group")); } else { fileItem->setText(2, fileEle.attribute("old_size")); fileItem->setText(3, fileEle.attribute("new_size")); fileItem->setText(4, fileEle.attribute("matches")); fileItem->setText(5, fileEle.attribute("user")); fileItem->setText(6, fileEle.attribute("group")); } TQDomNode lineNode = fileEle.firstChild(); while (!lineNode.isNull()) { TQDomElement lineEle = lineNode.toElement(); TDEListViewItem *lineItem = new TDEListViewItem(fileItem); lineItem->setText(0, lineEle.text()); lineNode = lineNode.nextSibling(); } } tln = tln.nextSibling(); } emit updateGUI(); } void TDEFileReplaceView::slotResultSave() { // Check there are results in the list TDEListView *rv = getResultsView(); if (!rv->firstChild()) { KMessageBox::error(0, i18n("There are no results to save.")); return; } // Selects the file where results will be saved TQString menu = "*.tfr_results|" + i18n("TDEFileReplace Results") + " (*.tfr_results)\n*|" + i18n("All Files") + " (*)"; TQString fileName = KFileDialog::getSaveFileName(TQString(), menu, this, i18n("Save Results to File")); if (fileName.isEmpty()) { return; } TQFile file(fileName); if (!file.open(IO_WriteOnly)) { KMessageBox::error(0, i18n("File %1 cannot be saved.").arg(fileName)); return; } TQTextStream filestream(&file); filestream.setEncoding(TQTextStream::UnicodeUTF8); filestream << "\n\n"; if (m_option->m_searchingOnlyMode) { filestream << "\t\n"; } else { filestream << "\t\n"; } filestream << "\t\n"; TQListViewItem *lvi = rv->firstChild(); while (lvi) { // File filestream << TQString("\t\ttext(0)).arg(lvi->text(1)); if (m_option->m_searchingOnlyMode) { filestream << TQString("size=\"%1\" matches=\"%2\" user=\"%3\" group=\"%4\">\n") .arg(lvi->text(2)).arg(lvi->text(3)).arg(lvi->text(4)).arg(lvi->text(5)); } else { filestream << TQString("old_size=\"%1\" new_size=\"%2\" matches=\"%3\" user=\"%4\" group=\"%5\">\n") .arg(lvi->text(2)).arg(lvi->text(3)).arg(lvi->text(4)).arg(lvi->text(5)).arg(lvi->text(6)); } // File entries TQListViewItem *lvsubi = lvi->firstChild(); while (lvsubi) { filestream << TQString("\t\t\t%1\n").arg(lvsubi->text(0)); lvsubi = lvsubi->nextSibling(); } filestream << "\t\t\n"; lvi = lvi->nextSibling(); } filestream << "\t\n\n"; file.close(); } void TDEFileReplaceView::slotResultHeaderClicked(int sortCol) { TDEListView *lv = getResultsView(); int oldSortCol = lv->columnSorted(); if (oldSortCol == -1 || sortCol != oldSortCol) { lv->setSorting(sortCol, true); } else { lv->setSorting(sortCol, lv->ascendingSort()); } } void TDEFileReplaceView::slotStringsAdd() { KAddStringDlg addStringDlg(m_option); if(!addStringDlg.exec()) { return; } changeViews(); loadMapIntoView(m_option->m_mapStringsView); emit updateGUI(); } void TDEFileReplaceView::slotQuickStringsAdd(const TQString& quickSearch, const TQString& quickReplace) { if(!quickSearch.isEmpty()) { KeyValueMap map; if(quickReplace.isEmpty()) { map[quickSearch] = TQString(); m_option->m_searchingOnlyMode = true; } else { map[quickSearch] = quickReplace; m_option->m_searchingOnlyMode = false; } m_option->m_mapStringsView = map; changeViews(); loadMapIntoView(map); } } void TDEFileReplaceView::slotStringsLoad() { // Selects the file to load from TQString menu = "*.kfr|" + i18n("TDEFileReplace strings") + " (*.kfr)\n*|"+i18n("All Files") + " (*)"; TQString fileName = KFileDialog::getOpenFileName(TQString(), menu, this, i18n("Load Strings From File")); if (fileName.isEmpty()) { return; } // Creates a xml document and browses it TQDomDocument doc("strings"); TQFile file(fileName); if (!file.open(IO_ReadOnly)) { KMessageBox::error(this, i18n("Cannot open the file %1 and load the string list.").arg(fileName)); return; } if (!doc.setContent(&file)) { file.close(); KMessageBox::information(this, i18n("File %1 seems not to be written in a valid kfr format.").arg(fileName), i18n("Warning")); return; } else { file.close(); } TQDomElement docElem = doc.documentElement(); TQDomNode n = docElem.firstChild(); TQString searchAttribute = n.toElement().attribute("search"); if (searchAttribute.isNull() || searchAttribute.isEmpty()) { int answer = KMessageBox::warningYesNo(this, i18n("Missing search type. Is this a search-and-replace list of strings?").arg(fileName),i18n("Warning"),i18n("Yes"),i18n("No")); if (answer == KMessageBox::Yes) { m_option->m_searchingOnlyMode = false; } else { m_option->m_searchingOnlyMode = true; } } else { m_option->m_searchingOnlyMode = (searchAttribute == "true"); } changeViews(); // Clears view TDEListView *sv = getStringsView(); sv->clear(); // Reads the string list KeyValueMap docMap; n = n.nextSibling(); while (!n.isNull()) { TQDomElement e = n.toElement(); if (!e.isNull()) { TQString searchString = e.firstChild().toElement().text(); TQString replaceString = e.lastChild().toElement().text(); docMap[searchString] = replaceString; } n = n.nextSibling(); } loadMap(docMap); emit updateGUI(); } void TDEFileReplaceView::slotStringsSave() { // Check there are strings in the list TDEListView *sv = getStringsView(); if (!sv->firstChild()) { KMessageBox::error(0, i18n("No strings to save as the list is empty.")); return; } // Selects the file where strings will be saved TQString menu = "*.kfr|" + i18n("TDEFileReplace Strings") + " (*.kfr)\n*|" + i18n("All Files") + " (*)"; TQString fileName = KFileDialog::getSaveFileName(TQString(), menu, this, i18n("Save Strings to File")); if (fileName.isEmpty()) { return; } TQFile file(fileName); if (!file.open(IO_WriteOnly)) { KMessageBox::error(0, i18n("File %1 cannot be saved.").arg(fileName)); return ; } TQString header("\n"), footer("\n"), body; if(m_option->m_searchingOnlyMode) header += "\n\t"; else header += "\n\t"; TQListViewItem *lvi = sv->firstChild(); while (lvi) { body += TQString("\n\t" "\n\t\t%1" "\n\t\t%2" "\n\t").arg(lvi->text(0)).arg(lvi->text(1)); lvi = lvi->nextSibling(); } TQTextStream oTStream(&file); oTStream.setEncoding(TQTextStream::UnicodeUTF8); oTStream << header << body << footer; file.close(); } void TDEFileReplaceView::slotStringsInvertCur() { stringsInvert(false); } void TDEFileReplaceView::slotStringsInvertAll() { stringsInvert(true); } void TDEFileReplaceView::slotStringsDeleteItem() { TQListViewItem *item = m_sv->currentItem(); if (item) { KeyValueMap m = m_option->m_mapStringsView; m.remove(item->text(0)); m_option->m_mapStringsView = m; delete item; emit updateGUI(); } } void TDEFileReplaceView::slotStringsEmpty() { m_sv->clear(); m_option->m_mapStringsView.clear(); emit updateGUI(); } //PRIVATE void TDEFileReplaceView::initGUI() { m_option->m_searchingOnlyMode = true; m_stackResults->addWidget(m_lvResults); m_stackResults->addWidget(m_lvResults_2); m_stackStrings->addWidget(m_lvStrings); m_stackStrings->addWidget(m_lvStrings_2); DCOPClient *client = kapp->dcopClient(); QCStringList appList = client->registeredApplications(); bool quantaFound = false; for(QCStringList::Iterator it = appList.begin(); it != appList.end(); ++it) { if((*it).left(6) == "quanta") { quantaFound = true; break; } } m_menuResult = new TDEPopupMenu(this, "ResultPopup"); m_menuResult->insertItem(SmallIconSet(TQString::fromLatin1("document-open")), i18n("&Open"), this, TQT_SLOT(slotResultOpen())); m_menuResult->insertItem(SmallIconSet(TQString::fromLatin1("document-open")), i18n("Open &With..."), this, TQT_SLOT(slotResultOpenWith())); if(quantaFound) { m_menuResult->insertItem(SmallIconSet("quanta"), i18n("&Edit in Quanta"), this, TQT_SLOT(slotResultEdit())); } m_menuResult->insertItem(SmallIconSet(TQString::fromLatin1("go-up")), i18n("Open Parent &Folder"), this, TQT_SLOT(slotResultDirOpen())); m_menuResult->insertItem(SmallIconSet(TQString::fromLatin1("edit-clear")), i18n("Remove &Entry"), this, TQT_SLOT(slotResultRemoveEntry())); m_menuResult->insertItem(SmallIconSet(TQString::fromLatin1("edit-delete")), i18n("&Delete"), this, TQT_SLOT(slotResultDelete())); m_menuResult->insertSeparator(); m_menuResult->insertItem(SmallIconSet(TQString::fromLatin1("application-vnd.tde.info")), i18n("&Properties"), this, TQT_SLOT(slotResultProperties())); changeViews(); } coord TDEFileReplaceView::extractWordCoordinates(TQListViewItem* lvi) { //get coordinates of the first string of the current selected file coord c; c.line = 0; c.column = 0; TQString s = lvi->text(0); //tqWarning("WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW=%s",s.latin1()); /* if(lvi->parent()) s = lvi->text(0); else return c;*/ TQString temp; int i = 0; //extracts line and column from lvi->text(0) //FIXME: Don't get the line and column number from the text as it's translated and it will //fail for non-English languages! //EMILIANO: This is not a good fixing but for now it should reduce the problems while(true) { if(s[i] < '0' || s[i] > '9') i++; else break; } while(true) { if(s[i] >= '0' && s[i] <= '9') { temp += s[i]; i++; } else break; } c.line = temp.toInt(); temp = TQString(); while(true) { if(s[i] < '0' || s[i] > '9') i++; else break; } while(true) { if(s[i] >= '0' && s[i] <= '9') { temp += s[i]; i++; } else break; } c.column = temp.toInt(); if(c.line > 0) c.line--; if(c.column > 0) c.column--; return c; } void TDEFileReplaceView::expand(TQListViewItem *lviCurrent, bool b) { // current item lviCurrent->setOpen(b); // recursivity while((lviCurrent = lviCurrent->nextSibling()) != 0) { lviCurrent->setOpen(b); if (lviCurrent->firstChild()) expand(lviCurrent->firstChild(), b); } } void TDEFileReplaceView::updateStringMap() { m_option->m_mapStringsView.clear(); TQListViewItem *item = m_sv->firstChild(); while (item) { if (m_option->m_searchingOnlyMode) { m_option->m_mapStringsView[item->text(0)] = TQString(); } else { m_option->m_mapStringsView[item->text(0)] = item->text(1); } item = item->nextSibling(); } } void TDEFileReplaceView::loadMapIntoView(KeyValueMap map) { m_sv->clear(); KeyValueMap::Iterator itMap; for(itMap = map.begin(); itMap != map.end(); ++itMap) { TQListViewItem* lvi = new TQListViewItem(m_sv); lvi->setMultiLinesEnabled(true); lvi->setText(0,itMap.key()); if(!m_option->m_searchingOnlyMode) lvi->setText(1,itMap.data()); } } void TDEFileReplaceView::whatsThis() { TQWhatsThis::add(getResultsView(), lvResultWhatthis); TQWhatsThis::add(getStringsView(), lvStringsWhatthis); } #include "tdefilereplaceview.moc"